RE: EFI INVESTIGATION

All development related issues welcome

Moderator: Moderator Team

Post Reply
untermensch
Posts: 2
Joined: Thu Feb 02, 2012 6:57 pm

RE: EFI INVESTIGATION

Post by untermensch »

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);
you can then create and array of pointers to the boot entries like this.

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);
}
then I have been dumping the boot entries to files with this code

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();
	}
}
I'd like to thank the developers for the NDK, I am working on creating boot entries from scratch, similar to how bcdedit.exe
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.
.

untermensch
Posts: 2
Joined: Thu Feb 02, 2012 6:57 pm

Re: RE: EFI INVESTIGATION

Post by untermensch »

I found the answer to my question

Code: Select all

typedef struct _FILE_PATH
{
    ULONG Version;
    ULONG Length;
    ULONG Type;
    CHAR FilePath[1];
} FILE_PATH, *PFILE_PATH;
the FilePath[] field is of the type EFI_DEVICE_PATH_PROTOCOL and is an EFI type and can be found in UEFI Specification Version 2.3.1

Code: Select all

http://www.uefi.org/specs/
and can be found starting on page 261

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests