windows SetupDiGetClassDevs 是否与记录的设备实例 ID 一起使用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/956669/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:35:43  来源:igfitidea点击:

Does SetupDiGetClassDevs work with device instance IDs as documented?

windowswinapidevicehardware-interfacesetupapi

提问by Judge Maygarden

According to MSDN documentation, SetupDiGetClassDevscan be passed a device instance IDto obtain a device information setfor a specific device:

根据 MSDN 文档,SetupDiGetClassDevs可以通过一个设备实例 ID来获取为特定设备设置设备信息

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.

要仅返回特定设备,请设置 DIFCF_DEVICEINTERFACE 标志并使用 Enumerator 参数提供设备的设备实例 ID。

I get the device instance ID by parsing the symbolic name from the WM_DEVICECHANGEmessage DBT_DEVICEARRIVALevent, 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).

我通过解析WM_DEVICECHANGE消息DBT_DEVICEARRIVAL事件中的符号名称来获取设备实例 ID ,并通过将其与从SetupDiGetDeviceInstanceId返回的 ID 进行比较来验证结果 ID 。即使传递操作系统提供的设备实例 ID 也不起作用(即 SetupDiGetClassDevs 调用失败并显示ERROR_INVALID_PARAMETER)。

My current workaround to fetch a SP_DEVINFO_DATAstructure 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...

我当前SP_DEVINFO_DATA为新到达的设备获取结构的解决方法是枚举同一类中的所有设备,并将 SetupDiGetDeviceInstanceId 的结果与符号名称进行比较。但是,我不明白为什么根据文档需要这样做......

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?

有没有人让 SetupDiGetClassDevs 以这种方式工作?是否有更好的方法使用 DBT_DEVICEARRIVAL 事件中的数据获取设备的更多信息?

回答by John Weldon

It seems you have to either specify the DIGCF_ALLCLASSESflag to find all classes that match the given device instance id, or else specify the ClassGuid and use the DIGCF_DEFAULTflag.

似乎您必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例 ID 匹配的所有类,或者指定 ClassGuid 并使用该DIGCF_DEFAULT标志。

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.

回答by Ilya

It seems that you're misunderstanding DBT_DEVICEARRIVAL.

看来你误会了DBT_DEVICEARRIVAL

There are a few different types of DBT_DEVICEARRIVALmessages-- 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_namefield of the DEV_BROADCAST_DEVICEINTERFACEstructure will contain the "device interface path".

有几种不同类型的DBT_DEVICEARRIVAL消息——用于卷、用于句柄、用于设备接口。我猜你说的是 DBT_DEVTYP_DEVICEINTERFACE 品种。在这种情况下,结构的dbcc_name字段DEV_BROADCAST_DEVICEINTERFACE将包含“设备接口路径”。

The "device interface path" is NOT the same as a "device instance ID".

“设备接口路径”与“设备实例 ID”不同。

If you want to know more information about this device, you should enumerate all device interfacesby this device interface GUID (through SetupDiGetClassDevs with DIGCF_DEVICEINTERFACE), and compare the dbcc_name to the strings retrieved by SetupDiEnumDeviceInterfaces.

如果您想了解有关此设备的更多信息,则应通过此设备接口 GUID(通过 SetupDiGetClassDevs 和 DIGCF_DEVICEINTERFACE)枚举所有设备接口,并将 dbcc_name 与检索到的字符串进行比较SetupDiEnumDeviceInterfaces