windows - Fungerer SetupDiGetClassDevs med enhedsinstans ID'er som dokumenteret?

Indlæg af Hanne Mølgaard Plasc

Problem



Ifølge MSDN-dokumentation kan SetupDiGetClassDevs videregives et enhedsinstans-id for at opnå en enhedsinformationssæt til en bestemt enhed: [14] [15] [16]



  For at returnere kun en bestemt enhed skal du indstille
  DIFCF\_DEVICEINTERFACE flag og brug
  Enumerator parameteren til at levere
  enhedens instans ID for enheden.



Jeg får enheds forekomst-id ved at analysere det symbolske navn fra WM\_DEVICECHANGE meddelelsen DBT\_DEVICEARRIVAL, og jeg har verificeret det resulterende ID ved at sammenligne det med det, der returneres fra SetupDiGetDeviceInstanceId. Selv om det operativsystem, der leveres med det operativsystem, der leveres, virker det ikke, at instans-ID'et virker (dvs. opkaldet SetupDiGetClassDevs mislykkes med ERROR\_INVALID\_PARAMETER. [17] [18] [19]


Min nuværende løsning for at hente en SP\_DEVINFO\_DATA struktur for den nyankomne enhed er at opregne alle enheder i samme klasse og sammenligne resultatet af SetupDiGetDeviceInstanceId med det symbolske navn. Jeg ser dog ikke, hvorfor det skulle være nødvendigt i henhold til dokumentationen ... [20]


Har nogen fået SetupDiGetClassDevs til at arbejde på denne måde? Er der en bedre metode til at få yderligere oplysninger om en enhed ved hjælp af data i DBT\_DEVICEARRIVAL-hændelsen?

Bedste reference


Det ser ud til, at du enten skal angive flaget DIGCF\_ALLCLASSES for at finde alle klasser, der matcher det givne enheds forekomst id, ellers angive ClassGuid og bruge flag DIGCF\_DEFAULT.


Dette fungerede for mig:


void error(DWORD err)
{
    WCHAR buf[0x200];
    FormatMessage(FORMAT\_MESSAGE\_FROM\_SYSTEM, NULL, err, 0, buf, 0x200, NULL);
    wprintf(L"\%x: \%s
", 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
");
    }

    error(GetLastError());

    SetupDiDestroyDeviceInfoList(hinfo);
    return 0;
}


Med output:


Match
103: No more data is available.

Andre referencer 1


Det ser ud som om du er misforståelse DBT\_DEVICEARRIVAL.


Der er et par forskellige typer af DBT\_DEVICEARRIVAL meddelelser - for et volumen, til et håndtag, til en enhedens grænseflade. Jeg 'gætter dig' taler om DBT\_DEVTYP\_DEVICEINTERFACE sorten. I dette tilfælde vil feltet dbcc\_name i strukturen DEV\_BROADCAST\_DEVICEINTERFACE indeholde 'enhedens grænsefladevej'.


'Device interface path' er IKKE den samme som en 'Device Instance ID'.


Hvis du vil vide mere om denne enhed, skal du opregne alle enheder grænseflader ved hjælp af denne enhedens grænseflade GUID (via SetupDiGetClassDevs med DIGCF\_DEVICEINTERFACE) og sammenligne dbcc\_name med de strenge, der hentes af SetupDiEnumDeviceInterfaces. .