为什么 windows 不加载 WINUSB 驱动程序?
Why isn't windows loading the WINUSB Driver?
我正在使用 windows 提供的驱动程序开发包含几个 USB 功能(目前为 CDC-ACM 和 DFU)的 USB 设备。
设备描述符指示设备使用 IAD(接口关联描述符),配置描述符反映了这一点,包含 CDC 功能和 DFU 功能的所有描述符。此配置在非 windows 平台上开箱即用,两个驱动程序均已正确分配。
由于 WCID (Windows Compatible ID) requirements,我设置了以下描述符,指示 windows 应该为 DFU 接口加载 WINUSB。
USB_MicrosoftCompatibleDescriptor msft_compID =
{
.dwLength = sizeof(USB_MicrosoftCompatibleDescriptor) + (2 * sizeof(USB_MicrosoftCompatibleDescriptor_Interface)),
.bcdVersion = 0x0100,
.wIndex = 0x0004,
.bCount = 2,
.interfaces = {
{
.bFirstInterfaceNumber = 0, //CDC
.compatibleID = {0, 0, 0, 0, 0, 0, 0, 0},
.subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
},
{
.bFirstInterfaceNumber = INTERFACE_DFU,
.compatibleID = {0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00},
.subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
}
}
};
连接设备后,我观察到 windows 请求 0xEE 字符串描述符,然后请求 CompatibleID 描述符。设备管理器确认这一点,如下面的屏幕截图所示。但是,使用 WINUSB API 调用的主机端软件无法检测到该设备。当我检查 Zadig 时,很明显 windows 加载了 libusb 驱动程序,而不是我请求的 winusb。
尽管存在此问题,但 CDC-ACM 功能仍可正常工作,并在设备管理器中显示一个正常运行的虚拟串行端口。
我是否在 ComaptibleID 描述符配置中犯了任何错误,或者是否需要采取任何其他步骤来确保加载正确的驱动程序?
您不需要使用 Zadig 来查看 Windows 正在使用的驱动程序。当您在设备上 double-click 并转到“驱动程序”选项卡时,SYS 文件列表会显示在设备管理器中。
在某些时候,可能通过像 Zadig 这样的软件,您可能已经在计算机上加载了一个 INF 文件,告诉它在您的设备上使用 libusb0。如果是这样,您可以在设备管理器中检查您的设备并查看“Inf 名称”字段以找出对此负责的 INF 文件。
我建议您 right-click 在您的设备上 select “卸载设备...”以删除您的设备与 libusb0 的关联。您还应该在执行此操作时单击“卸载驱动程序软件”复选框以删除不需要的 INF 文件(如果存在)。
我在阅读 Microsoft Descriptor 文档的字里行间后找到了解决方案。为了 windows 加载 WINUSB 驱动程序,仅 MicrosoftComaptibleID
描述符是不够的。 Windows 要求设备在另一个 Microsoft 特定描述符的帮助下添加 DeviceGUID 注册表项。
这可以在 Microsoft Descriptor Specification 1 下完成,但我在 excellent guide by google.
的帮助下更新了整个设备以支持 2.0 版
因此我当前的描述符结构如下所示。
BOS descriptor
Bos header
WEBusb capability
Microsoft capability
Microsoft descriptor set header
BOS 描述符是 2.0 和 3.0 之间发布的官方 USB 规范的一部分。当windows读取Microsoft描述符集头时,它通过供应商请求的方式请求Microsoft描述符集。
MSFTDesc
USB_MSFTDescriptorHeader
USB_MSFTConfigurationSubsetHeader
USB_MSFTFunctionSubsetHeader
USB_MSFTCompatibleIDFeatureDescriptor
USB_MSFTRegPropertyDescriptor
Microsoft 描述符集包含兼容 ID 以及 GUID 的注册表 属性 描述符。
我正在使用 windows 提供的驱动程序开发包含几个 USB 功能(目前为 CDC-ACM 和 DFU)的 USB 设备。
设备描述符指示设备使用 IAD(接口关联描述符),配置描述符反映了这一点,包含 CDC 功能和 DFU 功能的所有描述符。此配置在非 windows 平台上开箱即用,两个驱动程序均已正确分配。
由于 WCID (Windows Compatible ID) requirements,我设置了以下描述符,指示 windows 应该为 DFU 接口加载 WINUSB。
USB_MicrosoftCompatibleDescriptor msft_compID =
{
.dwLength = sizeof(USB_MicrosoftCompatibleDescriptor) + (2 * sizeof(USB_MicrosoftCompatibleDescriptor_Interface)),
.bcdVersion = 0x0100,
.wIndex = 0x0004,
.bCount = 2,
.interfaces = {
{
.bFirstInterfaceNumber = 0, //CDC
.compatibleID = {0, 0, 0, 0, 0, 0, 0, 0},
.subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
},
{
.bFirstInterfaceNumber = INTERFACE_DFU,
.compatibleID = {0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00},
.subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}
}
}
};
连接设备后,我观察到 windows 请求 0xEE 字符串描述符,然后请求 CompatibleID 描述符。设备管理器确认这一点,如下面的屏幕截图所示。但是,使用 WINUSB API 调用的主机端软件无法检测到该设备。当我检查 Zadig 时,很明显 windows 加载了 libusb 驱动程序,而不是我请求的 winusb。
尽管存在此问题,但 CDC-ACM 功能仍可正常工作,并在设备管理器中显示一个正常运行的虚拟串行端口。
我是否在 ComaptibleID 描述符配置中犯了任何错误,或者是否需要采取任何其他步骤来确保加载正确的驱动程序?
您不需要使用 Zadig 来查看 Windows 正在使用的驱动程序。当您在设备上 double-click 并转到“驱动程序”选项卡时,SYS 文件列表会显示在设备管理器中。
在某些时候,可能通过像 Zadig 这样的软件,您可能已经在计算机上加载了一个 INF 文件,告诉它在您的设备上使用 libusb0。如果是这样,您可以在设备管理器中检查您的设备并查看“Inf 名称”字段以找出对此负责的 INF 文件。
我建议您 right-click 在您的设备上 select “卸载设备...”以删除您的设备与 libusb0 的关联。您还应该在执行此操作时单击“卸载驱动程序软件”复选框以删除不需要的 INF 文件(如果存在)。
我在阅读 Microsoft Descriptor 文档的字里行间后找到了解决方案。为了 windows 加载 WINUSB 驱动程序,仅 MicrosoftComaptibleID
描述符是不够的。 Windows 要求设备在另一个 Microsoft 特定描述符的帮助下添加 DeviceGUID 注册表项。
这可以在 Microsoft Descriptor Specification 1 下完成,但我在 excellent guide by google.
因此我当前的描述符结构如下所示。
BOS descriptor
Bos header
WEBusb capability
Microsoft capability
Microsoft descriptor set header
BOS 描述符是 2.0 和 3.0 之间发布的官方 USB 规范的一部分。当windows读取Microsoft描述符集头时,它通过供应商请求的方式请求Microsoft描述符集。
MSFTDesc
USB_MSFTDescriptorHeader
USB_MSFTConfigurationSubsetHeader
USB_MSFTFunctionSubsetHeader
USB_MSFTCompatibleIDFeatureDescriptor
USB_MSFTRegPropertyDescriptor
Microsoft 描述符集包含兼容 ID 以及 GUID 的注册表 属性 描述符。