How to enumerate hardware devices by using SetupDi calls

Summary

To get a list of installed hardware devices on Windows NT and later versions, applications can employ the SetupDi class of API functions.

More Information

The following code fragment demonstrates how to display a list of all installed hardware devices:

   #include <stdio.h>
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>

int main( int argc, char *argv[ ], char *envp[ ] )
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;

// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(NULL,
0, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );

if (hDevInfo == INVALID_HANDLE_VALUE)
{
// Insert error handling here.
return 1;
}

// Enumerate through all devices in Set.

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR buffer = NULL;
DWORD buffersize = 0;

//
// Call function with null to begin with,
// then use the returned buffer size (doubled)
// to Alloc the buffer. Keep calling until
// success or an unknown failure.
//
// Double the returned buffersize to correct
// for underlying legacy CM functions that
// return an incorrect buffersize value on
// DBCS/MBCS systems.
//
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_DEVICEDESC,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() ==
ERROR_INSUFFICIENT_BUFFER)
{
// Change the buffer size.
if (buffer) LocalFree(buffer);
// Double the size to avoid problems on
// W2k MBCS systems per KB 888609.
buffer = LocalAlloc(LPTR,buffersize * 2);
}
else
{
// Insert error handling here.
break;
}
}

printf("Result:[%s]\n",buffer);

if (buffer) LocalFree(buffer);
}


if ( GetLastError()!=NO_ERROR &&
GetLastError()!=ERROR_NO_MORE_ITEMS )
{
// Insert error handling here.
return 1;
}

// Cleanup
SetupDiDestroyDeviceInfoList(hDevInfo);

return 0;
}
Note The SetupDiGetDeviceRegistryProperty function returns an incorrect RequiredSize value on multibyte character sets (MBCS) systems that are running Microsoft Windows 2000. The sample code included in this article works around this issue by doubling the RequiredSize value.

The following code fragment demonstrates how to retrieve a set of all devices on the Peripheral Component Interconnect (PCI) bus.
    hDevInfo = SetupDiGetClassDevs(NULL,
REGSTR_KEY_PCIENUM, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );
Windows API functions that require a Device Instance Handle, such as the Config Manager set of API functions, can use the DevInst value in the structure SP_DEVINFO_DATA returned by the SetupDiEnumDeviceInfo function.

References

SetupDi API calls are documented in the Device Development Kit (DDK). For working sample code that demonstrates device enumeration, refer to the DevCon sample code in the DDK (src\setup\devcon).
Properties

Article ID: 259695 - Last Review: May 11, 2006 - Revision: 1

Feedback