Hardware/FirmwareTable.cs
author moel.mich
Sun, 04 Aug 2013 06:54:46 +0000
changeset 419 07d44b20bbd4
parent 308 d882720734bf
permissions -rw-r--r--
Fixed an issue in the NCT677X class causing a crash when calling Update.
moel@308
     1
/*
moel@308
     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@308
     6
 
moel@344
     7
  Copyright (C) 2011 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@308
     9
*/
moel@308
    10
moel@308
    11
using System;
moel@308
    12
using System.ComponentModel;
moel@308
    13
using System.Runtime.InteropServices;
moel@308
    14
using System.Text;
moel@308
    15
moel@308
    16
namespace OpenHardwareMonitor.Hardware {
moel@308
    17
moel@308
    18
  internal static class FirmwareTable {
moel@308
    19
moel@308
    20
    public static byte[] GetTable(Provider provider, string table) {
moel@308
    21
      int id = table[3] << 24 | table[2] << 16 | table[1] << 8 | table[0];
moel@308
    22
      return GetTable(provider, id);
moel@308
    23
    }
moel@308
    24
moel@308
    25
    public static byte[] GetTable(Provider provider, int table) {
moel@308
    26
      
moel@308
    27
      int size;
moel@308
    28
      try {
moel@308
    29
        size = NativeMethods.GetSystemFirmwareTable(provider, table, 
moel@308
    30
          IntPtr.Zero, 0);
moel@308
    31
      } catch (DllNotFoundException) { return null; } 
moel@308
    32
        catch (EntryPointNotFoundException) { return null; }
moel@308
    33
moel@308
    34
      if (size <= 0)
moel@308
    35
        return null;
moel@308
    36
moel@308
    37
      IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
moel@308
    38
      NativeMethods.GetSystemFirmwareTable(provider, table, nativeBuffer, size);
moel@308
    39
moel@308
    40
      if (Marshal.GetLastWin32Error() != 0)
moel@308
    41
        return null;
moel@308
    42
moel@308
    43
      byte[] buffer = new byte[size];
moel@308
    44
      Marshal.Copy(nativeBuffer, buffer, 0, size);
moel@308
    45
      Marshal.FreeHGlobal(nativeBuffer);
moel@308
    46
moel@308
    47
      return buffer;
moel@308
    48
    }
moel@308
    49
moel@308
    50
    public static string[] EnumerateTables(Provider provider) {
moel@308
    51
      int size;
moel@308
    52
      try {
moel@308
    53
        size = NativeMethods.EnumSystemFirmwareTables(
moel@308
    54
          provider, IntPtr.Zero, 0);
moel@308
    55
      } catch (DllNotFoundException) { return null; } 
moel@308
    56
        catch (EntryPointNotFoundException) { return null; }
moel@308
    57
moel@308
    58
      IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
moel@308
    59
      NativeMethods.EnumSystemFirmwareTables(
moel@308
    60
        provider, nativeBuffer, size);
moel@308
    61
      byte[] buffer = new byte[size];
moel@308
    62
      Marshal.Copy(nativeBuffer, buffer, 0, size);
moel@308
    63
      Marshal.FreeHGlobal(nativeBuffer);
moel@308
    64
moel@308
    65
      string[] result = new string[size / 4];
moel@308
    66
      for (int i = 0; i < result.Length; i++) 
moel@308
    67
        result[i] = Encoding.ASCII.GetString(buffer, 4 * i, 4);
moel@308
    68
moel@308
    69
      return result;
moel@308
    70
    }
moel@308
    71
moel@308
    72
    public enum Provider : int {
moel@308
    73
      ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I',
moel@308
    74
      FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M',
moel@308
    75
      RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B'
moel@308
    76
    }
moel@308
    77
moel@308
    78
    private static class NativeMethods {
moel@308
    79
      private const string KERNEL = "kernel32.dll";
moel@308
    80
moel@308
    81
      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
moel@308
    82
        SetLastError = true)]
moel@308
    83
      public static extern int EnumSystemFirmwareTables(
moel@308
    84
        Provider firmwareTableProviderSignature,
moel@308
    85
        IntPtr firmwareTableBuffer, int bufferSize);
moel@308
    86
moel@308
    87
      [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
moel@308
    88
        SetLastError = true)]
moel@308
    89
      public static extern int GetSystemFirmwareTable(
moel@308
    90
        Provider firmwareTableProviderSignature,
moel@308
    91
        int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize);
moel@308
    92
    }
moel@308
    93
  }
moel@308
    94
}