【问题标题】:How do you get the raw descriptor data from a USB HID device in Windows?如何从 Windows 中的 USB HID 设备获取原始描述符数据?
【发布时间】:2023-03-21 16:15:01
【问题描述】:

如何从 Windows 中的 HID 设备获取原始描述符数据?

背景:

我需要从 Windows 中的 HID 设备获取制造商、产品名称和序列号。我正在使用 hid.dll 来访问使用 functions seen here 的设备。我的问题与to this one 非常相似。我能够从一些 HID 设备中获取制造商字符串和产品字符串,但大多数都无法返回此数据,并且 HidD_GetManufacturerString 返回 false。但是,我知道这些设备的描述符中确实包含字符串信息,因为我可以看到它using USBTreeView

有趣的是,即使对于返回制造商和产品名称的设备,我通过 hid.dll 获得的值与我使用上述工具从 USB 获取原始数据时看到的值也大不相同设备。

例如,Xbox 360 控制器:

Via USB Tree View:
Device Description       : Xbox 360 Controller for Windows
Language 0x0409          : "©Microsoft Corporation"
iProduct                 : 0x02
Language 0x0409          : "Controller"
iSerialNumber            : 0x03
Language 0x0409          : "0843806"

Via hid.dll using HidD_GetManufacturerString, HidD_GetProductString, and HidD_GetSerialNumberString:
Description              : HID-compliant game controller
Product                  : Controller (XBOX 360 Controller for Windows)
Manufacturer             : FAILS
Serial Number            : FAILS

WinUSB 根本无法打开这些设备来检索这些数据,因为它们不使用 winusb.sys 驱动程序。

1) 我不明白为什么 HidD 函数返回的值与 USB 描述符中的值不匹配。 2) 我找不到任何方法来访问 HID 设备的原始 USB 描述符数据,因为我无法使用 WinUSB 访问它们。


编辑 1:

好的,我对 HID 有了更多了解。我通过 hid.dll 获得的数据似乎是驱动程序指定的数据,而不是来自 USB 设备的数据。 HID 也可以应用于 USB 以外的传输设备。所以没关系。最终,我真正想知道的是,当我拥有 HID 设备时如何获取 USB 设备以及为此使用什么 API。除了不起作用的WinUSB,我唯一能找到的是内核级函数IOCTL。我不知道这是否适合普通的非管理员应用程序。

【问题讨论】:

  • 认为 USB 设备将成为 HID 设备的父设备(它在设备管理器中是这样显示的,至少在我的系统上是这样)所以也许你可以使用 CM_Get_Parent和相关的功能?
  • @HarryJohnston 感谢您的提示。不幸的是,父设备并不总是 USB 设备,因为某些 HID 设备嵌套了好几层。最终,关键是 CM 功能。我会添加一个答案。

标签: c# c++ windows usb hid


【解决方案1】:

我终于找到了解决办法。主要问题只是将 HID 设备与其父 USB 设备相关联。这是基本流程:

假设您已经拥有 HID 设备和它的 SP_DEVINFO_DATA:

  1. 枚举所有 USB 设备as seen here
  2. 使用 CM_GetChild 和 CM_GetSibling 查找 USB 设备的所有子设备。
  3. 将已知 HID 设备的实例句柄 (SP_DEVINFO_DATA->DevInst) 与 CM 函数返回的每个子设备的实例句柄进行比较,以确定哪个 USB 设备是父设备。
  4. 从那里,您可以获取所需的任何 USB 信息,包括描述符。

【讨论】:

  • 你不能只是重复调用 CM_Get_Parent 来跟踪这个链直到你找到一个 USB 设备吗?
  • @HarryJohnston 你可能是对的。没想到这点,主要是我经历了这个过程之后才真正了解USB设备和HID设备之间的关系。您还必须能够识别哪个是最顶层的 USB 设备,因为可能有多个。我猜你会想在你碰到一个集线器并去 -1 时停下来。
  • "从那里,您可以获得任何您想要的 USB 信息,包括描述符。"我试图弄清楚如何做到这一点。当您说父 USB 设备时,这是否意味着 HID 连接到的集线器?因为即使有了 USB 设备实例句柄和设备路径,我也无法获得 USB 描述符。看来您需要调用 DeviceIoControl 传入集线器,并指定您的设备连接到的端口以获取描述符。是否有其他方法可以仅从 USB 设备实例句柄中获取它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
相关资源
最近更新 更多