jjzjj

c# - 检测设备是否使用 USB 3.0

coder 2024-05-27 原文

有谁知道使用 C# 检测连接到 USB 3.0 主机端口的 USB 设备是运行在 3.0 还是 2.0 的方法?

我们正在制造 USB 3.0 延长线,我们需要验证所有引脚是否已正确焊接。我们想在软件中做到这一点。我们想将 3.0 拇指驱动器连接到电缆并检查设备是否在 USB 3.0 模式下运行。如果它处于 2.0 模式,我们知道它们是 1 条或多条 USB 3.0 线的问题。

最佳答案

在一些源代码的帮助下,我设法制作了一个工作演示 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);
      }
    }
  }
}

应用程序枚举 USB 主机 Controller 。然后它获取根集线器并枚举属于它的端口。如果连接了设备但不是集线器,则会显示所需信息。

在您的情况下,您可能知道要检查哪个设备,因此您可以修改源代码(上面和链接的代码)以专门检查该设备。

您需要在 USB 类中创建一个方法,通过指定端口号和到集线器的路径从特定集线器获取特定端口。

类似于:

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

并用适当的值调用它:

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

如果您不愿意这样做,那么您可以简单地使用上面的代码并注意您要测试的设备的序列号,然后只检查速度:

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

如果您要在带有 GUI 的应用程序中使用它,您只需在下拉列表中选择要检查的设备。

嗯...有一些想法,希望有一个可行的解决方案。

附录

为了长篇大论,我将包括我用于演示的修改类。
(由于 SO 对 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;
    }
}

关于c# - 检测设备是否使用 USB 3.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15820091/

有关c# - 检测设备是否使用 USB 3.0的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