使用代码禁用设备管理器里面的鼠标设备
禁用一个设备的方法有很多,但是能够跟设备管理器里面状态同步的方法并不多。
本文是使用SetupDi 系列API来实现的,有点老生常谈了~
整体套路就是:
使用SetupDiGetClassDevs 返回一类设备信息集
使用SetupDiEnumDeviceInfo便利设备信息集
使用SetupDiGetDeviceRegistryProperty获取设备信息,从而判断是不是你想要的设备
最后使用SetupDiChangeState来改变设备的Enable/Disable状态
这种操作的前提是设备管理器里面这个设备支持启用禁用。
从本质上讲就要要这个设备的驱动程序支持IRP_MJ_PNP 的子功能代码 IRP_MN_STOP_DEVICE等。
另外需要注意的一点就是 SetupDiGetClassDevs的时候不要设置DIGCF_PRESENT flag,不然被禁用的设备是搜索不到的。
最后需要注意的是:SetupDiChangeState 需要用管理员权限才能保证执行成功。
以下是大致代码:
extern "C" {
#include "hidsdi.h"
#include <setupapi.h>
}
#pragma comment(lib,"setupapi.lib")
#pragma comment(lib,"hid.lib")
#pragma comment(lib,"Wtsapi32.lib")
DWORD ControlMouseDevice(BOOL bEnable)
{
GUID HidGuid;
HANDLE hDevInfo;
SP_DEVINFO_DATA spdevInfoData;
HidD_GetHidGuid(&HidGuid);
hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PROFILE | DIGCF_DEVICEINTERFACE);
if (INVALID_HANDLE_VALUE == hDevInfo)
{
return -1;
}
spdevInfoData.cbSize = sizeof(spdevInfoData);
int idx;
SP_PROPCHANGE_PARAMS params = { sizeof(SP_CLASSINSTALL_HEADER) };
params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
params.Scope = DICS_FLAG_CONFIGSPECIFIC;
if (bEnable)
{
params.StateChange = DICS_ENABLE;
}
else
{
params.StateChange = DICS_DISABLE;
}
params.HwProfile = 0;
for (idx = 0;SetupDiEnumDeviceInfo(hDevInfo, idx, &spdevInfoData);
idx++)
{
LPTSTR buffer = NULL;
DWORD buffersize = 0;
//ULONG len;
//step1 get the buffer size
DWORD regType;
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spdevInfoData,
SPDRP_HARDWAREID,
®Type,
(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;
}
}
OutputDebugString(buffer);
//step2 get the information
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spdevInfoData,
SPDRP_DEVICEDESC,
®Type,
(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;
}
}
OutputDebugString(buffer);
CString strDeviceRegistryProperty(buffer);
strDeviceRegistryProperty.MakeUpper();
if (strDeviceRegistryProperty.Find(_T("MOUSE")) != -1)
{
SetupDiSetClassInstallParams(hDevInfo, &spdevInfoData, (SP_CLASSINSTALL_HEADER*)¶ms, sizeof(SP_PROPCHANGE_PARAMS));
BOOL bret = SetupDiChangeState(hDevInfo, &spdevInfoData);
if (!bret)
{
DWORD dwerror = GetLastError();
CString str;
str.Format(_T("GetLastError() == %d"), dwerror);
}
}
}
if (!SetupDiDestroyDeviceInfoList(hDevInfo))
{
DWORD dwerror = GetLastError();
CString str;
str.Format(_T("GetLastError() == %d"), dwerror);
}
return 0;
}
这里面只对设备描述里面提到是鼠标的设备进行了操作
if (strDeviceRegistryProperty.Find(_T("MOUSE")) != -1)
以下为代码执行效果: