According to MSDN documentation, SetupDiGetClassDevs can be passed a device instance ID to obtain a device information set for a specific device:
To return only a specific device, set the DIFCF_DEVICEINTERFACE flag and use the Enumerator parameter to supply the device instance ID of the device.
I get the device instance ID by parsing the symbolic name from the WM_DEVICECHANGE
message DBT_DEVICEARRIVAL
event, and I have verified the resulting ID by comparing it to that returned from SetupDiGetDeviceInstanceId. Even passing the OS supplied device instance ID does not work (i.e. the SetupDiGetClassDevs call fails with ERROR_INVALID_PARAMETER
).
My current workaround to fetch a SP_DEVINFO_DATA
structure for the newly arrived device is to enumerate all devices in the same class and compare the result of SetupDiGetDeviceInstanceId to the symbolic name. However, I don't see why this should be necessary according to the documentation...
Has anyone gotten SetupDiGetClassDevs to work in this way? Is there a better method for getting further information for a device using data in the DBT_DEVICEARRIVAL event?
It seems you have to either specify the DIGCF_ALLCLASSES
flag to find all classes that match the given device instance id, or else specify the ClassGuid and use the DIGCF_DEFAULT
flag.
This worked for me:
void error(DWORD err)
{
WCHAR buf[0x200];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, 0x200, NULL);
wprintf(L"%x: %s\n", err, buf);
}
int _tmain(int argc, _TCHAR* argv[])
{
PCWSTR devinst = L"HID\\VID_413C&PID_2105\\6&22CE0F66&0&0000";
HDEVINFO hinfo = SetupDiGetClassDevs(NULL, devinst, NULL, DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);
if (hinfo == INVALID_HANDLE_VALUE)
{
error(GetLastError());
return 1;
}
SP_DEVINFO_DATA dinfo;
dinfo.cbSize = sizeof(dinfo);
int ix = 0;
while (SetupDiEnumDeviceInfo(hinfo, ix++, &dinfo))
{
wprintf(L"Match\n");
}
error(GetLastError());
SetupDiDestroyDeviceInfoList(hinfo);
return 0;
}
With output:
Match
103: No more data is available.
It seems that you're misunderstanding DBT_DEVICEARRIVAL
.
There are a few different types of DBT_DEVICEARRIVAL
messages-- for a volume, for a handle, for a device interface. I'm guessing you're talking about the DBT_DEVTYP_DEVICEINTERFACE variety. In this case, the dbcc_name
field of the DEV_BROADCAST_DEVICEINTERFACE
structure will contain the "device interface path".
The "device interface path" is NOT the same as a "device instance ID".
If you want to know more information about this device, you should enumerate all device interfaces by this device interface GUID (through SetupDiGetClassDevs with DIGCF_DEVICEINTERFACE), and compare the dbcc_name to the strings retrieved by SetupDiEnumDeviceInterfaces
.
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