Search code examples
c#controllerusbport-scanning

C# How do I check USB Ports with USB Hub and used Controller?


I am currently trying to scan all USB Ports with their USB Hub (check if it is Root or not) and to which controller they are connectet.

To make it more visible:

USB Port1 (nothing plugged in)   -> USB Hub1   |                 |-> Controller 1
USB Port2 (Keyboard plugged in)  ->            |-> USB Root Hub  |-> Controller 2
USB Port3 (nothing plugged in)   -> USB Hub2   |                 |
USB Port4 (nothing plugged in)   ->            |-> USB Root Hub  |-> Controller3 (Mainboard)

I want to show the User all ports and connected Hubs as a tree. And if the USB Port with its controller are in use or not.

I hope you guys can understand what I am trying to describe. If you could give me some Keywords or even Code snippets i would greatly appreciate it.

PS.: Sorry for my bad english.

Here is the Code so far (I am using the .NetFramework 4.5.x):

USBPortScanner Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using System.IO.Ports;

namespace USBPortScanner

{
    class USBPortScanner
    {
        static void Main(string[] args)
        {
            var usbDevices = GetUSBDevices();
            foreach (var usbDevice in usbDevices)
            {
                //Prints all defined porperties, they need to be defined in the USBDeviceInfo.cs!
                Console.WriteLine("Name: {0}\r\nCaption: {1}\r\nError Code: {2}\r\nDevice ID: {3}\r\nSystem Name: {4}\r\nStatus: {5}",
                    usbDevice.Name, usbDevice.Caption, usbDevice.ConfigManagerErrorCode, usbDevice.DeviceID, usbDevice.SystemName, usbDevice.Status);
                Console.WriteLine();
            }

            Console.Read();
        }
        //Sets the Properties for the device variable
        static List<USBDeviceInfo> GetUSBDevices()
        {
            List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

            //Scanning all USBHubs with WMI
            using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
            {
                using (ManagementObjectCollection collection = searcher.Get())
                {
                    foreach (ManagementObject device in collection)
                    {

                        //To show all available data
                        //Console.WriteLine(device.Path);

                        //foreach (PropertyData prop in device.Properties)
                        //{
                        //    Console.WriteLine(prop.Name + ": " + prop.Value);
                        //}

                        //Console.WriteLine();

                        //Adds properties to device
                        devices.Add(new USBDeviceInfo(device));
                    }
                }
            }

            return devices;
        }
    }
}

USBDeviceInfo Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;

namespace USBPortScanner
{

    class USBDeviceInfo
    {
        public USBDeviceInfo(ManagementObject device)
        {
            this.Name = device.GetPropertyValue("Name").ToString();
            this.Caption = device.GetPropertyValue("Caption").ToString();

            if (device.GetPropertyValue("ConfigManagerErrorCode") != null)
            {
                this.ConfigManagerErrorCode = (ErrorCode)device.GetPropertyValue("ConfigManagerErrorCode");
            }
            else
            {
                this.ConfigManagerErrorCode = ErrorCode.Device_is_not_present_not_working_properly_or_does_not_have_all_of_its_drivers_installed;
            }

            this.DeviceID = device.GetPropertyValue("DeviceID").ToString();
            this.SystemName = device.GetPropertyValue("SystemName").ToString();
            this.Status = device.GetPropertyValue("Status").ToString();
        }

