遍历设备管理器的两种方法: 连接/ 类型

1. 按照设备的连接去遍历设备管理器

int EnumDevs::ListByConnection(char *szXML)
{
    if (!szXML) return -1;

    CONFIGRET cr;
    DEVINST root;
    char *ACPI = _T("ROOT\\ACPI_HAL\\0000");

    XMLDocument doc;
    XMLElement *xml_root = doc.NewElement("DeviceTree");
    doc.InsertEndChild(xml_root);

    cr = CM_Locate_DevNode(&root, ACPI, 0);
    if (cr != CR_SUCCESS)
    {
        _tprintf(_T("[Error] CM_Locate_DevNode() failed, cr= 0x%lx\n"),cr);
        return 1;
    }

    cr = ListSubNodes(root, 0, doc, xml_root);
    if (cr != CR_SUCCESS)
        return 2;
    
    doc.SaveFile(szXML);
    return 0;

}
CONFIGRET EnumDevs::GetDeviceInfo(DEVINST DevInst, PDEVICE_INFO pDevInfo)
{
    CONFIGRET cr;
    ULONG ulSize;

    //description
    ulSize = sizeof(pDevInfo->szDevDescription);
    cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_FRIENDLYNAME, NULL, pDevInfo->szDevDescription, &ulSize, 0);
    if (cr != CR_SUCCESS)
    {
        ulSize = sizeof(pDevInfo->szDevDescription);
        cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_DEVICEDESC, NULL, pDevInfo->szDevDescription, &ulSize, 0);
        if (cr != CR_SUCCESS)
        {
            _tprintf(_T("[Error] CM_Get_DevNode_Registry_Property() failed,cr = 0x%lx\n"), cr);
            return cr;
        }
    }

    //class guid
    ulSize = sizeof(pDevInfo->szClassGUID);
    cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_CLASSGUID, NULL, pDevInfo->szClassGUID, &ulSize, 0);
    if (cr != CR_SUCCESS)
    {
        _tprintf(_T("[Error] CM_Get_DevNode_Registry_Property() failed,cr = 0x%lx\n"), cr);
        return cr;
    }

    //MFG
    ulSize = sizeof(pDevInfo->szManufacturer);
    cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_MFG, NULL, pDevInfo->szManufacturer, &ulSize, 0);
    if (cr != CR_SUCCESS)
    {
        _tprintf(_T("[Error] CM_Get_DevNode_Registry_Property() failed,cr = 0x%lx\n"), cr);
        return cr;
    }

    //HWID
    ulSize = sizeof(pDevInfo->szHWID);
    cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_HARDWAREID, NULL, pDevInfo->szHWID, &ulSize, 0);
    if (cr != CR_SUCCESS)
    {
        _tprintf(_T("[Error] CM_Get_DevNode_Registry_Property() failed,cr = 0x%lx\n"), cr);
        return cr;
    }

    //Class Name
    ulSize = sizeof(pDevInfo->szClassName);
    cr = CM_Get_DevNode_Registry_Property(DevInst, CM_DRP_HARDWAREID, NULL, pDevInfo->szClassName, &ulSize, 0);
    if (cr != CR_SUCCESS)
    {
        _tprintf(_T("[Error] CM_Get_DevNode_Registry_Property() failed,cr = 0x%lx\n"), cr);
        return cr;
    }

    //status 
    cr = CM_Get_DevNode_Status(&(pDevInfo->ulStatus), &(pDevInfo->ulProblemNumber), DevInst, 0);
    if (cr != CR_SUCCESS)
    {
        _tprintf(_T("[Error] CM_Get_DevNode_Status() failed,cr = 0x%lx\n"), cr);
        return cr;
    }

    return cr;
}
CONFIGRET EnumDevs::ListSubNodes(DEVINST parent, DWORD Level, XMLDocument &doc, XMLElement *elem)
{
    CONFIGRET cr;
    DEVINST child;
    
    cr = CM_Get_Child(&child, parent, 0);
    if (cr == CR_NO_SUCH_DEVINST)
        return CR_SUCCESS;
    else 
        if (cr != CR_SUCCESS)
        {
            _tprintf(_T("[Error] CM_Get_Child() failed, cr= 0x%lx\n"), cr);
            return cr;
        }

    do
    {
        
        DEVICE_INFO devInfo = { 0 };
        GetDeviceInfo(child, &devInfo);

        // 判断设备是隐藏设备还是要显示
        if (devInfo.ulStatus & DN_NO_SHOW_IN_DM)
            return CR_SUCCESS;

        XMLElement *child_elem = doc.NewElement("Device");

        child_elem->SetAttribute("Manufacturer", devInfo.szManufacturer);
        child_elem->SetAttribute("Description", devInfo.szDevDescription);
        child_elem->SetAttribute("HWID", devInfo.szHWID);
        child_elem->SetAttribute("ClassName", devInfo.szClassName);
        child_elem->SetAttribute("ClassGUID", devInfo.szClassGUID);

        char chTmp[MAX_PATH];
        ZeroMemory(chTmp, MAX_PATH);
        sprintf(chTmp, "%d", devInfo.ulStatus);
        child_elem->SetAttribute("Status", chTmp);

        ZeroMemory(chTmp, MAX_PATH);
        sprintf(chTmp, "%d", devInfo.ulProblemNumber);
        child_elem->SetAttribute("ProblemNumber", chTmp);

        child_elem->SetAttribute("Flags", "0");
    
        elem->InsertEndChild(child_elem);
        
        cr = ListSubNodes(child, Level + 1,doc,child_elem);
        if (cr != CR_SUCCESS)
            return cr;

        cr = CM_Get_Sibling(&child, child, 0);
        if (cr != CR_SUCCESS && cr != CR_NO_SUCH_DEVINST)
        {
            _tprintf(_T("[Error] CM_Get_Sibling() failed, cr=0x%lx\n"), cr);
            return cr;
        }
    } while (cr == CR_SUCCESS);
    
    return CR_SUCCESS;

}

