本文介绍 Windows 如何识别 WinUSB 设备。 制造商和独立硬件供应商(IHV)可以使用本文中的信息开发使用 Winusb.sys 作为功能驱动程序的设备。 本文介绍如何自动加载驱动程序,而无需提供自定义信息(INF)文件。
什么是 WinUSB 设备
WinUSB 设备是通用串行总线(USB)设备,其固件定义了某些 Microsoft 操作系统(OS)功能描述符,这些描述符报告 WINUSB 为兼容 ID。
WinUSB 设备的目的是使 Windows 能够在没有自定义 INF 文件的情况下将 Winusb.sys 加载为设备的函数驱动程序。 对于 WinUSB 设备,无需为设备分发 INF 文件,这使得驱动程序安装过程对于最终用户来说很简单。 相反,如果需要提供自定义 INF,则不应将设备定义为 WinUSB 设备,并在 INF 中指定设备的硬件 ID。
Microsoft提供 Winusb.inf 文件,其中包含安装 Winusb.sys 作为 USB 设备的设备驱动程序所需的信息。
在 Windows 8 之前,若要将 Winusb.sys 加载为函数驱动程序,需要提供自定义 INF。 自定义 INF 指定特定于设备的硬件 ID,还包括内置 Winusb.inf 中的部分。 这些部分对于实例化服务、复制收件箱二进制文件以及注册设备接口 GUID 是必需的,后者是应用程序查找设备并与之通信所必需的。 有关详细信息,请参阅 编写用于 WinUSB 安装的自定义 INF。
在 Windows 8 中,内置 Winusb.inf 文件已更新,使 Windows 能够自动将 INF 与 WinUSB 设备匹配。
使用自带的 Winusb.inf 安装 WinUSB 设备
在 Windows 8 中,内置 Winusb.inf 文件已更新。 INF 包含一个安装部分,该部分引用了名为 USB\MS_COMP_WINUSB的兼容 ID。
[Generic.Section.NTamd64]
%USB\MS_COMP_WINUSB.DeviceDesc%=WINUSB,USB\MS_COMP_WINUSB
更新后的 INF 还包括名为 USBDevice 的新安装类。
USBDevice 安装类适用于Microsoft不提供内置驱动程序的设备。 通常,此类设备不属于定义完善的 USB 类,例如音频或蓝牙,并且需要自定义驱动程序。 如果设备是 WinUSB 设备,很可能是该设备不属于 USB 类。 必须在 USBDevice 安装类下安装设备。 更新后的 Winusb.inf 有助于满足该要求。
关于使用 “USBDevice” 类
不要将 USB 安装类用于未分类的设备。 该类用于安装控制器、集线器和复合设备。 误用 USB 类可能会导致显著的可靠性和性能问题。 将 USBDevice 用于未分类的设备。
在 Windows 8 中,将此定义添加到 INF 文件以使用 USBDevice 设备类:
[Version]
...
Class=USBDevice
ClassGuid={88BAE032-5A81-49f0-BC3D-A4FF138216D6}
...
在设备管理器中,查看名为 USB 通用串行总线设备的新节点。 设备显示在该节点下。
在 Windows 7 中,除了上述行外,还需要在 INF 中创建以下注册表设置:
;---------- Add Registry Section ----------
[USBDeviceClassReg]
HKR,,,,"Universal Serial Bus devices"
HKR,,NoInstallClass,,1
HKR,,SilentInstall,,1
HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
在设备管理器中,设备显示在 USB 通用串行总线设备下。 设备类说明派生自 INF 中指定的注册表设置。
USBDevice 类不限于 WinUSB。 如果你有设备的自定义驱动程序,则可以在自定义 INF 中使用 USBDevice 安装类。
在设备枚举期间,USB 驱动程序堆栈从设备读取兼容 ID。 如果是 WINUSB 兼容的 ID,Windows 会将其用作设备标识符,并在更新的内置 Winusb.inf 中找到匹配项,然后将 Winusb.sys 加载为设备的函数驱动程序。
此图像是用于一个单接口的 Microsoft USB 测试工具(MUTT)设备,该设备被定义为 WinUSB 设备,因此 Winusb.sys 作为该设备的驱动程序被加载。
对于早于 Windows 8 的 Windows 版本,可通过 Windows 更新获取更新的 Winusb.inf。 如果计算机配置为自动获取驱动程序更新,则使用新的 INF 包无需任何用户干预即可安装 WinUSB 驱动程序。
如何更改 WinUSB 设备的设备说明
对于 WinUSB 设备,设备管理器将显示 WinUsb Device 为设备说明。 该字符串派生自 Winusb.inf。 如果有多个 WinUSB 设备,则所有设备都会获得相同的设备说明。
为了在 Device Manager 中唯一标识和区分设备,Windows 8 在设备类上提供了一个新属性。 该属性指示系统优先于设备在其 iProduct 字符串描述符中报告的设备说明,优先于 INF 中的说明。 在 Windows 8 中定义的 USBDevice 类设置此属性。
在 USBDevice 类下安装设备时,Windows 会查询设备以获取设备说明,并将 Device Manager 字符串设置为查询中检索到的任何内容。 在这种情况下,将忽略 INF 中提供的设备说明。 请注意设备说明字符串:上图中的 MUTT 。 USB 设备在其产品字符串描述符中提供字符串。
早期版本的 Windows 不支持新类属性。 若要在早期版本的 Windows 上自定义设备说明,必须编写自己的自定义 INF。
如何配置 WinUSB 设备
若要将 USB 设备标识为 WinUSB 设备,设备固件必须具有Microsoft OS 描述符。 有关详细信息,请参阅 USB 设备的Microsoft OS 描述符。
支持扩展功能描述符
若要使 USB 驱动程序堆栈知道设备支持扩展功能描述符,设备必须定义存储在字符串索引 0xEE中的 OS 字符串描述符。 在枚举期间,驱动程序堆栈会查询字符串描述符。 如果存在描述符,驱动程序堆栈假定设备包含一个或多个 OS 功能描述符,以及检索这些功能描述符所需的数据。
检索到的字符串描述符具有 bMS_VendorCode 字段值。 该值指示 USB 驱动程序堆栈必须用于检索扩展功能描述符的供应商代码。
若要定义 OS 字符串描述符,请参阅 USB 设备的Microsoft OS 描述符。
设置兼容的 ID
需要扩展兼容的 ID OS 功能描述符来匹配内置 Winusb.inf 并加载 WinUSB 驱动程序模块。
扩展兼容的 ID OS 功能描述符包括标头部分,后跟一个或多个函数部分,具体取决于设备是复合还是非组合。 标头节指定整个描述符的长度、函数节数和版本号。
对于非复合设备,标头后跟着一个与设备的唯一接口关联的功能部分。 该节的 compatibleID 字段必须指定 WINUSB 为字段值。 对于复合设备,有多个函数部分。 每个函数节的 compatibleID 字段必须指定 WINUSB。
注册设备接口的全球唯一标识符 (GUID)
需要扩展属性 OS 功能描述符来注册其设备接口 GUID。 需要 GUID 才能从应用程序或服务中查找设备、配置设备以及执行 I/O 操作。
在早期版本的 Windows 中,设备接口 GUID 注册是通过自定义 INF 完成的。 从 Windows 8 开始,设备应通过使用扩展属性的操作系统功能描述符来报告接口 GUID。
扩展属性 OS 功能描述符包括一个标头部分,后跟一个或多个自定义属性节。 标头部分描述整个扩展属性描述符,包括其总长度、版本号和自定义属性节的数目。 若要注册设备接口 GUID,请添加将 bPropertyName 字段设置为 DeviceInterfaceGUID 的自定义属性部分, 并将 wPropertyNameLength 设置为 40 字节。
使用 GUID 生成器生成唯一的设备接口 GUID,并将 bPropertyData 字段设置为该 GUID,例如 {8FE6D4D7-49DD-41E7-9486-49AFC6BFE475}。 GUID 指定为 Unicode 字符串,字符串的长度为 78 字节,包括 null 终止符。
| bPropertyData | 78 字节 | 7B 00 38 00 46 00 45 00 36 00 44 00 34 00 44 00 37 00 2D 00 34 00 39 00 00 44 00 2D 00 34 00 31 00 45 00 37 00 2D 00 39 00 34 00 38 00 36 00 2D 00 34 00 39 00 41 00 46 00 43 00 36 00 42 00 46 00 45 00 34 00 37 00 35 00 7D 00 00 00 | 属性值为 {8FE6D4D7-49DD-41E7-9486-49AFC6BFE475}。 |
在设备枚举期间,USB 驱动程序堆栈随后从扩展属性 OS 功能描述符中检索 DeviceInterfaceGUID 值,并在设备的硬件密钥中注册设备。 应用程序可以使用 SetupDiXxx API 检索值。 请参阅 SetupDiOpenDevRegKey。 有关详细信息,请参阅 使用 WinUSB 函数访问 USB 设备。
启用或禁用 WinUSB 电源管理功能
在 Windows 8 之前,若要配置 WinUSB 的电源管理功能,您必须在自定义 INF 的 HW.AddReg 部分中编写注册表项值。
在 Windows 8 及更高版本中,可以在设备中指定电源设置。 可以通过扩展属性 OS 功能描述符报告值,这些描述符在 WinUSB 中启用或禁用该设备的功能。 可以配置两个功能: 选择性挂起 和 系统唤醒。 选择性挂起允许设备在空闲时进入低功率状态。 系统唤醒是指当系统处于低功率状态时设备唤醒系统的能力。
有关详细信息,请参阅 WinUSB 电源管理。
| 属性名称 | DESCRIPTION |
|---|---|
| 设备空闲已启用 | 此值设置为 1,指示设备可在空闲状态下断电(选择性挂起)。 |
| DefaultIdleState(默认空闲状态) | 此值设置为 1,以指示设备在默认情况下处于空闲状态时可以挂起。 |
| DefaultIdleTimeout | 此值设置为 5000 毫秒,以指示在确定设备处于空闲状态之前等待的时间(以毫秒为单位)。 |
| 用户设置设备空闲启用 | 此值设置为 1,允许用户控制设备启用或禁用 USB 选择性挂起功能。 有一个复选框 ,允许计算机关闭此设备以在 设备 电源管理 属性页中节省电源。 用户可以启用或禁用 USB 选择性挂起。 |
| 系统唤醒已启用 | 此值设置为 1,允许用户控制设备从低功率状态唤醒系统的能力。 启用后, “允许此设备唤醒计算机 ”复选框将显示在设备 电源管理 属性页中。 用户可以启用或禁用 USB 系统唤醒。 |
例如,若要在设备上启用选择性挂起,请添加一个自定义属性部分,该节将 bPropertyName 字段设置为 Unicode 字符串 DeviceIdleEnabled , 并将 wPropertyNameLength 设置为 36 字节。 将 bPropertyData 字段设置为 0x00000001. 属性值存储为 little-endian 32 位整数。
枚举期间,USB 驱动程序堆栈读取扩展属性功能描述符,并在以下项下创建注册表项:
HKEY_LOCAL_MACHINE\\\\<>\<
此图显示了 WinUSB 设备的示例设置。
有关更多示例,请参阅 Microsoft OS 描述符。