        //Sets the variables above usable for our purpose in the Program.cs
        public string Name { get; private set; }
        public string Caption { get; private set; }
        public ErrorCode ConfigManagerErrorCode { get; private set; }
        public string DeviceID { get; private set; }
        public string SystemName { get; private set; }
        public string Status { get; private set; }
    }
    enum ErrorCode : uint
    {
        Device_is_working_properly = 0,
        Device_is_not_configured_correctly = 1,
        Windows_cannot_load_the_driver_for_this_device = 2,
        Driver_for_this_device_might_be_corrupted_or_the_system_may_be_low_on_memory_or_other_resources = 3,
        Device_is_not_working_properly_One_of_its_drivers_or_the_registry_might_be_corrupted = 4,
        Driver_for_the_device_requires_a_resource_that_Windows_cannot_manage = 5,
        Boot_configuration_for_the_device_conflicts_with_other_devices = 6,
        Cannot_filter = 7,
        Driver_loader_for_the_device_is_missing = 8,
        Device_is_not_working_properly_The_controlling_firmware_is_incorrectly_reporting_the_resources_for_the_device = 9,
        Device_cannot_start = 10,
        Device_failed = 11,
        Device_cannot_find_enough_free_resources_to_use = 12,
        Windows_cannot_verify_the_device_resources = 13,
        Device_cannot_work_properly_until_the_computer_is_restarted = 14,
        Device_is_not_working_properly_due_to_a_possible_reenumeration_problem = 15,
        Windows_cannot_identify_all_of_the_resources_that_the_device_uses = 16,
        Device_is_requesting_an_unknown_resource_type = 17,
        Device_drivers_must_be_reinstalled = 18,
        Failure_using_the_VxD_loader = 19,
        Registry_might_be_corrupted = 20,
        System_failure_If_changing_the_device_driver_is_ineffective_see_the_hardware_documentation_Windows_is_removing_the_device = 21,
        Device_is_disabled = 22,
        System_failure_If_changing_the_device_driver_is_ineffective_see_the_hardware_documentation = 23,
        Device_is_not_present_not_working_properly_or_does_not_have_all_of_its_drivers_installed = 24,
        Windows_is_still_setting_up_the_device = 25 | 26,
        Device_does_not_have_valid_log_configuration = 27,
        Device_drivers_are_not_installed = 28,
        Device_is_disabled_The_device_firmware_did_not_provide_the_required_resources = 29,
        Device_is_using_an_IRQ_resource_that_another_device_is_using = 30,
        Device_is_not_working_properly_Windows_cannot_load_the_required_device_drivers = 31,

    }
}

