|
|
|
@@ -16,9 +16,7 @@ Abstract:
|
|
|
|
|
#include <ntrtl.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
#include "bootlib.h"
|
|
|
|
|
#include "bootmgr.h"
|
|
|
|
|
#include "efi.h"
|
|
|
|
|
#include "efilib.h"
|
|
|
|
|
|
|
|
|
|
UCHAR EfiInitScratch[2048];
|
|
|
|
|
const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
|
|
|
@@ -277,7 +275,7 @@ NTSTATUS
|
|
|
|
|
EfiInitpConvertEfiDevicePath (
|
|
|
|
|
IN EFI_DEVICE_PATH *EfiDevicePath,
|
|
|
|
|
IN BCDE_DATA_TYPE OptionType,
|
|
|
|
|
IN OUT PBOOT_APPLICATION_OPTION Option,
|
|
|
|
|
IN OUT PBOOT_ENTRY_OPTION Option,
|
|
|
|
|
IN ULONG BufferSize
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -309,23 +307,23 @@ Return Value:
|
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
PBCDE_DEVICE DeviceElement;
|
|
|
|
|
|
|
|
|
|
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
|
|
|
|
|
if (BufferSize < sizeof(BOOT_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
|
|
|
|
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_OPTION));
|
|
|
|
|
RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION));
|
|
|
|
|
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_ENTRY_OPTION));
|
|
|
|
|
Status = EfiInitTranslateDevicePath(
|
|
|
|
|
EfiDevicePath,
|
|
|
|
|
&DeviceElement->Device,
|
|
|
|
|
BufferSize - (sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device))
|
|
|
|
|
BufferSize - (sizeof(BOOT_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device))
|
|
|
|
|
);
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
return Status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Option->Type = OptionType;
|
|
|
|
|
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
|
|
|
|
Option->DataOffset = sizeof(BOOT_ENTRY_OPTION);
|
|
|
|
|
Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size;
|
|
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
@@ -335,7 +333,7 @@ NTSTATUS
|
|
|
|
|
EfiInitpConvertEfiFilePath (
|
|
|
|
|
IN EFI_DEVICE_PATH *EfiFilePath,
|
|
|
|
|
IN BCDE_DATA_TYPE OptionType,
|
|
|
|
|
IN OUT PBOOT_APPLICATION_OPTION Option,
|
|
|
|
|
IN OUT PBOOT_ENTRY_OPTION Option,
|
|
|
|
|
IN ULONG BufferSize
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -368,19 +366,19 @@ Return Value:
|
|
|
|
|
PWCHAR PathStart, Position;
|
|
|
|
|
ULONG BufferRemaining, Length, Appended;
|
|
|
|
|
|
|
|
|
|
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION)) {
|
|
|
|
|
if (BufferSize < sizeof(BOOT_ENTRY_OPTION)) {
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
|
|
|
|
RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION));
|
|
|
|
|
Option->Type = OptionType;
|
|
|
|
|
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
|
|
|
|
Option->DataOffset = sizeof(BOOT_ENTRY_OPTION);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Loop through nodes and add one at a time.
|
|
|
|
|
//
|
|
|
|
|
Option->DataSize = 0;
|
|
|
|
|
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_OPTION);
|
|
|
|
|
BufferRemaining = BufferSize - sizeof(BOOT_ENTRY_OPTION);
|
|
|
|
|
Node = EfiFilePath;
|
|
|
|
|
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
|
|
|
|
|
Position = PathStart;
|
|
|
|
@@ -440,7 +438,7 @@ Return Value:
|
|
|
|
|
VOID
|
|
|
|
|
EfiInitpCreateApplicationEntry (
|
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable,
|
|
|
|
|
IN OUT PBOOT_INPUT_APPLICATION_ENTRY Entry,
|
|
|
|
|
IN OUT PBOOT_INIT_APPLICATION_ENTRY Entry,
|
|
|
|
|
IN ULONG BufferSize,
|
|
|
|
|
IN EFI_DEVICE_PATH *EfiDevicePath,
|
|
|
|
|
IN EFI_DEVICE_PATH *EfiFilePath,
|
|
|
|
@@ -491,7 +489,7 @@ Return Value:
|
|
|
|
|
PWCHAR BcdOptionString;
|
|
|
|
|
BOOLEAN BcdIdentifierSet;
|
|
|
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
|
PBOOT_APPLICATION_OPTION Option, PrevOption;
|
|
|
|
|
PBOOT_ENTRY_OPTION Option, PrevOption;
|
|
|
|
|
PBCDE_DEVICE BootDeviceElement;
|
|
|
|
|
|
|
|
|
|
(VOID)SystemTable;
|
|
|
|
@@ -503,13 +501,13 @@ Return Value:
|
|
|
|
|
BcdIdentifierSet = FALSE;
|
|
|
|
|
|
|
|
|
|
BufferRemaining = BufferSize;
|
|
|
|
|
if (BufferRemaining < sizeof(BOOT_INPUT_APPLICATION_ENTRY)) {
|
|
|
|
|
if (BufferRemaining < sizeof(BOOT_INIT_APPLICATION_ENTRY)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RtlZeroMemory(Entry, sizeof(BOOT_INPUT_APPLICATION_ENTRY));
|
|
|
|
|
Entry->Signature = BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE;
|
|
|
|
|
BufferRemaining -= FIELD_OFFSET(BOOT_INPUT_APPLICATION_ENTRY, Options);
|
|
|
|
|
RtlZeroMemory(Entry, sizeof(BOOT_INIT_APPLICATION_ENTRY));
|
|
|
|
|
Entry->Signature = BOOT_INIT_APPLICATION_ENTRY_SIGNATURE;
|
|
|
|
|
BufferRemaining -= FIELD_OFFSET(BOOT_INIT_APPLICATION_ENTRY, Options);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Terminate load options.
|
|
|
|
@@ -530,7 +528,7 @@ Return Value:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!BcdIdentifierSet) {
|
|
|
|
|
Entry->Attributes |= BOOT_INPUT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER;
|
|
|
|
|
Entry->Attributes |= BOOT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
@@ -553,7 +551,7 @@ Return Value:
|
|
|
|
|
// TODO: Support UDP/PXE boot.
|
|
|
|
|
//
|
|
|
|
|
PrevOption = Option;
|
|
|
|
|
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
|
|
|
|
Option = (PBOOT_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
|
|
|
|
Status = EfiInitpConvertEfiFilePath(EfiFilePath, BCDE_DATA_TYPE_APPLICATION_PATH, Option, BufferRemaining);
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
goto exit;
|
|
|
|
@@ -567,7 +565,7 @@ Return Value:
|
|
|
|
|
// TODO: Parse additional options from LoadOptions.
|
|
|
|
|
//
|
|
|
|
|
PrevOption = Option;
|
|
|
|
|
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
|
|
|
|
Option = (PBOOT_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
|
|
|
|
// Status = Unknown(LoadOptions, &Entry->Options, RemainingSize, &OptionsSize, &PrevOption, &Size);
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
goto exit;
|
|
|
|
@@ -577,10 +575,11 @@ exit:
|
|
|
|
|
*BufferUsed = BufferSize - BufferRemaining;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PBOOT_INPUT_PARAMETERS
|
|
|
|
|
EfiInitCreateInputParameters (
|
|
|
|
|
PBOOT_APPLICATION_PARAMETERS
|
|
|
|
|
EfiInitCreateInputParametersEx (
|
|
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable,
|
|
|
|
|
IN ULONG Flags
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
@@ -595,6 +594,8 @@ Arguments:
|
|
|
|
|
|
|
|
|
|
SystemTable - Pointer to the EFI system table.
|
|
|
|
|
|
|
|
|
|
Flags - Unused.
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Pointer to parameter structure if successful.
|
|
|
|
@@ -603,19 +604,22 @@ Return Value:
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
ULONG ScratchUsed = 0;
|
|
|
|
|
ULONG ApplicationEntrySize = 0;
|
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
ULONG ScratchUsed;
|
|
|
|
|
ULONG ApplicationEntrySize;
|
|
|
|
|
EFI_PHYSICAL_ADDRESS BadPageAddress;
|
|
|
|
|
EFI_LOADED_IMAGE *LoadedImage;
|
|
|
|
|
EFI_DEVICE_PATH *DevicePath;
|
|
|
|
|
PBOOT_INPUT_PARAMETERS InputParameters;
|
|
|
|
|
PBOOT_APPLICATION_PARAMETERS InputParameters;
|
|
|
|
|
PBOOT_MEMORY_INFO MemoryInfo;
|
|
|
|
|
PMEMORY_DESCRIPTOR MemoryDescriptor;
|
|
|
|
|
PBOOT_DEVICE BootDevice;
|
|
|
|
|
PBOOT_FIRMWARE_DATA FirmwareData;
|
|
|
|
|
PBOOT_PLATFORM_DATA PlatformData;
|
|
|
|
|
PBOOT_RETURN_DATA ReturnData;
|
|
|
|
|
|
|
|
|
|
ScratchUsed = 0;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Page 0x102 may be broken on some machines.
|
|
|
|
|
// It is mapped here so that it does not get used.
|
|
|
|
@@ -641,12 +645,12 @@ Return Value:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
|
|
|
|
|
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS);
|
|
|
|
|
InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE;
|
|
|
|
|
InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION;
|
|
|
|
|
InputParameters = (PBOOT_APPLICATION_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
|
|
|
|
|
ScratchUsed += sizeof(BOOT_APPLICATION_PARAMETERS);
|
|
|
|
|
InputParameters->Signature = BOOT_APPLICATION_PARAMETERS_SIGNATURE;
|
|
|
|
|
InputParameters->Version = BOOT_APPLICATION_PARAMETERS_VERSION;
|
|
|
|
|
InputParameters->MachineType = BOOT_MACHINE_TYPE;
|
|
|
|
|
InputParameters->TranslationType = BOOT_TRANSLATION_TYPE_NONE;
|
|
|
|
|
InputParameters->TranslationType = TRANSLATION_TYPE_NONE;
|
|
|
|
|
InputParameters->ImageBase = LoadedImage->ImageBase;
|
|
|
|
|
InputParameters->ImageSize = LoadedImage->ImageSize;
|
|
|
|
|
|
|
|
|
@@ -669,13 +673,13 @@ Return Value:
|
|
|
|
|
InputParameters->ApplicationEntryOffset = ScratchUsed;
|
|
|
|
|
EfiInitpCreateApplicationEntry(
|
|
|
|
|
SystemTable,
|
|
|
|
|
(PBOOT_INPUT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]),
|
|
|
|
|
(PBOOT_INIT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]),
|
|
|
|
|
sizeof(EfiInitScratch) - ScratchUsed,
|
|
|
|
|
DevicePath,
|
|
|
|
|
LoadedImage->FilePath,
|
|
|
|
|
LoadedImage->LoadOptions,
|
|
|
|
|
LoadedImage->LoadOptionsSize,
|
|
|
|
|
0,
|
|
|
|
|
Flags,
|
|
|
|
|
&ApplicationEntrySize,
|
|
|
|
|
&BootDevice
|
|
|
|
|
);
|
|
|
|
@@ -698,6 +702,15 @@ Return Value:
|
|
|
|
|
FirmwareData->ImageHandle = ImageHandle;
|
|
|
|
|
FirmwareData->SystemTable = SystemTable;
|
|
|
|
|
|
|
|
|
|
InputParameters->PlatformDataOffset = ScratchUsed;
|
|
|
|
|
PlatformData = (PBOOT_PLATFORM_DATA)(&EfiInitScratch[ScratchUsed]);
|
|
|
|
|
ScratchUsed += sizeof(BOOT_PLATFORM_DATA);
|
|
|
|
|
PlatformData->Reserved = 0;
|
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
|
|
|
asm volatile("mov %%cr3, %0" :"=r"(PlatformData->CR3));
|
|
|
|
|
#endif
|
|
|
|
|
BlpArchGetDescriptorTableContext(&PlatformData->DescriptorTableContext);
|
|
|
|
|
|
|
|
|
|
InputParameters->ReturnDataOffset = ScratchUsed;
|
|
|
|
|
ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]);
|
|
|
|
|
ScratchUsed += sizeof(BOOT_RETURN_DATA);
|
|
|
|
@@ -710,3 +723,32 @@ Return Value:
|
|
|
|
|
|
|
|
|
|
return InputParameters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PBOOT_APPLICATION_PARAMETERS
|
|
|
|
|
EfiInitCreateInputParameters (
|
|
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*++
|
|
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
|
|
Creates the input parameter structure for the boot application.
|
|
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
|
|
ImageHandle - EFI handle for the boot application image.
|
|
|
|
|
|
|
|
|
|
SystemTable - Pointer to the EFI system table.
|
|
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
|
|
|
|
Pointer to parameter structure if successful.
|
|
|
|
|
NULL on failure.
|
|
|
|
|
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
return EfiInitCreateInputParametersEx(ImageHandle, SystemTable, 0);
|
|
|
|
|
}
|
|
|
|
|