windowsuefi

Is it possible to get a list of UEFI variables in Windows?


I know it's possible to read a UEFI variable with e.g. GetFirmwareEnvironmentVariable() given the name of the variable and the GUID of the namespace. But is it possible to get a list of namespaces and names that are available? Say, e.g. I wanted to write a utility to backup or dump all the variables. Reading documentation and googling has found nothing.


Solution

  • for this possible use NtEnumerateSystemEnvironmentValuesEx and need have SE_SYSTEM_ENVIRONMENT_PRIVILEGE

    demo code of dump all:

    NTSTATUS DumpSystemEnv()
    {
        BOOLEAN b;
        ULONG cb = 0x1000;
    
        NTSTATUS status = RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &b);
        do 
        {
            status = STATUS_NO_MEMORY;
    
            if (PVOID Buffer = LocalAlloc(LMEM_FIXED, cb))
            {
                if (0 <= (status = NtEnumerateSystemEnvironmentValuesEx(SystemEnvironmentValueInformation, Buffer, &cb)))
                {
                    union {
                        PVOID pv;
                        PVARIABLE_NAME_AND_VALUE pvna;
                        ULONG_PTR up;
                        PBYTE pb;
                    };
    
                    pv = Buffer;
    
                    ULONG NextEntryOffset = 0;
    
                    do 
                    {
                        up += NextEntryOffset;
    
                        DbgPrint("%08x:{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} \"%ws\"\n", 
                            pvna->Attributes,
                            pvna->VendorGuid.Data1, 
                            pvna->VendorGuid.Data2, 
                            pvna->VendorGuid.Data3,
                            pvna->VendorGuid.Data4[0],
                            pvna->VendorGuid.Data4[1],
                            pvna->VendorGuid.Data4[2],
                            pvna->VendorGuid.Data4[3],
                            pvna->VendorGuid.Data4[4],
                            pvna->VendorGuid.Data4[5],
                            pvna->VendorGuid.Data4[6],
                            pvna->VendorGuid.Data4[7],
                            pvna->Name);
    
                        PSTR buf = 0;
                        cb = 0;
                        while (CryptBinaryToStringA(pb + pvna->ValueOffset, pvna->ValueLength, CRYPT_STRING_HEXASCII, buf, &cb))
                        {
                            if (buf)
                            {
                                PSTR psz = buf;
                                ULONG len;
                                do 
                                {
                                    DbgPrint("%.*s", len = min(0x80, cb), psz);
                                } while (psz += len, cb -= len);
                                break;
                            }
    
                            if (!(buf = new char[cb]))
                            {
                                break;
                            }
                        }
    
                        if (buf)
                        {
                            delete [] buf;
                        }
    
                    } while (NextEntryOffset = pvna->NextEntryOffset);
                }
                LocalFree(Buffer);
            }
        } while (STATUS_BUFFER_TOO_SMALL == status);
    
        return status;
    }