Hardware/TBalancer/FTD2XX.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 195 0ee888c485d5
child 384 76f859f4aea1
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
moel@87
     1
/*
moel@87
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@87
     6
 
moel@344
     7
  Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@87
     9
*/
moel@87
    10
moel@87
    11
using System;
moel@87
    12
using System.Runtime.InteropServices;
moel@87
    13
moel@87
    14
namespace OpenHardwareMonitor.Hardware.TBalancer {
moel@87
    15
moel@165
    16
  internal enum FT_DEVICE : uint {
moel@186
    17
    FT_DEVICE_232BM,
moel@186
    18
    FT_DEVICE_232AM,
moel@87
    19
    FT_DEVICE_100AX,
moel@87
    20
    FT_DEVICE_UNKNOWN,
moel@186
    21
    FT_DEVICE_2232C,
moel@87
    22
    FT_DEVICE_232R,
moel@87
    23
    FT_DEVICE_2232H,
moel@87
    24
    FT_DEVICE_4232H
moel@87
    25
  }
moel@87
    26
moel@165
    27
  internal enum FT_STATUS {
moel@87
    28
    FT_OK,
moel@87
    29
    FT_INVALID_HANDLE,
moel@87
    30
    FT_DEVICE_NOT_FOUND,
moel@87
    31
    FT_DEVICE_NOT_OPENED,
moel@87
    32
    FT_IO_ERROR,
moel@87
    33
    FT_INSUFFICIENT_RESOURCES,
moel@87
    34
    FT_INVALID_PARAMETER,
moel@87
    35
    FT_INVALID_BAUD_RATE,
moel@87
    36
    FT_DEVICE_NOT_OPENED_FOR_ERASE,
moel@87
    37
    FT_DEVICE_NOT_OPENED_FOR_WRITE,
moel@87
    38
    FT_FAILED_TO_WRITE_DEVICE,
moel@87
    39
    FT_EEPROM_READ_FAILED,
moel@87
    40
    FT_EEPROM_WRITE_FAILED,
moel@87
    41
    FT_EEPROM_ERASE_FAILED,
moel@87
    42
    FT_EEPROM_NOT_PRESENT,
moel@87
    43
    FT_EEPROM_NOT_PROGRAMMED,
moel@87
    44
    FT_INVALID_ARGS,
moel@87
    45
    FT_OTHER_ERROR
moel@87
    46
  }
moel@87
    47
moel@165
    48
  internal enum FT_FLOW_CONTROL : ushort {
moel@87
    49
    FT_FLOW_DTR_DSR = 512,
moel@87
    50
    FT_FLOW_NONE = 0,
moel@87
    51
    FT_FLOW_RTS_CTS = 256,
moel@87
    52
    FT_FLOW_XON_XOFF = 1024,
moel@87
    53
  }
moel@87
    54
moel@165
    55
  internal enum FT_PURGE : uint {
moel@87
    56
    FT_PURGE_RX = 1,
moel@87
    57
    FT_PURGE_TX = 2,
moel@87
    58
    FT_PURGE_ALL = 3,
moel@87
    59
  }
moel@87
    60
moel@87
    61
  [StructLayout(LayoutKind.Sequential)]
moel@165
    62
  internal struct FT_HANDLE {
moel@195
    63
    private readonly uint handle;
moel@87
    64
  }
moel@87
    65
moel@87
    66
  [StructLayout(LayoutKind.Sequential)]
moel@165
    67
  internal struct FT_DEVICE_INFO_NODE {    
moel@87
    68
    public uint Flags;
moel@87
    69
    public FT_DEVICE Type; 
moel@87
    70
    public uint ID; 
moel@87
    71
    public uint LocId; 
moel@87
    72
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
moel@87
    73
    public string SerialNumber; 
moel@87
    74
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
moel@87
    75
    public string Description;
moel@87
    76
    public FT_HANDLE Handle;
moel@87
    77
  }
moel@87
    78
moel@165
    79
  internal class FTD2XX {
moel@87
    80
moel@87
    81
    public delegate FT_STATUS FT_CreateDeviceInfoListDelegate(
moel@87
    82
      out uint numDevices);
moel@87
    83
    public delegate FT_STATUS FT_GetDeviceInfoListDelegate(
moel@87
    84
      [Out] FT_DEVICE_INFO_NODE[] deviceInfoNodes, ref uint length);
moel@87
    85
    public delegate FT_STATUS FT_OpenDelegate(int device, out FT_HANDLE handle);
moel@87
    86
    public delegate FT_STATUS FT_CloseDelegate(FT_HANDLE handle);
moel@87
    87
    public delegate FT_STATUS FT_SetBaudRateDelegate(FT_HANDLE handle,
moel@87
    88
      uint baudRate);
moel@87
    89
    public delegate FT_STATUS FT_SetDataCharacteristicsDelegate(
moel@87
    90
      FT_HANDLE handle, byte wordLength, byte stopBits, byte parity);
moel@87
    91
    public delegate FT_STATUS FT_SetFlowControlDelegate(FT_HANDLE handle,
moel@87
    92
      FT_FLOW_CONTROL flowControl, byte xon, byte xoff);
moel@87
    93
    public delegate FT_STATUS FT_SetTimeoutsDelegate(FT_HANDLE handle,
moel@87
    94
      uint readTimeout, uint writeTimeout);
moel@87
    95
    public delegate FT_STATUS FT_WriteDelegate(FT_HANDLE handle, byte[] buffer,
moel@87
    96
      uint bytesToWrite, out uint bytesWritten);
moel@87
    97
    public delegate FT_STATUS FT_PurgeDelegate(FT_HANDLE handle, FT_PURGE mask);
moel@87
    98
    public delegate FT_STATUS FT_GetStatusDelegate(FT_HANDLE handle,
moel@87
    99
      out uint amountInRxQueue, out uint amountInTxQueue, out uint eventStatus);
moel@87
   100
    public delegate FT_STATUS FT_ReadDelegate(FT_HANDLE handle, 
moel@87
   101
      [Out] byte[] buffer, uint bytesToRead, out uint bytesReturned);
moel@87
   102
moel@167
   103
    public static readonly FT_CreateDeviceInfoListDelegate 
moel@167
   104
      FT_CreateDeviceInfoList = CreateDelegate<
moel@167
   105
      FT_CreateDeviceInfoListDelegate>("FT_CreateDeviceInfoList");
moel@167
   106
    public static readonly FT_GetDeviceInfoListDelegate 
moel@167
   107
      FT_GetDeviceInfoList = CreateDelegate<
moel@167
   108
      FT_GetDeviceInfoListDelegate>("FT_GetDeviceInfoList");
moel@167
   109
    public static readonly FT_OpenDelegate 
moel@167
   110
      FT_Open = CreateDelegate<
moel@167
   111
      FT_OpenDelegate>("FT_Open");
moel@167
   112
    public static readonly FT_CloseDelegate 
moel@167
   113
      FT_Close = CreateDelegate<
moel@167
   114
      FT_CloseDelegate>("FT_Close");
moel@167
   115
    public static readonly FT_SetBaudRateDelegate 
moel@167
   116
      FT_SetBaudRate = CreateDelegate<
moel@167
   117
      FT_SetBaudRateDelegate>("FT_SetBaudRate");
moel@167
   118
    public static readonly FT_SetDataCharacteristicsDelegate 
moel@167
   119
      FT_SetDataCharacteristics = CreateDelegate<
moel@167
   120
      FT_SetDataCharacteristicsDelegate>("FT_SetDataCharacteristics");
moel@167
   121
    public static readonly FT_SetFlowControlDelegate 
moel@167
   122
      FT_SetFlowControl = CreateDelegate<
moel@167
   123
      FT_SetFlowControlDelegate>("FT_SetFlowControl");
moel@167
   124
    public static readonly FT_SetTimeoutsDelegate 
moel@167
   125
      FT_SetTimeouts = CreateDelegate<
moel@167
   126
      FT_SetTimeoutsDelegate>("FT_SetTimeouts");
moel@167
   127
    public static readonly FT_WriteDelegate 
moel@167
   128
      FT_Write = CreateDelegate<
moel@167
   129
      FT_WriteDelegate>("FT_Write");
moel@167
   130
    public static readonly FT_PurgeDelegate 
moel@167
   131
      FT_Purge = CreateDelegate<
moel@167
   132
      FT_PurgeDelegate>("FT_Purge");
moel@167
   133
    public static readonly FT_GetStatusDelegate 
moel@167
   134
      FT_GetStatus = CreateDelegate<
moel@167
   135
      FT_GetStatusDelegate>("FT_GetStatus");
moel@167
   136
    public static readonly FT_ReadDelegate 
moel@167
   137
      FT_Read = CreateDelegate<
moel@167
   138
      FT_ReadDelegate>("FT_Read");
moel@167
   139
moel@167
   140
    private FTD2XX() { }
moel@87
   141
moel@87
   142
    public static FT_STATUS Write(FT_HANDLE handle, byte[] buffer) {
moel@87
   143
      uint bytesWritten;
moel@87
   144
      FT_STATUS status = FT_Write(handle, buffer, (uint)buffer.Length, 
moel@87
   145
        out bytesWritten);
moel@87
   146
      if (bytesWritten != buffer.Length)
moel@87
   147
        return FT_STATUS.FT_FAILED_TO_WRITE_DEVICE;
moel@87
   148
      else
moel@87
   149
        return status;
moel@87
   150
    }
moel@87
   151
moel@87
   152
    public static int BytesToRead(FT_HANDLE handle) {
moel@87
   153
      uint amountInRxQueue;
moel@87
   154
      uint amountInTxQueue;
moel@87
   155
      uint eventStatus;
moel@87
   156
      if (FT_GetStatus(handle, out amountInRxQueue, out amountInTxQueue,
moel@87
   157
        out eventStatus) == FT_STATUS.FT_OK) {
moel@87
   158
        return (int)amountInRxQueue;
moel@87
   159
      } else {
moel@87
   160
        return 0;
moel@87
   161
      }
moel@87
   162
    }
moel@87
   163
moel@87
   164
    public static byte ReadByte(FT_HANDLE handle) {
moel@87
   165
      byte[] buffer = new byte[1];
moel@87
   166
      uint bytesReturned;
moel@87
   167
      FT_STATUS status = FT_Read(handle, buffer, 1, out bytesReturned);
moel@87
   168
      if (status != FT_STATUS.FT_OK || bytesReturned != 1)
moel@167
   169
        throw new InvalidOperationException();
moel@87
   170
      return buffer[0];
moel@87
   171
    }
moel@87
   172
moel@167
   173
    private static string GetDllName() {
moel@195
   174
      int p = (int)Environment.OSVersion.Platform;
moel@167
   175
      if ((p == 4) || (p == 128))
moel@167
   176
        return "libftd2xx.so";
moel@167
   177
      else
moel@167
   178
        return "ftd2xx.dll";
moel@167
   179
    }
moel@87
   180
moel@167
   181
    private static T CreateDelegate<T>(string entryPoint)
moel@87
   182
      where T : class {
moel@167
   183
      DllImportAttribute attribute = new DllImportAttribute(GetDllName());
moel@87
   184
      attribute.CallingConvention = CallingConvention.StdCall;
moel@87
   185
      attribute.PreserveSig = true;
moel@87
   186
      attribute.EntryPoint = entryPoint;
moel@167
   187
      T newDelegate;
moel@87
   188
      PInvokeDelegateFactory.CreateDelegate(attribute, out newDelegate);
moel@167
   189
      return newDelegate;
moel@87
   190
    }
moel@87
   191
  }
moel@87
   192
}