0

我正在尝试列出当前连接到计算机的所有显示器的设备信息。我有一个可以执行此操作的函数,并且完成了 90%,除非我SetupDiGetClassDevs()使用第二个参数集(非 NULL)调用该函数,然后该函数总是失败(返回 INVALID_HANDLE_VALUE)。

当我打电话时,GetLastError()我收到错误 13(十进制),即,"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

根据文档,Enumerator 必须设置为有效的设备实例 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 回答