Search code examples
c++windowswinapidevice

Windows Device Uninstall using C++


I need to programatically uninstall all Com port devices. The issue is that these Com Port Devices are not present and therefore completely hidden. Meaning, even if you want to uninstall them using device manager, first you have to add devmgr_show_nonpresent_devices = 1 to your environment variables and then show hidden devices in device manager. Then, you can right click each device and uninstall. I don't want to uninstall the associated driver though. I am adding that variable under advanced system settings, creating and saving a new user variable.

I try to do this with devcon. They can be found with devcon findall but I cannot remove them because the command to remove them fails stating no device has been uninstalled. Also, there is not flag to have it look for non-present devices. If I do a standard devcon find, no devices are found (of interest).

So, I am back to being forced to figure out how exactly to do this using my own code and here is where I get stuck. Here is what I have so far:

// Get all of the devices
PCTSTR enumType = "PORTS";
HDEVINFO devs = NULL;
devs = SetupDiGetClassDevs(NULL,enumType,0,DIGCF_PRESENT | DIGCF_ALLCLASSES);

// Loop through the devices
DWORD devCount = 0;
SP_DEVINFO_DATA devInfo;
int enumeratingDevices = 1;
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
while(enumeratingDevices){
    enumeratingDevices = SetupDiEnumDeviceInfo (devs,devCount,&devInfo);
    // Uninstall each device
    cout << SetupDiRemoveDevice(devs,&devInfo);
    cout << SetupDiCallClassInstaller(DIF_REMOVE,&devInfo,NULL);
    devCount++;
}
cout << devCount;
SetupDiDestroyDeviceInfoList(devs);
return 0;

Right now I am getting an output of 001. So, basically, SetupDiEnumDeviceInfo() orSetupDiRemoveDevice do not run correctly. I know that the enumeration is working because if I put in enumType = "USB"; I get ten for the devCount.

Any help or advice would be great.


Solution

  • So, I figured it out after a lot of tinkering and reading.

    // Get all of the devices
       //This enumeration does not work in general, instead passing
       //complete id of the device is probably best. 
       //It is helpful to know the vendor and device ID
    PCTSTR enumType = "PORTS"; 
    HDEVINFO devs = NULL;
    devs = SetupDiGetClassDevs(NULL,enumType,0,DIGCF_ALLCLASSES);
    
    // Loop through the devices
    DWORD devCount = 0;
    SP_DEVINFO_DATA devInfo;
    int enumeratingDevices = 1;
    /*This line is essential*/
    devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
    while(enumeratingDevices){
            enumeratingDevices = SetupDiEnumDeviceInfo (devs,devCount,&devInfo);
            // Uninstall each device
            if(enumeratingDevices){
               SetupDiRemoveDevice(devs,&devInfo);
               devCount++;
            }
    }
        //Clean up
    SetupDiDestroyDeviceInfoList(devs);
    

    I will update this tomorrow when I get to the lab with the exact enumeration I was talking about. However, with this method, you can uninstall virtually any device even if it is not present and just a "ghost" in the registry.