📄 cioctl.c
字号:
// #define DRIVER
//
// Include files needed for WDM driver support
//
#include <wdm.h>
#include "stdarg.h"
#include "stdio.h"
//
// Include files needed for USB support
//
#include "usbdi.h"
#include "usbdlib.h"
//
// Include file for the Ezusb Device
//
#include "ezusbsys.h"
//
// incude file containing driver version
//
#include "version.h"
NTSTATUS c_ProcessIOCTL(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
/*++
Routine Description:
This where all the DeviceIoControl codes are handled. You can add more code
here to handle IOCTL codes that are specific to your device driver.
Arguments:
fdo - pointer to the device object for this instance of the Ezusb device.
Return Value:
NT status code
--*/
{
PIO_STACK_LOCATION irpStack;
PVOID ioBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension;
ULONG ioControlCode;
NTSTATUS ntStatus;
ULONG length;
PUCHAR pch;
Ezusb_KdPrint (("IRP_MJ_DEVICE_CONTROL\n"));
if (!LockDevice(fdo))
return CompleteRequest(Irp, STATUS_DELETE_PENDING, 0);
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
ioBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
//
// Handle Ioctls from User mode
//
switch (ioControlCode)
{
case IOCTL_Ezusb_VENDOR_REQUEST:
length = c_VendorRequest (fdo, (PVENDOR_REQUEST_IN) ioBuffer);
if (length)
{
Irp->IoStatus.Information = length;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
else
{
Irp->IoStatus.Status = STATUS_SUCCESS;
}
Ezusb_KdPrint(("Vendor Request returned %d bytes\n", length));
break;
case IOCTL_Ezusb_ANCHOR_DOWNLOAD:
{
PURB urb = NULL;
int chunkcount;
int chunklength = 1024;
PVOID ioBufferPtr = NULL;
int i;
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
Ezusb_KdPrint (("IOCTL_Ezusb_ANCHOR_DOWNLOAD\n"));
if (urb)
{
chunkcount = inputBufferLength / CHUNKLENGTH;
ioBufferPtr = ioBuffer;
for (i=0;i<chunkcount;i++)
{
RtlZeroMemory(urb,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
Ezusb_KdPrint (("ioBuffer: %x | inputBufferLength: %d | outputBufferLength: %d\n",
ioBuffer, inputBufferLength, outputBufferLength));
urb->UrbControlVendorClassRequest.TransferBufferLength = CHUNKLENGTH;
urb->UrbControlVendorClassRequest.TransferBuffer = ioBufferPtr;
urb->UrbControlVendorClassRequest.TransferBufferMDL = NULL;
urb->UrbControlVendorClassRequest.Request = 0xA0;
urb->UrbControlVendorClassRequest.Value = (i * CHUNKLENGTH);
urb->UrbControlVendorClassRequest.Index = 0;
ntStatus = Ezusb_CallUSBD(fdo, urb);
(char *) ioBufferPtr += CHUNKLENGTH;
}
ExFreePool(urb);
}
}
break;
case IOCTL_EZUSB_ANCHOR_DOWNLOAD:
{
PANCHOR_DOWNLOAD_CONTROL downloadControl = (PANCHOR_DOWNLOAD_CONTROL) ioBuffer;
Ezusb_KdPrint (("IOCTL_EZUSB_ANCHOR_DOWNLOAD\n"));
//
// check the arguments
//
if (inputBufferLength != sizeof(ANCHOR_DOWNLOAD_CONTROL) ||
outputBufferLength == 0)
{
Ezusb_KdPrint (("Error: Invalid Parameter\n"));
ntStatus = STATUS_INVALID_PARAMETER;
}
else
{
ntStatus = c_AnchorDownload(fdo,
downloadControl->Offset,
(PUCHAR) MmGetSystemAddressForMdl(Irp->MdlAddress),
outputBufferLength);
}
break;
}
case IOCTL_Ezusb_GET_CURRENT_CONFIG:
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case IOCTL_EZUSB_GET_CURRENT_FRAME_NUMBER:
{
ULONG frameNumber = 0;
//
// make sure the output buffer is valid
//
if (outputBufferLength < sizeof(ULONG))
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break;
}
frameNumber = c_GetCurrentFrameNumber (fdo);
if (frameNumber)
{
*((PULONG)ioBuffer) = frameNumber;
Irp->IoStatus.Information = sizeof(ULONG);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
else
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
break;
case IOCTL_Ezusb_RESETPIPE:
{
ULONG pipenum = *((PULONG) ioBuffer);
Irp->IoStatus.Status = c_ResetPipe(fdo,pipenum);
}
break;
case IOCTL_Ezusb_ABORTPIPE:
{
int pipenum = *((PULONG) ioBuffer);
c_AbortPipe(fdo,
(USBD_PIPE_HANDLE) pdx->Interface->Pipes[pipenum].PipeHandle);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case IOCTL_Ezusb_GET_PIPE_INFO:
//
// inputs - none
// outputs - we copy the interface information structure that we have
// stored in our device extension area to the output buffer which
// will be reflected to the user mode application by the IOS.
//
length = 0;
pch = (PUCHAR) ioBuffer;
if (pdx->Interface)
{
RtlCopyMemory(pch+length,
(PUCHAR) pdx->Interface,
pdx->Interface->Length);
length += pdx->Interface->Length;
}
Irp->IoStatus.Information = length;
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR:
//
// inputs - pointer to a buffer in which to place descriptor data
// outputs - we put the device descriptor data, if any is returned by the device
// in the system buffer and then we set the length inthe Information field
// in the Irp, which will then cause the system to copy the buffer back
// to the user's buffer
//
length = c_GetDeviceDescriptor (fdo, ioBuffer);
Ezusb_KdPrint(("Get Device Descriptor returned %d bytes\n", length));
Irp->IoStatus.Information = length;
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IOCTL_Ezusb_GET_STRING_DESCRIPTOR:
{
PGET_STRING_DESCRIPTOR_IN Input = ioBuffer;
if ((inputBufferLength = sizeof(GET_STRING_DESCRIPTOR_IN)) &&
(outputBufferLength > 0))
{
length = c_GetStringDescriptor (fdo,
Input->Index,
Input->LanguageId,
ioBuffer,
outputBufferLength);
if (length)
{
Irp->IoStatus.Information = length;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
else
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
}
else
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
}
break;
case IOCTL_Ezusb_GET_CONFIGURATION_DESCRIPTOR:
//
// inputs - pointer to a buffer in which to place descriptor data
// outputs - we put the configuration descriptor data, if any is returned by the device
// in the system buffer and then we set the length in the Information field
// in the Irp, which will then cause the system to copy the buffer back
// to the user's buffer
//
length = c_GetConfigDescriptor (fdo, ioBuffer, outputBufferLength);
Ezusb_KdPrint(("Get Config Descriptor returned %d bytes\n", length));
Irp->IoStatus.Information = length;
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IOCTL_Ezusb_SETINTERFACE:
{
PSET_INTERFACE_IN input = ioBuffer;
Irp->IoStatus.Status = c_SetInterface(fdo,
input->interfaceNum,
input->alternateSetting);
Irp->IoStatus.Status = 0;
}
break;
case IOCTL_Ezusb_RESET:
c_ResetParentPort(fdo);
break;
case IOCTL_EZUSB_BULK_WRITE:
case IOCTL_EZUSB_BULK_READ:
Irp->IoStatus.Status = Ezusb_Read_Write(fdo,Irp);
break;
case IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST:
Irp->IoStatus.Status = c_VendorRequest2(fdo,Irp);
break;
case IOCTL_EZUSB_GET_LAST_ERROR:
//
// make sure the output buffer is ok, and then copy the most recent
// URB status from the device extension to it
//
if (outputBufferLength >= sizeof(ULONG))
{
*((PULONG)ioBuffer) = pdx->LastFailedUrbStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(ULONG);
}
else
{
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
break;
case IOCTL_EZUSB_ISO_READ:
case IOCTL_EZUSB_ISO_WRITE:
Irp->IoStatus.Status = Ezusb_StartIsoTransfer(fdo,Irp);
Irp->IoStatus.Information = 0;
break;
case IOCTL_EZUSB_START_ISO_STREAM:
Irp->IoStatus.Status = Ezusb_StartIsoStream(fdo,Irp);
Irp->IoStatus.Information = 0;
break;
case IOCTL_EZUSB_STOP_ISO_STREAM:
pdx->StopIsoStream = TRUE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case IOCTL_EZUSB_READ_ISO_BUFFER:
{
ULONG dataBytesToRead;
ULONG descriptorBytesToRead;
ULONG dataBytesRead;
ULONG descriptorBytesRead;
PISO_TRANSFER_CONTROL isoControl =
(PISO_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer;
//
// verify the input and output params
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -