Reputation: 103
I'm enumerating device manager tree using the CM_Locate_DevNode()
, CM_Get_Child()
and CM_Get_DevNode_Registry_Property()
APIs. I'm able to get the device instance handle.
Using that handle I'm trying to get the device handle to query the string descriptor of the device.
Are both device instance handle and device handle same or is there any way to get the device handle from device instance handle?
Upvotes: 3
Views: 3690
Reputation: 1367
Are both device instance handle and device handle same or is there any way to get the device handle from device instance handle?
No, they are not the same. One is called Device Instance ID, and the other is called the Device Path.
Your question is similar to this one.
Using that handle I'm trying to get the device handle to query the string descriptor of the device.
In order to get a USB String descriptor from a device, given its Device Instance ID, you need to:
GetInterfaces
function I'm providing belowThis function returns a list of NULL-terminated Device Paths (that's what we get from CM_Get_Device_Interface_List
)
You need to pass it the Device Instance ID, and the wanted interface GUID
, which, for a USB HUB, is
const GUID* ptrGUID = &GUID_DEVINTERFACE_USB_HUB;
Since both the Device Instance ID and interface GUID are specified, it is highly likely that CM_Get_Device_Interface_List
will return a single Device Path for that interface, but technically you should be prepared to get more than one result.
I used a slight variation of this function successfully in production code for getting the Device Interface of a USB HUB (GUID_CLASS_USBHUB
): I used the resulting Device Path with CreateFile and opened it succesfully.
It is responsibility of the caller to delete[]
the returned list if the function returns successfully (return code 0)
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;
}
Upvotes: 1