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

3

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

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

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


你自己找到解决方案了吗? - avgvstvs
2
你是谁,DenverCoder9?你看到了什么?https://xkcd.com/979/ - Edward Falk
1
换句话说,我也想知道这个问题的答案。 - Edward Falk
2
@EdwardFalk的回答已添加 ;) - gog
1个回答

1

设备实例句柄和设备句柄是相同的吗?还是有办法从设备实例句柄获取设备句柄?

不,它们不同。一个称为设备实例 ID,另一个称为设备路径。

您的问题类似于此问题

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

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

  1. 使用 CM_Get_Parent 获取其父 USB Hub
  2. 然后,使用下面提供的 GetInterfaces 函数获取其 USB Hub 设备接口
  3. 然后,您可以将 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;
}

不需要设备处理程序,也不需要使用 DeviceIoControl 获取大多数字符串描述符,因为Windows会为其中几个创建设备属性,可以通过CM_和DiSetup API读取它们。 - Ben Voigt
实际上,我用它来获取USB设备描述符。我发现相同的函数可能对回答“设备实例ID到设备路径”的简单问题有用,并在此处发布了它 ;) - gog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接