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.
However, SetupDiGetDeviceInterface requires 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.
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.
I've also tried to supply deviceInfoData.ClassGuid into SetupDiGetDeviceInterface but I get the same error as above, "no more interfaces".
Questions:
Is there a general interface class which will cover all USB devices? (HID, generic, etc.)
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).
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
}
Use the Device Manager to determine if your computer has USB 1.1, 2.0, or 3.0 ports: Open the Device Manager. In the "Device Manager" window, click the + (plus sign) next to Universal Serial Bus controllers. You will see a list of the USB ports installed on your computer.
Finding the Device Path Parameters using Device ManagerOpen the properties for a USB device and click on the 'Details' tab. Select the 'Device Instance Path' property from the combo box to display the device instance path which shares the components of the device path used for CreateFile().
MSDN says that there's a generic USB device interface class named GUID_DEVINTERFACE_USB_DEVICE
with the GUID {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.
Here's a code example that seems to do what you want to do, using the DEVINTERFACE_USB_DEVICE GUID.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With