By coming back home this WE I went to a problem concerning a steam video game : I got regular lags, and by searching the web I found that this came from some control devices, as my WE keyboard.
The solution is to deactivate some HID devices in the device manager (human interface devices section) with the standard right-click => disable operation. So I started to code a small utility to disable these devices while launching the game, and re-enable them after exiting.
Using SetupDI API functions, I managed to isolate the devices I wanted to disable, but when I disable them by applying the DICS_DISABLE operation, instead of acting as if I disabled them with the right mouse button method, the devices become "unkown devices" in the device manager. I have to update the devices's drivers to get them back in the device manager. I also tried the DICS_STOP operation, but with this one the devices simply disappear from the DM...
Is there something I am missing in this operation ?
Here is my prototype code : (console application, x64) => the system is x64, and if my application is 32 bits, all device operations simply fail.
#include <stdio.h>
#include <Windows.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
#pragma comment (lib, "Newdev.lib")
#pragma comment (lib, "Setupapi.lib")
int main(int argc, void * argv[])
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;
SP_PROPCHANGE_PARAMS params; // params to set in order to enable/disable the device
// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(NULL,
0, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );
if (hDevInfo == INVALID_HANDLE_VALUE)
{
// Insert error handling here.
return 1;
}
// Enumerate through all devices in Set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR buffer = NULL;
LPTSTR servBuffer = NULL;
DWORD buffersize = 0;
DWORD servBufferSize = 0;
//
// Call function with null to begin with,
// then use the returned buffer size (doubled)
// to Alloc the buffer. Keep calling until
// success or an unknown failure.
//
// Double the returned buffersize to correct
// for underlying legacy CM functions that
// return an incorrect buffersize value on
// DBCS/MBCS systems.
//
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_DEVICEDESC,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
{
// Change the buffer size.
if (buffer) LocalFree(buffer);
// Double the size to avoid problems on
// W2k MBCS systems per KB 888609.
buffer = (LPTSTR)LocalAlloc(LPTR,buffersize * 2);
}
else
{
// Insert error handling here.
break;
}
}
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_SERVICE,
&DataT,
(PBYTE)servBuffer,
servBufferSize,
&servBufferSize))
{
if (GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
{
// Change the buffer size.
if (servBuffer) LocalFree(servBuffer);
// Double the size to avoid problems on
// W2k MBCS systems per KB 888609.
servBuffer = (LPTSTR)LocalAlloc(LPTR,servBufferSize * 2);
}
else
{
// Insert error handling here.
break;
}
}
if (strstr((char *)buffer, "(HID)") && NULL == servBuffer)
{
printf("New device found : %s\n", buffer);
printf("disabling...\n");
// init the structure
params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
params.HwProfile = 0;
params.Scope = DICS_FLAG_CONFIGSPECIFIC;
params.StateChange = DICS_DISABLE;
// prepare operation
if (!SetupDiSetClassInstallParams(hDevInfo, &DeviceInfoData, ¶ms.ClassInstallHeader, sizeof(params)))
{
printf("Error while preparing params !\n");
break;
}
// launch op
if (!SetupDiCallClassInstaller(DICS_DISABLE, hDevInfo, &DeviceInfoData))
{
printf("Error while calling OP ! Return code is %x\n", GetLastError());
continue;
}
printf("done.\n\n");
}
if (buffer) LocalFree(buffer);
}
if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS )
{
// Insert error handling here.
return 1;
}
// Cleanup
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0;
}
Open Start on Windows 10. Search for Device Manager and click the top result to open the app. Expand the branch with the driver you want to disable. Right-click the device and select the Disable device option.
Type the desired command - /disable to disable a device , /enable to enable a device , /disable_enable to disable and the enable again the specified device , and /uninstall to uninstall a device.
Windows enables all devices it recognizes. Once disabled, Windows will no longer assign system resources to the device and no software on your computer will be able to use it.
You have the parameter wrong, you need
SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData)
with a filled SP_PROPCHANGE_PARAMS
in DeviceInfoData
.
See this for example. (it's in Chinese, just read the code is enough)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With