⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 urb.txt

📁 Driver URB
💻 TXT
字号:
                                     初始化请求
为了创建一个URB,你首先应该为URB分配内存,然后调用初始化例程把URB结构中的各个域填入请求要求的内容.
USB_DEVICE_DESCRIPTOR dd;
URB urb;
UsbBuildGetDescriptorRequest(&urb,//创建URB
			     sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
			     USB_DEVICE_DESCRIPTOR_TYPE,
			     0,
			     0,
		    	     &dd,
			     NULL,
			     sizeof(dd),
			     NULL);
当然,你还可以在系统堆上为URB动态地分配内存:

PURB urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST));
if (!urb)
	return STATUS_INSUFFICIENT_RESOURCES;
UsbBuildGetDescriptorRequest(urb, ...);//创建URB
...
ExFreePool(urb);
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       发送URB
创建完URB后,你需要创建并发送一个内部I/O控制(IOCTL)请求到USBD驱动程序,USBD驱动程序位于驱动程序层次结构的低端。在大多数情况下,你需要等待设备回应,可以使用下面辅助函数:

NTSTATUS SendAwaitUrb(PDEVICE_OBJECT fdo, PURB urb)
{
  PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  KEVENT event;										<--1
  KeInitializeEvent(&event, NotificationEvent, FALSE);
  IO_STATUS_BLOCK iostatus;
  PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,		<--2
					   pdx->LowerDeviceObject,
					   NULL,
					   0,
					   NULL,
					   0,
					   TRUE,
					   &event,
					   &iostatus);
  PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);				<--3
  stack->Parameters.Others.Argument1 = (PVOID) urb;
  NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);				<--4
  if (status  == STATUS_PENDING)
  {
    KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
    status = iostatus.Status;
  }
  return status;
}
 

1、我们将等待URB完成,所以我们必须先创建一个内核事件对象。这与我在第六章"即插即用"中使用的辅助函数
ForwardAndWait类似。 
2、创建内部IOCTL请求最简单的的方法是调用IoBuildDeviceIoControlRequest函数,第一个参数(IOCTL_INTERN
AL_USB_SUBMIT_URB)指出I/O控制代码。第二个参数(pdx->LowerDeviceObject)指定接收请求的设备对象;
3、IoBuildDeviceIoControlRequest使用这个指针来决定需要接收多少个堆栈单元。接下来的四个参数描述输入
输出缓冲区,提交这种URB并不需要这些信息,所以例子中将它们置成NULL或0值。第七个参数为TRUE,它指出我
们创建的是IRP_MJ_INTERNAL_DEVICE_CONTROL请求而不是IRP_MJ_DEVICE_CONTROL请求。最后两个参数指出等待
URB完成的事件和一个接收该操作最终状态的结构IO_STATUS_BLOCK。 
4、被提交的URB的地址被填入Parameters.Others的Argument1域。对于普通的IOCTL请求,该偏移对应OutputBu
fferLength域。 
5、我们用IoCallDriver把请求发送到下一层驱动程序。USBD将处理该URB请求并完成,然后I/O管理器将那个
IRP删除并置事件信号。由于我们没有提供自己的完成例程,所以不能确定I/O管理器在所有可能的完成情况下
都置事件信号。我们仅当低级派遣例程返回STATUS_PENDING时才等待那个事件。 
………………………………………………………………………………………………………………………………
                                        URB返回的状态

NTSTATUS status = SendAwaitUrb(fdo, &urb);
USBD_STATUS ustatus = URB_STATUS(&urb);
…………………………………………………………………………………………………………………………………

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -