Mercurial > hg > ucis.core
changeset 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 | 4e1a5dec786a |
children | 2b24666cd759 |
files | UCIS.Core.csproj USBLib/Communication/LibUsbDotNet.cs USBLib/Communication/VBoxUSB.cs USBLib/Windows/USB/UsbBus.cs USBLib/Windows/USB/UsbController.cs USBLib/Windows/USB/UsbDevice.cs USBLib/Windows/USB/UsbHub.cs |
diffstat | 7 files changed, 115 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/UCIS.Core.csproj Wed Oct 09 20:56:28 2013 +0200 +++ b/UCIS.Core.csproj Sat Oct 12 16:35:24 2013 +0200 @@ -161,7 +161,6 @@ <Compile Include="USBLib\Internal\Windows\UsbApi.cs" /> <Compile Include="USBLib\Internal\Windows\Win32Kernel.cs" /> <Compile Include="USBLib\Windows\Devices\DeviceNode.cs" /> - <Compile Include="USBLib\Windows\USB\UsbBus.cs" /> <Compile Include="USBLib\Windows\USB\UsbController.cs" /> <Compile Include="USBLib\Windows\USB\UsbDevice.cs" /> <Compile Include="USBLib\Windows\USB\UsbHub.cs" />
--- a/USBLib/Communication/LibUsbDotNet.cs Wed Oct 09 20:56:28 2013 +0200 +++ b/USBLib/Communication/LibUsbDotNet.cs Sat Oct 12 16:35:24 2013 +0200 @@ -20,6 +20,7 @@ public class UsbDevice : IUsbDevice { public nIUsbInterface Device { get; private set; } public UsbDevice(nIUsbInterface dev) { + if (dev == null) throw new ArgumentNullException("dev"); Device = dev; } public bool GetDescriptor(byte descriptorType, byte index, short langId, Byte[] buffer, int bufferLength, out int transferLength) { @@ -87,6 +88,7 @@ nIUsbDevice dev = Device as nIUsbDevice; if (dev == null) return false; try { + if (dev.Configuration == 0) dev.Configuration = 1; dev.ClaimInterface(interfaceID); return true; } catch {
--- a/USBLib/Communication/VBoxUSB.cs Wed Oct 09 20:56:28 2013 +0200 +++ b/USBLib/Communication/VBoxUSB.cs Sat Oct 12 16:35:24 2013 +0200 @@ -238,9 +238,57 @@ public UInt32 numIsoPkts; public fixed byte aIsoPkts[8 * 8]; } - class USBRegistry : WindowsUsbDeviceRegistry, IUsbDeviceRegistry { + class USBRegistry : IUsbDeviceRegistry { + public DeviceNode DeviceNode { get; private set; } + public String DevicePath { get; private set; } + public String DeviceID { get; private set; } + public String SymbolicName { get { return DevicePath; } } + private UCIS.HWLib.Windows.USB.UsbDevice usbdev = null; + private Boolean hasDeviceDescriptor = false; + private UCIS.USBLib.Descriptor.UsbDeviceDescriptor deviceDescriptor; + private IDictionary<string, object> mDeviceProperties; + public UCIS.HWLib.Windows.USB.UsbDevice USBDevice { + get { + if (usbdev == null) usbdev = UCIS.HWLib.Windows.USB.UsbDevice.GetUsbDevice(DeviceNode); + return usbdev; + } + } + public UCIS.USBLib.Descriptor.UsbDeviceDescriptor DeviceDescriptor { + get { + if (!hasDeviceDescriptor) deviceDescriptor = UCIS.USBLib.Descriptor.UsbDeviceDescriptor.FromDevice(USBDevice); + return deviceDescriptor; + } + } + public IDictionary<string, object> DeviceProperties { + get { + if (mDeviceProperties == null) mDeviceProperties = SetupApi.GetSPDRPProperties(DeviceNode); + return mDeviceProperties; + } + } + + internal USBRegistry(DeviceNode device, String interfacepath) { + DeviceNode = device; + DeviceID = device.DeviceID; + DevicePath = interfacepath; + } + + public int Vid { get { return DeviceDescriptor.VendorID; } } + public int Pid { get { return DeviceDescriptor.ProductID; } } + public byte InterfaceID { get { return 0; } } + + public string Name { get { return DeviceNode.GetPropertyString(CMRDP.DEVICEDESC); } } + public string Manufacturer { get { return DeviceNode.GetPropertyString(CMRDP.MFG); } } + public string FullName { + get { + String desc = Name; + String mfg = Manufacturer; + if (mfg == null) return desc; + if (desc == null) return mfg; + return mfg + " - " + desc; + } + } + public IUsbDevice Open() { return new VBoxUSB(this); } - public USBRegistry(DeviceNode devnode, String intf) : base(devnode, intf) { } } public class VBoxUSB : UsbInterface, IUsbDevice { @@ -269,10 +317,15 @@ static SafeFileHandle hMonitor = null; const String USBMON_DEVICE_NAME = "\\\\.\\VBoxUSBMon"; - static unsafe void SyncIoControl(SafeHandle hDevice, int IoControlCode, void* InBuffer, int nInBufferSize, void* OutBuffer, int nOutBufferSize) { + static unsafe int SyncIoControl(SafeHandle hDevice, int IoControlCode, void* InBuffer, int nInBufferSize, void* OutBuffer, int nOutBufferSize, Boolean throwError) { Int32 pBytesReturned = 0; - if (!Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, null)) - throw new Win32Exception(Marshal.GetLastWin32Error()); + if (Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, null)) return 0; + int ret = Marshal.GetLastWin32Error(); + if (throwError) throw new Win32Exception(ret); + return ret; + } + static unsafe void SyncIoControl(SafeHandle hDevice, int IoControlCode, void* InBuffer, int nInBufferSize, void* OutBuffer, int nOutBufferSize) { + SyncIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, true); } unsafe static void InitMonitor() { @@ -326,8 +379,8 @@ initFilterFromDevice(ref Filter, aDevice); IntPtr pvId = USBLibAddFilter(ref Filter); if (pvId == IntPtr.Zero) throw new Exception("Add one-shot Filter failed"); - //USBLibRunFilters(); - aDevice.Reenumerate(0); + USBLibRunFilters(); + //aDevice.Reenumerate(0); } public unsafe static void Release(DeviceNode aDevice) { InitMonitor(); @@ -335,8 +388,8 @@ initFilterFromDevice(ref Filter, aDevice); IntPtr pvId = USBLibAddFilter(ref Filter); if (pvId == IntPtr.Zero) throw new Exception("Add one-shot Filter failed"); - //USBLibRunFilters(); - aDevice.Reenumerate(0); + USBLibRunFilters(); + //aDevice.Reenumerate(0); } public static IUsbDeviceRegistry GetDeviceForDeviceNode(DeviceNode device) { String[] intfpath = device.GetInterfaces(new Guid(0x873fdf, 0xCAFE, 0x80EE, 0xaa, 0x5e, 0x0, 0xc0, 0x4f, 0xb1, 0x72, 0xb)); @@ -368,7 +421,7 @@ public unsafe override void Close() { if (!hDev.IsInvalid && !hDev.IsClosed) { USBSUP_CLAIMDEV release = new USBSUP_CLAIMDEV() { bInterfaceNumber = bInterfaceNumber }; - SyncIoControl(hDev, SUPUSB_IOCTL_USB_RELEASE_DEVICE, &release, sizeof(USBSUP_CLAIMDEV), null, 0); + SyncIoControl(hDev, SUPUSB_IOCTL_USB_RELEASE_DEVICE, &release, sizeof(USBSUP_CLAIMDEV), null, 0, false); } hDev.Close(); } @@ -409,6 +462,7 @@ } private unsafe int BlockTransfer(USBSUP_TRANSFER_TYPE type, USBSUP_DIRECTION dir, USBSUP_XFER_FLAG flags, UInt32 ep, Byte[] buffer, int offset, int length) { + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); fixed (Byte* ptr = buffer) { USBSUP_URB urb = new USBSUP_URB(); urb.type = type; @@ -416,7 +470,7 @@ urb.flags = flags; urb.ep = ep; urb.len = (UIntPtr)length; - urb.buf = ptr; + urb.buf = ptr + offset; HandleURB(&urb); return (int)urb.len; }
--- a/USBLib/Windows/USB/UsbBus.cs Wed Oct 09 20:56:28 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using UCIS.HWLib.Windows.Devices; -using UCIS.USBLib.Internal.Windows; - -namespace UCIS.HWLib.Windows.USB { - public class UsbBus { - private List<UsbController> devices = null; - public IList<UsbController> Controllers { - get { - if (devices == null) Refresh(); - return devices.AsReadOnly(); - } - } - public void Refresh() { - devices = new List<UsbController>(); - Guid m_Guid = new Guid(UsbApi.GUID_DEVINTERFACE_HUBCONTROLLER); - foreach (DeviceNode dev in DeviceNode.GetDevices(m_Guid)) { - String[] interfaces = dev.GetInterfaces(m_Guid); - if (interfaces == null || interfaces.Length == 0) continue; - devices.Add(new UsbController(this, dev, interfaces[0])); - } - } - } -} \ No newline at end of file
--- a/USBLib/Windows/USB/UsbController.cs Wed Oct 09 20:56:28 2013 +0200 +++ b/USBLib/Windows/USB/UsbController.cs Sat Oct 12 16:35:24 2013 +0200 @@ -1,19 +1,16 @@ using System; -using System.Runtime.InteropServices; +using System.Collections.Generic; using Microsoft.Win32.SafeHandles; using UCIS.HWLib.Windows.Devices; using UCIS.USBLib.Internal.Windows; namespace UCIS.HWLib.Windows.USB { public class UsbController { + static readonly Guid IID_DEVINTERFACE_USB_CONTROLLER = new Guid(UsbApi.GUID_DEVINTERFACE_HUBCONTROLLER); public String DevicePath { get; private set; } public DeviceNode DeviceNode { get; private set; } - public String DeviceDescription { - get { return DeviceNode.GetPropertyString(SPDRP.DeviceDesc); } - } - public String DriverKey { - get { return DeviceNode.GetPropertyString(SPDRP.Driver); } - } + public String DeviceDescription { get { return DeviceNode.DeviceDescription; } } + public String DriverKey { get { return DeviceNode.DriverKey; } } public UsbHub RootHub { get { String rootHubName; @@ -21,9 +18,24 @@ return new UsbHub(null, new USB_NODE_CONNECTION_INFORMATION_EX(), @"\\?\" + rootHubName, 0, true); } } - internal UsbController(UsbBus parent, DeviceNode di, String devicePath) { + private UsbController(DeviceNode di, String devicePath) { this.DeviceNode = di; this.DevicePath = devicePath; } + + public static UsbController GetControllerForDeviceNode(DeviceNode node) { + String[] interfaces = node.GetInterfaces(IID_DEVINTERFACE_USB_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)) { + UsbController controller = GetControllerForDeviceNode(dev); + if (controller != null) devices.Add(controller); + } + return devices; + } } }
--- a/USBLib/Windows/USB/UsbDevice.cs Wed Oct 09 20:56:28 2013 +0200 +++ b/USBLib/Windows/USB/UsbDevice.cs Sat Oct 12 16:35:24 2013 +0200 @@ -1,8 +1,6 @@ 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; @@ -10,8 +8,8 @@ using UCIS.USBLib.Internal.Windows; namespace UCIS.HWLib.Windows.USB { - public class UsbDevice : IUsbInterface { - internal static SafeFileHandle OpenHandle(String path) { + public class UsbDevice : IUsbDevice, IUsbInterface { + protected 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; @@ -29,7 +27,7 @@ throw new Win32Exception(Marshal.GetLastWin32Error()); return true; } - internal static String GetNodeConnectionName(SafeFileHandle handle, UInt32 port) { + protected 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; @@ -37,7 +35,7 @@ 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) { + protected 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; @@ -57,7 +55,7 @@ if (nBytes > 0) Buffer.BlockCopy(bigbuffer, szRequest, buffer, offset, nBytes); return nBytes; } - internal unsafe static String GetRootHubName(SafeFileHandle handle) { + protected 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)) @@ -65,7 +63,7 @@ if (rootHubName.ActualLength <= 0) return null; return rootHubName.RootHubName; } - internal unsafe static String GetNodeConnectionDriverKey(SafeFileHandle handle, UInt32 port) { + protected 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; @@ -75,10 +73,10 @@ } public UsbDevice Parent { get; protected set; } - public string DevicePath { get; private set; } - public uint AdapterNumber { get; private set; } + public String DevicePath { get; private set; } + public UInt32 AdapterNumber { get; private set; } internal USB_NODE_CONNECTION_INFORMATION_EX NodeConnectionInfo { get; set; } - internal USB_DEVICE_DESCRIPTOR DeviceDescriptor { get { return NodeConnectionInfo.DeviceDescriptor; } } + private 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; } } @@ -105,7 +103,7 @@ 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 virtual string DeviceDescription { get { return DeviceNode == null ? null : DeviceNode.DeviceDescription; } } public string DeviceID { get { return DeviceNode == null ? null : DeviceNode.DeviceID; } } private DeviceNode mDeviceNode; @@ -137,10 +135,10 @@ } static UsbDevice GetUsbDevice(DeviceNode node, out Boolean isHostController) { - String[] hciinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_HOST_CONTROLLER); - if (hciinterface != null && hciinterface.Length > 0) { + UsbController controller = UsbController.GetControllerForDeviceNode(node); + if (controller != null) { isHostController = true; - return (new UsbController(null, node, hciinterface[0])).RootHub; + return controller.RootHub; } isHostController = false; DeviceNode parent = node.GetParent(); @@ -148,8 +146,12 @@ UsbDevice usbdev = GetUsbDevice(parent, out isHostControllerA); if (isHostControllerA) return usbdev; UsbHub usbhub = usbdev as UsbHub; - if (usbhub == null) return null; + if (usbhub == null) { + if (parent.Service == "usbccgp") return usbdev; + return null; + } String driverkey = node.DriverKey; + if (driverkey == null) return null; foreach (UsbDevice child in usbhub.Devices) { if (driverkey.Equals(child.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return child; } @@ -158,27 +160,6 @@ 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); - } - String[] devinterface = node.GetInterfaces(UsbApi.GUID_DEVINTERFACE_USB_DEVICE); - if (devinterface == null || devinterface.Length == 0) return null; - DeviceNode parent = node.GetParent(); - if (parent == null) return null; - UsbHub usbhub = GetUsbDevice(parent) as UsbHub; - if (usbhub == null) return null; - String driverkey = node.DriverKey; - foreach (UsbDevice usbdev in usbhub.Devices) { - if (driverkey.Equals(usbdev.DriverKey, StringComparison.InvariantCultureIgnoreCase)) return usbdev; - } - return null;*/ } #region IUsbInterface Members @@ -202,6 +183,12 @@ UsbPipeStream IUsbInterface.GetInterruptStream(byte endpoint) { throw new NotImplementedException(); } void IDisposable.Dispose() { } #endregion + #region IUsbDevice Members + 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 } - }
--- a/USBLib/Windows/USB/UsbHub.cs Wed Oct 09 20:56:28 2013 +0200 +++ b/USBLib/Windows/USB/UsbHub.cs Sat Oct 12 16:35:24 2013 +0200 @@ -1,10 +1,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; using UCIS.USBLib.Internal.Windows; -using System.ComponentModel; -using UCIS.USBLib.Communication; namespace UCIS.HWLib.Windows.USB { public class UsbHub : UsbDevice { @@ -18,7 +17,7 @@ public override string DriverKey { get { if (Parent == null) return null; - using (SafeFileHandle handle = OpenHandle(Parent.DevicePath)) return UsbHub.GetNodeConnectionDriverKey(handle, AdapterNumber); + using (SafeFileHandle handle = OpenHandle(Parent.DevicePath)) return GetNodeConnectionDriverKey(handle, AdapterNumber); } } @@ -34,7 +33,7 @@ public override int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) { if (Parent == null) return 0; - using (SafeFileHandle handle = UsbHub.OpenHandle(Parent.DevicePath)) return UsbHub.GetDescriptor(handle, AdapterNumber, descriptorType, index, langId, buffer, offset, length); + using (SafeFileHandle handle = UsbHub.OpenHandle(Parent.DevicePath)) return GetDescriptor(handle, AdapterNumber, descriptorType, index, langId, buffer, offset, length); }