Работает ли SetupDiGetClassDevs с идентификаторами экземпляров устройства, как описано в документации? - PullRequest
8 голосов
/ 05 июня 2009

Согласно документации MSDN, SetupDiGetClassDevs можно передать ИД экземпляра устройства , чтобы получить набор информации об устройстве для конкретного устройства:

Чтобы вернуть только определенное устройство, установите флаг DIFCF_DEVICEINTERFACE и использовать параметр Enumerator для предоставления идентификатор экземпляра устройства.

Я получаю идентификатор экземпляра устройства, анализируя символическое имя из сообщения WM_DEVICECHANGE DBT_DEVICEARRIVAL, и проверяю полученный идентификатор, сравнивая его с возвращенным от SetupDiGetDeviceInstanceId . Даже передача идентификатора экземпляра устройства, предоставленного операционной системой, не работает (т. Е. Происходит сбой вызова SetupDiGetClassDevs с ERROR_INVALID_PARAMETER).

Мой текущий обходной путь для извлечения структуры SP_DEVINFO_DATA для вновь прибывшего устройства заключается в перечислении всех устройств в одном классе и сравнении результата SetupDiGetDeviceInstanceId с символическим именем. Тем не менее, я не понимаю, почему это необходимо в соответствии с документацией ...

Кто-нибудь заставил SetupDiGetClassDevs работать таким образом? Есть ли лучший способ получения дополнительной информации для устройства, использующего данные в событии DBT_DEVICEARRIVAL?

Ответы [ 2 ]

9 голосов
/ 08 июня 2009

Кажется, вам нужно либо указать флаг DIGCF_ALLCLASSES, чтобы найти все классы, которые соответствуют заданному идентификатору экземпляра устройства, либо указать 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.
4 голосов
/ 29 декабря 2010

Кажется, вы неправильно понимаете DBT_DEVICEARRIVAL.

Существует несколько различных типов сообщений DBT_DEVICEARRIVAL - для тома, для дескриптора, для интерфейса устройства. Я предполагаю, что вы говорите о разновидности DBT_DEVTYP_DEVICEINTERFACE. В этом случае поле dbcc_name структуры DEV_BROADCAST_DEVICEINTERFACE будет содержать «путь интерфейса устройства».

«Путь к интерфейсу устройства» НЕ совпадает с «идентификатором экземпляра устройства».

Если вы хотите узнать больше информации об этом устройстве, вы должны перечислить все интерфейсы устройства по этому GUID интерфейса устройства (через SetupDiGetClassDevs с DIGCF_DEVICEINTERFACE) и сравнить dbcc_name со строками, полученными SetupDiEnumDeviceInterfaces .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...