#includ" /> #includ" /> #includ"/>

A Windows program cannot obtain a SP_DEVINFO_DATA for a device

89 Views Asked by At

Now I have this non-working (minimum?) example:

#pragma comment (lib, "Setupapi.lib")
#pragma comment (lib, "newdev.lib")

#include <windows.h>
#include <newdev.h>
#include <setupapi.h>
#include <iostream>

int main() {
    GUID guid;
    HRESULT hResult =
        CLSIDFromString(
            L"{4d36e96b-e325-11ce-bfc1-08002be10318}",
            (LPCLSID) &guid);

    if (hResult == CO_E_CLASSSTRING) {
        std::cerr << "ERROR: Bad GUID string.\n";
        return EXIT_FAILURE;
    }

    HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(&guid, NULL);
                
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        std::cerr << "ERROR: Could not obtain HDEVINFO.\n";
        return EXIT_FAILURE;
    }

    SP_DEVINFO_DATA deviceInfoData;

    BOOL gotDeviceInfoData = SetupDiCreateDeviceInfoA(
        hDevInfo,
        "HID\\ASUE140D&COL04\\4&67A7B61&0&0003",
        &guid,
        NULL,
        NULL,
        0,
        &deviceInfoData);

    if (!gotDeviceInfoData) {
        std::cerr << "ERROR: Could not obtain SP_DEVINFO_DATA.\n";
        return EXIT_FAILURE;
    }

    BOOL removeStatus = 
        SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &deviceInfoData);   

    if (!removeStatus) {
        std::cerr << "ERROR: SetupDiCallClassInstaller failed. "
                  << "Could not remove the device.\n";

        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

My problem now is that I cannot successfully obtain a SP_DEVINFO_DATA from SetupDiCreateDeviceInfoA. (The program prints ERROR: Could not obtain SP_DEVINFO_DATA..)

What am I doing wrong here?

1

There are 1 best solutions below

0
coderodde On

After some research, I got this to work:

#pragma comment (lib, "Setupapi.lib")

#include <windows.h>
#include <setupapi.h>
#include <iostream>

int main() {
    GUID guid;
    HRESULT hResult =
        CLSIDFromString(
            L"{4d36e96b-e325-11ce-bfc1-08002be10318}",
            (LPCLSID) &guid);

    if (hResult == CO_E_CLASSSTRING) {
        std::cerr << "ERROR: Bad GUID string.\n";
        return EXIT_FAILURE;
    }

    HDEVINFO hDeviceInfo =
        SetupDiGetClassDevsExA(
            &guid,
            NULL,
            NULL,
            DIGCF_PRESENT,
            NULL,
            NULL,
            NULL);

    if (hDeviceInfo == INVALID_HANDLE_VALUE) {
        std::cerr << "ERROR: Could not obtain HDEVINFO.\n";
        return EXIT_FAILURE;
    }
    
    SP_DEVINFO_DATA deviceInfoData;
    deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    deviceInfoData.ClassGuid = guid;
    
    BOOL deviceEnumerated = 
        SetupDiEnumDeviceInfo(
            hDeviceInfo, 
            0,
            &deviceInfoData);

    if (!deviceEnumerated) {
        std::cerr << "ERROR: Could not enumerate the SP_DEVINFO_DATA.\n";
        return EXIT_FAILURE;
    }

    BOOL removeStatus =
        SetupDiCallClassInstaller(
            DIF_REMOVE,
            hDeviceInfo, 
            &deviceInfoData);

    if (!removeStatus) {
        std::cerr << "ERROR: Could not remove the device.\n";
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

However, it does the job only when the ASUS NumberPad is on and the program is run with administrator privileges.