Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Rikitav/Unified.Firmware/llms.txt

Use this file to discover all available pages before exploring further.

IFirmwareBackend is the platform abstraction layer that decouples high-level UEFI logic from OS-specific system calls. Every operation that touches firmware — checking availability, locating the EFI System Partition, reading NVRAM variables, writing NVRAM variables — is funnelled through a single implementation of this interface. The library ships two built-in implementations selected automatically by FirmwareInterface.CurrentBackend, but the interface is public so you can supply your own backend for custom platforms, unit testing, or CI environments. Namespace: Unified.Firmware

Built-in Implementations

Win32PlatformBackend

Targets Windows (PlatformID.Win32NT). NVRAM reads and writes are performed via the Win32 API functions GetFirmwareEnvironmentVariableExW and SetFirmwareEnvironmentVariableExW, which require the SE_SYSTEM_ENVIRONMENT_NAME privilege (Administrator). The EFI System Partition is located by enumerating volumes and sending an IOCTL_STORAGE_GET_DEVICE_NUMBER + partition-type query to identify the GPT ESP entry.

LinuxPlatfromBackend

Targets Linux (PlatformID.Unix). NVRAM variables are read from and written to the kernel’s efivars filesystem at /sys/firmware/efi/efivars/. Each variable is represented as a file named <VarName>-<VendorGUID>. The EFI System Partition is located by enumerating block devices and inspecting GPT partition type GUIDs via ioctl. Root privileges or CAP_SYS_ADMIN are required.
FirmwareInterface.CurrentBackend selects the correct implementation automatically based on Environment.OSVersion.Platform. You never need to instantiate a backend class directly unless you are supplying a custom implementation.

Methods

CheckFirmwareAvailablity

Returns true if the system is running in UEFI mode and the firmware is accessible, or false if the system booted in Legacy BIOS mode or the required OS APIs are unavailable.
bool CheckFirmwareAvailablity();
returns
bool
true if UEFI firmware is available and accessible; false otherwise.
IFirmwareBackend backend = FirmwareInterface.CurrentBackend;

if (backend.CheckFirmwareAvailablity())
    Console.WriteLine("UEFI is available.");
else
    Console.WriteLine("Legacy BIOS or inaccessible firmware.");

FindEfiSystemPartition

Locates the EFI System Partition among the system volumes and returns a VolumePath that identifies it. On Windows this is a volume GUID path (e.g. \\?\Volume{...}\); on Linux it is the mount point or block device path for the ESP.
VolumePath FindEfiSystemPartition();
returns
VolumePath
A VolumePath value identifying the EFI System Partition. FirmwareInterface.SystemPartition wraps this result as a DirectoryInfo.
ThrowsCondition
PlatformNotSupportedExceptionNo EFI System Partition was found, or the system is not UEFI.
FirmwareEnvironmentExceptionThe partition enumeration failed at the OS layer.
VolumePath esp = FirmwareInterface.CurrentBackend.FindEfiSystemPartition();
Console.WriteLine($"ESP volume path: {esp}");

ReadEnvironmentVariable

Reads a UEFI NVRAM variable and returns a pointer to a heap-allocated buffer containing the raw variable bytes. The caller is responsible for freeing this memory with Marshal.FreeHGlobal once the data has been consumed.
IntPtr ReadEnvironmentVariable(
    string varName,
    Guid environmentIdentificator,
    out VariableAttributes attributes,
    int bufferSize,
    out uint dataSize);
varName
string
required
The name of the firmware environment variable to read. Must not be null or empty.
environmentIdentificator
Guid
required
The GUID identifying the variable namespace (vendor). Pass FirmwareVendors.GlobalVariable for standard UEFI variables, or a vendor-specific GUID for OEM variables.
attributes
VariableAttributes
required
Output parameter. Contains the VariableAttributes flags for the variable when the method returns.
bufferSize
int
required
The maximum number of bytes to allocate and read into the buffer. Must be large enough to hold the variable value; FirmwareEnvironment passes Marshal.SizeOf<T>() for structs and 2 * 1024 for strings.
dataSize
uint
required
Output parameter. Contains the actual byte size of the data written into the buffer when the method returns. Used by ReadArrayVariable to determine array element count.
returns
IntPtr
A pointer to a heap-allocated block of memory containing the raw variable data. The caller must free this pointer with Marshal.FreeHGlobal.
ThrowsCondition
PlatformNotSupportedExceptionThe firmware is unavailable or the OS API is not accessible.
FirmwareEnvironmentExceptionThe variable was not found or the read operation failed.
ReadEnvironmentVariable allocates unmanaged heap memory and returns the raw pointer. You must call Marshal.FreeHGlobal(pointer) after you have finished using the data, or you will leak native memory. The higher-level FirmwareEnvironment read methods (ReadVariable<T>, ReadStringVariable, ReadArrayVariable<T>) handle allocation and deallocation for you — prefer them over calling this method directly.
using System;
using System.Runtime.InteropServices;
using Unified.Firmware;

