检测设备是否使用USB 3.0

有没有人知道如何使用C#检测连接到USB 3.0主机端口的USB设备是以3.0还是2.0运行?

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

我已经设法在我找到的一些源代码的帮助下做了一个工作演示。

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主机控制器。 然后它获取根集线器并使用属于它的端口。 如果连接了设备且它不是集线器,则会显示所需信息。

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

您需要在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的应用程序中使用此function,则只需在下拉列表中选择要检查的设备即可。

嗯……有一些想法,希望是一个有效的解决方案。

附录

为了长寿,我将包括我用于演示的修改过的类。
由于300个字符的SO限制,注释和空行被删除 ):

 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 GetHostControllers() { List HostList = new List(); 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(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 GetPorts() { List PortList = new List(); 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(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; } }