【问题标题】:How to get USB Device handle using device instance handle?如何使用设备实例句柄获取 USB 设备句柄?
【发布时间】:2014-01-21 13:05:11
【问题描述】:

我正在使用CM_Locate_DevNode()CM_Get_Child()CM_Get_DevNode_Registry_Property() API 枚举设备管理器树。我能够获取设备实例句柄。

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

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

【问题讨论】:

  • 您自己找到解决方案了吗?
  • 你在哪里 DenverCoder9?你看见什么了? xkcd.com/979
  • 也就是说,我也想要这个问题的答案。
  • @EdwardFalk 回答已添加 ;)

标签: windows winapi usb device-driver device-instance-id


【解决方案1】:

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

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

您的问题类似于this one

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

为了从设备获取 USB 字符串描述符,给定设备实例 ID,您需要:

  1. 使用CM_Get_Parent 获取其父级 USB 集线器
  2. 然后,使用我在下面提供的GetInterfaces 函数获取其 USB 集线器设备接口
  3. 然后,您可以在CreateFile中使用USB Device Interface作为Device Path,然后调用DeviceIoControl获取您想要的USB String Descriptor。

这个函数返回一个以 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;
}

【讨论】:

  • 不需要设备处理程序也不需要使用DeviceIoControl 来获取大部分字符串描述符,因为 Windows 会为其中的几个创建设备属性,这些属性可以通过 CM_* 和 DiSetup* API 读取.
  • 我实际上是使用它来获取 USB 设备描述符。我发现相同的功能可能有助于回答“设备实例 ID 到设备路径”这个简单问题并将其发布在这里 ;)
猜你喜欢
  • 2014-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多