IFirmwareBackend backend = FirmwareInterface.CurrentBackend;
Guid globalGuid = new Guid("8BE4DF61-93CA-11D2-AA0D-00E098032B8C");

IntPtr ptr = backend.ReadEnvironmentVariable(
    "Timeout",
    globalGuid,
    out VariableAttributes attrs,
    bufferSize: sizeof(ushort),
    out uint dataSize);

try
{
    ushort timeout = Marshal.PtrToStructure<ushort>(ptr);
    Console.WriteLine($"Timeout = {timeout}s, Attributes = {attrs}, DataSize = {dataSize}");
}
finally
{
    // Always free the returned pointer
    Marshal.FreeHGlobal(ptr);
}

WriteEnvironmentVariable

Writes a raw byte buffer to NVRAM as a UEFI variable. The variable is stored non-volatilely (subject to the attributes flags) and will persist across reboots.
void WriteEnvironmentVariable(
    string varName,
    Guid environmentIdentificator,
    VariableAttributes attributes,
    IntPtr valueBuffer,
    int bufferSize);
varName
string
required
The name of the firmware environment variable to write. Must not be null or empty.
environmentIdentificator
Guid
required
The GUID identifying the variable namespace (vendor).
attributes
VariableAttributes
required
The attribute flags to associate with the variable. Use NON_VOLATILE | BOOTSERVICE_ACCESS | RUNTIME_ACCESS for standard persistent UEFI variables.
valueBuffer
IntPtr
required
A pointer to the buffer containing the bytes to write. The buffer must remain valid and pinned for the duration of this call.
bufferSize
int
required
The number of bytes in valueBuffer to write.
ThrowsCondition
PlatformNotSupportedExceptionThe firmware is unavailable or the OS API is not accessible.
FirmwareEnvironmentExceptionThe write operation failed (for example, insufficient privilege, read-only variable, or invalid attributes).
using System;
using System.Runtime.InteropServices;
using Unified.Firmware;

IFirmwareBackend backend = FirmwareInterface.CurrentBackend;
Guid globalGuid = new Guid("8BE4DF61-93CA-11D2-AA0D-00E098032B8C");

ushort newTimeout = 5;
int size = Marshal.SizeOf<ushort>();
IntPtr ptr = Marshal.AllocHGlobal(size);

try
{
    Marshal.StructureToPtr(newTimeout, ptr, false);

    backend.WriteEnvironmentVariable(
        "Timeout",
        globalGuid,
        VariableAttributes.NON_VOLATILE |
        VariableAttributes.BOOTSERVICE_ACCESS |
        VariableAttributes.RUNTIME_ACCESS,
        ptr,
        size);

    Console.WriteLine("Timeout written successfully.");
}
finally
{
    Marshal.FreeHGlobal(ptr);
}

Custom Implementation Skeleton

Implement IFirmwareBackend to support a platform that neither of the built-in backends covers — for example, an embedded environment, a firmware emulator, or a test double.
using System;
using System.Runtime.InteropServices;
using Unified.Firmware;

/// <summary>
/// Example stub backend — replace each method body with real platform calls.
/// </summary>
public class MyCustomBackend : IFirmwareBackend
{
    /// <inheritdoc/>
    public bool CheckFirmwareAvailablity()
    {
        // Return true if your platform exposes UEFI variables
        return true;
    }

    /// <inheritdoc/>
    public VolumePath FindEfiSystemPartition()
    {
        // Locate the ESP on your platform and return its path
        throw new PlatformNotSupportedException("ESP enumeration not implemented.");
    }

    /// <inheritdoc/>
    public IntPtr ReadEnvironmentVariable(
        string varName,
        Guid environmentIdentificator,
        out VariableAttributes attributes,
        int bufferSize,
        out uint dataSize)
    {
        // Allocate a buffer, fill it with the variable data, set attributes and dataSize
        // The caller (FirmwareEnvironment) will free the returned pointer.
        attributes = VariableAttributes.None;
        dataSize = 0;

        IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
        // TODO: populate buffer from your platform's NVRAM API
        return buffer;
    }

    /// <inheritdoc/>
    public void WriteEnvironmentVariable(
        string varName,
        Guid environmentIdentificator,
        VariableAttributes attributes,
        IntPtr valueBuffer,
        int bufferSize)
    {
        // Write bufferSize bytes from valueBuffer to your platform's NVRAM
        throw new NotImplementedException("WriteEnvironmentVariable not implemented.");
    }
}

// Register the custom backend by passing it directly to FirmwareEnvironment
var env = new FirmwareEnvironment(new MyCustomBackend(), FirmwareVendors.GlobalVariable);
ushort timeout = env.ReadVariable<ushort>("Timeout", out _);
Console.WriteLine($"Timeout = {timeout}");
When writing a test double, have CheckFirmwareAvailablity() return false to keep unit tests isolated from real firmware. FirmwareInterface.Available will then return false, and all guarded operations will short-circuit without touching NVRAM.

Build docs developers (and LLMs) love