diff USBLib/Windows/USB/UsbDevice.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
line wrap: on
line diff
--- a/USBLib/Windows/USB/UsbDevice.cs	Fri Oct 04 13:22:21 2013 +0200
+++ b/USBLib/Windows/USB/UsbDevice.cs	Wed Oct 09 20:54:15 2013 +0200
@@ -1,45 +1,120 @@
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Runtime.InteropServices;
 using System.Text;
 using Microsoft.Win32.SafeHandles;
 using UCIS.HWLib.Windows.Devices;
+using UCIS.USBLib.Communication;
+using UCIS.USBLib.Descriptor;
 using UCIS.USBLib.Internal.Windows;
 
 namespace UCIS.HWLib.Windows.USB {
-	public class UsbDevice {
-		public UsbDevice Parent { get; protected set; }
-		internal USB_NODE_CONNECTION_INFORMATION_EX NodeConnectionInfo { get; set; }
-		internal USB_DEVICE_DESCRIPTOR DeviceDescriptor { get; private set; }
-		internal IList<USB_CONFIGURATION_DESCRIPTOR> ConfigurationDescriptor { get; private set; }
-		internal IList<USB_INTERFACE_DESCRIPTOR> InterfaceDescriptor { get; private set; }
-		internal IList<USB_ENDPOINT_DESCRIPTOR> EndpointDescriptor { get; private set; }
-		internal IList<HID_DESCRIPTOR> HdiDescriptor { get; private set; }
-		public string DevicePath { get; private set; }
-		public uint AdapterNumber { get; internal set; }
-		public string DriverKey { get; private set; }
+	public class UsbDevice : IUsbInterface {
+		internal static SafeFileHandle OpenHandle(String path) {
+			SafeFileHandle handle = Kernel32.CreateFile(path, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero);
+			if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
+			return handle;
+		}
+		internal static Boolean GetNodeInformation(SafeFileHandle handle, out USB_NODE_INFORMATION nodeInfo) {
+			nodeInfo = new USB_NODE_INFORMATION();
+			int nBytes = Marshal.SizeOf(typeof(USB_NODE_INFORMATION));
+			return Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_INFORMATION, ref nodeInfo, nBytes, out nodeInfo, nBytes, out nBytes, IntPtr.Zero);
+		}
+		internal static Boolean GetNodeConnectionInformation(SafeFileHandle handle, UInt32 port, out USB_NODE_CONNECTION_INFORMATION_EX nodeConnection) {
+			int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX));
+			nodeConnection = new USB_NODE_CONNECTION_INFORMATION_EX();
+			nodeConnection.ConnectionIndex = port;
+			if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, ref nodeConnection, nBytes, out nodeConnection, nBytes, out nBytes, IntPtr.Zero))
+				throw new Win32Exception(Marshal.GetLastWin32Error());
+			return true;
+		}
+		internal static String GetNodeConnectionName(SafeFileHandle handle, UInt32 port) {
+			int nBytes = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_NAME));
+			USB_NODE_CONNECTION_NAME nameConnection = new USB_NODE_CONNECTION_NAME();
+			nameConnection.ConnectionIndex = port;
+			if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_NAME, ref nameConnection, nBytes, out nameConnection, nBytes, out nBytes, IntPtr.Zero))
+				throw new Win32Exception(Marshal.GetLastWin32Error());
+			return nameConnection.NodeName;
+		}
+		internal unsafe static int GetDescriptor(SafeFileHandle handle, UInt32 port, byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) {
+			int szRequest = Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST));
+			USB_DESCRIPTOR_REQUEST request = new USB_DESCRIPTOR_REQUEST();
+			request.ConnectionIndex = port;
+			request.SetupPacket.wValue = (ushort)((descriptorType << 8) + index);
+			request.SetupPacket.wIndex = (ushort)langId;
+			request.SetupPacket.wLength = (ushort)length;
+			int nBytes = length + szRequest;
+			Byte[] bigbuffer = new Byte[nBytes];
+			if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ref request, Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST)), bigbuffer, nBytes, out nBytes, IntPtr.Zero)) {
+				int err = Marshal.GetLastWin32Error();
+				if (err != 2 && err != 31 && err != 87) throw new Win32Exception(err);
+				return 0;
+			}
+			nBytes -= szRequest;
+			if (nBytes > length) nBytes = length;
+			if (nBytes < 0) return 0;
+			if (nBytes > 0) Buffer.BlockCopy(bigbuffer, szRequest, buffer, offset, nBytes);
+			return nBytes;
+		}
+		internal unsafe static String GetRootHubName(SafeFileHandle handle) {
+			USB_ROOT_HUB_NAME rootHubName = new USB_ROOT_HUB_NAME();
+			int nBytesReturned;
+			if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_ROOT_HUB_NAME, IntPtr.Zero, 0, out rootHubName, Marshal.SizeOf(rootHubName), out nBytesReturned, IntPtr.Zero))
+				throw new Win32Exception(Marshal.GetLastWin32Error());
+			if (rootHubName.ActualLength <= 0) return null;
+			return rootHubName.RootHubName;
+		}
+		internal unsafe static String GetNodeConnectionDriverKey(SafeFileHandle handle, UInt32 port) {
+			USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKeyStruct = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
+			int nBytes = Marshal.SizeOf(DriverKeyStruct);
+			DriverKeyStruct.ConnectionIndex = port;
+			if (!Kernel32.DeviceIoControl(handle, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ref DriverKeyStruct, nBytes, out DriverKeyStruct, nBytes, out nBytes, IntPtr.Zero))
+				return null;
+			return DriverKeyStruct.DriverKeyName;
+		}
 
