10

MSDN のドキュメントによると、SetupDiGetClassDevsにデバイス インスタンス IDを渡して、特定のデバイスのデバイス情報セットを取得できます。

特定のデバイスのみを返すには、DIFCF_DEVICEINTERFACE フラグを設定し、Enumerator パラメーターを使用してデバイスのデバイス インスタンス ID を指定します。

WM_DEVICECHANGEメッセージDBT_DEVICEARRIVALイベントからシンボリック名を解析してデバイス インスタンス ID を取得し、結果の ID をSetupDiGetDeviceInstanceIdから返された ID と比較して検証しました。OS 提供のデバイス インスタンス ID を渡しても機能しません (つまり、SetupDiGetClassDevs 呼び出しが で失敗しますERROR_INVALID_PARAMETER)。

新しく到着したデバイスの構造を取得するための現在の回避策SP_DEVINFO_DATAは、同じクラスのすべてのデバイスを列挙し、SetupDiGetDeviceInstanceId の結果をシンボリック名と比較することです。ただし、ドキュメントによると、なぜこれが必要なのかわかりません...

この方法で SetupDiGetClassDevs を動作させた人はいますか? DBT_DEVICEARRIVAL イベントのデータを使用してデバイスの詳細情報を取得するためのより良い方法はありますか?

4

2 に答える 2

12

指定さDIGCF_ALLCLASSESれたデバイス インスタンス ID に一致するすべてのクラスを見つけるためにフラグを指定するか、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.
于 2009-06-08T17:22:50.137 に答える
4

誤解しているようですDBT_DEVICEARRIVAL

DBT_DEVICEARRIVALボリューム用、ハンドル用、デバイス インターフェイス用など、いくつかの異なる種類のメッセージがあります。DBT_DEVTYP_DEVICEINTERFACE の種類について話していると思います。この場合、構造体のdbcc_nameフィールドにDEV_BROADCAST_DEVICEINTERFACEは「デバイス インターフェイス パス」が含まれます。

「デバイス インターフェイス パス」は「デバイス インスタンス ID」と同じではありません。

このデバイスに関する詳細情報を知りたい場合は、このデバイス インターフェイス GUID で (DIGCF_DEVICEINTERFACE を指定した SetupDiGetClassDevs を介して)すべてのデバイスインターフェイスSetupDiEnumDeviceInterfacesを列挙し、dbcc_name を によって取得された文字列と比較する必要があります。

于 2010-12-29T13:25:53.553 に答える