我已经能够使用SetupAPI枚举USB设备,并且已经从WDK中查看了usbview应用程序,但我仍然无法弄清楚如何获取USB_DEVICE_DESCRIPTOR 。
我宁愿避免使用WMI。
DeviceIoControl是示例应用程序usbview使用的内容,但只有在枚举集线器上的设备时才有效。 我想,如果我可以得到设备path(或Id)的父集线器(和端口),这种方法可能会工作,但我还没有能够确定如何做到这一点。
我有我想要描述符的设备的混合。 其中一些是HID,可能有一些是WinUsb.sys设备。 如果他们是WinUsb设备我可以使用WinUsb_GetDescriptor ,但是这将不适用于HID(我不知道如何从ID或path…我接口类之间的区别)。
我可以使用SetupDiGetDeviceRegistryProperty,但在可用属性列表中,我可以看到制造商string,但不是供应商ID。
我可以从设备path或设备IDparsing这个值,但是这似乎有点…… hack-ish。 这只是人们的行为? 另外,如果我想要制造商这样的其他领域的话,还是会让我去其他的方法,如果我可以得到整个USB_DEVICE_DESCRIPTOR,我想我会有我需要的一切。
LibUsb.Net显然只支持WinUsb设备。 这似乎是如何得到描述符。
显然WinRT有一些新的API,因此Windows Store应用程序有一个很好的方式来获取描述符。 但是这绝对不是一个Windowsapp store的应用程序,我不知道有另一种方式来使用较新的API。
任何人都可以指向正确的方向吗? 是不是可以从一个很好的方式从WinAPI获取这些信息,而不需要在Hub上启动?
命令:rails console,生成不能识别。 错误:无法识别命令'rails'用法:rails COMMAND
在多个监视器上设置控制台窗口信息
clock(),gettickcount(),QueryPerformanceCounter()和QueryPerformanceFrequency()之间有什么区别?
检测目录是否在java中被修改
用于Windows的MySQL命令行客户端
你最好的选择是从设备路径中提取信息,并使用SetupDi函数获取其他的零碎。 据我所知,设备路径总是遵循相同的约定。 即:
“\? usb#vid_ 0000 &pid_ 1111 # SERIAL #{ GUID }”其中0000是VID,1111是PID作为十六进制字符串。 SERIAL是由硬件提供的串行或OS分配的串行值。
我个人发现一个实例,我绝对想要获取设备描述符,以便以这种方式获取序列。 在某些情况下,操作系统不能识别我的硬件提供的序列号。 我在硬件方面解决了这一问题,但我仍然希望在PC端适应旧的硬件。 以下是我的做法。 可能会有更好的,但这是迄今为止我所提出的最好的。 虽然你可能仍然认为它是“黑客”。
调用SetupDiGetClassDevs()来设置你想要的DeviceInfoSet
使用SetupDiEnumDeviceInfo()获取设备信息数据
使用SPDRP_LOCATION_informatION调用SetupDiGetDeviceRegistryProperty()以获取位置信息。 这个字符串应该看起来像“Port_#0001.Hub_#0001”。 解析此字符串以获取设备所在的端口号。 (我假设这个值是基数10,但是我还没有验证这个)
调用CM_Get_Parent()来获取父(集线器)的设备节点指针值
使用{0xf18a0e88,0xc30c,0x11d0,{0x88,0x15,0x00,0xa0,0xc9,0x06,0xbe,0xd8}的GUID调用SetupDiGetClassDevs()以获取系统上的所有集线器。 该GUID应该在usbiodef.h中定义为GUID_DEVINTERFACE_USB_HUB。
使用SetupDiEnumDeviceInfo()遍历设备列表。 一旦DevInst等于在步骤4中获得的值,停止。
调用步骤6中找到的索引SetupDiGetDeviceInterfaceDetail()。
在步骤7中获取的DevicePath上调用CreateFile()。
使用步骤8中创建的文件和步骤3中获取的端口号作为连接索引调用DeviceIoControl()。
-编辑-
正如Ben在注释中指出的那样,可以通过在步骤4中获得的父节点的开发节点上使用CM_Get_Device_ID来跳过第5,6和7步。将此字符串中的斜线()更改为磅(#)。 预先加上“\?”,然后附加“#{f18a0e88-c30c-11d0-8815-00a0c906bed8}”。 在步骤8中将其用作设备路径。这样可以避免遍历系统中的所有集线器设备:)