#region Copyright (c) Travis Robinson // Copyright (c) 2011-2021 Travis Robinson // All rights reserved. // // C# libusbK Bindings // Auto-generated on: 07.08.2021 // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRAVIS LEE ROBINSON // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // THE POSSIBILITY OF SUCH DAMAGE. #endregion using System; using System.Diagnostics; using System.Runtime.InteropServices; // ReSharper disable InconsistentNaming // ReSharper disable CheckNamespace // ReSharper disable UnassignedReadonlyField namespace libusbK { public static class AllKOptions { /// /// Alternate libusbK library to use. This must be assigned before any libusbK functions are called and it must be the /// full path and file name to a libusbK.dll. /// public static string LIBUSBK_FULLPATH_TO_ALTERNATE_DLL; } public static class AllKConstants { /// /// Allocated length for all strings in a \ref KLST_DEVINFO structure. /// public const int KLST_STRING_MAX_LEN = 256; /// /// libusbK library /// public const string LIBUSBK_DLL = "libusbK.dll"; /// /// Config power mask for the \c bmAttributes field of a \ref USB_CONFIGURATION_DESCRIPTOR /// public const byte USB_CONFIG_POWERED_MASK = 0xC0; /// /// Endpoint direction mask for the \c bEndpointAddress field of a \ref USB_ENDPOINT_DESCRIPTOR /// public const byte USB_ENDPOINT_DIRECTION_MASK = 0x80; /// /// Endpoint address mask for the \c bEndpointAddress field of a \ref USB_ENDPOINT_DESCRIPTOR /// public const byte USB_ENDPOINT_ADDRESS_MASK = 0x0F; } public enum PipePolicyType { SHORT_PACKET_TERMINATE = 0x01, AUTO_CLEAR_STALL = 0x02, PIPE_TRANSFER_TIMEOUT = 0x03, IGNORE_SHORT_PACKETS = 0x04, ALLOW_PARTIAL_READS = 0x05, AUTO_FLUSH = 0x06, RAW_IO = 0x07, MAXIMUM_TRANSFER_SIZE = 0x08, RESET_PIPE_ON_RESUME = 0x09, ISO_START_LATENCY = 0x20, ISO_ALWAYS_START_ASAP = 0x21, ISO_NUM_FIXED_PACKETS = 0x22, SIMUL_PARALLEL_REQUESTS = 0x30, } public enum PowerPolicyType { AUTO_SUSPEND = 0x81, SUSPEND_DELAY = 0x83, } public enum DeviceInformationType { DEVICE_SPEED = 0x01, } public enum EndpointType { /// /// Indicates a control endpoint /// CONTROL = 0x00, /// /// Indicates an isochronous endpoint /// ISOCHRONOUS = 0x01, /// /// Indicates a bulk endpoint /// BULK = 0x02, /// /// Indicates an interrupt endpoint /// INTERRUPT = 0x03, /// /// Endpoint type mask for the \c bmAttributes field of a \ref USB_ENDPOINT_DESCRIPTOR /// MASK = 0x03, } public static class ErrorCodes { /// /// The operation completed successfully. /// public const int Success = 0; /// /// Access is denied. /// public const int AccessDenied = 5; /// /// The handle is invalid. /// public const int InvalidHandle = 6; /// /// Not enough storage is available to process this command. /// public const int NotEnoughMemory = 8; /// /// The request is not supported. /// public const int NotSupported = 50; /// /// The parameter is incorrect. /// public const int InvalidParameter = 87; /// /// The semaphore timeout period has expired. /// public const int SemTimeout = 121; /// /// The requested resource is in use. /// public const int Busy = 170; /// /// Too many dynamic-link modules are attached to this program or dynamic-link module. /// public const int TooManyModules = 214; /// /// More data is available. /// public const int MoreData = 234; /// /// No more data is available. /// public const int NoMoreItems = 259; /// /// An attempt was made to operate on a thread within a specific process, but the thread specified is not in the /// process specified. /// public const int ThreadNotInProcess = 566; /// /// A thread termination occurred while the thread was suspended. The thread was resumed, and termination proceeded. /// public const int ThreadWasSuspended = 699; /// /// The I/O operation has been aborted because of either a thread exit or an application request. /// public const int OperationAborted = 995; /// /// Overlapped I/O event is not in a signaled state. /// public const int IoIncomplete = 996; /// /// Overlapped I/O operation is in progress. /// public const int IoPending = 997; /// /// Element not found. /// public const int NotFound = 1168; /// /// The operation was canceled by the user. /// public const int Cancelled = 1223; /// /// The library, drive, or media pool is empty. /// public const int Empty = 4306; /// /// The cluster resource is not available. /// public const int ResourceNotAvailable = 5006; /// /// The cluster resource could not be found. /// public const int ResourceNotFound = 5007; } public interface IKLIB_HANDLE { KLIB_HANDLE_TYPE HandleType { get; } IntPtr Pointer { get; } IntPtr GetContext(); bool SetContext(IntPtr UserContext); bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback); } /// /// A structure representing additional information about super speed (or higher) endpoints. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Specifies the maximum number of packets that the endpoint can send or receive as a part of a burst. public byte bMaxBurst; public byte AsUchar; /// Number of bytes per interval public ushort wBytesPerInterval; /// Specifies the maximum number of streams supported by the bulk endpoint. public byte BulkMaxStreams { get { return (byte) (AsUchar & 0x1F); } } /// /// Specifies a zero-based number that determines the maximum number of packets (bMaxBurst * (Mult + 1)) that can /// be sent to the endpoint within a service interval. /// public byte IsoMult { get { return (byte) (AsUchar & 0x3); } } public byte SspCompanion { get { return (byte) (AsUchar >> 7); } } } #region Opaque library handles public struct KLST_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KLST_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.LSTK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } } public struct KHOT_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KHOT_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.HOTK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } } public struct KUSB_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KUSB_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.USBK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } #region USB Shared Device Context public IntPtr GetSharedContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, KLIB_HANDLE_TYPE.USBSHAREDK); } public bool SetSharedContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, KLIB_HANDLE_TYPE.USBSHAREDK, UserContext); } public bool SetSharedCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, KLIB_HANDLE_TYPE.USBSHAREDK, CleanupCallback); } #endregion } public struct KOVL_POOL_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KOVL_POOL_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.OVLPOOLK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } } public struct KOVL_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KOVL_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.OVLK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } } public struct KSTM_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KSTM_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.STMK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } } public struct KISOCH_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KISOCH_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.ISOCHK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } } #endregion #region Internal Function Imports internal static class AllKFunctions { [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate void HotK_FreeAllDelegate(); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool HotK_FreeDelegate([In] KHOT_HANDLE Handle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool HotK_InitDelegate([Out] out KHOT_HANDLE Handle, [In] [Out] ref KHOT_PARAMS InitParams); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_CalcPacketInformationDelegate(bool IsHighSpeed, [In] ref WINUSB_PIPE_INFORMATION_EX PipeInformationEx, [Out] out KISOCH_PACKET_INFORMATION PacketInformation); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_EnumPacketsDelegate([In] KISOCH_HANDLE IsochHandle, KISOCH_ENUM_PACKETS_CB EnumPackets, uint StartPacketIndex, IntPtr UserState); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_FreeDelegate([In] KISOCH_HANDLE IsochHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_GetNumberOfPacketsDelegate([In] KISOCH_HANDLE IsochHandle, out uint NumberOfPackets); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_GetPacketDelegate([In] KISOCH_HANDLE IsochHandle, uint PacketIndex, out uint Offset, out uint Length, out uint Status); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_InitDelegate([Out] out KISOCH_HANDLE IsochHandle, [In] KUSB_HANDLE InterfaceHandle, byte PipeId, uint MaxNumberOfPackets, IntPtr TransferBuffer, uint TransferBufferSize); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_SetNumberOfPacketsDelegate([In] KISOCH_HANDLE IsochHandle, uint NumberOfPackets); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_SetPacketDelegate([In] KISOCH_HANDLE IsochHandle, uint PacketIndex, uint Offset, uint Length, uint Status); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsochK_SetPacketOffsetsDelegate([In] KISOCH_HANDLE IsochHandle, uint PacketSize); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_EnumPacketsDelegate([In] KISO_CONTEXT IsoContext, KISO_ENUM_PACKETS_CB EnumPackets, int StartPacketIndex, IntPtr UserState); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_FreeDelegate([In] KISO_CONTEXT IsoContext); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_GetPacketDelegate([In] KISO_CONTEXT IsoContext, int PacketIndex, [Out] out KISO_PACKET IsoPacket); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_InitDelegate([Out] out KISO_CONTEXT IsoContext, int NumberOfPackets, int StartFrame); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_ReUseDelegate([In] KISO_CONTEXT IsoContext); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_SetPacketDelegate([In] KISO_CONTEXT IsoContext, int PacketIndex, [In] ref KISO_PACKET IsoPacket); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool IsoK_SetPacketsDelegate([In] KISO_CONTEXT IsoContext, int PacketSize); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate void LibK_Context_FreeDelegate(); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_Context_InitDelegate(IntPtr Heap, IntPtr Reserved); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_CopyDriverAPIDelegate([Out] out KUSB_DRIVER_API DriverAPI, [In] KUSB_HANDLE UsbHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate IntPtr LibK_GetContextDelegate([In] IntPtr Handle, KLIB_HANDLE_TYPE HandleType); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate IntPtr LibK_GetDefaultContextDelegate(KLIB_HANDLE_TYPE HandleType); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_GetProcAddressDelegate(IntPtr ProcAddress, int DriverID, int FunctionID); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate void LibK_GetVersionDelegate([Out] out KLIB_VERSION Version); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_IsFunctionSupportedDelegate([In] ref KUSB_DRIVER_API DriverAPI, uint FunctionID); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_LoadDriverAPIDelegate([Out] out KUSB_DRIVER_API DriverAPI, int DriverID); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_SetCleanupCallbackDelegate([In] IntPtr Handle, KLIB_HANDLE_TYPE HandleType, KLIB_HANDLE_CLEANUP_CB CleanupCB); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_SetContextDelegate([In] IntPtr Handle, KLIB_HANDLE_TYPE HandleType, IntPtr ContextValue); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LibK_SetDefaultContextDelegate(KLIB_HANDLE_TYPE HandleType, IntPtr ContextValue); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_CountDelegate([In] KLST_HANDLE DeviceList, ref uint Count); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_CurrentDelegate([In] KLST_HANDLE DeviceList, [Out] out KLST_DEVINFO_HANDLE DeviceInfo); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_EnumerateDelegate([In] KLST_HANDLE DeviceList, KLST_ENUM_DEVINFO_CB EnumDevListCB, IntPtr Context); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_FindByVidPidDelegate([In] KLST_HANDLE DeviceList, int Vid, int Pid, [Out] out KLST_DEVINFO_HANDLE DeviceInfo); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_FreeDelegate([In] KLST_HANDLE DeviceList); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_InitDelegate([Out] out KLST_HANDLE DeviceList, KLST_FLAG Flags); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_InitExDelegate([Out] out KLST_HANDLE DeviceList, KLST_FLAG Flags, [In] ref KLST_PATTERN_MATCH PatternMatch); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LstK_MoveNextDelegate([In] KLST_HANDLE DeviceList, [Out] out KLST_DEVINFO_HANDLE DeviceInfo); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate void LstK_MoveResetDelegate([In] KLST_HANDLE DeviceList); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LUsb0_ControlTransferDelegate([In] KUSB_HANDLE InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool LUsb0_SetConfigurationDelegate([In] KUSB_HANDLE InterfaceHandle, byte ConfigurationNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_AcquireDelegate([Out] out KOVL_HANDLE OverlappedK, [In] KOVL_POOL_HANDLE PoolHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_FreeDelegate([In] KOVL_POOL_HANDLE PoolHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate IntPtr OvlK_GetEventHandleDelegate([In] KOVL_HANDLE OverlappedK); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_InitDelegate([Out] out KOVL_POOL_HANDLE PoolHandle, [In] KUSB_HANDLE UsbHandle, int MaxOverlappedCount, KOVL_POOL_FLAG Flags); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_IsCompleteDelegate([In] KOVL_HANDLE OverlappedK); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_ReleaseDelegate([In] KOVL_HANDLE OverlappedK); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_ReUseDelegate([In] KOVL_HANDLE OverlappedK); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_WaitAndReleaseDelegate([In] KOVL_HANDLE OverlappedK, int TimeoutMS, out uint TransferredLength); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_WaitDelegate([In] KOVL_HANDLE OverlappedK, int TimeoutMS, KOVL_WAIT_FLAG WaitFlags, out uint TransferredLength); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_WaitOldestDelegate([In] KOVL_POOL_HANDLE PoolHandle, [Out] out KOVL_HANDLE OverlappedK, int TimeoutMS, KOVL_WAIT_FLAG WaitFlags, out uint TransferredLength); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool OvlK_WaitOrCancelDelegate([In] KOVL_HANDLE OverlappedK, int TimeoutMS, out uint TransferredLength); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool StmK_FreeDelegate([In] KSTM_HANDLE StreamHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool StmK_InitDelegate([Out] out KSTM_HANDLE StreamHandle, [In] KUSB_HANDLE UsbHandle, byte PipeID, int MaxTransferSize, int MaxPendingTransfers, int MaxPendingIO, [In] ref KSTM_CALLBACK Callbacks, KSTM_FLAG Flags); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool StmK_ReadDelegate([In] KSTM_HANDLE StreamHandle, IntPtr Buffer, int Offset, int Length, out uint TransferredLength); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool StmK_StartDelegate([In] KSTM_HANDLE StreamHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool StmK_StopDelegate([In] KSTM_HANDLE StreamHandle, int TimeoutCancelMS); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool StmK_WriteDelegate([In] KSTM_HANDLE StreamHandle, IntPtr Buffer, int Offset, int Length, out uint TransferredLength); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool UsbK_FreeDelegate([In] KUSB_HANDLE InterfaceHandle); private static readonly IntPtr mModuleLibusbK = IntPtr.Zero; public static LibK_GetVersionDelegate LibK_GetVersion; public static LibK_GetContextDelegate LibK_GetContext; public static LibK_SetContextDelegate LibK_SetContext; public static LibK_SetCleanupCallbackDelegate LibK_SetCleanupCallback; public static LibK_LoadDriverAPIDelegate LibK_LoadDriverAPI; public static LibK_IsFunctionSupportedDelegate LibK_IsFunctionSupported; public static LibK_CopyDriverAPIDelegate LibK_CopyDriverAPI; public static LibK_GetProcAddressDelegate LibK_GetProcAddress; public static LibK_SetDefaultContextDelegate LibK_SetDefaultContext; public static LibK_GetDefaultContextDelegate LibK_GetDefaultContext; public static LibK_Context_InitDelegate LibK_Context_Init; public static LibK_Context_FreeDelegate LibK_Context_Free; public static UsbK_FreeDelegate UsbK_Free; public static LstK_InitDelegate LstK_Init; public static LstK_InitExDelegate LstK_InitEx; public static LstK_FreeDelegate LstK_Free; public static LstK_EnumerateDelegate LstK_Enumerate; public static LstK_CurrentDelegate LstK_Current; public static LstK_MoveNextDelegate LstK_MoveNext; public static LstK_MoveResetDelegate LstK_MoveReset; public static LstK_FindByVidPidDelegate LstK_FindByVidPid; public static LstK_CountDelegate LstK_Count; public static HotK_InitDelegate HotK_Init; public static HotK_FreeDelegate HotK_Free; public static HotK_FreeAllDelegate HotK_FreeAll; public static OvlK_AcquireDelegate OvlK_Acquire; public static OvlK_ReleaseDelegate OvlK_Release; public static OvlK_InitDelegate OvlK_Init; public static OvlK_FreeDelegate OvlK_Free; public static OvlK_GetEventHandleDelegate OvlK_GetEventHandle; public static OvlK_WaitDelegate OvlK_Wait; public static OvlK_WaitOldestDelegate OvlK_WaitOldest; public static OvlK_WaitOrCancelDelegate OvlK_WaitOrCancel; public static OvlK_WaitAndReleaseDelegate OvlK_WaitAndRelease; public static OvlK_IsCompleteDelegate OvlK_IsComplete; public static OvlK_ReUseDelegate OvlK_ReUse; public static StmK_InitDelegate StmK_Init; public static StmK_FreeDelegate StmK_Free; public static StmK_StartDelegate StmK_Start; public static StmK_StopDelegate StmK_Stop; public static StmK_ReadDelegate StmK_Read; public static StmK_WriteDelegate StmK_Write; public static IsoK_InitDelegate IsoK_Init; public static IsoK_FreeDelegate IsoK_Free; public static IsoK_SetPacketsDelegate IsoK_SetPackets; public static IsoK_SetPacketDelegate IsoK_SetPacket; public static IsoK_GetPacketDelegate IsoK_GetPacket; public static IsoK_EnumPacketsDelegate IsoK_EnumPackets; public static IsoK_ReUseDelegate IsoK_ReUse; public static IsochK_InitDelegate IsochK_Init; public static IsochK_FreeDelegate IsochK_Free; public static IsochK_SetPacketOffsetsDelegate IsochK_SetPacketOffsets; public static IsochK_SetPacketDelegate IsochK_SetPacket; public static IsochK_GetPacketDelegate IsochK_GetPacket; public static IsochK_EnumPacketsDelegate IsochK_EnumPackets; public static IsochK_CalcPacketInformationDelegate IsochK_CalcPacketInformation; public static IsochK_GetNumberOfPacketsDelegate IsochK_GetNumberOfPackets; public static IsochK_SetNumberOfPacketsDelegate IsochK_SetNumberOfPackets; public static LUsb0_ControlTransferDelegate LUsb0_ControlTransfer; public static LUsb0_SetConfigurationDelegate LUsb0_SetConfiguration; static AllKFunctions() { if (string.IsNullOrEmpty(AllKOptions.LIBUSBK_FULLPATH_TO_ALTERNATE_DLL)) mModuleLibusbK = LoadLibraryEx(AllKConstants.LIBUSBK_DLL, IntPtr.Zero, LoadLibraryFlags.NONE); else mModuleLibusbK = LoadLibraryEx(AllKOptions.LIBUSBK_FULLPATH_TO_ALTERNATE_DLL, IntPtr.Zero, LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH); if (mModuleLibusbK == IntPtr.Zero) throw new DllNotFoundException("libusbK.dll not found. Please install drivers/applications and retry."); LoadDynamicFunctions(); } [DllImport("kernel32.dll")] private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags); [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); private static void LoadDynamicFunctions() { LibK_GetVersion = (LibK_GetVersionDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_GetVersion"), typeof(LibK_GetVersionDelegate)); LibK_GetContext = (LibK_GetContextDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_GetContext"), typeof(LibK_GetContextDelegate)); LibK_SetContext = (LibK_SetContextDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_SetContext"), typeof(LibK_SetContextDelegate)); LibK_SetCleanupCallback = (LibK_SetCleanupCallbackDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_SetCleanupCallback"), typeof(LibK_SetCleanupCallbackDelegate)); LibK_LoadDriverAPI = (LibK_LoadDriverAPIDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_LoadDriverAPI"), typeof(LibK_LoadDriverAPIDelegate)); LibK_IsFunctionSupported = (LibK_IsFunctionSupportedDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_IsFunctionSupported"), typeof(LibK_IsFunctionSupportedDelegate)); LibK_CopyDriverAPI = (LibK_CopyDriverAPIDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_CopyDriverAPI"), typeof(LibK_CopyDriverAPIDelegate)); LibK_GetProcAddress = (LibK_GetProcAddressDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_GetProcAddress"), typeof(LibK_GetProcAddressDelegate)); LibK_SetDefaultContext = (LibK_SetDefaultContextDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_SetDefaultContext"), typeof(LibK_SetDefaultContextDelegate)); LibK_GetDefaultContext = (LibK_GetDefaultContextDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_GetDefaultContext"), typeof(LibK_GetDefaultContextDelegate)); LibK_Context_Init = (LibK_Context_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_Context_Init"), typeof(LibK_Context_InitDelegate)); LibK_Context_Free = (LibK_Context_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LibK_Context_Free"), typeof(LibK_Context_FreeDelegate)); UsbK_Free = (UsbK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "UsbK_Free"), typeof(UsbK_FreeDelegate)); LstK_Init = (LstK_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_Init"), typeof(LstK_InitDelegate)); LstK_InitEx = (LstK_InitExDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_InitEx"), typeof(LstK_InitExDelegate)); LstK_Free = (LstK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_Free"), typeof(LstK_FreeDelegate)); LstK_Enumerate = (LstK_EnumerateDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_Enumerate"), typeof(LstK_EnumerateDelegate)); LstK_Current = (LstK_CurrentDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_Current"), typeof(LstK_CurrentDelegate)); LstK_MoveNext = (LstK_MoveNextDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_MoveNext"), typeof(LstK_MoveNextDelegate)); LstK_MoveReset = (LstK_MoveResetDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_MoveReset"), typeof(LstK_MoveResetDelegate)); LstK_FindByVidPid = (LstK_FindByVidPidDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_FindByVidPid"), typeof(LstK_FindByVidPidDelegate)); LstK_Count = (LstK_CountDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LstK_Count"), typeof(LstK_CountDelegate)); HotK_Init = (HotK_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "HotK_Init"), typeof(HotK_InitDelegate)); HotK_Free = (HotK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "HotK_Free"), typeof(HotK_FreeDelegate)); HotK_FreeAll = (HotK_FreeAllDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "HotK_FreeAll"), typeof(HotK_FreeAllDelegate)); OvlK_Acquire = (OvlK_AcquireDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_Acquire"), typeof(OvlK_AcquireDelegate)); OvlK_Release = (OvlK_ReleaseDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_Release"), typeof(OvlK_ReleaseDelegate)); OvlK_Init = (OvlK_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_Init"), typeof(OvlK_InitDelegate)); OvlK_Free = (OvlK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_Free"), typeof(OvlK_FreeDelegate)); OvlK_GetEventHandle = (OvlK_GetEventHandleDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_GetEventHandle"), typeof(OvlK_GetEventHandleDelegate)); OvlK_Wait = (OvlK_WaitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_Wait"), typeof(OvlK_WaitDelegate)); OvlK_WaitOldest = (OvlK_WaitOldestDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_WaitOldest"), typeof(OvlK_WaitOldestDelegate)); OvlK_WaitOrCancel = (OvlK_WaitOrCancelDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_WaitOrCancel"), typeof(OvlK_WaitOrCancelDelegate)); OvlK_WaitAndRelease = (OvlK_WaitAndReleaseDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_WaitAndRelease"), typeof(OvlK_WaitAndReleaseDelegate)); OvlK_IsComplete = (OvlK_IsCompleteDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_IsComplete"), typeof(OvlK_IsCompleteDelegate)); OvlK_ReUse = (OvlK_ReUseDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "OvlK_ReUse"), typeof(OvlK_ReUseDelegate)); StmK_Init = (StmK_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "StmK_Init"), typeof(StmK_InitDelegate)); StmK_Free = (StmK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "StmK_Free"), typeof(StmK_FreeDelegate)); StmK_Start = (StmK_StartDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "StmK_Start"), typeof(StmK_StartDelegate)); StmK_Stop = (StmK_StopDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "StmK_Stop"), typeof(StmK_StopDelegate)); StmK_Read = (StmK_ReadDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "StmK_Read"), typeof(StmK_ReadDelegate)); StmK_Write = (StmK_WriteDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "StmK_Write"), typeof(StmK_WriteDelegate)); IsoK_Init = (IsoK_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_Init"), typeof(IsoK_InitDelegate)); IsoK_Free = (IsoK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_Free"), typeof(IsoK_FreeDelegate)); IsoK_SetPackets = (IsoK_SetPacketsDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_SetPackets"), typeof(IsoK_SetPacketsDelegate)); IsoK_SetPacket = (IsoK_SetPacketDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_SetPacket"), typeof(IsoK_SetPacketDelegate)); IsoK_GetPacket = (IsoK_GetPacketDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_GetPacket"), typeof(IsoK_GetPacketDelegate)); IsoK_EnumPackets = (IsoK_EnumPacketsDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_EnumPackets"), typeof(IsoK_EnumPacketsDelegate)); IsoK_ReUse = (IsoK_ReUseDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsoK_ReUse"), typeof(IsoK_ReUseDelegate)); IsochK_Init = (IsochK_InitDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_Init"), typeof(IsochK_InitDelegate)); IsochK_Free = (IsochK_FreeDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_Free"), typeof(IsochK_FreeDelegate)); IsochK_SetPacketOffsets = (IsochK_SetPacketOffsetsDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_SetPacketOffsets"), typeof(IsochK_SetPacketOffsetsDelegate)); IsochK_SetPacket = (IsochK_SetPacketDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_SetPacket"), typeof(IsochK_SetPacketDelegate)); IsochK_GetPacket = (IsochK_GetPacketDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_GetPacket"), typeof(IsochK_GetPacketDelegate)); IsochK_EnumPackets = (IsochK_EnumPacketsDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_EnumPackets"), typeof(IsochK_EnumPacketsDelegate)); IsochK_CalcPacketInformation = (IsochK_CalcPacketInformationDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_CalcPacketInformation"), typeof(IsochK_CalcPacketInformationDelegate)); IsochK_GetNumberOfPackets = (IsochK_GetNumberOfPacketsDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_GetNumberOfPackets"), typeof(IsochK_GetNumberOfPacketsDelegate)); IsochK_SetNumberOfPackets = (IsochK_SetNumberOfPacketsDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "IsochK_SetNumberOfPackets"), typeof(IsochK_SetNumberOfPacketsDelegate)); LUsb0_ControlTransfer = (LUsb0_ControlTransferDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LUsb0_ControlTransfer"), typeof(LUsb0_ControlTransferDelegate)); LUsb0_SetConfiguration = (LUsb0_SetConfigurationDelegate) Marshal.GetDelegateForFunctionPointer(GetProcAddress(mModuleLibusbK, "LUsb0_SetConfiguration"), typeof(LUsb0_SetConfigurationDelegate)); } [Flags] enum LoadLibraryFlags { NONE = 0, DONT_RESOLVE_DLL_REFERENCES = 0x00000001, LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010, LOAD_LIBRARY_AS_DATAFILE = 0x00000002, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040, LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020, LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 } } #endregion #region Enumerations /// Values used in the \c bmAttributes field of a \ref USB_ENDPOINT_DESCRIPTOR public enum USBD_PIPE_TYPE { /// Indicates a control endpoint UsbdPipeTypeControl, /// Indicates an isochronous endpoint UsbdPipeTypeIsochronous, /// Indicates a bulk endpoint UsbdPipeTypeBulk, /// Indicates an interrupt endpoint UsbdPipeTypeInterrupt, } /// Additional ISO transfer flags. [Flags] public enum KISO_FLAG { NONE = 0, /// Do not start the transfer immediately, instead use \ref KISO_CONTEXT::StartFrame. SET_START_FRAME = 0x00000001, } /// Handle type enumeration. public enum KLIB_HANDLE_TYPE { /// Hot plug handle. \ref KHOT_HANDLE HOTK, /// USB handle. \ref KUSB_HANDLE USBK, /// Shared USB handle. \ref KUSB_HANDLE USBSHAREDK, /// Device list handle. \ref KLST_HANDLE LSTK, /// Device info handle. \ref KLST_DEVINFO_HANDLE LSTINFOK, /// Overlapped handle. \ref KOVL_HANDLE OVLK, /// Overlapped pool handle. \ref KOVL_POOL_HANDLE OVLPOOLK, /// Pipe stream handle. \ref KSTM_HANDLE STMK, /// Pipe stream handle. \ref KSTM_HANDLE ISOCHK, /// Max handle type count. COUNT } /// Device list sync flags. [Flags] public enum KLST_SYNC_FLAG { /// Cleared/invalid state. NONE = 0, /// Unchanged state, UNCHANGED = 0x0001, /// Added (Arrival) state, ADDED = 0x0002, /// Removed (Unplugged) state, REMOVED = 0x0004, /// Connect changed state. CONNECT_CHANGE = 0x0008, /// All states. MASK = 0x000F, } /// Device list initialization flags. [Flags] public enum KLST_FLAG { /// No flags (or 0) NONE = 0, /// Enable listings for the raw device interface GUID \b only. {A5DCBF10-6530-11D2-901F-00C04FB951ED} INCLUDE_RAWGUID = 0x0001, /// List all libusbK devices including those not currently connected. INCLUDE_DISCONNECT = 0x0002, } /// bmRequest.Dir public enum BMREQUEST_DIR { HOST_TO_DEVICE = 0, DEVICE_TO_HOST = 1, } /// bmRequest.Type public enum BMREQUEST_TYPE { /// Standard request. See \ref USB_REQUEST_ENUM STANDARD = 0, /// Class-specific request. CLASS = 1, /// Vendor-specific request VENDOR = 2, } /// bmRequest.Recipient public enum BMREQUEST_RECIPIENT { /// Request is for a device. DEVICE = 0, /// Request is for an interface of a device. INTERFACE = 1, /// Request is for an endpoint of a device. ENDPOINT = 2, /// Request is for a vendor-specific purpose. OTHER = 3, } /// Values for the bits returned by the \ref USB_REQUEST_GET_STATUS request. public enum USB_GETSTATUS { /// Device is self powered SELF_POWERED = 0x01, /// Device can wake the system from a low power/sleeping state. REMOTE_WAKEUP_ENABLED = 0x02 } /// Standard USB descriptor types. For more information, see section 9-5 of the USB 3.0 specifications. public enum USB_DESCRIPTOR_TYPE { /// Device descriptor type. DEVICE = 0x01, /// Configuration descriptor type. CONFIGURATION = 0x02, /// String descriptor type. STRING = 0x03, /// Interface descriptor type. INTERFACE = 0x04, /// Endpoint descriptor type. ENDPOINT = 0x05, /// Device qualifier descriptor type. DEVICE_QUALIFIER = 0x06, /// Config power descriptor type. CONFIG_POWER = 0x07, /// Interface power descriptor type. INTERFACE_POWER = 0x08, /// Interface association descriptor type. INTERFACE_ASSOCIATION = 0x0B, /// BOS descriptor type BOS = 0x0F, /// Device capabilities descriptor type DEVICE_CAPS = 0x10, /// Superspeed endpoint companion descriptor type USB_SUPERSPEED_ENDPOINT_COMPANION = 0x30, } /// Values used in the \c bmAttributes field of a \ref USB_CONFIGURATION_DESCRIPTOR public enum USB_CONFIG_BM_ATTRIBUTE_ENUM { /// The device is powered by it's host. USB_CONFIG_BUS_POWERED = 0x80, /// The device has an external power source. USB_CONFIG_SELF_POWERED = 0x40, /// The device is capable of waking the the host from a low power/sleeping state. USB_CONFIG_REMOTE_WAKEUP = 0x20, } /// USB defined request codes public enum USB_REQUEST_ENUM { /// Request status of the specific recipient USB_REQUEST_GET_STATUS = 0x00, /// Clear or disable a specific feature USB_REQUEST_CLEAR_FEATURE = 0x01, /// Set or enable a specific feature USB_REQUEST_SET_FEATURE = 0x03, /// Set device address for all future accesses USB_REQUEST_SET_ADDRESS = 0x05, /// Get the specified descriptor USB_REQUEST_GET_DESCRIPTOR = 0x06, /// Update existing descriptors or add new descriptors USB_REQUEST_SET_DESCRIPTOR = 0x07, /// Get the current device configuration value USB_REQUEST_GET_CONFIGURATION = 0x08, /// Set device configuration USB_REQUEST_SET_CONFIGURATION = 0x09, /// Return the selected alternate setting for the specified interface USB_REQUEST_GET_INTERFACE = 0x0A, /// Select an alternate interface for the specified interface USB_REQUEST_SET_INTERFACE = 0x0B, /// Set then report an endpoint's synchronization frame USB_REQUEST_SYNC_FRAME = 0x0C, } /// USB defined class codes public enum USB_DEVICE_CLASS_ENUM { /// Reserved class USB_DEVICE_CLASS_RESERVED = 0x00, /// Audio class USB_DEVICE_CLASS_AUDIO = 0x01, /// Communications class USB_DEVICE_CLASS_COMMUNICATIONS = 0x02, /// Human Interface Device class USB_DEVICE_CLASS_HUMAN_INTERFACE = 0x03, /// Imaging class USB_DEVICE_CLASS_IMAGING = 0x06, /// Printer class USB_DEVICE_CLASS_PRINTER = 0x07, /// Mass storage class USB_DEVICE_CLASS_STORAGE = 0x08, /// Hub class USB_DEVICE_CLASS_HUB = 0x09, /// vendor-specific class USB_DEVICE_CLASS_VENDOR_SPECIFIC = 0xFF, } /// USB BOS capability types public enum BOS_CAPABILITY_TYPE { /// Wireless USB device capability. WIRELESS_USB_DEVICE_CAPABILITY = 0x01, /// USB 2.0 extensions. USB_2_0_EXTENSION = 0x02, /// SuperSpeed USB device capability. SS_USB_DEVICE_CAPABILITY = 0x03, /// Container ID type. CONTAINER_ID = 0x04, /// Platform specific capability. PLATFORM = 0x05, /// Defines the various PD Capabilities of this device. BOS_POWER_DELIVERY_CAPABILITY = 0x06, /// Provides information on each battery supported by the device. BOS_BATTERY_INFO_CAPABILITY = 0x07, /// The consumer characteristics of a port on the device. BOS_PD_CONSUMER_PORT_CAPABILITY = 0x08, /// The provider characteristics of a port on the device. BOS_PD_PROVIDER_PORT_CAPABILITY = 0x09, /// Defines the set of SuperSpeed Plus USB specific device level capabilities. BOS_SUPERSPEED_PLUS = 0x0A, /// Precision Time Measurement (PTM) Capability Descriptor. BOS_PRECISION_TIME_MEASUREMENT = 0x0B, /// Defines the set of Wireless USB 1.1-specific device level capabilities. BOS_WIRELESS_USB_EXT = 0x0C, /// Billboard capability. BOS_BILLBOARD = 0x0D, /// Authentication Capability Descriptor. BOS_AUTHENTICATION = 0x0E, /// Billboard Ex capability. BOS_BILLBOARD_EX = 0x0F, /// Summarizes configuration information for a function implemented by the device. BOS_CONFIGURATION_SUMMARY = 0x10, } /// Microsoft feature descriptor types. public enum MSOS_FEATURE_TYPE { /// Microsoft OS V1.0 compatible IDs descriptor V1_EXTENDED_COMPAT_ID = 0x0004, /// Microsoft OS V1.0 extended properties descriptor V1_EXTENDED_PROPS = 0x0005, /// Microsoft OS V2.0 descriptor set V2_DESCRIPTOR_SET = 0x0007, } /// Microsoft OS 2.0 descriptor wDescriptorType values public enum MSOSV2_DESCRIPTOR_TYPE { /// The MS OS 2.0 descriptor set header. SET_HEADER_DESCRIPTOR = 0x00, /// Microsoft OS 2.0 configuration subset header. SUBSET_HEADER_CONFIGURATION = 0x01, /// Microsoft OS 2.0 function subset header. SUBSET_HEADER_FUNCTION = 0x02, /// Microsoft OS 2.0 compatible ID descriptor. FEATURE_COMPATIBLE_ID = 0x03, /// Microsoft OS 2.0 registry property descriptor. FEATURE_REG_PROPERTY = 0x04, /// Microsoft OS 2.0 minimum USB resume time descriptor. FEATURE_MIN_RESUME_TIME = 0x05, /// Microsoft OS 2.0 model ID descriptor. FEATURE_MODEL_ID = 0x06, /// Microsoft OS 2.0 CCGP device descriptor. FEATURE_CCGP_DEVICE = 0x07, /// Microsoft OS 2.0 vendor revision descriptor. FEATURE_VENDOR_REVISION = 0x08, } /// Usb handle specific properties that can be retrieved with \ref UsbK_GetProperty. public enum KUSB_PROPERTY { /// Get the internal device file handle used for operations such as GetOverlappedResult or DeviceIoControl. DEVICE_FILE_HANDLE, COUNT } /// Supported driver id enumeration. public enum KUSB_DRVID { /// libusbK.sys driver ID LIBUSBK, /// libusb0.sys driver ID LIBUSB0, /// WinUSB.sys driver ID WINUSB, /// libusb0.sys filter driver ID LIBUSB0_FILTER, /// Supported driver count COUNT } /// Supported function id enumeration. public enum KUSB_FNID { /// \ref UsbK_Init dynamic driver function id. Init, /// \ref UsbK_Free dynamic driver function id. Free, /// \ref UsbK_ClaimInterface dynamic driver function id. ClaimInterface, /// \ref UsbK_ReleaseInterface dynamic driver function id. ReleaseInterface, /// \ref UsbK_SetAltInterface dynamic driver function id. SetAltInterface, /// \ref UsbK_GetAltInterface dynamic driver function id. GetAltInterface, /// \ref UsbK_GetDescriptor dynamic driver function id. GetDescriptor, /// \ref UsbK_ControlTransfer dynamic driver function id. ControlTransfer, /// \ref UsbK_SetPowerPolicy dynamic driver function id. SetPowerPolicy, /// \ref UsbK_GetPowerPolicy dynamic driver function id. GetPowerPolicy, /// \ref UsbK_SetConfiguration dynamic driver function id. SetConfiguration, /// \ref UsbK_GetConfiguration dynamic driver function id. GetConfiguration, /// \ref UsbK_ResetDevice dynamic driver function id. ResetDevice, /// \ref UsbK_Initialize dynamic driver function id. Initialize, /// \ref UsbK_SelectInterface dynamic driver function id. SelectInterface, /// \ref UsbK_GetAssociatedInterface dynamic driver function id. GetAssociatedInterface, /// \ref UsbK_Clone dynamic driver function id. Clone, /// \ref UsbK_QueryInterfaceSettings dynamic driver function id. QueryInterfaceSettings, /// \ref UsbK_QueryDeviceInformation dynamic driver function id. QueryDeviceInformation, /// \ref UsbK_SetCurrentAlternateSetting dynamic driver function id. SetCurrentAlternateSetting, /// \ref UsbK_GetCurrentAlternateSetting dynamic driver function id. GetCurrentAlternateSetting, /// \ref UsbK_QueryPipe dynamic driver function id. QueryPipe, /// \ref UsbK_SetPipePolicy dynamic driver function id. SetPipePolicy, /// \ref UsbK_GetPipePolicy dynamic driver function id. GetPipePolicy, /// \ref UsbK_ReadPipe dynamic driver function id. ReadPipe, /// \ref UsbK_WritePipe dynamic driver function id. WritePipe, /// \ref UsbK_ResetPipe dynamic driver function id. ResetPipe, /// \ref UsbK_AbortPipe dynamic driver function id. AbortPipe, /// \ref UsbK_FlushPipe dynamic driver function id. FlushPipe, /// \ref UsbK_IsoReadPipe dynamic driver function id. IsoReadPipe, /// \ref UsbK_IsoWritePipe dynamic driver function id. IsoWritePipe, /// \ref UsbK_GetCurrentFrameNumber dynamic driver function id. GetCurrentFrameNumber, /// \ref UsbK_GetOverlappedResult dynamic driver function id. GetOverlappedResult, /// \ref UsbK_GetProperty dynamic driver function id. GetProperty, /// \ref UsbK_IsochReadPipe dynamic driver function id. IsochReadPipe, /// \ref UsbK_IsochWritePipe dynamic driver function id. IsochWritePipe, /// \ref UsbK_QueryPipeEx dynamic driver function id. QueryPipeEx, /// \ref UsbK_GetSuperSpeedPipeCompanionDescriptor dynamic driver function id. GetSuperSpeedPipeCompanionDescriptor, /// Supported function count COUNT, } /// Hot plug config flags. [Flags] public enum KHOT_FLAG { /// No flags (or 0) NONE, /// Notify all devices which match upon a succuessful call to \ref HotK_Init. PLUG_ALL_ON_INIT = 0x0001, /// Allow other \ref KHOT_HANDLE instances to consume this match. PASS_DUPE_INSTANCE = 0x0002, /// If a \c UserHwnd is specified, use \c PostMessage instead of \c SendMessage. POST_USER_MESSAGE = 0x0004, } /// \c WaitFlags used by \ref OvlK_Wait. [Flags] public enum KOVL_WAIT_FLAG { /// Do not perform any additional actions upon exiting \ref OvlK_Wait. NONE = 0, /// If the i/o operation completes successfully, release the OverlappedK back to it's pool. RELEASE_ON_SUCCESS = 0x0001, /// If the i/o operation fails, release the OverlappedK back to it's pool. RELEASE_ON_FAIL = 0x0002, /// /// If the i/o operation fails or completes successfully, release the OverlappedK back to its pool. Perform no /// actions if it times-out. /// RELEASE_ON_SUCCESS_FAIL = 0x0003, /// If the i/o operation times-out cancel it, but do not release the OverlappedK back to its pool. CANCEL_ON_TIMEOUT = 0x0004, /// If the i/o operation times-out, cancel it and release the OverlappedK back to its pool. RELEASE_ON_TIMEOUT = 0x000C, /// /// Always release the OverlappedK back to its pool. If the operation timed-out, cancel it before releasing back /// to its pool. /// RELEASE_ALWAYS = 0x000F, /// /// Uses alterable wait functions. See /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms687036%28v=vs.85%29.aspx /// ALERTABLE = 0x0010, } /// \c Overlapped pool config flags. [Flags] public enum KOVL_POOL_FLAG { NONE = 0, } /// Stream config flags. [Flags] public enum KSTM_FLAG : uint { /// None NONE = 0, NO_PARTIAL_XFERS = 0x00100000, USE_TIMEOUT = 0x80000000, TIMEOUT_MASK = 0x0001FFFF } /// Stream config flags. public enum KSTM_COMPLETE_RESULT { /// Valid VALID = 0, /// Invalid INVALID, } #endregion #region Structs /// /// The \c WINUSB_PIPE_INFORMATION structure contains pipe information that the \ref UsbK_QueryPipe routine /// retrieves. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct WINUSB_PIPE_INFORMATION { /// A \c USBD_PIPE_TYPE enumeration value that specifies the pipe type public USBD_PIPE_TYPE PipeType; /// The pipe identifier (ID) public byte PipeId; /// The maximum size, in bytes, of the packets that are transmitted on the pipe public ushort MaximumPacketSize; /// The pipe interval public byte Interval; public override string ToString() { return string.Format("PipeType: {0}\nPipeId: {1}\nMaximumPacketSize: {2}\nInterval: {3}\n", PipeType, PipeId.ToString("X2") + "h", MaximumPacketSize, Interval.ToString("X2") + "h"); } } /// /// The \c WINUSB_PIPE_INFORMATION_EX structure contains pipe information that the \ref UsbK_QueryPipeEx routine /// retrieves. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct WINUSB_PIPE_INFORMATION_EX { /// A \c USBD_PIPE_TYPE enumeration value that specifies the pipe type public USBD_PIPE_TYPE PipeType; /// The pipe identifier (ID) public byte PipeId; /// The maximum size, in bytes, of the packets that are transmitted on the pipe public ushort MaximumPacketSize; /// The pipe interval public byte Interval; /// The maximum number of bytes that can be transmitted in single interval. public uint MaximumBytesPerInterval; public override string ToString() { return string.Format("PipeType: {0}\nPipeId: {1}\nMaximumPacketSize: {2}\nInterval: {3}\nMaximumBytesPerInterval: {4}\n", PipeType, PipeId.ToString("X2") + "h", MaximumPacketSize, Interval.ToString("X2") + "h", MaximumBytesPerInterval); } } /// The \c WINUSB_SETUP_PACKET structure describes a USB setup packet. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct WINUSB_SETUP_PACKET { /// /// The request type. The values that are assigned to this member are defined in Table 9.2 of section 9.3 of the /// Universal Serial Bus (USB) specification (www.usb.org). /// public byte RequestType; /// /// The device request. The values that are assigned to this member are defined in Table 9.3 of section 9.4 of the /// Universal Serial Bus (USB) specification. /// public byte Request; /// /// The meaning of this member varies according to the request. For an explanation of this member, see the /// Universal Serial Bus (USB) specification. /// public ushort Value; /// /// The meaning of this member varies according to the request. For an explanation of this member, see the /// Universal Serial Bus (USB) specification. /// public ushort Index; /// The number of bytes to transfer. (not including the \c WINUSB_SETUP_PACKET itself) public ushort Length; public override string ToString() { return string.Format("RequestType: {0}\nRequest: {1}\nValue: {2}\nIndex: {3}\nLength: {4}\n", RequestType.ToString("X2") + "h", Request.ToString("X2") + "h", Value.ToString("X4") + "h", Index.ToString("X4") + "h", Length); } } /// Structure describing an isochronous transfer packet for libusbK. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct KISO_PACKET { /// /// Specifies the offset, in bytes, of the buffer for this packet from the beginning of the entire isochronous /// transfer data buffer. /// public uint Offset; /// /// Set by the host controller to indicate the actual number of bytes received by the device for isochronous IN /// transfers. Length not used for isochronous OUT transfers. /// public ushort Length; /// /// Contains the 16 least significant USBD status bits, on return from the host controller driver, of this /// transfer packet. /// public ushort Status; public override string ToString() { return string.Format("Offset: {0}\nLength: {1}\nStatus: {2}\n", Offset, Length, Status.ToString("X4") + "h"); } } /// Structure describing an isochronous transfer packet for winusb. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct KISO_WUSB_PACKET { /// /// Specifies the offset, in bytes, of the buffer for this packet from the beginning of the entire isochronous /// transfer data buffer. /// public uint Offset; /// /// Set by the host controller to indicate the actual number of bytes received by the device for isochronous IN /// transfers. Length not used for isochronous OUT transfers. /// public uint Length; /// /// Contains the 16 least significant USBD status bits, on return from the host controller driver, of this /// transfer packet. /// public uint Status; public override string ToString() { return string.Format("Offset: {0}\nLength: {1}\nStatus: {2}\n", Offset, Length, Status); } } [StructLayout(LayoutKind.Sequential)] public struct KISO_CONTEXT { private readonly IntPtr mHandlePtr; public KISO_CONTEXT(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } /// KISO_CONTEXT_MAP is used for calculating field offsets only [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] private struct KISO_CONTEXT_MAP { /// Additional ISO transfer flags. See \ref KISO_FLAG. private readonly KISO_FLAG Flags; /// Specifies the frame number that the transfer should begin on (0 for ASAP). private readonly uint StartFrame; /// /// Contains the number of packets that completed with an error condition on return from the host controller /// driver. /// private readonly short ErrorCount; /// Specifies the number of packets that are described by the variable-length array member \c IsoPacket. private readonly short NumberOfPackets; /// Contains the URB Hdr.Status value on return from the host controller driver. private readonly uint UrbHdrStatus; } private static readonly int ofsFlags = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "Flags").ToInt32(); private static readonly int ofsStartFrame = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "StartFrame").ToInt32(); private static readonly int ofsErrorCount = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "ErrorCount").ToInt32(); private static readonly int ofsNumberOfPackets = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "NumberOfPackets").ToInt32(); private static readonly int ofsUrbHdrStatus = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "UrbHdrStatus").ToInt32(); /// Additional ISO transfer flags. See \ref KISO_FLAG. public KISO_FLAG Flags { get { return (KISO_FLAG) Marshal.ReadInt32(mHandlePtr, ofsFlags); } } /// Specifies the frame number that the transfer should begin on (0 for ASAP). public uint StartFrame { get { return (uint) Marshal.ReadInt32(mHandlePtr, ofsStartFrame); } } /// /// Contains the number of packets that completed with an error condition on return from the host controller /// driver. /// public short ErrorCount { get { return Marshal.ReadInt16(mHandlePtr, ofsErrorCount); } } /// Specifies the number of packets that are described by the variable-length array member \c IsoPacket. public short NumberOfPackets { get { return Marshal.ReadInt16(mHandlePtr, ofsNumberOfPackets); } } /// Contains the URB Hdr.Status value on return from the host controller driver. public uint UrbHdrStatus { get { return (uint) Marshal.ReadInt32(mHandlePtr, ofsUrbHdrStatus); } } public override string ToString() { return string.Format("Flags: {0}\nStartFrame: {1}\nErrorCount: {2}\nNumberOfPackets: {3}\nUrbHdrStatus: {4}\n", Flags.ToString(), StartFrame, ErrorCount, NumberOfPackets, UrbHdrStatus.ToString("X8") + "h"); } } /// Structure describing additional information about how an isochronous pipe transfers data. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct KISOCH_PACKET_INFORMATION { /// Number of ISO packets transferred per whole USB frame (1 millisecond). public uint PacketsPerFrame; /// How often a pipe transfers data. public uint PollingPeriodMicroseconds; /// Number of bytes transferred per millisecond (or whole frame). public uint BytesPerMillisecond; public override string ToString() { return string.Format("PacketsPerFrame: {0}\nPollingPeriodMicroseconds: {1}\nBytesPerMillisecond: {2}\n", PacketsPerFrame, PollingPeriodMicroseconds, BytesPerMillisecond); } } /// libusbK verson information structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct KLIB_VERSION { /// Major version number. public int Major; /// Minor version number. public int Minor; /// Micro version number. public int Micro; /// Nano version number. public int Nano; public override string ToString() { return string.Format("Major: {0}\nMinor: {1}\nMicro: {2}\nNano: {3}\n", Major, Minor, Micro, Nano); } } /// Common usb device information structure [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct KLST_DEV_COMMON_INFO { /// VendorID parsed from \ref KLST_DEVINFO::DeviceID public int Vid; /// ProductID parsed from \ref KLST_DEVINFO::DeviceID public int Pid; /// /// Composite interface number parsed from \ref KLST_DEVINFO::DeviceID. Set to \b -1 for devices that do not have /// the composite parent driver. /// public int MI; // An ID that uniquely identifies a USB device. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] public string InstanceID; public override string ToString() { return string.Format("Vid: {0}\nPid: {1}\nMI: {2}\nInstanceID: {3}\n", Vid.ToString("X4") + "h", Pid.ToString("X4") + "h", MI.ToString("X2") + "h", InstanceID); } } [StructLayout(LayoutKind.Sequential)] public struct KLST_DEVINFO_HANDLE : IKLIB_HANDLE { private readonly IntPtr mHandlePtr; public KLST_DEVINFO_HANDLE(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } public KLIB_HANDLE_TYPE HandleType { get { return KLIB_HANDLE_TYPE.LSTINFOK; } } public IntPtr GetContext() { return AllKFunctions.LibK_GetContext(mHandlePtr, HandleType); } public bool SetContext(IntPtr UserContext) { return AllKFunctions.LibK_SetContext(mHandlePtr, HandleType, UserContext); } public bool SetCleanupCallback(KLIB_HANDLE_CLEANUP_CB CleanupCallback) { return AllKFunctions.LibK_SetCleanupCallback(mHandlePtr, HandleType, CleanupCallback); } /// KLST_DEVINFO_MAP is used for calculating field offsets only [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] private struct KLST_DEVINFO_MAP { /// Common usb device information private readonly KLST_DEV_COMMON_INFO Common; /// Driver id this device element is using private readonly int DriverID; /// Device interface GUID [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string DeviceInterfaceGUID; /// Device instance ID. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string DeviceID; /// Class GUID. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string ClassGUID; /// Manufacturer name as specified in the INF file. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string Mfg; /// Device description as specified in the INF file. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string DeviceDesc; /// Driver service name. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string Service; /// Unique identifier. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string SymbolicLink; /// physical device filename used with the Windows \c CreateFile() [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string DevicePath; /// libusb-win32 filter index id. private readonly int LUsb0FilterIndex; /// Indicates the devices connection state. private readonly bool Connected; /// Synchronization flags. (internal use only) private readonly KLST_SYNC_FLAG SyncFlags; private readonly int BusNumber; private readonly int DeviceAddress; /// /// If the the device is serialized, represents the string value of \ref USB_DEVICE_DESCRIPTOR::iSerialNumber. For /// Devices without a \b iSerialNumber, represents the unique \b InstanceID assigned by \b Windows. /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] private readonly string SerialNumber; } private static readonly int ofsCommon = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "Common").ToInt32(); private static readonly int ofsDriverID = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "DriverID").ToInt32(); private static readonly int ofsDeviceInterfaceGUID = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "DeviceInterfaceGUID").ToInt32(); private static readonly int ofsDeviceID = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "DeviceID").ToInt32(); private static readonly int ofsClassGUID = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "ClassGUID").ToInt32(); private static readonly int ofsMfg = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "Mfg").ToInt32(); private static readonly int ofsDeviceDesc = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "DeviceDesc").ToInt32(); private static readonly int ofsService = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "Service").ToInt32(); private static readonly int ofsSymbolicLink = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "SymbolicLink").ToInt32(); private static readonly int ofsDevicePath = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "DevicePath").ToInt32(); private static readonly int ofsLUsb0FilterIndex = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "LUsb0FilterIndex").ToInt32(); private static readonly int ofsConnected = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "Connected").ToInt32(); private static readonly int ofsSyncFlags = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "SyncFlags").ToInt32(); private static readonly int ofsBusNumber = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "BusNumber").ToInt32(); private static readonly int ofsDeviceAddress = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "DeviceAddress").ToInt32(); private static readonly int ofsSerialNumber = Marshal.OffsetOf(typeof(KLST_DEVINFO_MAP), "SerialNumber").ToInt32(); /// Common usb device information public KLST_DEV_COMMON_INFO Common { get { return (KLST_DEV_COMMON_INFO) Marshal.PtrToStructure(new IntPtr(mHandlePtr.ToInt64() + ofsCommon), typeof(KLST_DEV_COMMON_INFO)); } } /// Driver id this device element is using public int DriverID { get { return Marshal.ReadInt32(mHandlePtr, ofsDriverID); } } /// Device interface GUID public string DeviceInterfaceGUID { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsDeviceInterfaceGUID)); } } /// Device instance ID. public string DeviceID { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsDeviceID)); } } /// Class GUID. public string ClassGUID { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsClassGUID)); } } /// Manufacturer name as specified in the INF file. public string Mfg { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsMfg)); } } /// Device description as specified in the INF file. public string DeviceDesc { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsDeviceDesc)); } } /// Driver service name. public string Service { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsService)); } } /// Unique identifier. public string SymbolicLink { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsSymbolicLink)); } } /// physical device filename used with the Windows \c CreateFile() public string DevicePath { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsDevicePath)); } } /// libusb-win32 filter index id. public int LUsb0FilterIndex { get { return Marshal.ReadInt32(mHandlePtr, ofsLUsb0FilterIndex); } } /// Indicates the devices connection state. public bool Connected { get { return Marshal.ReadInt32(mHandlePtr, ofsConnected) != 0; } } /// Synchronization flags. (internal use only) public KLST_SYNC_FLAG SyncFlags { get { return (KLST_SYNC_FLAG) Marshal.ReadInt32(mHandlePtr, ofsSyncFlags); } } public int BusNumber { get { return Marshal.ReadInt32(mHandlePtr, ofsBusNumber); } } public int DeviceAddress { get { return Marshal.ReadInt32(mHandlePtr, ofsDeviceAddress); } } /// /// If the the device is serialized, represents the string value of \ref USB_DEVICE_DESCRIPTOR::iSerialNumber. For /// Devices without a \b iSerialNumber, represents the unique \b InstanceID assigned by \b Windows. /// public string SerialNumber { get { return Marshal.PtrToStringAnsi(new IntPtr(mHandlePtr.ToInt64() + ofsSerialNumber)); } } public override string ToString() { return string.Format("DriverID: {0}\nDeviceInterfaceGUID: {1}\nDeviceID: {2}\nClassGUID: {3}\nMfg: {4}\nDeviceDesc: {5}\nService: {6}\nSymbolicLink: {7}\nDevicePath: {8}\nLUsb0FilterIndex: {9}\nConnected: {10}\nSyncFlags: {11}\nBusNumber: {12}\nDeviceAddress: {13}\nSerialNumber: {14}\n", DriverID, DeviceInterfaceGUID, DeviceID, ClassGUID, Mfg, DeviceDesc, Service, SymbolicLink, DevicePath, LUsb0FilterIndex, Connected, SyncFlags.ToString(), BusNumber, DeviceAddress, SerialNumber); } } /// Device list/hot-plug pattern match structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 1024)] public struct KLST_PATTERN_MATCH { /// Pattern match a device instance id. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] public string DeviceID; /// Pattern match a device interface guid. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] public string DeviceInterfaceGUID; /// Pattern match a symbolic link. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] public string ClassGUID; public override string ToString() { return string.Format("DeviceID: {0}\nDeviceInterfaceGUID: {1}\nClassGUID: {2}\n", DeviceID, DeviceInterfaceGUID, ClassGUID); } } /// A structure representing the standard USB device descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_DEVICE_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// USB specification release number in binary-coded decimal. public ushort bcdUSB; /// USB-IF class code for the device public byte bDeviceClass; /// USB-IF subclass code for the device public byte bDeviceSubClass; /// USB-IF protocol code for the device public byte bDeviceProtocol; /// Maximum packet size for control endpoint 0 public byte bMaxPacketSize0; /// USB-IF vendor ID public ushort idVendor; /// USB-IF product ID public ushort idProduct; /// Device release number in binary-coded decimal public ushort bcdDevice; /// Index of string descriptor describing manufacturer public byte iManufacturer; /// Index of string descriptor describing product public byte iProduct; /// Index of string descriptor containing device serial number public byte iSerialNumber; /// Number of possible configurations public byte bNumConfigurations; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\nbcdUSB: {2}\nbDeviceClass: {3}\nbDeviceSubClass: {4}\nbDeviceProtocol: {5}\nbMaxPacketSize0: {6}\nidVendor: {7}\nidProduct: {8}\nbcdDevice: {9}\niManufacturer: {10}\niProduct: {11}\niSerialNumber: {12}\nbNumConfigurations: {13}\n", bLength, bDescriptorType.ToString("X2") + "h", bcdUSB.ToString("X4") + "h", bDeviceClass.ToString("X2") + "h", bDeviceSubClass.ToString("X2") + "h", bDeviceProtocol.ToString("X2") + "h", bMaxPacketSize0, idVendor.ToString("X4") + "h", idProduct.ToString("X4") + "h", bcdDevice.ToString("X4") + "h", iManufacturer, iProduct, iSerialNumber, bNumConfigurations); } } /// A structure representing the standard USB endpoint descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_ENDPOINT_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// The address of the endpoint described by this descriptor. public byte bEndpointAddress; /// Attributes which apply to the endpoint when it is configured using the bConfigurationValue. public byte bmAttributes; /// Maximum packet size this endpoint is capable of sending/receiving. public ushort wMaxPacketSize; /// Interval for polling endpoint for data transfers. public byte bInterval; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\nbEndpointAddress: {2}\nbmAttributes: {3}\nwMaxPacketSize: {4}\nbInterval: {5}\n", bLength, bDescriptorType.ToString("X2") + "h", bEndpointAddress.ToString("X2") + "h", bmAttributes.ToString("X2") + "h", wMaxPacketSize, bInterval); } } /// BOS device capability descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_DEV_CAPABILITY_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Capability type public byte bDevCapabilityType; /// Capability Data } /// USB 3.0 and USB 2.0 LPM Binary Device Object Store (BOS). [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Length of this descriptor and all sub descriptors public ushort wTotalLength; /// Number of device capability descriptors public byte bNumDeviceCaps; } /// USB 2.0 Extension descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_USB_2_0_EXTENSION_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Capability type. See \ref BOS_CAPABILITY_TYPE public byte bDevCapabilityType; /// Bitmap encoding of supported device level features. public uint bmAttributes; } /// SuperSpeed Device Capability Descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_SS_USB_DEVICE_CAPABILITY_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Capability type. See \ref BOS_CAPABILITY_TYPE public byte bDevCapabilityType; /// Bitmap encoding of supported device level features. public byte bmAttributes; /// Bitmap encoding of the supported speeds. public ushort wSpeedSupported; /// The lowest speed at which all the functionality supported by the device is available to the user public byte bFunctionalitySupport; /// U1 Device Exit Latency. Worst-case latency to transition from U1 to U0. public byte bU1DevExitLat; /// U2 Device Exit Latency. Worst-case latency to transition from U2 to U0. public ushort bU2DevExitLat; } /// Container ID Descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_CONTAINER_ID_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Capability type. See \ref BOS_CAPABILITY_TYPE public byte bDevCapabilityType; // Reserved. public byte bReserved; /// This is a 128-bit number that is used to uniquely identify the device instance across all modes of operation. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] ContainerID; } /// Platform specific capabilities [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_PLATFORM_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; // Capability type. See \ref BOS_CAPABILITY_TYPE public byte bDevCapabilityType; /// Reserved public byte bReserved; /// A 128-bit number that uniquely identifies a platform-specific capability of the device. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] PlatformCapabilityUUID; /// Capability Data } /// This structure represents the windows version records that follow a BOS windows platform descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct BOS_WINDOWS_PLATFORM_VERSION { /// Minimum version of Windows public uint dwWindowsVersion; /// The length, in bytes of the MS OS 2.0 descriptor set. public ushort wMSOSDescriptorSetTotalLength; /// Vendor defined code. public byte bMS_VendorCode; /// Alternate enumeration indicator. public byte bAltEnumCode; } /// Special Microsoft string descriptor used to indicate that a device supports Microsoft OS V1.0 descriptors. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_MSOSV1_STRING_DESCRIPTOR { /// Size of this descriptor. Shall always be 18 bytes public byte bLength; /// Descriptor type (0x03) public byte bDescriptorType; /// Microsoft signature. Shall always be "MSFT100" [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] qwSignature; /// Vendor specific vendor code public byte bMS_VendorCode; /// Padding public byte bPad; } // !The extended compat ID OS descriptor has two components: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV1_EXTENDED_COMPAT_ID_DESCRIPTOR { /// The length, in bytes, of the complete extended compat ID descriptor public uint dwLength; /// The descriptor’s version number, in binary coded decimal (BCD) format public ushort bcdVersion; /// An index that identifies the particular OS feature descriptor public ushort wIndex; /// The number of custom property sections public byte bCount; /// Reserved [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public byte[] Rsvd; } /// A function section defines the compatible ID and a subcompatible ID for a specified interface or function. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV1_FUNCTION_DESCRIPTOR { /// The interface or function number public byte bFirstInterfaceNumber; /// Reserved [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public byte[] Rsvd1; /// The function’s compatible ID [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] CompatibleID; /// The function’s subcompatible ID [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] SubCompatibleID; /// Reserved [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] Rsvd2; } // !The extended properties OS descriptor is a Microsoft OS feature descriptor that can be used to store vendor-specific property data. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV1_EXTENDED_PROP_DESCRIPTOR { /// The length, in bytes, of the complete extended prop descriptor public uint dwLength; /// The descriptor’s version number, in binary coded decimal (BCD) format public ushort bcdVersion; /// The index for extended properties OS descriptors public ushort wIndex; /// The number of custom property sections that follow this header section public ushort wCount; /// Placeholder for \b wCount number of custom properties. See \ref MSOSV1_CUSTOM_PROP_DESCRIPTOR and \ref MSOS_CUSTOM_PROP_ELEMENT } /// A custom property section contains the information for a single property [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV1_CUSTOM_PROP_DESCRIPTOR { /// The size of this custom properties section public uint dwSize; /// The type of data associated with the section public uint dwPropertyDataType; /// Placeholder for variable length property name and data field. see \ref MSOS_CUSTOM_PROP_ELEMENT } /// /// Helper structure for parsing a /ref MSOSV1_CUSTOM_PROP_DESCRIPTOR or a \ref /// MSOSV2_FEATURE_REG_PROPERTY_DESCRIPTOR /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOS_CUSTOM_PROP_ELEMENT { public ushort wPropertyNameLength; public IntPtr pPropertyName; public ushort wPropertyDataLength; public IntPtr pPropertyData; } /// All MS OS V2.0 descriptors start with these two fields. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_COMMON_DESCRIPTOR { /// The length, in bytes, of this descriptor. public ushort wLength; /// See \ref MSOSV2_DESCRIPTOR_TYPE public ushort wDescriptorType; } /// Microsoft OS 2.0 descriptor set header [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_SET_HEADER_DESCRIPTOR { /// The length, in bytes, of this header. Shall be set to 10. public ushort wLength; /// \ref SET_HEADER_DESCRIPTOR public ushort wDescriptorType; /// Windows version. public uint dwWindowsVersion; /// /// The size of entire MS OS 2.0 descriptor set. The value shall match the value in the descriptor set information /// structure. See \ref BOS_WINDOWS_PLATFORM_VERSION::wMSOSDescriptorSetTotalLength /// public ushort wTotalLength; } /// Microsoft OS 2.0 configuration subset header [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_SUBSET_HEADER_CONFIGURATION_DESCRIPTOR { /// The length, in bytes, of this subset header. Shall be set to 8. public ushort wLength; /// \ref SUBSET_HEADER_CONFIGURATION public ushort wDescriptorType; /// The configuration value for the USB configuration to which this subset applies. public byte bConfigurationValue; /// Reserved public byte bReserved; /// The size of entire configuration subset including this header. public ushort wTotalLength; } /// Microsoft OS 2.0 function subset header [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_SUBSET_HEADER_FUNCTION_DESCRIPTOR { /// The length, in bytes, of this subset header. Shall be set to 8. public ushort wLength; /// \ref SUBSET_HEADER_FUNCTION public ushort wDescriptorType; /// The interface number for the first interface of the function to which this subset applies. public byte bFirstInterface; /// Reserved public byte bReserved; /// The size of entire function subset including this header. public ushort wSubsetLength; } /// Microsoft OS 2.0 compatible ID descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_FEATURE_COMPATBLE_ID_DESCRIPTOR { /// The length, bytes, of the compatible ID descriptor including value descriptors. Shall be set to 20. public ushort wLength; /// \ref FEATURE_COMPATIBLE_ID public ushort wDescriptorType; /// Compatible ID String [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] CompatibleID; /// Sub-compatible ID String [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] SubCompatibleID; } /// Microsoft OS 2.0 registry property descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_FEATURE_REG_PROPERTY_DESCRIPTOR { /// The length, in bytes, of this descriptor. public ushort wLength; /// \ref FEATURE_REG_PROPERTY public ushort wDescriptorType; /// The type of data associated with the section public ushort wPropertyDataType; /// Placeholder for variable length property name and data field. see \ref MSOS_CUSTOM_PROP_ELEMENT } /// Microsoft OS 2.0 minimum USB resume time descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_FEATURE_MIN_RESUME_TIME_DESCRIPTOR { /// The length, in bytes, of this descriptor. Shall be set to 6. public ushort wLength; /// \ref FEATURE_MIN_RESUME_TIME public ushort wDescriptorType; /// The number of milliseconds the device requires to recover from port resume. (Valid values are 0 to 10) public byte bResumeRecoveryTime; /// The number of milliseconds the device requires resume signaling to be asserted. (Valid values 1 to 20) public byte bResumeSignalingTime; } /// Microsoft OS 2.0 model ID descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_FEATURE_MODEL_ID_DESCRIPTOR { /// The length, in bytes, of this descriptor. Shall be set to 20. public ushort wLength; /// \ref FEATURE_MODEL_ID public ushort wDescriptorType; /// This is a 128-bit number that uniquely identifies a physical device. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] ModelID; } /// Microsoft OS 2.0 CCGP device descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_FEATURE_CCGP_DESCRIPTOR { /// The length, in bytes, of this descriptor. Shall be set to 4. public ushort wLength; /// \ref FEATURE_CCGP_DEVICE public ushort wDescriptorType; } /// Microsoft OS 2.0 vendor revision descriptor [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct MSOSV2_FEATURE_VENDOR_REVISION_DESCRIPTOR { /// The length, in bytes, of this descriptor. Shall be set to 6. public ushort wLength; /// \ref FEATURE_VENDOR_REVISION public ushort wDescriptorType; /// Revision number associated with the descriptor set. public ushort VendorRevision; } /// A structure representing the standard USB configuration descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_CONFIGURATION_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Total length of data returned for this configuration public ushort wTotalLength; /// Number of interfaces supported by this configuration public byte bNumInterfaces; /// Identifier value for this configuration public byte bConfigurationValue; /// Index of string descriptor describing this configuration public byte iConfiguration; /// Configuration characteristics public byte bmAttributes; /// /// Maximum power consumption of the USB device from this bus in this configuration when the device is fully /// operation. /// public byte MaxPower; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\nwTotalLength: {2}\nbNumInterfaces: {3}\nbConfigurationValue: {4}\niConfiguration: {5}\nbmAttributes: {6}\nMaxPower: {7}\n", bLength, bDescriptorType.ToString("X2") + "h", wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration, bmAttributes.ToString("X2") + "h", MaxPower); } } /// A structure representing the standard USB interface descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_INTERFACE_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Number of this interface public byte bInterfaceNumber; /// Value used to select this alternate setting for this interface public byte bAlternateSetting; /// Number of endpoints used by this interface (excluding the control endpoint) public byte bNumEndpoints; /// USB-IF class code for this interface public byte bInterfaceClass; /// USB-IF subclass code for this interface public byte bInterfaceSubClass; /// USB-IF protocol code for this interface public byte bInterfaceProtocol; /// Index of string descriptor describing this interface public byte iInterface; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\nbInterfaceNumber: {2}\nbAlternateSetting: {3}\nbNumEndpoints: {4}\nbInterfaceClass: {5}\nbInterfaceSubClass: {6}\nbInterfaceProtocol: {7}\niInterface: {8}\n", bLength, bDescriptorType.ToString("X2") + "h", bInterfaceNumber, bAlternateSetting, bNumEndpoints, bInterfaceClass.ToString("X2") + "h", bInterfaceSubClass.ToString("X2") + "h", bInterfaceProtocol.ToString("X2") + "h", iInterface); } } /// A structure representing the standard USB string descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] public struct USB_STRING_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// Content of the string [MarshalAs(UnmanagedType.ByValTStr, SizeConst = AllKConstants.KLST_STRING_MAX_LEN)] public string bString; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\nbString: {2}\n", bLength, bDescriptorType.ToString("X2") + "h", bString); } } /// A structure representing the common USB descriptor. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_COMMON_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\n", bLength, bDescriptorType.ToString("X2") + "h"); } } /// Allows hardware manufacturers to define groupings of interfaces. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct USB_INTERFACE_ASSOCIATION_DESCRIPTOR { /// Size of this descriptor (in bytes) public byte bLength; /// Descriptor type public byte bDescriptorType; /// First interface number of the set of interfaces that follow this descriptor public byte bFirstInterface; /// The Number of interfaces follow this descriptor that are considered "associated" public byte bInterfaceCount; /// \c bInterfaceClass used for this associated interfaces public byte bFunctionClass; /// \c bInterfaceSubClass used for the associated interfaces public byte bFunctionSubClass; /// \c bInterfaceProtocol used for the associated interfaces public byte bFunctionProtocol; /// Index of string descriptor describing the associated interfaces public byte iFunction; public override string ToString() { return string.Format("bLength: {0}\nbDescriptorType: {1}\nbFirstInterface: {2}\nbInterfaceCount: {3}\nbFunctionClass: {4}\nbFunctionSubClass: {5}\nbFunctionProtocol: {6}\niFunction: {7}\n", bLength, bDescriptorType.ToString("X2") + "h", bFirstInterface, bInterfaceCount, bFunctionClass.ToString("X2") + "h", bFunctionSubClass.ToString("X2") + "h", bFunctionProtocol.ToString("X2") + "h", iFunction); } } /// USB core driver API information structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct KUSB_DRIVER_API_INFO { /// \readonly Driver id of the driver api. public int DriverID; /// \readonly Number of valid functions contained in the driver API. public int FunctionCount; public override string ToString() { return string.Format("DriverID: {0}\nFunctionCount: {1}\n", DriverID, FunctionCount); } } /// Driver API function set structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 512)] public struct KUSB_DRIVER_API { /// Driver API information. public KUSB_DRIVER_API_INFO Info; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_InitDelegate Init; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_FreeDelegate Free; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_ClaimInterfaceDelegate ClaimInterface; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_ReleaseInterfaceDelegate ReleaseInterface; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_SetAltInterfaceDelegate SetAltInterface; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetAltInterfaceDelegate GetAltInterface; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetDescriptorDelegate GetDescriptor; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_ControlTransferDelegate ControlTransfer; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_SetPowerPolicyDelegate SetPowerPolicy; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetPowerPolicyDelegate GetPowerPolicy; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_SetConfigurationDelegate SetConfiguration; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetConfigurationDelegate GetConfiguration; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_ResetDeviceDelegate ResetDevice; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_InitializeDelegate Initialize; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_SelectInterfaceDelegate SelectInterface; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetAssociatedInterfaceDelegate GetAssociatedInterface; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_CloneDelegate Clone; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_QueryInterfaceSettingsDelegate QueryInterfaceSettings; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_QueryDeviceInformationDelegate QueryDeviceInformation; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_SetCurrentAlternateSettingDelegate SetCurrentAlternateSetting; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetCurrentAlternateSettingDelegate GetCurrentAlternateSetting; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_QueryPipeDelegate QueryPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_SetPipePolicyDelegate SetPipePolicy; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetPipePolicyDelegate GetPipePolicy; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_ReadPipeDelegate ReadPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_WritePipeDelegate WritePipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_ResetPipeDelegate ResetPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_AbortPipeDelegate AbortPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_FlushPipeDelegate FlushPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_IsoReadPipeDelegate IsoReadPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_IsoWritePipeDelegate IsoWritePipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetCurrentFrameNumberDelegate GetCurrentFrameNumber; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetOverlappedResultDelegate GetOverlappedResult; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetPropertyDelegate GetProperty; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_IsochReadPipeDelegate IsochReadPipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_IsochWritePipeDelegate IsochWritePipe; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_QueryPipeExDelegate QueryPipeEx; [MarshalAs(UnmanagedType.FunctionPtr)] public KUSB_GetSuperSpeedPipeCompanionDescriptorDelegate GetSuperSpeedPipeCompanionDescriptor; } /// Hot plug parameter structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 2048)] public struct KHOT_PARAMS { /// Hot plug event window handle to send/post messages when notifications occur. public IntPtr UserHwnd; /// WM_USER message start offset used when sending/posting messages, See details. public uint UserMessage; /// Additional init/config parameters public KHOT_FLAG Flags; /// File pattern matches for restricting notifcations to a single/group or all supported usb devices. public KLST_PATTERN_MATCH PatternMatch; /// Hot plug event callback function invoked when notifications occur. [MarshalAs(UnmanagedType.FunctionPtr)] public KHOT_PLUG_CB OnHotPlug; /// \b WM_POWERBROADCAST event callback function invoked when a power-management event has occurred. [MarshalAs(UnmanagedType.FunctionPtr)] public KHOT_POWER_BROADCAST_CB OnPowerBroadcast; public override string ToString() { return string.Format("UserHwnd: {0}\nUserMessage: {1}\nFlags: {2}\n", UserHwnd.ToString("X16") + "h", UserMessage.ToString("X8") + "h", Flags.ToString()); } } [StructLayout(LayoutKind.Sequential)] public struct KSTM_XFER_CONTEXT { private readonly IntPtr mHandlePtr; public KSTM_XFER_CONTEXT(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } /// KSTM_XFER_CONTEXT_MAP is used for calculating field offsets only [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] private struct KSTM_XFER_CONTEXT_MAP { /// Internal stream buffer. private readonly IntPtr Buffer; /// Size of internal stream buffer. private readonly int BufferSize; /// Number of bytes to write or number of bytes read. private readonly int TransferLength; /// User defined state. private readonly IntPtr UserState; } private static readonly int ofsBuffer = Marshal.OffsetOf(typeof(KSTM_XFER_CONTEXT_MAP), "Buffer").ToInt32(); private static readonly int ofsBufferSize = Marshal.OffsetOf(typeof(KSTM_XFER_CONTEXT_MAP), "BufferSize").ToInt32(); private static readonly int ofsTransferLength = Marshal.OffsetOf(typeof(KSTM_XFER_CONTEXT_MAP), "TransferLength").ToInt32(); private static readonly int ofsUserState = Marshal.OffsetOf(typeof(KSTM_XFER_CONTEXT_MAP), "UserState").ToInt32(); /// Internal stream buffer. public IntPtr Buffer { get { return Marshal.ReadIntPtr(mHandlePtr, ofsBuffer); } } /// Size of internal stream buffer. public int BufferSize { get { return Marshal.ReadInt32(mHandlePtr, ofsBufferSize); } } /// Number of bytes to write or number of bytes read. public int TransferLength { get { return Marshal.ReadInt32(mHandlePtr, ofsTransferLength); } } /// User defined state. public IntPtr UserState { get { return Marshal.ReadIntPtr(mHandlePtr, ofsUserState); } set { Marshal.WriteIntPtr(mHandlePtr, ofsUserState, value); } } public override string ToString() { return string.Format("Buffer: {0}\nBufferSize: {1}\nTransferLength: {2}\nUserState: {3}\n", Buffer.ToString("X16") + "h", BufferSize, TransferLength, UserState.ToString("X16") + "h"); } } [StructLayout(LayoutKind.Sequential)] public struct KSTM_INFO { private readonly IntPtr mHandlePtr; public KSTM_INFO(IntPtr Handle) { mHandlePtr = Handle; } public IntPtr Pointer { get { return mHandlePtr; } } /// KSTM_INFO_MAP is used for calculating field offsets only [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] private struct KSTM_INFO_MAP { /// \ref KUSB_HANDLE this stream uses. private readonly IntPtr UsbHandle; /// This parameter corresponds to the bEndpointAddress field in the endpoint descriptor. private readonly byte PipeID; /// Maximum transfer read/write request allowed pending. private readonly int MaxPendingTransfers; /// Maximum transfer sage size. private readonly int MaxTransferSize; /// Maximum number of I/O request allowed pending. private readonly int MaxPendingIO; /// Populated with the endpoint descriptor for the specified \c PipeID. private readonly USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; /// Populated with the driver api for the specified \c UsbHandle. private readonly KUSB_DRIVER_API DriverAPI; /// Populated with the device file handle for the specified \c UsbHandle. private readonly IntPtr DeviceHandle; /// Stream handle. private readonly IntPtr StreamHandle; /// Stream info user defined state. private readonly IntPtr UserState; } private static readonly int ofsUsbHandle = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "UsbHandle").ToInt32(); private static readonly int ofsPipeID = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "PipeID").ToInt32(); private static readonly int ofsMaxPendingTransfers = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "MaxPendingTransfers").ToInt32(); private static readonly int ofsMaxTransferSize = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "MaxTransferSize").ToInt32(); private static readonly int ofsMaxPendingIO = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "MaxPendingIO").ToInt32(); private static readonly int ofsEndpointDescriptor = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "EndpointDescriptor").ToInt32(); private static readonly int ofsDriverAPI = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "DriverAPI").ToInt32(); private static readonly int ofsDeviceHandle = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "DeviceHandle").ToInt32(); private static readonly int ofsStreamHandle = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "StreamHandle").ToInt32(); private static readonly int ofsUserState = Marshal.OffsetOf(typeof(KSTM_INFO_MAP), "UserState").ToInt32(); /// \ref KUSB_HANDLE this stream uses. public IntPtr UsbHandle { get { return Marshal.ReadIntPtr(mHandlePtr, ofsUsbHandle); } } /// This parameter corresponds to the bEndpointAddress field in the endpoint descriptor. public byte PipeID { get { return Marshal.ReadByte(mHandlePtr, ofsPipeID); } } /// Maximum transfer read/write request allowed pending. public int MaxPendingTransfers { get { return Marshal.ReadInt32(mHandlePtr, ofsMaxPendingTransfers); } } /// Maximum transfer sage size. public int MaxTransferSize { get { return Marshal.ReadInt32(mHandlePtr, ofsMaxTransferSize); } } /// Maximum number of I/O request allowed pending. public int MaxPendingIO { get { return Marshal.ReadInt32(mHandlePtr, ofsMaxPendingIO); } } /// Populated with the endpoint descriptor for the specified \c PipeID. public USB_ENDPOINT_DESCRIPTOR EndpointDescriptor { get { return (USB_ENDPOINT_DESCRIPTOR) Marshal.PtrToStructure(new IntPtr(mHandlePtr.ToInt64() + ofsEndpointDescriptor), typeof(USB_ENDPOINT_DESCRIPTOR)); } } /// Populated with the driver api for the specified \c UsbHandle. public KUSB_DRIVER_API DriverAPI { get { return (KUSB_DRIVER_API) Marshal.PtrToStructure(new IntPtr(mHandlePtr.ToInt64() + ofsDriverAPI), typeof(KUSB_DRIVER_API)); } } /// Populated with the device file handle for the specified \c UsbHandle. public IntPtr DeviceHandle { get { return Marshal.ReadIntPtr(mHandlePtr, ofsDeviceHandle); } } /// Stream handle. public IntPtr StreamHandle { get { return Marshal.ReadIntPtr(mHandlePtr, ofsStreamHandle); } } /// Stream info user defined state. public IntPtr UserState { get { return Marshal.ReadIntPtr(mHandlePtr, ofsUserState); } set { Marshal.WriteIntPtr(mHandlePtr, ofsUserState, value); } } public override string ToString() { return string.Format("UsbHandle: {0}\nPipeID: {1}\nMaxPendingTransfers: {2}\nMaxTransferSize: {3}\nMaxPendingIO: {4}\nDeviceHandle: {5}\nStreamHandle: {6}\nUserState: {7}\n", UsbHandle.ToString("X16") + "h", PipeID.ToString("X2") + "h", MaxPendingTransfers, MaxTransferSize, MaxPendingIO, DeviceHandle.ToString("X16") + "h", StreamHandle.ToString("X16") + "h", UserState.ToString("X16") + "h"); } } /// Stream callback structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 64)] public struct KSTM_CALLBACK { /// Executed when a transfer error occurs. [MarshalAs(UnmanagedType.FunctionPtr)] public KSTM_ERROR_CB Error; /// Executed to submit a transfer. [MarshalAs(UnmanagedType.FunctionPtr)] public KSTM_SUBMIT_CB Submit; /// Executed when a valid transfer completes. [MarshalAs(UnmanagedType.FunctionPtr)] public KSTM_COMPLETE_CB Complete; /// Executed for every transfer context when the stream is started with \ref StmK_Start. [MarshalAs(UnmanagedType.FunctionPtr)] public KSTM_STARTED_CB Started; /// Executed for every transfer context when the stream is stopped with \ref StmK_Stop. [MarshalAs(UnmanagedType.FunctionPtr)] public KSTM_STOPPED_CB Stopped; /// Executed immediately after a transfer completes. [MarshalAs(UnmanagedType.FunctionPtr)] public KSTM_BEFORE_COMPLETE_CB BeforeComplete; } #endregion #region Delegates [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate int KLIB_HANDLE_CLEANUP_CB([In] IntPtr Handle, KLIB_HANDLE_TYPE HandleType, IntPtr UserContext); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KISO_ENUM_PACKETS_CB(uint PacketIndex, [In] ref KISO_PACKET IsoPacket, IntPtr UserState); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KISOCH_ENUM_PACKETS_CB(uint PacketIndex, ref uint Offset, ref uint Length, ref uint Status, IntPtr UserState); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KLST_ENUM_DEVINFO_CB([In] KLST_HANDLE DeviceList, [In] KLST_DEVINFO_HANDLE DeviceInfo, IntPtr Context); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_InitDelegate([Out] out KUSB_HANDLE InterfaceHandle, [In] KLST_DEVINFO_HANDLE DevInfo); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_FreeDelegate([In] KUSB_HANDLE InterfaceHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_ClaimInterfaceDelegate([In] KUSB_HANDLE InterfaceHandle, byte NumberOrIndex, bool IsIndex); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_ReleaseInterfaceDelegate([In] KUSB_HANDLE InterfaceHandle, byte NumberOrIndex, bool IsIndex); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_SetAltInterfaceDelegate([In] KUSB_HANDLE InterfaceHandle, byte NumberOrIndex, bool IsIndex, byte AltSettingNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetAltInterfaceDelegate([In] KUSB_HANDLE InterfaceHandle, byte NumberOrIndex, bool IsIndex, out byte AltSettingNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetDescriptorDelegate([In] KUSB_HANDLE InterfaceHandle, byte DescriptorType, byte Index, ushort LanguageID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_ControlTransferDelegate([In] KUSB_HANDLE InterfaceHandle, WINUSB_SETUP_PACKET SetupPacket, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_SetPowerPolicyDelegate([In] KUSB_HANDLE InterfaceHandle, uint PolicyType, uint ValueLength, IntPtr Value); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetPowerPolicyDelegate([In] KUSB_HANDLE InterfaceHandle, uint PolicyType, ref uint ValueLength, IntPtr Value); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_SetConfigurationDelegate([In] KUSB_HANDLE InterfaceHandle, byte ConfigurationNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetConfigurationDelegate([In] KUSB_HANDLE InterfaceHandle, out byte ConfigurationNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_ResetDeviceDelegate([In] KUSB_HANDLE InterfaceHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_InitializeDelegate(IntPtr DeviceHandle, [Out] out KUSB_HANDLE InterfaceHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_SelectInterfaceDelegate([In] KUSB_HANDLE InterfaceHandle, byte NumberOrIndex, bool IsIndex); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetAssociatedInterfaceDelegate([In] KUSB_HANDLE InterfaceHandle, byte AssociatedInterfaceIndex, [Out] out KUSB_HANDLE AssociatedInterfaceHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_CloneDelegate([In] KUSB_HANDLE InterfaceHandle, [Out] out KUSB_HANDLE DstInterfaceHandle); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_QueryInterfaceSettingsDelegate([In] KUSB_HANDLE InterfaceHandle, byte AltSettingIndex, [Out] out USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_QueryDeviceInformationDelegate([In] KUSB_HANDLE InterfaceHandle, uint InformationType, ref uint BufferLength, IntPtr Buffer); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_SetCurrentAlternateSettingDelegate([In] KUSB_HANDLE InterfaceHandle, byte AltSettingNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetCurrentAlternateSettingDelegate([In] KUSB_HANDLE InterfaceHandle, out byte AltSettingNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_QueryPipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte AltSettingNumber, byte PipeIndex, [Out] out WINUSB_PIPE_INFORMATION PipeInformation); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_QueryPipeExDelegate([In] KUSB_HANDLE InterfaceHandle, byte AlternateSettingNumber, byte PipeIndex, [Out] out WINUSB_PIPE_INFORMATION_EX PipeInformationEx); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetSuperSpeedPipeCompanionDescriptorDelegate([In] KUSB_HANDLE Handle, byte AltSettingNumber, byte PipeIndex, [Out] out USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR PipeCompanionDescriptor); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_SetPipePolicyDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID, uint PolicyType, uint ValueLength, IntPtr Value); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetPipePolicyDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID, uint PolicyType, ref uint ValueLength, IntPtr Value); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_ReadPipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_WritePipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_ResetPipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_AbortPipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_FlushPipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_IsoReadPipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID, IntPtr Buffer, uint BufferLength, IntPtr Overlapped, [In] KISO_CONTEXT IsoContext); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_IsoWritePipeDelegate([In] KUSB_HANDLE InterfaceHandle, byte PipeID, IntPtr Buffer, uint BufferLength, IntPtr Overlapped, [In] KISO_CONTEXT IsoContext); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetCurrentFrameNumberDelegate([In] KUSB_HANDLE InterfaceHandle, out uint FrameNumber); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetOverlappedResultDelegate([In] KUSB_HANDLE InterfaceHandle, IntPtr Overlapped, out uint lpNumberOfBytesTransferred, bool bWait); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_GetPropertyDelegate([In] KUSB_HANDLE InterfaceHandle, KUSB_PROPERTY PropertyType, ref uint PropertySize, IntPtr Value); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_IsochReadPipeDelegate([In] KISOCH_HANDLE IsochHandle, uint DataLength, ref uint FrameNumber, uint NumberOfPackets, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate bool KUSB_IsochWritePipeDelegate([In] KISOCH_HANDLE IsochHandle, uint DataLength, ref uint FrameNumber, uint NumberOfPackets, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate void KHOT_PLUG_CB([In] KHOT_HANDLE HotHandle, [In] KLST_DEVINFO_HANDLE DeviceInfo, KLST_SYNC_FLAG PlugType); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate void KHOT_POWER_BROADCAST_CB([In] KHOT_HANDLE HotHandle, [In] KLST_DEVINFO_HANDLE DeviceInfo, uint PbtEvent); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate int KSTM_ERROR_CB([In] KSTM_INFO StreamInfo, [In] KSTM_XFER_CONTEXT XferContext, int XferContextIndex, int ErrorCode); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate int KSTM_SUBMIT_CB([In] KSTM_INFO StreamInfo, [In] KSTM_XFER_CONTEXT XferContext, int XferContextIndex, IntPtr Overlapped); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate int KSTM_STARTED_CB([In] KSTM_INFO StreamInfo, [In] KSTM_XFER_CONTEXT XferContext, int XferContextIndex); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate int KSTM_STOPPED_CB([In] KSTM_INFO StreamInfo, [In] KSTM_XFER_CONTEXT XferContext, int XferContextIndex); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate int KSTM_COMPLETE_CB([In] KSTM_INFO StreamInfo, [In] KSTM_XFER_CONTEXT XferContext, int XferContextIndex, int ErrorCode); [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi, SetLastError = true)] public delegate KSTM_COMPLETE_RESULT KSTM_BEFORE_COMPLETE_CB([In] KSTM_INFO StreamInfo, [In] KSTM_XFER_CONTEXT XferContext, int XferContextIndex, ref int ErrorCode); #endregion public class LstK : IDisposable { protected bool mbDisposed; protected KLST_HANDLE mHandleStruct; protected LstK() { } /// Initializes a new usb device list containing all supported devices. public LstK(KLST_FLAG Flags) { bool success = AllKFunctions.LstK_Init(out mHandleStruct, Flags); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Initializes a new usb device list containing only devices matching a specific class GUID. public LstK(KLST_FLAG Flags, ref KLST_PATTERN_MATCH PatternMatch) { bool success = AllKFunctions.LstK_InitEx(out mHandleStruct, Flags, ref PatternMatch); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KLST_HANDLE Handle { get { return mHandleStruct; } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~LstK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.LstK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KLST_HANDLE(IntPtr.Zero); mbDisposed = true; } } /// Initializes a new usb device list containing all supported devices. protected bool Init(KLST_FLAG Flags) { bool success = AllKFunctions.LstK_Init(out mHandleStruct, Flags); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Initializes a new usb device list containing only devices matching a specific class GUID. protected bool InitEx(KLST_FLAG Flags, ref KLST_PATTERN_MATCH PatternMatch) { bool success = AllKFunctions.LstK_InitEx(out mHandleStruct, Flags, ref PatternMatch); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Enumerates \ref KLST_DEVINFO elements of a \ref KLST_HANDLE. public virtual bool Enumerate(KLST_ENUM_DEVINFO_CB EnumDevListCB, IntPtr Context) { return AllKFunctions.LstK_Enumerate(mHandleStruct, EnumDevListCB, Context); } /// Gets the \ref KLST_DEVINFO element for the current position. public virtual bool Current(out KLST_DEVINFO_HANDLE DeviceInfo) { return AllKFunctions.LstK_Current(mHandleStruct, out DeviceInfo); } /// Advances the device list current \ref KLST_DEVINFO position. public virtual bool MoveNext(out KLST_DEVINFO_HANDLE DeviceInfo) { return AllKFunctions.LstK_MoveNext(mHandleStruct, out DeviceInfo); } /// Sets the device list to its initial position, which is before the first element in the list. public virtual void MoveReset() { AllKFunctions.LstK_MoveReset(mHandleStruct); } /// Find a device by vendor and product id public virtual bool FindByVidPid(int Vid, int Pid, out KLST_DEVINFO_HANDLE DeviceInfo) { return AllKFunctions.LstK_FindByVidPid(mHandleStruct, Vid, Pid, out DeviceInfo); } /// Counts the number of device info elements in a device list. public virtual bool Count(ref uint Count) { return AllKFunctions.LstK_Count(mHandleStruct, ref Count); } } public class HotK : IDisposable { protected bool mbDisposed; protected KHOT_HANDLE mHandleStruct; protected HotK() { } /// Creates a new hot-plug handle for USB device arrival/removal event monitoring. public HotK(ref KHOT_PARAMS InitParams) { bool success = AllKFunctions.HotK_Init(out mHandleStruct, ref InitParams); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KHOT_HANDLE Handle { get { return mHandleStruct; } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~HotK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.HotK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KHOT_HANDLE(IntPtr.Zero); mbDisposed = true; } } /// Creates a new hot-plug handle for USB device arrival/removal event monitoring. protected bool Init(ref KHOT_PARAMS InitParams) { bool success = AllKFunctions.HotK_Init(out mHandleStruct, ref InitParams); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Frees all hot-plug handles initialized with \ref HotK_Init. public static void FreeAll() { AllKFunctions.HotK_FreeAll(); } } public class UsbK : IDisposable { protected KUSB_DRIVER_API driverAPI; protected bool mbDisposed; protected KUSB_HANDLE mHandleStruct; protected UsbK() { } /// Creates/opens a libusbK interface handle from the device list. This is a preferred method. public UsbK(KLST_DEVINFO_HANDLE DevInfo) { bool success = AllKFunctions.LibK_LoadDriverAPI(out driverAPI, DevInfo.DriverID); if (!success) throw new Exception(string.Format("{0} failed loading Driver API. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); success = driverAPI.Init(out mHandleStruct, DevInfo); if (!success) throw new Exception(string.Format("{0} failed initializing usb device. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Creates a libusbK handle for the device specified by a file handle. public UsbK(IntPtr DeviceHandle, KUSB_DRVID driverID) { bool success = AllKFunctions.LibK_LoadDriverAPI(out driverAPI, (int) driverID); if (!success) throw new Exception(string.Format("{0} failed loading Driver API. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); success = driverAPI.Initialize(DeviceHandle, out mHandleStruct); if (!success) throw new Exception(string.Format("{0} failed initializing usb device. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KUSB_HANDLE Handle { get { return mHandleStruct; } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~UsbK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.UsbK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KUSB_HANDLE(IntPtr.Zero); mbDisposed = true; } } /// Creates/opens a libusbK interface handle from the device list. This is a preferred method. protected bool Init(KLST_DEVINFO_HANDLE DevInfo) { bool success = AllKFunctions.LibK_LoadDriverAPI(out driverAPI, DevInfo.DriverID); if (!success) throw new Exception(string.Format("{0} failed loading Driver API. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); success = driverAPI.Init(out mHandleStruct, DevInfo); if (!success) throw new Exception(string.Format("{0} failed initializing usb device. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Claims the specified interface by number or index. public virtual bool ClaimInterface(byte NumberOrIndex, bool IsIndex) { return driverAPI.ClaimInterface(mHandleStruct, NumberOrIndex, IsIndex); } /// Releases the specified interface by number or index. public virtual bool ReleaseInterface(byte NumberOrIndex, bool IsIndex) { return driverAPI.ReleaseInterface(mHandleStruct, NumberOrIndex, IsIndex); } /// Sets the alternate setting of the specified interface. public virtual bool SetAltInterface(byte NumberOrIndex, bool IsIndex, byte AltSettingNumber) { return driverAPI.SetAltInterface(mHandleStruct, NumberOrIndex, IsIndex, AltSettingNumber); } /// Gets the alternate setting for the specified interface. public virtual bool GetAltInterface(byte NumberOrIndex, bool IsIndex, out byte AltSettingNumber) { return driverAPI.GetAltInterface(mHandleStruct, NumberOrIndex, IsIndex, out AltSettingNumber); } /// Gets the requested descriptor. This is a synchronous operation. public virtual bool GetDescriptor(byte DescriptorType, byte Index, int LanguageID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred) { return driverAPI.GetDescriptor(mHandleStruct, DescriptorType, Index, (ushort) LanguageID, Buffer, BufferLength, out LengthTransferred); } /// Gets the requested descriptor. This is a synchronous operation. public virtual bool GetDescriptor(byte DescriptorType, byte Index, int LanguageID, Array Buffer, uint BufferLength, out uint LengthTransferred) { return driverAPI.GetDescriptor(mHandleStruct, DescriptorType, Index, (ushort) LanguageID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred); } /// Transmits control data over a default control endpoint. public virtual bool ControlTransfer(WINUSB_SETUP_PACKET SetupPacket, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped) { return driverAPI.ControlTransfer(mHandleStruct, SetupPacket, Buffer, BufferLength, out LengthTransferred, Overlapped); } /// Transmits control data over a default control endpoint. public virtual bool ControlTransfer(WINUSB_SETUP_PACKET SetupPacket, Array Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped) { return driverAPI.ControlTransfer(mHandleStruct, SetupPacket, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred, Overlapped); } /// Transmits control data over a default control endpoint. public virtual bool ControlTransfer(WINUSB_SETUP_PACKET SetupPacket, Array Buffer, uint BufferLength, out uint LengthTransferred, KOVL_HANDLE Overlapped) { return driverAPI.ControlTransfer(mHandleStruct, SetupPacket, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred, Overlapped.Pointer); } /// Transmits control data over a default control endpoint. public virtual bool ControlTransfer(WINUSB_SETUP_PACKET SetupPacket, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, KOVL_HANDLE Overlapped) { return driverAPI.ControlTransfer(mHandleStruct, SetupPacket, Buffer, BufferLength, out LengthTransferred, Overlapped.Pointer); } /// Sets the power policy for a device. public virtual bool SetPowerPolicy(uint PolicyType, uint ValueLength, IntPtr Value) { return driverAPI.SetPowerPolicy(mHandleStruct, PolicyType, ValueLength, Value); } /// Sets the power policy for a device. public virtual bool SetPowerPolicy(uint PolicyType, uint ValueLength, Array Value) { return driverAPI.SetPowerPolicy(mHandleStruct, PolicyType, ValueLength, Marshal.UnsafeAddrOfPinnedArrayElement(Value, 0)); } /// Gets the power policy for a device. public virtual bool GetPowerPolicy(uint PolicyType, ref uint ValueLength, IntPtr Value) { return driverAPI.GetPowerPolicy(mHandleStruct, PolicyType, ref ValueLength, Value); } /// Gets the power policy for a device. public virtual bool GetPowerPolicy(uint PolicyType, ref uint ValueLength, Array Value) { return driverAPI.GetPowerPolicy(mHandleStruct, PolicyType, ref ValueLength, Marshal.UnsafeAddrOfPinnedArrayElement(Value, 0)); } /// Sets the device configuration number. public virtual bool SetConfiguration(byte ConfigurationNumber) { return driverAPI.SetConfiguration(mHandleStruct, ConfigurationNumber); } /// Gets the device current configuration number. public virtual bool GetConfiguration(out byte ConfigurationNumber) { return driverAPI.GetConfiguration(mHandleStruct, out ConfigurationNumber); } /// Resets the usb device of the specified interface handle. (port cycle). public virtual bool ResetDevice() { return driverAPI.ResetDevice(mHandleStruct); } /// Creates a libusbK handle for the device specified by a file handle. protected bool Initialize(IntPtr DeviceHandle, KUSB_DRVID driverID) { bool success = AllKFunctions.LibK_LoadDriverAPI(out driverAPI, (int) driverID); if (!success) throw new Exception(string.Format("{0} failed loading Driver API. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); success = driverAPI.Initialize(DeviceHandle, out mHandleStruct); if (!success) throw new Exception(string.Format("{0} failed initializing usb device. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Selects the specified interface by number or index as the current interface. public virtual bool SelectInterface(byte NumberOrIndex, bool IsIndex) { return driverAPI.SelectInterface(mHandleStruct, NumberOrIndex, IsIndex); } /// Retrieves a handle for an associated interface. public virtual bool GetAssociatedInterface(byte AssociatedInterfaceIndex, out KUSB_HANDLE AssociatedInterfaceHandle) { return driverAPI.GetAssociatedInterface(mHandleStruct, AssociatedInterfaceIndex, out AssociatedInterfaceHandle); } /// Clones the specified interface handle. public virtual bool Clone(out KUSB_HANDLE DstInterfaceHandle) { return driverAPI.Clone(mHandleStruct, out DstInterfaceHandle); } /// /// Retrieves the interface descriptor for the specified alternate interface settings for a particular interface /// handle. /// public virtual bool QueryInterfaceSettings(byte AltSettingIndex, out USB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor) { return driverAPI.QueryInterfaceSettings(mHandleStruct, AltSettingIndex, out UsbAltInterfaceDescriptor); } /// Retrieves information about the physical device that is associated with a libusbK handle. public virtual bool QueryDeviceInformation(uint InformationType, ref uint BufferLength, IntPtr Buffer) { return driverAPI.QueryDeviceInformation(mHandleStruct, InformationType, ref BufferLength, Buffer); } /// Retrieves information about the physical device that is associated with a libusbK handle. public virtual bool QueryDeviceInformation(uint InformationType, ref uint BufferLength, Array Buffer) { return driverAPI.QueryDeviceInformation(mHandleStruct, InformationType, ref BufferLength, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0)); } /// Sets the alternate setting of an interface. public virtual bool SetCurrentAlternateSetting(byte AltSettingNumber) { return driverAPI.SetCurrentAlternateSetting(mHandleStruct, AltSettingNumber); } /// Gets the current alternate interface setting for an interface. public virtual bool GetCurrentAlternateSetting(out byte AltSettingNumber) { return driverAPI.GetCurrentAlternateSetting(mHandleStruct, out AltSettingNumber); } /// Retrieves information about a pipe that is associated with an interface. public virtual bool QueryPipe(byte AltSettingNumber, byte PipeIndex, out WINUSB_PIPE_INFORMATION PipeInformation) { return driverAPI.QueryPipe(mHandleStruct, AltSettingNumber, PipeIndex, out PipeInformation); } /// Retrieves information about a pipe that is associated with an interface. public virtual bool QueryPipeEx(byte AltSettingNumber, byte PipeIndex, out WINUSB_PIPE_INFORMATION_EX PipeInformationEx) { return driverAPI.QueryPipeEx(mHandleStruct, AltSettingNumber, PipeIndex, out PipeInformationEx); } /// Retrieves a pipes super speed endpoint companion descriptor associated with an interface. public virtual bool GetSuperSpeedPipeCompanionDescriptor(byte AltSettingNumber, byte PipeIndex, out USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR PipeCompanionDescriptor) { return driverAPI.GetSuperSpeedPipeCompanionDescriptor(mHandleStruct, AltSettingNumber, PipeIndex, out PipeCompanionDescriptor); } /// /// Sets the policy for a specific pipe associated with an endpoint on the device. This is a synchronous /// operation. /// public virtual bool SetPipePolicy(byte PipeID, uint PolicyType, uint ValueLength, IntPtr Value) { return driverAPI.SetPipePolicy(mHandleStruct, PipeID, PolicyType, ValueLength, Value); } /// /// Sets the policy for a specific pipe associated with an endpoint on the device. This is a synchronous /// operation. /// public virtual bool SetPipePolicy(byte PipeID, uint PolicyType, uint ValueLength, Array Value) { return driverAPI.SetPipePolicy(mHandleStruct, PipeID, PolicyType, ValueLength, Marshal.UnsafeAddrOfPinnedArrayElement(Value, 0)); } /// Gets the policy for a specific pipe (endpoint). public virtual bool GetPipePolicy(byte PipeID, uint PolicyType, ref uint ValueLength, IntPtr Value) { return driverAPI.GetPipePolicy(mHandleStruct, PipeID, PolicyType, ref ValueLength, Value); } /// Gets the policy for a specific pipe (endpoint). public virtual bool GetPipePolicy(byte PipeID, uint PolicyType, ref uint ValueLength, Array Value) { return driverAPI.GetPipePolicy(mHandleStruct, PipeID, PolicyType, ref ValueLength, Marshal.UnsafeAddrOfPinnedArrayElement(Value, 0)); } /// Reads data from the specified pipe. public virtual bool ReadPipe(byte PipeID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped) { return driverAPI.ReadPipe(mHandleStruct, PipeID, Buffer, BufferLength, out LengthTransferred, Overlapped); } /// Reads data from the specified pipe. public virtual bool ReadPipe(byte PipeID, Array Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped) { return driverAPI.ReadPipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred, Overlapped); } /// Reads data from the specified pipe. public virtual bool ReadPipe(byte PipeID, Array Buffer, uint BufferLength, out uint LengthTransferred, KOVL_HANDLE Overlapped) { return driverAPI.ReadPipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred, Overlapped.Pointer); } /// Reads data from the specified pipe. public virtual bool ReadPipe(byte PipeID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, KOVL_HANDLE Overlapped) { return driverAPI.ReadPipe(mHandleStruct, PipeID, Buffer, BufferLength, out LengthTransferred, Overlapped.Pointer); } /// Writes data to a pipe. public virtual bool WritePipe(byte PipeID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped) { return driverAPI.WritePipe(mHandleStruct, PipeID, Buffer, BufferLength, out LengthTransferred, Overlapped); } /// Writes data to a pipe. public virtual bool WritePipe(byte PipeID, Array Buffer, uint BufferLength, out uint LengthTransferred, IntPtr Overlapped) { return driverAPI.WritePipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred, Overlapped); } /// Writes data to a pipe. public virtual bool WritePipe(byte PipeID, Array Buffer, uint BufferLength, out uint LengthTransferred, KOVL_HANDLE Overlapped) { return driverAPI.WritePipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, out LengthTransferred, Overlapped.Pointer); } /// Writes data to a pipe. public virtual bool WritePipe(byte PipeID, IntPtr Buffer, uint BufferLength, out uint LengthTransferred, KOVL_HANDLE Overlapped) { return driverAPI.WritePipe(mHandleStruct, PipeID, Buffer, BufferLength, out LengthTransferred, Overlapped.Pointer); } /// Resets the data toggle and clears the stall condition on a pipe. public virtual bool ResetPipe(byte PipeID) { return driverAPI.ResetPipe(mHandleStruct, PipeID); } /// Aborts all of the pending transfers for a pipe. public virtual bool AbortPipe(byte PipeID) { return driverAPI.AbortPipe(mHandleStruct, PipeID); } /// Discards any data that is cached in a pipe. public virtual bool FlushPipe(byte PipeID) { return driverAPI.FlushPipe(mHandleStruct, PipeID); } /// Reads from an isochronous pipe. public virtual bool IsoReadPipe(byte PipeID, IntPtr Buffer, uint BufferLength, IntPtr Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoReadPipe(mHandleStruct, PipeID, Buffer, BufferLength, Overlapped, IsoContext); } /// Reads from an isochronous pipe. public virtual bool IsoReadPipe(byte PipeID, Array Buffer, uint BufferLength, IntPtr Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoReadPipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, Overlapped, IsoContext); } /// Reads from an isochronous pipe. public virtual bool IsoReadPipe(byte PipeID, Array Buffer, uint BufferLength, KOVL_HANDLE Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoReadPipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, Overlapped.Pointer, IsoContext); } /// Reads from an isochronous pipe. public virtual bool IsoReadPipe(byte PipeID, IntPtr Buffer, uint BufferLength, KOVL_HANDLE Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoReadPipe(mHandleStruct, PipeID, Buffer, BufferLength, Overlapped.Pointer, IsoContext); } /// Writes to an isochronous pipe. public virtual bool IsoWritePipe(byte PipeID, IntPtr Buffer, uint BufferLength, IntPtr Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoWritePipe(mHandleStruct, PipeID, Buffer, BufferLength, Overlapped, IsoContext); } /// Writes to an isochronous pipe. public virtual bool IsoWritePipe(byte PipeID, Array Buffer, uint BufferLength, IntPtr Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoWritePipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, Overlapped, IsoContext); } /// Writes to an isochronous pipe. public virtual bool IsoWritePipe(byte PipeID, Array Buffer, uint BufferLength, KOVL_HANDLE Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoWritePipe(mHandleStruct, PipeID, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), BufferLength, Overlapped.Pointer, IsoContext); } /// Writes to an isochronous pipe. public virtual bool IsoWritePipe(byte PipeID, IntPtr Buffer, uint BufferLength, KOVL_HANDLE Overlapped, KISO_CONTEXT IsoContext) { return driverAPI.IsoWritePipe(mHandleStruct, PipeID, Buffer, BufferLength, Overlapped.Pointer, IsoContext); } /// Retrieves the current USB frame number. public virtual bool GetCurrentFrameNumber(out uint FrameNumber) { return driverAPI.GetCurrentFrameNumber(mHandleStruct, out FrameNumber); } /// Reads from an isochronous pipe. Supports LibusbK or WinUsb public virtual bool IsochReadPipe(KISOCH_HANDLE IsochHandle, uint DataLength, ref uint FrameNumber, uint NumberOfPackets, IntPtr Overlapped) { return driverAPI.IsochReadPipe(IsochHandle, DataLength, ref FrameNumber, NumberOfPackets, Overlapped); } /// Reads from an isochronous pipe. Supports LibusbK or WinUsb public virtual bool IsochReadPipe(KISOCH_HANDLE IsochHandle, uint DataLength, ref uint FrameNumber, uint NumberOfPackets, KOVL_HANDLE Overlapped) { return driverAPI.IsochReadPipe(IsochHandle, DataLength, ref FrameNumber, NumberOfPackets, Overlapped.Pointer); } /// Writes to an isochronous pipe. Supports LibusbK or WinUsb public virtual bool IsochWritePipe(KISOCH_HANDLE IsochHandle, uint DataLength, ref uint FrameNumber, uint NumberOfPackets, IntPtr Overlapped) { return driverAPI.IsochWritePipe(IsochHandle, DataLength, ref FrameNumber, NumberOfPackets, Overlapped); } /// Writes to an isochronous pipe. Supports LibusbK or WinUsb public virtual bool IsochWritePipe(KISOCH_HANDLE IsochHandle, uint DataLength, ref uint FrameNumber, uint NumberOfPackets, KOVL_HANDLE Overlapped) { return driverAPI.IsochWritePipe(IsochHandle, DataLength, ref FrameNumber, NumberOfPackets, Overlapped.Pointer); } /// Retrieves the results of an overlapped operation on the specified libusbK handle. public virtual bool GetOverlappedResult(IntPtr Overlapped, out uint lpNumberOfBytesTransferred, bool bWait) { return driverAPI.GetOverlappedResult(mHandleStruct, Overlapped, out lpNumberOfBytesTransferred, bWait); } /// Retrieves the results of an overlapped operation on the specified libusbK handle. public virtual bool GetOverlappedResult(KOVL_HANDLE Overlapped, out uint lpNumberOfBytesTransferred, bool bWait) { return driverAPI.GetOverlappedResult(mHandleStruct, Overlapped.Pointer, out lpNumberOfBytesTransferred, bWait); } /// Gets a USB device (driver specific) property from usb handle. public virtual bool GetProperty(KUSB_PROPERTY PropertyType, ref uint PropertySize, IntPtr Value) { return driverAPI.GetProperty(mHandleStruct, PropertyType, ref PropertySize, Value); } /// Gets a USB device (driver specific) property from usb handle. public virtual bool GetProperty(KUSB_PROPERTY PropertyType, ref uint PropertySize, Array Value) { return driverAPI.GetProperty(mHandleStruct, PropertyType, ref PropertySize, Marshal.UnsafeAddrOfPinnedArrayElement(Value, 0)); } } public class OvlK : IDisposable { protected bool mbDisposed; protected KOVL_POOL_HANDLE mHandleStruct; protected OvlK() { } /// Creates a new overlapped pool. public OvlK(KUSB_HANDLE UsbHandle, int MaxOverlappedCount, KOVL_POOL_FLAG Flags) { bool success = AllKFunctions.OvlK_Init(out mHandleStruct, UsbHandle, MaxOverlappedCount, Flags); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KOVL_POOL_HANDLE Handle { get { return mHandleStruct; } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~OvlK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.OvlK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KOVL_POOL_HANDLE(IntPtr.Zero); mbDisposed = true; } } /// Gets a preallocated \c OverlappedK structure from the specified/default pool. public virtual bool Acquire(out KOVL_HANDLE OverlappedK) { return AllKFunctions.OvlK_Acquire(out OverlappedK, mHandleStruct); } /// Returns an \c OverlappedK structure to it's pool. public static bool Release(KOVL_HANDLE OverlappedK) { return AllKFunctions.OvlK_Release(OverlappedK); } /// Creates a new overlapped pool. protected bool Init(KUSB_HANDLE UsbHandle, int MaxOverlappedCount, KOVL_POOL_FLAG Flags) { bool success = AllKFunctions.OvlK_Init(out mHandleStruct, UsbHandle, MaxOverlappedCount, Flags); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Returns the internal event handle used to signal IO operations. public static IntPtr GetEventHandle(KOVL_HANDLE OverlappedK) { return AllKFunctions.OvlK_GetEventHandle(OverlappedK); } /// Waits for overlapped I/O completion, and performs actions specified in \c WaitFlags. public static bool Wait(KOVL_HANDLE OverlappedK, int TimeoutMS, KOVL_WAIT_FLAG WaitFlags, out uint TransferredLength) { return AllKFunctions.OvlK_Wait(OverlappedK, TimeoutMS, WaitFlags, out TransferredLength); } /// /// Waits for overlapped I/O completion on the oldest acquired OverlappedK handle and performs actions specified /// in \c WaitFlags. /// public virtual bool WaitOldest(out KOVL_HANDLE OverlappedK, int TimeoutMS, KOVL_WAIT_FLAG WaitFlags, out uint TransferredLength) { return AllKFunctions.OvlK_WaitOldest(mHandleStruct, out OverlappedK, TimeoutMS, WaitFlags, out TransferredLength); } /// Waits for overlapped I/O completion, cancels on a timeout error. public static bool WaitOrCancel(KOVL_HANDLE OverlappedK, int TimeoutMS, out uint TransferredLength) { return AllKFunctions.OvlK_WaitOrCancel(OverlappedK, TimeoutMS, out TransferredLength); } /// /// Waits for overlapped I/O completion, cancels on a timeout error and always releases the OvlK handle back to /// its pool. /// public static bool WaitAndRelease(KOVL_HANDLE OverlappedK, int TimeoutMS, out uint TransferredLength) { return AllKFunctions.OvlK_WaitAndRelease(OverlappedK, TimeoutMS, out TransferredLength); } /// Checks for i/o completion; returns immediately. (polling) public static bool IsComplete(KOVL_HANDLE OverlappedK) { return AllKFunctions.OvlK_IsComplete(OverlappedK); } /// Initializes an overlappedK for re-use. The overlappedK is not return to its pool. public static bool ReUse(KOVL_HANDLE OverlappedK) { return AllKFunctions.OvlK_ReUse(OverlappedK); } } public class StmK : IDisposable { protected bool mbDisposed; protected KSTM_HANDLE mHandleStruct; protected StmK() { } /// Initializes a new uni-directional pipe stream. public StmK(KUSB_HANDLE UsbHandle, byte PipeID, int MaxTransferSize, int MaxPendingTransfers, int MaxPendingIO, ref KSTM_CALLBACK Callbacks, KSTM_FLAG Flags) { bool success = AllKFunctions.StmK_Init(out mHandleStruct, UsbHandle, PipeID, MaxTransferSize, MaxPendingTransfers, MaxPendingIO, ref Callbacks, Flags); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KSTM_HANDLE Handle { get { return mHandleStruct; } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~StmK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.StmK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KSTM_HANDLE(IntPtr.Zero); mbDisposed = true; } } /// Initializes a new uni-directional pipe stream. protected bool Init(KUSB_HANDLE UsbHandle, byte PipeID, int MaxTransferSize, int MaxPendingTransfers, int MaxPendingIO, ref KSTM_CALLBACK Callbacks, KSTM_FLAG Flags) { bool success = AllKFunctions.StmK_Init(out mHandleStruct, UsbHandle, PipeID, MaxTransferSize, MaxPendingTransfers, MaxPendingIO, ref Callbacks, Flags); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Starts the internal stream thread. public virtual bool Start() { return AllKFunctions.StmK_Start(mHandleStruct); } /// Stops the internal stream thread. public virtual bool Stop(int TimeoutCancelMS) { return AllKFunctions.StmK_Stop(mHandleStruct, TimeoutCancelMS); } /// Reads data from the stream buffer. public virtual bool Read(IntPtr Buffer, int Offset, int Length, out uint TransferredLength) { return AllKFunctions.StmK_Read(mHandleStruct, Buffer, Offset, Length, out TransferredLength); } /// Reads data from the stream buffer. public virtual bool Read(Array Buffer, int Offset, int Length, out uint TransferredLength) { return AllKFunctions.StmK_Read(mHandleStruct, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), Offset, Length, out TransferredLength); } /// Writes data to the stream buffer. public virtual bool Write(IntPtr Buffer, int Offset, int Length, out uint TransferredLength) { return AllKFunctions.StmK_Write(mHandleStruct, Buffer, Offset, Length, out TransferredLength); } /// Writes data to the stream buffer. public virtual bool Write(Array Buffer, int Offset, int Length, out uint TransferredLength) { return AllKFunctions.StmK_Write(mHandleStruct, Marshal.UnsafeAddrOfPinnedArrayElement(Buffer, 0), Offset, Length, out TransferredLength); } } public class IsoK : IDisposable { private static readonly int ofsFlags = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "Flags").ToInt32(); private static readonly int ofsStartFrame = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "StartFrame").ToInt32(); private static readonly int ofsErrorCount = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "ErrorCount").ToInt32(); private static readonly int ofsNumberOfPackets = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "NumberOfPackets").ToInt32(); private static readonly int ofsUrbHdrStatus = Marshal.OffsetOf(typeof(KISO_CONTEXT_MAP), "UrbHdrStatus").ToInt32(); protected bool mbDisposed; protected KISO_CONTEXT mHandleStruct; protected IsoK() { } /// Creates a new isochronous transfer context for libusbK only. public IsoK(int NumberOfPackets, int StartFrame) { bool success = AllKFunctions.IsoK_Init(out mHandleStruct, NumberOfPackets, StartFrame); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KISO_CONTEXT Handle { get { return mHandleStruct; } } /// Additional ISO transfer flags. See \ref KISO_FLAG. public KISO_FLAG Flags { get { return (KISO_FLAG) Marshal.ReadInt32(mHandleStruct.Pointer, ofsFlags); } set { Marshal.WriteInt32(mHandleStruct.Pointer, ofsFlags, (int) value); } } /// Specifies the frame number that the transfer should begin on (0 for ASAP). public uint StartFrame { get { return (uint) Marshal.ReadInt32(mHandleStruct.Pointer, ofsStartFrame); } set { Marshal.WriteInt32(mHandleStruct.Pointer, ofsStartFrame, (int) value); } } /// /// Contains the number of packets that completed with an error condition on return from the host controller /// driver. /// public short ErrorCount { get { return Marshal.ReadInt16(mHandleStruct.Pointer, ofsErrorCount); } set { Marshal.WriteInt16(mHandleStruct.Pointer, ofsErrorCount, value); } } /// Specifies the number of packets that are described by the variable-length array member \c IsoPacket. public short NumberOfPackets { get { return Marshal.ReadInt16(mHandleStruct.Pointer, ofsNumberOfPackets); } set { Marshal.WriteInt16(mHandleStruct.Pointer, ofsNumberOfPackets, value); } } /// Contains the URB Hdr.Status value on return from the host controller driver. public uint UrbHdrStatus { get { return (uint) Marshal.ReadInt32(mHandleStruct.Pointer, ofsUrbHdrStatus); } set { Marshal.WriteInt32(mHandleStruct.Pointer, ofsUrbHdrStatus, (int) value); } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~IsoK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.IsoK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KISO_CONTEXT(IntPtr.Zero); mbDisposed = true; } } /// Creates a new isochronous transfer context for libusbK only. protected bool Init(int NumberOfPackets, int StartFrame) { bool success = AllKFunctions.IsoK_Init(out mHandleStruct, NumberOfPackets, StartFrame); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Convenience function for setting the offset of all ISO packets of an isochronous transfer context. public virtual bool SetPackets(int PacketSize) { return AllKFunctions.IsoK_SetPackets(mHandleStruct, PacketSize); } /// Convenience function for setting all fields of a \ref KISO_PACKET. public virtual bool SetPacket(int PacketIndex, ref KISO_PACKET IsoPacket) { return AllKFunctions.IsoK_SetPacket(mHandleStruct, PacketIndex, ref IsoPacket); } /// Convenience function for getting all fields of a \ref KISO_PACKET. public virtual bool GetPacket(int PacketIndex, out KISO_PACKET IsoPacket) { return AllKFunctions.IsoK_GetPacket(mHandleStruct, PacketIndex, out IsoPacket); } /// Convenience function for enumerating ISO packets of an isochronous transfer context. public virtual bool EnumPackets(KISO_ENUM_PACKETS_CB EnumPackets, int StartPacketIndex, IntPtr UserState) { return AllKFunctions.IsoK_EnumPackets(mHandleStruct, EnumPackets, StartPacketIndex, UserState); } /// Convenience function for re-using an isochronous transfer context in a subsequent request. public virtual bool ReUse() { return AllKFunctions.IsoK_ReUse(mHandleStruct); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] private struct KISO_CONTEXT_MAP { /// Additional ISO transfer flags. See \ref KISO_FLAG. private readonly KISO_FLAG Flags; /// Specifies the frame number that the transfer should begin on (0 for ASAP). private readonly uint StartFrame; /// /// Contains the number of packets that completed with an error condition on return from the host controller /// driver. /// private readonly short ErrorCount; /// Specifies the number of packets that are described by the variable-length array member \c IsoPacket. private readonly short NumberOfPackets; /// Contains the URB Hdr.Status value on return from the host controller driver. private readonly uint UrbHdrStatus; } } public class IsochK : IDisposable { protected bool mbDisposed; protected KISOCH_HANDLE mHandleStruct; protected IsochK() { } /// Creates a new isochronous transfer handle for libusbK or WinUSB. public IsochK(KUSB_HANDLE InterfaceHandle, byte PipeId, uint MaxNumberOfPackets, IntPtr TransferBuffer, uint TransferBufferSize) { bool success = AllKFunctions.IsochK_Init(out mHandleStruct, InterfaceHandle, PipeId, MaxNumberOfPackets, TransferBuffer, TransferBufferSize); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); } /// Gets the handle class structure. public KISOCH_HANDLE Handle { get { return mHandleStruct; } } /// Explicitly closes and frees the handle. public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~IsochK() { Dispose(false); } /// Calls the dispose method. public virtual void Free() { Dispose(); } protected virtual void Dispose(bool disposing) { if (!mbDisposed) { if (mHandleStruct.Pointer != IntPtr.Zero) { AllKFunctions.IsochK_Free(mHandleStruct); Debug.Print("{0} Dispose: Freed Handle:{1:X16}h Explicit:{2}", GetType().Name, mHandleStruct.Pointer.ToInt64(), disposing); } else { Debug.Print("{0} Dispose: [WARNING] Handle is null", GetType().Name); } mHandleStruct = new KISOCH_HANDLE(IntPtr.Zero); mbDisposed = true; } } /// Creates a new isochronous transfer handle for libusbK or WinUSB. protected bool Init(KUSB_HANDLE InterfaceHandle, byte PipeId, uint MaxNumberOfPackets, IntPtr TransferBuffer, uint TransferBufferSize) { bool success = AllKFunctions.IsochK_Init(out mHandleStruct, InterfaceHandle, PipeId, MaxNumberOfPackets, TransferBuffer, TransferBufferSize); if (!success) throw new Exception(string.Format("{0} failed initializing. ErrorCode={1:X8}h", GetType().Name, Marshal.GetLastWin32Error())); Debug.Print("{0} Init: handle 0x{1:X16}", GetType().Name, mHandleStruct.Pointer.ToInt64()); return true; } /// Convenience function for setting the offsets and lengths of all ISO packets of an isochronous transfer handle. public virtual bool SetPacketOffsets(uint PacketSize) { return AllKFunctions.IsochK_SetPacketOffsets(mHandleStruct, PacketSize); } /// Convenience function for setting all fields in an isochronous transfer packet. public virtual bool SetPacket(uint PacketIndex, uint Offset, uint Length, uint Status) { return AllKFunctions.IsochK_SetPacket(mHandleStruct, PacketIndex, Offset, Length, Status); } /// Convenience function for getting all fields in an isochronous transfer packet. public virtual bool GetPacket(uint PacketIndex, out uint Offset, out uint Length, out uint Status) { return AllKFunctions.IsochK_GetPacket(mHandleStruct, PacketIndex, out Offset, out Length, out Status); } /// Convenience function for enumerating ISO packets of an isochronous transfer context. public virtual bool EnumPackets(KISOCH_ENUM_PACKETS_CB EnumPackets, uint StartPacketIndex, IntPtr UserState) { return AllKFunctions.IsochK_EnumPackets(mHandleStruct, EnumPackets, StartPacketIndex, UserState); } /// Helper function for isochronous packet/transfer calculations. public static bool CalcPacketInformation(bool IsHighSpeed, ref WINUSB_PIPE_INFORMATION_EX PipeInformationEx, out KISOCH_PACKET_INFORMATION PacketInformation) { return AllKFunctions.IsochK_CalcPacketInformation(IsHighSpeed, ref PipeInformationEx, out PacketInformation); } /// Gets the number of iso packets that will be used. public virtual bool GetNumberOfPackets(out uint NumberOfPackets) { return AllKFunctions.IsochK_GetNumberOfPackets(mHandleStruct, out NumberOfPackets); } /// Sets the number of iso packets that will be used. public virtual bool SetNumberOfPackets(uint NumberOfPackets) { return AllKFunctions.IsochK_SetNumberOfPackets(mHandleStruct, NumberOfPackets); } } }