alcyone/BOOT/ENVIRON/LIB/bootlib.c

220 lines
5.4 KiB
C

/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
bootlib.c
Abstract:
Provides boot library utilities.
--*/
#include <ntrtl.h>
#include "bootlib.h"
#define MIN_INPUT_PARAMETERS_SIZE ( \
sizeof(BOOT_INPUT_PARAMETERS) + \
sizeof(BOOT_MEMORY_INFO) + \
sizeof(BOOT_FIRMWARE_DATA) + \
sizeof(BOOT_RETURN_DATA) \
)
PBOOT_INPUT_PARAMETERS BlpApplicationParameters;
BOOT_APPLICATION_ENTRY BlpApplicationEntry;
PBOOT_DEVICE BlpBootDevice;
NTSTATUS
InitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters,
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
)
/*++
Routine Description:
Initializes the boot library.
Arguments:
InputParameters - Pointer to the application's input parameters.
LibraryParameters - Pointer to the library parameters.
Return Value:
STATUS_SUCCESS if successful.
--*/
{
NTSTATUS Status;
PBOOT_MEMORY_INFO MemoryInfo;
PBOOT_INPUT_APPLICATION_ENTRY ApplicationEntry;
PBOOT_FIRMWARE_DATA FirmwareData;
PBOOT_BLOCK_IDENTIFIER BlockDevice;
PBOOT_APPLICATION_OPTION Option;
(VOID)LibraryParameters;
if (InputParameters == NULL ||
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE ||
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
return STATUS_INVALID_PARAMETER;
}
MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)InputParameters + InputParameters->MemoryInfoOffset);
ApplicationEntry = (PBOOT_INPUT_APPLICATION_ENTRY)((PUCHAR)InputParameters + InputParameters->ApplicationEntryOffset);
BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)InputParameters + InputParameters->BootDeviceOffset);
FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)InputParameters + InputParameters->FirmwareDataOffset);
//
// Initialize firmware library.
// It is important to do this early so that
// ConsolePrint() and DebugPrint() can be used.
//
Status = BlpFwInitialize(0, FirmwareData);
if (!NT_SUCCESS(Status)) {
return Status;
}
ConsolePrint(L"-------- Alcyone EFI Boot Manager --------\r\n");
ConsolePrintf(L"Image base: %x %x\r\nImage size: %x\r\n", HIDWORD((ULONG_PTR)InputParameters->ImageBase), LODWORD((ULONG_PTR)InputParameters->ImageBase), InputParameters->ImageSize);
DebugPrint(L"Initializing boot library...\r\n");
if (ApplicationEntry->Signature != BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE) {
DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n");
return STATUS_INVALID_PARAMETER_9;
}
//
// Save input parameters and application entry.
//
BlpApplicationParameters = InputParameters;
BlpApplicationEntry.Attributes = ApplicationEntry->Attributes;
RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID));
BlpApplicationEntry.Options = &ApplicationEntry->Options;
Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters);
if (!NT_SUCCESS(Status)) {
return Status;
}
//
// Print debug information.
// TODO: Remove this once the project is more stable?
//
#ifdef _DEBUG
DebugPrint(L"Boot device type: ");
switch (BlpBootDevice->Type) {
case BOOT_DEVICE_TYPE_PARTITION:
DebugPrint(L"partition\r\n");
BlockDevice = &BlpBootDevice->Partition.Parent;
break;
case BOOT_DEVICE_TYPE_PARTITION_EX:
DebugPrint(L"partition\r\n");
BlockDevice = &BlpBootDevice->PartitionEx.Parent;
break;
default:
DebugPrint(L"generic block device\r\n");
BlockDevice = &BlpBootDevice->Block;
break;
}
DebugPrint(L"Boot device parent type: ");
switch (BlockDevice->Type) {
case BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE:
DebugPrint(L"hard drive\r\n");
break;
case BOOT_BLOCK_DEVICE_TYPE_CDROM:
DebugPrint(L"CD-ROM\r\n");
break;
case BOOT_BLOCK_DEVICE_TYPE_RAMDISK:
DebugPrint(L"RAM disk\r\n");
break;
default:
DebugPrint(L"generic block device\r\n");
break;
}
Option = &ApplicationEntry->Options;
for (ULONG Index = 0; !Option->IsInvalid; Index++) {
DebugPrintf(L"Boot entry option %x: ", Index);
if (Option->Type == BCDE_DATA_TYPE_APPLICATION_PATH) {
DebugPrint(L"application path \"");
DebugPrint((PWSTR)((PUCHAR)Option + Option->DataOffset));
DebugPrint(L"\"\r\n");
} else {
DebugPrintf(L"type %x, data size %x\r\n", Option->Type, Option->DataSize);
}
if (Option->NextOptionOffset == 0) {
break;
}
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)Option + Option->NextOptionOffset);
}
#endif
return STATUS_SUCCESS;
}
NTSTATUS
BlInitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters,
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
)
/*++
Routine Description:
Initializes the boot library. Wrapper for InitializeLibrary().
Arguments:
InputParameters - Pointer to the application's input parameters.
LibraryParameters - Pointer to the library parameters.
Return Value:
Any value returned by InitializeLibrary().
--*/
{
return InitializeLibrary(InputParameters, LibraryParameters);
}
NTSTATUS
BlDestroyLibrary (
VOID
)
/*++
Routine Description:
Cleans up after the boot library.
Arguments:
None.
Return Value:
STATUS_SUCCESS.
--*/
{
return STATUS_SUCCESS;
}