设备实例句柄和设备句柄是否相同,或者有什么方法可以从设备实例句柄中获取设备句柄?
不,它们不一样。一个叫Device Instance ID,另一个叫设备路径。
您的问题类似于this one。
使用该句柄我试图获取设备句柄来查询设备的字符串描述符。
为了从设备获取 USB 字符串描述符,给定设备实例 ID,您需要:
- 使用CM_Get_Parent 获取其父级 USB 集线器
- 然后,使用我在下面提供的
GetInterfaces 函数获取其 USB 集线器设备接口
- 然后,您可以在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;
}