Hardware/FirmwareTable.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 308 d882720734bf
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@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
}