Skip to content

Instantly share code, notes, and snippets.

@smourier
Created July 17, 2023 13:02
Show Gist options
  • Save smourier/d0911bbb2ef7c6714734781036cd0b2d to your computer and use it in GitHub Desktop.
Save smourier/d0911bbb2ef7c6714734781036cd0b2d to your computer and use it in GitHub Desktop.
Dump system firmware tables.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace ConsoleApp1
{
internal class Program
{
static void Main()
{
Console.WriteLine("ACPI");
foreach (var name in FirmwareTable.EnumerateTables(FirmwareTableProviderSignature.ACPI))
{
Console.WriteLine(" " + name);
FirmwareTable.GetTableBytes(FirmwareTableProviderSignature.ACPI, name);
}
Console.WriteLine("RSMB");
foreach (var name in FirmwareTable.EnumerateTables(FirmwareTableProviderSignature.RSMB))
{
Console.WriteLine(" " + name);
FirmwareTable.GetTableBytes(FirmwareTableProviderSignature.ACPI, name);
}
Console.WriteLine("FIRM");
foreach (var name in FirmwareTable.EnumerateTables(FirmwareTableProviderSignature.FIRM))
{
Console.WriteLine(" " + name);
FirmwareTable.GetTableBytes(FirmwareTableProviderSignature.ACPI, name);
}
}
public static class FirmwareTable
{
public static byte[] GetTableBytes(FirmwareTableProviderSignature signature, string table) => GetTableBytes(signature, table[3] << 24 | table[2] << 16 | table[1] << 8 | table[0]);
public static byte[] GetTableBytes(FirmwareTableProviderSignature signature, int table)
{
var size = GetSystemFirmwareTable(signature, table, IntPtr.Zero, 0);
if (size <= 0)
return null;
var ptr = Marshal.AllocHGlobal(size);
try
{
GetSystemFirmwareTable(signature, table, ptr, size);
if (Marshal.GetLastWin32Error() != 0)
return null;
var buffer = new byte[size];
Marshal.Copy(ptr, buffer, 0, size);
return buffer;
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
public static IReadOnlyList<string> EnumerateTables(FirmwareTableProviderSignature provider)
{
var size = EnumSystemFirmwareTables(provider, IntPtr.Zero, 0);
if (size <= 0)
return Array.Empty<string>();
var ptr = Marshal.AllocHGlobal(size);
try
{
EnumSystemFirmwareTables(provider, ptr, size);
var buffer = new byte[size];
Marshal.Copy(ptr, buffer, 0, size);
var list = new string[size / 4];
for (var i = 0; i < list.Length; i++)
{
list[i] = Encoding.ASCII.GetString(buffer, 4 * i, 4);
}
return list;
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
[DllImport("kernel32")]
private static extern int GetSystemFirmwareTable(FirmwareTableProviderSignature FirmwareTableProviderSignature, int FirmwareTableID, IntPtr pFirmwareTableBuffer, int BufferSize);
[DllImport("kernel32")]
private static extern int EnumSystemFirmwareTables(FirmwareTableProviderSignature FirmwareTableProviderSignature, IntPtr pFirmwareTableEnumBuffer, int BufferSize);
}
public enum FirmwareTableProviderSignature : int
{
ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I',
FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M',
RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B'
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment