gburanov wrote:Hello everybody.
I am not really sure if it is a right place to ask, but still I try.
I am investigating UEFI for Windows, and I need simple task: Add/Delete/Enumerate Firmware Entries.
I found out following code here:
//
// Firmware Boot Entry
//
typedef struct _BOOT_ENTRY
{
ULONG Version;
ULONG Length;
ULONG Id;
ULONG Attributes;
ULONG FriendlyNameOffset;
ULONG BootFilePathOffset;
ULONG OsOptionsLength;
CHAR OsOptions[1];
} BOOT_ENTRY, *PBOOT_ENTRY;
and the way of obtaining it is
NTSYSCALLAPI NTSTATUS NTAPI
NtEnumerateBootEntries(
IN PVOID Buffer,
IN PULONG BufferLength
);
This is absolutely not documented, but i found out that Attributes are not attributes, but UEFI FirmwareBootNumber and Version is second and Length is first (just the opposite as now).
However other fields are not so clear =)
Moreover, the function
NTSYSCALLAPI NTSTATUS NTAPI NtModifyBootEntry(IN PBOOT_ENTRY BootEntry);
always return "Wrong argument", even if I give it the same BOOT_ENTRY I got from NtEnumerateBootEntries.
Have somebody tried to investigate this?
Regards,
Georgy
I realize this is an old thread, but I have also been looking in to this area and I think I can answer OP's question.
when you use NtEnumerateBootEntries the buffer is filled with a data blob with all the boot entries in NVRAM.
Code: Select all
Status = pNtEnumerateBootEntries(NULL,&BufferLength);
UCHAR* Buffer = new UCHAR[BufferLength];
memset(Buffer, 0x0, BufferLength);
Status = pNtEnumerateBootEntries(Buffer, &BufferLength);
Code: Select all
//
// create and array of boot entry pointers.
//
UINT Count;
UINT Length = 0;
Status = pNtQueryBootEntryOrder(NULL, &Count);
PBOOT_ENTRY* BootEntries = new PBOOT_ENTRY[Count];
for (UINT i = 0; i < Count; i++) {
BootEntries[i] = (PBOOT_ENTRY) (Buffer + Length + 4);
Length += *(PULONG) (Buffer + Length);
}
Code: Select all
//
// dump individual boot entries.
//
for (UINT i = 0; i < Count; i++) {
string filename = "entry";
char t[10] = {};
_itoa_s(BootEntries[i]->Id, t, 10);
filename += t;
filename += ".bin";
outfile.open(filename, ios_base::binary);
if (outfile.is_open()) {
outfile.write((char*)BootEntries[i], BootEntries[i]->Length);
outfile.close();
}
}
does it, and I have encountered a slow down with the FILE_PATH structure, where did the dev's find this info? I think that
there is a separate struct for the different FILE_PATH types, and would like to chase down the info rather than reverse it.
.