Windows枚举系统设备及启用禁用功能
#include <iostream>
#if !defined(_UNICODE)&&!defined(UNICODE)
#define TCOUT std::cout
#define TSTRING std::string
#define TO_TSTRING(T) std::string(T)
#define TMAIN main
#else
#define TCOUT std::wcout
#define TSTRING std::wstring
#define TO_TSTRING(T) std::wstring(T)
#define TMAIN wmain
#endif
#include <windows.h>
#include <SetupAPI.h>
#include <cfgmgr32.h> // cfgmgr32.h 在Microsoft Windows 2000 DDK 中.
#pragma comment(lib,"setupapi.lib")
BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo);
BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo);
BOOL StateChange(DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo);
//////////////////////////////////////////////////////////////////////////
// 获得设备注册表中的内容
//////////////////////////////////////////////////////////////////////////
BOOL GetRegistryProperty(HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
ULONG Property,
PVOID Buffer,
PULONG Length)
{
while (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
DeviceInfoData,
Property,
NULL,
(BYTE*)*(TCHAR**)Buffer,
*Length,
Length))
{
// 长度不够则重新分配缓冲区
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (*(LPTSTR*)Buffer)
LocalFree(*(LPTSTR*)Buffer);
*(LPTSTR*)Buffer = (TCHAR*)LocalAlloc(LPTR, (*Length)*sizeof(TCHAR));
}
else
{
return false;
}
}
return (BOOL)(*(LPTSTR*)Buffer)[0];
}
BOOL EnableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
return StateChange(DICS_ENABLE, dwDevID, hDevInfo);
}
BOOL DisableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
return StateChange(DICS_DISABLE, dwDevID, hDevInfo);
}
BOOL ControlDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
BOOL bCanDisable;
bCanDisable = (IsDisableable(dwDevID, hDevInfo) && (!IsDisabled(dwDevID, hDevInfo)));
if (bCanDisable)
return DisableDevice(dwDevID, hDevInfo);
else
return EnableDevice(dwDevID, hDevInfo);
}
void EnumSystemDevs()
{
DWORD Status, Problem;
LPTSTR Buffer = NULL;
DWORD BufSize = 0;
// 返回所有设备信息
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (INVALID_HANDLE_VALUE == hDevInfo)
return;
SP_DEVINFO_DATA DeviceInfoData = { sizeof(SP_DEVINFO_DATA) };
//////////////////////////////////////////////////////////////////////////
// 枚举设备
//////////////////////////////////////////////////////////////////////////
for (DWORD DeviceId = 0;
SetupDiEnumDeviceInfo(hDevInfo, DeviceId, &DeviceInfoData);
DeviceId++)
{
// 获得设备的状态
if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst, 0) != CR_SUCCESS)
continue;
// 获取设备类名
TCHAR szDevName[MAX_PATH + MAX_PATH + MAX_PATH] = TEXT("");
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS, &Buffer, (PULONG)&BufSize))
{
memset(szDevName, 0, sizeof(szDevName));
lstrcpyn(szDevName, Buffer, BufSize);
}
TCOUT << szDevName << std::endl;
TCHAR szName[MAX_PATH + MAX_PATH + MAX_PATH] = TEXT("");
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME, &Buffer, (PULONG)&BufSize))
{
memset(szName, 0, sizeof(szName));
lstrcpyn(szName, Buffer, BufSize);
}
TCOUT << TEXT("--") << szName << std::endl;
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER, &Buffer, (PULONG)&BufSize))
{
memset(szName, 0, sizeof(szName));
lstrcpyn(szName, Buffer, BufSize);
TCOUT << TEXT("---") << szName << std::endl;
// 获取设备描述
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, &Buffer, (PULONG)&BufSize))
{
memset(szName, 0, sizeof(szName));
lstrcpyn(szName, Buffer, BufSize);
TCOUT << TEXT("----") << szName << std::endl;
/*if (ControlDevice(DeviceId, hDevInfo))
{
printf("Successful\n");
}
else
{
printf("FAILED\n");
}*/
}
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
BOOL StateChange(DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo)
{
SP_PROPCHANGE_PARAMS PropChangeParams;
SP_DEVINFO_DATA DevInfoData = { sizeof(SP_DEVINFO_DATA) };
SP_DEVINSTALL_PARAMS devParams;
//查询设备信息
if (!SetupDiEnumDeviceInfo(hDevInfo, dwDevID, &DevInfoData))
{
OutputDebugString(TEXT("SetupDiEnumDeviceInfo FAILED"));
return FALSE;
}
//设置设备属性变化参数
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL; //使修改的属性保存在所有的硬件属性文件
PropChangeParams.StateChange = dwNewState;
PropChangeParams.HwProfile = 0;
//改变设备属性
if (!SetupDiSetClassInstallParams(hDevInfo,
&DevInfoData,
(SP_CLASSINSTALL_HEADER*)&PropChangeParams,
sizeof(PropChangeParams)))
{
OutputDebugString(TEXT("SetupDiSetClassInstallParams FAILED"));
return FALSE;
}
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;//使修改的属性保存在指定的属性文件
PropChangeParams.StateChange = dwNewState;
PropChangeParams.HwProfile = 0;
//改变设备属性并调用安装服务
if (!SetupDiSetClassInstallParams(hDevInfo,
&DevInfoData,
(SP_CLASSINSTALL_HEADER*)&PropChangeParams,
sizeof(PropChangeParams)) ||
!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DevInfoData))
{
OutputDebugString(TEXT("SetupDiSetClassInstallParams or SetupDiCallClassInstaller FAILED"));
return TRUE;
}
else
{
//判断是否需要重新启动
devParams.cbSize = sizeof(devParams);
if (!SetupDiGetDeviceInstallParams(hDevInfo, &DevInfoData, &devParams))
{
OutputDebugString(TEXT("SetupDiGetDeviceInstallParams FAILED"));
return FALSE;
}
if (devParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))
{
OutputDebugString(TEXT("Need Restart Computer"));
return TRUE;
}
return TRUE;
}
}
BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo)
{
SP_DEVINFO_DATA DevInfoData = { sizeof(SP_DEVINFO_DATA) };
DWORD dwDevStatus, dwProblem;
if (!SetupDiEnumDeviceInfo(hDevInfo, dwDevID, &DevInfoData))
{
OutputDebugString(TEXT("SetupDiEnumDeviceInfo FAILED"));
return FALSE;
}
//查询设备状态
if (CM_Get_DevNode_Status(&dwDevStatus, &dwProblem, DevInfoData.DevInst, 0) != CR_SUCCESS)
{
OutputDebugString(TEXT("CM_GET_DevNode_Status FAILED"));
return FALSE;
}
return ((dwDevStatus & DN_DISABLEABLE) && (dwProblem != CM_PROB_HARDWARE_DISABLED));
}
BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo)
{
SP_DEVINFO_DATA DevInfoData = { sizeof(SP_DEVINFO_DATA) };
DWORD dwDevStatus, dwProblem;
if (!SetupDiEnumDeviceInfo(hDevInfo, dwDevID, &DevInfoData))
{
OutputDebugString(TEXT("SetupDiEnumDeviceInfo FAILED"));
return FALSE;
}
//查询设备状态
if (CM_Get_DevNode_Status(&dwDevStatus, &dwProblem, DevInfoData.DevInst, 0) != CR_SUCCESS)
{
OutputDebugString(TEXT("CM_GET_DevNode_Status FAILED"));
return FALSE;
}
return ((dwDevStatus & DN_HAS_PROBLEM) && (dwProblem == CM_PROB_DISABLED));
}
int TMAIN(int argc, TCHAR ** argv)
{
TCOUT.imbue(std::locale("chs"));//支持中文打印
TCOUT << TEXT("Hello World!") << std::endl;
EnumSystemDevs();
return 0;
}