Mercurial > hg > ucis.core
annotate USBLib/Windows/USB/UsbHub.cs @ 68:e811297f5aa4
Updated USBLib: removed old LibUsbDotNet compatibility code and added new information helper classes
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Wed, 16 Oct 2013 16:58:39 +0200 |
parents | 309c705d7460 |
children | 9b898d8b2541 |
rev | line source |
---|---|
21 | 1 using System; |
22 | 2 using System.Collections.Generic; |
60
3424fa5a12c9
Updated Windows USB enumeration classes and VBoxUSB backend
Ivo Smits <Ivo@UCIS.nl>
parents:
58
diff
changeset
|
3 using System.ComponentModel; |
21 | 4 using System.Runtime.InteropServices; |
5 using Microsoft.Win32.SafeHandles; | |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
6 using UCIS.HWLib.Windows.Devices; |
68
e811297f5aa4
Updated USBLib: removed old LibUsbDotNet compatibility code and added new information helper classes
Ivo Smits <Ivo@UCIS.nl>
parents:
63
diff
changeset
|
7 using UCIS.USBLib.Descriptor; |
21 | 8 using UCIS.USBLib.Internal.Windows; |
9 | |
10 namespace UCIS.HWLib.Windows.USB { | |
11 public class UsbHub : UsbDevice { | |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
12 internal static SafeFileHandle OpenHandle(String path) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
13 SafeFileHandle handle = Kernel32.CreateFile(path, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
14 if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
15 return handle; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
16 } |
21 | 17 |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
18 private Boolean HasNodeInformation = false; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
19 private USB_NODE_INFORMATION NodeInformation; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
20 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
21 private void GetNodeInformation() { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
22 if (HasNodeInformation) return; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
23 NodeInformation = new USB_NODE_INFORMATION(); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
24 int nBytes = Marshal.SizeOf(typeof(USB_NODE_INFORMATION)); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
25 using (SafeFileHandle handle = OpenHandle()) |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
26 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_INFORMATION, ref NodeInformation, nBytes, out NodeInformation, nBytes, out nBytes, IntPtr.Zero)) |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
27 throw new Win32Exception(Marshal.GetLastWin32Error()); |
21 | 28 } |
29 | |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
30 public bool IsRootHub { get; private set; } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
31 public int PortCount { get { GetNodeInformation(); return NodeInformation.HubInformation.HubDescriptor.bNumberOfPorts; } } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
32 public bool IsBusPowered { get { GetNodeInformation(); return NodeInformation.HubInformation.HubIsBusPowered; } } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
33 public override string DeviceDescription { get { return IsRootHub ? "Root hub" : base.DeviceDescription; } } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
34 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
35 public String DevicePath { get; private set; } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
36 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
37 internal UsbHub(UsbHub parent, string devicePath, uint port) |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
38 : base(null, parent, port) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
39 this.DevicePath = devicePath; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
40 this.IsRootHub = (parent == null); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
41 if (IsRootHub) SetNodeConnectionInfo(new USB_NODE_CONNECTION_INFORMATION_EX()); |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
42 } |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
43 |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
44 private UsbHub(DeviceNode devnode, string devicePath) |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
45 : base(devnode, null, 0) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
46 this.DevicePath = devicePath; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
47 this.IsRootHub = false; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
48 } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
49 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
50 internal SafeFileHandle OpenHandle() { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
51 return OpenHandle(DevicePath); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
52 } |
21 | 53 |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
54 public IList<UsbDevice> Devices { |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
55 get { |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
56 UsbDevice[] devices = new UsbDevice[PortCount]; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
57 using (SafeFileHandle handle = OpenHandle()) { |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
58 for (uint index = 1; index <= PortCount; index++) { |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
59 USB_NODE_CONNECTION_INFORMATION_EX nodeConnection = GetNodeConnectionInformation(handle, index); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
60 UsbDevice device; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
61 if (nodeConnection.ConnectionStatus != USB_CONNECTION_STATUS.DeviceConnected) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
62 device = new UsbDevice(null, this, index); |
68
e811297f5aa4
Updated USBLib: removed old LibUsbDotNet compatibility code and added new information helper classes
Ivo Smits <Ivo@UCIS.nl>
parents:
63
diff
changeset
|
63 } else if (nodeConnection.DeviceDescriptor.DeviceClass == UsbClassCode.Hub) { |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
64 int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_NAME)); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
65 USB_NODE_CONNECTION_NAME nameConnection = new USB_NODE_CONNECTION_NAME(); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
66 nameConnection.ConnectionIndex = index; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
67 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_NAME, ref nameConnection, nBytes, out nameConnection, nBytes, out nBytes, IntPtr.Zero)) |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
68 throw new Win32Exception(Marshal.GetLastWin32Error()); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
69 device = new UsbHub(this, @"\\?\" + nameConnection.NodeName, index); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
70 } else { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
71 device = new UsbDevice(null, this, index); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
72 } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
73 device.SetNodeConnectionInfo(nodeConnection); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
74 devices[index - 1] = device; |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
75 } |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
76 } |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
77 return devices; |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
78 } |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
79 } |
21 | 80 |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
81 static readonly Guid IID_DEVINTERFACE_USB_HUB = new Guid(UsbApi.GUID_DEVINTERFACE_USB_HUB); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
82 public static UsbHub GetHubForDeviceNode(DeviceNode node) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
83 if (node == null) return null; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
84 String[] interfaces = node.GetInterfaces(IID_DEVINTERFACE_USB_HUB); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
85 if (interfaces == null || interfaces.Length == 0) return null; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
86 return new UsbHub(node, interfaces[0]); |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
87 } |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
88 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
89 public static IList<UsbHub> GetHubs() { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
90 IList<UsbHub> devices = new List<UsbHub>(); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
91 foreach (DeviceNode dev in DeviceNode.GetDevices(IID_DEVINTERFACE_USB_HUB)) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
92 UsbHub hub = GetHubForDeviceNode(dev); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
93 if (hub != null) devices.Add(hub); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
94 } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
95 return devices; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
96 } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
97 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
98 public UsbDevice FindChildForDeviceNode(DeviceNode node) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
99 String driverkey = node.DriverKey; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
100 if (driverkey != null) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
101 foreach (UsbDevice child in Devices) if (driverkey.Equals(child.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return child; |
21 | 102 } else { |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
103 int? address = node.Address; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
104 if (address == null || address.Value == 0) return null; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
105 int port = address.Value; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
106 foreach (UsbDevice child in Devices) if (port == child.AdapterNumber) return child; |
21 | 107 } |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
108 return null; |
21 | 109 } |
110 } | |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
111 } |