Jump to content

  • Log In with Google      Sign In   
  • Create Account

Obtain Device Information Set for Monitors: Returned Handle is always INVALID_HANDLE_VALUE


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 gretty   Members   -  Reputation: 212

Like
0Likes
Like

Posted 11 January 2013 - 06:09 PM

Hello

 

I am attempting to list the device information for all the monitors currently connected to the computer. I have a function that can do this and its 90% done except when I go to call the function SetupDiGetClassDevs() with the 2nd parameter set(not NULL) then the function always fails(returns INVALID_HANDLE_VALUE).

 

When I call GetLastError() I get the error 13(decimal), ie, "The data is invalid" which I am not sure what that means?

What is going wrong? Can you provide any advice on whats happening and how I can fix it?

Function Information:

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

 


My function that attempts to get a Device Information Set for Monitors only and output each monitors details(the error line is commented):

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

Edited by gretty, 11 January 2013 - 06:16 PM.


Sponsor:

#2 ApochPiQ   Moderators   -  Reputation: 15697

Like
0Likes
Like

Posted 11 January 2013 - 06:50 PM

The documentation is very clear. DIGCF_DEVICEINTERFACE is used only if you are providing a device instance ID, which you are not - you are providing an enumerator GUID.

Remove the flag.

#3 gretty   Members   -  Reputation: 212

Like
0Likes
Like

Posted 11 January 2013 - 07:01 PM

Thanks, removing that flag and using "PCI" as the enumerator works now. But I am not sure PCI is the correct enumator value I should be using?

 

If I want to obtain Device Information for all Monitors, what enumerator should I use? MSDN doesn't list all possible enumerator values.

 

So far I have tried "Monitor" and "{4d36e96e-e325-11ce-bfc1-08002be10318}" but that causes the same error "data is invalid"






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS