2009-06-05 9 views
8

Selon la documentation MSDN, SetupDiGetClassDevs peut être passé un device instance ID pour obtenir un device information set pour un dispositif spécifique:Est-ce que SetupDiGetClassDevs fonctionne avec les ID d'instance de périphérique comme documenté?

Pour revenir un périphérique spécifique, définissez le drapeau DIFCF_DEVICEINTERFACE et utiliser le paramètre recenseur pour fournir le ID d'instance de périphérique de l'unité.

je reçois l'instance de périphérique ID en analysant le nom symbolique de l'événement WM_DEVICECHANGE message DBT_DEVICEARRIVAL, et je l'ai vérifié l'ID résultant en le comparant à celui retourné de SetupDiGetDeviceInstanceId. Même le passage de l'ID d'instance de périphérique fourni par le système d'exploitation ne fonctionne pas (c'est-à-dire que l'appel SetupDiGetClassDevs échoue avec ERROR_INVALID_PARAMETER). Ma solution actuelle pour récupérer une structure SP_DEVINFO_DATA pour le périphérique nouvellement arrivé est d'énumérer tous les périphériques de la même classe et de comparer le résultat de SetupDiGetDeviceInstanceId au nom symbolique. Cependant, je ne vois pas pourquoi cela devrait être nécessaire selon la documentation ...

Quelqu'un at-il obtenu SetupDiGetClassDevs pour fonctionner de cette façon? Existe-t-il une meilleure méthode pour obtenir des informations supplémentaires pour un périphérique utilisant des données dans l'événement DBT_DEVICEARRIVAL?

Répondre

9

Il semble que vous deviez spécifier l'indicateur DIGCF_ALLCLASSES pour trouver toutes les classes correspondant à l'ID d'instance de périphérique donné, ou bien spécifier le ClassGuid et utiliser l'indicateur DIGCF_DEFAULT.

Cela a fonctionné pour moi:

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; 
} 

Avec sortie:

Match 
103: No more data is available. 
+0

Le DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES était la partie manquante pour moi. De la documentation de MSDN j'ai compris que seulement DIGCF_DEVICEINTERFACE était nécessaire, mais cela a donné l'erreur 87 (mauvais arguments). – angularsen

4

Il semble que vous êtes malentendu DBT_DEVICEARRIVAL.

Il existe différents types de messages DBT_DEVICEARRIVAL - pour un volume, pour un handle, pour une interface de périphérique. Je suppose que vous parlez de la variété DBT_DEVTYP_DEVICEINTERFACE. Dans ce cas, le champ dbcc_name de la structure DEV_BROADCAST_DEVICEINTERFACE contiendra le "chemin de l'interface du périphérique".

Le «chemin d'interface de périphérique» n'est PAS identique à un «ID d'instance de périphérique».

Si vous voulez en savoir plus d'informations sur cet appareil, vous devez énumérer tous les périphériques interfaces par ce GUID d'interface de périphérique (par SetupDiGetClassDevs avec DIGCF_DEVICEINTERFACE) et comparer les dbcc_name aux chaînes récupérées par SetupDiEnumDeviceInterfaces.