1

I have a USB Hub of 10 USB slots connected to my USB Port. I want to get the USB device connected to the specific port.
Example: Two USB's are connected at Slot 3 and Slot 7. So, I want a list which will show Slot 3 and Slot 7 have USB and rest slot are empty.

I have tried using WMI Query Win32_USBHub. But here I am only getting 6 device IDs and not 10. I am differentiating the ports using common VID for the Device ID.

But still even after getting the USB's connected to the specific port. I want to get their corresponding slot in which they are connected to USBHub.

I am not able to identify the slot in which the USB is connected and where the slot is empty.

ManagementObjectCollection collection;
var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub");
collection = searcher.Get();
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
RahulGo8u
  • 148
  • 2
  • 19

2 Answers2

0

I would try to extract location information from the USB device (the same as in device manager)... I do not code in C# nor WMI but you should be able to obtain this kind of info with setupapi.h which is part of winapi (I think) I do it like this in C++/VCL:

#include <setupapi.h>
bool USBinfo()
    {
    int i,n;
    AnsiString s,txt="";
    DWORD dwSize,dwPropertyRegDataType;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    TCHAR szDesc[1024];

    // List all connected USB devices
    hDevInfo = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
    if (hDevInfo == INVALID_HANDLE_VALUE) return false;
    for (i=0;;i++)
        {
        DeviceInfoData.cbSize = sizeof(DeviceInfoData);
        if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData)) break;
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,&dwPropertyRegDataType, (BYTE*)szDesc,sizeof(szDesc),&dwSize);
        s=szDesc; n=48; while (s.Length()<n) s+=" "; if (s.Length()>n) s=s.SubString(1,n); txt+=s+" "; // this just set constant string size to allign the columns to n chars
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID,&dwPropertyRegDataType, (BYTE*)szDesc,sizeof(szDesc),&dwSize);
        s=szDesc; if (s=="USB\\VID_????&PID_????REV_????")
            {
            // here you can do custom stuff for specific VID,PID just change the ???? in above line to your specific VID,PID,REV
            }
        s=szDesc; n=64; while (s.Length()<n) s+=" "; if (s.Length()>n) s=s.SubString(1,n); txt+=s+" ";
        SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_LOCATION_INFORMATION,&dwPropertyRegDataType, (BYTE*)szDesc,sizeof(szDesc),&dwSize);
        s=szDesc; n=64; while (s.Length()<n) s+=" "; if (s.Length()>n) s=s.SubString(1,n); txt+=s+" ";
        txt+="\r\n";
        }
    Main->mm_log->Lines->Add(txt); // this just output txt string to memo
    return true;
    }

Here output on my machine:

USB Root Hub                                     USB\ROOT_HUB&VID1022&PID7807&REV0011                             USB\ROOT_HUB&VID1022&PID7807&REV0011                             
USB Root Hub                                     USB\ROOT_HUB&VID1022&PID7807&REV0011                             USB\ROOT_HUB&VID1022&PID7807&REV0011                             
USB Root Hub                                     USB\ROOT_HUB&VID1022&PID7809&REV0011                             USB\ROOT_HUB&VID1022&PID7809&REV0011                             
USB Root Hub                                     USB\ROOT_HUB20&VID1022&PID7808&REV0011                           USB\ROOT_HUB20&VID1022&PID7808&REV0011                           
USB Root Hub                                     USB\ROOT_HUB20&VID1022&PID7808&REV0011                           USB\ROOT_HUB20&VID1022&PID7808&REV0011                           
USB Composite Device                             USB\VID_048D&PID_9006&REV_0200                                   Port_#0001.Hub_#0004                                             
IT9135 BDA Device                                USB\VID_048D&PID_9006&REV_0200&MI_00                             0000.0013.0002.001.000.000.000.000.000                           
USB Input Device                                 USB\VID_048D&PID_9006&REV_0200&MI_01                             0000.0013.0002.001.000.000.000.000.000                           
Canon LiDE 30                                    USB\VID_04A9&PID_220E&REV_0100                                   Port_#0005.Hub_#0001                                             
American Power Conversion USB UPS                USB\VID_051D&PID_0002&REV_0106                                   Port_#0001.Hub_#0001                                             
USB Input Device                                 USB\Vid_093A&Pid_2510&Rev_0100                                   USB Optical Mouse                                                
USB Input Device                                 USB\VID_413C&PID_2107&REV_0115                                   Port_#0002.Hub_#0001                                             

