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