Hardware/FirmwareTable.cs
author moel.mich
Sat, 31 Dec 2011 17:31:04 +0000
changeset 324 c6ee430d6995
child 344 3145aadca3d2
permissions -rw-r--r--
Modified and extended version of the patch v4 by Roland Reinl (see Issue 256). Main differences to the original patch: DeviceIoControl refactorings removed, SmartAttribute is now descriptive only and does not hold any state, report is written as one 80 columns table, sensors are created only for meaningful values and without duplicates (remaining life, temperatures, host writes and reads). Also the current implementation should really preserve all the functionality of the old system. Additionally there is now a simple SMART devices emulation class (DebugSmart) that can be used in place of WindowsSmart for testing with reported data.
moel@308
     1
/*
moel@308
     2
  
moel@308
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@308
     4
moel@308
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@308
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@308
     7
  the License. You may obtain a copy of the License at
moel@308
     8
 
moel@308
     9
  http://www.mozilla.org/MPL/
moel@308
    10
moel@308
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@308
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@308
    13
  for the specific language governing rights and limitations under the License.
moel@308
    14
moel@308
    15
  The Original Code is the Open Hardware Monitor code.
moel@308
    16
moel@308
    17
  The Initial Developer of the Original Code is 
moel@308
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@308
    19
  Portions created by the Initial Developer are Copyright (C) 2011
moel@308
    20
  the Initial Developer. All Rights Reserved.
moel@308
    21
moel@308
    22
  Contributor(s):
moel@308
    23
moel@308
    24
  Alternatively, the contents of this file may be used under the terms of
moel@308
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@308
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@308
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@308
    28
  of those above. If you wish to allow use of your version of this file only
moel@308
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@308
    30
  use your version of this file under the terms of the MPL, indicate your
moel@308
    31
  decision by deleting the provisions above and replace them with the notice
moel@308
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@308
    33
  the provisions above, a recipient may use your version of this file under
moel@308
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@308
    35
 
moel@308
    36
*/
moel@308
    37
moel@308
    38
using System;
moel@308
    39
using System.ComponentModel;
moel@308
    40
using System.Runtime.InteropServices;
moel@308
    41
using System.Text;
moel@308
    42
moel@308
    43
namespace OpenHardwareMonitor.Hardware {
moel@308
    44
moel@308
    45
  internal static class FirmwareTable {
moel@308
    46
moel@308
    47
    public static byte[] GetTable(Provider provider, string table) {
moel@308
    48
      int id = table[3] << 24 | table[2] << 16 | table[1] << 8 | table[0];
moel@308
    49
      return GetTable(provider, id);
moel@308
    50
    }
moel@308
    51
moel@308
    52
    public static byte[] GetTable(Provider provider, int table) {
moel@308
    53
      
moel@308
    54
      int size;
moel@308
    55
      try {
moel@308
    56
        size = NativeMethods.GetSystemFirmwareTable(provider, table, 
moel@308
    57
          IntPtr.Zero, 0);
moel@308
    58
      } catch (DllNotFoundException) { return null; } 
moel@308
    59
        catch (EntryPointNotFoundException) { return null; }
moel@308
    60
moel@308
    61
      if (size <= 0)
moel@308
    62
        return null;
moel@308
    63
moel@308
    64
      IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
moel@308
    65
      NativeMethods.GetSystemFirmwareTable(provider, table, nativeBuffer, size);
moel@308
    66
moel@308
    67
      if (Marshal.GetLastWin32Error() != 0)
moel@308
    68
        return null;
moel@308
    69
moel@308
    70
      byte[] buffer = new byte[size];
moel@308
    71
      Marshal.Copy(nativeBuffer, buffer, 0, size);
moel@308
    72
      Marshal.FreeHGlobal(nativeBuffer);
moel@308
    73
moel@308
    74
      return buffer;
moel@308
    75
    }
moel@308
    76
moel@308
    77
    public static string[] EnumerateTables(Provider provider) {
moel@308
    78
      int size;
moel@308
    79
      try {
moel@308
    80
        size = NativeMethods.EnumSystemFirmwareTables(
moel@308
    81
          provider, IntPtr.Zero, 0);
moel@308
    82
      } catch (DllNotFoundException) { return null; } 
moel@308
    83
        catch (EntryPointNotFoundException) { return null; }
moel@308
    84
moel@308
    85
      IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
moel@308
    86
      NativeMethods.EnumSystemFirmwareTables(
moel@308
    87
        provider, nativeBuffer, size);
moel@308
    88
      byte[] buffer = new byte[size];
moel@308
    89
      Marshal.Copy(nativeBuffer, buffer, 0, size);
moel@308
    90
      Marshal.FreeHGlobal(nativeBuffer);
moel@308
    91
moel@308
    92
      string[] result = new string[size / 4];
moel@308
    93
      for (int i = 0; i < result.Length; i++) 
moel@308
    94
        result[i] = Encoding.ASCII.GetString(buffer, 4 * i, 4);
moel@308
    95
moel@308
    96
      return result;
moel@308
    97
    }
moel@308
    98
moel@308
    99
    public enum Provider : int {
moel@308
   100
      ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I',
moel@308
   101
      FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M',
moel@308
   102
      RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B'
moel@308
   103
    }
moel@308
   104
moel@308
   105
    private static class NativeMethods {
moel@308
   106
      private const string KERNEL = "kernel32.dll";
moel@308
   107
moel@308
   108
      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
moel@308
   109
        SetLastError = true)]
moel@308
   110
      public static extern int EnumSystemFirmwareTables(
moel@308
   111
        Provider firmwareTableProviderSignature,
moel@308
   112
        IntPtr firmwareTableBuffer, int bufferSize);
moel@308
   113
moel@308
   114
      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
moel@308
   115
        SetLastError = true)]
moel@308
   116
      public static extern int GetSystemFirmwareTable(
moel@308
   117
        Provider firmwareTableProviderSignature,
moel@308
   118
        int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize);
moel@308
   119
    }
moel@308
   120
  }
moel@308
   121
}