Search code examples
c#winapibiosuefi

How do I detect if the current Windows is installed in UEFI or legacy mode


My Goal is to simply get, if the current Windows installation is in UEFI or legacy mode. Manually I could just run msinfo32 and look at the "Bios-Mode" row. My current approach is by checking if the "HKLM\SYSTEM\CurrentControlSet\Control\SecureBoot" key exists, but I'm not sure if that's a good approach.

I have already tried looking at quite some WMI classes and properties but neither of them had the information I needed. I read that you could use GetFirmwareType() but it seems like that had been introduced in Windows 8 and I want it to run on Windows 7 as well. I also tried the method microsoft gave me, calling GetFirmwareEnvironmentVariableA with a dummy variable and a dummy namespace.

public const int ERROR_INVALID_FUNCTION = 1;

[DllImport("kernel32.dll",
    EntryPoint = "GetFirmwareEnvironmentVariableA",
    SetLastError = true,
    CharSet = CharSet.Unicode,
    ExactSpelling = true,
    CallingConvention = CallingConvention.StdCall)]
public static extern int GetFirmwareType(string lpName, string lpGUID, IntPtr pBuffer, uint size);

public static bool IsWindowsUEFI()
{
    // Call the function with a dummy variable name and a dummy variable namespace (function will fail because these don't exist.)
    GetFirmwareType("", "{00000000-0000-0000-0000-000000000000}", IntPtr.Zero, 0);

    if (Marshal.GetLastWin32Error() == ERROR_INVALID_FUNCTION)
    {
        // Calling the function threw an ERROR_INVALID_FUNCTION win32 error, which gets thrown if either
        // - The mainboard doesn't support UEFI and/or
        // - Windows is installed in legacy BIOS mode
        return false;
    }
    else
    {
        // If the system supports UEFI and Windows is installed in UEFI mode it doesn't throw the above error, but a more specific UEFI error
        return true;
    }
}

It told me when I get ERROR_INVALID_FUNCTION, I am running legacy, otherwise it will return a different, more specific error. All I ever got from that code was ERROR_INVALID_PARAMETER on any type of system and I don't know where my mistake is.


Solution

  • That was just a Typo.

    3   [DllImport("kernel32.dll",
    4 >     EntryPoint = "GetFirmwareEnvironmentVariableA",
    5       SetLastError = true,                        ^
    

    Replace the A pointed by the > and the ^ with a W.