2009-06-05 7 views
8

Согласно MSDN документации, SetupDiGetClassDevs может быть принят device instance ID получить device information set для конкретного устройства:Работает ли SetupDiGetClassDevs с идентификаторами экземпляра устройства, как задокументировано?

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

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

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

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

ответ

9

Возможно, вам необходимо указать флаг 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. 
+0

DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES был недостающей частью для меня. Из документации MSDN я понял, что нужен только DIGCF_DEVICEINTERFACE, но это дало ошибку 87 (плохие аргументы). – angularsen

4

кажется, что вы недоразумение DBT_DEVICEARRIVAL.

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

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

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