简体   繁体   English

检测设备是否使用 USB 3.0

[英]Detect if device is using USB 3.0

Does anyone know a way to detect if a USB device connected to a USB 3.0 host port is running at 3.0 or 2.0 using C#?有谁知道使用 C# 检测连接到 USB 3.0 主机端口的 USB 设备是在 3.0 还是 2.0 上运行的方法?

We are manufacturing USB 3.0 extension cables and we need to verify that all the pins have been soldered correctly.我们正在制造 USB 3.0 延长线,我们需要验证所有引脚是否已正确焊接。 We would like to do this in software.我们想在软件中做到这一点。 We would like to connect a 3.0 thumb drive to the cable and check if the device is operating in USB 3.0 mode.我们想将 3.0 拇指驱动器连接到电缆并检查设备是否在 USB 3.0 模式下运行。 If it is in 2.0 mode, we know their is a problem with 1 or more of the USB 3.0 lines.如果它处于 2.0 模式,我们知道它们是 1 个或多个 USB 3.0 线的问题。

I've managed to cook up a working demo with the help of some source code I found .在我找到的一些源代码的帮助下,我设法制作了一个工作演示。

private static void Main(string[] args)
{
  var hostCtrls = USB.GetHostControllers();

  foreach (var hostCtrl in hostCtrls)
  {
    var hub = hostCtrl.GetRootHub();
    foreach (var port in hub.GetPorts())
    {
      if (port.IsDeviceConnected && !port.IsHub)
      {
        var device = port.GetDevice();
        Console.WriteLine("Serial: " + device.DeviceSerialNumber);
        Console.WriteLine("Speed:  " + port.Speed);
        Console.WriteLine("Port:   " + device.PortNumber + Environment.NewLine);
      }
    }
  }
}

输出

The application enumerates the USB Host Controllers.该应用程序枚举 USB 主机控制器。 Then it gets the Root Hub and enumarates the ports belonging to it.然后它获取根集线器并枚举属于它的端口。 If there is a device connected and it's not a hub then it displays the required information.如果有连接的设备并且它不是集线器,那么它会显示所需的信息。

In your case you probably know which device you want to check so you can modify the source (both the above and the linked code) to specifically check only that device.在您的情况下,您可能知道要检查哪个设备,因此您可以修改源(上面和链接的代码)以专门检查该设备。

You'll need to create a method in the USB class to get a specific port from a specific hub by specifying port number and the path to the hub.您需要在 USB 类中创建一个方法,通过指定端口号和到集线器的路径来从特定集线器获取特定端口。

Something like:就像是:

GetDeviceSpeed(string hubPath, int portNumber) { ... }

and the call it with the appropriate values:并使用适当的值调用它:

var hubPath = @"\\.\NUSB3#ROOT_HUB30#5&b235176&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}";
var portNumber = 2;
GetDeviceSpeed(hubPath, portNumber);

If you however are reluctant to do this then you can simply use the above code and make notice of the serial number of the device you want to test and only check the speed then:但是,如果您不愿意这样做,那么您可以简单地使用上面的代码并注意要测试的设备的序列号,然后只检查速度:

if (device.DeviceSerialNumber == "xxxxxx")
  Console.WriteLine("Speed:  " + port.Speed);

If you are to use this in an application with a GUI you could just select the device you want to check in a dropdown.如果您要在带有 GUI 的应用程序中使用它,您只需在下拉列表中选择要检查的设备。

Well... There are some thoughts and hopefully a working solution.嗯......有一些想法,希望有一个可行的解决方案。

Addendum附录

For the sake of longevity I'll include the modified classes I used for the demo.为了长寿起见,我将包括我用于演示的修改后的类。
( Comments and empty lines removed due to SO limitations on 30000 characters ): 由于 30000 个字符的限制,注释和空行被删除):