Solution

  • I've found the solution myself. The Code below is a example i used from another site. I hope it will help the community too.

    source: http://www.news2news.com/vfp/?example=545&ver=vcs&PHPSESSID=70ba6845606a96b355ab7f772fb14386

    Code:

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Linq;
    
    namespace DeviceEnumerator
    {
        public class Program
        {
            public static void Main()
            {
                var deviceTree = new DeviceTree();
    
                foreach (var deviceClass in Win32.DeviceClasses)
                {
                    Console.WriteLine("\n{0}:", deviceClass.Value);
    
                    foreach (var device in deviceTree.DeviceNodes
                        .Where(d => d.ClassGuid == deviceClass.Key))
                    {
                        Console.WriteLine(
                            "\t{1}: {0}",
                            device.Description,
                            device.EnumeratorName);
                    }
                }
    
                Console.Write("\n\nAny key...");
                Console.ReadKey();
            }
        }
    
        public class DeviceTree : IDisposable
        {
            private IntPtr _machineHandle = IntPtr.Zero;
            private IntPtr _rootDeviceHandle = IntPtr.Zero;
            private DeviceNode _rootNode;
    
            // flat collection of all devices found
            private List< DeviceNode > _deviceNodes;
    
            public DeviceNode RootNode
            {
                get
                {
                    return this._rootNode;
                }
            }
    
            public List< DeviceNode > DeviceNodes
            {
                get
                {
                    return this._deviceNodes;
                }
            }
    
            public DeviceTree()
            {
                EnumerateDevices();
            }
    
            ~DeviceTree()
            {
                this.Dispose(false);
            }
    
            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    this._deviceNodes.Clear();
                }
    
                this.DisconnectFromMachine();
            }
    
            private void EnumerateDevices()
            {
                this.DisconnectFromMachine();
    
                // local machine assumed
                if (Win32.CM_Connect_Machine(
                    null, ref this._machineHandle) != 0)
                {
                    return;
                }
    
                try
                {
                    Win32.CM_Locate_DevNode_Ex(
                        ref this._rootDeviceHandle,
                        0,
                        0,
                        this._machineHandle);
    
                    // recursive enumeration
                    this._rootNode = new DeviceNode(
                        this._rootDeviceHandle,
                        null,
                        this._machineHandle);
                }
                finally
                {
                    this.DisconnectFromMachine();
    
                    if (this._rootNode != null)
                    {
                        this._deviceNodes = this._rootNode
                            .Flatten(node => node.Children).ToList();
                    }
                }
            }
    
            private void DisconnectFromMachine()
            {
                if (this._machineHandle != IntPtr.Zero)
                {
                    Win32.CM_Disconnect_Machine(this._machineHandle);
                    this._machineHandle = IntPtr.Zero;
                }
            }
        }
    
        public class DeviceNode : IDisposable
        {
            private readonly DeviceNode _parentDevice;
            private readonly List< DeviceNode > _children;
            private readonly IntPtr _deviceHandle;
            private readonly IntPtr _machineHandle;
    
            private readonly Dictionary< int, string >
                _deviceProperties;
    
            public DeviceNode ParentDevice
            {
                get
                {
                    return _parentDevice;
                }
            }
    
            public Dictionary< int, string > DeviceProperties
            {
                get
                {
                    return _deviceProperties;
                }
            }
    
            public List< DeviceNode > Children
            {
                get
                {
                    return this._children;
                }
            }
    
            public Guid ClassGuid
            {
                get
                {
                    string buffer =
                        this.GetProperty(Win32.DevRegProperty.ClassGuid);
    
                    var guid = new Guid();
    
                    if (buffer.Length >= 32)
                    {
                        try
                        {
                            guid = new Guid(buffer);
                        }
                        catch
                        {
                            guid = new Guid();
                        }
                    }
    
                    return guid;
                }
            }
    
            public string Description
            {
                get
                {
                    return
                        GetProperty(Win32.DevRegProperty.DeviceDescription);
                }
            }
    
            public string FriendlyName
            {
                get
                {
                    return
                        GetProperty(Win32.DevRegProperty.FriendlyName);
                }
            }
    
            public string EnumeratorName
            {
                get
                {
                    return
                        GetProperty(Win32.DevRegProperty.EnumeratorName);
                }
            }
    
            public string LocationInfo
            {
                get
                {
                    return
                        GetProperty(Win32.DevRegProperty.LocationInfo);
                }
            }
    
            public DeviceNode(IntPtr deviceHandle, DeviceNode parentDevice)
                : this(
                        deviceHandle, 
                        parentDevice, 
                        parentDevice._machineHandle)
            {
            }
    
            public DeviceNode(
                IntPtr deviceHandle,
                DeviceNode parentDevice,
                IntPtr machineHandle)
            {
                _deviceProperties = new Dictionary< int, string >();
                _children = new List< DeviceNode >();
    
                _deviceHandle = deviceHandle;
                _machineHandle = machineHandle;
                _parentDevice = parentDevice;
    
                EnumerateDeviceProperties();
                EnumerateChildren();
            }
    
            private string GetProperty(
                Win32.DevRegProperty devRegProperty)
            {
                return GetProperty((int)devRegProperty);
            }
    
            private string GetProperty(int index)
            {
                string buffer;
                var result = this._deviceProperties
                    .TryGetValue(index, out buffer);
                return result ? buffer : string.Empty;
            }
    
            private void EnumerateDeviceProperties()
            {
                for (var index = 0; index < 64; index++)
                {
                    uint bufsize = 2048;
    
                    IntPtr buffer = 
                        Marshal.AllocHGlobal((int)bufsize);
    
                    var result = 
                        Win32.CM_Get_DevNode_Registry_Property_Ex(
                            _deviceHandle,
                            index,
                            IntPtr.Zero,
                            buffer,
                            ref bufsize,
                            0,
                            _machineHandle);
    
                    var propertyString = result == 0
                        ? Marshal.PtrToStringAnsi(buffer) 
                        : string.Empty;
    
                    _deviceProperties.Add(index, propertyString);
    
                    Marshal.FreeHGlobal(buffer);
                }
            }
    
            private void EnumerateChildren()
            {
                IntPtr ptrFirstChild = IntPtr.Zero;
    
                if (Win32.CM_Get_Child_Ex(
                    ref ptrFirstChild, 
                    _deviceHandle, 
                    0, 
                    _machineHandle) != 0)
                {
                    return;
                }
    
                var ptrChild = ptrFirstChild;
                var ptrSibling = IntPtr.Zero;
    
                do
                {
                    var childDevice = new DeviceNode(ptrChild, this);
                    _children.Add(childDevice);
    
                    if (Win32.CM_Get_Sibling_Ex(
                        ref ptrSibling, 
                        ptrChild, 
                        0, 
                        _machineHandle) != 0) break;
    
                    ptrChild = ptrSibling;
                }
                while (true);
            }
    
            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposing)
                {
                    _deviceProperties.Clear();
                }
            }
        }
    
        internal static class LinqExtensionMethods
        {
            public static IEnumerable< T > Return< T >(T element)
            {
                yield return element;
            }
    
            public static IEnumerable< T > StartWith< T >(
                this IEnumerable< T > list, T element)
            {
                return Return(element).Concat(list);
            }
    
            public static IEnumerable< TEntity > Flatten< TEntity >(
                this TEntity element,
                Func< TEntity, IEnumerable< TEntity > > childSelector)
            {
                if (childSelector(element) != null)
                    return childSelector(element)
                        .SelectMany(child => child.Flatten(childSelector))
                        .StartWith(element);
    
                var items = new List< TEntity > { element };
                return items;
            }
        }
    
        public static class Win32
        {
            // this is a partial list
            public static readonly
                Dictionary< Guid, string > DeviceClasses =
                new Dictionary< Guid, string >
                {
                    { new Guid("{4d36e967-e325-11ce-bfc1-08002be10318}"), 
                        "Disk Drives" },
                    { new Guid("{4d36e968-e325-11ce-bfc1-08002be10318}"), 
                        "Display Adapters" },
                    { new Guid("{4d36e96b-e325-11ce-bfc1-08002be10318}"), 
                        "Keyboards" },
                    { new Guid("{4d36e96f-e325-11ce-bfc1-08002be10318}"), 
                        "Mice" },
                };
    
            public enum DevRegProperty : uint
            {
                DeviceDescription = 1,
                HardwareId = 2,
                CompatibleIds = 3,
                Unused0 = 4,
                Service = 5,
                Unused1 = 6,
                Unused2 = 7,
                Class = 8,
                ClassGuid = 9,
                Driver = 0x0a,
                ConfigFlags = 0x0b,
                Mfg = 0x0c,
                FriendlyName = 0x0d,
                LocationInfo = 0x0e,
                PhysicalDeviceObjectName = 0x0f,
                Capabilities = 0x10,
                UiNumber = 0x11,
                UpperFilters = 0x12,
                LowerFilters = 0x13,
                BusTypeGuid = 0x014,
                LegacyBusType = 0x15,
                BusNumber = 0x16,
                EnumeratorName = 0x17,
            }
    
            [DllImport("kernel32.dll")]
            public static extern uint GetLogicalDrives();
    
            [DllImport("kernel32.dll")]
            public static extern int GetDriveType(
                [MarshalAs(UnmanagedType.LPStr)] string rootPathName);
    
            [DllImport("cfgmgr32.dll")]
            public static extern int CM_Connect_Machine(
                [MarshalAs(UnmanagedType.LPStr)] string uncServerName,
                ref IntPtr machineHandle);
    
            [DllImport("cfgmgr32.dll")]
            public static extern int CM_Disconnect_Machine(
                IntPtr machineHandle);
    
            [DllImport("cfgmgr32.dll")]
            public static extern int CM_Locate_DevNode_Ex(
                ref IntPtr deviceHandle,
                int deviceId,
                uint flags,
                IntPtr machineHandle);
    
            [DllImport("cfgmgr32.dll")]
            public static extern int CM_Get_Child_Ex(
                ref IntPtr childDeviceHandle,
                IntPtr parentDeviceHandle,
                uint flags,
                IntPtr machineHandle);
    
            [DllImport("cfgmgr32.dll")]
            public static extern int CM_Get_Sibling_Ex(
                ref IntPtr siblingDeviceHandle,
                IntPtr deviceHandle,
                uint flags,
                IntPtr machineHandle);
    
            [DllImport("cfgmgr32.dll")]
            public static extern int 
                CM_Get_DevNode_Registry_Property_Ex(
                    IntPtr deviceHandle,
                    int property,
                    IntPtr regDataType,
                    IntPtr outBuffer,
                    ref uint size,
                    int flags,
                    IntPtr machineHandle);
        }
    }