comparison USBLib/Windows/USB/UsbDevice.cs @ 60:3424fa5a12c9

Updated Windows USB enumeration classes and VBoxUSB backend
author Ivo Smits <Ivo@UCIS.nl>
date Sat, 12 Oct 2013 16:35:24 +0200
parents fd63c453ff65
children 2b24666cd759
comparison
equal deleted inserted replaced
59:4e1a5dec786a 60:3424fa5a12c9
1 using System; 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel; 2 using System.ComponentModel;
4 using System.Runtime.InteropServices; 3 using System.Runtime.InteropServices;
5 using System.Text;
6 using Microsoft.Win32.SafeHandles; 4 using Microsoft.Win32.SafeHandles;
7 using UCIS.HWLib.Windows.Devices; 5 using UCIS.HWLib.Windows.Devices;
8 using UCIS.USBLib.Communication; 6 using UCIS.USBLib.Communication;
9 using UCIS.USBLib.Descriptor; 7 using UCIS.USBLib.Descriptor;
10 using UCIS.USBLib.Internal.Windows; 8 using UCIS.USBLib.Internal.Windows;
11 9
12 namespace UCIS.HWLib.Windows.USB { 10 namespace UCIS.HWLib.Windows.USB {
13 public class UsbDevice : IUsbInterface { 11 public class UsbDevice : IUsbDevice, IUsbInterface {
14 internal static SafeFileHandle OpenHandle(String path) { 12 protected internal static SafeFileHandle OpenHandle(String path) {
15 SafeFileHandle handle = Kernel32.CreateFile(path, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero); 13 SafeFileHandle handle = Kernel32.CreateFile(path, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero);
16 if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); 14 if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
17 return handle; 15 return handle;
18 } 16 }
19 internal static Boolean GetNodeInformation(SafeFileHandle handle, out USB_NODE_INFORMATION nodeInfo) { 17 internal static Boolean GetNodeInformation(SafeFileHandle handle, out USB_NODE_INFORMATION nodeInfo) {
27 nodeConnection.ConnectionIndex = port; 25 nodeConnection.ConnectionIndex = port;
28 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ref nodeConnection, nBytes, out nodeConnection, nBytes, out nBytes, IntPtr.Zero)) 26 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ref nodeConnection, nBytes, out nodeConnection, nBytes, out nBytes, IntPtr.Zero))
29 throw new Win32Exception(Marshal.GetLastWin32Error()); 27 throw new Win32Exception(Marshal.GetLastWin32Error());
30 return true; 28 return true;
31 } 29 }
32 internal static String GetNodeConnectionName(SafeFileHandle handle, UInt32 port) { 30 protected static String GetNodeConnectionName(SafeFileHandle handle, UInt32 port) {
33 int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_NAME)); 31 int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_NAME));
34 USB_NODE_CONNECTION_NAME nameConnection = new USB_NODE_CONNECTION_NAME(); 32 USB_NODE_CONNECTION_NAME nameConnection = new USB_NODE_CONNECTION_NAME();
35 nameConnection.ConnectionIndex = port; 33 nameConnection.ConnectionIndex = port;
36 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_NAME, ref nameConnection, nBytes, out nameConnection, nBytes, out nBytes, IntPtr.Zero)) 34 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_NAME, ref nameConnection, nBytes, out nameConnection, nBytes, out nBytes, IntPtr.Zero))
37 throw new Win32Exception(Marshal.GetLastWin32Error()); 35 throw new Win32Exception(Marshal.GetLastWin32Error());
38 return nameConnection.NodeName; 36 return nameConnection.NodeName;
39 } 37 }
40 internal unsafe static int GetDescriptor(SafeFileHandle handle, UInt32 port, byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) { 38 protected unsafe static int GetDescriptor(SafeFileHandle handle, UInt32 port, byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) {
41 int szRequest = Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST)); 39 int szRequest = Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST));
42 USB_DESCRIPTOR_REQUEST request = new USB_DESCRIPTOR_REQUEST(); 40 USB_DESCRIPTOR_REQUEST request = new USB_DESCRIPTOR_REQUEST();
43 request.ConnectionIndex = port; 41 request.ConnectionIndex = port;
44 request.SetupPacket.wValue = (ushort)((descriptorType << 8) + index); 42 request.SetupPacket.wValue = (ushort)((descriptorType << 8) + index);
45 request.SetupPacket.wIndex = (ushort)langId; 43 request.SetupPacket.wIndex = (ushort)langId;
55 if (nBytes > length) nBytes = length; 53 if (nBytes > length) nBytes = length;
56 if (nBytes < 0) return 0; 54 if (nBytes < 0) return 0;
57 if (nBytes > 0) Buffer.BlockCopy(bigbuffer, szRequest, buffer, offset, nBytes); 55 if (nBytes > 0) Buffer.BlockCopy(bigbuffer, szRequest, buffer, offset, nBytes);
58 return nBytes; 56 return nBytes;
59 } 57 }
60 internal unsafe static String GetRootHubName(SafeFileHandle handle) { 58 protected internal unsafe static String GetRootHubName(SafeFileHandle handle) {
61 USB_ROOT_HUB_NAME rootHubName = new USB_ROOT_HUB_NAME(); 59 USB_ROOT_HUB_NAME rootHubName = new USB_ROOT_HUB_NAME();
62 int nBytesReturned; 60 int nBytesReturned;
63 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_ROOT_HUB_NAME, IntPtr.Zero, 0, out rootHubName, Marshal.SizeOf(rootHubName), out nBytesReturned, IntPtr.Zero)) 61 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_ROOT_HUB_NAME, IntPtr.Zero, 0, out rootHubName, Marshal.SizeOf(rootHubName), out nBytesReturned, IntPtr.Zero))
64 throw new Win32Exception(Marshal.GetLastWin32Error()); 62 throw new Win32Exception(Marshal.GetLastWin32Error());
65 if (rootHubName.ActualLength <= 0) return null; 63 if (rootHubName.ActualLength <= 0) return null;
66 return rootHubName.RootHubName; 64 return rootHubName.RootHubName;
67 } 65 }
68 internal unsafe static String GetNodeConnectionDriverKey(SafeFileHandle handle, UInt32 port) { 66 protected unsafe static String GetNodeConnectionDriverKey(SafeFileHandle handle, UInt32 port) {
69 USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKeyStruct = new USB_NODE_CONNECTION_DRIVERKEY_NAME(); 67 USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKeyStruct = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
70 int nBytes = Marshal.SizeOf(DriverKeyStruct); 68 int nBytes = Marshal.SizeOf(DriverKeyStruct);
71 DriverKeyStruct.ConnectionIndex = port; 69 DriverKeyStruct.ConnectionIndex = port;
72 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ref DriverKeyStruct, nBytes, out DriverKeyStruct, nBytes, out nBytes, IntPtr.Zero)) 70 if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ref DriverKeyStruct, nBytes, out DriverKeyStruct, nBytes, out nBytes, IntPtr.Zero))
73 return null; 71 return null;
74 return DriverKeyStruct.DriverKeyName; 72 return DriverKeyStruct.DriverKeyName;
75 } 73 }
76 74
77 public UsbDevice Parent { get; protected set; } 75 public UsbDevice Parent { get; protected set; }
78 public string DevicePath { get; private set; } 76 public String DevicePath { get; private set; }
79 public uint AdapterNumber { get; private set; } 77 public UInt32 AdapterNumber { get; private set; }
80 internal USB_NODE_CONNECTION_INFORMATION_EX NodeConnectionInfo { get; set; } 78 internal USB_NODE_CONNECTION_INFORMATION_EX NodeConnectionInfo { get; set; }
81 internal USB_DEVICE_DESCRIPTOR DeviceDescriptor { get { return NodeConnectionInfo.DeviceDescriptor; } } 79 private USB_DEVICE_DESCRIPTOR DeviceDescriptor { get { return NodeConnectionInfo.DeviceDescriptor; } }
82 80
83 public bool IsHub { get { return NodeConnectionInfo.DeviceIsHub != 0; } } 81 public bool IsHub { get { return NodeConnectionInfo.DeviceIsHub != 0; } }
84 public bool IsConnected { get { return NodeConnectionInfo.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected; } } 82 public bool IsConnected { get { return NodeConnectionInfo.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected; } }
85 public string Status { get { return NodeConnectionInfo.ConnectionStatus.ToString(); } } 83 public string Status { get { return NodeConnectionInfo.ConnectionStatus.ToString(); } }
86 public string Speed { get { return NodeConnectionInfo.Speed.ToString(); } } 84 public string Speed { get { return NodeConnectionInfo.Speed.ToString(); } }
103 public string Manufacturer { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iManufacturer); } } 101 public string Manufacturer { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iManufacturer); } }
104 public string Product { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iProduct); } } 102 public string Product { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iProduct); } }
105 public string SerialNumber { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iSerialNumber); } } 103 public string SerialNumber { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iSerialNumber); } }
106 public virtual string DriverKey { get { using (SafeFileHandle handle = OpenHandle(DevicePath)) return UsbHub.GetNodeConnectionDriverKey(handle, AdapterNumber); } } 104 public virtual string DriverKey { get { using (SafeFileHandle handle = OpenHandle(DevicePath)) return UsbHub.GetNodeConnectionDriverKey(handle, AdapterNumber); } }
107 105
108 public virtual string DeviceDescription { get { return DeviceNode == null ? null : DeviceNode.GetPropertyString(CMRDP.DEVICEDESC); } } 106 public virtual string DeviceDescription { get { return DeviceNode == null ? null : DeviceNode.DeviceDescription; } }
109 public string DeviceID { get { return DeviceNode == null ? null : DeviceNode.DeviceID; } } 107 public string DeviceID { get { return DeviceNode == null ? null : DeviceNode.DeviceID; } }
110 108
111 private DeviceNode mDeviceNode; 109 private DeviceNode mDeviceNode;
112 public DeviceNode DeviceNode { 110 public DeviceNode DeviceNode {
113 get { 111 get {
135 private String GetStringDescriptor(Byte index) { 133 private String GetStringDescriptor(Byte index) {
136 return UsbStringDescriptor.GetStringFromDevice(this, index, 0); //0x409 134 return UsbStringDescriptor.GetStringFromDevice(this, index, 0); //0x409
137 } 135 }
138 136
139 static UsbDevice GetUsbDevice(DeviceNode node, out Boolean isHostController) { 137 static UsbDevice GetUsbDevice(DeviceNode node, out Boolean isHostController) {
140 String[] hciinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_HOST_CONTROLLER); 138 UsbController controller = UsbController.GetControllerForDeviceNode(node);
141 if (hciinterface != null && hciinterface.Length > 0) { 139 if (controller != null) {
142 isHostController = true; 140 isHostController = true;
143 return (new UsbController(null, node, hciinterface[0])).RootHub; 141 return controller.RootHub;
144 } 142 }
145 isHostController = false; 143 isHostController = false;
146 DeviceNode parent = node.GetParent(); 144 DeviceNode parent = node.GetParent();
147 Boolean isHostControllerA; 145 Boolean isHostControllerA;
148 UsbDevice usbdev = GetUsbDevice(parent, out isHostControllerA); 146 UsbDevice usbdev = GetUsbDevice(parent, out isHostControllerA);
149 if (isHostControllerA) return usbdev; 147 if (isHostControllerA) return usbdev;
150 UsbHub usbhub = usbdev as UsbHub; 148 UsbHub usbhub = usbdev as UsbHub;
151 if (usbhub == null) return null; 149 if (usbhub == null) {
150 if (parent.Service == "usbccgp") return usbdev;
151 return null;
152 }
152 String driverkey = node.DriverKey; 153 String driverkey = node.DriverKey;
154 if (driverkey == null) return null;
153 foreach (UsbDevice child in usbhub.Devices) { 155 foreach (UsbDevice child in usbhub.Devices) {
154 if (driverkey.Equals(child.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return child; 156 if (driverkey.Equals(child.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return child;
155 } 157 }
156 return null; 158 return null;
157 } 159 }
158 public static UsbDevice GetUsbDevice(DeviceNode node) { 160 public static UsbDevice GetUsbDevice(DeviceNode node) {
159 Boolean isHostController; 161 Boolean isHostController;
160 return GetUsbDevice(node, out isHostController); 162 return GetUsbDevice(node, out isHostController);
161 /*
162
163 String[] hubinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_HUB);
164 if (hubinterface != null && hubinterface.Length > 0) {
165 USB_NODE_CONNECTION_INFORMATION_EX nodeConnection;
166 using (SafeFileHandle handle = OpenHandle(hubinterface[0])) {
167 if (!GetNodeConnectionInformation(handle, 0, out nodeConnection)) return null;
168 }
169 return new UsbHub(null, nodeConnection, hubinterface[0], false);
170 }
171 String[] devinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_DEVICE);
172 if (devinterface == null || devinterface.Length == 0) return null;
173 DeviceNode parent = node.GetParent();
174 if (parent == null) return null;
175 UsbHub usbhub = GetUsbDevice(parent) as UsbHub;
176 if (usbhub == null) return null;
177 String driverkey = node.DriverKey;
178 foreach (UsbDevice usbdev in usbhub.Devices) {
179 if (driverkey.Equals(usbdev.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return usbdev;
180 }
181 return null;*/
182 } 163 }
183 164
184 #region IUsbInterface Members 165 #region IUsbInterface Members
185 byte IUsbInterface.Configuration { get { throw new NotImplementedException(); } } 166 byte IUsbInterface.Configuration { get { throw new NotImplementedException(); } }
186 void IUsbInterface.Close() { } 167 void IUsbInterface.Close() { }
200 int IUsbInterface.ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotImplementedException(); } 181 int IUsbInterface.ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
201 UsbPipeStream IUsbInterface.GetBulkStream(byte endpoint) { throw new NotImplementedException(); } 182 UsbPipeStream IUsbInterface.GetBulkStream(byte endpoint) { throw new NotImplementedException(); }
202 UsbPipeStream IUsbInterface.GetInterruptStream(byte endpoint) { throw new NotImplementedException(); } 183 UsbPipeStream IUsbInterface.GetInterruptStream(byte endpoint) { throw new NotImplementedException(); }
203 void IDisposable.Dispose() { } 184 void IDisposable.Dispose() { }
204 #endregion 185 #endregion
186 #region IUsbDevice Members
187 byte IUsbDevice.Configuration { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } }
188 void IUsbDevice.ClaimInterface(int interfaceID) { }
189 void IUsbDevice.ReleaseInterface(int interfaceID) { }
190 void IUsbDevice.ResetDevice() { throw new NotSupportedException(); }
191 IUsbDeviceRegistry IUsbDevice.Registry { get { throw new NotImplementedException(); } }
192 #endregion
205 } 193 }
206
207 } 194 }