【问题标题】:How to know if a device has been explicitly been disabled by user?如何知道设备是否已被用户明确禁用?
【发布时间】:2018-04-28 07:41:33
【问题描述】:

使用设备管理器,用户可以显式启用/禁用设备,如下图所示。

对于给定的设备,我想知道它当前是否处于用户禁用/启用状态。

我尝试了以下方法

  1. CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); 我希望 DN_STARTED 或 DN_DRIVER_LOADED 的存在会告诉我这一点。但是,即使操作系统正在加载/卸载驱动程序,当设备连接/断开连接时,这些也可能为零。例如,启用并加载驱动程序的设备。 DN_STARTED 将是 1,但是当我们断开设备连接时,它会在设备条目从设备管理器中删除之前设置为零。
  2. SetupDiGetDeviceRegistryProperty(..., SPDRP_INSTALL_STATE, ...) 虽然CM_INSTALL_STATE_INSTALLED 的状态应该意味着设备已启用。但即使对于禁用的设备,该函数也会返回此状态。
  3. 使用 WMI 我能够获得所需的信息,但我在 PowerShell 中使用了 wmi。我不想使用 wmi,因为它很难在原生 c++ 中实现。我使用了以下查询。

    Select Name, Availability, ConfigManagerErrorCode, ConfigManagerUserConfig from Win32_PnPEntity where Name = 'NVIDIA Quadro M1000M'

上面查询中的ConfigManagerErrorCode,如果设置为22,表示设备已被禁用,21表示windows正在移除设备

我正在寻找非 wmi 解决方案。

【问题讨论】:

    标签: c++ wmi device-driver device-manager setupapi


    【解决方案1】:

    可以从设备的问题代码中获取信息。我可以找到两种方法来获得它。

    1. 使用SetupDiGetDeviceProperty()查询DEVPKEY_Device_ProblemCode。
    2. 使用CM_Get_DevNode_Status(),问题代码将出现在调用后的第二个参数中。

    问题代码 22 (CM_PROB_DISABLED) 表示该设备已被用户通过使用设备管理器或其他此类实用程序明确禁用。

    示例代码

    #include "stdafx.h"
    #include <Windows.h>
    #include <SetupAPI.h>
    #include <Cfgmgr32.h>
    #include <devguid.h>
    #include <initguid.h>
    #include "devpkey.h"
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0); //only getting for GPUs on the machine
    
        if (INVALID_HANDLE_VALUE != hDevInfo)
        {
            SP_DEVINFO_DATA data;
            data.cbSize = (DWORD)sizeof(data);
    
            for (unsigned int nIndex = 0; ::SetupDiEnumDeviceInfo(hDevInfo, nIndex, &data); nIndex++)
            {
                ULONG status = 0, problem = 0;
                CONFIGRET cr = ::CM_Get_DevNode_Status(&status, &problem, data.DevInst, 0); //after the call 'problem' variable will have the problem code
                if (CR_SUCCESS == cr)
                {
                    cout << " problem " << problem <<endl;
                    if(problem == CM_PROB_DISABLED)
                    { /*Do Something*/ }
    
                    DEVPROPTYPE propertyType;
                    const DWORD propertyBufferSize = 100;
                    BYTE propertyBuffer[propertyBufferSize];
                    std::fill(begin(propertyBuffer), end(propertyBuffer), BYTE(0));
                    DWORD requiredSize = 0;
    
                    if (SetupDiGetDeviceProperty(hDevInfo, &data, &DEVPKEY_Device_ProblemCode, &propertyType, propertyBuffer, propertyBufferSize, &requiredSize, 0)) //after the call 'propertyBuffer' will have error codes
                    {
                        unsigned long deviceProblemCode = *((unsigned long*)propertyBuffer);
                        cout << " deviceProblemCode " << deviceProblemCode << endl;
                    if(problem == CM_PROB_DISABLED)
                    { /*Do Something*/ }
    
                    }
                }
            }
        }
        return 0;
    }
    

    样本输出

    problem 0
    deviceProblemCode 0
    problem 22
    deviceProblemCode 22
    

    在问题中可以看到Intel(R) HD Graphics 530被启用,NVIDIA Quadro M1000M被禁用。因此,在输出中我们得到了一个问题代码 0 和一个问题代码 22 (CM_PROB_DISABLED)。

    【讨论】:

      猜你喜欢
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多