如何使用设备实例句柄获取USB设备句柄?

时间:2014-01-21 13:05:12

标签: windows winapi usb device-driver

我正在使用

枚举设备管理器树

CM_Locate_DevNode()CM_Get_Child()CM_Get_DevNode_Registry_Property() API。我能够获得设备实例句柄。

使用该句柄我试图获取设备句柄来查询设备的字符串描述符。

设备实例句柄和设备句柄是否相同,或者有没有办法从设备实例句柄获取设备句柄?

1 个答案:

答案 0 :(得分:1)

  

设备实例句柄和设备句柄是否相同,或者有什么方法可以从设备实例句柄获取设备句柄?

不,它们不一样。一个称为Device Instance ID,另一个称为设备路径。

您的问题类似于this one

  

使用该句柄,我试图获取设备句柄以查询设备的字符串描述符。

要从设备获取USB String描述符(给定其设备实例ID),您需要:

  1. 使用CM_Get_Parent
  2. 获取其父USB集线器
  3. 然后,使用我在下面提供的GetInterfaces函数获取其USB集线器设备接口
  4. 然后,您可以将USB设备接口用作CreateFile中的设备路径,然后调用DeviceIoControl以获取所需的USB字符串描述符。

此函数返回以NULL结尾的设备路径的列表(这是我们从CM_Get_Device_Interface_List获得的信息)

您需要向其传递设备实例ID,以及想要的接口GUID,对于USB HUB,它是

const GUID* ptrGUID = &GUID_DEVINTERFACE_USB_HUB;

由于同时指定了设备实例ID和接口GUID,CM_Get_Device_Interface_List很可能会为该接口返回一个设备路径,但是从技术上讲,您应该准备获得多个结果。

我在生产代码中成功使用了此功能的微小变化,以获取USB HUB(GUID_CLASS_USBHUB)的设备接口:我将生成的设备路径与CreateFile一起使用,并成功打开了它。

如果函数成功返回(返回码0),则调用方有责任delete[]返回列表

int GetInterfaces(const WCHAR* sysDeviceID, const LPGUID interfaceGUID, wchar_t**outIfaces, ULONG* outIfacesLen)
{
    CONFIGRET cres;
    if (!outIfaces)
        return -1;
    if (!outIfacesLen)
        return -2;

    // Get list size
    ULONG ifaceListSize = 0;
    cres = CM_Get_Device_Interface_List_Size(&ifaceListSize, interfaceGUID, sysDeviceID, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    if (cres != CR_SUCCESS)
        return -12;

    // Allocate memory for the list
    wchar_t* ifaceList = new wchar_t[ifaceListSize*2];    // Double the required size, in order minimize the chances of getting CR_BUFFER_SMALL errors

    // Populate the list
    cres = CM_Get_Device_Interface_List(interfaceGUID, sysDeviceID, ifaceList, ifaceListSize, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    if (cres != CR_SUCCESS) {
        delete[] ifaceList;
        return -13;
    }

    // Return list
    *outIfaces = ifaceList;
    *outIfacesLen = ifaceListSize;

    return 0;
}