按照记录,SetupDiGetClassDevs 是否可以使用设备实例 ID?
-
12-09-2019 - |
题
根据 MSDN 文档, 设置DiGetClassDevs 可以通过一个 设备实例ID 获得一个 设备信息集 对于特定设备:
要仅返回特定设备,请设置DIFCF_DEVICEINTERFACE标志,然后使用枚举参数来提供设备的设备实例ID。
我通过解析符号名称来获取设备实例 ID WM_DEVICECHANGE
信息 DBT_DEVICEARRIVAL
事件,并且我通过将结果 ID 与从返回的 ID 进行比较来验证它 设置DiGetDeviceInstanceId. 。即使传递操作系统提供的设备实例 ID 也不起作用(即SetupDiGetClassDevs 调用失败并显示 ERROR_INVALID_PARAMETER
).
我当前的解决方法是获取 SP_DEVINFO_DATA
新到达的设备的结构是枚举同一类中的所有设备并将SetupDiGetDeviceInstanceId的结果与符号名称进行比较。但是,根据文档,我不明白为什么这是必要的......
有没有人让SetupDiGetClassDevs 以这种方式工作?是否有更好的方法使用 DBT_DEVICEARRIVAL 事件中的数据获取设备的更多信息?
解决方案
看来你必须要么指定DIGCF_ALLCLASSES
标志找到匹配给定设备实例ID的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT
标志。
这为我工作:
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;
}
使用输出:
Match
103: No more data is available.
其他提示
看来你误解DBT_DEVICEARRIVAL
。
有几种不同类型的DBT_DEVICEARRIVAL
messages--的一个体积,对于一个手柄,用于一设备接口。我猜你在谈论的DBT_DEVTYP_DEVICEINTERFACE品种。在这种情况下,dbcc_name
结构的DEV_BROADCAST_DEVICEINTERFACE
字段将包含“设备接口路径”。
在“设备接口路径”是不一样为“设备实例ID”。
如果您想了解该设备的详细信息,您应该枚举所有设备的接口此设备接口GUID(通过与DIGCF_DEVICEINTERFACE SetupDiGetClassDevs),并比较dbcc_name由SetupDiEnumDeviceInterfaces
检索到的字符串。