none
Is it possible to enumerate a USB device ...... RRS feed

  • Question

  • hello..,

    I am doing a USB project in windows XP, in which i need to eject the any USB mass storage device which is plugged-in , for this i am using CM_Request_Device_Eject(). And it is working well.

    But when more than one device is plugged-in to the system, sometimes, there are cases that more than one device is getting the same deviceInstance, basing on which i am ejecting the device. Due to this the CM_Request_Device_Eject() is either ejecting the recently plugged-in device or ejecting the already ejected device by returning S_OK.

    To avoid this mismatch of the DeviceInstances, i want to enumerate the plugged-in devices for every minute.

    But when i do this, GetLastError() is returning NO_MORE_ITEMS.

    So, my doubt is..
    Is this possible to enumerate a USB device which is already enumerated and but neither closed or ejected.

    or

    Is this possible to enumerate a USB device which is under use. For more than once.

    And if it is not possible to do using setupapi. Is there anyother way to enumerate the USB devices more than once when they r being used.

    Thank you.
    Anupama

    Tuesday, September 12, 2006 8:34 AM

Answers

  • This kind of code always makes my brain hurt... The one thing that jumps out as "this can't be right" is your call to SetupDiDestroyDeviceInfoList().  You're doing this inside your enumeration loop, you should do it when you exit the loop.

    Also, rather than polling once a minute, I implemented a message handler for WM_DEVICECHANGE.  You can tell whether a device got removed or added from the WPARAM arg and you'll get the name of the device from the PDEV_BROADCAST_DEVICEINTERFACE pointer.
    Wednesday, September 13, 2006 12:55 PM
    Moderator

