diff options
author | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2017-03-05 14:38:01 +0300 |
---|---|---|
committer | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2017-03-05 14:40:12 +0300 |
commit | d1fb6c4ab4e259a8082a2c24e28538351880d0fc (patch) | |
tree | 4fa7a422ab71de2ab1a8a6603c80e714a2d57ea5 /FelLib | |
parent | 8aee67b69c23a11ebdac6858466bf3bec8cd6b27 (diff) |
USB library changed to LibWinUsb, it's more portable
Diffstat (limited to 'FelLib')
-rw-r--r-- | FelLib/Fel.cs | 115 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/APIException.cs | 45 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/DeviceDetails.cs | 23 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/DeviceManagement.cs | 315 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/DeviceManagementAPI.cs | 159 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/FileAPI.cs | 39 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/WinUSBDevice.cs | 477 | ||||
-rw-r--r-- | FelLib/WinUSBNet/API/WinUSBDeviceAPI.cs | 202 | ||||
-rw-r--r-- | FelLib/WinUSBNet/DeviceNotifyHook.cs | 117 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USB.cs | 80 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBAsyncResult.cs | 136 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBDevice.cs | 756 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBDeviceDescriptor.cs | 135 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBDeviceInfo.cs | 85 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBException.cs | 40 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBInterface.cs | 152 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBInterfaceCollection.cs | 160 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBNotifier.cs | 190 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBPipe.cs | 387 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBPipeCollection.cs | 135 | ||||
-rw-r--r-- | FelLib/WinUSBNet/USBPipePolicy.cs | 181 |
21 files changed, 78 insertions, 3851 deletions
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 -{ - /// <summary> - /// Exception used internally to catch Win32 API errors. This exception should - /// not be thrown to the library's caller. - /// </summary> - 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
-{
- /// <summary>
- /// Routines for detecting devices and receiving device notifications.
- /// </summary>
- 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<DeviceDetails> deviceList = new List<DeviceDetails>();
- 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 -{ - /// <summary> - /// API declarations relating to device management (SetupDixxx and - /// RegisterDeviceNotification functions). - /// </summary> - - 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 -{ - /// <summary> - /// API declarations relating to file I/O (and used by WinUsb). - /// </summary> - - 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 -{ - /// <summary> - /// Wrapper for a WinUSB device dealing with the WinUSB and additional interface handles - /// </summary> - 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<WINUSB_PIPE_INFORMATION>(); - 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<IntPtr> interfaces = new List<IntPtr>(); - 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 -{ - /// <summary> - /// USB base class code enumeration, as defined in the USB specification - /// </summary> - public enum USBBaseClass - { - /// <summary>Unknown non-zero class code. Used when the actual class code - /// does not match any of the ones defined in this enumeration. </summary> - Unknown = -1, - - /// <summary>Base class defined elsewhere (0x00)</summary> - None = 0x00, - - /// <summary>Audio base class (0x01)</summary> - Audio = 0x01, - - /// <summary>Communications and CDC control base class (0x02)</summary> - CommCDC = 0x02, - - /// <summary>HID base class (0x03)</summary> - HID = 0x03, - - /// <summary>Physical base class (0x05)</summary> - Physical = 0x05, - - /// <summary>Image base class (0x06)</summary> - Image = 0x06, - - /// <summary>Printer base class (0x07)</summary> - Printer = 0x07, - - /// <summary>Mass storage base class (0x08)</summary> - MassStorage = 0x08, - - /// <summary>Hub base class (0x09)</summary> - Hub = 0x09, - - /// <summary>CDC data base class (0x0A)</summary> - CDCData = 0x0A, - - /// <summary>Smart card base class (0x0B)</summary> - SmartCard = 0x0B, - - /// <summary>Content security base class (0x0D)</summary> - ContentSecurity = 0x0D, - - /// <summary>Video base class (0x0E)</summary> - Video = 0x0E, - - /// <summary>Personal healthcare base class (0x0F)</summary> - PersonalHealthcare = 0x0F, - - /// <summary>Diagnosticdevice base class (0xDC)</summary> - DiagnosticDevice = 0xDC, - - /// <summary>Wireless controller base class (0xE0)</summary> - WirelessController = 0xE0, - - /// <summary>Miscellaneous base class (0xEF)</summary> - Miscellaneous = 0xEF, - - /// <summary>Application specific base class (0xFE)</summary> - ApplicationSpecific = 0xFE, - - /// <summary>Vendor specific base class (0xFF)</summary> - 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 -{ - /// <summary> - /// The UsbDevice class represents a single WinUSB device. - /// </summary> - public class USBDevice : IDisposable - { - private API.WinUSBDevice _wuDevice = null; - private bool _disposed = false; - - /// <summary> - /// Collection of all pipes available on the USB device - /// </summary> - public USBPipeCollection Pipes - { - get; - private set; - } - - - - - /// <summary> - /// Collection of all interfaces available on the USB device - /// </summary> - public USBInterfaceCollection Interfaces - { - get; - private set; - } - - /// <summary> - /// Device descriptor with information about the device - /// </summary> - public USBDeviceDescriptor Descriptor - { - get; - private set; - } - - /// <summary> - /// Constructs a new USB device - /// </summary> - /// <param name="deviceInfo">USB device info of the device to create</param> - public USBDevice(USBDeviceInfo deviceInfo) - : this(deviceInfo.DevicePath) - { - // Handled in other constructor - } - - /// <summary> - /// 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. - /// </summary> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// <summary> - /// Finalizer for the UsbDevice. Disposes all unmanaged handles. - /// </summary> - ~USBDevice() - { - Dispose(false); - } - - /// <summary> - /// Disposes the object - /// </summary> - /// <param name="disposing">Indicates wether Dispose was called manually (true) or by - /// the garbage collector (false) via the destructor.</param> - protected virtual void Dispose(bool disposing) - { - if (_disposed) - return; - - if (disposing) - { - if (_wuDevice != null) - _wuDevice.Dispose(); - } - - // Clean unmanaged resources here. - // (none currently) - - _disposed = true; - } - - /// <summary> - /// Constructs a new USB device - /// </summary> - /// <param name="devicePathName">Device path name of the USB device to create</param> - 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<USBPipe> allPipes = new List<USBPipe>(); - - 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"); - } - - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - - /// <summary> - /// 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 <paramref name="requestType"/> parameter. Alternatively, <see cref="ControlIn(byte,byte,int,int,byte[],int)"/> and - /// <see cref="ControlOut(byte,byte,int,int,byte[],int)"/> 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. - /// </summary> - /// <param name="requestType">The setup packet request type.</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">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.</param> - /// <param name="length">Length of the data to transfer. Must be equal to or less than the length of <paramref name="buffer"/>. - /// The setup packet's length member will be set to this length.</param> - 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); - } - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter. Alternatively, <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> and - /// <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> 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. </summary> - /// <param name="requestType">The setup packet request type.</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">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.</param> - /// <param name="length">Length of the data to transfer. Must be equal to or less than the length of <paramref name="buffer"/>. The setup packet's length member will be set to this length.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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; - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter. Alternatively, <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> and - /// <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> 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. </summary> - /// <param name="requestType">The setup packet request type.</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">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. </param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - - /// <summary> - /// Waits for a pending asynchronous control transfer to complete. - /// </summary> - /// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchonous operation, - /// as returned by one of the ControlIn, ControlOut or ControlTransfer methods.</param> - /// <returns>The number of bytes transfered during the operation.</returns> - /// <remarks>Every asynchronous control transfer must have a matching call to <see cref="EndControlTransfer"/> 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.</remarks> - 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(); - } - - } - - - /// <summary> - /// 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 <paramref name="requestType"/> parameter). Alternatively, <see cref="ControlIn(byte,byte,int,int,byte[])"/> and - /// <see cref="ControlOut(byte,byte,int,int,byte[])"/> 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. - /// </summary> - /// <param name="requestType">The setup packet request type.</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">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.</param> - public void ControlTransfer(byte requestType, byte request, int value, int index, byte[] buffer) - { - ControlTransfer(requestType, request, value, index, buffer, buffer.Length); - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter). Alternatively, <see cref="ControlIn(byte,byte,int,int)"/> and - /// <see cref="ControlOut(byte,byte,int,int)"/> 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. - /// </summary> - /// <param name="requestType">The setup packet request type.</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - 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."); - } - - /// <summary> - /// Initiates a control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter). A buffer to receive the data is automatically created by this method. - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="length">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.</param> - /// <returns>A buffer containing the data transfered.</returns> - 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; - } - - - /// <summary> - /// Initiates a control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter). - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">The buffer that will receive the data transfered.</param> - /// <param name="length">Length of the data to transfer. The length member of the setup packet will be set to this length. The buffer specified - /// by the <paramref name="buffer"/> parameter should have at least this length.</param> - public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer, int length) - { - CheckIn(requestType); - ControlTransfer(requestType, request, value, index, buffer, length); - } - - /// <summary> - /// Initiates a control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter). The length of buffer given by the <paramref name="buffer"/> parameter will dictate - /// the number of bytes that are transfered and the value of the setup packet's length member. - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">The buffer that will receive the data transfered. The length of this buffer will be the number of bytes transfered.</param> - public void ControlIn(byte requestType, byte request, int value, int index, byte[] buffer) - { - CheckIn(requestType); - ControlTransfer(requestType, request, value, index, buffer); - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter). The setup packets' length member will be set to zero. - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - 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]); - } - - /// <summary> - /// Initiates a control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter). - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">A buffer containing the data to transfer in the data stage.</param> - /// <param name="length">Length of the data to transfer. Only the first <paramref name="length"/> bytes of <paramref name="buffer"/> will be transfered. - /// The setup packet's length parameter is set to this length.</param> - public void ControlOut(byte requestType, byte request, int value, int index, byte[] buffer, int length) - { - CheckOut(requestType); - ControlTransfer(requestType, request, value, index, buffer, length); - } - - /// <summary> - /// Initiates a control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter). - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">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.</param> - public void ControlOut(byte requestType, byte request, int value, int index, byte[] buffer) - { - CheckOut(requestType); - ControlTransfer(requestType, request, value, index, buffer); - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter. The setup packets' length member will be set to zero. - /// </summary> - /// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - 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]); - } - - - - /// <summary> - /// 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 <paramref name="requestType"/> parameter. Alternatively, <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> and - /// <see cref="BeginControlIn(byte,byte,int,int,byte[],int,AsyncCallback,object)"/> 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. </summary> - /// <param name="requestType">The setup packet request type.</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - - - /// <summary> - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter).</summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">The buffer that will receive the data transfered.</param> - /// <param name="length">Length of the data to transfer. Must be equal to or less than the length of <paramref name="buffer"/>. The setup packet's length member will be set to this length.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - /// <summary> - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an IN direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter).</summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">The buffer that will receive the data transfered. The setup packet's length member will be set to the length of this buffer.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter). - /// The setup packets' length member will be set to zero.</summary> - /// <param name="requestType">The setup packet request type. The request type must specify the IN direction (highest bit set).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - /// <summary> - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter).</summary> - /// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">The buffer that contains the data to be transfered.</param> - /// <param name="length">Length of the data to transfer. Must be equal to or less than the length of <paramref name="buffer"/>. The setup packet's length member will be set to this length.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - /// <summary> - /// Initiates an asynchronous control transfer over the default control endpoint. The request should have an OUT direction (specified by the highest bit - /// of the <paramref name="requestType"/> parameter).</summary> - /// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="buffer">The buffer that contains the data to be transfered. The setup packet's length member will be set to the length of this buffer.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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); - } - - /// <summary> - /// 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 <paramref name="requestType"/> parameter). - /// The setup packets' length member will be set to zero.</summary> - /// <param name="requestType">The setup packet request type. The request type must specify the OUT direction (highest bit cleared).</param> - /// <param name="request">The setup packet device request.</param> - /// <param name="value">The value member in the setup packet. Its meaning depends on the request. Value should be between zero and 65535 (0xFFFF).</param> - /// <param name="index">The index member in the setup packet. Its meaning depends on the request. Index should be between zero and 65535 (0xFFFF).</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the control transfer is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous control transfer, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndControlTransfer"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndControlTransfer"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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."); - } - - /// <summary> - /// Finds USB devices - /// </summary> - 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; - } - - /// <summary> - /// Finds the first WinUSB device with a VIA and PID - /// </summary> - 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 -{ - /// <summary> - /// USB device details - /// </summary> - public class USBDeviceDescriptor - { - /// <summary> - /// Windows path name for the USB device - /// </summary> - public string PathName { get; private set; } - - /// <summary> - /// USB vendor ID (VID) of the device - /// </summary> - public int VID { get; private set; } - - /// <summary> - /// USB product ID (PID) of the device - /// </summary> - public int PID { get; private set; } - - /// <summary> - /// Manufacturer name, or null if not available - /// </summary> - public string Manufacturer { get; private set; } - - /// <summary> - /// Product name, or null if not available - /// </summary> - public string Product { get; private set; } - - /// <summary> - /// Device serial number, or null if not available - /// </summary> - public string SerialNumber { get; private set; } - - - /// <summary> - /// Friendly device name, or path name when no - /// further device information is available - /// </summary> - 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; - } - } - - /// <summary> - /// 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 - /// </summary> - public byte ClassValue - { - get; - private set; - } - - /// <summary> - /// Device subclass code - /// </summary> - public byte SubClass - { - get; - private set; - } - - /// <summary> - /// Device protocol code - /// </summary> - public byte Protocol - { - get; - private set; - } - - /// <summary> - /// Device class code. If the device class does - /// not match any of the USBBaseClass enumeration values - /// the value will be USBBaseClass.Unknown - /// </summary> - 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 -{ - /// <summary> - /// 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. - /// </summary> - public class USBDeviceInfo - { - private API.DeviceDetails _details; - - /// <summary> - /// Vendor ID (VID) of the USB device - /// </summary> - public int VID - { - get - { - return _details.VID; - } - } - - /// <summary> - /// Product ID (VID) of the USB device - /// </summary> - public int PID - { - get - { - return _details.PID; - } - } - - /// <summary> - /// Manufacturer of the device, as specified in the INF file (not the device descriptor) - /// </summary> - public string Manufacturer - { - get - { - return _details.Manufacturer; - } - } - - /// <summary> - /// Description of the device, as specified in the INF file (not the device descriptor) - /// </summary> - public string DeviceDescription - { - get - { - return _details.DeviceDescription; - } - } - - /// <summary> - /// Device pathname - /// </summary> - 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 -{ - /// <summary> - /// Exception used by WinUSBNet to indicate errors. This is the - /// main exception to catch when using the library. - /// </summary> - public class USBException : Exception - { - /// <summary> - /// Constructs a new USBException with the given message - /// </summary> - /// <param name="message">The message describing the exception</param> - public USBException(string message) - : base(message) - { - } - - /// <summary> - /// Constructs a new USBException with the given message and underlying exception - /// that caused the USBException. - /// </summary> - /// <param name="message">The message describing the exception</param> - /// <param name="innerException">The underlying exception causing the USBException</param> - 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 -{ - /// <summary> - /// Represents a single USB interface from a USB device - /// </summary> - public class USBInterface - { - /// <summary> - /// Collection of pipes associated with this interface - /// </summary> - public USBPipeCollection Pipes - { - get; - private set; - } - - /// <summary> - /// Interface number from the interface descriptor - /// </summary> - public int Number - { - get; - private set; - } - - /// <summary> - /// USB device associated with this interface - /// </summary> - public USBDevice Device - { - get; - private set; - } - - /// <summary> - /// First IN direction pipe on this interface - /// </summary> - public USBPipe InPipe - { - get; - private set; - } - - /// <summary> - /// First OUT direction pipe on this interface - /// </summary> - public USBPipe OutPipe - { - get; - private set; - } - - /// <summary> - /// Interface class code. If the interface class does - /// not match any of the USBBaseClass enumeration values - /// the value will be USBBaseClass.Unknown - /// </summary> - public USBBaseClass BaseClass - { - get; - private set; - } - - /// <summary> - /// 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 - /// </summary> - public byte ClassValue - { - get; - private set; - } - - /// <summary> - /// Interface subclass code - /// </summary> - public byte SubClass - { - get; - private set; - } - - /// <summary> - /// Interface protocol code - /// </summary> - 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 -{ - /// <summary> - /// Collection of UsbInterface objects - /// </summary> - public class USBInterfaceCollection : IEnumerable<USBInterface> - { - private USBInterface[] _interfaces; - - internal USBInterfaceCollection(USBInterface[] interfaces) - { - _interfaces = interfaces; - } - - private class USBInterfaceEnumerator : IEnumerator<USBInterface> - { - 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; - } - } - - /// <summary> - /// Finds the first interface with that matches the device class - /// given by the <paramref name="interfaceClass"/> parameter. - /// </summary> - /// <param name="interfaceClass">The device class the interface should match</param> - /// <returns>The first interface with the given interface class, or null - /// if no such interface exists.</returns> - 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; - } - - /// <summary> - /// Finds all interfaces matching the device class given by the - /// <paramref name="interfaceClass"/> parameter. - /// </summary> - /// <param name="interfaceClass">The device class the interface should match</param> - /// <returns>An array of USBInterface objects matching the device class, or an empty - /// array if no interface matches.</returns> - public USBInterface[] FindAll(USBBaseClass interfaceClass) - { - List<USBInterface> matchingInterfaces = new List<USBInterface>(); - for (int i = 0; i < _interfaces.Length; i++) - { - USBInterface iface = _interfaces[i]; - if (iface.BaseClass == interfaceClass) - matchingInterfaces.Add(iface); - } - return matchingInterfaces.ToArray(); - } - - /// <summary> - /// Returns a typed enumerator that iterates through a collection. - /// </summary> - /// <returns>The enumerator object that can be used to iterate through the collection.</returns> - public IEnumerator<USBInterface> GetEnumerator() - { - return new USBInterfaceEnumerator(_interfaces); - } - - /// <summary> - /// Get interface by interface number - /// </summary> - /// <param name="interfaceNumber">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.</param> - /// <exception cref="IndexOutOfRangeException">Thrown when the given interface number does not exist in the collection.</exception> - /// <returns></returns> - 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)); - } - } - - /// <summary> - /// Returns an enumerator that iterates through a collection. - /// </summary> - /// <returns>An IEnumerator object that can be used to iterate through the collection.</returns> - 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 -{ - /// <summary> - /// Delegate for event handler methods handing USB events - /// </summary> - /// <param name="sender">The source of the event</param> - /// <param name="e">Details of the event</param> - public delegate void USBEventHandler(object sender, USBEvent e); - - /// <summary> - /// Event type enumeration for WinUSB events - /// </summary> - public enum USBEventType - { - /// <summary> - /// A device has been connected to the system - /// </summary> - DeviceArrival, - - /// <summary> - /// A device has been disconnected from the system - /// </summary> - DeviceRemoval, - } - - /// <summary> - /// Contains the details of a USB event - /// </summary> - public class USBEvent : EventArgs - { - /// <summary> - /// WinUSB interface GUID of the device as specified in the WinUSBNotifier - /// </summary> - public Guid Guid; - - /// <summary> - /// Device pathname that identifies the device - /// </summary> - public string DevicePath; - - /// <summary> - /// Type of event that occurred - /// </summary> - public USBEventType Type; - - internal USBEvent(USBEventType type, Guid guid, string devicePath) - { - this.Guid = guid; - this.DevicePath = devicePath; - this.Type= type; - } - } - - /// <summary> - /// Helper class to receive notifications on USB device changes such as - /// connecting or removing a device. - /// </summary> - public class USBNotifier : IDisposable - { - private DeviceNotifyHook _hook; - private Guid _guid; - - /// <summary> - /// Event triggered when a new USB device that matches the USBNotifier's GUID is connected - /// </summary> - public event USBEventHandler Arrival; - - /// <summary> - /// Event triggered when a new USB device that matches the USBNotifier's GUID is disconnected - /// </summary> - public event USBEventHandler Removal; - - /// <summary> - /// The interface GUID of devices this USBNotifier will watch - /// </summary> - public Guid Guid - { - get - { - return _guid; - } - } - - /// <summary> - /// 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. - /// </summary> - /// <param name="control">A control that will be used internally for device notification messages. - /// You can use a Form object for example.</param> - /// <param name="guidString">The interface GUID string of the devices to watch.</param> - public USBNotifier(Control control, string guidString) : - this(control, new Guid(guidString)) - { - // Handled in other constructor - } - - - /// <summary> - /// 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. - /// </summary> - /// <param name="control">A control that will be used internally for device notification messages. - /// You can use a Form object for example.</param> - /// <param name="guid">The interface GUID of the devices to watch.</param> - public USBNotifier(Control control, Guid guid) - { - _guid = guid; - _hook = new DeviceNotifyHook(this, control, _guid); - } - - /// <summary> - /// Triggers the arrival event - /// </summary> - /// <param name="devicePath">Device pathname of the device that has been connected</param> - protected void OnArrival(string devicePath) - { - if (Arrival != null) - Arrival(this, new USBEvent(USBEventType.DeviceArrival, _guid, devicePath)); - } - /// <summary> - /// Trigggers the removal event - /// </summary> - /// <param name="devicePath">Device pathname of the device that has been connected</param> - 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); - } - - } - - /// <summary> - /// Disposes the USBNotifier object and frees all resources. - /// Call this method when the object is no longer needed. - /// </summary> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// <summary> - /// Disposes the object's resources. - /// </summary> - /// <param name="disposing">True when dispose is called manually, false when called by the finalizer.</param> - 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 -{ - /// <summary> - /// 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) - /// </summary> - public class USBPipe - { - private API.WINUSB_PIPE_INFORMATION _pipeInfo; - private USBInterface _interface = null; - private USBDevice _device; - private USBPipePolicy _policy; - - /// <summary> - /// Endpoint address including the direction in the most significant bit - /// </summary> - public byte Address - { - get - { - return _pipeInfo.PipeId; - } - } - - /// <summary> - /// The USBDevice this pipe is associated with - /// </summary> - public USBDevice Device - { - get - { - return _device; - } - } - - /// <summary> - /// Maximum packet size for transfers on this endpoint - /// </summary> - public int MaximumPacketSize - { - get - { - return _pipeInfo.MaximumPacketSize; - } - } - - /// <summary> - /// The interface associated with this pipe - /// </summary> - public USBInterface Interface - { - get - { - return _interface; - } - } - - /// <summary> - /// The pipe policy settings for this pipe - /// </summary> - public USBPipePolicy Policy - { - get - { - return _policy; - } - } - - /// <summary> - /// True if the pipe has direction OUT (host to device), false otherwise. - /// </summary> - public bool IsOut - { - get - { - return (_pipeInfo.PipeId & 0x80) == 0; - } - } - - /// <summary> - /// True if the pipe has direction IN (device to host), false otherwise. - /// </summary> - public bool IsIn - { - get - { - return (_pipeInfo.PipeId & 0x80) != 0; - } - } - - /// <summary> - /// Reads data from the pipe into a buffer. - /// </summary> - /// <param name="buffer">The buffer to read data into. The maximum number of bytes that will be read is specified by the length of the buffer.</param> - /// <returns>The number of bytes read from the pipe.</returns> - public int Read(byte[] buffer) - { - return Read(buffer, 0, buffer.Length); - } - - /// <summary> - /// Reads data from the pipe into a buffer. - /// </summary> - /// <param name="buffer">The buffer to read data into.</param> - /// <param name="offset">The byte offset in <paramref name="buffer"/> from which to begin writing data read from the pipe.</param> - /// <param name="length">The maximum number of bytes to read, starting at offset</param> - /// <returns>The number of bytes read from the pipe.</returns> - 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."); - - } - - /// <summary>Initiates an asynchronous read operation on the pipe. </summary> - /// <param name="buffer">Buffer that will receive the data read from the pipe.</param> - /// <param name="offset">Byte offset within the buffer at which to begin writing the data received.</param> - /// <param name="length">Length of the data to transfer.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous operation, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndRead"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndRead"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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; - } - - /// <summary> - /// Waits for a pending asynchronous read operation to complete. - /// </summary> - /// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchonous operation, - /// as returned by <see cref="BeginRead"/>.</param> - /// <returns>The number of bytes transfered during the operation.</returns> - /// <remarks>Every call to <see cref="BeginRead"/> must have a matching call to <see cref="EndRead"/> 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.</remarks> - 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(); - } - - } - - /// <summary> - /// Writes data from a buffer to the pipe. - /// </summary> - /// <param name="buffer">The buffer to write data from. The complete buffer will be written to the device.</param> - public void Write(byte[] buffer) - { - Write(buffer, 0, buffer.Length); - } - - /// <summary> - /// Writes data from a buffer to the pipe. - /// </summary> - /// <param name="buffer">The buffer to write data from.</param> - /// <param name="offset">The byte offset in <paramref name="buffer"/> from which to begin writing.</param> - /// <param name="length">The number of bytes to write, starting at offset</param> - 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); - } - } - - /// <summary>Initiates an asynchronous write operation on the pipe. </summary> - /// <param name="buffer">Buffer that contains the data to write to the pipe.</param> - /// <param name="offset">Byte offset within the buffer from which to begin writing.</param> - /// <param name="length">Length of the data to transfer.</param> - /// <param name="userCallback">An optional asynchronous callback, to be called when the operation is complete. Can be null if no callback is required.</param> - /// <param name="stateObject">A user-provided object that distinguishes this particular asynchronous operation. Can be null if not required.</param> - /// <returns>An <see cref="IAsyncResult"/> object repesenting the asynchronous operation, which could still be pending.</returns> - /// <remarks>This method always completes immediately even if the operation is still pending. The <see cref="IAsyncResult"/> object returned represents the operation - /// and must be passed to <see cref="EndWrite"/> to retrieve the result of the operation. For every call to this method a matching call to - /// <see cref="EndWrite"/> must be made. When <paramref name="userCallback"/> specifies a callback function, this function will be called when the operation is completed. The optional - /// <paramref name="stateObject"/> parameter can be used to pass user-defined information to this callback or the <see cref="IAsyncResult"/>. The <see cref="IAsyncResult"/> - /// also provides an event handle (<see cref="IAsyncResult.AsyncWaitHandle" />) that will be triggered when the operation is complete as well. - /// </remarks> - 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; - } - - /// <summary> - /// Waits for a pending asynchronous write operation to complete. - /// </summary> - /// <param name="asyncResult">The <see cref="IAsyncResult"/> object representing the asynchonous operation, - /// as returned by <see cref="BeginWrite"/>.</param> - /// <returns>The number of bytes transfered during the operation.</returns> - /// <remarks>Every call to <see cref="BeginWrite"/> must have a matching call to <see cref="EndWrite"/> 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.</remarks> - 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(); - } - } - - /// <summary> - /// Aborts all pending transfers for this pipe. - /// </summary> - public void Abort() - { - try - { - _device.InternalDevice.AbortPipe(Interface.InterfaceIndex, _pipeInfo.PipeId); - } - catch (API.APIException e) - { - throw new USBException("Failed to abort pipe.", e); - } - } - - /// <summary> - /// Flushes the pipe, discarding any data that is cached. Only available on IN direction pipes. - /// </summary> - 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 -{ - /// <summary> - /// Collection of UsbPipe objects - /// </summary> - public class USBPipeCollection : IEnumerable<USBPipe> - { - private Dictionary<byte, USBPipe> _pipes; - - internal USBPipeCollection(USBPipe[] pipes) - { - _pipes = new Dictionary<byte, USBPipe>(pipes.Length); - foreach (USBPipe pipe in pipes) - { - if (_pipes.ContainsKey(pipe.Address)) - throw new USBException("Duplicate pipe address in endpoint."); - _pipes[pipe.Address] = pipe; - } - } - - /// <summary> - /// Returns the pipe from the collection with the given pipe address - /// </summary> - /// <param name="pipeAddress">Address of the pipe to return</param> - /// <returns>The pipe with the given pipe address</returns> - /// <exception cref="IndexOutOfRangeException">Thrown if no pipe with the specified address - /// is available in the collection.</exception> - public USBPipe this [byte pipeAddress] - { - get - { - USBPipe pipe; - if (!_pipes.TryGetValue(pipeAddress, out pipe)) - throw new IndexOutOfRangeException(); - return pipe; - } - } - - private class UsbPipeEnumerator : IEnumerator<USBPipe> - { - 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; - } - - /// <summary> - /// Returns a typed enumerator that iterates through a collection. - /// </summary> - /// <returns>The enumerator object that can be used to iterate through the collection.</returns> - public IEnumerator<USBPipe> GetEnumerator() - { - return new UsbPipeEnumerator(GetPipeList()); - } - - /// <summary> - /// Returns an enumerator that iterates through a collection. - /// </summary> - /// <returns>An IEnumerator object that can be used to iterate through the collection.</returns> - 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 -{ - - /// <summary> - /// Describes the policy for a specific USB pipe - /// </summary> - 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."); - } - - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - /// <summary> - /// When true, the driver fails stalled data transfers, but the driver clears the stall condition automatically. Default - /// value is false. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - /// <summary> - /// 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. - /// </summary> - /// <seealso href="http://msdn.microsoft.com/en-us/library/aa476439.aspx">WinUSB_GetPipePolicy for a more detailed description</seealso> - 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); - } - } - - } -} |