使用 hid.dll API 从 HID 设备读取制造商字符串时遇到问题

Posted

技术标签:

【中文标题】使用 hid.dll API 从 HID 设备读取制造商字符串时遇到问题【英文标题】:Trouble reading Manufacturer String from HID Device using hid.dll API 【发布时间】:2010-02-24 21:13:11 【问题描述】:

我正在编写一个可以与 HID 设备通信的 .NET 应用程序。我希望能够从设备固件中检索和解析制造商字符串。我知道在 hid.dll 中有一个名为 HidD_GetManufacturerString 的方法。 MSDN 对这种方法的描述如下:

 BOOLEAN   HidD_GetManufacturerString(
     IN HANDLE  HidDeviceObject,
     OUT PVOID  Buffer,
     IN ULONG  BufferLength
     );

我用于此方法的包装器看起来像这样......

[DllImport("hid.dll", SetLastError = true)]
        internal static extern Boolean HidD_GetManufacturerString(
            SafeFileHandle hFile,
            Byte[] SerialNumber,
            Int32 SerianNumberLength);

我需要知道两件事。首先,我如何知道将 SerialNumber 缓冲区初始化为什么大小?当我执行 GetFeatureReport 之类的操作时,我知道缓冲区的大小,因为我可以使用 HidD_GetAttributes() 从设备属性中检索最大功能报告长度;不幸的是,这个方法没有给我任何关于制造商字符串、序列号字符串、产品名称字符串等长度的信息。

我的第二个问题是,将返回的字节数组解析为字符串的正确方法是什么?我尝试使用

System.Text.Encoding.ASCII.GetString(MfrBuffer)

但我得到了一个奇怪的结果。对于戴尔制造的产品,我的字符串看起来像这样“D\0e\0l\0l\0\0\0\0\0...”,“\0”继续到我通过的缓冲区的末尾。如何将其解析为“Dell”?

【问题讨论】:

【参考方案1】:

看起来“Dell”以 unicode 字符串的形式返回,(您可以通过每个字符之间的 \0 来判断)。所以你会使用。

System.Text.Encoding.Unicode.GetString(MfrBuffer)

至于缓冲区长度, the documentation for this function 说

嵌入字符串中的最大可能字符数是特定于设备的。对于 USB 设备,最大字符串长度为 126 个宽字符(不包括终止 NULL 字符)。

所以缓冲区的大小需要为(126+1) * 2 字节。

然后您可以使用TrimEnd("\0".ToCharArray()) 删除多余的尾随\0s

【讨论】:

太棒了。那么,对于不使用整个 126 个宽字符的设备,我该如何去掉所有的零呢? 看起来是这样做的... raw.TrimEnd("\0".ToCharArray());

以上是关于使用 hid.dll API 从 HID 设备读取制造商字符串时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

win 7系统,开机总是弹出C:\Windows\System32\HID.DLL没有被指定在Windows上运行,或者它包含错误

如何从 USB HID 设备读取输入?

如何在 Linux 上使用 Qt 读取 HID 设备 (/dev/hidrawX)?

从 GNU Octave 中与 USB HID 设备对话

在 Windows 应用商店应用中读取 HID 代理卡

UWP:从 HID 采集卡读取输入字节