Пример #1
0
            /// <summary>return a list of the down stream ports</summary>
            /// <returns>List of downstream ports</returns>
            internal IEnumerable <UsbPort> GetPorts()
            {
                List <UsbPort> portList = new List <UsbPort>();

                // Open a handle to the Hub device
                IntPtr h = CreateFile(HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
                                      IntPtr.Zero);

                if (h == INVALID_HANDLE_VALUE)
                {
                    return(new ReadOnlyCollection <UsbPort>(portList));
                }

                int    nBytes            = Marshal.SizeOf(typeof(UsbNodeConnectionInformationEx));
                IntPtr ptrNodeConnection = Marshal.AllocHGlobal(nBytes);

                // loop thru all of the ports on the hub
                // BTW: Ports are numbered starting at 1
                for (int i = 1; i <= HubPortCount; i++)
                {
                    var nodeConnection = new UsbNodeConnectionInformationEx
                    {
                        ConnectionIndex = i
                    };

                    Marshal.StructureToPtr(nodeConnection, ptrNodeConnection, true);

                    if (!DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes,
                                         ptrNodeConnection, nBytes, out _, IntPtr.Zero))
                    {
                        continue;
                    }

                    nodeConnection =
                        (UsbNodeConnectionInformationEx)Marshal.PtrToStructure(ptrNodeConnection,
                                                                               typeof(UsbNodeConnectionInformationEx));

                    // load up the USBPort class
                    var port = new UsbPort
                    {
                        PortPortNumber        = i,
                        PortHubDevicePath     = HubDevicePath,
                        PortStatus            = ((UsbConnectionStatus)nodeConnection.ConnectionStatus).ToString(),
                        PortSpeed             = ((UsbDeviceSpeed)nodeConnection.Speed).ToString(),
                        PortIsDeviceConnected =
                            nodeConnection.ConnectionStatus == (int)UsbConnectionStatus.DeviceConnected,
                        PortIsHub            = Convert.ToBoolean(nodeConnection.DeviceIsHub),
                        PortDeviceDescriptor = nodeConnection.DeviceDescriptor
                    };

                    // add it to the list
                    portList.Add(port);
                }

                Marshal.FreeHGlobal(ptrNodeConnection);
                CloseHandle(h);

                // convert it into a Collection
                return(new ReadOnlyCollection <UsbPort>(portList));
            }
Пример #2
0
        public IEnumerable <UsbPort> GetPorts()
        {
            var h = Kernel32.CreateFile(this.HubDevicePath, UsbConstants.GENERIC_WRITE, UsbConstants.FILE_SHARE_WRITE, IntPtr.Zero, UsbConstants.OPEN_EXISTING, default(int), IntPtr.Zero);

            if (h.ToInt32() != UsbConstants.INVALID_HANDLE_VALUE)
            {
                var nBytes            = Marshal.SizeOf(typeof(UsbNodeConnectionInformationEx));
                var ptrNodeConnection = Marshal.AllocHGlobal(nBytes);

                for (var i = 1; i <= this.HubPortCount; i++)
                {
                    var nodeConnection = new UsbNodeConnectionInformationEx
                    {
                        ConnectionIndex = i,
                    };
                    Marshal.StructureToPtr(nodeConnection, ptrNodeConnection, true);

                    if (Kernel32.DeviceIoControl(h, UsbConstants.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes, ptrNodeConnection, nBytes, out int nBytesReturned, IntPtr.Zero))
                    {
                        nodeConnection = (UsbNodeConnectionInformationEx)Marshal.PtrToStructure(ptrNodeConnection, typeof(UsbNodeConnectionInformationEx));
                        var status = (UsbConnectionStatus)nodeConnection.ConnectionStatus;
                        var speed  = (UsbDeviceSpeed)nodeConnection.Speed;

                        var port = new UsbPort(this)
                        {
                            PortNumber        = i,
                            Status            = status.ToString(),
                            HubDevicePath     = this.HubDevicePath,
                            Speed             = speed.ToString(),
                            IsHub             = Convert.ToBoolean(nodeConnection.DeviceIsHub),
                            IsDeviceConnected = nodeConnection.ConnectionStatus == (int)UsbConnectionStatus.DeviceConnected,
                            DeviceDescriptor  = nodeConnection.DeviceDescriptor,
                        };

                        yield return(port);
                    }
                }
                Marshal.FreeHGlobal(ptrNodeConnection);
                Kernel32.CloseHandle(h);
            }
        }
