I have following code that enumerates devices and write it description to console:
#include <windows.h>
#include <setupapi.h>
#include <stdio.h>
#include <tchar.h>
#ifdef DEBUG
#undef DBG
#define DBG 1
#endif
#if DBG
#define OOPS() Oops(__FILE__, __LINE__)
#else
#define OOPS()
#endif
#define ALLOC(dwBytes) GlobalAlloc(GPTR,(dwBytes))
#define REALLOC(hMem, dwBytes) GlobalReAlloc((hMem), (dwBytes), (GMEM_MOVEABLE|GMEM_ZEROINIT))
#define FREE(hMem) GlobalFree((hMem))
#define CHECKFORLEAKS()
_Success_(return == TRUE)
BOOL
GetDeviceProperty(
_In_ HDEVINFO DeviceInfoSet,
_In_ PSP_DEVINFO_DATA DeviceInfoData,
_In_ DWORD Property,
_Outptr_ LPTSTR *ppBuffer
)
{
BOOL bResult;
DWORD requiredLength = 0;
DWORD lastError;
if(ppBuffer == NULL)
{
return FALSE;
}
*ppBuffer = NULL;
bResult = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
DeviceInfoData,
Property,
NULL,
NULL,
0,
&requiredLength);
lastError = GetLastError();
if((requiredLength == 0) || (bResult != FALSE && lastError != ERROR_INSUFFICIENT_BUFFER))
{
return FALSE;
}
*ppBuffer = ALLOC(requiredLength);
if(*ppBuffer == NULL)
{
return FALSE;
}
bResult = SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
DeviceInfoData,
Property,
NULL,
(PBYTE)*ppBuffer,
requiredLength,
&requiredLength);
if(bResult == FALSE)
{
FREE(*ppBuffer);
*ppBuffer = NULL;
return FALSE;
}
return TRUE;
}
void
EnumerateAllDevices(
)
{
HDEVINFO deviceInfo = NULL;
// Getting all present devices
deviceInfo = SetupDiGetClassDevs(NULL,
NULL,
NULL,
(DIGCF_ALLCLASSES | DIGCF_PRESENT));
if(deviceInfo != INVALID_HANDLE_VALUE)
{
ULONG index;
DWORD error;
error = 0;
index = 0;
while(error != ERROR_NO_MORE_ITEMS)
{
BOOL success;
SP_DEVINFO_DATA infoData;
ZeroMemory(&infoData, sizeof(SP_DEVINFO_DATA));
PSTR DeviceDescName = NULL;
infoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
success = SetupDiEnumDeviceInfo(deviceInfo,
index,
&infoData);
index++;
if(success == FALSE)
{
error = GetLastError();
if(error != ERROR_NO_MORE_ITEMS)
{
//OOPS();
}
}
else
{
BOOL bResult;
bResult = GetDeviceProperty(deviceInfo,
&infoData,
SPDRP_DEVICEDESC,
&DeviceDescName);
if(bResult == FALSE)
{
//OOPS();
break;
}
printf("DeviceDescName = %s\n", DeviceDescName);
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
EnumerateAllDevices();
return 0;
}
DeviceDescName is PSTR as you can see from the code. For some reason this works perfect for one project type Windows driver application. Here I see full device name DeviceDescName like "High Definition Audio Controller".
The same code is not working for other Console Application. Toolset v120. Here in DeviceDescName I see only first latter "H"(from "High Definition Audio Controller"). What can be the reason? (you can try this)
It's because the driver project is compiled as UNICODE and PSTR points to a WCHAR * whereas your console application is not compiled as UNICODE and PSTR is rendered as a CHAR *.
You can try to compile your console application as UNICODE by tweaking the settings, but this may cause issues unless your code is carefully written and uses the right types - and it sounds like it doesn't.
An alternative is to use PWSTR for this code (and other similar instances), which will always be a wide character string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With