1. 程式人生 > >使用程式碼禁用裝置管理器裡面的滑鼠裝置

使用程式碼禁用裝置管理器裡面的滑鼠裝置

使用程式碼禁用裝置管理器裡面的滑鼠裝置

禁用一個裝置的方法有很多,但是能夠跟裝置管理器裡面狀態同步的方法並不多。 本文是使用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,
			&regType,
			(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,
			&regType,
			(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)
以下為程式碼執行效果: