Windows C++ :Enumeration USB child device

Introduction:

This blog is related to listing USB child device for particular parent (USB HUB).

I had some requirement in one of my project for this. So i thought of writing this. I’m using  SetupDixxxx APIs to implement this in C++.

Under USB HUB there could be list of device available. After getting device id of all children under USB HUB you can use them for different purpose.

Description:

Goal : List device id’s for particular USB HUB device.

For example:

You want  list of child device for USB HUB: USB\USBxx_HUB

#include <iostream>
#include <vector>
#include <windows.h>
#include <devguid.h>
#include <setupapi.h>
#include <tchar.h>
#include <devpkey.h>


#pragma comment (lib, "setupapi.lib")

void PrintUSBChildren(TCHAR *pChildrenList)
{
size_t iStrlen = 0;
TCHAR *child;
std::vector<TCHAR*> v_children;
TCHAR *ptr = pChildrenList;
_tprintf(_T("Printing children:\n"));
while (*ptr)
{
iStrlen = _tcsclen(ptr);
child = new TCHAR[iStrlen + 1];
if (child == NULL)
{
return;
}
ZeroMemory(child, iStrlen + 1);
_tcsncpy(child, ptr, iStrlen + 1);
v_children.push_back(child);
_tprintf(child);
_tprintf(_T("\n"));
delete[] child;
ptr += iStrlen + 1;
}
}


// List all USB devices with some additional information
void ListDevices(CONST GUID *pClassGuid, LPCTSTR pszEnumerator, TCHAR *pszCompatibleID)
{
_tprintf(_T("For Device %s \n"), pszCompatibleID);
unsigned i;
DWORD dwSize = 0;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
HRESULT hr = S_OK;
DEVPROPTYPE propType = 0;
PTCHAR pCompatibleID;
PTCHAR pChildrenID;
// List all connected USB devices
hDevInfo = SetupDiGetClassDevs(pClassGuid, pszEnumerator, NULL, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
return;
for (i = 0; ; i++) {
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
//To enumerate for all USB devices
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
break;
/*Get Compatible ID*/
// Get size to store compatible id (value stored in argument dwSize)
if (FALSE == SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_CompatibleIds, &propType, NULL, NULL, &dwSize, 0) && ERROR_INSUFFICIENT_BUFFER != GetLastError())
{//Continue enumeration until its getting compatibleid
hr = HRESULT_FROM_WIN32(GetLastError());
continue;
}
pCompatibleID = new TCHAR[dwSize];
if (NULL == pCompatibleID)
{
hr = E_OUTOFMEMORY;
}
//Store CompatibleID in pCompatibleID
if (FALSE == SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_CompatibleIds, &propType, (PBYTE)pCompatibleID, dwSize, &dwSize, 0))
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
/*Compare Compatible ID with user passed during API call*/
//If same then Get children detail for that USB device
if (_tcscmp(pCompatibleID, pszCompatibleID) == 0)
{
//Get buffer size to store All children info for USB device
if (FALSE == SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_Children, &propType, NULL, NULL, &dwSize, 0) && ERROR_INSUFFICIENT_BUFFER != GetLastError())
{
hr = HRESULT_FROM_WIN32(GetLastError());
continue;
}
pChildrenID = new TCHAR[dwSize];
if (NULL == pChildrenID)
{
hr = E_OUTOFMEMORY;
}
//Get
if (FALSE == SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_Children, &propType, (PBYTE)pChildrenID, dwSize, &dwSize, 0))
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
PrintUSBChildren(pChildrenID);
printf("\n");
delete[]pChildrenID;
}
delete[]pCompatibleID;
}
return;
}


int main()
{
ListDevices(&GUID_DEVCLASS_USB, NULL, _T("USB\\USBxx_HUB"));
return 0;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s