windows下设备信息管理系列函数——用于设备枚举

(一)SetupDiGetClassDevs

链接:https://msdn.microsoft.com/en-us/library/windows/hardware/ff551069(v=vs.85).aspx


枚举设备信息SetupDiGetClassDevs:获取一个指定类别或全部类别的所有已安装设备的信息

HDEVINFO SetupDiGetClassDevs(

IN PGUID ClassGuid,

IN PCTSTR Enumerator,

IN HWND hwndParent,

IN DWORD Flags

);

参数说明:

ClassGuid:一个特定类别GUID(需要查询注册表)的指针;如果设置了DIGCF_ALLCLASSES标记,该参数备忽略,将返回所有类别的设备信息表

Enumerator:过滤枚举的内容:如:PCI则只显示PCI设备,

hwndParent:用于关联到集合成员中的用户接口的顶层窗口句柄

Flags:建立设备信息表的控制选项,可以是下列值

l  DIGCF_PRESENT:只列出当前存在的设备信息

l  DIGCF_ALLCLASSES:列出所有类别的一安装的设备表,如果设置了此值,则指定的类别将备忽略

l  DIGCF_PROFILE:只返回当前硬件概况部分

 

返回值:

如成功,返回包含所有与指定参数匹配的已经安装设备信息句柄

如失败则返回INVALID_HANDLE_VALUE


(二)SetupDiEnumDeviceInfo

链接:https://msdn.microsoft.com/en-us/library/windows/hardware/ff551010(v=vs.85).aspx

 SetupDiEnumDeviceInfo:枚举指定设备信息集合的成员,并将数据放在PSP_DEVINFO_DATA中

BOOLEAN SetupDiEnumDeviceInfo(

IN HDEVINFO DeviceInfoSet,

IN DWORD MemberIndex,

OUT PSP_DEVINFO_DATA DeviceInfoData

);

参数说明:

DeviceInfoSet:提供一个设备信息集合的句柄

MemberIndex:指定一个要取得的设备信息成员序号,从0开始

DeviceInfoData:指向SP_DEVINFO_DATA结构的指针,关于指定成员的返回信息就放在该结构中

返回值:

成功返回True,否则返回False)

 

