使用SetupAPI禁用和开启设备
2022-01-24
473
0
无论开启或禁用,都需要调用SetupAPI中的两个函数: SetupDiSetClassInstallParams 和 SetupDiCallClassInstaller 前者用于设置类安装参数,后者用于调用类安装程序和任何注册过的协安装程序。
BOOL SetupDiSetClassInstallParams(
_In_ HDEVINFO DeviceInfoSet,
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData,
_In_opt_ PSP_CLASSINSTALL_HEADER ClassInstallParams,
_In_ DWORD ClassInstallParamsSize
);
SetupDiSetClassInstallParams 函数的核心在于第三个参数。
PSP_CLASSINSTALL_HEADER 是任何类安装参数(class install parameter)的第一个成员,里面主要内容是一个 DI_FUNCTION 类型的设备安装方法(DIF,Device Installation Function),且被定义为 DIF_XXX 的形式。
这里的 ClassInstallParams 要填入的也就是一个类安装参数的指针,当然它的第一个成员必须是 PSP_CLASSINSTALL_HEADER 。参数4的size指的是整个类安装参数的大小而不仅仅是 PSP_CLASSINSTALL_HEADER 的大小。
BOOL SetupDiCallClassInstaller(
_In_ DI_FUNCTION InstallFunction,
_In_ HDEVINFO DeviceInfoSet,
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
);
这是改变设备状态的代码,如下:
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("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("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("SetupDiSetClassInstallParams or SetupDiCallClassInstaller FAILED");
return TRUE;
}
else
{
//判断是否需要重新启动
devParams.cbSize = sizeof(devParams);
if (!SetupDiGetDeviceInstallParams( hDevInfo, &DevInfoData, &devParams))
{
OutputDebugString("SetupDiGetDeviceInstallParams FAILED");
return FALSE;
}
if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
{
OutputDebugString("Need Restart Computer");
return TRUE;
}
return TRUE;
}
}
这里的类安装参数为 SP_PROPCHANGE_PARAMS 结构体,其 StateChange 参数指定了状态改变的动作,有 DICS_ENABLE 、 DICS_DISABLE 、 DICS_PROPCHANGE 、 DICS_START 、 DICS_STOP 可选。
我们需要实现的禁用和开启,不过是将 PropChangeParams.StateChange 设为 DICS_DISABLE 和 DICS_ENABLE 。