As you can see the last column (3th) holds the info you want. Look inside setupapi.h for all the SPDRP_ defines you can use ... The only thing used from VCL is AnsiString so change it to any string type you have at your disposal.

This is not restricted to USB. If you want all the devices then change TEXT("USB") search parameter to NULL

hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • I have also tried the similar approach. The output that you have shown here is showing the DeviceID for each device's present under USB Controllers in DeviceManager. However, I am looking for the exact location details of the device manager. The location details are showing there as Port_#0003.Hub_#0003. But here it is just showing VID, PID & REV which will not help to identify the Slot No. of the USBHub. – RahulGo8u May 29 '17 at 11:05
  • @RahulAnand roll the scrollbar to the right the locations are after the VID PID column like `Port_#0005.Hub_#0001` – Spektre May 29 '17 at 22:45
  • @Spektre...Thanks for providing correct analysis approach. Although I have tried using C# but still not able to figure out the Location property properly. I am still working on it. But Indeed this is the correct solution approach which you have provided. It really helped. – RahulGo8u May 31 '17 at 18:37
  • 1
    I disagree that this is a helpful answer. Experimenting with a USB hub that I have and the UsbViewer tool, the location information does not indicate a slot number. Using a HUB with 5 slots I plug in one device at a time either to the far right or left, neither the hub nor the port number are ever 1 or 5. Maybe it isn't clear what the OP meant by slot number. Perhaps one could get lucky with one particular hub, but I don't see a discernible pattern. Every HUB could be different in the way that it assigns location information to plugged in devices. – shawn1874 May 30 '18 at 00:58
  • @shawn1874 it can be also a matter of firmware (bug) of the HUB of yours how it enumerates its devices. But if the HUB does not tell the OS this info correctly then you have no other means to acquire it from it by SW... On my machines I tested this the info looks OK (ports are not the same) – Spektre May 30 '18 at 06:39
  • @Spektre that is a fair point. I was wondering about that. I just cannot find any official document that states how that is supposed to work. Is the port number supposed to represent the same thing as a slot number counting from right to left or left to right on a hub? Thanks for the reply. I also wonder if it is only a preference. To hub manufactures have to set the port numbers in a particular way? I have a hub with 2 power ports and 5 regular ports. The USB viewer only shows 4 ports and then an embedded hub within the hub. It's an old DLINK USB 2.0 hub. – shawn1874 May 31 '18 at 16:16
  • @shawn1874 I think the slot numbers are hardwired on USB chip and the actual number of a connector depends on the PCB layout (how is physically interconnected with the USB chip) but That is far from my field of expertize so I am just guessing and might be wrong in this... Your best bet would be to find datasheet to specific USB chip ... – Spektre May 31 '18 at 18:34
0
static int GetPhysicalPort()
    {
        try
        {
            devices = new List<USBDeviceInfo>();
            
            ManagementObjectCollection collection;
            using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPSignedDriver WHERE DeviceId LIKE 'USB\\VID%' AND Description = 'USB Mass Storage Device' "))
            {
                collection = searcher.Get();
                searcher.Dispose();
            }
                

            foreach (var device in collection)
            {
                devices.Add(new USBDeviceInfo(
                (string)device.GetPropertyValue("DeviceId"),
                (string)device.GetPropertyValue("Description"),
                (string)device.GetPropertyValue("Location")
                ));
            }

            collection.Dispose();
           
            string LastAdded = devices[0].Location.Substring(6, 4);
            Console.WriteLine(LastAdded);
            return Convert.ToInt32(LastAdded);
        }

        catch (Exception e)
        {
            Console.WriteLine(e);
            return 0;
        }
    }


 class USBDeviceInfo
{
    public USBDeviceInfo(string deviceID, string Description, string location)
    {
        this.DeviceID = deviceID;
        this.Desc = Description;
        this.Location = location;
        
       
    }
    public string DeviceID   { get;}
    public string  Desc      { get;}
    public string Location   { get;}
}

I am using this Method to take the slot you are asking for. In fact I take the slot of the last plugged in USB due to the requirements I have. You can just debug and see the content of the class USBDeviceInfo and then use it for your own purpose.

edgj4718
  • 47
  • 9
  • Usually a bad idea to catch exceptions inside a specific method and return a C-style error code. Better only catch exceptions if you know how to handle them. – Uwe Keim Aug 19 '20 at 08:37
  • 1
    For my particular application is quite fine. Anyway, thank you for the advice. – edgj4718 Aug 19 '20 at 08:51