Sign in to follow this  
gretty

Function to Get Device Information always returns ERROR_NO_MORE_ITEMS

Recommended Posts

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);

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this