All replies

  • You're not saying how you are enumerating the USB devices, hard to say what might be wrong.  I've done it before by calling SetupDiGetClassDevs(), SetupDiEnumDeviceInterfaces() and SetupDiGetDeviceInterfaceDetail().  Be sure to get the class GUID right...
    Tuesday, September 12, 2006 6:34 PM
    Moderator
  • Hello nobugz...

    Thank you for ur response.  I am enumerating device using two cases..1) when USB device is plugged-in. and 2) After every minute, that is i am calling this function in  onTimer().

    1)On_Device_connected()
     {
       
       int nDevCount=0;
       DEVINST devInst=0;
     
       PDEV_BROADCAST_DEVICEINTERFACE pDevInf=GetPDevHdr(lp);

        //  get the device information ; Query For the Device Information.  
       
           // Retrieve a context structure for a device interface of a device
         //information set.
       
       
        DWORD dwIndex = 0;
        SP_DEVICE_INTERFACE_DATA devInterfaceData = {0};
        devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        BOOL bRet = FALSE;

        BYTE Buf[1024];
        PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
        SP_DEVICE_INTERFACE_DATA         spdid;
        SP_DEVINFO_DATA                  spdd;
        DWORD                            dwSize;
        DEVINST DevInst=0;
        long res;
       
        spdid.cbSize = sizeof(spdid);   
        while(true) //dwIndex<=nDeviceCount)
        {

            HDEVINFO hDevInfo     = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE,0,0,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);      

            if(hDevInfo== INVALID_HANDLE_VALUE) return 0; 
      
            bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID)&GUID_CLASS_USB_DEVICE, dwIndex, &devInterfaceData);
            if(!bRet)
                break;

            BOOL b=SetupDiEnumInterfaceDevice(hDevInfo, NULL,(LPGUID)&GUID_CLASS_USB_DEVICE, dwIndex, &spdid);

            dwSize = 0;
            SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL);
        
            if ( dwSize!=0 && dwSize<=sizeof(Buf) )
              {
                pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!

                ZeroMemory((PVOID)&spdd, sizeof(spdd));
                spdd.cbSize = sizeof(spdd);

                res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd);
                
                if(res)
                     {   
                     // the device instance id string contains the serial number if the
                    // device has one...
                    char szDevInstId[260] = {0};
                    SetupDiGetDeviceInstanceId(hDevInfo, &spdd, (PWSTR)szDevInstId, 260, NULL);
                    SetupDiDestroyDeviceInfoList(hDevInfo);
                    DevInst=spdd.DevInst;                               
                    }
                }
            dwIndex++;
         }
    }


    This function is called for every one minute.....
    Void EnumerateAllUSBDevicesForEveryMinute(){

        DEVINST DevInst=0;
        DWORD dwIndex=0;
        HDEVINFO hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE,0,/*Enumerator*/0,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);  // | DIGCF_ALLCLASSES);      

        if(hDevInfo!= INVALID_HANDLE_VALUE){   
        //for(long dwIndex=0;dwIndex<=nDeviceConnected /*nDeviceCount*/;dwIndex++)   
        while(true)//GetLastError ()> ERROR_NO_MORE_ITEMS)
         {
            BYTE Buf[1024];
            SP_DEVICE_INTERFACE_DATA devInterfaceData = {0};
            devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
            BOOL bRet = FALSE;
            SP_DEVICE_INTERFACE_DATA         spdid;
            SP_DEVINFO_DATA                  spdd;
            DWORD                            dwSize;
            PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
            long res;

            bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, (LPGUID)&GUID_CLASS_USB_DEVICE, dwIndex, &devInterfaceData);
            if(!bRet)break;
            BOOL b=SetupDiEnumInterfaceDevice(hDevInfo, NULL,(LPGUID)&GUID_CLASS_USB_DEVICE, dwIndex, &spdid);
            dwSize = 0;
            b=SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL);
            if (dwSize!=0 && dwSize<=sizeof(Buf))
             {
              pspdidd->cbSize = sizeof(*pspdidd);
              ZeroMemory((PVOID)&spdd, sizeof(spdd));
              spdd.cbSize = sizeof(spdd);
              res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd);
              if(res)
               {                                           
                // the device instance id string contains the serial number if the
               // device has one...
               char szDevInstId[260] = {0};
              // CString szDevInstId=_T("");
               SetupDiGetDeviceInstanceId(hDevInfo, &spdd,(PWSTR)szDevInstId, 260, NULL);
               SetupDiDestroyDeviceInfoList(hDevInfo);
               DevInst=spdd.DevInst;
               CString serNo=GetSerialNumber(szDevInstId);
               for(int i=0;i<nDeviceCount;i++)
                if((struct_infoIdea.szSerialNumber==serNo)&& (struct_infoIdea.szTime_out=="In..Use.."))     
                      PollDatabase_Vallidity(i,DevInst);   
                    }
            }
            dwIndex++;
          }   
       }
    }

    but when once the plugged-in USB device is enumerated in:

     case 1:
    OnDeviceConnected(wparam,lparam) ...Again when i want to enumerate it after every one minute then SetupDiEnumInterfaceDevice() and SetupDiGetDeviceInterfaceDetail() are returning zero.

    case 2:
     If after the case1, when i plug-in another USB device without removing the first device, then even the first USB device plugged-in in case-1 and also case-2 are being enumerated. This  i got when i debug the project.

    That means in my case, all the devices are getting enumerated only when another device is recently plugged-in. Else not...

    This is my problem....i am unable to fix this..

    Thanking you ...




     
    Wednesday, September 13, 2006 7:37 AM
  • This kind of code always makes my brain hurt... The one thing that jumps out as "this can't be right" is your call to SetupDiDestroyDeviceInfoList().  You're doing this inside your enumeration loop, you should do it when you exit the loop.

    Also, rather than polling once a minute, I implemented a message handler for WM_DEVICECHANGE.  You can tell whether a device got removed or added from the WPARAM arg and you'll get the name of the device from the PDEV_BROADCAST_DEVICEINTERFACE pointer.
    Wednesday, September 13, 2006 12:55 PM
    Moderator
  • Hello.....

    Thanks nobugz!!!.... for ur answer.. i have mislocated the SetupDiDestroyDeviceInfoList(). Now i changed it to correct place. My problem got solved..All the devices are being enumerated for every minute.

    But when i am ejecting the USB device using CM_REQUEST_DEVICE_EJECT.. the USB device's power supply stops.. But it is not firing the DBT_DEVICEREMOVECOMPLETE.    When i saw my computer's device manager... there for that particular device's hardware properties  it is given that.. this device is ready for "safe removal" but is not removed from the computer....

    My doubt is, how can i fire
    DBT_DEVICEREMOVECOMPLETE after executing CM_REQUEST_DEVICE_EJECT.... because.. i need execute a function when the wparam=DBT_DEVICEREMOVECOMPLETE is called....

    NOTE: SOMETIMES, if i run my project for some 50-60 times... so for 2-3 times this event is getting generated ......

    I am struggling with this for very long time..

    Thank you.....
    Friday, September 15, 2006 12:33 PM
  •  HDEVINFO hDevInfo     = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_DEVICE,0,0,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);      

     

    SetupDiGetClassDevs always returns ERROR_IO_PENDING ?
     

    Wednesday, December 20, 2006 12:59 PM
  • Hey Nobugz,

    can you help me for the same on WinCE 6.0 Platform using C++???

    I want to enumerate USB Device on WinCE platform.

    Monday, January 7, 2013 9:16 AM