-		public virtual string DeviceDescription { get { return DeviceNode.GetPropertyString(CMRDP.DEVICEDESC); } }
-		public string DeviceID { get { return DeviceNode.DeviceID; } }
+		public UsbDevice Parent { get; protected set; }
+		public string DevicePath { get; private set; }
+		public uint AdapterNumber { get; private set; }
+		internal USB_NODE_CONNECTION_INFORMATION_EX NodeConnectionInfo { get; set; }
+		internal USB_DEVICE_DESCRIPTOR DeviceDescriptor { get { return NodeConnectionInfo.DeviceDescriptor; } }
+
+		public bool IsHub { get { return NodeConnectionInfo.DeviceIsHub != 0; } }
+		public bool IsConnected { get { return NodeConnectionInfo.ConnectionStatus == USB_CONNECTION_STATUS.DeviceConnected; } }
+		public string Status { get { return NodeConnectionInfo.ConnectionStatus.ToString(); } }
+		public string Speed { get { return NodeConnectionInfo.Speed.ToString(); } }
+
+		SafeFileHandle OpenHandle() {
+			return OpenHandle(DevicePath);
+		}
 
-		public bool IsConnected { get; internal set; }
-		public bool IsHub { get; internal set; }
-		public string Status { get; internal set; }
-		public string Speed { get; internal set; }
+		public int NumConfigurations { get { return DeviceDescriptor == null ? 0 : DeviceDescriptor.bNumConfigurations; } }
+		public int VendorID { get { return DeviceDescriptor == null ? 0 : DeviceDescriptor.idVendor; } }
+		public int ProductID { get { return DeviceDescriptor == null ? 0 : DeviceDescriptor.idProduct; } }
 
-		public string Manufacturer { get; private set; }
-		public string SerialNumber { get; private set; }
-		public string Product { get; private set; }
+		private String GetStringSafe(Byte id) {
+			if (id == 0) return null;
+			String s = GetStringDescriptor(id);
+			if (s == null) return s;
+			return s.Trim(' ', '\0');
+		}
 
