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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 using System;
22
5b14fed54a89 USBLib: cleanup
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Runtime.InteropServices;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 using UCIS.USBLib.Internal.Windows;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 namespace UCIS.HWLib.Windows.USB {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
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
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107 }
63
309c705d7460 Updates and cleanup in Windows USB enumeration code
Ivo Smits <Ivo@UCIS.nl>
parents: 62
diff changeset
108 return null;
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 }
58
fd63c453ff65 Improved Windows USB enumeration classes
Ivo Smits <Ivo@UCIS.nl>
parents: 22
diff changeset
111 }