WinUSB 设备

在本文中,你将了解 Windows 如何识别 WinUSB 设备。

如果你是 OEM 或独立硬件供应商, (IHV) 开发想要使用 Winusb.sys 作为函数驱动程序的设备,并且想要在不提供自定义 INF 的情况下自动加载驱动程序,则本文中的信息适用于你。

什么是 WinUSB 设备

WinUSB 设备是通用串行总线 (USB) 设备,其固件定义某些 Microsoft 操作系统 (OS) 功能描述符,将兼容 ID 报告为“WINUSB”。

WinUSB 设备的目的是使 Windows 能够加载 Winusb.sys 作为设备的功能驱动程序,而无需自定义 INF 文件。 对于 WinUSB 设备,无需为设备分发 INF 文件,从而使最终用户的驱动程序安装过程变得简单。 相反,如果需要提供自定义 INF,则不应将设备定义为 WinUSB 设备,并在 INF 中指定设备的硬件 ID。

Microsoft 提供 Winusb.inf,其中包含安装 Winusb.sys 作为 USB 设备的设备驱动程序所需的信息。

在Windows 8之前,若要将 Winusb.sys 加载为函数驱动程序,需要提供自定义 INF。 自定义 INF 指定特定于设备的硬件 ID,还包括内置 Winusb.inf 中的部分。 这些部分是实例化服务、复制收件箱二进制文件和注册应用程序查找设备并与之通信所需的设备接口 GUID 所必需的。 有关编写自定义 INF 的信息,请参阅 WinUSB (Winusb.sys) 安装