2. 按照设备的类型去遍历设备管理器

void EnumDevs::ListByClass()
{
    GUID ClassGuid;
    TCHAR ClassName[MAX_CLASS_NAME_LEN];
    TCHAR PropertyBuffer[256];
    HKEY KeyClass;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    int i = 0, j;
    long Size;
    
    while (1)
    {
        CONFIGRET res;
        res = CM_Enumerate_Classes(i, &ClassGuid, 0);
        if (res == CR_NO_SUCH_VALUE)
            break;
        i++;
        ZeroMemory(ClassName, MAX_CLASS_NAME_LEN);
        if (!SetupDiClassNameFromGuid(&ClassGuid,ClassName,sizeof(ClassName) / sizeof(ClassName[0]),NULL))
        {
            _tprintf(_T("[Error] SetupDiClassNameFromGuid() failed with status 0x%lx\n"), GetLastError());
            continue;
        }

        /* Get class description */
        if (_tcscmp(ClassName, _T("")) == 0)
        {
            TCHAR ClassDescription[MAX_PATH];
            Size = sizeof(ClassDescription);
            ZeroMemory(ClassDescription, Size);

            KeyClass = SetupDiOpenClassRegKey(&ClassGuid, KEY_READ);
            if (KeyClass == INVALID_HANDLE_VALUE)
            {
                _tprintf(_T("[Error]SetupDiOpenClassRegKey() failed with status 0x%lx\n"), GetLastError());
                continue;
            }

            long rc = RegQueryValue(KeyClass, NULL, ClassDescription, &Size);
            if (rc == ERROR_SUCCESS)
            {
                _tcscat(ClassName, ClassDescription);
            }
            else
                _tprintf(_T("[Error] RegQueryValue() failed with status 0x%lx\n"), rc);

            RegCloseKey(KeyClass);
        }

        /* Enumerate devices in the class */
        hDevInfo = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT);
        if (hDevInfo == INVALID_HANDLE_VALUE)
            continue;

        DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
        SetupDiEnumDeviceInfo(hDevInfo, 0, &DeviceInfoData)? _tprintf(_T("- %s\n"), ClassName) : NULL;

        j = 0;
        while (1)
        {
            DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
            if (!SetupDiEnumDeviceInfo(hDevInfo,j,&DeviceInfoData))
            {
                break;
            }

            j++;

            if (SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_DEVICEDESC,NULL, (PBYTE)PropertyBuffer,sizeof(PropertyBuffer),NULL))
            {
                _tprintf(_T("    - %s\n"), PropertyBuffer);
            }
            else 
                if (SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInfoData,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,NULL,(PBYTE)PropertyBuffer,sizeof(PropertyBuffer),NULL))
                {
                    _tprintf(_T("    - %s\n"), PropertyBuffer);
                }
            else
                _tprintf(_T("[Error] SetupDiGetDeviceRegistryProperty() failed with status 0x%lx\n"), GetLastError());
         }

        SetupDiDestroyDeviceInfoList(hDevInfo);

    }
}

源码: https://download.csdn.net/download/cola8_jun/11037665

你可能感兴趣的:(C/C++)