Mercurial > hg > ucis.core
annotate USBLib/Windows/USB/UsbHub.cs @ 111:df53bdd49507 default tip
Merge
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Fri, 07 Nov 2014 18:37:39 +0100 |
parents | 9b898d8b2541 |
children |
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)); |
87
9b898d8b2541
Small improvements in Windows USB device handling
Ivo Smits <Ivo@UCIS.nl>
parents:
68
diff
changeset
|
25 using (SafeFileHandle handle = OpenHandle()) |
9b898d8b2541
Small improvements in Windows USB device handling
Ivo Smits <Ivo@UCIS.nl>
parents:
68
diff
changeset
|
26 HasNodeInformation = Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_INFORMATION, ref NodeInformation, nBytes, out NodeInformation, nBytes, out nBytes, IntPtr.Zero); |
21 | 27 } |
28 | |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
29 public bool IsRootHub { get; private set; } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
30 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
|
31 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
|
32 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
|
33 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
34 public String DevicePath { get; private set; } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
35 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
36 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
|
37 : base(null, parent, port) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
38 this.DevicePath = devicePath; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
39 this.IsRootHub = (parent == null); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
40 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
|
41 } |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
42 |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
43 private UsbHub(DeviceNode devnode, string devicePath) |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
44 : base(devnode, null, 0) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
45 this.DevicePath = devicePath; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
46 this.IsRootHub = false; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
47 } |
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 internal SafeFileHandle OpenHandle() { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
50 return OpenHandle(DevicePath); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
51 } |
21 | 52 |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
53 public IList<UsbDevice> Devices { |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
54 get { |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
55 UsbDevice[] devices = new UsbDevice[PortCount]; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
56 using (SafeFileHandle handle = OpenHandle()) { |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
57 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
|
58 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
|
59 UsbDevice device; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
60 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
|
61 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
|
62 } 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
|
63 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
|
64 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
|
65 nameConnection.ConnectionIndex = index; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
66 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
|
67 throw new Win32Exception(Marshal.GetLastWin32Error()); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
68 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
|
69 } else { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
70 device = new UsbDevice(null, this, index); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
71 } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
72 device.SetNodeConnectionInfo(nodeConnection); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
73 devices[index - 1] = device; |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
74 } |
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 return devices; |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
77 } |
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
78 } |
21 | 79 |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
80 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
|
81 public static UsbHub GetHubForDeviceNode(DeviceNode node) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
82 if (node == null) return null; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
83 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
|
84 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
|
85 return new UsbHub(node, interfaces[0]); |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
86 } |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
87 |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
88 public static IList<UsbHub> GetHubs() { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
89 IList<UsbHub> devices = new List<UsbHub>(); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
90 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
|
91 UsbHub hub = GetHubForDeviceNode(dev); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
92 if (hub != null) devices.Add(hub); |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
93 } |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
94 return devices; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
95 } |
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 public UsbDevice FindChildForDeviceNode(DeviceNode node) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
98 String driverkey = node.DriverKey; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
99 if (driverkey != null) { |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
100 foreach (UsbDevice child in Devices) if (driverkey.Equals(child.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return child; |
21 | 101 } else { |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
102 int? address = node.Address; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
103 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
|
104 int port = address.Value; |
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
105 foreach (UsbDevice child in Devices) if (port == child.AdapterNumber) return child; |
21 | 106 } |
63
309c705d7460
Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents:
62
diff
changeset
|
107 return null; |
21 | 108 } |
109 } | |
58
fd63c453ff65
Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
110 } |