Windows下USB驱动异步URB转IRP请求函数代码
2021-08-30
332
1
URB有同步请求,也有异步请求。这里微软官方提供了一个异步请求URB的代码示例
// The SubmitUrbASync routine submits an URB asynchronously.
//
// Parameters:
//
// Parameters:
// DeviceExtension: Pointer to the caller's device extension. The
// device extension must have a pointer to
// the next lower device object in the device stacks.
//
// Irp: Pointer to an IRP allocated by the caller.
//
// Urb: Pointer to an URB that is allocated by USBD_UrbAllocate,
// USBD_IsochUrbAllocate, USBD_SelectConfigUrbAllocateAndBuild,
// or USBD_SelectInterfaceUrbAllocateAndBuild.
// CompletionRoutine: Completion routine.
//
// CompletionContext: Context for the completion routine.
//
//
// Return Value:
//
// NTSTATUS
NTSTATUS SubmitUrbASync ( PDEVICE_EXTENSION DeviceExtension,
PIRP Irp,
PURB Urb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
{
// Completion routine is required if the URB is submitted asynchronously.
// The caller's completion routine releases the IRP when it completes.
NTSTATUS ntStatus = -1;
PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);
// Attach the URB to this IRP.
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
// Attach the URB to this IRP.
nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
// Attach the URB to this IRP.
(void) USBD_AssignUrbToIoStackLocation (DeviceExtension->UsbdHandle, nextStack, Urb);
// Caller's completion routine will free the irp when it completes.
ntStatus = IoSetCompletionRoutineEx ( DeviceExtension->NextDeviceObject,
Irp,
CompletionRoutine,
CompletionContext,
TRUE,
TRUE,
TRUE);
if (!NT_SUCCESS(ntStatus))
{
goto Exit;
}
(void) IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
Exit:
if (!NT_SUCCESS(ntStatus))
{
// We hit a failure condition,
// We will free the IRP
IoFreeIrp(Irp);
Irp = NULL;
}
return ntStatus;
}
可以看到,这个代码和同步的方式类似,只是少了:
- 创建创建IRP完成时回调函数中需要激活的EVENT事件
- IoCallDriver后,不再要根据Pending状态等待事件。
当然,该IRP什么时候完成,这里就需要放在完成例程中实现了。而对于同步传输,后续的处理代码既可以放在完成例程中,也可以放在KeWaitForSingleObject之后,而对于异步传输,就只能放在完成例程中了。
注意:完成例程的中断请求级别比交高。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936