使用说明:如果要枚举全部设备信息成员,装载者首先应该将MemberIndex设为0调用SetupDiEnumDeviceInfo,然后递增MemberIndex(使用一个for循环),调用SetupDiEnumDeviceInfo,直至所有成员全部遍历(此时函数返回False,并且GetLastError返回ERROR_NO_MORE_ITEMS


(三)SetupDiGetDeviceInstanceId

链接:https://msdn.microsoft.com/en-us/library/windows/hardware/ff551106(v=vs.85).aspx

The  SetupDiGetDeviceInstanceId  function retrieves the  device instance ID  that is associated with a device information element.


(四)SetupDiGetDeviceRegistryProperty

链接:https://msdn.microsoft.com/en-us/library/windows/hardware/ff551967(v=vs.85).aspx

SetupDiGetDeviceRegistryProperty:获得单个装置的详细资料

WINSETUPAPIBOOL WINAPI 
SetupDiGetDeviceRegistryProperty(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN DWORD Property,
OUT PDWORD PropertyRegDataType,OPTIONAL
OUT PBYTE PropertyBuffer,
IN DWORD PropertyBufferSize,
OUT PDWORD RequiredSize OPTIONAL
);

参数说明:

DeviceInfoSet:设备信息句柄

DeviceInfoData:SP_DEVINFO_DATA结构体,包含DeviceInfoSet 中的设备信息

Property:

取以下的值:

SPDRP_ADDRESS:查询设备的地址

SPDRP_BUSNUMBER:查询设备的bus号

SPDRP_BUSTYPEGUID:查询设备的GUID号

SPDRP_CAPABILITIES


(五)SetupDiDestroyDeviceInfoList

 链接:https://msdn.microsoft.com/en-us/library/windows/hardware/ff550996(v=vs.85).aspx


The SetupDiDestroyDeviceInfoList 销毁一个设备信息集合,并且释放所有关联的内存

BOOL SetupDiDestroyDeviceInfoList( HDEVINFO DeviceInfoSet );
Paremeter:

DeviceInfoSet

[in]要释放的设备信息句柄

ReturnValue:

成功返回非零,否则返回零


枚举实例

int CUsbVcpDev::FindDevices(void)
{
    HDEVINFO                            hDevInfo = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA                     spDevInfoData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA    DevDetail = NULL;
    int                                 DevCount = 0;
    int                                 Index;
    TCHAR                               szBuf[MAX_PATH];
    BOOL                                ok;
    QString                             strDevName;
    QString                             strFriendlyName;
    QString                             strDeviceDesc;
    QString                             strPid;
    QString                             strVid;
    QString                             strDevPath;
    QString                             strPortName;

    spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    m_strDevPath.clear();

    /*Format the pid and vid*/
    strVid.sprintf(("VID_%04X"), m_vid);
    strPid.sprintf(("PID_%04X"), m_pid);


    // GUID_DEVINTERFACE_USB_DEVICE
    GUID usb_guid = { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED }};


    /* Get Device Information for all present devices */
    hDevInfo = SetupDiGetClassDevs(&usb_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES/*|DIGCF_DEVICEINTERFACE*//*|DIGCF_ALLCLASSES*/);

    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        SetupDiDestroyDeviceInfoList(hDevInfo);
        return 0;
    }

    //A zero-based index into the list of interfaces in the device information set.
    //The caller should call this function first with MemberIndex set to zero to obtain
    //the first interface. Then, repeatedly increment MemberIndex and retrieve an
    //interface until this function fails and GetLastError returns ERROR_NO_MORE_ITEMS.

    Index = -1;

    /* Scan all Devices */
    while (1)
    {
        Index++;

        ok = SetupDiEnumDeviceInfo(hDevInfo, Index, &spDevInfoData);
        if (!ok)
        {
            break;
        }

        //get instanceID such as "USB\VID_0483&PID_5740\48EB81653230"
        ok = SetupDiGetDeviceInstanceId(
                 hDevInfo,
                 &spDevInfoData,
                 szBuf,
                 MAX_PATH,
                 NULL);
        if (!ok)
        {
            break;
        }

        strDevName = QString::fromWCharArray(szBuf);
        strDevName.toUpper();

        /*check the idProduct and idVendor are match or not*/
        if ((strDevName.indexOf(("USB")) != 0)
            || (strDevName.indexOf(strVid) != 4)
            || (strDevName.indexOf(strPid) != 13)
           )
        {
            /*not a usb device or pid & vid is not match*/
            continue;
        }

        /*get device name such as "STMicroelectronics Virtual COM Port"*/
        ok = SetupDiGetDeviceRegistryProperty(
                 hDevInfo,
                 &spDevInfoData,
                 SPDRP_DEVICEDESC,
                 NULL,
                 (PBYTE)szBuf,
                 MAX_PATH,
                 NULL);
        if (!ok)
        {
            break;
        }

        /*get device desc*/
        strDeviceDesc =  QString::fromWCharArray(szBuf);

        //get device friendly name such as "STMicroelectronics Virtual COM Port (COM13)"
        ok = SetupDiGetDeviceRegistryProperty(
                 hDevInfo,
                 &spDevInfoData,
                 SPDRP_FRIENDLYNAME,
                 NULL,
                 (PBYTE)szBuf,
                 MAX_PATH,
                 NULL);
        if (!ok)
        {
            break;
        }
        /*get device friendly name*/
        strFriendlyName = QString::fromWCharArray(szBuf);

        /*remove device descrition*/
        strPortName = strFriendlyName.right(strFriendlyName.length() - strDeviceDesc.length());

        /*the com name is between '(' and ')'*/
        int sIndex = strPortName.indexOf(("(")) + 1;
        int eIndex = strPortName.indexOf((")")) ;

        strPortName = strPortName.mid(sIndex, eIndex - sIndex);

        strDevPath =("\\\\.\\") + strPortName;


        m_strDevPath = strDevPath;
        m_strDeviceDesc = strFriendlyName;//strDeviceDesc;

        DevCount++;
    }



你可能感兴趣的:(windows编程)