changeset 65:abe0d55a2201

Removed some redundant USB communication code
author Ivo Smits <Ivo@UCIS.nl>
date Tue, 15 Oct 2013 16:19:45 +0200
parents 99ed461509fe
children b7bc27c6734e
files USBLib/Communication/IUsbDevice.cs USBLib/Communication/LibUsbDotNet.cs USBLib/Communication/USBIO/USBIODevice.cs USBLib/Communication/UsbInterface.cs USBLib/Communication/WinUsb/WinUsbDevice.cs USBLib/Descriptor/UsbDescriptor.cs USBLib/Windows/USB/UsbDevice.cs
diffstat 7 files changed, 51 insertions(+), 237 deletions(-) [+]
line wrap: on
line diff
--- a/USBLib/Communication/IUsbDevice.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Communication/IUsbDevice.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -8,8 +8,6 @@
 		void ResetDevice();
 
 		IUsbDeviceRegistry Registry { get; }
-
-		//void Close();
 	}
 	public interface IUsbInterface : IDisposable {
 		Byte Configuration { get; }
@@ -17,7 +15,6 @@
 
 		//int ControlTransfer(byte requestType, byte request, short value, short index, Byte[] buffer, int offset, int length);
 		int GetDescriptor(byte descriptorType, byte index, short langId, Byte[] buffer, int offset, int length);
-		String GetString(short langId, byte stringIndex);
 
 		int BulkWrite(Byte endpoint, Byte[] buffer, int offset, int length);
 		int BulkRead(Byte endpoint, Byte[] buffer, int offset, int length);
--- a/USBLib/Communication/LibUsbDotNet.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Communication/LibUsbDotNet.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -9,6 +9,7 @@
 using LibUsbDotNet.Info;
 using LibUsbDotNet.Main;
 using UCIS.USBLib.Communication;
+using UCIS.USBLib.Descriptor;
 using LibUsb0Registry = UCIS.USBLib.Communication.LibUsb.LibUsb0Registry;
 using LibUsb1Registry = UCIS.USBLib.Communication.LibUsb1.LibUsb1Registry;
 using nIUsbDevice = UCIS.USBLib.Communication.IUsbDevice;
@@ -17,7 +18,7 @@
 using USBIORegistry = UCIS.USBLib.Communication.USBIO.USBIORegistry;
 
 namespace LibUsbDotNet {
-	public class UsbDevice : IUsbDevice {
+	public class UsbDevice {
 		public nIUsbInterface Device { get; private set; }
 		public UsbDevice(nIUsbInterface dev) {
 			if (dev == null) throw new ArgumentNullException("dev");
@@ -40,17 +41,6 @@
 			}
 			return true;
 		}
-		public DriverModeType DriverMode { get { return DriverModeType.Unknown; } }
-		public enum DriverModeType {
-			Unknown,
-			LibUsb,
-			WinUsb,
-			MonoLibUsb,
-			LibUsbWinBack
-		}
-		public UsbEndpointWriter OpenEndpointWriter(WriteEndpointID writeEndpointID, EndpointType endpointType) {
-			return new UsbEndpointWriter(Device, (Byte)writeEndpointID, endpointType);
-		}
 		public UsbEndpointReader OpenEndpointReader(ReadEndpointID readEndpointID, int buffersize, EndpointType endpointType) {
 			UsbEndpointReader reader = new UsbEndpointReader(Device, (Byte)readEndpointID, endpointType);
 			reader.ReadBufferSize = buffersize;
@@ -73,7 +63,6 @@
 				return list;
 			}
 		}
-		private SafeHandle Handle { get { return null; } }
 		public bool SetConfiguration(byte config) {
 			nIUsbDevice dev = Device as nIUsbDevice;
 			if (dev == null) return false;
@@ -108,24 +97,18 @@
 		public IList<UsbConfigInfo> Configs {
 			get {
 				List<UsbConfigInfo> rtnConfigs = new List<UsbConfigInfo>();
-				int iConfigs = Info.Descriptor.ConfigurationCount;
-				for (int iConfig = 0; iConfig < iConfigs; iConfig++) {
+				int iConfigs = Info.Descriptor.NumConfigurations;
+				for (Byte iConfig = 0; iConfig < iConfigs; iConfig++) {
+					UsbConfigurationDescriptor configDescriptor = UsbConfigurationDescriptor.FromDevice(Device, iConfig);
+					if (configDescriptor.Length < UsbConfigurationDescriptor.Size || configDescriptor.Type != UsbDescriptorType.Configuration)
+						throw new Exception("GetDeviceConfigs: USB config descriptor is invalid.");
+					Byte[] cfgBuffer = new Byte[configDescriptor.TotalLength];
 					int iBytesTransmitted;
-					byte[] cfgBuffer = new byte[9];
 					if (!GetDescriptor((byte)UsbDescriptorType.Configuration, (byte)iConfig, 0, cfgBuffer, cfgBuffer.Length, out iBytesTransmitted))
 						throw new Exception("Could not read configuration descriptor");
-					if (iBytesTransmitted < UsbConfigDescriptor.Size || cfgBuffer[1] != (byte)UsbDescriptorType.Configuration)
+					configDescriptor = UsbConfigurationDescriptor.FromByteArray(cfgBuffer, 0, iBytesTransmitted);
+					if (configDescriptor.Length < UsbConfigurationDescriptor.Size || configDescriptor.Type != UsbDescriptorType.Configuration)
 						throw new Exception("GetDeviceConfigs: USB config descriptor is invalid.");
-					UsbConfigDescriptor configDescriptor = new UsbConfigDescriptor();
-					Helper.BytesToObject(cfgBuffer, 0, Math.Min(UsbConfigDescriptor.Size, cfgBuffer[0]), configDescriptor);
-					if (configDescriptor.TotalLength > cfgBuffer.Length) {
-						cfgBuffer = new Byte[configDescriptor.TotalLength];
-						if (!GetDescriptor((byte)UsbDescriptorType.Configuration, (byte)iConfig, 0, cfgBuffer, cfgBuffer.Length, out iBytesTransmitted))
-							throw new Exception("Could not read configuration descriptor");
-						if (iBytesTransmitted < UsbConfigDescriptor.Size || cfgBuffer[1] != (byte)UsbDescriptorType.Configuration)
-							throw new Exception("GetDeviceConfigs: USB config descriptor is invalid.");
-						Helper.BytesToObject(cfgBuffer, 0, Math.Min(UsbConfigDescriptor.Size, cfgBuffer[0]), configDescriptor);
-					}
 					if (configDescriptor.TotalLength != iBytesTransmitted) throw new Exception("GetDeviceConfigs: USB config descriptor length doesn't match the length received.");
 					List<byte[]> rawDescriptorList = new List<byte[]>();
 					int iRawLengthPosition = configDescriptor.Length;
@@ -136,37 +119,12 @@
 						rawDescriptorList.Add(rawDescriptor);
 						iRawLengthPosition += rawDescriptor.Length;
 					}
-					rtnConfigs.Add(new UsbConfigInfo(this, configDescriptor, ref rawDescriptorList));
+					rtnConfigs.Add(new UsbConfigInfo(this, configDescriptor, rawDescriptorList));
 				}
 				return rtnConfigs;
 			}
 		}
 	}
-	public interface IUsbDevice {
-		bool SetConfiguration(byte config);
-		bool ClaimInterface(int interfaceID);
-		bool ReleaseInterface(int interfaceID);
-	}
-	public class UsbEndpointWriter : IDisposable {
-		public nIUsbInterface Device { get; private set; }
-		public Byte EndpointID { get; private set; }
-		public EndpointType EndpointType { get; private set; }
-		public Byte EpNum { get { return EndpointID; } }
-		public UsbEndpointWriter(nIUsbInterface dev, byte epid, EndpointType eptype) {
-			Device = dev;
-			EndpointID = epid;
-			EndpointType = eptype;
-		}
-		public ErrorCode Write(byte[] buffer, int offset, int count, int timeout, out int transferLength) {
-			switch (EndpointType) {
-				case EndpointType.Bulk: transferLength = Device.BulkWrite(EndpointID, buffer, offset, count); break;
-				case EndpointType.Interrupt: transferLength = Device.InterruptWrite(EndpointID, buffer, offset, count); break;
-				default: transferLength = 0; return ErrorCode.Error;
-			}
-			return ErrorCode.Ok;
-		}
-		public void Dispose() { }
-	}
 	public class UsbEndpointReader : IDisposable {
 		public nIUsbInterface Device { get; private set; }
 		public Byte EndpointID { get; private set; }
@@ -229,26 +187,6 @@
 	}
 }
 namespace LibUsbDotNet.Main {
-	public static class UsbConstants {
-		public const int MAX_CONFIG_SIZE = 4096;
-		public const int MAX_DEVICES = 128;
-		public const int MAX_ENDPOINTS = 32;
-		public const byte ENDPOINT_DIR_MASK = 0x80;
-		public const byte ENDPOINT_NUMBER_MASK = 0xf;
-	}
-	public static class Helper {
-		public static void BytesToObject(byte[] sourceBytes, int iStartIndex, int iLength, object destObject) {
-			GCHandle gch = GCHandle.Alloc(destObject, GCHandleType.Pinned);
-			IntPtr ptrDestObject = gch.AddrOfPinnedObject();
-			Marshal.Copy(sourceBytes, iStartIndex, ptrDestObject, iLength);
-			gch.Free();
-		}
-		public static string ToString(string sep0, string[] names, string sep1, object[] values, string sep2) {
-			StringBuilder sb = new StringBuilder();
-			for (int i = 0; i < names.Length; i++) sb.Append(sep0 + names[i] + sep1 + values[i] + sep2);
-			return sb.ToString();
-		}
-	}
 	public class EndpointDataEventArgs : EventArgs {
 		internal EndpointDataEventArgs(byte[] bytes, int size) {
 			Buffer = bytes;
@@ -282,23 +220,6 @@
 		TypeStandard = (0x00 << 5),
 		TypeVendor = (0x02 << 5),
 	}
-	public enum WriteEndpointID : byte {
-		Ep01 = 0x01,
-		Ep02 = 0x02,
-		Ep03 = 0x03,
-		Ep04 = 0x04,
-		Ep05 = 0x05,
-		Ep06 = 0x06,
-		Ep07 = 0x07,
-		Ep08 = 0x08,
-		Ep09 = 0x09,
-		Ep10 = 0x0A,
-		Ep11 = 0x0B,
-		Ep12 = 0x0C,
-		Ep13 = 0x0D,
-		Ep14 = 0x0E,
-		Ep15 = 0x0F,
-	}
 	public enum ReadEndpointID : byte {
 		Ep01 = 0x81,
 		Ep02 = 0x82,
@@ -357,44 +278,37 @@
 		internal UsbDevice mUsbDevice;
 		internal UsbDeviceInfo(UsbDevice usbDevice) {
 			mUsbDevice = usbDevice;
-			mDeviceDescriptor = new UsbDeviceDescriptor();
-			Byte[] bytes = new Byte[UsbDeviceDescriptor.Size];
-			int ret;
-			usbDevice.GetDescriptor((byte)UsbDescriptorType.Device, 0, 0, bytes, UsbDeviceDescriptor.Size, out ret);
-			Object asobj = mDeviceDescriptor;
-			Helper.BytesToObject(bytes, 0, ret, asobj);
-			mDeviceDescriptor = (UsbDeviceDescriptor)asobj;
+			mDeviceDescriptor = UsbDeviceDescriptor.FromDevice(usbDevice.Device);
 		}
 		public UsbDeviceDescriptor Descriptor { get { return mDeviceDescriptor; } }
 		public String ManufacturerString {
 			get {
-				if (Descriptor.ManufacturerStringIndex == 0) return null;
-				return mUsbDevice.Device.GetString(0, Descriptor.ManufacturerStringIndex);
+				if (Descriptor.ManufacturerStringID == 0) return null;
+				return UsbStringDescriptor.GetStringFromDevice(mUsbDevice.Device, Descriptor.ManufacturerStringID, 0);
 			}
 		}
 		public String ProductString {
 			get {
-				if (Descriptor.ProductStringIndex == 0) return null;
-				return mUsbDevice.Device.GetString(0, Descriptor.ProductStringIndex);
+				if (Descriptor.ProductStringID == 0) return null;
+				return UsbStringDescriptor.GetStringFromDevice(mUsbDevice.Device, Descriptor.ProductStringID, 0);
 			}
 		}
 		public String SerialString {
 			get {
-				if (Descriptor.SerialStringIndex == 0) return null;
-				return mUsbDevice.Device.GetString(0, Descriptor.SerialStringIndex);
+				if (Descriptor.SerialNumberStringID == 0) return null;
+				return UsbStringDescriptor.GetStringFromDevice(mUsbDevice.Device, Descriptor.SerialNumberStringID, 0);
 			}
 		}
 	}
 	public class UsbConfigInfo {
 		private readonly List<UsbInterfaceInfo> mInterfaceList = new List<UsbInterfaceInfo>();
-		internal readonly UsbConfigDescriptor mUsbConfigDescriptor;
+		internal readonly UsbConfigurationDescriptor mUsbConfigDescriptor;
 		internal UsbDevice mUsbDevice;
-		internal UsbConfigInfo(UsbDevice usbDevice, UsbConfigDescriptor descriptor, ref List<byte[]> rawDescriptors) {
+		internal UsbConfigInfo(UsbDevice usbDevice, UsbConfigurationDescriptor descriptor, IEnumerable<byte[]> rawDescriptors) {
 			mUsbDevice = usbDevice;
 			mUsbConfigDescriptor = descriptor;
 			UsbInterfaceInfo currentInterface = null;
-			for (int iRawDescriptor = 0; iRawDescriptor < rawDescriptors.Count; iRawDescriptor++) {
-				byte[] bytesRawDescriptor = rawDescriptors[iRawDescriptor];
+			foreach (Byte[] bytesRawDescriptor in rawDescriptors) {
 				switch (bytesRawDescriptor[1]) {
 					case (byte)UsbDescriptorType.Interface:
 						currentInterface = new UsbInterfaceInfo(usbDevice, bytesRawDescriptor);
@@ -407,7 +321,7 @@
 				}
 			}
 		}
-		public UsbConfigDescriptor Descriptor { get { return mUsbConfigDescriptor; } }
+		public UsbConfigurationDescriptor Descriptor { get { return mUsbConfigDescriptor; } }
 		public ReadOnlyCollection<UsbInterfaceInfo> InterfaceInfoList { get { return mInterfaceList.AsReadOnly(); } }
 	}
 	public class UsbInterfaceInfo {
@@ -416,8 +330,7 @@
 		internal List<UsbEndpointInfo> mEndpointInfo = new List<UsbEndpointInfo>();
 		internal UsbInterfaceInfo(UsbDevice usbDevice, byte[] descriptor) {
 			mUsbDevice = usbDevice;
-			mUsbInterfaceDescriptor = new UsbInterfaceDescriptor();
-			Helper.BytesToObject(descriptor, 0, Math.Min(UsbInterfaceDescriptor.Size, descriptor[0]), mUsbInterfaceDescriptor);
+			mUsbInterfaceDescriptor = UsbInterfaceDescriptor.FromByteArray(descriptor, 0, descriptor.Length);
 		}
 		public UsbInterfaceDescriptor Descriptor { get { return mUsbInterfaceDescriptor; } }
 		public ReadOnlyCollection<UsbEndpointInfo> EndpointInfoList { get { return mEndpointInfo.AsReadOnly(); } }
@@ -425,8 +338,7 @@
 	public class UsbEndpointInfo {
 		internal UsbEndpointDescriptor mUsbEndpointDescriptor;
 		internal UsbEndpointInfo(byte[] descriptor) {
-			mUsbEndpointDescriptor = new UsbEndpointDescriptor();
-			Helper.BytesToObject(descriptor, 0, Math.Min(UsbEndpointDescriptor.Size, descriptor[0]), mUsbEndpointDescriptor);
+			mUsbEndpointDescriptor = UsbEndpointDescriptor.FromByteArray(descriptor, 0, descriptor.Length);
 		}
 		public UsbEndpointDescriptor Descriptor {
 			get { return mUsbEndpointDescriptor; }
@@ -434,23 +346,6 @@
 	}
 }
 namespace LibUsbDotNet.Descriptors {
-	public enum DescriptorType : byte {
-		Device = 1,
-		Configuration = 2,
-		String = 3,
-		Interface = 4,
-		Endpoint = 5,
-		DeviceQualifier = 6,
-		OtherSpeedConfiguration = 7,
-		InterfacePower = 8,
-		OTG = 9,
-		Debug = 10,
-		InterfaceAssociation = 11,
-		Hid = 0x21,
-		HidReport = 0x22,
-		Physical = 0x23,
-		Hub = 0x29
-	}
 	public enum ClassCodeType : byte {
 		PerInterface = 0,
 		Audio = 1,
@@ -463,78 +358,4 @@
 		Data = 10,
 		VendorSpec = 0xff
 	}
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	public abstract class UsbDescriptor {
-		public static readonly int Size = Marshal.SizeOf(typeof(UsbDescriptor));
-		public byte Length;
-		public DescriptorType DescriptorType;
-	}
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	public class UsbDeviceDescriptor : UsbDescriptor {
-		public new static readonly int Size = Marshal.SizeOf(typeof(UsbDeviceDescriptor));
-		public short BcdUsb;
-		public ClassCodeType Class;
-		public byte SubClass;
-		public byte Protocol;
-		public byte MaxPacketSize0;
-		public short VendorID;
-		public short ProductID;
-		public short BcdDevice;
-		public byte ManufacturerStringIndex;
-		public byte ProductStringIndex;
-		public byte SerialStringIndex;
-		public byte ConfigurationCount;
-		internal UsbDeviceDescriptor() { }
-	}
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	public class UsbConfigDescriptor : UsbDescriptor {
-		public new static readonly int Size = Marshal.SizeOf(typeof(UsbConfigDescriptor));
-		public readonly short TotalLength;
-		public readonly byte InterfaceCount;
-		public readonly byte ConfigID;
-		public readonly byte StringIndex;
-		public readonly byte Attributes;
-		public readonly byte MaxPower;
-		internal UsbConfigDescriptor() { }
-	}
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	public class UsbInterfaceDescriptor : UsbDescriptor {
-		public new static readonly int Size = Marshal.SizeOf(typeof(UsbInterfaceDescriptor));
-		public readonly byte InterfaceID;
-		public readonly byte AlternateID;
-		public readonly byte EndpointCount;
-		public readonly ClassCodeType Class;
-		public readonly byte SubClass;
-		public readonly byte Protocol;
-		public readonly byte StringIndex;
-		internal UsbInterfaceDescriptor() { }
-	}
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	public class UsbEndpointDescriptor : UsbDescriptor {
-		public new static readonly int Size = Marshal.SizeOf(typeof(UsbEndpointDescriptor));
-		public readonly byte EndpointID;
-		public readonly byte Attributes;
-		public readonly short MaxPacketSize;
-		public readonly byte Interval;
-		public readonly byte Refresh;
-		public readonly byte SynchAddress;
-		internal UsbEndpointDescriptor() { }
-	}
 }
-namespace MonoLibUsb {
-	public static class MonoUsbApi {
-		internal const CallingConvention CC = 0;
-		internal const string LIBUSB_DLL = "libusb-1.0.dll";
-		[DllImport(LIBUSB_DLL, CallingConvention = CC, SetLastError = false, EntryPoint = "libusb_detach_kernel_driver")]
-		public static extern int DetachKernelDriver([In] MonoUsbDeviceHandle deviceHandle, int interfaceNumber);
-		public static int ControlTransfer(MonoUsbDeviceHandle deviceHandle, byte requestType, byte request, short value, short index, object data, short dataLength, int timeout) {
-			throw new NotImplementedException();
-		}
-		public static int BulkTransfer(MonoUsbDeviceHandle deviceHandle, byte endpoint, object data, int length, out int actualLength, int timeout) {
-			throw new NotImplementedException();
-		}
-	}
-	public abstract class MonoUsbDeviceHandle : SafeHandle {
-		public MonoUsbDeviceHandle(Boolean bOwnsHandle) : base(IntPtr.Zero, bOwnsHandle) { }
-	}
-}
--- a/USBLib/Communication/USBIO/USBIODevice.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Communication/USBIO/USBIODevice.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -109,15 +109,15 @@
 				IList<LibUsbDotNet.Info.UsbConfigInfo> configs = (new LibUsbDotNet.UsbDevice(this)).Configs;
 				for (int i = 0; i < configs.Count; i++) {
 					LibUsbDotNet.Info.UsbConfigInfo config = configs[i];
-					if (config.Descriptor.ConfigID == value) {
+					if (config.Descriptor.ConfigurationValue == value) {
 						unsafe {
 							USBIO_SET_CONFIGURATION req = new USBIO_SET_CONFIGURATION();
 							req.ConfigurationIndex = (ushort)i;
-							req.NbOfInterfaces = Math.Min((ushort)32, config.Descriptor.InterfaceCount);
+							req.NbOfInterfaces = Math.Min((ushort)32, config.Descriptor.NumInterfaces);
 							for (int j = 0; j < req.NbOfInterfaces; j++) {
 								LibUsbDotNet.Info.UsbInterfaceInfo intf = config.InterfaceInfoList[j];
 								*((USBIO_INTERFACE_SETTING*)(req.InterfaceList + sizeof(USBIO_INTERFACE_SETTING) * j)) =
-									new USBIO_INTERFACE_SETTING() { InterfaceIndex = intf.Descriptor.InterfaceID, AlternateSettingIndex = 0, MaximumTransferSize = UInt16.MaxValue };
+									new USBIO_INTERFACE_SETTING() { InterfaceIndex = intf.Descriptor.InterfaceNumber, AlternateSettingIndex = 0, MaximumTransferSize = UInt16.MaxValue };
 							}
 							try {
 								DeviceIoControl(DeviceHandle, IOCTL_USBIO_SET_CONFIGURATION, (IntPtr)(&req), sizeof(USBIO_SET_CONFIGURATION), IntPtr.Zero, 0);
--- a/USBLib/Communication/UsbInterface.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Communication/UsbInterface.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -18,12 +18,6 @@
 				throw new NotImplementedException();
 			}
 		}
-		public unsafe virtual string GetString(short langId, byte stringIndex) {
-			Byte[] buffer = new Byte[256];
-			int tl = GetDescriptor((byte)UsbDescriptorType.String, stringIndex, langId, buffer, 0, buffer.Length);
-			if (tl < 2) return null;
-			return UsbStringDescriptor.GetString(buffer, 0, tl);
-		}
 		public virtual int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) {
 			return ControlRead(
 				UsbControlRequestType.EndpointIn | UsbControlRequestType.RecipDevice | UsbControlRequestType.TypeStandard,
--- a/USBLib/Communication/WinUsb/WinUsbDevice.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Communication/WinUsb/WinUsbDevice.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -80,16 +80,16 @@
 			if (InterfaceHandle.IsInvalid || InterfaceHandle.IsClosed) throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not open interface");
 			InterfaceHandles = new SafeWinUsbInterfaceHandle[1] { InterfaceHandle };
 			foreach (LibUsbDotNet.Info.UsbConfigInfo ci in (new LibUsbDotNet.UsbDevice(this)).Configs) {
-				if (ci.Descriptor.ConfigID == Configuration) {
+				if (ci.Descriptor.ConfigurationValue == Configuration) {
 					foreach (LibUsbDotNet.Info.UsbInterfaceInfo ifinfo in ci.InterfaceInfoList) {
 						foreach (LibUsbDotNet.Info.UsbEndpointInfo epinfo in ifinfo.EndpointInfoList) {
-							int epidx = epinfo.Descriptor.EndpointID & 0x7F;
-							if ((epinfo.Descriptor.EndpointID & 0x80) != 0) {
+							int epidx = epinfo.Descriptor.EndpointAddress & 0x7F;
+							if ((epinfo.Descriptor.EndpointAddress & 0x80) != 0) {
 								if (EndpointToInterfaceIn.Length <= epidx) Array.Resize(ref EndpointToInterfaceIn, epidx + 1);
-								EndpointToInterfaceIn[epidx] = ifinfo.Descriptor.InterfaceID;
+								EndpointToInterfaceIn[epidx] = ifinfo.Descriptor.InterfaceNumber;
 							} else {
 								if (EndpointToInterfaceOut.Length <= epidx) Array.Resize(ref EndpointToInterfaceOut, epidx + 1);
-								EndpointToInterfaceOut[epidx] = ifinfo.Descriptor.InterfaceID;
+								EndpointToInterfaceOut[epidx] = ifinfo.Descriptor.InterfaceNumber;
 							}
 						}
 					}
--- a/USBLib/Descriptor/UsbDescriptor.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Descriptor/UsbDescriptor.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -103,6 +103,11 @@
 			if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions");
 			fixed (Byte* ptr = buffer) return *(UsbConfigurationDescriptor*)(ptr + offset);
 		}
+		public static UsbConfigurationDescriptor FromDevice(IUsbInterface device, Byte index) {
+			Byte[] buff = new Byte[UsbConfigurationDescriptor.Size];
+			int len = device.GetDescriptor((Byte)UsbDescriptorType.Configuration, index, 0, buff, 0, buff.Length);
+			return FromByteArray(buff, 0, len);
+		}
 		public static unsafe int Size { get { return sizeof(UsbConfigurationDescriptor); } }
 	}
 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
--- a/USBLib/Windows/USB/UsbDevice.cs	Sun Oct 13 20:03:05 2013 +0200
+++ b/USBLib/Windows/USB/UsbDevice.cs	Tue Oct 15 16:19:45 2013 +0200
@@ -51,7 +51,7 @@
 
 		private String GetStringSafe(Byte id) {
 			if (id == 0) return null;
-			String s = GetString(id, 0);
+			String s = UsbStringDescriptor.GetStringFromDevice(this, id, 0);
 			if (s == null) return s;
 			return s.Trim(' ', '\0');
 		}
@@ -152,27 +152,24 @@
 				return nBytes;
 			}
 		}
-		public String GetString(short langId, byte stringIndex) {
-			return UsbStringDescriptor.GetStringFromDevice(this, stringIndex, langId);
-		}
-		byte IUsbInterface.Configuration { get { throw new NotImplementedException(); } }
+		byte IUsbInterface.Configuration { get { return CurrentConfigurationValue; } }
+		byte IUsbDevice.Configuration { get { return CurrentConfigurationValue; } set { throw new NotSupportedException(); } }
+		void IUsbDevice.ResetDevice() { throw new NotImplementedException(); }
+		IUsbDeviceRegistry IUsbDevice.Registry { get { throw new NotImplementedException(); } }
 		void IUsbInterface.Close() { }
-		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(); }
+		int IUsbInterface.BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); }
+		int IUsbInterface.BulkRead(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); }
 		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(); }
+		int IUsbInterface.InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); }
+		int IUsbInterface.InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { throw new NotSupportedException(); }
+		void IUsbInterface.InterruptReset(byte endpoint) { throw new NotSupportedException(); }
+		int IUsbInterface.ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotSupportedException(); }
+		int IUsbInterface.ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { throw new NotSupportedException(); }
+		UsbPipeStream IUsbInterface.GetBulkStream(byte endpoint) { throw new NotSupportedException(); }
+		UsbPipeStream IUsbInterface.GetInterruptStream(byte endpoint) { throw new NotSupportedException(); }
 		void IDisposable.Dispose() { }
-		byte IUsbDevice.Configuration { get { throw new NotSupportedException(); } set { throw new NotSupportedException(); } }
 		void IUsbDevice.ClaimInterface(int interfaceID) { }
 		void IUsbDevice.ReleaseInterface(int interfaceID) {	}
-		void IUsbDevice.ResetDevice() { throw new NotSupportedException(); }
-		IUsbDeviceRegistry IUsbDevice.Registry { get { throw new NotImplementedException(); } }
 		#endregion
 	}
 }