public class USB
{
    const int GENERIC_WRITE = 0x40000000;
    const int FILE_SHARE_READ = 0x1;
    const int FILE_SHARE_WRITE = 0x2;
    const int OPEN_EXISTING = 0x3;
    const int INVALID_HANDLE_VALUE = -1;
    const int IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
    const int IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
    const int IOCTL_USB_GET_NODE_INFORMATION = 0x220408;
    const int IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX = 0x220448;
    const int IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION = 0x220410;
    const int IOCTL_USB_GET_NODE_CONNECTION_NAME = 0x220414;
    const int IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME = 0x220420;
    const int USB_DEVICE_DESCRIPTOR_TYPE = 0x1;
    const int USB_STRING_DESCRIPTOR_TYPE = 0x3;
    const int BUFFER_SIZE = 2048;
    const int MAXIMUM_USB_STRING_LENGTH = 255;
    const string GUID_DEVINTERFACE_HUBCONTROLLER = "3abf6f2d-71c4-462a-8a92-1e6861e6af27";
    const string REGSTR_KEY_USB = "USB";
    const int DIGCF_PRESENT = 0x2;
    const int DIGCF_ALLCLASSES = 0x4;
    const int DIGCF_DEVICEINTERFACE = 0x10;
    const int SPDRP_DRIVER = 0x9;
    const int SPDRP_DEVICEDESC = 0x0;
    const int REG_SZ = 1;
    enum USB_HUB_NODE
    {
        UsbHub,
        UsbMIParent
    }
    enum USB_CONNECTION_STATUS
    {
        NoDeviceConnected,
        DeviceConnected,
        DeviceFailedEnumeration,
        DeviceGeneralFailure,
        DeviceCausedOvercurrent,
        DeviceNotEnoughPower,
        DeviceNotEnoughBandwidth,
        DeviceHubNestedTooDeeply,
        DeviceInLegacyHub
    }
    enum USB_DEVICE_SPEED : byte
    {
        UsbLowSpeed,
        UsbFullSpeed,
        UsbHighSpeed,
        UsbSuperSpeed
    }
    [StructLayout(LayoutKind.Sequential)]
    struct SP_DEVINFO_DATA
    {
        public int cbSize;
        public Guid ClassGuid;
        public IntPtr DevInst;
        public IntPtr Reserved;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct SP_DEVICE_INTERFACE_DATA
    {
        public int cbSize;
        public Guid InterfaceClassGuid;
        public int Flags;
        public IntPtr Reserved;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct SP_DEVICE_INTERFACE_DETAIL_DATA
    {
        public int cbSize;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
        public string DevicePath;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct USB_HCD_DRIVERKEY_NAME
    {
        public int ActualLength;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
        public string DriverKeyName;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct USB_ROOT_HUB_NAME
    {
        public int ActualLength;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
        public string RootHubName;
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct USB_HUB_DESCRIPTOR
    {
        public byte bDescriptorLength;
        public byte bDescriptorType;
        public byte bNumberOfPorts;
        public short wHubCharacteristics;
        public byte bPowerOnToPowerGood;
        public byte bHubControlCurrent;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public byte[] bRemoveAndPowerMask;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct USB_HUB_INFORMATION
    {
        public USB_HUB_DESCRIPTOR HubDescriptor;
        public byte HubIsBusPowered;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct USB_NODE_INFORMATION
    {
        public int NodeType;
        public USB_HUB_INFORMATION HubInformation;
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct USB_NODE_CONNECTION_INFORMATION_EX
    {
        public int ConnectionIndex;
        public USB_DEVICE_DESCRIPTOR DeviceDescriptor;
        public byte CurrentConfigurationValue;
        public byte Speed;
        public byte DeviceIsHub;
        public short DeviceAddress;
        public int NumberOfOpenPipes;
        public int ConnectionStatus;
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct USB_DEVICE_DESCRIPTOR
    {
        public byte bLength;
        public byte bDescriptorType;
        public short bcdUSB;
        public byte bDeviceClass;
        public byte bDeviceSubClass;
        public byte bDeviceProtocol;
        public byte bMaxPacketSize0;
        public short idVendor;
        public short idProduct;
        public short bcdDevice;
        public byte iManufacturer;
        public byte iProduct;
        public byte iSerialNumber;
        public byte bNumConfigurations;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct USB_STRING_DESCRIPTOR
    {
        public byte bLength;
        public byte bDescriptorType;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXIMUM_USB_STRING_LENGTH)]
        public string bString;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct USB_SETUP_PACKET
    {
        public byte bmRequest;
        public byte bRequest;
        public short wValue;
        public short wIndex;
        public short wLength;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct USB_DESCRIPTOR_REQUEST
    {
        public int ConnectionIndex;
        public USB_SETUP_PACKET SetupPacket;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct USB_NODE_CONNECTION_NAME
    {
        public int ConnectionIndex;
        public int ActualLength;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
        public string NodeName;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    struct USB_NODE_CONNECTION_DRIVERKEY_NAME
    {
        public int ConnectionIndex;
        public int ActualLength;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
        public string DriverKeyName;
    }
    [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SetupDiGetClassDevs(
            ref Guid ClassGuid,
            int Enumerator,
            IntPtr hwndParent,
            int Flags
    );
    [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SetupDiGetClassDevs(
            int ClassGuid,
            string Enumerator,
            IntPtr hwndParent,
            int Flags
    );
    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool SetupDiEnumDeviceInterfaces(
            IntPtr DeviceInfoSet,
            IntPtr DeviceInfoData,
            ref Guid InterfaceClassGuid,
            int MemberIndex,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
    );
    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool SetupDiGetDeviceInterfaceDetail(
            IntPtr DeviceInfoSet,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
            ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
            int DeviceInterfaceDetailDataSize,
            ref int RequiredSize,
            ref SP_DEVINFO_DATA DeviceInfoData
    );
    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool SetupDiGetDeviceRegistryProperty(
            IntPtr DeviceInfoSet,
            ref SP_DEVINFO_DATA DeviceInfoData,
            int iProperty,
            ref int PropertyRegDataType,
            IntPtr PropertyBuffer,
            int PropertyBufferSize,
            ref int RequiredSize
    );
    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool SetupDiEnumDeviceInfo(
            IntPtr DeviceInfoSet,
            int MemberIndex,
            ref SP_DEVINFO_DATA DeviceInfoData
    );
    [DllImport("setupapi.dll", SetLastError = true)]
    static extern bool SetupDiDestroyDeviceInfoList(
            IntPtr DeviceInfoSet
    );
    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool SetupDiGetDeviceInstanceId(
            IntPtr DeviceInfoSet,
            ref SP_DEVINFO_DATA DeviceInfoData,
            StringBuilder DeviceInstanceId,
            int DeviceInstanceIdSize,
            out int RequiredSize
    );
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool DeviceIoControl(
            IntPtr hDevice,
            int dwIoControlCode,
            IntPtr lpInBuffer,
            int nInBufferSize,
            IntPtr lpOutBuffer,
            int nOutBufferSize,
            out int lpBytesReturned,
            IntPtr lpOverlapped
    );
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern IntPtr CreateFile(
         string lpFileName,
         int dwDesiredAccess,
         int dwShareMode,
         IntPtr lpSecurityAttributes,
         int dwCreationDisposition,
         int dwFlagsAndAttributes,
         IntPtr hTemplateFile
    );
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool CloseHandle(
            IntPtr hObject
    );
    static public System.Collections.ObjectModel.ReadOnlyCollection<USBController> GetHostControllers()
    {
        List<USBController> HostList = new List<USBController>();
        Guid HostGUID = new Guid(GUID_DEVINTERFACE_HUBCONTROLLER);
        IntPtr h = SetupDiGetClassDevs(ref HostGUID, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
        if (h.ToInt32() != INVALID_HANDLE_VALUE)
        {
            IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
            bool Success;
            int i = 0;
            do
            {
                USBController host = new USBController();
                host.ControllerIndex = i;
                SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
                dia.cbSize = Marshal.SizeOf(dia);
                Success = SetupDiEnumDeviceInterfaces(h, IntPtr.Zero, ref HostGUID, i, ref dia);
                if (Success)
                {
                    SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                    da.cbSize = Marshal.SizeOf(da);
                    SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
                    didd.cbSize = 4 + Marshal.SystemDefaultCharSize;
                    int nRequiredSize = 0;
                    int nBytes = BUFFER_SIZE;
                    if (SetupDiGetDeviceInterfaceDetail(h, ref dia, ref didd, nBytes, ref nRequiredSize, ref da))
                    {
                        host.ControllerDevicePath = didd.DevicePath;
                        int RequiredSize = 0;
                        int RegType = REG_SZ;
                        if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
                        {
                            host.ControllerDeviceDesc = Marshal.PtrToStringAuto(ptrBuf);
                        }
                        if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
                        {
                            host.ControllerDriverKeyName = Marshal.PtrToStringAuto(ptrBuf);
                        }
                    }
                    HostList.Add(host);
                }
                i++;
            } while (Success);
            Marshal.FreeHGlobal(ptrBuf);
            SetupDiDestroyDeviceInfoList(h);
        }
        return new System.Collections.ObjectModel.ReadOnlyCollection<USBController>(HostList);
    }
    public class USBController
    {
        internal int ControllerIndex;
        internal string ControllerDriverKeyName, ControllerDevicePath, ControllerDeviceDesc;
        public USBController()
        {
            ControllerIndex = 0;
            ControllerDevicePath = "";
            ControllerDeviceDesc = "";
            ControllerDriverKeyName = "";
        }
        public int Index
        {
            get { return ControllerIndex; }
        }
        public string DevicePath
        {
            get { return ControllerDevicePath; }
        }
        public string DriverKeyName
        {
            get { return ControllerDriverKeyName; }
        }
        public string Name
        {
            get { return ControllerDeviceDesc; }
        }
        public USBHub GetRootHub()
        {
            IntPtr h, h2;
            USBHub Root = new USBHub();
            Root.HubIsRootHub = true;
            Root.HubDeviceDesc = "Root Hub";
            h = CreateFile(ControllerDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (h.ToInt32() != INVALID_HANDLE_VALUE)
            {
                int nBytesReturned;
                USB_ROOT_HUB_NAME HubName = new USB_ROOT_HUB_NAME();
                int nBytes = Marshal.SizeOf(HubName);
                IntPtr ptrHubName = Marshal.AllocHGlobal(nBytes);
                if (DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes, out nBytesReturned, IntPtr.Zero))
                {
                    HubName = (USB_ROOT_HUB_NAME)Marshal.PtrToStructure(ptrHubName, typeof(USB_ROOT_HUB_NAME));
                    Root.HubDevicePath = @"\\.\" + HubName.RootHubName;
                }
                h2 = CreateFile(Root.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                if (h2.ToInt32() != INVALID_HANDLE_VALUE)
                {
                    USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
                    NodeInfo.NodeType = (int)USB_HUB_NODE.UsbHub;
                    nBytes = Marshal.SizeOf(NodeInfo);
                    IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
                    Marshal.StructureToPtr(NodeInfo, ptrNodeInfo, true);
                    if (DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo, typeof(USB_NODE_INFORMATION));
                        Root.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
                        Root.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
                    }
                    Marshal.FreeHGlobal(ptrNodeInfo);
                    CloseHandle(h2);
                }
                Marshal.FreeHGlobal(ptrHubName);
                CloseHandle(h);
            }
            return Root;
        }
    }
    public class USBHub
    {
        internal int HubPortCount;
        internal string HubDriverKey, HubDevicePath, HubDeviceDesc;
        internal string HubManufacturer, HubProduct, HubSerialNumber, HubInstanceID;
        internal bool HubIsBusPowered, HubIsRootHub;
        public USBHub()
        {
            HubPortCount = 0;
            HubDevicePath = "";
            HubDeviceDesc = "";
            HubDriverKey = "";
            HubIsBusPowered = false;
            HubIsRootHub = false;
            HubManufacturer = "";
            HubProduct = "";
            HubSerialNumber = "";
            HubInstanceID = "";
        }
        public int PortCount
        {
            get { return HubPortCount; }
        }
        public string DevicePath
        {
            get { return HubDevicePath; }
        }
        public string DriverKey
        {
            get { return HubDriverKey; }
        }
        public string Name
        {
            get { return HubDeviceDesc; }
        }
        public string InstanceID
        {
            get { return HubInstanceID; }
        }
        public bool IsBusPowered
        {
            get { return HubIsBusPowered; }
        }
        public bool IsRootHub
        {
            get { return HubIsRootHub; }
        }
        public string Manufacturer
        {
            get { return HubManufacturer; }
        }
        public string Product
        {
            get { return HubProduct; }
        }
        public string SerialNumber
        {
            get { return HubSerialNumber; }
        }
        public System.Collections.ObjectModel.ReadOnlyCollection<USBPort> GetPorts()
        {
            List<USBPort> PortList = new List<USBPort>();
            IntPtr h = CreateFile(HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (h.ToInt32() != INVALID_HANDLE_VALUE)
            {
                int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX));
                IntPtr ptrNodeConnection = Marshal.AllocHGlobal(nBytes);
                for (int i = 1; i <= HubPortCount; i++)
                {
                    int nBytesReturned;
                    USB_NODE_CONNECTION_INFORMATION_EX NodeConnection = new USB_NODE_CONNECTION_INFORMATION_EX();
                    NodeConnection.ConnectionIndex = i;
                    Marshal.StructureToPtr(NodeConnection, ptrNodeConnection, true);
                    if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ptrNodeConnection, nBytes, ptrNodeConnection, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        NodeConnection = (USB_NODE_CONNECTION_INFORMATION_EX)Marshal.PtrToStructure(ptrNodeConnection, typeof(USB_NODE_CONNECTION_INFORMATION_EX));
                        USBPort port = new USBPort();
                        port.PortPortNumber = i;
                        port.PortHubDevicePath = HubDevicePath;
                        USB_CONNECTION_STATUS Status = (USB_CONNECTION_STATUS)NodeConnection.ConnectionStatus;
                        port.PortStatus = Status.ToString();
                        USB_DEVICE_SPEED Speed = (USB_DEVICE_SPEED)NodeConnection.Speed;
                        port.PortSpeed = Speed.ToString();
                        port.PortIsDeviceConnected = (NodeConnection.ConnectionStatus == (int)USB_CONNECTION_STATUS.DeviceConnected);
                        port.PortIsHub = Convert.ToBoolean(NodeConnection.DeviceIsHub);
                        port.PortDeviceDescriptor = NodeConnection.DeviceDescriptor;
                        PortList.Add(port);
                    }
                }
                Marshal.FreeHGlobal(ptrNodeConnection);
                CloseHandle(h);
            }
            return new System.Collections.ObjectModel.ReadOnlyCollection<USBPort>(PortList);
        }
    }
    public class USBPort
    {
        internal int PortPortNumber;
        internal string PortStatus, PortHubDevicePath, PortSpeed;
        internal bool PortIsHub, PortIsDeviceConnected;
        internal USB_DEVICE_DESCRIPTOR PortDeviceDescriptor;
        public USBPort()
        {
            PortPortNumber = 0;
            PortStatus = "";
            PortHubDevicePath = "";
            PortSpeed = "";
            PortIsHub = false;
            PortIsDeviceConnected = false;
        }
        public int PortNumber
        {
            get { return PortPortNumber; }
        }
        public string HubDevicePath
        {
            get { return PortHubDevicePath; }
        }
        public string Status
        {
            get { return PortStatus; }
        }
        public string Speed
        {
            get { return PortSpeed; }
        }
        public bool IsHub
        {
            get { return PortIsHub; }
        }
        public bool IsDeviceConnected
        {
            get { return PortIsDeviceConnected; }
        }
        public USBDevice GetDevice()
        {
            if (!PortIsDeviceConnected)
            {
                return null;
            }
            USBDevice Device = new USBDevice();
            Device.DevicePortNumber = PortPortNumber;
            Device.DeviceHubDevicePath = PortHubDevicePath;
            Device.DeviceDescriptor = PortDeviceDescriptor;
            IntPtr h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (h.ToInt32() != INVALID_HANDLE_VALUE)
            {
                int nBytesReturned;
                int nBytes = BUFFER_SIZE;
                string NullString = new string((char)0, BUFFER_SIZE / Marshal.SystemDefaultCharSize);
                if (PortDeviceDescriptor.iManufacturer > 0)
                {
                    USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
                    Request.ConnectionIndex = PortPortNumber;
                    Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iManufacturer);
                    Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                    Request.SetupPacket.wIndex = 0x409;
                    IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
                    Marshal.StructureToPtr(Request, ptrRequest, true);
                    if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                        USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                        Device.DeviceManufacturer = StringDesc.bString;
                    }
                    Marshal.FreeHGlobal(ptrRequest);
                }
                if (PortDeviceDescriptor.iProduct > 0)
                {
                    USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
                    Request.ConnectionIndex = PortPortNumber;
                    Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iProduct);
                    Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                    Request.SetupPacket.wIndex = 0x409;
                    IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
                    Marshal.StructureToPtr(Request, ptrRequest, true);
                    if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                        USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                        Device.DeviceProduct = StringDesc.bString;
                    }
                    Marshal.FreeHGlobal(ptrRequest);
                }
                if (PortDeviceDescriptor.iSerialNumber > 0)
                {
                    USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
                    Request.ConnectionIndex = PortPortNumber;
                    Request.SetupPacket.wValue = (short)((USB_STRING_DESCRIPTOR_TYPE << 8) + PortDeviceDescriptor.iSerialNumber);
                    Request.SetupPacket.wLength = (short)(nBytes - Marshal.SizeOf(Request));
                    Request.SetupPacket.wIndex = 0x409;
                    IntPtr ptrRequest = Marshal.StringToHGlobalAuto(NullString);
                    Marshal.StructureToPtr(Request, ptrRequest, true);
                    if (DeviceIoControl(h, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ptrRequest, nBytes, ptrRequest, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        IntPtr ptrStringDesc = new IntPtr(ptrRequest.ToInt32() + Marshal.SizeOf(Request));
                        USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure(ptrStringDesc, typeof(USB_STRING_DESCRIPTOR));
                        Device.DeviceSerialNumber = StringDesc.bString;
                    }
                    Marshal.FreeHGlobal(ptrRequest);
                }
                USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKey = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
                DriverKey.ConnectionIndex = PortPortNumber;
                nBytes = Marshal.SizeOf(DriverKey);
                IntPtr ptrDriverKey = Marshal.AllocHGlobal(nBytes);
                Marshal.StructureToPtr(DriverKey, ptrDriverKey, true);
                if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes, ptrDriverKey, nBytes, out nBytesReturned, IntPtr.Zero))
                {
                    DriverKey = (USB_NODE_CONNECTION_DRIVERKEY_NAME)Marshal.PtrToStructure(ptrDriverKey, typeof(USB_NODE_CONNECTION_DRIVERKEY_NAME));
                    Device.DeviceDriverKey = DriverKey.DriverKeyName;

                    Device.DeviceName = GetDescriptionByKeyName(Device.DeviceDriverKey);
                    Device.DeviceInstanceID = GetInstanceIDByKeyName(Device.DeviceDriverKey);
                }
                Marshal.FreeHGlobal(ptrDriverKey);
                CloseHandle(h);
            }
            return Device;
        }
        public USBHub GetHub()
        {
            if (!PortIsHub)
            {
                return null;
            }
            USBHub Hub = new USBHub();
            IntPtr h, h2;
            Hub.HubIsRootHub = false;
            Hub.HubDeviceDesc = "External Hub";
            h = CreateFile(PortHubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (h.ToInt32() != INVALID_HANDLE_VALUE)
            {
                int nBytesReturned;
                USB_NODE_CONNECTION_NAME NodeName = new USB_NODE_CONNECTION_NAME();
                NodeName.ConnectionIndex = PortPortNumber;
                int nBytes = Marshal.SizeOf(NodeName);
                IntPtr ptrNodeName = Marshal.AllocHGlobal(nBytes);
                Marshal.StructureToPtr(NodeName, ptrNodeName, true);
                if (DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes, out nBytesReturned, IntPtr.Zero))
                {
                    NodeName = (USB_NODE_CONNECTION_NAME)Marshal.PtrToStructure(ptrNodeName, typeof(USB_NODE_CONNECTION_NAME));
                    Hub.HubDevicePath = @"\\.\" + NodeName.NodeName;
                }
                h2 = CreateFile(Hub.HubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                if (h2.ToInt32() != INVALID_HANDLE_VALUE)
                {
                    USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION();
                    NodeInfo.NodeType = (int)USB_HUB_NODE.UsbHub;
                    nBytes = Marshal.SizeOf(NodeInfo);
                    IntPtr ptrNodeInfo = Marshal.AllocHGlobal(nBytes);
                    Marshal.StructureToPtr(NodeInfo, ptrNodeInfo, true);
                    if (DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out nBytesReturned, IntPtr.Zero))
                    {
                        NodeInfo = (USB_NODE_INFORMATION)Marshal.PtrToStructure(ptrNodeInfo, typeof(USB_NODE_INFORMATION));
                        Hub.HubIsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered);
                        Hub.HubPortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
                    }
                    Marshal.FreeHGlobal(ptrNodeInfo);
                    CloseHandle(h2);
                }
                USBDevice Device = GetDevice();
                Hub.HubInstanceID = Device.DeviceInstanceID;
                Hub.HubManufacturer = Device.Manufacturer;
                Hub.HubProduct = Device.Product;
                Hub.HubSerialNumber = Device.SerialNumber;
                Hub.HubDriverKey = Device.DriverKey;
                Marshal.FreeHGlobal(ptrNodeName);
                CloseHandle(h);
            }
            return Hub;
        }
    }
    public class USBDevice
    {
        internal int DevicePortNumber;
        internal string DeviceDriverKey, DeviceHubDevicePath, DeviceInstanceID, DeviceName;
        internal string DeviceManufacturer, DeviceProduct, DeviceSerialNumber;
        internal USB_DEVICE_DESCRIPTOR DeviceDescriptor;
        public USBDevice()
        {
            DevicePortNumber = 0;
            DeviceHubDevicePath = "";
            DeviceDriverKey = "";
            DeviceManufacturer = "";
            DeviceProduct = "Unknown USB Device";
            DeviceSerialNumber = "";
            DeviceName = "";
            DeviceInstanceID = "";
        }
        public int PortNumber
        {
            get { return DevicePortNumber; }
        }
        public string HubDevicePath
        {
            get { return DeviceHubDevicePath; }
        }
        public string DriverKey
        {
            get { return DeviceDriverKey; }
        }
        public string InstanceID
        {
            get { return DeviceInstanceID; }
        }
        public string Name
        {
            get { return DeviceName; }
        }
        public string Manufacturer
        {
            get { return DeviceManufacturer; }
        }
        public string Product
        {
            get { return DeviceProduct; }
        }
        public string SerialNumber
        {
            get { return DeviceSerialNumber; }
        }
    }
    static string GetDescriptionByKeyName(string DriverKeyName)
    {
        string ans = "";
        string DevEnum = REGSTR_KEY_USB;
        IntPtr h = SetupDiGetClassDevs(0, DevEnum, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
        if (h.ToInt32() != INVALID_HANDLE_VALUE)
        {
            IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
            string KeyName;
            bool Success;
            int i = 0;
            do
            {
                SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                da.cbSize = Marshal.SizeOf(da);
                Success = SetupDiEnumDeviceInfo(h, i, ref da);
                if (Success)
                {
                    int RequiredSize = 0;
                    int RegType = REG_SZ;
                    KeyName = "";
                    if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
                    {
                        KeyName = Marshal.PtrToStringAuto(ptrBuf);
                    }
                    if (KeyName == DriverKeyName)
                    {
                        if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DEVICEDESC, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
                        {
                            ans = Marshal.PtrToStringAuto(ptrBuf);
                        }
                        break;
                    }
                }
                i++;
            } while (Success);
            Marshal.FreeHGlobal(ptrBuf);
            SetupDiDestroyDeviceInfoList(h);
        }
        return ans;
    }
    static string GetInstanceIDByKeyName(string DriverKeyName)
    {
        string ans = "";
        string DevEnum = REGSTR_KEY_USB;
        IntPtr h = SetupDiGetClassDevs(0, DevEnum, IntPtr.Zero, DIGCF_PRESENT | DIGCF_ALLCLASSES);
        if (h.ToInt32() != INVALID_HANDLE_VALUE)
        {
            IntPtr ptrBuf = Marshal.AllocHGlobal(BUFFER_SIZE);
            string KeyName;
            bool Success;
            int i = 0;
            do
            {
                SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                da.cbSize = Marshal.SizeOf(da);
                Success = SetupDiEnumDeviceInfo(h, i, ref da);
                if (Success)
                {
                    int RequiredSize = 0;
                    int RegType = REG_SZ;
                    KeyName = "";
                    if (SetupDiGetDeviceRegistryProperty(h, ref da, SPDRP_DRIVER, ref RegType, ptrBuf, BUFFER_SIZE, ref RequiredSize))
                    {
                        KeyName = Marshal.PtrToStringAuto(ptrBuf);
                    }
                    if (KeyName == DriverKeyName)
                    {
                        int nBytes = BUFFER_SIZE;
                        StringBuilder sb = new StringBuilder(nBytes);
                        SetupDiGetDeviceInstanceId(h, ref da, sb, nBytes, out RequiredSize);
                        ans = sb.ToString();
                        break;
                    }
                }
                i++;
            } while (Success);
            Marshal.FreeHGlobal(ptrBuf);
            SetupDiDestroyDeviceInfoList(h);
        }
        return ans;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM