changeset 62:edc41c861d96

Updates and cleanup in Windows USB enumeration code
author Ivo Smits <Ivo@UCIS.nl>
date Sun, 13 Oct 2013 02:47:08 +0200
parents 2b24666cd759
children 309c705d7460
files USBLib/Internal/Windows/UsbApi.cs USBLib/Windows/USB/UsbController.cs USBLib/Windows/USB/UsbDevice.cs USBLib/Windows/USB/UsbHub.cs
diffstat 4 files changed, 26 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/USBLib/Internal/Windows/UsbApi.cs	Sun Oct 13 00:48:28 2013 +0200
+++ b/USBLib/Internal/Windows/UsbApi.cs	Sun Oct 13 02:47:08 2013 +0200
@@ -1,13 +1,11 @@
 using System;
 using System.Runtime.InteropServices;
+using UCIS.USBLib.Communication;
+using UCIS.USBLib.Communication.WinUsb;
+using UCIS.USBLib.Descriptor;
 
 namespace UCIS.USBLib.Internal.Windows {
 	class UsbApi {
-		//public const int INVALID_HANDLE_VALUE = -1;
-
-		public const int USBUSER_GET_CONTROLLER_INFO_0 = 0x00000001;
-		public const int USBUSER_GET_CONTROLLER_DRIVER_KEY = 0x00000002;
-
 		public const int IOCTL_GET_HCD_DRIVERKEY_NAME = 0x220424;
 		public const int IOCTL_USB_GET_ROOT_HUB_NAME = 0x220408;
 		public const int IOCTL_USB_GET_NODE_INFORMATION = 0x220408;
@@ -17,32 +15,16 @@
 		public const int IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME = 0x220420;
 		public const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;
 
-		public const int USB_DEVICE_DESCRIPTOR_TYPE = 0x1;
-		public const int USB_CONFIGURATION_DESCRIPTOR_TYPE = 0x2;
-		public const int USB_STRING_DESCRIPTOR_TYPE = 0x3;
-		public const int USB_INTERFACE_DESCRIPTOR_TYPE = 0x4;
-		public const int USB_ENDPOINT_DESCRIPTOR_TYPE = 0x5;
-
-		public const string GUID_DEVINTERFACE_HUBCONTROLLER = "3abf6f2d-71c4-462a-8a92-1e6861e6af27";
 		public const string GUID_DEVINTERFACE_USB_HOST_CONTROLLER = "{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}";
 		public const string GUID_DEVINTERFACE_USB_HUB = "{F18A0E88-C30C-11D0-8815-00A0C906BED8}";
 		public const string GUID_DEVINTERFACE_USB_DEVICE = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}";
 
 		public const int MAX_BUFFER_SIZE = 2048;
-		public const int MAXIMUM_USB_STRING_LENGTH = 255;
-		public const string REGSTR_KEY_USB = "USB";
-		public const int REG_SZ = 1;
 		public const int DIF_PROPERTYCHANGE = 0x00000012;
 		public const int DICS_FLAG_GLOBAL = 0x00000001;
 
-
-		//public const int SPDRP_DRIVER = 0x9;
-		//public const int SPDRP_DEVICEDESC = 0x0;
-
 		public const int DICS_ENABLE = 0x00000001;
 		public const int DICS_DISABLE = 0x00000002;
-
-		//#endregion
 	}
 
 	#region enumerations
@@ -80,31 +62,6 @@
 		UsbMIParent
 	}
 
-	enum USB_DESCRIPTOR_TYPE : byte {
-		DeviceDescriptorType = 0x1,
-		ConfigurationDescriptorType = 0x2,
-		StringDescriptorType = 0x3,
-		InterfaceDescriptorType = 0x4,
-		EndpointDescriptorType = 0x5,
-		HubDescriptor = 0x29
-	}
-
-	[Flags]
-	enum USB_CONFIGURATION : byte {
-		RemoteWakeUp = 32,
-		SelfPowered = 64,
-		BusPowered = 128,
-		RemoteWakeUp_BusPowered = 160,
-		RemoteWakeUp_SelfPowered = 96
-	}
-
-	enum USB_TRANSFER : byte {
-		Control = 0x0,
-		Isochronous = 0x1,
-		Bulk = 0x2,
-		Interrupt = 0x3
-	}
-
 	enum USB_CONNECTION_STATUS : int {
 		NoDeviceConnected,
 		DeviceConnected,
@@ -203,7 +160,7 @@
 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
 	struct USB_HUB_DESCRIPTOR {
 		public byte bDescriptorLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
+		public UsbDescriptorType bDescriptorType;
 		public byte bNumberOfPorts;
 		public ushort wHubCharacteristics;
 		public byte bPowerOnToPowerGood;
@@ -228,7 +185,7 @@
 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
 	struct USB_NODE_CONNECTION_INFORMATION_EX {
 		public uint ConnectionIndex;
-		public USB_DEVICE_DESCRIPTOR DeviceDescriptor;
+		public UsbDeviceDescriptor DeviceDescriptor;
 		public byte CurrentConfigurationValue;
 		public USB_DEVICE_SPEED Speed;
 		public byte DeviceIsHub; //BOOLEAN  DeviceIsHub;
@@ -240,73 +197,6 @@
 		//Byte[] PipeList;
 	}
 
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	struct USB_DESCRIPTOR {
-		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
-	}
-
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	class USB_DEVICE_DESCRIPTOR {
-		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
-		public ushort bcdUSB;
-		public UsbDeviceClass bDeviceClass;
-		public byte bDeviceSubClass;
-		public byte bDeviceProtocol;
-		public byte bMaxPacketSize0;
-		public ushort idVendor;
-		public ushort idProduct;
-		public ushort bcdDevice;
-		public byte iManufacturer;
-		public byte iProduct;
-		public byte iSerialNumber;
-		public byte bNumConfigurations;
-	}
-
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	struct USB_ENDPOINT_DESCRIPTOR {
-		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
-		public byte bEndpointAddress;
-		public USB_TRANSFER bmAttributes;
-		public short wMaxPacketSize;
-		public byte bInterval;
-	}
-
-	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
-	struct USB_STRING_DESCRIPTOR {
-		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
-		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = UsbApi.MAXIMUM_USB_STRING_LENGTH)]
-		public string bString; //WCHAR bString[1];
-	}
-
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	struct USB_INTERFACE_DESCRIPTOR {
-		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
-		public byte bInterfaceNumber;
-		public byte bAlternateSetting;
-		public byte bNumEndpoints;
-		public byte bInterfaceClass;
-		public byte bInterfaceSubClass;
-		public byte bInterfaceProtocol;
-		public byte Interface;
-	}
-
-	[StructLayout(LayoutKind.Sequential, Pack = 1)]
-	struct USB_CONFIGURATION_DESCRIPTOR {
-		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
-		public ushort wTotalLength;
-		public byte bNumInterface;
-		public byte bConfigurationsValue;
-		public byte iConfiguration;
-		public USB_CONFIGURATION bmAttributes;
-		public byte MaxPower;
-	}
-
 	[StructLayout(LayoutKind.Sequential)]
 	struct HID_DESCRIPTOR_DESC_LIST {
 		public byte bReportType;
@@ -316,26 +206,17 @@
 	[StructLayout(LayoutKind.Sequential, Pack = 1)]
 	struct HID_DESCRIPTOR {
 		public byte bLength;
-		public USB_DESCRIPTOR_TYPE bDescriptorType;
+		public UsbDescriptorType bDescriptorType;
 		public ushort bcdHID;
 		public byte bCountry;
 		public byte bNumDescriptors;
 		public HID_DESCRIPTOR_DESC_LIST hid_desclist; //DescriptorList [1];
 	}
 
-	[StructLayout(LayoutKind.Sequential)]
-	struct USB_SETUP_PACKET {
-		public byte bmRequest;
-		public byte bRequest;
-		public ushort wValue;
-		public ushort wIndex;
-		public ushort wLength;
-	}
-
-	[StructLayout(LayoutKind.Sequential)]
+	[StructLayout(LayoutKind.Sequential, Pack = 8)]
 	struct USB_DESCRIPTOR_REQUEST {
 		public uint ConnectionIndex;
-		public USB_SETUP_PACKET SetupPacket;
+		public UsbSetupPacket SetupPacket;
 		//public byte[] Data; //UCHAR  Data[0];
 	}
 
@@ -361,26 +242,5 @@
 		public uint DeviceNumber;
 		public uint PartitionNumber;
 	}
-
-	[StructLayout(LayoutKind.Sequential)]
-	class SP_DEVINFO_DATA1 {
-		public int cbSize;
-		public Guid ClassGuid;
-		public int DevInst;
-		public ulong Reserved;
-	};
-
-	[StructLayout(LayoutKind.Sequential)]
-	class RAW_ROOTPORT_PARAMETERS {
-		public ushort PortNumber;
-		public ushort PortStatus;
-	}
-
-	[StructLayout(LayoutKind.Sequential)]
-	class USB_UNICODE_NAME {
-		public uint Length;
-		public string str; //WCHAR  String[1];
-	}
-
 	#endregion
-}
\ No newline at end of file
+}
--- a/USBLib/Windows/USB/UsbController.cs	Sun Oct 13 00:48:28 2013 +0200
+++ b/USBLib/Windows/USB/UsbController.cs	Sun Oct 13 02:47:08 2013 +0200
@@ -6,7 +6,7 @@
 
 namespace UCIS.HWLib.Windows.USB {
 	public class UsbController {
-		static readonly Guid IID_DEVINTERFACE_USB_CONTROLLER = new Guid(UsbApi.GUID_DEVINTERFACE_HUBCONTROLLER);
+		static readonly Guid IID_DEVINTERFACE_USB_HOST_CONTROLLER = new Guid(UsbApi.GUID_DEVINTERFACE_USB_HOST_CONTROLLER);
 		public String DevicePath { get; private set; }
 		public DeviceNode DeviceNode { get; private set; }
 		public String DeviceDescription { get { return DeviceNode.DeviceDescription; } }
@@ -24,14 +24,14 @@
 		}
 
 		public static UsbController GetControllerForDeviceNode(DeviceNode node) {
-			String[] interfaces = node.GetInterfaces(IID_DEVINTERFACE_USB_CONTROLLER);
+			String[] interfaces = node.GetInterfaces(IID_DEVINTERFACE_USB_HOST_CONTROLLER);
 			if (interfaces == null || interfaces.Length == 0) return null;
 			return new UsbController(node, interfaces[0]);
 		}
 
 		public static IList<UsbController> GetControllers() {
 			IList<UsbController>  devices = new List<UsbController>();
-			foreach (DeviceNode dev in DeviceNode.GetDevices(IID_DEVINTERFACE_USB_CONTROLLER)) {
+			foreach (DeviceNode dev in DeviceNode.GetDevices(IID_DEVINTERFACE_USB_HOST_CONTROLLER)) {
 				UsbController controller = GetControllerForDeviceNode(dev);
 				if (controller != null) devices.Add(controller);
 			}
--- a/USBLib/Windows/USB/UsbDevice.cs	Sun Oct 13 00:48:28 2013 +0200
+++ b/USBLib/Windows/USB/UsbDevice.cs	Sun Oct 13 02:47:08 2013 +0200
@@ -39,9 +39,9 @@
 			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;
+			request.SetupPacket.Value = (short)((descriptorType << 8) + index);
+			request.SetupPacket.Index = (short)langId;
+			request.SetupPacket.Length = (short)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)) {
@@ -76,20 +76,23 @@
 		public String DevicePath { get; private set; }
 		public UInt32 AdapterNumber { get; private set; }
 		internal USB_NODE_CONNECTION_INFORMATION_EX NodeConnectionInfo { get; set; }
-		private USB_DEVICE_DESCRIPTOR DeviceDescriptor { get { return NodeConnectionInfo.DeviceDescriptor; } }
+		public UsbDeviceDescriptor 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(); } }
+		public Byte CurrentConfigurationValue { get { return NodeConnectionInfo.CurrentConfigurationValue; } }
+		public UInt16 DeviceAddress { get { return NodeConnectionInfo.DeviceAddress; } }
+		public UInt32 NumberOfOpenPipes { get { return NodeConnectionInfo.NumberOfOpenPipes; } }
 
 		SafeFileHandle OpenHandle() {
 			return OpenHandle(DevicePath);
 		}
 
-		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 int NumConfigurations { get { return DeviceDescriptor.NumConfigurations; } }
+		public int VendorID { get { return DeviceDescriptor.VendorID; } }
+		public int ProductID { get { return DeviceDescriptor.ProductID; } }
 
 		private String GetStringSafe(Byte id) {
 			if (id == 0) return null;
@@ -98,9 +101,9 @@
 			return s.Trim(' ', '\0');
 		}
 
-		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 string Manufacturer { get { return GetStringSafe(DeviceDescriptor.ManufacturerStringID); } }
+		public string Product { get { return GetStringSafe(DeviceDescriptor.ProductStringID); } }
+		public string SerialNumber { get { return GetStringSafe(DeviceDescriptor.SerialNumberStringID); } }
 		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.DeviceDescription; } }
--- a/USBLib/Windows/USB/UsbHub.cs	Sun Oct 13 00:48:28 2013 +0200
+++ b/USBLib/Windows/USB/UsbHub.cs	Sun Oct 13 02:47:08 2013 +0200
@@ -58,7 +58,7 @@
 			UsbDevice device = null;
 			if (nodeConnection.ConnectionStatus != USB_CONNECTION_STATUS.DeviceConnected) {
 				device = new UsbDevice(parent, nodeConnection, portCount, devicePath);
-			} else if (nodeConnection.DeviceDescriptor.bDeviceClass == UsbDeviceClass.HubDevice) {
+			} else if (nodeConnection.DeviceDescriptor.DeviceClass == (Byte)UsbDeviceClass.HubDevice) {
 				String nodeName = GetNodeConnectionName(handle, portCount);
 				device = new UsbHub(parent, nodeConnection, @"\\?\" + nodeName, portCount, false);
 			} else {