Windows枚举系统设备及启用禁用功能

xingyun86 2021-6-30 935

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;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回