-		public int VendorID { get { return DeviceDescriptor.idVendor; } }
-		public int ProductID { get { return DeviceDescriptor.idProduct; } }
+		public string Manufacturer { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iManufacturer); } }
+		public string Product { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iProduct); } }
+		public string SerialNumber { get { return DeviceDescriptor == null ? null : GetStringSafe(DeviceDescriptor.iSerialNumber); } }
+		public virtual string DriverKey { get { using (SafeFileHandle handle = OpenHandle(DevicePath)) return UsbHub.GetNodeConnectionDriverKey(handle, AdapterNumber); } }
+
+		public virtual string DeviceDescription { get { return DeviceNode == null ? null : DeviceNode.GetPropertyString(CMRDP.DEVICEDESC); } }
+		public string DeviceID { get { return DeviceNode == null ? null : DeviceNode.DeviceID; } }
 
 		private DeviceNode mDeviceNode;
 		public DeviceNode DeviceNode {
 			get {
-				if (mDeviceNode == null && DriverKey != null) {
+				String dk = DriverKey;
+				if (mDeviceNode == null && dk != null) {
 					foreach (DeviceNode node in DeviceNode.GetDevices("USB")) {
-						if (DriverKey.Equals(node.DriverKey, StringComparison.InvariantCultureIgnoreCase)) {
+						if (dk.Equals(node.DriverKey, StringComparison.InvariantCultureIgnoreCase)) {
 							mDeviceNode = node;
 							break;
 						}
@@ -49,131 +124,84 @@
 			}
 		}
 
-		internal UsbDevice(UsbDevice parent, USB_DEVICE_DESCRIPTOR deviceDescriptor, uint adapterNumber)
-			: this(parent, deviceDescriptor, adapterNumber, null) { }
-		unsafe internal UsbDevice(UsbDevice parent, USB_DEVICE_DESCRIPTOR deviceDescriptor, uint adapterNumber, string devicePath) {
+		internal UsbDevice(UsbDevice parent, USB_NODE_CONNECTION_INFORMATION_EX nci, uint port, string devicePath) {
 			this.Parent = parent;
-			this.AdapterNumber = adapterNumber;
-			this.DeviceDescriptor = deviceDescriptor;
+			this.NodeConnectionInfo = nci;
 			this.DevicePath = devicePath;
-			ConfigurationDescriptor = new List<USB_CONFIGURATION_DESCRIPTOR>();
-			InterfaceDescriptor = new List<USB_INTERFACE_DESCRIPTOR>();
-			HdiDescriptor = new List<HID_DESCRIPTOR>();
-			EndpointDescriptor = new List<USB_ENDPOINT_DESCRIPTOR>();
+			this.AdapterNumber = port;
 			if (devicePath == null) return;
-
-			using (SafeFileHandle handel = Kernel32.CreateFile(devicePath, Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, 0, IntPtr.Zero)) {
-				if (handel.IsInvalid) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
-				int nBytesReturned;
-				int nBytes = UsbApi.MAX_BUFFER_SIZE;
-
-				USB_DESCRIPTOR_REQUEST Request1 = new USB_DESCRIPTOR_REQUEST();
-				Request1.ConnectionIndex = adapterNumber;// portCount;
-				Request1.SetupPacket.wValue = (ushort)((UsbApi.USB_CONFIGURATION_DESCRIPTOR_TYPE << 8));
-				Request1.SetupPacket.wLength = (ushort)(nBytes - Marshal.SizeOf(Request1));
-				Request1.SetupPacket.wIndex = 0; // 0x409; // Language Code
-
-				// Use an IOCTL call to request the String Descriptor
-				Byte[] buffer = new Byte[nBytes];
-				fixed (Byte* bufferptr = buffer) {
-					if (!Kernel32.DeviceIoControl(handel, UsbApi.IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ref Request1, Marshal.SizeOf(typeof(USB_DESCRIPTOR_REQUEST)), (IntPtr)bufferptr, nBytes, out nBytesReturned, IntPtr.Zero)) {
-						int err = Marshal.GetLastWin32Error();
-						Console.WriteLine("IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION returned {0} {1}", err, (new System.ComponentModel.Win32Exception(err)).Message);
-						//SerialNumber = (new System.ComponentModel.Win32Exception(err)).Message;
-						if (err != 2 && err != 31 && err != 87) throw new System.ComponentModel.Win32Exception(err);
-					} else {
-						if (nBytesReturned > nBytes) throw new IndexOutOfRangeException("IOCtl returned too much data");
-						if (nBytesReturned < 0) throw new IndexOutOfRangeException("IOCtl returned insufficient data");
-						Byte* ptr = bufferptr + Marshal.SizeOf(Request1);
-						nBytesReturned -= Marshal.SizeOf(Request1);
-						if (nBytesReturned < 0) throw new IndexOutOfRangeException("IOCtl returned insufficient data");
+		}
 
-						int offset = 0;
-						while (offset < nBytesReturned) {
-							if (offset + Marshal.SizeOf(typeof(USB_DESCRIPTOR)) >= nBytesReturned) throw new IndexOutOfRangeException("Error in configuration descriptor");
-							USB_DESCRIPTOR* desc = (USB_DESCRIPTOR*)(ptr + offset);
-							offset += desc->bLength;
-							if (offset > nBytesReturned) throw new IndexOutOfRangeException("Error in configuration descriptor");
-							Console.WriteLine("Descriptor type {0} length {1}", desc->bDescriptorType, desc->bLength);
-							if (desc->bDescriptorType == USB_DESCRIPTOR_TYPE.ConfigurationDescriptorType) {
-								if (desc->bLength < 9) throw new IndexOutOfRangeException("Error in configuration descriptor");
-								USB_CONFIGURATION_DESCRIPTOR configurationDescriptor = *(USB_CONFIGURATION_DESCRIPTOR*)desc;
-								ConfigurationDescriptor.Add(configurationDescriptor);
-							} else if (desc->bDescriptorType == USB_DESCRIPTOR_TYPE.InterfaceDescriptorType) {
-								if (desc->bLength < 9) throw new IndexOutOfRangeException("Error in configuration descriptor");
-								USB_INTERFACE_DESCRIPTOR interfaceDescriptor = *(USB_INTERFACE_DESCRIPTOR*)desc;
-								InterfaceDescriptor.Add(interfaceDescriptor);
-							} else if (desc->bDescriptorType == USB_DESCRIPTOR_TYPE.EndpointDescriptorType) {
-								if (desc->bLength < 7) throw new IndexOutOfRangeException("Error in configuration descriptor");
-								USB_ENDPOINT_DESCRIPTOR endpointDescriptor1 = *(USB_ENDPOINT_DESCRIPTOR*)desc;
-								EndpointDescriptor.Add(endpointDescriptor1);
-							}
-						}
-					}
-					// The iManufacturer, iProduct and iSerialNumber entries in the
-					// device descriptor are really just indexes.  So, we have to 
-					// request a string descriptor to get the values for those strings.
-					if (DeviceDescriptor != null) {
-						if (DeviceDescriptor.iManufacturer > 0) Manufacturer = GetStringDescriptor(handel, DeviceDescriptor.iManufacturer);
-						if (DeviceDescriptor.iProduct > 0) Product = GetStringDescriptor(handel, DeviceDescriptor.iProduct);
-						if (DeviceDescriptor.iSerialNumber > 0) SerialNumber = GetStringDescriptor(handel, DeviceDescriptor.iSerialNumber);
-					}
-				}
-				// Get the Driver Key Name (usefull in locating a device)
-				USB_NODE_CONNECTION_DRIVERKEY_NAME DriverKeyStruct = new USB_NODE_CONNECTION_DRIVERKEY_NAME();
-				DriverKeyStruct.ConnectionIndex = adapterNumber;
-				// Use an IOCTL call to request the Driver Key Name
-				if (Kernel32.DeviceIoControl(handel, UsbApi.IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ref DriverKeyStruct, Marshal.SizeOf(DriverKeyStruct), out DriverKeyStruct, Marshal.SizeOf(DriverKeyStruct), out nBytesReturned, IntPtr.Zero)) {
-					DriverKey = DriverKeyStruct.DriverKeyName;
-				}
-			}
+		private String GetStringDescriptor(Byte index) {
+			return UsbStringDescriptor.GetStringFromDevice(this, index, 0); //0x409
 		}
 
-		private unsafe String GetStringDescriptor(SafeFileHandle handel, Byte id) {
-			int nBytes = UsbApi.MAX_BUFFER_SIZE;
-			int nBytesReturned = 0;
-			Byte[] buffer = new Byte[nBytes];
-			fixed (Byte* bufferptr = buffer) {
-				// Build a request for string descriptor.
-				USB_DESCRIPTOR_REQUEST Request = new USB_DESCRIPTOR_REQUEST();
-				Request.ConnectionIndex = AdapterNumber;
-				Request.SetupPacket.wValue = (ushort)((UsbApi.USB_STRING_DESCRIPTOR_TYPE << 8) + id);
-				Request.SetupPacket.wLength = (ushort)(nBytes - Marshal.SizeOf(Request));
-				Request.SetupPacket.wIndex = 0x409; // The language code.
-				// Use an IOCTL call to request the string descriptor.
-				if (Kernel32.DeviceIoControl(handel, UsbApi.IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, ref Request, Marshal.SizeOf(Request), (IntPtr)bufferptr, nBytes, out nBytesReturned, IntPtr.Zero)) {
-					if (nBytesReturned < nBytes) buffer[nBytesReturned] = 0;
-					if (nBytesReturned + 1 < nBytes) buffer[nBytesReturned + 1] = 0;
-					// The location of the string descriptor is immediately after
-					// the Request structure.  Because this location is not "covered"
-					// by the structure allocation, we're forced to zero out this
-					// chunk of memory by using the StringToHGlobalAuto() hack above
-					//*(UsbApi.USB_STRING_DESCRIPTOR*)(bufferptr + Marshal.SizeOf(Request));
-					USB_STRING_DESCRIPTOR StringDesc = (USB_STRING_DESCRIPTOR)Marshal.PtrToStructure((IntPtr)(bufferptr + Marshal.SizeOf(Request)), typeof(USB_STRING_DESCRIPTOR));
-					//return StringDesc.bString;
-					int len = Math.Min(nBytesReturned - Marshal.SizeOf(Request) - 2, StringDesc.bLength);
-					return Encoding.Unicode.GetString(buffer, 2 + Marshal.SizeOf(Request), len);
-				} else {
-					return null;
+		static UsbDevice GetUsbDevice(DeviceNode node, out Boolean isHostController) {
+			String[] hciinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_HOST_CONTROLLER);
+			if (hciinterface != null && hciinterface.Length > 0) {
+				isHostController = true;
+				return (new UsbController(null, node, hciinterface[0])).RootHub;
+			}
+			isHostController = false;
+			DeviceNode parent = node.GetParent();
+			Boolean isHostControllerA;
+			UsbDevice usbdev = GetUsbDevice(parent, out isHostControllerA);
+			if (isHostControllerA) return usbdev;
+			UsbHub usbhub = usbdev as UsbHub;
+			if (usbhub == null) return null;
+			String driverkey = node.DriverKey;
+			foreach (UsbDevice child in usbhub.Devices) {
+				if (driverkey.Equals(child.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return child;
+			}
+			return null;
+		}
+		public static UsbDevice GetUsbDevice(DeviceNode node) {
+			Boolean isHostController;
+			return GetUsbDevice(node, out isHostController);
+			/*
+
+			String[] hubinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_HUB);
+			if (hubinterface != null && hubinterface.Length > 0) {
+				USB_NODE_CONNECTION_INFORMATION_EX nodeConnection;
+				using (SafeFileHandle handle = OpenHandle(hubinterface[0])) {
+					if (!GetNodeConnectionInformation(handle, 0, out nodeConnection)) return null;
 				}
+				return new UsbHub(null, nodeConnection, hubinterface[0], false);
 			}
-		}
-
-		/*public static UsbDevice GetUsbDevice(DeviceNode node) {
-			String[] hubinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_HUB);
-			if (hubinterface != null && hubinterface.Length > 0) return new UsbHub(null, hubinterface[0], false);
 			String[] devinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_DEVICE);
-			if (devinterface == null || devinterface.Length == 0) throw new InvalidOperationException("Device is not an USB device");
+			if (devinterface == null || devinterface.Length == 0) return null;
 			DeviceNode parent = node.GetParent();
-			if (parent == null) throw new InvalidOperationException("Could not find parent hub device");
+			if (parent == null) return null;
 			UsbHub usbhub = GetUsbDevice(parent) as UsbHub;
-			if (usbhub == null) throw new InvalidOperationException("Could not find parent hub device");
+			if (usbhub == null) return null;
 			String driverkey = node.DriverKey;
 			foreach (UsbDevice usbdev in usbhub.Devices) {
 				if (driverkey.Equals(usbdev.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return usbdev;
 			}
-			throw new InvalidOperationException("Could not find device on parent hub");
-			//return null;
-		}*/
+			return null;*/
+		}
+
+		#region IUsbInterface Members
+		byte IUsbInterface.Configuration { get { throw new NotImplementedException(); } }
+		void IUsbInterface.Close() { }
+		public virtual int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) {
+			using (SafeFileHandle handle = UsbHub.OpenHandle(DevicePath)) return UsbHub.GetDescriptor(handle, AdapterNumber, descriptorType, index, langId, buffer, offset, length);
+		}
+		string IUsbInterface.GetString(short langId, byte stringIndex) {
+			return UsbStringDescriptor.GetStringFromDevice(this, stringIndex, langId);
+		}
+		int IUsbInterface.BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
+		int IUsbInterface.BulkRead(byte endpoint, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
+		void IUsbInterface.BulkReset(byte endpoint) { throw new NotImplementedException(); }
+		int IUsbInterface.InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
+		int IUsbInterface.InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
+		void IUsbInterface.InterruptReset(byte endpoint) { throw new NotImplementedException(); }
+		int IUsbInterface.ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
+		int IUsbInterface.ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotImplementedException(); }
+		UsbPipeStream IUsbInterface.GetBulkStream(byte endpoint) { throw new NotImplementedException(); }
+		UsbPipeStream IUsbInterface.GetInterruptStream(byte endpoint) { throw new NotImplementedException(); }
+		void IDisposable.Dispose() { }
+		#endregion
 	}
-}
\ No newline at end of file
+	
+}