USB 设备描述符

设备描述符包含有关整个 USB 设备的信息。 本文介绍 USB_DEVICE_DESCRIPTOR 结构,并包括有关客户端驱动程序如何发送 get 描述符请求以获取设备描述符的信息。

每个通用串行总线(USB)设备都必须能够提供包含设备相关信息的单个设备描述符。 USB_DEVICE_DESCRIPTOR结构描述设备描述符。 Windows 使用该信息来派生各种信息集。 例如,idVendor 和 idProduct 字段分别指定供应商和产品标识符。 Windows 使用这些字段值为设备构造 硬件 ID 。 查看特定设备的硬件 ID:

  1. 打开设备管理器
  2. 右键单击 USB 设备,然后选择“ 属性”。
  3. “属性”对话框中选择“详细信息 ”选项卡。
  4. 下拉 属性 列表。
  5. 选择硬件 ID 属性

这些值指示 Windows 生成的硬件 ID(“USB\XXX”。

USB_DEVICE_DESCRIPTOR结构的 bcdUSB 字段指示设备符合的 USB 规范的版本。 例如,0x0200指示设备按 USB 2.0 规范设计。 bcdDevice 值指示设备定义的修订号。

USB 驱动程序堆栈使用 bcdDevice 以及 idVendoridProduct 为设备生成硬件和兼容的 ID。 可以在设备管理器查看这些标识符。 设备描述符还指示设备支持的配置总数。

当设备以高速容量连接到主计算机时,设备可能会报告其设备描述符中的不同信息,而不是当设备以全速容量连接时。 设备不得在连接的生存期内更改设备描述符中包含的信息,包括在电源状态更改期间。

主机通过控制传输获取设备描述符。 在传输中,请求类型为 GET DESCRIPTOR,接收方是设备。 客户端驱动程序可以通过以下两种方式之一启动传输:使用框架 USB 目标设备对象或发送包含请求信息的 URB。

获取设备描述符

只有在创建框架 USB 目标设备对象后,Windows 驱动程序框架(WDF)客户端驱动程序才能获取设备描述符。

内核模式驱动程序框架 (KMDF) 驱动程序必须通过调用 WdfUsbTargetDeviceCreate 来获取 USB 目标设备对象的 WDFUSBDEVICE 句柄。 通常,客户端驱动程序在驱动程序的 EvtDevicePrepareHardware 回调实现中调用 WdfUsbTargetDeviceCreate 之后,客户端驱动程序必须调用 WdfUsbTargetDeviceGetDeviceDescriptor 方法。 调用完成后,在调用方分配 USB_DEVICE_DESCRIPTOR 结构中接收设备描述符。

用户模式驱动程序框架(UMDF)驱动程序必须查询 IWDFUsbTargetDevice 指针的框架设备对象,然后调用 IWDFUsbTargetDevice::RetrieveDescriptor 方法,并将USB_DEVICE_DESCRIPTOR_TYPE指定为描述符类型。

主机还可以通过发送 URB 来获取设备描述符。 此方法仅适用于内核模式驱动程序。 但是,除非驱动程序基于 Windows 驱动程序模型(WDM),否则客户端驱动程序永远不必为此类请求发送 URB。 此类驱动程序必须分配 URB 结构,然后调用 UsbBuildGetDescriptorRequest 宏来指定请求的 URB 格式。 然后,驱动程序可以通过将 URB 提交到 USB 驱动程序堆栈来发送请求。 有关详细信息,请参阅 如何提交 URB

此代码示例演示 UsbBuildGetDescriptorRequest 调用,该调用使用相应的 URB 设置 pURB 指向的缓冲区的格式:

UsbBuildGetDescriptorRequest(
    pURB,                                                 // Points to the URB to be formatted
    sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
    USB_DEVICE_DESCRIPTOR_TYPE,
    0,                                                    // Not used for device descriptors
    0,                                                    // Not used for device descriptors
    pDescriptor,                                          // Points to a USB_DEVICE_DESCRIPTOR structure
    NULL,
    sizeof(USB_DEVICE_DESCRIPTOR),
    NULL
);

示例设备描述符

此示例显示了 USB 网络摄像头设备的设备描述符(请参阅 USB 设备布局),通过使用 USBView 应用程序获取:

Device Descriptor:
bcdUSB:             0x0200
bDeviceClass:         0xEF
bDeviceSubClass:      0x02
bDeviceProtocol:      0x01
bMaxPacketSize0:      0x40 (64)
idVendor:           0x045E (Microsoft Corporation)
idProduct:          0x0728
bcdDevice:          0x0100
iManufacturer:        0x01
0x0409: "Microsoft"
iProduct:             0x02
0x0409: "Microsoft LifeCam VX-5000"
0x0409: "Microsoft LifeCam VX-5000"
iSerialNumber:        0x00
bNumConfigurations:   0x01

在前面的示例中,根据 USB 规范版本 2.0 开发设备。 请注意 bDeviceClassbDeviceSubClassbDeviceProtocol 值。 这些值指示设备包含一个或多个 USB 接口关联描述符,这些描述符可用于对每个函数的多个接口进行分组。 有关详细信息,请参阅 USB 接口关联描述符

接下来,请参阅 bMaxPacketSize0 的值。 此值指示默认终结点的最大数据包大小。 此示例设备可以通过其默认终结点传输多达 64 字节的数据。

通常,若要配置设备,客户端驱动程序会在获取设备描述符后获取有关设备中支持的配置的信息。 若要确定设备支持的配置数,请检查 返回结构的 bNumConfigurations 成员。 此设备支持一个配置。 若要获取有关 USB 配置的信息,驱动程序必须获取 USB 配置描述符