Function to Get Device Information always returns ERROR_NO_MORE_ITEMS

Started by
0 comments, last by violentrevolution 11 years, 3 months ago

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

Advertisement

Checkout this MSDN thread --> http://social.msdn.microsoft.com/forums/en-US/windowsgeneraldevelopmentissues/thread/ea9babfb-ffe5-455f-8afe-016f8161c659

This should help solve your problem.

This topic is closed to new replies.

Advertisement