在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,若要使用“USBDevice”设备类,只需将此添加到 INF:

  [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。 如果兼容 ID 为“WINUSB”,则 Windows 将其用作设备标识符,并在更新的内置 Winusb.inf 中查找匹配项,然后加载 Winusb.sys 作为设备的函数驱动程序。

此映像适用于定义为 WinUSB 设备的单个接口 MUTT 设备,因此 Winusb.sys 加载为设备的函数驱动程序。

显示 WinUSB 设备的 Windows 设备管理器的屏幕截图。

对于早于 Windows 8 的 Windows 版本,可通过Windows 更新获取更新后的 Winusb.inf。 如果计算机配置为自动获取驱动程序更新,则使用新的 INF 包将安装 WinUSB 驱动程序,而无需任何用户干预。

如何更改 WinUSB 设备的设备说明

对于 WinUSB 设备,设备管理器显示“WinUsb 设备”作为设备说明。 该字符串派生自 Winusb.inf。 如果有多个 WinUSB 设备,则所有设备都会获得相同的设备说明。

为了在 设备管理器 中唯一标识和区分设备,Windows 8在设备类上提供一个新属性,该属性指示系统在其 iProduct 字符串描述符) 中将设备描述 (报告的设备说明优先于 INF 中的说明。 Windows 8 中定义的“USBDevice”类将设置此属性。 换句话说,当设备安装在“USBDevice”类下时,系统会查询设备以获取设备说明,并将设备管理器字符串设置为查询中检索到的任何内容。 在这种情况下,将忽略 INF 中提供的设备说明。 请注意上图中的设备说明字符串:“MUTT”。 字符串由 USB 设备在其产品字符串描述符中提供。

早期版本的 Windows 不支持新的类属性。 若要在早期版本的 Windows 上获得自定义设备说明,必须编写自己的自定义 INF。

如何配置 WinUSB 设备

若要将 USB 设备标识为 WinUSB 设备,设备固件必须具有 Microsoft OS 描述符。 有关描述符的信息,请参阅此处所述的规范: Microsoft OS 描述符

支持扩展功能描述符

为了使 USB 驱动程序堆栈知道设备支持扩展功能描述符,设备必须定义存储在字符串索引0xEE的 OS 字符串描述符。 在枚举期间,驱动程序堆栈会查询字符串描述符。 如果描述符存在,则驱动程序堆栈假定设备包含一个或多个 OS 功能描述符以及检索这些功能描述符所需的数据。

检索到的字符串描述符具有 bMS_VendorCode 字段值。 值指示 USB 驱动程序堆栈必须用于检索扩展功能描述符的供应商代码。

有关如何定义 OS 字符串描述符的信息,请参阅此处所述的规范中的“OS 字符串 描述符”:Microsoft OS 描述符

设置兼容 ID

扩展的兼容 ID OS 功能描述符,用于匹配内置 Winusb.inf 并加载 WinUSB 驱动程序模块。

扩展的兼容 ID OS 功能描述符包括标头部分,后跟一个或多个功能部分,具体取决于设备是复合设备还是非复合设备。 标头部分指定整个描述符的长度、函数节数和版本号。 对于非复合设备,标头后跟一个与设备的唯一接口关联的函数部分。 该部分的 compatibleID 字段必须指定“WINUSB”作为字段值。 对于复合设备,有多个功能部分。 每个函数节的 compatibleID 字段必须指定“WINUSB”。

注册设备接口 GUID

注册其设备接口 GUID 所需的扩展属性 OS 功能描述符。 需要 GUID 才能从应用程序或服务中查找设备、配置设备以及执行 I/O 操作。

在早期版本的 Windows 中,设备接口 GUID 注册是通过自定义 INF 完成的。 从 Windows 8 开始,设备应使用扩展属性 OS 功能描述符报告接口 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 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 0 0 43 00 36 00 42 00 46 00 45 00 34 00 37 00 35 00 7D 0000 00 属性值为 {8FE6D4D7-49DD-41E7-9486-49AFC6BFE475}。

在设备枚举期间,USB 驱动程序堆栈随后从扩展属性 OS 功能描述符中检索 DeviceInterfaceGUID 值,并在设备的硬件密钥中注册设备。 应用程序可以使用 SetupDiXxx API 检索值 (请参阅 SetupDiOpenDevRegKey) 。 有关详细信息,请参阅 如何使用 WinUSB 函数访问 USB 设备

启用或禁用 WinUSB 电源管理功能

在Windows 8之前,若要配置 WinUSB 的电源管理功能,必须在 HW 中编写注册表项值自定义 INF 的 AddReg 部分。

在Windows 8及更高版本中,可以在设备中指定电源设置。 可以通过扩展属性 OS 功能描述符报告值,这些描述符在 WinUSB 中为该设备启用或禁用功能。 可以配置两个功能:选择性挂起和系统唤醒。 选择性挂起允许设备在空闲时进入低功耗状态。 系统唤醒是指设备在系统处于低功耗状态时唤醒系统的能力。

有关 WinUSB 的电源管理功能的信息,请参阅 WinUSB 电源管理

属性名称 说明
DeviceIdleEnabled 此值设置为 1,指示设备可以在空闲 (选择性挂起) 关机。
DefaultIdleState 此值设置为 1,表示设备在默认情况下处于空闲状态时可以挂起。
DefaultIdleTimeout 此值设置为 5000 毫秒,表示在确定设备处于空闲状态之前等待的时间(以毫秒为单位)。
UserSetDeviceIdleEnabled 此值设置为 1 以允许用户控制设备启用或禁用 USB 选择性挂起的能力。 检查框允许计算机关闭此设备以节省设备电源管理属性页上的电源,用户可以检查或取消选中该框以启用或禁用 USB 选择性挂起。
SystemWakeEnabled 此值设置为 1 以允许用户控制设备将系统从低功耗状态唤醒的能力。 启用后,“允许此设备唤醒计算机检查”框将显示在设备电源管理属性页中。 用户可以检查或取消选中复选框以启用或禁用 USB 系统唤醒。

例如,若要在设备上启用选择性挂起,请添加一个自定义属性部分,用于将 bPropertyName 字段设置为 Unicode 字符串“DeviceIdleEnabled”和 wPropertyNameLength 为 36 字节。 将 bPropertyData 字段设置为“0x00000001”。 属性值存储为小字节序 32 位整数。

在枚举期间,USB 驱动程序堆栈读取扩展属性功能描述符,并在此项下创建注册表项:

\ HKEY_LOCAL_MACHINE系统\CurrentControlSet\枚举\Usb\<设备标识符>\<实例标识符>\设备参数

此图显示了 WinUSB 设备的示例设置。

Windows 注册表编辑器的屏幕截图,其中显示了 WinUSB 设备的设置。

有关其他示例,请参阅 Microsoft OS 描述符上的规范。