windows - 如何枚举所有连接的 USB 设备的设备路径?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13927475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
windows - How to enumerate all connected USB devices' device path?
提问by Daniel
I'm trying to use the SetupDi functions to enumerate all connected USB devices' device path. The device path is the path used in CreateFile() so I can communicate with the device.
我正在尝试使用 SetupDi 函数来枚举所有连接的 USB 设备的设备路径。设备路径是 CreateFile() 中使用的路径,因此我可以与设备进行通信。
However, SetupDiGetDeviceInterfacerequires an interface GUID but I'm not specifically looking for a particular interface (other than all connected USBs). This part has been commented as /* ??? */ in the source below.
但是,SetupDiGetDeviceInterface需要一个接口 GUID,但我并没有专门寻找特定的接口(除了所有连接的 USB)。这部分已被注释为 /* ??? */ 在下面的源代码中。
Attempted Solutions:
尝试的解决方案:
I've tried to supply GUID_DEVCLASS_UNKNOWN = {0x4d36e97e, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; but this threw a "no more interfaces" error.
我试图提供 GUID_DEVCLASS_UNKNOWN = {0x4d36e97e, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; 但这引发了“不再有接口”的错误。
I've also tried to supply deviceInfoData.ClassGuid into SetupDiGetDeviceInterface but I get the same error as above, "no more interfaces".
我还尝试将 deviceInfoData.ClassGuid 提供到 SetupDiGetDeviceInterface 中,但出现与上述相同的错误,“没有更多接口”。
Questions:
问题:
Is there a general interface class which will cover all USB devices? (HID, generic, etc.)
是否有涵盖所有 USB 设备的通用接口类?(HID、通用等)
Or is there an alternate function which will give me the path to the device? (Instread of the SP_DEVICE_INTERFACE_DETAIL_DATA structure returned by SetupDiGetDeviceInterfaceDetail).
或者是否有替代功能可以为我提供设备的路径?(安装由 SetupDiGetDeviceInterfaceDetail 返回的 SP_DEVICE_INTERFACE_DETAIL_DATA 结构的插入)。
Source:
来源:
HDEVINFO deviceInfoList
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
DWORD requiredLength = 0;
char *hardwareID = 0;
// Retrieve a list of all present devices
deviceInfoList = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);
if (deviceInfoList == INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(deviceInfoList);
return false;
}
// Iterate over the list
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoList, i, &deviceInfoData); i++) {
if (deviceInterfaceDetailData) LocalFree(deviceInterfaceDetailData);
requiredLength = 0;
SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, &DataT, NULL, 0, &requiredLength);
if (requiredLength <= 0) {
SetupDiDestroyDeviceInfoList(deviceInfoList);
return false;
}
hardwareID = new char[requiredLength]();
SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)hardwareID, requiredLength, NULL);
// Parse hardwareID for vendor ID and product ID
delete hardwareID;
hardwareID = 0;
deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
// Requires an interface GUID, for which I have none to specify
if (!SetupDiEnumDeviceInterfaces(deviceInfoList, &deviceInfoData, /* ??? */, 0, &deviceInterfaceData)) {
SetupDiDestroyDeviceInfoList(deviceInfoList);
return false;
}
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInterfaceData, NULL, 0, &requiredLength, NULL)) {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && requiredLength > 0) {
deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);
if (!deviceInterfaceDetailData) {
SetupDiDestroyDeviceInfoList(deviceInfoList);
return false;
}
} else {
SetupDiDestroyDeviceInfoList(deviceInfoList);
return false;
}
}
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInterfaceData, deviceInterfaceDetailData, requiredLength, NULL, &deviceInfoData)) {
SetupDiDestroyDeviceInfoList(deviceInfoList);
return false;
}
SetupDiDestroyDeviceInfoList(deviceInfoList);
// deviceInterfaceDetailData->DevicePath yields the device path
}
回答by Michael
MSDNsays that there's a generic USB device interface class named GUID_DEVINTERFACE_USB_DEVICE
with the GUID {A5DCBF10-6530-11D2-901F-00C04FB951ED}
:
MSDN说有一个GUID_DEVINTERFACE_USB_DEVICE
用 GUID命名的通用 USB 设备接口类{A5DCBF10-6530-11D2-901F-00C04FB951ED}
:
The system-supplied USB hub driver registers instances of GUID_DEVINTERFACE_USB_DEVICE to notify the system and applications of the presence of USB devices that are attached to a USB hub.
系统提供的 USB 集线器驱动程序注册 GUID_DEVINTERFACE_USB_DEVICE 的实例,以通知系统和应用程序存在连接到 USB 集线器的 USB 设备。
Here's a code examplethat seems to do what you want to do, using the DEVINTERFACE_USB_DEVICE GUID.
这是一个代码示例,它似乎使用 DEVINTERFACE_USB_DEVICE GUID 执行您想做的事情。