Mercurial > hg > ucis.core
comparison USBLib/Windows/USB/UsbHub.cs @ 58:fd63c453ff65
Improved Windows USB enumeration classes
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Wed, 09 Oct 2013 20:54:15 +0200 |
parents | 5b14fed54a89 |
children | 3424fa5a12c9 |
comparison
equal
deleted
inserted
replaced
57:b1efeada517e | 58:fd63c453ff65 |
---|---|
1 using System; | 1 using System; |
2 using System.Collections.Generic; | 2 using System.Collections.Generic; |
3 using System.Runtime.InteropServices; | 3 using System.Runtime.InteropServices; |
4 using Microsoft.Win32.SafeHandles; | 4 using Microsoft.Win32.SafeHandles; |
5 using UCIS.USBLib.Internal.Windows; | 5 using UCIS.USBLib.Internal.Windows; |
6 using System.ComponentModel; | |
7 using UCIS.USBLib.Communication; | |
6 | 8 |
7 namespace UCIS.HWLib.Windows.USB { | 9 namespace UCIS.HWLib.Windows.USB { |
8 public class UsbHub : UsbDevice { | 10 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; } | 11 public bool IsRootHub { get; private set; } |
12 internal USB_NODE_INFORMATION NodeInformation { get; private set; } | 12 internal USB_NODE_INFORMATION NodeInformation { get; private set; } |
13 private List<UsbDevice> devices = new List<UsbDevice>(); | 13 |
14 public IList<UsbDevice> Devices { get { return devices.AsReadOnly(); } } | 14 public int PortCount { get { return NodeInformation.HubInformation.HubDescriptor.bNumberOfPorts; } } |
15 public bool IsBusPowered { get { return NodeInformation.HubInformation.HubIsBusPowered; } } | |
15 public override string DeviceDescription { get { return IsRootHub ? "RootHub" : "Standard-USB-Hub"; } } | 16 public override string DeviceDescription { get { return IsRootHub ? "RootHub" : "Standard-USB-Hub"; } } |
16 internal UsbHub(UsbController parent, USB_DEVICE_DESCRIPTOR deviceDescriptor, string devicePath) | 17 |
17 : this(null, deviceDescriptor, devicePath, true) { } | 18 public override string DriverKey { |
18 internal UsbHub(UsbDevice parent, USB_DEVICE_DESCRIPTOR deviceDescriptor, string devicePath, Boolean roothub) | 19 get { |
19 : base(parent, deviceDescriptor, 0, devicePath) { | 20 if (Parent == null) return null; |
21 using (SafeFileHandle handle = OpenHandle(Parent.DevicePath)) return UsbHub.GetNodeConnectionDriverKey(handle, AdapterNumber); | |
22 } | |
23 } | |
24 | |
25 internal UsbHub(UsbDevice parent, USB_NODE_CONNECTION_INFORMATION_EX nci, string devicePath, uint port, Boolean roothub) | |
26 : base(parent, nci, port, devicePath) { | |
20 this.IsRootHub = roothub; | 27 this.IsRootHub = roothub; |
21 | 28 using (SafeFileHandle handle = OpenHandle(DevicePath)) { |
22 // TODO: Get the driver key name for the root hub. | 29 USB_NODE_INFORMATION NodeInfo; |
23 // Now let's open the hub (based upon the hub name we got above). | 30 GetNodeInformation(handle, out NodeInfo); |
24 using (SafeFileHandle handel2 = Kernel32.CreateFile(this.DevicePath, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero)) { | 31 this.NodeInformation = NodeInfo; |
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 } | 32 } |
40 } | 33 } |
41 | 34 |
42 private static UsbDevice BuildDevice(UsbDevice parent, uint portCount, string devicePath, SafeFileHandle handel1) { | 35 public override int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) { |
43 int nBytesReturned; | 36 if (Parent == null) return 0; |
44 int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX)); | 37 using (SafeFileHandle handle = UsbHub.OpenHandle(Parent.DevicePath)) return UsbHub.GetDescriptor(handle, AdapterNumber, descriptorType, index, langId, buffer, offset, length); |
45 USB_NODE_CONNECTION_INFORMATION_EX nodeConnection = new USB_NODE_CONNECTION_INFORMATION_EX(); | 38 } |
46 nodeConnection.ConnectionIndex = portCount; | |
47 | 39 |
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 | 40 |
54 UsbDevice _Device = null; | 41 public IList<UsbDevice> Devices { |
55 if (!isConnected) { | 42 get { |
56 _Device = new UsbDevice(parent, null, portCount); | 43 List<UsbDevice> devices = new List<UsbDevice>(); |
44 using (SafeFileHandle handle = OpenHandle(DevicePath)) { | |
45 for (uint index = 1; index <= PortCount; index++) { | |
46 devices.Add(BuildDevice(this, index, this.DevicePath, handle)); | |
47 } | |
48 } | |
49 return devices; | |
50 } | |
51 } | |
52 | |
53 internal static UsbDevice BuildDevice(UsbDevice parent, uint portCount, string devicePath) { | |
54 using (SafeFileHandle handle = OpenHandle(devicePath)) return BuildDevice(parent, portCount, devicePath, handle); | |
55 } | |
56 internal static UsbDevice BuildDevice(UsbDevice parent, uint portCount, string devicePath, SafeFileHandle handle) { | |
57 USB_NODE_CONNECTION_INFORMATION_EX nodeConnection; | |
58 if (!GetNodeConnectionInformation(handle, portCount, out nodeConnection)) throw new Win32Exception(Marshal.GetLastWin32Error()); | |
59 UsbDevice device = null; | |
60 if (nodeConnection.ConnectionStatus != USB_CONNECTION_STATUS.DeviceConnected) { | |
61 device = new UsbDevice(parent, nodeConnection, portCount, devicePath); | |
57 } else if (nodeConnection.DeviceDescriptor.bDeviceClass == UsbDeviceClass.HubDevice) { | 62 } else if (nodeConnection.DeviceDescriptor.bDeviceClass == UsbDeviceClass.HubDevice) { |
58 nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_NAME)); | 63 String nodeName = GetNodeConnectionName(handle, portCount); |
59 USB_NODE_CONNECTION_NAME nameConnection = new USB_NODE_CONNECTION_NAME(); | 64 device = new UsbHub(parent, nodeConnection, @"\\?\" + nodeName, portCount, false); |
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 } else { |
65 _Device = new UsbDevice(parent, nodeConnection.DeviceDescriptor, portCount, devicePath); | 66 device = new UsbDevice(parent, nodeConnection, portCount, devicePath); |
66 } | 67 } |
67 _Device.NodeConnectionInfo = nodeConnection; | 68 device.NodeConnectionInfo = nodeConnection; |
68 _Device.AdapterNumber = _Device.NodeConnectionInfo.ConnectionIndex; | 69 return device; |
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 } | 70 } |
75 } | 71 } |
76 } | 72 } |