Hello
Using native Win32 functions I am attempting to list all devices(Mouse, Keyboard, Printer, USB Storage, HDMI(TV/Projector) and etc.) connected to the computer. I am following this example and my code is pretty much exactly the same as the example.
My Problem: Whenever I call the function SetupDiEnumDeviceInfo() it always gives the error ERROR_NO_MORE_ITEMS. This is incorrect because it should find atleast some items such as my keyboard, mouse or usb storage device right?
What do you think is going wrong?
Below is the specific function that causing the error and line where the error occurs is pointed out below:
int EnumeratePortsNext(HANDLE DeviceInfoSet, LPTSTR lpBuffer)
{
static CM_Open_DevNode_KeyT OpenDevNodeKey = NULL;
static HINSTANCE CfgMan;
int res1, numport;
char DevName[MAX_NAME_PORTS] = {0};
static int numDev = 0;
SP_DEVINFO_DATA DeviceInfoData = {0};
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!DeviceInfoSet || !lpBuffer)
return -1;
if (!OpenDevNodeKey) {
CfgMan = LoadLibrary(_T("cfgmgr32"));
if (!CfgMan)
return -2;
OpenDevNodeKey = (CM_Open_DevNode_KeyT)GetProcAddress(CfgMan, (LPCSTR)"CM_Open_DevNode_Key");
if (!OpenDevNodeKey) {
FreeLibrary(CfgMan);
return -3;
}
}
while (TRUE) {
printf("Loop: \r\n");
HKEY KeyDevice;
DWORD len;
// ERROR OCCURS BELOW
res1 = SetupDiEnumDeviceInfo(DeviceInfoSet, numDev, &DeviceInfoData);
// ERROR OCCURS ABOVE
if (!res1)
{
// The error reported is always ERROR_NO_MORE_ITEMS
printf("err==ERROR_NO_MORE_ITEMS: %d\r\n", GetLastError()==ERROR_NO_MORE_ITEMS);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
FreeLibrary(CfgMan);
OpenDevNodeKey=NULL;
return -4;
}
res1=OpenDevNodeKey(DeviceInfoData.DevInst, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &KeyDevice, CM_REGISTRY_HARDWARE);
if(res1 != ERROR_SUCCESS)
return -5;
len=MAX_NAME_PORTS;
res1 = RegQueryValueEx(KeyDevice, _T("portname"), NULL, NULL, (BYTE*)DevName, &len);
RegCloseKey(KeyDevice);
if (res1 != ERROR_SUCCESS)
return -6;
numDev++;
if (memicmp(DevName, _T("com"), 3))
continue;
numport=atoi(DevName+3);
if (numport > 0 && numport <= 256) {
strcpy((char*)lpBuffer, DevName);
printf("DevName: %s\n", DevName);
return 1;
}
FreeLibrary(CfgMan);
OpenDevNodeKey=NULL;
return -7;
}
}
All code:
typedef DWORD (WINAPI* CM_Open_DevNode_KeyT)(DWORD, DWORD, DWORD, DWORD, ::PHKEY, DWORD);
HANDLE BeginEnumeratePorts(VOID)
{
BOOL guidTest = FALSE;
DWORD RequiredSize = 0;
HDEVINFO DeviceInfoSet;
char* buf;
int j;
guidTest = SetupDiClassGuidsFromNameA("Ports", 0, 0, &RequiredSize); printf("No Devices: %d\r\n", RequiredSize);
if (RequiredSize < 1) {
printf("Error 1\r\n");
return NULL;
}
buf = (char*)malloc(RequiredSize*sizeof(GUID));
guidTest = SetupDiClassGuidsFromNameA("Ports", (_GUID*)buf, RequiredSize*sizeof(GUID), &RequiredSize);
if (!guidTest) {
printf("Error 2\r\n");
return NULL;
}
DeviceInfoSet = SetupDiGetClassDevs((_GUID*)buf,NULL,NULL,DIGCF_PRESENT);
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
printf("Error 3\r\n");
return NULL;
}
free(buf);
return DeviceInfoSet;
}
int EnumeratePortsNext(HANDLE DeviceInfoSet, LPTSTR lpBuffer)
{
static CM_Open_DevNode_KeyT OpenDevNodeKey = NULL;
static HINSTANCE CfgMan;
int res1, numport;
char DevName[MAX_NAME_PORTS] = {0};
static int numDev = 0;
SP_DEVINFO_DATA DeviceInfoData = {0};
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!DeviceInfoSet || !lpBuffer)
return -1;
if (!OpenDevNodeKey) {
CfgMan = LoadLibrary(_T("cfgmgr32"));
if (!CfgMan)
return -2;
OpenDevNodeKey = (CM_Open_DevNode_KeyT)GetProcAddress(CfgMan, (LPCSTR)"CM_Open_DevNode_Key");
if (!OpenDevNodeKey) {
FreeLibrary(CfgMan);
return -3;
}
}
while (TRUE) {
printf("Loop: \r\n");
HKEY KeyDevice;
DWORD len;
// ERROR OCCURS BELOW
res1 = SetupDiEnumDeviceInfo(DeviceInfoSet, numDev, &DeviceInfoData);
// ERROR OCCURS ABOVE
if (!res1)
{
// The error reported is always ERROR_NO_MORE_ITEMS
printf("err==ERROR_NO_MORE_ITEMS: %d\r\n", GetLastError()==ERROR_NO_MORE_ITEMS);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
FreeLibrary(CfgMan);
OpenDevNodeKey=NULL;
return -4;
}
res1=OpenDevNodeKey(DeviceInfoData.DevInst, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &KeyDevice, CM_REGISTRY_HARDWARE);
if(res1 != ERROR_SUCCESS)
return -5;
len=MAX_NAME_PORTS;
res1 = RegQueryValueEx(KeyDevice, _T("portname"), NULL, NULL, (BYTE*)DevName, &len);
RegCloseKey(KeyDevice);
if (res1 != ERROR_SUCCESS)
return -6;
numDev++;
if (memicmp(DevName, _T("com"), 3))
continue;
numport=atoi(DevName+3);
if (numport > 0 && numport <= 256) {
strcpy((char*)lpBuffer, DevName);
printf("DevName: %s\n", DevName);
return 1;
}
FreeLibrary(CfgMan);
OpenDevNodeKey=NULL;
return -7;
}
}
// Usage
HANDLE h = BeginEnumeratePorts();
EnumeratePortsNext(h, (LPTSTR)lpBuffer);