21
|
1 using System; |
22
|
2 using System.Collections.Generic; |
21
|
3 using System.Runtime.InteropServices; |
|
4 using Microsoft.Win32.SafeHandles; |
|
5 using UCIS.USBLib.Internal.Windows; |
|
6 |
|
7 namespace UCIS.HWLib.Windows.USB { |
|
8 public class UsbHub : UsbDevice { |
|
9 public int PortCount { get; private set; } |
|
10 public bool IsBusPowered { get; private set; } |
|
11 public bool IsRootHub { get; private set; } |
|
12 internal USB_NODE_INFORMATION NodeInformation { get; private set; } |
|
13 private List<UsbDevice> devices = new List<UsbDevice>(); |
|
14 public IList<UsbDevice> Devices { get { return devices.AsReadOnly(); } } |
|
15 public override string DeviceDescription { get { return IsRootHub ? "RootHub" : "Standard-USB-Hub"; } } |
|
16 internal UsbHub(UsbController parent, USB_DEVICE_DESCRIPTOR deviceDescriptor, string devicePath) |
|
17 : this(null, deviceDescriptor, devicePath, true) { } |
|
18 internal UsbHub(UsbDevice parent, USB_DEVICE_DESCRIPTOR deviceDescriptor, string devicePath, Boolean roothub) |
|
19 : base(parent, deviceDescriptor, 0, devicePath) { |
|
20 this.IsRootHub = roothub; |
|
21 |
|
22 // TODO: Get the driver key name for the root hub. |
|
23 // Now let's open the hub (based upon the hub name we got above). |
|
24 using (SafeFileHandle handel2 = Kernel32.CreateFile(this.DevicePath, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero)) { |
|
25 if (handel2.IsInvalid) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); |
|
26 USB_NODE_INFORMATION NodeInfo = new USB_NODE_INFORMATION(); |
|
27 int nBytes = Marshal.SizeOf(typeof(USB_NODE_INFORMATION)); // Marshal.SizeOf(NodeInfo); |
|
28 // Get the hub information. |
|
29 int nBytesReturned = -1; |
|
30 if (Kernel32.DeviceIoControl(handel2, UsbApi.IOCTL_USB_GET_NODE_INFORMATION, ref NodeInfo, nBytes, out NodeInfo, nBytes, out nBytesReturned, IntPtr.Zero)) { |
|
31 this.NodeInformation = NodeInfo; |
|
32 this.IsBusPowered = Convert.ToBoolean(NodeInfo.HubInformation.HubIsBusPowered); |
|
33 this.PortCount = NodeInfo.HubInformation.HubDescriptor.bNumberOfPorts; |
|
34 } |
|
35 |
|
36 for (uint index = 1; index <= PortCount; index++) { |
|
37 devices.Add(BuildDevice(this, index, this.DevicePath, handel2)); |
|
38 } |
|
39 } |
|
40 } |
|
41 |
|
42 private static UsbDevice BuildDevice(UsbDevice parent, uint portCount, string devicePath, SafeFileHandle handel1) { |
|
43 int nBytesReturned; |
|
44 int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX)); |
|
45 USB_NODE_CONNECTION_INFORMATION_EX nodeConnection = new USB_NODE_CONNECTION_INFORMATION_EX(); |
|
46 nodeConnection.ConnectionIndex = portCount; |
|
47 |
|
48 //DateTime t = DateTime.Now; |
|
49 if (!Kernel32.DeviceIoControl(handel1, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ref nodeConnection, nBytes, out nodeConnection, nBytes, out nBytesReturned, IntPtr.Zero)) |
|
50 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); |
|
51 //Console.WriteLine("IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX took {0} ms (class={1})", DateTime.Now.Subtract(t).TotalMilliseconds, nodeConnection.DeviceDescriptor.bDeviceClass); |
|
52 bool isConnected = (nodeConnection.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected); |
|
53 |
|
54 UsbDevice _Device = null; |
|
55 if (!isConnected) { |
|
56 _Device = new UsbDevice(parent, null, portCount); |
|
57 } else if (nodeConnection.DeviceDescriptor.bDeviceClass == UsbDeviceClass.HubDevice) { |
|
58 nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_NAME)); |
|
59 USB_NODE_CONNECTION_NAME nameConnection = new USB_NODE_CONNECTION_NAME(); |
|
60 nameConnection.ConnectionIndex = portCount; |
|
61 if (!Kernel32.DeviceIoControl(handel1, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_NAME, ref nameConnection, nBytes, out nameConnection, nBytes, out nBytesReturned, IntPtr.Zero)) |
|
62 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); |
|
63 _Device = new UsbHub(parent, nodeConnection.DeviceDescriptor, @"\\?\" + nameConnection.NodeName, false); |
|
64 } else { |
|
65 _Device = new UsbDevice(parent, nodeConnection.DeviceDescriptor, portCount, devicePath); |
|
66 } |
|
67 _Device.NodeConnectionInfo = nodeConnection; |
|
68 _Device.AdapterNumber = _Device.NodeConnectionInfo.ConnectionIndex; |
|
69 _Device.Status = ((USB_CONNECTION_STATUS)_Device.NodeConnectionInfo.ConnectionStatus).ToString(); |
|
70 _Device.Speed = ((USB_DEVICE_SPEED)_Device.NodeConnectionInfo.Speed).ToString(); |
|
71 _Device.IsConnected = isConnected; |
|
72 _Device.IsHub = Convert.ToBoolean(_Device.NodeConnectionInfo.DeviceIsHub); |
|
73 return _Device; |
|
74 } |
|
75 } |
|
76 } |