📄 ios.c
字号:
VOID
UMSS_ClassSpecificRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN UCHAR Request,
IN UCHAR TransferDirection,
IN PVOID Buffer,
IN ULONG BufferLength,
IN PIO_COMPLETION_ROUTINE CompletionRoutine
)
/*++
Routine Description:
Sends a class-specific request to the device
NOTE: Assumes device extension has valid IRP and URB.
Arguments:
DeviceExtension - Our device extension.
Request - Class specific request value.
TransferDirection - Direction of data transfer.
Buffer - Address of data buffer to use for data transfer.
BufferLength - Number of bytes to transfer.
CompletionRoutine - Function to call when request completes.
Return Value:
NONE.
--*/
{
PIRP Irp;
PURB Urb;
PIO_STACK_LOCATION NextStack;
ENTER(UMSS_ClassSpecificRequest);
Irp = DeviceExtension->Irp;
Urb = DeviceExtension->Urb;
// Build URB for the ADSC command
UsbBuildVendorRequest(
Urb,
URB_FUNCTION_CLASS_INTERFACE,
(USHORT) sizeof (struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
(DATA_IN == TransferDirection) ? USBD_TRANSFER_DIRECTION_IN : 0,
0,
Request,
0,
0,
Buffer,
NULL,
BufferLength,
NULL
);
NextStack = IoGetNextIrpStackLocation(Irp);
UMSS_ASSERT(NextStack != NULL);
UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);
// Initialize our Irp
NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1 = Urb;
NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
// Register our Irp completion handler
IoSetCompletionRoutine(
Irp,
CompletionRoutine,
DeviceExtension,
TRUE, // invoke on success
TRUE, // invoke on error
TRUE // invoke on cancellation of the Irp
);
// Pass Irp to the USB driver stack
IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
EXIT(UMSS_ClassSpecificRequest);
}
VOID
UMSS_BulkTransfer(
IN PDEVICE_EXTENSION DeviceExtension,
IN UCHAR TransferDirection,
IN PVOID Buffer,
IN ULONG BufferLength,
IN PIO_COMPLETION_ROUTINE CompletionRoutine
)
/*++
Routine Description:
Initiates a bulk transfer with the USB device.
Arguments:
DeviceExtension - Our device extension.
TransferDirection - Direction of data transfer.
Buffer - Address of data buffer to use for data transfer.
BufferLength - Number of bytes to transfer.
CompletionRoutine - Function to call when request completes.
Return Value:
NONE
--*/
{
PIO_STACK_LOCATION NextStack;
USBD_PIPE_HANDLE PipeHandle;
PIRP Irp;
PURB Urb;
ENTER(UMSS_DoBulkTransfer);
if (DATA_IN == TransferDirection)
PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataInPipe].PipeHandle;
else
PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataOutPipe].PipeHandle;
Urb = DeviceExtension->Urb;
Irp = DeviceExtension->Irp;
// Build a URB for our bulk transfer
UsbBuildInterruptOrBulkTransferRequest(
Urb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
Buffer,
NULL,
BufferLength,
(DATA_OUT == TransferDirection) ? USBD_TRANSFER_DIRECTION_OUT :
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL
);
NextStack = IoGetNextIrpStackLocation(Irp);
UMSS_ASSERT(NextStack != NULL);
UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);
// Initialize our Irp
NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1 = Urb;
NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
// Register our Irp completion handler
IoSetCompletionRoutine(
Irp,
CompletionRoutine,
DeviceExtension,
TRUE, // invoke on success
TRUE, // invoke on error
TRUE // invoke on cancellation of the Irp
);
// Pass Irp to the USB driver stack
IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
EXIT(UMSS_DoBulkTransfer);
}
VOID
UMSS_BulkTransfer2(
IN PDEVICE_EXTENSION DeviceExtension,
IN UCHAR TransferDirection,
IN PVOID Buffer,
IN ULONG BufferLength,
IN PIO_COMPLETION_ROUTINE CompletionRoutine
)
/*++
Routine Description:
Initiates a bulk transfer with the USB device.
Arguments:
DeviceExtension - Our device extension.
TransferDirection - Direction of data transfer.
Buffer - Address of data buffer to use for data transfer.
BufferLength - Number of bytes to transfer.
CompletionRoutine - Function to call when request completes.
Return Value:
NONE
--*/
{
PIO_STACK_LOCATION NextStack;
USBD_PIPE_HANDLE PipeHandle;
PIRP Irp;
PURB Urb;
ENTER(UMSS_DoBulkTransfer);
if (DATA_IN == TransferDirection)
PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataInPipe].PipeHandle;
else
PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataOutPipe].PipeHandle;
Urb = DeviceExtension->Urb2;
Irp = DeviceExtension->Irp2;
// Build a URB for our bulk transfer
UsbBuildInterruptOrBulkTransferRequest(
Urb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
Buffer,
NULL,
BufferLength,
(DATA_OUT == TransferDirection) ? USBD_TRANSFER_DIRECTION_OUT :
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL
);
NextStack = IoGetNextIrpStackLocation(Irp);
UMSS_ASSERT(NextStack != NULL);
UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);
// Initialize our Irp
NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1 = Urb;
NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
// Register our Irp completion handler
IoSetCompletionRoutine(
Irp,
CompletionRoutine,
DeviceExtension,
TRUE, // invoke on success
TRUE, // invoke on error
TRUE // invoke on cancellation of the Irp
);
// Pass Irp to the USB driver stack
IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
EXIT(UMSS_DoBulkTransfer);
}
VOID
UMSS_BulkTransfer3(
IN PDEVICE_EXTENSION DeviceExtension,
IN UCHAR TransferDirection,
IN PVOID Buffer,
IN ULONG BufferLength,
IN PIO_COMPLETION_ROUTINE CompletionRoutine
)
/*++
Routine Description:
Initiates a bulk transfer with the USB device.
Arguments:
DeviceExtension - Our device extension.
TransferDirection - Direction of data transfer.
Buffer - Address of data buffer to use for data transfer.
BufferLength - Number of bytes to transfer.
CompletionRoutine - Function to call when request completes.
Return Value:
NONE
--*/
{
PIO_STACK_LOCATION NextStack;
USBD_PIPE_HANDLE PipeHandle;
PIRP Irp;
PURB Urb;
ENTER(UMSS_DoBulkTransfer);
if (DATA_IN == TransferDirection)
PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataInPipe].PipeHandle;
else
PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataOutPipe].PipeHandle;
Urb = DeviceExtension->Urb3;
Irp = DeviceExtension->Irp3;
// Build a URB for our bulk transfer
UsbBuildInterruptOrBulkTransferRequest(
Urb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
PipeHandle,
Buffer,
NULL,
BufferLength,
(DATA_OUT == TransferDirection) ? USBD_TRANSFER_DIRECTION_OUT :
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL
);
NextStack = IoGetNextIrpStackLocation(Irp);
UMSS_ASSERT(NextStack != NULL);
UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);
// Initialize our Irp
NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
NextStack->Parameters.Others.Argument1 = Urb;
NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
// Register our Irp completion handler
IoSetCompletionRoutine(
Irp,
CompletionRoutine,
DeviceExtension,
TRUE, // invoke on success
TRUE, // invoke on error
TRUE // invoke on cancellation of the Irp
);
// Pass Irp to the USB driver stack
IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);
EXIT(UMSS_DoBulkTransfer);
}
BOOLEAN
UMSS_ScheduleWorkItem(
PVOID Context,
UMSS_WORKER_ROUTINE Routine
)
/*++
Routine Description:
Wrapper for handling worker thread callbacks
Arguments:
Routine - Routine to be called when this work-item is processed
Context - Value to be passed to worker routine
Return Value:
TRUE if work item queued
FALSE if work item not queued
--*/
{
BOOLEAN RetVal = TRUE;
PWORK_QUEUE_ITEM WorkItem;
PUMSS_WORKER_PACKET WorkerPacket;
ENTER(UMSS_ScheduleWorkItem);
WorkItem = UMSS_ExAllocatePool(NonPagedPool, sizeof(WORK_QUEUE_ITEM));
WorkerPacket = UMSS_ExAllocatePool(NonPagedPool, sizeof(UMSS_WORKER_PACKET));
if ((WorkItem) && (WorkerPacket))
{
WorkerPacket->Routine = Routine;
WorkerPacket->Context = Context;
WorkerPacket->WorkItem = WorkItem;
// Initialize the work-item
ExInitializeWorkItem(
WorkItem,
UMSS_Worker,
WorkerPacket
);
// Schedule the work-item
ExQueueWorkItem(
WorkItem,
DelayedWorkQueue
);
UMSS_KdPrint( DBGLVL_MINIMUM,("Work-item queued\n"));
}
else
{
UMSS_KdPrint( DBGLVL_MINIMUM,("Failed to allocate work-item\n"));
if (WorkItem)
UMSS_ExFreePool(WorkItem);
if (WorkerPacket)
UMSS_ExFreePool(WorkerPacket);
RetVal = FALSE;
}
RETURN(RetVal, UMSS_ScheduleWorkItem);
}
VOID
UMSS_Worker(
IN PVOID Reference
)
/*++
Routine Description:
Wrapper for worker thread function. Handles cleaning up work-item, etc.,
before calling real worker function.
Arguments:
Reference - Context value to be passed to worker function.
Return Value:
NONE
--*/
{
PUMSS_WORKER_PACKET WorkerPacket;
ENTER(UMSS_Worker);
WorkerPacket = (PUMSS_WORKER_PACKET)Reference;
WorkerPacket->Routine(WorkerPacket->Context);
UMSS_ExFreePool(WorkerPacket->WorkItem);
UMSS_ExFreePool(WorkerPacket);
EXIT(UMSS_Worker);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -