From d1fb6c4ab4e259a8082a2c24e28538351880d0fc Mon Sep 17 00:00:00 2001 From: Alexey 'Cluster' Avdyukhin Date: Sun, 5 Mar 2017 14:38:01 +0300 Subject: USB library changed to LibWinUsb, it's more portable --- FelLib/Fel.cs | 115 +++-- FelLib/WinUSBNet/API/APIException.cs | 45 -- FelLib/WinUSBNet/API/DeviceDetails.cs | 23 - FelLib/WinUSBNet/API/DeviceManagement.cs | 315 ------------ FelLib/WinUSBNet/API/DeviceManagementAPI.cs | 159 ------ FelLib/WinUSBNet/API/FileAPI.cs | 39 -- FelLib/WinUSBNet/API/WinUSBDevice.cs | 477 ------------------ FelLib/WinUSBNet/API/WinUSBDeviceAPI.cs | 202 -------- FelLib/WinUSBNet/DeviceNotifyHook.cs | 117 ----- FelLib/WinUSBNet/USB.cs | 80 --- FelLib/WinUSBNet/USBAsyncResult.cs | 136 ----- FelLib/WinUSBNet/USBDevice.cs | 756 ---------------------------- FelLib/WinUSBNet/USBDeviceDescriptor.cs | 135 ----- FelLib/WinUSBNet/USBDeviceInfo.cs | 85 ---- FelLib/WinUSBNet/USBException.cs | 40 -- FelLib/WinUSBNet/USBInterface.cs | 152 ------ FelLib/WinUSBNet/USBInterfaceCollection.cs | 160 ------ FelLib/WinUSBNet/USBNotifier.cs | 190 ------- FelLib/WinUSBNet/USBPipe.cs | 387 -------------- FelLib/WinUSBNet/USBPipeCollection.cs | 135 ----- FelLib/WinUSBNet/USBPipePolicy.cs | 181 ------- 21 files changed, 78 insertions(+), 3851 deletions(-) delete mode 100644 FelLib/WinUSBNet/API/APIException.cs delete mode 100644 FelLib/WinUSBNet/API/DeviceDetails.cs delete mode 100644 FelLib/WinUSBNet/API/DeviceManagement.cs delete mode 100644 FelLib/WinUSBNet/API/DeviceManagementAPI.cs delete mode 100644 FelLib/WinUSBNet/API/FileAPI.cs delete mode 100644 FelLib/WinUSBNet/API/WinUSBDevice.cs delete mode 100644 FelLib/WinUSBNet/API/WinUSBDeviceAPI.cs delete mode 100644 FelLib/WinUSBNet/DeviceNotifyHook.cs delete mode 100644 FelLib/WinUSBNet/USB.cs delete mode 100644 FelLib/WinUSBNet/USBAsyncResult.cs delete mode 100644 FelLib/WinUSBNet/USBDevice.cs delete mode 100644 FelLib/WinUSBNet/USBDeviceDescriptor.cs delete mode 100644 FelLib/WinUSBNet/USBDeviceInfo.cs delete mode 100644 FelLib/WinUSBNet/USBException.cs delete mode 100644 FelLib/WinUSBNet/USBInterface.cs delete mode 100644 FelLib/WinUSBNet/USBInterfaceCollection.cs delete mode 100644 FelLib/WinUSBNet/USBNotifier.cs delete mode 100644 FelLib/WinUSBNet/USBPipe.cs delete mode 100644 FelLib/WinUSBNet/USBPipeCollection.cs delete mode 100644 FelLib/WinUSBNet/USBPipePolicy.cs (limited to 'FelLib') diff --git a/FelLib/Fel.cs b/FelLib/Fel.cs index 7c195d4d..d525edd1 100644 --- a/FelLib/Fel.cs +++ b/FelLib/Fel.cs @@ -1,4 +1,5 @@ -using MadWizard.WinUSBNet; +using LibUsbDotNet; +using LibUsbDotNet.Main; using System; using System.Collections.Generic; using System.Diagnostics; @@ -16,9 +17,9 @@ namespace com.clusterrr.FelLib public enum CurrentAction { RunningCommand, ReadingMemory, WritingMemory } public delegate void OnFelProgress(CurrentAction action, string command); - USBDevice device = null; - byte inEndp = 0; - byte outEndp = 0; + UsbDevice device = null; + UsbEndpointReader epReader = null; + UsbEndpointWriter epWriter = null; const int ReadTimeout = 1000; const int WriteTimeout = 1000; public const int MaxBulkSize = 0x10000; @@ -85,46 +86,74 @@ namespace com.clusterrr.FelLib this.pid = pid; Close(); Debug.WriteLine("Trying to open device..."); - device = USBDevice.GetSingleDevice(vid, pid); - if (device == null) throw new FelException("Device with such VID and PID not found"); - Debug.WriteLine("Checking USB endpoints..."); - foreach (var pipe in device.Pipes) + var devices = UsbDevice.AllDevices; + device = null; + foreach (UsbRegistry regDevice in devices) { - if (pipe.IsIn) - { - inEndp = pipe.Address; - Debug.WriteLine("IN endpoint found: " + inEndp); - } - else + if (regDevice.Vid == vid && regDevice.Pid == pid) { - outEndp = pipe.Address; - Debug.WriteLine("Out endpoint found: " + outEndp); + regDevice.Open(out device); + break; } } - device.Pipes[inEndp].Policy.PipeTransferTimeout = ReadTimeout; - device.Pipes[outEndp].Policy.PipeTransferTimeout = WriteTimeout; + if (device == null) throw new FelException("Device with such VID and PID not found"); + + IUsbDevice wholeUsbDevice = device as IUsbDevice; + if (!ReferenceEquals(wholeUsbDevice, null)) + { + // This is a "whole" USB device. Before it can be used, + // the desired configuration and interface must be selected. + + // Select config #1 + wholeUsbDevice.SetConfiguration(1); + + // Claim interface #0. + wholeUsbDevice.ClaimInterface(0); + } + + int inEndp = -1; + int outEndp = -1; + int inMax = 0; + int outMax = 0; + Debug.WriteLine("Checking USB endpoints..."); + foreach (var config in device.Configs) + foreach (var @interface in config.InterfaceInfoList) + foreach (var endp in @interface.EndpointInfoList) + { + if ((endp.Descriptor.EndpointID & 0x80) != 0) + { + inEndp = endp.Descriptor.EndpointID; + inMax = endp.Descriptor.MaxPacketSize; + Debug.WriteLine("IN endpoint found: " + inEndp); + Debug.WriteLine("IN endpoint maxsize: " + inMax); + } + else + { + outEndp = endp.Descriptor.EndpointID; + outMax = endp.Descriptor.MaxPacketSize; + Debug.WriteLine("OUT endpoint found: " + outEndp); + Debug.WriteLine("OUT endpoint maxsize: " + outMax); + } + } + if (inEndp != 0x82 || inMax != 64 || outEndp != 0x01 || outMax != 64) + throw new Exception("Uncorrect FEL device"); + epReader = device.OpenEndpointReader((ReadEndpointID)inEndp, 65536); + epWriter = device.OpenEndpointWriter((WriteEndpointID)outEndp); + Debug.WriteLine("Trying to verify device"); if (VerifyDevice().Board != 0x00166700) throw new FelException("Invalid board ID: " + VerifyDevice().Board); } public void Close() { if (device != null) - { - try - { - device.Pipes[inEndp].Abort(); - } - catch { } - try - { - device.Pipes[outEndp].Abort(); - } - catch - { - } - device.Dispose(); - device = null; - } + device.Close(); + device = null; + if (epReader != null) + epReader.Dispose(); + epReader = null; + if (epWriter != null) + epWriter.Dispose(); + epWriter = null; } private void WriteToUSB(byte[] buffer) @@ -133,17 +162,29 @@ namespace com.clusterrr.FelLib // Debug.WriteLine("-> " + BitConverter.ToString(buffer)); //#endif Debug.WriteLine(string.Format("-> {0} bytes" , buffer.Length)); - device.Pipes[outEndp].Write(buffer); + int pos = 0; + int l; + while (pos < buffer.Length) + { + epWriter.Write(buffer, pos, buffer.Length - pos, WriteTimeout, out l); + if (l > 0) + pos += l; + else + throw new Exception("Can't write to USB"); + } } private int ReadFromUSB(byte[] buffer, int offset, int length) { - var data = device.Pipes[inEndp].Read(buffer, offset, length); + int l; + var result = epReader.Read(buffer, offset, length, ReadTimeout, out l); + if (result != ErrorCode.Ok) + throw new Exception("USB read error: " + result.ToString()); //#if DEBUG // Debug.WriteLine("<- " + BitConverter.ToString(buffer)); //#endif Debug.WriteLine(string.Format("<- {0} bytes", length)); - return data; + return l; } private byte[] ReadFromUSB(UInt32 length) { diff --git a/FelLib/WinUSBNet/API/APIException.cs b/FelLib/WinUSBNet/API/APIException.cs deleted file mode 100644 index 8c9987a6..00000000 --- a/FelLib/WinUSBNet/API/APIException.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime; -using System.Runtime.InteropServices; -using System.ComponentModel; - - -namespace MadWizard.WinUSBNet.API -{ - /// - /// Exception used internally to catch Win32 API errors. This exception should - /// not be thrown to the library's caller. - /// - internal class APIException : Exception - { - public APIException(string message) : - base(message) - { - - } - public APIException(string message, Exception innerException) : base(message, innerException) - { - } - - public static APIException Win32(string message) - { - return APIException.Win32(message, Marshal.GetLastWin32Error()); - } - - public static APIException Win32(string message, int errorCode) - { - return new APIException(message, new Win32Exception(errorCode)); - - } - - } -} diff --git a/FelLib/WinUSBNet/API/DeviceDetails.cs b/FelLib/WinUSBNet/API/DeviceDetails.cs deleted file mode 100644 index ada560c3..00000000 --- a/FelLib/WinUSBNet/API/DeviceDetails.cs +++ /dev/null @@ -1,23 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace MadWizard.WinUSBNet.API -{ - internal struct DeviceDetails - { - public string DevicePath; - public string Manufacturer; - public string DeviceDescription; - public ushort VID; - public ushort PID; - } -} diff --git a/FelLib/WinUSBNet/API/DeviceManagement.cs b/FelLib/WinUSBNet/API/DeviceManagement.cs deleted file mode 100644 index f14eea14..00000000 --- a/FelLib/WinUSBNet/API/DeviceManagement.cs +++ /dev/null @@ -1,315 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -/* NOTE: Parts of the code in this file are based on the work of Jan Axelson - * See http://www.lvr.com/winusb.htm for more information - */ - -using System; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Windows.Forms; -using System.Text.RegularExpressions; -using System.Diagnostics; - -namespace MadWizard.WinUSBNet.API -{ - /// - /// Routines for detecting devices and receiving device notifications. - /// - internal static partial class DeviceManagement - { - - // Get device name from notification message. - // Also checks checkGuid with the GUID from the message to check the notification - // is for a relevant device. Other messages might be received. - public static string GetNotifyMessageDeviceName(Message m, Guid checkGuid) - { - int stringSize; - - - DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE_1(); - DEV_BROADCAST_HDR devBroadcastHeader = new DEV_BROADCAST_HDR(); - - // The LParam parameter of Message is a pointer to a DEV_BROADCAST_HDR structure. - - Marshal.PtrToStructure(m.LParam, devBroadcastHeader); - - if ((devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)) - { - // The dbch_devicetype parameter indicates that the event applies to a device interface. - // So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure, - // which begins with a DEV_BROADCAST_HDR. - - // Obtain the number of characters in dbch_name by subtracting the 32 bytes - // in the strucutre that are not part of dbch_name and dividing by 2 because there are - // 2 bytes per character. - - stringSize = System.Convert.ToInt32((devBroadcastHeader.dbch_size - 32) / 2); - - // The dbcc_name parameter of devBroadcastDeviceInterface contains the device name. - // Trim dbcc_name to match the size of the String. - - devBroadcastDeviceInterface.dbcc_name = new char[stringSize + 1]; - - // Marshal data from the unmanaged block pointed to by m.LParam - // to the managed object devBroadcastDeviceInterface. - - Marshal.PtrToStructure(m.LParam, devBroadcastDeviceInterface); - - // Check if message is for the GUID - if (devBroadcastDeviceInterface.dbcc_classguid != checkGuid) - return null; - - // Store the device name in a String. - string deviceNameString = new String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize); - - return deviceNameString; - - } - return null; - } - - private static byte[] GetProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property, out int regType) - { - uint requiredSize; - - if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, IntPtr.Zero, IntPtr.Zero, 0, out requiredSize)) - { - if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) - throw APIException.Win32("Failed to get buffer size for device registry property."); - } - - byte[] buffer = new byte[requiredSize]; - - if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, property, out regType, buffer, (uint)buffer.Length, out requiredSize)) - throw APIException.Win32("Failed to get device registry property."); - - return buffer; - } - - // todo: is the queried data always available, or should we check ERROR_INVALID_DATA? - private static string GetStringProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property) - { - int regType; - byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out regType); - if (regType != (int)RegTypes.REG_SZ) - throw new APIException("Invalid registry type returned for device property."); - - // sizof(char), 2 bytes, are removed to leave out the string terminator - return System.Text.Encoding.Unicode.GetString(buffer, 0, buffer.Length - sizeof(char)); - } - - private static string[] GetMultiStringProperty(IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData, SPDRP property) - { - int regType; - byte[] buffer = GetProperty(deviceInfoSet, deviceInfoData, property, out regType); - if (regType != (int)RegTypes.REG_MULTI_SZ) - throw new APIException("Invalid registry type returned for device property."); - - string fullString = System.Text.Encoding.Unicode.GetString(buffer); - - return fullString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); - - } - private static DeviceDetails GetDeviceDetails(string devicePath, IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData) - { - DeviceDetails details = new DeviceDetails(); - details.DevicePath = devicePath; - details.DeviceDescription = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_DEVICEDESC); - details.Manufacturer = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_MFG); - string[] hardwareIDs = GetMultiStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_HARDWAREID); - - Regex regex = new Regex("^USB\\\\VID_([0-9A-F]{4})&PID_([0-9A-F]{4})", RegexOptions.IgnoreCase); - bool foundVidPid = false; - foreach (string hardwareID in hardwareIDs) - { - Match match = regex.Match(hardwareID); - if (match.Success) - { - details.VID = ushort.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.AllowHexSpecifier); - details.PID = ushort.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.AllowHexSpecifier); - foundVidPid = true; - break; - } - } - - if (!foundVidPid) - throw new APIException("Failed to find VID and PID for USB device. No hardware ID could be parsed."); - - return details; - } - - - public static DeviceDetails[] FindDevices(UInt16 vid, UInt16 pid) - { - IntPtr deviceInfoSet = IntPtr.Zero; - List deviceList = new List(); - var guid = new Guid("{A5DCBF10-6530-11D2-901F-00C04FB951ED}"); // USB device - try - { - deviceInfoSet = SetupDiGetClassDevs(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, - DIGCF_PRESENT | DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES); - if (deviceInfoSet == FileIO.INVALID_HANDLE_VALUE) - throw APIException.Win32("Failed to enumerate devices."); - int memberIndex = 0; - while (true) - { - // Begin with 0 and increment through the device information set until - // no more devices are available. - SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); - - // The cbSize element of the deviceInterfaceData structure must be set to - // the structure's size in bytes. - // The size is 28 bytes for 32-bit code and 32 bytes for 64-bit code. - deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); - - bool success; - - success = SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData); - - // Find out if a device information set was retrieved. - if (!success) - { - int lastError = Marshal.GetLastWin32Error(); - if (lastError == ERROR_NO_MORE_ITEMS) - break; - - throw APIException.Win32("Failed to get device interface."); - } - // A device is present. - - int bufferSize = 0; - - success = SetupDiGetDeviceInterfaceDetail - (deviceInfoSet, - ref deviceInterfaceData, - IntPtr.Zero, - 0, - ref bufferSize, - IntPtr.Zero); - - if (!success) - { - if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) - throw APIException.Win32("Failed to get interface details buffer size."); - } - - IntPtr detailDataBuffer = IntPtr.Zero; - try - { - - // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size. - detailDataBuffer = Marshal.AllocHGlobal(bufferSize); - - // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems. - - Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8); - - // Call SetupDiGetDeviceInterfaceDetail again. - // This time, pass a pointer to DetailDataBuffer - // and the returned required buffer size. - - // build a DevInfo Data structure - SP_DEVINFO_DATA da = new SP_DEVINFO_DATA(); - da.cbSize = Marshal.SizeOf(da); - - - success = SetupDiGetDeviceInterfaceDetail - (deviceInfoSet, - ref deviceInterfaceData, - detailDataBuffer, - bufferSize, - ref bufferSize, - ref da); - - if (!success) - throw APIException.Win32("Failed to get device interface details."); - - - // Skip over cbsize (4 bytes) to get the address of the devicePathName. - - IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt64() + 4); - string pathName = Marshal.PtrToStringUni(pDevicePathName); - - // Get the String containing the devicePathName. - try - { - Debug.WriteLine("Trying to parse device: " + pathName); - DeviceDetails details = GetDeviceDetails(pathName, deviceInfoSet, da); - if (details.VID == vid && details.PID == pid) - deviceList.Add(details); - } - catch (APIException ex) - { - Debug.WriteLine("Can't parse this device: " + ex.Message + ex.StackTrace); - } - } - finally - { - if (detailDataBuffer != IntPtr.Zero) - { - Marshal.FreeHGlobal(detailDataBuffer); - detailDataBuffer = IntPtr.Zero; - } - } - memberIndex++; - } - } - finally - { - if (deviceInfoSet != IntPtr.Zero && deviceInfoSet != FileIO.INVALID_HANDLE_VALUE) - { - SetupDiDestroyDeviceInfoList(deviceInfoSet); - } - } - return deviceList.ToArray(); - } - - - public static void RegisterForDeviceNotifications(IntPtr controlHandle, Guid classGuid, ref IntPtr deviceNotificationHandle) - { - - DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE(); - IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero; - try - { - int size = Marshal.SizeOf(devBroadcastDeviceInterface); - devBroadcastDeviceInterface.dbcc_size = size; - - devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - devBroadcastDeviceInterface.dbcc_reserved = 0; - devBroadcastDeviceInterface.dbcc_classguid = classGuid; - devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size); - - // Copy the DEV_BROADCAST_DEVICEINTERFACE structure to the buffer. - // Set fDeleteOld True to prevent memory leaks. - Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true); - - deviceNotificationHandle = RegisterDeviceNotification(controlHandle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE); - if (deviceNotificationHandle == IntPtr.Zero) - throw APIException.Win32("Failed to register device notification"); - - // Marshal data from the unmanaged block devBroadcastDeviceInterfaceBuffer to - // the managed object devBroadcastDeviceInterface - Marshal.PtrToStructure(devBroadcastDeviceInterfaceBuffer, devBroadcastDeviceInterface); - } - finally - { - // Free the memory allocated previously by AllocHGlobal. - if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero) - Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer); - } - } - - public static void StopDeviceDeviceNotifications(IntPtr deviceNotificationHandle) - { - if (!DeviceManagement.UnregisterDeviceNotification(deviceNotificationHandle)) - throw APIException.Win32("Failed to unregister device notification"); - } - } -} diff --git a/FelLib/WinUSBNet/API/DeviceManagementAPI.cs b/FelLib/WinUSBNet/API/DeviceManagementAPI.cs deleted file mode 100644 index 00ebfc69..00000000 --- a/FelLib/WinUSBNet/API/DeviceManagementAPI.cs +++ /dev/null @@ -1,159 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -/* NOTE: Parts of the code in this file are based on the work of Jan Axelson - * See http://www.lvr.com/winusb.htm for more information - */ - -using System; -using System.Runtime.InteropServices; - -namespace MadWizard.WinUSBNet.API -{ - /// - /// API declarations relating to device management (SetupDixxx and - /// RegisterDeviceNotification functions). - /// - - internal static partial class DeviceManagement - { - // from dbt.h - - internal const Int32 DBT_DEVICEARRIVAL = 0X8000; - internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004; - private const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5; - private const Int32 DBT_DEVTYP_HANDLE = 6; - private const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4; - private const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 1; - private const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0; - internal const Int32 WM_DEVICECHANGE = 0X219; - - // from setupapi.h - - private const Int32 DIGCF_PRESENT = 2; - private const Int32 DIGCF_DEVICEINTERFACE = 0X10; - private const Int32 DIGCF_ALLCLASSES = 0X04; - - // Two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure. - - // Use this one in the call to RegisterDeviceNotification() and - // in checking dbch_devicetype in a DEV_BROADCAST_HDR structure: - - [StructLayout(LayoutKind.Sequential)] - private class DEV_BROADCAST_DEVICEINTERFACE - { - internal Int32 dbcc_size; - internal Int32 dbcc_devicetype; - internal Int32 dbcc_reserved; - internal Guid dbcc_classguid; - internal Int16 dbcc_name; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private class DEV_BROADCAST_DEVICEINTERFACE_1 - { - internal Int32 dbcc_size; - internal Int32 dbcc_devicetype; - internal Int32 dbcc_reserved; - internal Guid dbcc_classguid; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)] - internal Char[] dbcc_name; - } - - [StructLayout(LayoutKind.Sequential)] - private class DEV_BROADCAST_HDR - { - internal Int32 dbch_size; - internal Int32 dbch_devicetype; - internal Int32 dbch_reserved; - } - - private struct SP_DEVICE_INTERFACE_DATA - { - internal Int32 cbSize; - internal System.Guid InterfaceClassGuid; - internal Int32 Flags; - internal IntPtr Reserved; - } - private struct SP_DEVINFO_DATA - { - internal Int32 cbSize; - internal System.Guid ClassGuid; - internal Int32 DevInst; - internal IntPtr Reserved; - } - - // from pinvoke.net - private enum SPDRP : uint - { - SPDRP_DEVICEDESC = 0x00000000, - SPDRP_HARDWAREID = 0x00000001, - SPDRP_COMPATIBLEIDS = 0x00000002, - SPDRP_NTDEVICEPATHS = 0x00000003, - SPDRP_SERVICE = 0x00000004, - SPDRP_CONFIGURATION = 0x00000005, - SPDRP_CONFIGURATIONVECTOR = 0x00000006, - SPDRP_CLASS = 0x00000007, - SPDRP_CLASSGUID = 0x00000008, - SPDRP_DRIVER = 0x00000009, - SPDRP_CONFIGFLAGS = 0x0000000A, - SPDRP_MFG = 0x0000000B, - SPDRP_FRIENDLYNAME = 0x0000000C, - SPDRP_LOCATION_INFORMATION = 0x0000000D, - SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E, - SPDRP_CAPABILITIES = 0x0000000F, - SPDRP_UI_NUMBER = 0x00000010, - SPDRP_UPPERFILTERS = 0x00000011, - SPDRP_LOWERFILTERS = 0x00000012, - SPDRP_MAXIMUM_PROPERTY = 0x00000013, - - SPDRP_ENUMERATOR_NAME = 0x16, - }; - - - private enum RegTypes : int - { - // incomplete list, these are just the ones used. - REG_SZ = 1, - REG_MULTI_SZ = 7 - } - - - [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - private static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags); - - //[DllImport("setupapi.dll", SetLastError = true)] - //internal static extern Int32 SetupDiCreateDeviceInfoList(ref System.Guid ClassGuid, Int32 hwndParent); - - [DllImport("setupapi.dll", SetLastError = true)] - private static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); - - [DllImport("setupapi.dll", SetLastError = true)] - private static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData); - - [DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)] - private static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, SPDRP Property, out int PropertyRegDataType, byte[] PropertyBuffer, uint PropertyBufferSize, out UInt32 RequiredSize); - - [DllImport("setupapi.dll", CharSet = CharSet.Unicode, SetLastError = true)] - private static extern bool SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, SPDRP Property, IntPtr PropertyRegDataType, IntPtr PropertyBuffer, uint PropertyBufferSize, out UInt32 RequiredSize); - - [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern IntPtr SetupDiGetClassDevs(IntPtr ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags); - - [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData); - - [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData); - - [DllImport("user32.dll", SetLastError = true)] - private static extern bool UnregisterDeviceNotification(IntPtr Handle); - - private const int ERROR_NO_MORE_ITEMS = 259; - private const int ERROR_INSUFFICIENT_BUFFER = 122; - } -} diff --git a/FelLib/WinUSBNet/API/FileAPI.cs b/FelLib/WinUSBNet/API/FileAPI.cs deleted file mode 100644 index f785c9c4..00000000 --- a/FelLib/WinUSBNet/API/FileAPI.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -/* NOTE: Parts of the code in this file are based on the work of Jan Axelson - * See http://www.lvr.com/winusb.htm for more information - */ - -using System; -using Microsoft.Win32.SafeHandles; -using System.Runtime.InteropServices; - -namespace MadWizard.WinUSBNet.API -{ - /// - /// API declarations relating to file I/O (and used by WinUsb). - /// - - sealed internal class FileIO - { - public const Int32 FILE_ATTRIBUTE_NORMAL = 0X80; - public const Int32 FILE_FLAG_OVERLAPPED = 0X40000000; - public const Int32 FILE_SHARE_READ = 1; - public const Int32 FILE_SHARE_WRITE = 2; - public const UInt32 GENERIC_READ = 0X80000000; - public const UInt32 GENERIC_WRITE = 0X40000000; - public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); - public const Int32 OPEN_EXISTING = 3; - - public const Int32 ERROR_IO_PENDING = 997; - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern SafeFileHandle CreateFile(String lpFileName, UInt32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, Int32 hTemplateFile); - } - -} diff --git a/FelLib/WinUSBNet/API/WinUSBDevice.cs b/FelLib/WinUSBNet/API/WinUSBDevice.cs deleted file mode 100644 index 93a9ad9c..00000000 --- a/FelLib/WinUSBNet/API/WinUSBDevice.cs +++ /dev/null @@ -1,477 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -/* NOTE: Parts of the code in this file are based on the work of Jan Axelson - * See http://www.lvr.com/winusb.htm for more information - */ - -using System; -using Microsoft.Win32.SafeHandles; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Threading; -using System.ComponentModel; - -namespace MadWizard.WinUSBNet.API -{ - /// - /// Wrapper for a WinUSB device dealing with the WinUSB and additional interface handles - /// - partial class WinUSBDevice : IDisposable - { - private bool _disposed = false; - private SafeFileHandle _deviceHandle; - private IntPtr _winUsbHandle = IntPtr.Zero; - private IntPtr[] _addInterfaces = null; - public WinUSBDevice() - { - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - ~WinUSBDevice() - { - Dispose(false); - } - - private void CheckNotDisposed() - { - if (_disposed) - throw new ObjectDisposedException("USB device object has been disposed."); - } - - // TODO: check if not disposed on methods (although this is already checked by USBDevice) - - protected virtual void Dispose(bool disposing) - { - if (_disposed) - return; - - if (disposing) - { - // Dispose managed resources - if (_deviceHandle != null && !_deviceHandle.IsInvalid) - _deviceHandle.Dispose(); - _deviceHandle = null; - } - - // Dispose unmanaged resources - FreeWinUSB(); - _disposed = true; - } - private void FreeWinUSB() - { - if (_addInterfaces != null) - { - for (int i = 0; i < _addInterfaces.Length; i++) - { - WinUsb_Free(_addInterfaces[i]); - } - _addInterfaces = null; - } - if (_winUsbHandle != IntPtr.Zero) - WinUsb_Free(_winUsbHandle); - _winUsbHandle = IntPtr.Zero; - } - - public USB_DEVICE_DESCRIPTOR GetDeviceDescriptor() - { - USB_DEVICE_DESCRIPTOR deviceDesc; - uint transfered; - uint size = (uint)Marshal.SizeOf(typeof(USB_DEVICE_DESCRIPTOR)); - bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_DEVICE_DESCRIPTOR_TYPE, - 0, 0, out deviceDesc, size, out transfered); - if (!success) - throw APIException.Win32("Failed to get USB device descriptor."); - - if (transfered != size) - throw APIException.Win32("Incomplete USB device descriptor."); - - return deviceDesc; - } - - private int ReadStringDescriptor(byte index, ushort languageID, byte[] buffer) - { - uint transfered; - bool success = WinUsb_GetDescriptor(_winUsbHandle, USB_STRING_DESCRIPTOR_TYPE, - index, languageID, buffer, (uint)buffer.Length, out transfered); - if (!success) - throw APIException.Win32("Failed to get USB string descriptor (" + index + ")."); - - if (transfered == 0) - throw new APIException("No data returned when reading USB descriptor."); - - int length = buffer[0]; - if (length > transfered) - throw new APIException("Unexpected length when reading USB descriptor."); - return length; - } - - public ushort[] GetSupportedLanguageIDs() - { - byte[] buffer = new byte[256]; - int length = ReadStringDescriptor(0, 0, buffer); - length -= 2; // Skip length byte and descriptor type - if (length < 0 || (length % 2) != 0) - throw new APIException("Unexpected length when reading supported languages."); - - ushort[] langIDs = new ushort[length / 2]; - Buffer.BlockCopy(buffer, 2, langIDs, 0, length); - return langIDs; - } - - public string GetStringDescriptor(byte index, ushort languageID) - { - byte[] buffer = new byte[256]; - int length = ReadStringDescriptor(index, languageID, buffer); - length -= 2; // Skip length byte and descriptor type - if (length < 0) - return null; - char[] chars = System.Text.Encoding.Unicode.GetChars(buffer, 2, length); - return new string(chars); - } - - public void ControlTransfer(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data) - { - uint bytesReturned = 0; - WINUSB_SETUP_PACKET setupPacket; - - setupPacket.RequestType = requestType; - setupPacket.Request = request; - setupPacket.Value = value; - setupPacket.Index = index; - setupPacket.Length = length; - - bool success = WinUsb_ControlTransfer(_winUsbHandle, setupPacket, data, length, ref bytesReturned, IntPtr.Zero); - if (!success) // todo check bytes returned? - throw APIException.Win32("Control transfer on WinUSB device failed."); - } - - - public void OpenDevice(string devicePathName) - { - try - { - _deviceHandle = FileIO.CreateFile(devicePathName, - (FileIO.GENERIC_WRITE | FileIO.GENERIC_READ), - FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, - IntPtr.Zero, - FileIO.OPEN_EXISTING, - FileIO.FILE_ATTRIBUTE_NORMAL | FileIO.FILE_FLAG_OVERLAPPED, - 0); - if (_deviceHandle.IsInvalid) - throw APIException.Win32("Failed to open WinUSB device handle."); - InitializeDevice(); - - } - catch(Exception) - { - if (_deviceHandle != null) - { - _deviceHandle.Dispose(); - _deviceHandle = null; - } - FreeWinUSB(); - throw; - } - } - - private IntPtr InterfaceHandle(int index) - { - if (index == 0) - return _winUsbHandle; - return _addInterfaces[index - 1]; - } - - public int InterfaceCount - { - get - { - return 1 + (_addInterfaces == null ? 0 : _addInterfaces.Length); - } - } - - public void GetInterfaceInfo(int interfaceIndex, out USB_INTERFACE_DESCRIPTOR descriptor, out WINUSB_PIPE_INFORMATION[] pipes) - { - var pipeList = new List(); - bool success = WinUsb_QueryInterfaceSettings(InterfaceHandle(interfaceIndex), 0, out descriptor); - if (!success) - throw APIException.Win32("Failed to get WinUSB device interface descriptor."); - - IntPtr interfaceHandle = InterfaceHandle(interfaceIndex); - for (byte pipeIdx = 0; pipeIdx < descriptor.bNumEndpoints; pipeIdx++) - { - WINUSB_PIPE_INFORMATION pipeInfo; - success = WinUsb_QueryPipe(interfaceHandle, 0, pipeIdx, out pipeInfo); - - pipeList.Add(pipeInfo); - if (!success) - throw APIException.Win32("Failed to get WinUSB device pipe information."); - } - pipes = pipeList.ToArray(); - - } - private void InitializeDevice() - { - bool success; - - success = WinUsb_Initialize(_deviceHandle, ref _winUsbHandle); - - if (!success) - throw APIException.Win32("Failed to initialize WinUSB handle. Device might not be connected."); - - List interfaces = new List(); - byte numAddInterfaces = 0; - byte idx = 0; - - try - { - while (true) - { - IntPtr ifaceHandle = IntPtr.Zero; - success = WinUsb_GetAssociatedInterface(_winUsbHandle, idx, out ifaceHandle); - if (!success) - { - if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS) - break; - - throw APIException.Win32("Failed to enumerate interfaces for WinUSB device."); - } - interfaces.Add(ifaceHandle); - idx++; - numAddInterfaces++; - } - } - finally - { - // Save interface handles (will be cleaned by Dispose) - // also in case of exception (which is why it is in finally block), - // because some handles might have already been opened and need - // to be disposed. - _addInterfaces = interfaces.ToArray(); - } - - // Bind handle (needed for overlapped I/O thread pool) - ThreadPool.BindHandle(_deviceHandle); - // TODO: bind interface handles as well? doesn't seem to be necessary - } - - public void ReadPipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToRead, out uint bytesRead) - { - bool success; - unsafe - { - fixed (byte* pBuffer = buffer) - { - success = WinUsb_ReadPipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToRead, - out bytesRead, IntPtr.Zero); - } - } - if (!success) - throw APIException.Win32("Failed to read pipe on WinUSB device."); - } - - private unsafe void HandleOverlappedAPI(bool success, string errorMessage, NativeOverlapped* pOverlapped, USBAsyncResult result, int bytesTransfered) - { - if (!success) - { - if (Marshal.GetLastWin32Error() != FileIO.ERROR_IO_PENDING) - { - Overlapped.Unpack(pOverlapped); - Overlapped.Free(pOverlapped); - throw APIException.Win32(errorMessage); - } - } - else - { - // Immediate success! - Overlapped.Unpack(pOverlapped); - Overlapped.Free(pOverlapped); - - result.OnCompletion(true, null, bytesTransfered, false); - // is the callback still called in this case?? todo - } - - } - - public void ReadPipeOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToRead, USBAsyncResult result) - { - Overlapped overlapped = new Overlapped(); - - overlapped.AsyncResult = result; - - unsafe - { - NativeOverlapped* pOverlapped = null; - uint bytesRead; - - pOverlapped = overlapped.Pack(PipeIOCallback, buffer); - bool success; - // Buffer is pinned already by overlapped.Pack - fixed (byte* pBuffer = buffer) - { - success = WinUsb_ReadPipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToRead, - out bytesRead, pOverlapped); - } - HandleOverlappedAPI(success, "Failed to asynchronously read pipe on WinUSB device.", pOverlapped, result, (int)bytesRead); - } - } - - public void WriteOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToWrite, USBAsyncResult result) - { - Overlapped overlapped = new Overlapped(); - overlapped.AsyncResult = result; - - unsafe - { - NativeOverlapped* pOverlapped = null; - - uint bytesWritten; - pOverlapped = overlapped.Pack(PipeIOCallback, buffer); - - bool success; - // Buffer is pinned already by overlapped.Pack - fixed (byte* pBuffer = buffer) - { - success = WinUsb_WritePipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)bytesToWrite, - out bytesWritten, pOverlapped); - } - HandleOverlappedAPI(success, "Failed to asynchronously write pipe on WinUSB device.", pOverlapped, result, (int)bytesWritten); - - } - } - - - - public void ControlTransferOverlapped(byte requestType, byte request, ushort value, ushort index, ushort length, byte[] data, USBAsyncResult result) - { - uint bytesReturned = 0; - WINUSB_SETUP_PACKET setupPacket; - - setupPacket.RequestType = requestType; - setupPacket.Request = request; - setupPacket.Value = value; - setupPacket.Index = index; - setupPacket.Length = length; - - Overlapped overlapped = new Overlapped(); - overlapped.AsyncResult = result; - - unsafe - { - NativeOverlapped* pOverlapped = null; - pOverlapped = overlapped.Pack(PipeIOCallback, data); - bool success = WinUsb_ControlTransfer(_winUsbHandle, setupPacket, data, length, ref bytesReturned, pOverlapped); - HandleOverlappedAPI(success, "Asynchronous control transfer on WinUSB device failed.", pOverlapped, result, (int)bytesReturned); - } - } - - private unsafe void PipeIOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped) - { - try - { - Exception error = null; - if (errorCode != 0) - { - error = APIException.Win32("Asynchronous operation on WinUSB device failed.", (int)errorCode); - } - Overlapped overlapped = Overlapped.Unpack(pOverlapped); - USBAsyncResult result = (USBAsyncResult)overlapped.AsyncResult; - Overlapped.Free(pOverlapped); - pOverlapped = null; - - result.OnCompletion(false, error, (int)numBytes, true); - } - finally - { - if (pOverlapped != null) - { - Overlapped.Unpack(pOverlapped); - Overlapped.Free(pOverlapped); - } - } - } - public void AbortPipe(int ifaceIndex, byte pipeID) - { - bool success = WinUsb_AbortPipe(InterfaceHandle(ifaceIndex), pipeID); - if (!success) - throw APIException.Win32("Failed to abort pipe on WinUSB device."); - - } - - public void WritePipe(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int length) - { - uint bytesWritten; - bool success; - unsafe - { - fixed (byte* pBuffer = buffer) - { - success = WinUsb_WritePipe(InterfaceHandle(ifaceIndex), pipeID, pBuffer + offset, (uint)length, - out bytesWritten, IntPtr.Zero); - } - } - if (!success || (bytesWritten != length)) - throw APIException.Win32("Failed to write pipe on WinUSB device."); - - } - - public void FlushPipe(int ifaceIndex, byte pipeID) - { - bool success = WinUsb_FlushPipe(InterfaceHandle(ifaceIndex), pipeID); - if (!success) - throw APIException.Win32("Failed to flush pipe on WinUSB device."); - } - - public void SetPipePolicy(int ifaceIndex, byte pipeID, POLICY_TYPE policyType, bool value) - { - byte byteVal = (byte)(value ? 1 : 0); - bool success = WinUsb_SetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, 1, ref byteVal); - if (!success) - throw APIException.Win32("Failed to set WinUSB pipe policy."); - } - - - public void SetPipePolicy(int ifaceIndex, byte pipeID, POLICY_TYPE policyType, uint value) - { - - bool success = WinUsb_SetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, 4, ref value); - - if (!success) - throw APIException.Win32("Failed to set WinUSB pipe policy."); - } - - - public bool GetPipePolicyBool(int ifaceIndex, byte pipeID, POLICY_TYPE policyType) - { - byte result; - uint length = 1; - - bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out result); - if (!success || length != 1) - throw APIException.Win32("Failed to get WinUSB pipe policy."); - return result != 0; - } - - - public uint GetPipePolicyUInt(int ifaceIndex, byte pipeID, POLICY_TYPE policyType) - { - - uint result; - uint length = 4; - bool success = WinUsb_GetPipePolicy(InterfaceHandle(ifaceIndex), pipeID, (uint)policyType, ref length, out result); - - if (!success || length != 4) - throw APIException.Win32("Failed to get WinUSB pipe policy."); - return result; - } - } -} diff --git a/FelLib/WinUSBNet/API/WinUSBDeviceAPI.cs b/FelLib/WinUSBNet/API/WinUSBDeviceAPI.cs deleted file mode 100644 index 0492b7fd..00000000 --- a/FelLib/WinUSBNet/API/WinUSBDeviceAPI.cs +++ /dev/null @@ -1,202 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -/* NOTE: Parts of the code in this file are based on the work of Jan Axelson - * See http://www.lvr.com/winusb.htm for more information - */ - -using System; -using Microsoft.Win32.SafeHandles; -using System.Runtime.InteropServices; -using System.Threading; - -namespace MadWizard.WinUSBNet.API -{ - [StructLayout(LayoutKind.Sequential)] - struct USB_DEVICE_DESCRIPTOR - { - public byte bLength; - public byte bDescriptorType; - public ushort bcdUSB; - public byte 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)] - struct USB_CONFIGURATION_DESCRIPTOR - { - public byte bLength; - public byte bDescriptorType; - public ushort wTotalLength; - public byte bNumInterfaces; - public byte bConfigurationValue; - public byte iConfiguration; - public byte bmAttributes; - public byte MaxPower; - } - - [StructLayout(LayoutKind.Sequential)] - struct USB_INTERFACE_DESCRIPTOR - { - public byte bLength; - public byte bDescriptorType; - public byte bInterfaceNumber; - public byte bAlternateSetting; - public byte bNumEndpoints; - public byte bInterfaceClass; - public byte bInterfaceSubClass; - public byte bInterfaceProtocol; - public byte iInterface; - }; - enum USBD_PIPE_TYPE : int - { - UsbdPipeTypeControl, - UsbdPipeTypeIsochronous, - UsbdPipeTypeBulk, - UsbdPipeTypeInterrupt, - } - [StructLayout(LayoutKind.Sequential)] - struct WINUSB_PIPE_INFORMATION - { - public USBD_PIPE_TYPE PipeType; - public byte PipeId; - public ushort MaximumPacketSize; - public byte Interval; - } - - enum POLICY_TYPE : int - { - SHORT_PACKET_TERMINATE = 1, - AUTO_CLEAR_STALL, - PIPE_TRANSFER_TIMEOUT, - IGNORE_SHORT_PACKETS, - ALLOW_PARTIAL_READS, - AUTO_FLUSH, - RAW_IO, - } - - - partial class WinUSBDevice - { - private const UInt32 DEVICE_SPEED = ((UInt32)(1)); - - private enum USB_DEVICE_SPEED : int - { - UsbLowSpeed = 1, - UsbFullSpeed, - UsbHighSpeed, - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - private struct WINUSB_SETUP_PACKET - { - public byte RequestType; - public byte Request; - public ushort Value; - public ushort Index; - public ushort Length; - } - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_ControlTransfer(IntPtr InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, IntPtr Overlapped); - - [DllImport("winusb.dll", SetLastError = true)] - private static unsafe extern bool WinUsb_ControlTransfer(IntPtr InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, Byte[] Buffer, UInt32 BufferLength, ref UInt32 LengthTransferred, NativeOverlapped* pOverlapped); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_Free(IntPtr InterfaceHandle); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_Initialize(SafeFileHandle DeviceHandle, ref IntPtr InterfaceHandle); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_QueryDeviceInformation(IntPtr InterfaceHandle, UInt32 InformationType, ref UInt32 BufferLength, out byte Buffer); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_QueryInterfaceSettings(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, out USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_QueryPipe(IntPtr InterfaceHandle, Byte AlternateInterfaceNumber, Byte PipeIndex, out WINUSB_PIPE_INFORMATION PipeInformation); - - [DllImport("winusb.dll", SetLastError = true)] - private static unsafe extern bool WinUsb_ReadPipe(IntPtr InterfaceHandle, byte PipeID, byte* pBuffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped); - - [DllImport("winusb.dll", SetLastError = true)] - private static unsafe extern bool WinUsb_ReadPipe(IntPtr InterfaceHandle, byte PipeID, byte* pBuffer, uint BufferLength, out uint LengthTransferred, NativeOverlapped* pOverlapped); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_AbortPipe(IntPtr InterfaceHandle, byte PipeID); - - // Two declarations for WinUsb_SetPipePolicy. - // Use this one when the returned Value is a Byte (all except PIPE_TRANSFER_TIMEOUT): - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_SetPipePolicy(IntPtr InterfaceHandle, Byte PipeID, UInt32 PolicyType, UInt32 ValueLength, ref byte Value); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_GetPipePolicy(IntPtr InterfaceHandle, Byte PipeID, UInt32 PolicyType, ref UInt32 ValueLength, out byte Value); - - // Use this alias when the returned Value is a UInt32 (PIPE_TRANSFER_TIMEOUT only): - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_SetPipePolicy(IntPtr InterfaceHandle, Byte PipeID, UInt32 PolicyType, UInt32 ValueLength, ref UInt32 Value); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_GetPipePolicy(IntPtr InterfaceHandle, Byte PipeID, UInt32 PolicyType, ref UInt32 ValueLength, out UInt32 Value); - - [DllImport("winusb.dll", SetLastError = true)] - private static unsafe extern bool WinUsb_WritePipe(IntPtr InterfaceHandle, byte PipeID, byte* pBuffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped); - - [DllImport("winusb.dll", SetLastError = true)] - private static unsafe extern bool WinUsb_WritePipe(IntPtr InterfaceHandle, byte PipeID, byte* pBuffer, uint BufferLength, out uint LengthTransferred, NativeOverlapped* pOverlapped); - - - [DllImport("kernel32.dll", SetLastError = true)] - private static unsafe extern bool CancelIo(IntPtr hFile); - - [DllImport("kernel32.dll", SetLastError = true)] - private static unsafe extern bool CancelIoEx(IntPtr hFile, NativeOverlapped* pOverlapped); - - - - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_FlushPipe(IntPtr InterfaceHandle, byte PipeID); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_GetDescriptor(IntPtr InterfaceHandle, byte DescriptorType, - byte Index, UInt16 LanguageID, byte[] Buffer, UInt32 BufferLength, out UInt32 LengthTransfered); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_GetDescriptor(IntPtr InterfaceHandle, byte DescriptorType, - byte Index, UInt16 LanguageID, out USB_DEVICE_DESCRIPTOR deviceDesc, UInt32 BufferLength, out UInt32 LengthTransfered); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_GetDescriptor(IntPtr InterfaceHandle, byte DescriptorType, - byte Index, UInt16 LanguageID, out USB_CONFIGURATION_DESCRIPTOR deviceDesc, UInt32 BufferLength, out UInt32 LengthTransfered); - - [DllImport("winusb.dll", SetLastError = true)] - private static extern bool WinUsb_GetAssociatedInterface(IntPtr InterfaceHandle, byte AssociatedInterfaceIndex, - out IntPtr AssociatedInterfaceHandle); - - private const int USB_DEVICE_DESCRIPTOR_TYPE = 0x01; - private const int USB_CONFIGURATION_DESCRIPTOR_TYPE = 0x02; - private const int USB_STRING_DESCRIPTOR_TYPE = 0x03; - - private const int ERROR_NO_MORE_ITEMS = 259; - - } -} diff --git a/FelLib/WinUSBNet/DeviceNotifyHook.cs b/FelLib/WinUSBNet/DeviceNotifyHook.cs deleted file mode 100644 index 99d6fb04..00000000 --- a/FelLib/WinUSBNet/DeviceNotifyHook.cs +++ /dev/null @@ -1,117 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace MadWizard.WinUSBNet -{ - internal class DeviceNotifyHook : NativeWindow, IDisposable - { - // http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.aspx - - // TODO: disposed exception when disposed - - private Control _parent; - private USBNotifier _notifier; - private Guid _guid; - private IntPtr _notifyHandle; - - public DeviceNotifyHook(USBNotifier notifier, Control parent, Guid guid) - { - _parent = parent; - _guid = guid; - _parent.HandleCreated += new EventHandler(this.OnHandleCreated); - _parent.HandleDestroyed += new EventHandler(this.OnHandleDestroyed); - _notifier = notifier; - } - - ~DeviceNotifyHook() - { - Dispose(false); - } - - // Listen for the control's window creation and then hook into it. - internal void OnHandleCreated(object sender, EventArgs e) - { - try - { - // Window is now created, assign handle to NativeWindow. - IntPtr handle = ((Control)sender).Handle; - AssignHandle(handle); - - if (_notifyHandle != IntPtr.Zero) - { - API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle); - _notifyHandle = IntPtr.Zero; - } - API.DeviceManagement.RegisterForDeviceNotifications(handle, _guid, ref _notifyHandle); - } - catch (API.APIException ex) - { - throw new USBException("Failed to register new window handle for device notification.", ex); - } - } - - internal void OnHandleDestroyed(object sender, EventArgs e) - { - try - { - // Window was destroyed, release hook. - ReleaseHandle(); - if (_notifyHandle != IntPtr.Zero) - { - API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle); - _notifyHandle = IntPtr.Zero; - } - } - catch (API.APIException ex) - { - throw new USBException("Failed to unregister destroyed window handle for device notification.", ex); - } - } - - - protected override void WndProc(ref Message m) - { - // Listen for operating system messages - - switch (m.Msg) - { - case API.DeviceManagement.WM_DEVICECHANGE: - _notifier.HandleDeviceChange(m); - break; - } - base.WndProc(ref m); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - // clean managed resources - - // do not clean the notifier here. the notifier owns and will dispose this object. - } - if (_notifyHandle != IntPtr.Zero) - { - API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle); - _notifyHandle = IntPtr.Zero; - } - } - - } -} diff --git a/FelLib/WinUSBNet/USB.cs b/FelLib/WinUSBNet/USB.cs deleted file mode 100644 index 0875faf2..00000000 --- a/FelLib/WinUSBNet/USB.cs +++ /dev/null @@ -1,80 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; - - -namespace MadWizard.WinUSBNet -{ - /// - /// USB base class code enumeration, as defined in the USB specification - /// - public enum USBBaseClass - { - /// Unknown non-zero class code. Used when the actual class code - /// does not match any of the ones defined in this enumeration. - Unknown = -1, - - /// Base class defined elsewhere (0x00) - None = 0x00, - - /// Audio base class (0x01) - Audio = 0x01, - - /// Communications and CDC control base class (0x02) - CommCDC = 0x02, - - /// HID base class (0x03) - HID = 0x03, - - /// Physical base class (0x05) - Physical = 0x05, - - /// Image base class (0x06) - Image = 0x06, - - /// Printer base class (0x07) - Printer = 0x07, - - /// Mass storage base class (0x08) - MassStorage = 0x08, - - /// Hub base class (0x09) - Hub = 0x09, - - /// CDC data base class (0x0A) - CDCData = 0x0A, - - /// Smart card base class (0x0B) - SmartCard = 0x0B, - - /// Content security base class (0x0D) - ContentSecurity = 0x0D, - - /// Video base class (0x0E) - Video = 0x0E, - - /// Personal healthcare base class (0x0F) - PersonalHealthcare = 0x0F, - - /// Diagnosticdevice base class (0xDC) - DiagnosticDevice = 0xDC, - - /// Wireless controller base class (0xE0) - WirelessController = 0xE0, - - /// Miscellaneous base class (0xEF) - Miscellaneous = 0xEF, - - /// Application specific base class (0xFE) - ApplicationSpecific = 0xFE, - - /// Vendor specific base class (0xFF) - VendorSpecific = 0xFF, - }; - -} \ No newline at end of file diff --git a/FelLib/WinUSBNet/USBAsyncResult.cs b/FelLib/WinUSBNet/USBAsyncResult.cs deleted file mode 100644 index 6cb5dcef..00000000 --- a/FelLib/WinUSBNet/USBAsyncResult.cs +++ /dev/null @@ -1,136 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -namespace MadWizard.WinUSBNet -{ - internal class USBAsyncResult : IAsyncResult, IDisposable - { - private object _stateObject; - private AsyncCallback _userCallback; - private bool _completed; - private bool _completedSynchronously; - private ManualResetEvent _waitEvent; - private int _bytesTransfered; - private Exception _error; - - public USBAsyncResult(AsyncCallback userCallback, object stateObject) - { - _stateObject = stateObject; - _userCallback = userCallback; - _completedSynchronously = false; - _completed = false; - _waitEvent = null; - } - - public object AsyncState - { - get - { - return _stateObject; - } - } - - public Exception Error - { - get - { - lock (this) - { - return _error; - } - } - } - public int BytesTransfered - { - get { return _bytesTransfered; } - } - public WaitHandle AsyncWaitHandle - { - get - { - lock (this) - { - if (_waitEvent == null) - _waitEvent = new ManualResetEvent(_completed); - } - return _waitEvent; - } - } - - public bool CompletedSynchronously - { - get - { - lock (this) - { - return _completedSynchronously; - } - } - } - - public bool IsCompleted - { - get - { - lock (this) - { - return _completed; - } - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public void OnCompletion(bool completedSynchronously, Exception error, int bytesTransfered, bool synchronousCallback) - { - lock (this) - { - _completedSynchronously = completedSynchronously; - _completed = true; - _error = error; - _bytesTransfered = bytesTransfered; - if (_waitEvent != null) - _waitEvent.Set(); - } - if (_userCallback != null) - { - if (synchronousCallback) - RunCallback(null); - else - ThreadPool.QueueUserWorkItem(RunCallback); - } - - } - private void RunCallback(object state) - { - _userCallback(this); - } - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - // Cleanup managed resources - lock (this) - { - if (_waitEvent != null) - _waitEvent.Close(); - } - } - } - - - } -} diff --git a/FelLib/WinUSBNet/USBDevice.cs b/FelLib/WinUSBNet/USBDevice.cs deleted file mode 100644 index d4ef5668..00000000 --- a/FelLib/WinUSBNet/USBDevice.cs +++ /dev/null @@ -1,756 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - /// - /// The UsbDevice class represents a single WinUSB device. - /// - public class USBDevice : IDisposable - { - private API.WinUSBDevice _wuDevice = null; - private bool _disposed = false; - - /// - /// Collection of all pipes available on the USB device - /// - public USBPipeCollection Pipes - { - get; - private set; - } - - - - - /// - /// Collection of all interfaces available on the USB device - /// - public USBInterfaceCollection Interfaces - { - get; - private set; - } - - /// - /// Device descriptor with information about the device - /// - public USBDeviceDescriptor Descriptor - { - get; - private set; - } - - /// - /// Constructs a new USB device - /// - /// USB device info of the device to create - public USBDevice(USBDeviceInfo deviceInfo) - : this(deviceInfo.DevicePath) - { - // Handled in other constructor - } - - /// - /// Disposes the UsbDevice including all unmanaged WinUSB handles. This function - /// should be called when the UsbDevice object is no longer in use, otherwise - /// unmanaged handles will remain open until the garbage collector finalizes the - /// object. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Finalizer for the UsbDevice. Disposes all unmanaged handles. - /// - ~USBDevice() - { - Dispose(false); - } - - /// - /// Disposes the object - /// - /// Indicates wether Dispose was called manually (true) or by - /// the garbage collector (false) via the destructor. - protected virtual void Dispose(bool disposing) - { - if (_disposed) - return; - - if (disposing) - { - if (_wuDevice != null) - _wuDevice.Dispose(); - } - - // Clean unmanaged resources here. - // (none currently) - - _disposed = true; - } - - /// - /// Constructs a new USB device - /// - /// Device path name of the USB device to create - public USBDevice(string devicePathName) - { - try - { - Descriptor = GetDeviceDescriptor(devicePathName); - } - catch - { - Descriptor = null; - } - _wuDevice = new API.WinUSBDevice(); - try - { - _wuDevice.OpenDevice(devicePathName); - InitializeInterfaces(); - } - catch (API.APIException e) - { - _wuDevice.Dispose(); - throw new USBException("Failed to open device.", e); - } - } - - internal API.WinUSBDevice InternalDevice - { - get - { - return _wuDevice; - } - } - - private void InitializeInterfaces() - { - int numInterfaces = _wuDevice.InterfaceCount; - - List allPipes = new List(); - - USBInterface[] interfaces = new USBInterface[numInterfaces]; - // UsbEndpoint - for (int i = 0; i < numInterfaces; i++) - { - API.USB_INTERFACE_DESCRIPTOR descriptor; - API.WINUSB_PIPE_INFORMATION[] pipesInfo; - _wuDevice.GetInterfaceInfo(i, out descriptor, out pipesInfo); - USBPipe[] interfacePipes = new USBPipe[pipesInfo.Length]; - for (int k = 0; k < pipesInfo.Length; k++) - { - USBPipe pipe = new USBPipe(this, pipesInfo[k]); - interfacePipes[k] = pipe; - allPipes.Add(pipe); - } - // TODO: - //if (descriptor.iInterface != 0) - // _wuDevice.GetStringDescriptor(descriptor.iInterface); - USBPipeCollection pipeCollection = new USBPipeCollection(interfacePipes); - interfaces[i] = new USBInterface(this, i, descriptor, pipeCollection); - } - Pipes = new USBPipeCollection(allPipes.ToArray()); - Interfaces = new USBInterfaceCollection(interfaces); - } - - private void CheckControlParams(int value, int index, byte[] buffer, int length) - { - if (value < ushort.MinValue || value > ushort.MaxValue) - throw new ArgumentOutOfRangeException("Value parameter out of range."); - if (index < ushort.MinValue || index > ushort.MaxValue) - throw new ArgumentOutOfRangeException("Index parameter out of range."); - if (length > buffer.Length) - throw new ArgumentOutOfRangeException("Length parameter is larger than the size of the buffer."); - if (length > ushort.MaxValue) - throw new ArgumentOutOfRangeException("Length too large"); - } - - /// - /// Specifies the timeout in milliseconds for control pipe operations. If a control transfer does not finish within the specified time it will fail. - /// When set to zero, no timeout is used. Default value is 5000 milliseconds. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public int ControlPipeTimeout - { - get - { - return (int)_wuDevice.GetPipePolicyUInt(0, 0x00, API.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT); - } - set - { - if (value < 0) - throw new ArgumentOutOfRangeException("Control pipe timeout cannot be negative."); - _wuDevice.SetPipePolicy(0, 0x00, API.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, (uint)value); - } - } - - - /// - /// Initiates a control transfer over the default control endpoint. This method allows both IN and OUT direction transfers, depending - /// on the highest bit of the parameter. Alternatively, and - /// can be used for control transfers in a specific direction, which is the recommended way because - /// it prevents using the wrong direction accidentally. Use the ControlTransfer method when the direction is not known at compile time. - /// - /// The setup packet request type. - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be - /// written to this buffer. For an OUT direction transfer the contents of the buffer are written sent through the pipe. - /// Length of the data to transfer. Must be equal to or less than the length of . - /// The setup packet's length member will be set to this length. - public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, int length) - { - // Parameters are int and not ushort because ushort is not CLS compliant. - CheckNotDisposed(); - CheckControlParams(value, index, buffer, length); - - try - { - _wuDevice.ControlTransfer(requestType, request, (ushort)value, (ushort)index, (ushort)length, buffer); - } - catch (API.APIException e) - { - throw new USBException("Control transfer failed", e); - } - } - - /// - /// Initiates an asynchronous control transfer over the default control endpoint. This method allows both IN and OUT direction transfers, depending - /// on the highest bit of the parameter. Alternatively, and - /// can be used for asynchronous control transfers in a specific direction, which is - /// the recommended way because it prevents using the wrong direction accidentally. Use the BeginControlTransfer method when the direction is not - /// known at compile time. - /// The setup packet request type. - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be - /// written to this buffer. For an OUT direction transfer the contents of the buffer are written sent through the pipe. Note: This buffer is not allowed - /// to change for the duration of the asynchronous operation. - /// Length of the data to transfer. Must be equal to or less than the length of . The setup packet's length member will be set to this length. - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, int length, AsyncCallback userCallback, object stateObject) - { - // Parameters are int and not ushort because ushort is not CLS compliant. - CheckNotDisposed(); - CheckControlParams(value, index, buffer, length); - - USBAsyncResult result = new USBAsyncResult(userCallback, stateObject); - - try - { - _wuDevice.ControlTransferOverlapped(requestType, request, (ushort)value, (ushort)index, (ushort)length, buffer, result); - } - catch (API.APIException e) - { - if (result != null) - result.Dispose(); - throw new USBException("Asynchronous control transfer failed", e); - } - catch (Exception) - { - if (result != null) - result.Dispose(); - throw; - } - return result; - } - - /// - /// Initiates an asynchronous control transfer over the default control endpoint. This method allows both IN and OUT direction transfers, depending - /// on the highest bit of the parameter. Alternatively, and - /// can be used for asynchronous control transfers in a specific direction, which is - /// the recommended way because it prevents using the wrong direction accidentally. Use the BeginControlTransfer method when the direction is not - /// known at compile time. - /// The setup packet request type. - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be - /// written to this buffer. For an OUT direction transfer the contents of the buffer are written sent through the pipe. The setup packet's length member will - /// be set to the length of this buffer. Note: This buffer is not allowed to change for the duration of the asynchronous operation. - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject) - { - return BeginControlTransfer(requestType, request, value, index, buffer, buffer.Length, userCallback, stateObject); - } - - - /// - /// Waits for a pending asynchronous control transfer to complete. - /// - /// The object representing the asynchonous operation, - /// as returned by one of the ControlIn, ControlOut or ControlTransfer methods. - /// The number of bytes transfered during the operation. - /// Every asynchronous control transfer must have a matching call to to dispose - /// of any resources used and to retrieve the result of the operation. When the operation was successful the method returns the number - /// of bytes that were transfered. If an error occurred during the operation this method will throw the exceptions that would - /// otherwise have ocurred during the operation. If the operation is not yet finished EndControlTransfer will wait for the - /// operation to finish before returning. - public int EndControlTransfer(IAsyncResult asyncResult) - { - if (asyncResult == null) - throw new NullReferenceException("asyncResult cannot be null"); - if (!(asyncResult is USBAsyncResult)) - throw new ArgumentException("AsyncResult object was not created by calling one of the BeginControl* methods on this class."); - - // todo: check duplicate end control - USBAsyncResult result = (USBAsyncResult)asyncResult; - try - { - if (!result.IsCompleted) - result.AsyncWaitHandle.WaitOne(); - - if (result.Error != null) - throw new USBException("Asynchronous control transfer from pipe has failed.", result.Error); - - return result.BytesTransfered; - } - finally - { - result.Dispose(); - } - - } - - - /// - /// Initiates a control transfer over the default control endpoint. This method allows both IN and OUT direction transfers, depending - /// on the highest bit of the parameter). Alternatively, and - /// can be used for control transfers in a specific direction, which is the recommended way because - /// it prevents using the wrong direction accidentally. Use the ControlTransfer method when the direction is not known at compile time. - /// - /// The setup packet request type. - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The data to transfer in the data stage of the control. When the transfer is in the IN direction the data received will be - /// written to this buffer. For an OUT direction transfer the contents of the buffer are written sent through the pipe. The length of this - /// buffer is used as the number of bytes in the control transfer. The setup packet's length member will be set to this length as well. - public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer) - { - ControlTransfer(requestType, request, value, index, buffer, buffer.Length); - } - - /// - /// Initiates a control transfer without a data stage over the default control endpoint. This method allows both IN and OUT direction transfers, depending - /// on the highest bit of the parameter). Alternatively, and - /// can be used for control transfers in a specific direction, which is the recommended way because - /// it prevents using the wrong direction accidentally. Use the ControlTransfer method when the direction is not known at compile time. - /// - /// The setup packet request type. - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - public void ControlTransfer(byte requestType, byte request, int value, int index) - { - // TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin) - ControlTransfer(requestType, request, value, index, new byte[0], 0); - } - - private void CheckIn(byte requestType) - { - if ((requestType & 0x80) == 0) // Host to device? - throw new ArgumentException("Request type is not IN."); - } - - private void CheckOut(byte requestType) - { - if ((requestType & 0x80) == 0x80) // Device to host? - throw new ArgumentException("Request type is not OUT."); - } - - /// - /// Initiates a control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the parameter). A buffer to receive the data is automatically created by this method. - /// - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// Length of the data to transfer. A buffer will be created with this length and the length member of the setup packet - /// will be set to this length. - /// A buffer containing the data transfered. - public byte[] ControlIn(byte requestType, byte request, int value, int index, int length) - { - CheckIn(requestType); - byte[] buffer = new byte[length]; - ControlTransfer(requestType, request, value, index, buffer, buffer.Length); - return buffer; - } - - - /// - /// Initiates a control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the parameter). - /// - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The buffer that will receive the data transfered. - /// Length of the data to transfer. The length member of the setup packet will be set to this length. The buffer specified - /// by the parameter should have at least this length. - public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length) - { - CheckIn(requestType); - ControlTransfer(requestType, request, value, index, buffer, length); - } - - /// - /// Initiates a control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the parameter). The length of buffer given by the parameter will dictate - /// the number of bytes that are transfered and the value of the setup packet's length member. - /// - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The buffer that will receive the data transfered. The length of this buffer will be the number of bytes transfered. - public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer) - { - CheckIn(requestType); - ControlTransfer(requestType, request, value, index, buffer); - } - - /// - /// Initiates a control transfer without a data stage over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the parameter). The setup packets' length member will be set to zero. - /// - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - public void ControlIn(byte requestType, byte request, int value, int index) - { - CheckIn(requestType); - // TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin) - ControlTransfer(requestType, request, value, index, new byte[0]); - } - - /// - /// Initiates a control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the parameter). - /// - /// The setup packet request type. The request type must specify the OUT direction (highest bit cleared). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// A buffer containing the data to transfer in the data stage. - /// Length of the data to transfer. Only the first bytes of will be transfered. - /// The setup packet's length parameter is set to this length. - public void ControlOut(byte requestType, byte request, int value, int index, byte[] buffer, int length) - { - CheckOut(requestType); - ControlTransfer(requestType, request, value, index, buffer, length); - } - - /// - /// Initiates a control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the parameter). - /// - /// The setup packet request type. The request type must specify the OUT direction (highest bit cleared). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// A buffer containing the data to transfer in the data stage. The complete buffer is transfered. The setup packet's length - /// parameter is set to the length of this buffer. - public void ControlOut(byte requestType, byte request, int value, int index, byte[] buffer) - { - CheckOut(requestType); - ControlTransfer(requestType, request, value, index, buffer); - } - - /// - /// Initiates a control transfer without a data stage over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the parameter. The setup packets' length member will be set to zero. - /// - /// The setup packet request type. The request type must specify the OUT direction (highest bit cleared). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - public void ControlOut(byte requestType, byte request, int value, int index) - { - CheckOut(requestType); - // TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin) - ControlTransfer(requestType, request, value, index, new byte[0]); - } - - - - /// - /// Initiates an asynchronous control transfer without a data stage over the default control endpoint. This method allows both IN and OUT direction transfers, depending - /// on the highest bit of the parameter. Alternatively, and - /// can be used for asynchronous control transfers in a specific direction, which is - /// the recommended way because it prevents using the wrong direction accidentally. Use the BeginControlTransfer method when the direction is not - /// known at compile time. - /// The setup packet request type. - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject) - { - // TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin) - return BeginControlTransfer(requestType, request, value, index, new byte[0], 0, userCallback, stateObject); - } - - - - /// - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the parameter). - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The buffer that will receive the data transfered. - /// Length of the data to transfer. Must be equal to or less than the length of . The setup packet's length member will be set to this length. - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length, AsyncCallback userCallback, object stateObject) - { - CheckIn(requestType); - return BeginControlTransfer(requestType, request, value, index, buffer, length, userCallback, stateObject); - } - - /// - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the parameter). - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The buffer that will receive the data transfered. The setup packet's length member will be set to the length of this buffer. - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlIn(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject) - { - CheckIn(requestType); - return BeginControlTransfer(requestType, request, value, index, buffer, userCallback, stateObject); - } - - /// - /// Initiates an asynchronous control transfer without a data stage over the default control endpoint. - /// The request should have an IN direction (specified by the highest bit of the parameter). - /// The setup packets' length member will be set to zero. - /// The setup packet request type. The request type must specify the IN direction (highest bit set). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlIn(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject) - { - CheckIn(requestType); - return BeginControlTransfer(requestType, request, value, index, userCallback, stateObject); - } - - /// - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the parameter). - /// The setup packet request type. The request type must specify the OUT direction (highest bit cleared). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The buffer that contains the data to be transfered. - /// Length of the data to transfer. Must be equal to or less than the length of . The setup packet's length member will be set to this length. - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlOut(byte requestType, byte request, int value, int index, byte[] buffer, int length, AsyncCallback userCallback, object stateObject) - { - CheckOut(requestType); - return BeginControlTransfer(requestType, request, value, index, buffer, length, userCallback, stateObject); - } - - /// - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the parameter). - /// The setup packet request type. The request type must specify the OUT direction (highest bit cleared). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// The buffer that contains the data to be transfered. The setup packet's length member will be set to the length of this buffer. - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlOut(byte requestType, byte request, int value, int index, byte[] buffer, AsyncCallback userCallback, object stateObject) - { - CheckOut(requestType); - return BeginControlTransfer(requestType, request, value, index, buffer, userCallback, stateObject); - } - - /// - /// Initiates an asynchronous control transfer without a data stage over the default control endpoint. - /// The request should have an OUT direction (specified by the highest bit of the parameter). - /// The setup packets' length member will be set to zero. - /// The setup packet request type. The request type must specify the OUT direction (highest bit cleared). - /// The setup packet device request. - /// The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF). - /// The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF). - /// An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous control transfer, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginControlOut(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject) - { - CheckOut(requestType); - // TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin) - return BeginControlTransfer(requestType, request, value, index, new byte[0], userCallback, stateObject); - } - - - private void CheckNotDisposed() - { - if (_disposed) - throw new ObjectDisposedException("USB device object has been disposed."); - } - - /// - /// Finds USB devices - /// - public static USBDeviceInfo[] GetDevices(UInt16 vid, UInt16 pid) - { - API.DeviceDetails[] detailList = API.DeviceManagement.FindDevices(vid, pid); - - USBDeviceInfo[] devices = new USBDeviceInfo[detailList.Length]; - - for (int i = 0; i < detailList.Length; i++) - { - devices[i] = new USBDeviceInfo(detailList[i]); - } - return devices; - } - - /// - /// Finds the first WinUSB device with a VIA and PID - /// - public static USBDevice GetSingleDevice(UInt16 vid, UInt16 pid) - { - API.DeviceDetails[] detailList = API.DeviceManagement.FindDevices(vid, pid); - if (detailList.Length == 0) - return null; - - - return new USBDevice(detailList[0].DevicePath); - } - - - private static USBDeviceDescriptor GetDeviceDescriptor(string devicePath) - { - try - { - USBDeviceDescriptor descriptor; - using (API.WinUSBDevice wuDevice = new API.WinUSBDevice()) - { - wuDevice.OpenDevice(devicePath); - API.USB_DEVICE_DESCRIPTOR deviceDesc = wuDevice.GetDeviceDescriptor(); - - // Get first supported language ID - ushort[] langIDs = wuDevice.GetSupportedLanguageIDs(); - ushort langID = 0; - if (langIDs.Length > 0) - langID = langIDs[0]; - - string manufacturer = null, product = null, serialNumber = null; - byte idx = 0; - idx = deviceDesc.iManufacturer; - if (idx > 0) - manufacturer = wuDevice.GetStringDescriptor(idx, langID); - - idx = deviceDesc.iProduct; - if (idx > 0) - product = wuDevice.GetStringDescriptor(idx, langID); - - idx = deviceDesc.iSerialNumber; - if (idx > 0) - serialNumber = wuDevice.GetStringDescriptor(idx, langID); - descriptor = new USBDeviceDescriptor(devicePath, deviceDesc, manufacturer, product, serialNumber); - } - return descriptor; - } - catch (API.APIException e) - { - throw new USBException("Failed to retrieve device descriptor.", e); - } - } - - } -} diff --git a/FelLib/WinUSBNet/USBDeviceDescriptor.cs b/FelLib/WinUSBNet/USBDeviceDescriptor.cs deleted file mode 100644 index 329e6fc4..00000000 --- a/FelLib/WinUSBNet/USBDeviceDescriptor.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - /// - /// USB device details - /// - public class USBDeviceDescriptor - { - /// - /// Windows path name for the USB device - /// - public string PathName { get; private set; } - - /// - /// USB vendor ID (VID) of the device - /// - public int VID { get; private set; } - - /// - /// USB product ID (PID) of the device - /// - public int PID { get; private set; } - - /// - /// Manufacturer name, or null if not available - /// - public string Manufacturer { get; private set; } - - /// - /// Product name, or null if not available - /// - public string Product { get; private set; } - - /// - /// Device serial number, or null if not available - /// - public string SerialNumber { get; private set; } - - - /// - /// Friendly device name, or path name when no - /// further device information is available - /// - public string FullName - { - get - { - if (Manufacturer != null && Product != null) - return Product + " - " + Manufacturer; - else if (Product != null) - return Product; - else if (SerialNumber != null) - return SerialNumber; - else - return PathName; - } - } - - /// - /// Device class code as defined in the interface descriptor - /// This property can be used if the class type is not defined - /// int the USBBaseClass enumeraiton - /// - public byte ClassValue - { - get; - private set; - } - - /// - /// Device subclass code - /// - public byte SubClass - { - get; - private set; - } - - /// - /// Device protocol code - /// - public byte Protocol - { - get; - private set; - } - - /// - /// Device class code. If the device class does - /// not match any of the USBBaseClass enumeration values - /// the value will be USBBaseClass.Unknown - /// - public USBBaseClass BaseClass - { - get; - private set; - } - - internal USBDeviceDescriptor(string path, API.USB_DEVICE_DESCRIPTOR deviceDesc, string manufacturer, string product, string serialNumber) - { - PathName = path; - VID = deviceDesc.idVendor; - PID = deviceDesc.idProduct; - Manufacturer = manufacturer; - Product = product; - SerialNumber = serialNumber; - - - ClassValue = deviceDesc.bDeviceClass; - SubClass = deviceDesc.bDeviceSubClass; - Protocol = deviceDesc.bDeviceProtocol; - - // If interface class is of a known type (USBBaseeClass enum), use this - // for the InterfaceClass property. - BaseClass = USBBaseClass.Unknown; - if (Enum.IsDefined(typeof(USBBaseClass), (int)deviceDesc.bDeviceClass)) - { - BaseClass = (USBBaseClass)(int)deviceDesc.bDeviceClass; - } - - - - } - } -} diff --git a/FelLib/WinUSBNet/USBDeviceInfo.cs b/FelLib/WinUSBNet/USBDeviceInfo.cs deleted file mode 100644 index 4e10455c..00000000 --- a/FelLib/WinUSBNet/USBDeviceInfo.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - /// - /// Gives information about a device. This information is retrieved using the setup API, not the - /// actual device descriptor. Device description and manufacturer will be the strings specified - /// in the .inf file. After a device is opened the actual device descriptor can be read as well. - /// - public class USBDeviceInfo - { - private API.DeviceDetails _details; - - /// - /// Vendor ID (VID) of the USB device - /// - public int VID - { - get - { - return _details.VID; - } - } - - /// - /// Product ID (VID) of the USB device - /// - public int PID - { - get - { - return _details.PID; - } - } - - /// - /// Manufacturer of the device, as specified in the INF file (not the device descriptor) - /// - public string Manufacturer - { - get - { - return _details.Manufacturer; - } - } - - /// - /// Description of the device, as specified in the INF file (not the device descriptor) - /// - public string DeviceDescription - { - get - { - return _details.DeviceDescription; - } - } - - /// - /// Device pathname - /// - public string DevicePath - { - get - { - return _details.DevicePath; - } - } - - internal USBDeviceInfo(API.DeviceDetails details) - { - _details = details; - } - - } -} diff --git a/FelLib/WinUSBNet/USBException.cs b/FelLib/WinUSBNet/USBException.cs deleted file mode 100644 index d61d45e9..00000000 --- a/FelLib/WinUSBNet/USBException.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - /// - /// Exception used by WinUSBNet to indicate errors. This is the - /// main exception to catch when using the library. - /// - public class USBException : Exception - { - /// - /// Constructs a new USBException with the given message - /// - /// The message describing the exception - public USBException(string message) - : base(message) - { - } - - /// - /// Constructs a new USBException with the given message and underlying exception - /// that caused the USBException. - /// - /// The message describing the exception - /// The underlying exception causing the USBException - public USBException(string message, Exception innerException) - : base(message, innerException) - { - } - } -} diff --git a/FelLib/WinUSBNet/USBInterface.cs b/FelLib/WinUSBNet/USBInterface.cs deleted file mode 100644 index 1b13a446..00000000 --- a/FelLib/WinUSBNet/USBInterface.cs +++ /dev/null @@ -1,152 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - /// - /// Represents a single USB interface from a USB device - /// - public class USBInterface - { - /// - /// Collection of pipes associated with this interface - /// - public USBPipeCollection Pipes - { - get; - private set; - } - - /// - /// Interface number from the interface descriptor - /// - public int Number - { - get; - private set; - } - - /// - /// USB device associated with this interface - /// - public USBDevice Device - { - get; - private set; - } - - /// - /// First IN direction pipe on this interface - /// - public USBPipe InPipe - { - get; - private set; - } - - /// - /// First OUT direction pipe on this interface - /// - public USBPipe OutPipe - { - get; - private set; - } - - /// - /// Interface class code. If the interface class does - /// not match any of the USBBaseClass enumeration values - /// the value will be USBBaseClass.Unknown - /// - public USBBaseClass BaseClass - { - get; - private set; - } - - /// - /// Interface class code as defined in the interface descriptor - /// This property can be used if the class type is not defined - /// int the USBBaseClass enumeraiton - /// - public byte ClassValue - { - get; - private set; - } - - /// - /// Interface subclass code - /// - public byte SubClass - { - get; - private set; - } - - /// - /// Interface protocol code - /// - public byte Protocol - { - get; - private set; - } - - /// Zero based interface index in WinUSB. - /// Note that this is not necessarily the same as the interface *number* - /// from the interface descriptor. There might be interfaces within the - /// USB device that do not use WinUSB, these are not counted for index. - internal int InterfaceIndex - { - get; - private set; - } - - internal USBInterface(USBDevice device, int interfaceIndex, API.USB_INTERFACE_DESCRIPTOR rawDesc, USBPipeCollection pipes) - { - // Set raw class identifiers - ClassValue = rawDesc.bInterfaceClass; - SubClass = rawDesc.bInterfaceSubClass; - Protocol = rawDesc.bInterfaceProtocol; - - Number = rawDesc.bInterfaceNumber; - InterfaceIndex = interfaceIndex; - - // If interface class is of a known type (USBBaseClass enum), use this - // for the InterfaceClass property. - BaseClass = USBBaseClass.Unknown; - if (Enum.IsDefined(typeof(USBBaseClass), (int)rawDesc.bInterfaceClass)) - { - BaseClass = (USBBaseClass)(int)rawDesc.bInterfaceClass; - } - - - Device = device; - Pipes = pipes; - - // Handle pipes - foreach (USBPipe pipe in pipes) - { - // Attach pipe to this interface - pipe.AttachInterface(this); - - // If first in or out pipe, set InPipe and OutPipe - if (pipe.IsIn && InPipe == null) - InPipe = pipe; - if (pipe.IsOut && OutPipe == null) - OutPipe = pipe; - - } - - } - } -} diff --git a/FelLib/WinUSBNet/USBInterfaceCollection.cs b/FelLib/WinUSBNet/USBInterfaceCollection.cs deleted file mode 100644 index 4f4a8ee6..00000000 --- a/FelLib/WinUSBNet/USBInterfaceCollection.cs +++ /dev/null @@ -1,160 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Text; -using System.Collections; -using System.Collections.Generic; - -namespace MadWizard.WinUSBNet -{ - /// - /// Collection of UsbInterface objects - /// - public class USBInterfaceCollection : IEnumerable - { - private USBInterface[] _interfaces; - - internal USBInterfaceCollection(USBInterface[] interfaces) - { - _interfaces = interfaces; - } - - private class USBInterfaceEnumerator : IEnumerator - { - private int _index; - private USBInterface[] _interfaces; - - public USBInterfaceEnumerator(USBInterface[] interfaces) - { - _interfaces = interfaces; - _index = -1; - } - - public void Dispose() - { - // Intentionally empty - } - private USBInterface GetCurrent() - { - try - { - return _interfaces[_index]; - } - - catch (IndexOutOfRangeException) - { - throw new InvalidOperationException(); - } - } - - public USBInterface Current - { - get - { - return GetCurrent(); - } - } - - - object IEnumerator.Current - { - get - { - return GetCurrent(); - } - } - - public bool MoveNext() - { - _index++; - return _index < _interfaces.Length; - } - - public void Reset() - { - _index = -1; - } - } - - /// - /// Finds the first interface with that matches the device class - /// given by the parameter. - /// - /// The device class the interface should match - /// The first interface with the given interface class, or null - /// if no such interface exists. - public USBInterface Find(USBBaseClass interfaceClass) - { - for (int i = 0; i < _interfaces.Length; i++) - { - USBInterface iface = _interfaces[i]; - if (iface.BaseClass == interfaceClass) - return iface; - } - return null; - } - - /// - /// Finds all interfaces matching the device class given by the - /// parameter. - /// - /// The device class the interface should match - /// An array of USBInterface objects matching the device class, or an empty - /// array if no interface matches. - public USBInterface[] FindAll(USBBaseClass interfaceClass) - { - List matchingInterfaces = new List(); - for (int i = 0; i < _interfaces.Length; i++) - { - USBInterface iface = _interfaces[i]; - if (iface.BaseClass == interfaceClass) - matchingInterfaces.Add(iface); - } - return matchingInterfaces.ToArray(); - } - - /// - /// Returns a typed enumerator that iterates through a collection. - /// - /// The enumerator object that can be used to iterate through the collection. - public IEnumerator GetEnumerator() - { - return new USBInterfaceEnumerator(_interfaces); - } - - /// - /// Get interface by interface number - /// - /// Number of the interface to return. Note: this is the number from the interface descriptor, which - /// is not necessarily the same as the interface index. - /// Thrown when the given interface number does not exist in the collection. - /// - public USBInterface this[ int interfaceNumber ] - { - get - { - for (int i = 0; i < _interfaces.Length; i++) - { - USBInterface iface = _interfaces[i]; - if (iface.Number == interfaceNumber) - return iface; - } - throw new IndexOutOfRangeException(string.Format("No interface with number {0} exists.", interfaceNumber)); - } - } - - /// - /// Returns an enumerator that iterates through a collection. - /// - /// An IEnumerator object that can be used to iterate through the collection. - IEnumerator IEnumerable.GetEnumerator() - { - return new USBInterfaceEnumerator(_interfaces); - } - } -} diff --git a/FelLib/WinUSBNet/USBNotifier.cs b/FelLib/WinUSBNet/USBNotifier.cs deleted file mode 100644 index b97c01d9..00000000 --- a/FelLib/WinUSBNet/USBNotifier.cs +++ /dev/null @@ -1,190 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace MadWizard.WinUSBNet -{ - /// - /// Delegate for event handler methods handing USB events - /// - /// The source of the event - /// Details of the event - public delegate void USBEventHandler(object sender, USBEvent e); - - /// - /// Event type enumeration for WinUSB events - /// - public enum USBEventType - { - /// - /// A device has been connected to the system - /// - DeviceArrival, - - /// - /// A device has been disconnected from the system - /// - DeviceRemoval, - } - - /// - /// Contains the details of a USB event - /// - public class USBEvent : EventArgs - { - /// - /// WinUSB interface GUID of the device as specified in the WinUSBNotifier - /// - public Guid Guid; - - /// - /// Device pathname that identifies the device - /// - public string DevicePath; - - /// - /// Type of event that occurred - /// - public USBEventType Type; - - internal USBEvent(USBEventType type, Guid guid, string devicePath) - { - this.Guid = guid; - this.DevicePath = devicePath; - this.Type= type; - } - } - - /// - /// Helper class to receive notifications on USB device changes such as - /// connecting or removing a device. - /// - public class USBNotifier : IDisposable - { - private DeviceNotifyHook _hook; - private Guid _guid; - - /// - /// Event triggered when a new USB device that matches the USBNotifier's GUID is connected - /// - public event USBEventHandler Arrival; - - /// - /// Event triggered when a new USB device that matches the USBNotifier's GUID is disconnected - /// - public event USBEventHandler Removal; - - /// - /// The interface GUID of devices this USBNotifier will watch - /// - public Guid Guid - { - get - { - return _guid; - } - } - - /// - /// Constructs a new USBNotifier that will watch for events on - /// devices matching the given interface GUID. A Windows Forms control - /// is needed since the notifier relies on window messages. - /// - /// A control that will be used internally for device notification messages. - /// You can use a Form object for example. - /// The interface GUID string of the devices to watch. - public USBNotifier(Control control, string guidString) : - this(control, new Guid(guidString)) - { - // Handled in other constructor - } - - - /// - /// Constructs a new USBNotifier that will watch for events on - /// devices matching the given interface GUID. A Windows Forms control - /// is needed since the notifier relies on window messages. - /// - /// A control that will be used internally for device notification messages. - /// You can use a Form object for example. - /// The interface GUID of the devices to watch. - public USBNotifier(Control control, Guid guid) - { - _guid = guid; - _hook = new DeviceNotifyHook(this, control, _guid); - } - - /// - /// Triggers the arrival event - /// - /// Device pathname of the device that has been connected - protected void OnArrival(string devicePath) - { - if (Arrival != null) - Arrival(this, new USBEvent(USBEventType.DeviceArrival, _guid, devicePath)); - } - /// - /// Trigggers the removal event - /// - /// Device pathname of the device that has been connected - protected void OnRemoval(string devicePath) - { - if (Removal != null) - Removal(this, new USBEvent(USBEventType.DeviceRemoval, _guid, devicePath)); - } - - internal void HandleDeviceChange(Message m) - { - if (m.Msg != API.DeviceManagement.WM_DEVICECHANGE) - throw new USBException("Invalid device change message."); // should not happen - - if ((int)m.WParam == API.DeviceManagement.DBT_DEVICEARRIVAL) - { - - string devName = API.DeviceManagement.GetNotifyMessageDeviceName(m, _guid); - if (devName != null) - OnArrival(devName); - } - - if ((int)m.WParam == API.DeviceManagement.DBT_DEVICEREMOVECOMPLETE) - { - string devName = API.DeviceManagement.GetNotifyMessageDeviceName(m, _guid); - if (devName != null) - OnRemoval(devName); - } - - } - - /// - /// Disposes the USBNotifier object and frees all resources. - /// Call this method when the object is no longer needed. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Disposes the object's resources. - /// - /// True when dispose is called manually, false when called by the finalizer. - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _hook.Dispose(); - } - } - - } -} diff --git a/FelLib/WinUSBNet/USBPipe.cs b/FelLib/WinUSBNet/USBPipe.cs deleted file mode 100644 index 9a565633..00000000 --- a/FelLib/WinUSBNet/USBPipe.cs +++ /dev/null @@ -1,387 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - /// - /// UsbPipe represents a single pipe on a WinUSB device. A pipe is connected - /// to a certain endpoint on the device and has a fixed direction (IN or OUT) - /// - public class USBPipe - { - private API.WINUSB_PIPE_INFORMATION _pipeInfo; - private USBInterface _interface = null; - private USBDevice _device; - private USBPipePolicy _policy; - - /// - /// Endpoint address including the direction in the most significant bit - /// - public byte Address - { - get - { - return _pipeInfo.PipeId; - } - } - - /// - /// The USBDevice this pipe is associated with - /// - public USBDevice Device - { - get - { - return _device; - } - } - - /// - /// Maximum packet size for transfers on this endpoint - /// - public int MaximumPacketSize - { - get - { - return _pipeInfo.MaximumPacketSize; - } - } - - /// - /// The interface associated with this pipe - /// - public USBInterface Interface - { - get - { - return _interface; - } - } - - /// - /// The pipe policy settings for this pipe - /// - public USBPipePolicy Policy - { - get - { - return _policy; - } - } - - /// - /// True if the pipe has direction OUT (host to device), false otherwise. - /// - public bool IsOut - { - get - { - return (_pipeInfo.PipeId & 0x80) == 0; - } - } - - /// - /// True if the pipe has direction IN (device to host), false otherwise. - /// - public bool IsIn - { - get - { - return (_pipeInfo.PipeId & 0x80) != 0; - } - } - - /// - /// Reads data from the pipe into a buffer. - /// - /// The buffer to read data into. The maximum number of bytes that will be read is specified by the length of the buffer. - /// The number of bytes read from the pipe. - public int Read(byte[] buffer) - { - return Read(buffer, 0, buffer.Length); - } - - /// - /// Reads data from the pipe into a buffer. - /// - /// The buffer to read data into. - /// The byte offset in from which to begin writing data read from the pipe. - /// The maximum number of bytes to read, starting at offset - /// The number of bytes read from the pipe. - public int Read(byte[] buffer, int offset, int length) - { - CheckReadParams(buffer, offset, length); - - try - { - uint bytesRead; - - _device.InternalDevice.ReadPipe(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, out bytesRead); - - return (int)bytesRead; - } - catch (API.APIException e) - { - throw new USBException("Failed to read from pipe.", e); - } - } - - private void CheckReadParams(byte[] buffer, int offset, int length) - { - if (!IsIn) - throw new NotSupportedException("Cannot read from a pipe with OUT direction."); - - int bufferLength = buffer.Length; - if (offset < 0 || offset >= bufferLength) - throw new ArgumentOutOfRangeException("Offset of data to read is outside the buffer boundaries."); - if (length < 0 || (offset + length) > bufferLength) - throw new ArgumentOutOfRangeException("Length of data to read is outside the buffer boundaries."); - } - private void CheckWriteParams(byte[] buffer, int offset, int length) - { - if (!IsOut) - throw new NotSupportedException("Cannot write to a pipe with IN direction."); - - int bufferLength = buffer.Length; - if (offset < 0 || offset >= bufferLength) - throw new ArgumentOutOfRangeException("Offset of data to write is outside the buffer boundaries."); - if (length < 0 || (offset + length) > bufferLength) - throw new ArgumentOutOfRangeException("Length of data to write is outside the buffer boundaries."); - - } - - /// Initiates an asynchronous read operation on the pipe. - /// Buffer that will receive the data read from the pipe. - /// Byte offset within the buffer at which to begin writing the data received. - /// Length of the data to transfer. - /// An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous operation, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginRead(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject) - { - CheckReadParams(buffer, offset, length); - - USBAsyncResult result = new USBAsyncResult(userCallback, stateObject); - try - { - _device.InternalDevice.ReadPipeOverlapped(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, result); - } - catch (API.APIException e) - { - if (result != null) - result.Dispose(); - throw new USBException("Failed to read from pipe.", e); - } - catch (Exception) - { - if (result != null) - result.Dispose(); - throw; - } - return result; - } - - /// - /// Waits for a pending asynchronous read operation to complete. - /// - /// The object representing the asynchonous operation, - /// as returned by . - /// The number of bytes transfered during the operation. - /// Every call to must have a matching call to to dispose - /// of any resources used and to retrieve the result of the operation. When the operation was successful the method returns the number - /// of bytes that were transfered. If an error occurred during the operation this method will throw the exceptions that would - /// otherwise have ocurred during the operation. If the operation is not yet finished EndWrite will wait for the - /// operation to finish before returning. - public int EndRead(IAsyncResult asyncResult) - { - if (asyncResult == null) - throw new NullReferenceException("asyncResult cannot be null"); - if (!(asyncResult is USBAsyncResult)) - throw new ArgumentException("AsyncResult object was not created by calling BeginRead on this class."); - - // todo: check duplicate end reads? - USBAsyncResult result = (USBAsyncResult)asyncResult; - try - { - if (!result.IsCompleted) - result.AsyncWaitHandle.WaitOne(); - - if (result.Error != null) - throw new USBException("Asynchronous read from pipe has failed.", result.Error); - - return result.BytesTransfered; - } - finally - { - result.Dispose(); - } - - } - - /// - /// Writes data from a buffer to the pipe. - /// - /// The buffer to write data from. The complete buffer will be written to the device. - public void Write(byte[] buffer) - { - Write(buffer, 0, buffer.Length); - } - - /// - /// Writes data from a buffer to the pipe. - /// - /// The buffer to write data from. - /// The byte offset in from which to begin writing. - /// The number of bytes to write, starting at offset - public void Write(byte[] buffer, int offset, int length) - { - CheckWriteParams(buffer, offset, length); - - try - { - _device.InternalDevice.WritePipe(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length); - } - catch (API.APIException e) - { - throw new USBException("Failed to write to pipe.", e); - } - } - - /// Initiates an asynchronous write operation on the pipe. - /// Buffer that contains the data to write to the pipe. - /// Byte offset within the buffer from which to begin writing. - /// Length of the data to transfer. - /// An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required. - /// A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required. - /// An object repesenting the asynchronous operation, which could still be pending. - /// This method always completes immediately even if the operation is still pending. The object returned represents the operation - /// and must be passed to to retrieve the result of the operation. For every call to this method a matching call to - /// must be made. When specifies a callback function, this function will be called when the operation is completed. The optional - /// parameter can be used to pass user-defined information to this callback or the . The - /// also provides an event handle () that will be triggered when the operation is complete as well. - /// - public IAsyncResult BeginWrite(byte[] buffer, int offset, int length, AsyncCallback userCallback, object stateObject) - { - CheckWriteParams(buffer, offset, length); - - USBAsyncResult result = new USBAsyncResult(userCallback, stateObject); - try - { - _device.InternalDevice.WriteOverlapped(Interface.InterfaceIndex, _pipeInfo.PipeId, buffer, offset, length, result); - } - catch (API.APIException e) - { - if (result != null) - result.Dispose(); - throw new USBException("Failed to write to pipe.", e); - } - catch (Exception) - { - if (result != null) - result.Dispose(); - throw; - } - return result; - } - - /// - /// Waits for a pending asynchronous write operation to complete. - /// - /// The object representing the asynchonous operation, - /// as returned by . - /// The number of bytes transfered during the operation. - /// Every call to must have a matching call to to dispose - /// of any resources used and to retrieve the result of the operation. When the operation was successful the method returns the number - /// of bytes that were transfered. If an error occurred during the operation this method will throw the exceptions that would - /// otherwise have ocurred during the operation. If the operation is not yet finished EndWrite will wait for the - /// operation to finish before returning. - public void EndWrite(IAsyncResult asyncResult) - { - if (asyncResult == null) - throw new NullReferenceException("asyncResult cannot be null"); - if (!(asyncResult is USBAsyncResult)) - throw new ArgumentException("AsyncResult object was not created by calling BeginWrite on this class."); - - USBAsyncResult result = (USBAsyncResult)asyncResult; - try - { - // todo: check duplicate end writes? - - if (!result.IsCompleted) - result.AsyncWaitHandle.WaitOne(); - - if (result.Error != null) - throw new USBException("Asynchronous write to pipe has failed.", result.Error); - } - finally - { - result.Dispose(); - } - } - - /// - /// Aborts all pending transfers for this pipe. - /// - public void Abort() - { - try - { - _device.InternalDevice.AbortPipe(Interface.InterfaceIndex, _pipeInfo.PipeId); - } - catch (API.APIException e) - { - throw new USBException("Failed to abort pipe.", e); - } - } - - /// - /// Flushes the pipe, discarding any data that is cached. Only available on IN direction pipes. - /// - public void Flush() - { - if (!IsIn) - throw new NotSupportedException("Flush is only supported on IN direction pipes"); - try - { - _device.InternalDevice.FlushPipe(Interface.InterfaceIndex, _pipeInfo.PipeId); - } - catch (API.APIException e) - { - throw new USBException("Failed to flush pipe.", e); - } - } - - internal USBPipe(USBDevice device, API.WINUSB_PIPE_INFORMATION pipeInfo) - { - _pipeInfo = pipeInfo; - _device = device; - - // Policy is not set until interface is attached - _policy = null; - } - - internal void AttachInterface(USBInterface usbInterface) - { - _interface = usbInterface; - - // Initialize policy now that interface is set (policy requires interface) - _policy = new USBPipePolicy(_device, _interface.InterfaceIndex, _pipeInfo.PipeId); - } - - } - -} \ No newline at end of file diff --git a/FelLib/WinUSBNet/USBPipeCollection.cs b/FelLib/WinUSBNet/USBPipeCollection.cs deleted file mode 100644 index a91d8d58..00000000 --- a/FelLib/WinUSBNet/USBPipeCollection.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Text; -using System.Collections; -using System.Collections.Generic; - -namespace MadWizard.WinUSBNet -{ - /// - /// Collection of UsbPipe objects - /// - public class USBPipeCollection : IEnumerable - { - private Dictionary _pipes; - - internal USBPipeCollection(USBPipe[] pipes) - { - _pipes = new Dictionary(pipes.Length); - foreach (USBPipe pipe in pipes) - { - if (_pipes.ContainsKey(pipe.Address)) - throw new USBException("Duplicate pipe address in endpoint."); - _pipes[pipe.Address] = pipe; - } - } - - /// - /// Returns the pipe from the collection with the given pipe address - /// - /// Address of the pipe to return - /// The pipe with the given pipe address - /// Thrown if no pipe with the specified address - /// is available in the collection. - public USBPipe this [byte pipeAddress] - { - get - { - USBPipe pipe; - if (!_pipes.TryGetValue(pipeAddress, out pipe)) - throw new IndexOutOfRangeException(); - return pipe; - } - } - - private class UsbPipeEnumerator : IEnumerator - { - private int _index; - private USBPipe[] _pipes; - - public UsbPipeEnumerator(USBPipe[] pipes) - { - _pipes = pipes; - _index = -1; - } - - public void Dispose() - { - // Empty - } - private USBPipe GetCurrent() - { - try - { - return _pipes[_index]; - } - - catch (IndexOutOfRangeException) - { - throw new InvalidOperationException(); - } - } - - public USBPipe Current - { - get - { - return GetCurrent(); - } - } - - - object IEnumerator.Current - { - get - { - return GetCurrent(); - } - } - - public bool MoveNext() - { - _index++; - return _index < _pipes.Length; - } - - public void Reset() - { - _index = -1; - } - - } - - private USBPipe[] GetPipeList() - { - var values = _pipes.Values; - USBPipe[] pipeList = new USBPipe[values.Count]; - values.CopyTo(pipeList, 0); - return pipeList; - } - - /// - /// Returns a typed enumerator that iterates through a collection. - /// - /// The enumerator object that can be used to iterate through the collection. - public IEnumerator GetEnumerator() - { - return new UsbPipeEnumerator(GetPipeList()); - } - - /// - /// Returns an enumerator that iterates through a collection. - /// - /// An IEnumerator object that can be used to iterate through the collection. - IEnumerator IEnumerable.GetEnumerator() - { - return new UsbPipeEnumerator(GetPipeList()); - } - } -} diff --git a/FelLib/WinUSBNet/USBPipePolicy.cs b/FelLib/WinUSBNet/USBPipePolicy.cs deleted file mode 100644 index 800b748e..00000000 --- a/FelLib/WinUSBNet/USBPipePolicy.cs +++ /dev/null @@ -1,181 +0,0 @@ -/* WinUSBNet library - * (C) 2010 Thomas Bleeker (www.madwizard.org) - * - * Licensed under the MIT license, see license.txt or: - * http://www.opensource.org/licenses/mit-license.php - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace MadWizard.WinUSBNet -{ - - /// - /// Describes the policy for a specific USB pipe - /// - public class USBPipePolicy - { - - private byte _pipeID; - private int _interfaceIndex; - private USBDevice _device; - - internal USBPipePolicy(USBDevice device, int interfaceIndex, byte pipeID) - { - _pipeID = pipeID; - _interfaceIndex = interfaceIndex; - _device = device; - } - - - - private void RequireDirectionOut() - { - // Some policy types only apply specifically to OUT direction pipes - if ((_pipeID & 0x80) != 0) - throw new NotSupportedException("This policy type is only allowed on OUT direction pipes."); - } - - private void RequireDirectionIn() - { - // Some policy types only apply specifically to IN direction pipes - // This function checks for this. - if ((_pipeID & 0x80) == 0) - throw new NotSupportedException("This policy type is only allowed on IN direction pipes."); - } - - /// - /// When false, read requests fail when the device returns more data than requested. When true, extra data is - /// saved and returned on the next read. Default value is true. Only available on IN direction pipes. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public bool AllowPartialReads - { - get - { - RequireDirectionIn(); - return _device.InternalDevice.GetPipePolicyBool(_interfaceIndex, _pipeID, API.POLICY_TYPE.ALLOW_PARTIAL_READS); - } - set - { - RequireDirectionIn(); - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.ALLOW_PARTIAL_READS, value); - } - } - - /// - /// When true, the driver fails stalled data transfers, but the driver clears the stall condition automatically. Default - /// value is false. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public bool AutoClearStall - { - get - { - return _device.InternalDevice.GetPipePolicyBool(_interfaceIndex, _pipeID, API.POLICY_TYPE.AUTO_CLEAR_STALL); - } - set - { - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.AUTO_CLEAR_STALL, value); - } - } - - /// - /// If both AllowPartialReads and AutoFlush are true, when the device returns more data than requested by the client it - /// will discard the remaining data. Default value is false. Only available on IN direction pipes. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public bool AutoFlush - { - get - { - RequireDirectionIn(); - return _device.InternalDevice.GetPipePolicyBool(_interfaceIndex, _pipeID, API.POLICY_TYPE.AUTO_FLUSH); ; - } - set - { - RequireDirectionIn(); - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.AUTO_FLUSH, value); - } - } - /// - /// When true, read operations are completed only when the number of bytes requested by the client has been received. Default value is false. - /// Only available on IN direction pipes. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public bool IgnoreShortPackets - { - get - { - RequireDirectionIn(); - return _device.InternalDevice.GetPipePolicyBool(_interfaceIndex, _pipeID, API.POLICY_TYPE.IGNORE_SHORT_PACKETS); ; - } - set - { - RequireDirectionIn(); - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.IGNORE_SHORT_PACKETS, value); - } - } - - /// - /// Specifies the timeout in milliseconds for pipe operations. If an operation does not finish within the specified time it will fail. - /// When set to zero, no timeout is used. Default value is zero. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public int PipeTransferTimeout - { - get - { - return (int)_device.InternalDevice.GetPipePolicyUInt(_interfaceIndex, _pipeID, API.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT); - } - set - { - if (value < 0) - throw new ArgumentOutOfRangeException("Pipe transfer timeout cannot be negative."); - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT, (uint)value); - } - } - - /// - /// When true, read and write operations to the pipe must have a buffer length that is a multiple of the maximum endpoint packet size, - /// and the length must be less than the maximum transfer size. With these conditions met, data is sent directly to the USB driver stack, - /// bypassing the queuing and error handling of WinUSB. - /// Default value is false. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public bool RawIO - { - get - { - return _device.InternalDevice.GetPipePolicyBool(_interfaceIndex, _pipeID, API.POLICY_TYPE.RAW_IO); ; - } - set - { - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.RAW_IO, value); - } - } - - /// - /// When true, every write request that is a multiple of the maximum packet size for the endpoint is terminated with a zero-length packet. - /// Default value is false. Only available on OUT direction pipes. - /// - /// WinUSB_GetPipePolicy for a more detailed description - public bool ShortPacketTerminate - { - get - { - RequireDirectionOut(); - return _device.InternalDevice.GetPipePolicyBool(_interfaceIndex, _pipeID, API.POLICY_TYPE.SHORT_PACKET_TERMINATE); ; - } - set - { - RequireDirectionOut(); - _device.InternalDevice.SetPipePolicy(_interfaceIndex, _pipeID, API.POLICY_TYPE.SHORT_PACKET_TERMINATE, value); - } - } - - } -} -- cgit v1.2.3