0

現在コンピューターに接続されているすべてのモニターのデバイス情報を一覧表示しようとしています。これを実行できる関数があり、その 90% は完了していますSetupDiGetClassDevs()が、2 番目のパラメーターを設定して (NULL ではない) 関数を呼び出すと、関数は常に失敗します (INVALID_HANDLE_VALUE を返します)。

呼び出すGetLastError()と、エラー 13(10 進数) が表示されます。つまり、"The data is invalid"これが何を意味するのかわかりません。

何がうまくいかないのですか?何が起こっているのか、どうすれば修正できるのか、アドバイスをいただけますか?

機能情報:

HDEVINFO SetupDiGetClassDevs(
  _In_opt_  const GUID *ClassGuid,
  _In_opt_  PCTSTR Enumerator,     // According to MSDN this param MUST be set if I want Device Information for a specific class(Monitors)
  _In_opt_  HWND hwndParent,
  _In_      DWORD Flags
);

モニターのみのデバイス情報セットを取得し、各モニターの詳細を出力しようとする私の関数 (エラー行はコメント化されています):

void printDeviceData(GUID guID)
{
    // Device Classes:        http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426
    // System Device Classes: http://msdn.microsoft.com/en-us/library/windows/hardware/ff553428
    // Monitor Class GUI:     {4d36e96e-e325-11ce-bfc1-08002be10318}

    DWORD dataT                    = 0;
    PCTSTR monitorGuID             = _T("");
    SP_DEVINFO_DATA deviceInfoData = {0};
    deviceInfoData.cbSize          = sizeof(SP_DEVINFO_DATA);
    deviceInfoData.ClassGuid       = guID;

    // Step 1: Get Device Information Set for Monitors only
    // ERROR OCCURS HERE: SetupDiGetClassDevs() always fails
    // Also tried these values for param 2: "Monitor" "PCI" but all cause the function to return INVALID_HANDLE_VALUE
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&guID, _T("{4d36e96e-e325-11ce-bfc1-08002be10318}"), NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        //outputLastError(_T("Fail 1"));
        printf("hDevInfo == INVALID_HANDLE_VALUE\n");
        return;
    }
    else printf("SUCCESS 1\n");

    if (SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE) {
        //outputLastError(_T("SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE"));
        printf("SetupDiGetSelectedDevice(hDevInfo, &deviceInfoData) == FALSE, %d, %x\n", GetLastError(), GetLastError());
        return;
    }
    else printf("SUCCESS 2\n");

    // Step 2: For each Monitor: Output Device information
    const unsigned int FLAG_NUM = 30;
    DWORD flags[] = {SPDRP_FRIENDLYNAME, SPDRP_ENUMERATOR_NAME, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, SPDRP_DEVICEDESC,
                        SPDRP_ADDRESS, SPDRP_BUSNUMBER, SPDRP_BUSTYPEGUID, SPDRP_CHARACTERISTICS, SPDRP_CLASS, SPDRP_CLASSGUID,
                        SPDRP_COMPATIBLEIDS, SPDRP_CONFIGFLAGS, SPDRP_DEVICE_POWER_DATA, SPDRP_DEVTYPE, SPDRP_DRIVER,
                        SPDRP_ENUMERATOR_NAME, SPDRP_EXCLUSIVE, SPDRP_HARDWAREID, SPDRP_INSTALL_STATE, SPDRP_LEGACYBUSTYPE,
                        SPDRP_LOCATION_INFORMATION, SPDRP_LOCATION_PATHS, SPDRP_LOWERFILTERS, SPDRP_MFG, 
                        SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, SPDRP_UI_NUMBER, SPDRP_UI_NUMBER_DESC_FORMAT, SPDRP_UPPERFILTERS, 
                        SPDRP_SECURITY_SDS, SPDRP_SECURITY, SPDRP_SERVICE };

    for (int i=0; i<=FLAG_NUM; i++) {
        DWORD buffersize = 0;
        LPTSTR buffer    = NULL;

        while (!SetupDiGetDeviceRegistryProperty(hDevInfo,  &deviceInfoData, flags[i], &dataT,
                                                    (PBYTE)buffer, buffersize, &buffersize))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                // Change the buffer size.
                if (buffer) 
                    LocalFree(buffer);
                buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);
            }
            else {
                // Insert error handling here.
                break;
            }
        }

        printf("Data: %d: %s\n", i, buffer);
        if (buffer) 
            LocalFree(buffer);
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
}
4

1 に答える 1

0

ドキュメントによると、列挙子は有効なデバイスインスタンスIDに設定する必要があり、 http://msdn.microsoft.com/en-us/library/windows/hardware/ff541327に従って次のように指定する必要があります。

"PCI \ VEN_1000&DEV_0001&SUBSYS_00000000&REV_02 \ 1&08"

私はそれをテストしていませんが、それが無効なデータの出所だと思います。

于 2013-01-12T00:32:44.700 に答える