SetupApi函数
+ -

使用SetupAPI禁用和开启设备

2022-01-24 378 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 。

0 篇笔记 写笔记

使用SetupAPI禁用和开启设备
无论开启或禁用,都需要调用SetupAPI中的两个函数: SetupDiSetClassInstallParams 和 SetupDiCallClassInstaller 前者用于设置类安装参数,后者用于调用类安装程序和任何注册过的协安装程序。BOOL SetupDiSetClassInstall......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!