Пример #3
0
        public static async Task <ExportedDevice[]> GetAll(CancellationToken cancellationToken)
        {
            var exportedDevices = new SortedDictionary <string, ExportedDevice>();

            using var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(IntPtr.Zero, "USB", IntPtr.Zero, DiGetClassFlags.DIGCF_ALLCLASSES | DiGetClassFlags.DIGCF_PRESENT);
            foreach (var devInfoData in EnumDeviceInfo(deviceInfoSet))
            {
                cancellationToken.ThrowIfCancellationRequested();

                var instanceId = GetDevicePropertyString(deviceInfoSet, devInfoData, DEVPKEY_Device_InstanceId);
                if (IsUsbHub(instanceId))
                {
                    // device is itself a USB hub, which is not supported
                    continue;
                }
                var parentId = GetDevicePropertyString(deviceInfoSet, devInfoData, DEVPKEY_Device_Parent);
                if (!IsUsbHub(parentId))
                {
                    // parent is not a USB hub (which it must be for this device to be supported)
                    continue;
                }

                // OK, so the device is directly connected to a hub, but is not a hub itself ... this looks promising

                GetBusId(deviceInfoSet, devInfoData, out var hubNum, out var connectionIndex);

                var address = GetDevicePropertyUInt32(deviceInfoSet, devInfoData, DEVPKEY_Device_Address);
                if (connectionIndex != address)
                {
                    throw new NotSupportedException($"DEVPKEY_Device_Address ({address}) does not match DEVPKEY_Device_LocationInfo ({connectionIndex})");
                }

                // now query the parent USB hub for device details

                {
                    cancellationToken.ThrowIfCancellationRequested();

                    using var hubs        = NativeMethods.SetupDiGetClassDevs(GUID_DEVINTERFACE_USB_HUB, parentId, IntPtr.Zero, DiGetClassFlags.DIGCF_DEVICEINTERFACE | DiGetClassFlags.DIGCF_PRESENT);
                    var(_, interfaceData) = EnumDeviceInterfaces(hubs, GUID_DEVINTERFACE_USB_HUB).Single();
                    var hubPath = GetDeviceInterfaceDetail(hubs, interfaceData);

                    cancellationToken.ThrowIfCancellationRequested();
                    using var hubFile = new DeviceFile(hubPath);
                    using var cancellationTokenRegistration = cancellationToken.Register(() => hubFile.Dispose());

                    var data = new UsbNodeConnectionInformationEx()
                    {
                        ConnectionIndex = connectionIndex
                    };
                    var buf = StructToBytes(data);
                    await hubFile.IoControlAsync(IoControl.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, buf, buf);

                    BytesToStruct(buf, 0, out data);

                    var speed = MapWindowsSpeedToLinuxSpeed(data.Speed);

                    var data2 = new UsbNodeConnectionInformationExV2()
                    {
                        ConnectionIndex       = connectionIndex,
                        Length                = (uint)Marshal.SizeOf <UsbNodeConnectionInformationExV2>(),
                        SupportedUsbProtocols = UsbProtocols.Usb110 | UsbProtocols.Usb200 | UsbProtocols.Usb300,
                    };
                    var buf2 = StructToBytes(data2);
                    await hubFile.IoControlAsync(IoControl.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, buf2, buf2);

                    BytesToStruct(buf2, 0, out data2);

                    if ((data2.SupportedUsbProtocols & UsbProtocols.Usb300) != 0)
                    {
                        if ((data2.Flags & UsbNodeConnectionInformationExV2Flags.DeviceIsOperatingAtSuperSpeedPlusOrHigher) != 0)
                        {
                            speed = Linux.UsbDeviceSpeed.USB_SPEED_SUPER_PLUS;
                        }
                        else if ((data2.Flags & UsbNodeConnectionInformationExV2Flags.DeviceIsOperatingAtSuperSpeedOrHigher) != 0)
                        {
                            speed = Linux.UsbDeviceSpeed.USB_SPEED_SUPER;
                        }
                    }

                    var exportedDevice = new ExportedDevice()
                    {
                        Path                     = instanceId,
                        BusNum                   = hubNum,
                        DevNum                   = connectionIndex,
                        Speed                    = speed,
                        VendorId                 = data.DeviceDescriptor.idVendor,
                        ProductId                = data.DeviceDescriptor.idProduct,
                        BcdDevice                = data.DeviceDescriptor.bcdDevice,
                        DeviceClass              = data.DeviceDescriptor.bDeviceClass,
                        DeviceSubClass           = data.DeviceDescriptor.bDeviceSubClass,
                        DeviceProtocol           = data.DeviceDescriptor.bDeviceProtocol,
                        ConfigurationValue       = data.CurrentConfigurationValue,
                        NumConfigurations        = data.DeviceDescriptor.bNumConfigurations,
                        ConfigurationDescriptors = await GetConfigurationDescriptor(hubFile, connectionIndex, data.DeviceDescriptor.bNumConfigurations),
                    };

                    exportedDevices.Add(exportedDevice.BusId, exportedDevice);
                }
            }

            return(exportedDevices.Values.ToArray());
        }