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