237 lines
5.7 KiB
C
237 lines
5.7 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"
|
|
|
|
//
|
|
// Total size of required structures.
|
|
//
|
|
#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:
|
|
|
|
Internal routine to initialize the boot library.
|
|
|
|
Arguments:
|
|
|
|
InputParameters - pointer to the input parameters structure.
|
|
|
|
LibraryParameters - pointer to the library parameters structure.
|
|
|
|
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;
|
|
|
|
//
|
|
// Verify input parameters structure.
|
|
//
|
|
if (InputParameters == NULL ||
|
|
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE ||
|
|
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Calculate structure addresses from offsets.
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Print image information.
|
|
//
|
|
ConsolePrintf(L"Image base: %x %x\r\n", (ULONG)((ULONG_PTR)InputParameters->ImageBase >> 32), (ULONG)((ULONG_PTR)InputParameters->ImageBase));
|
|
ConsolePrintf(L"Image size: %x\r\n", InputParameters->ImageSize);
|
|
|
|
//
|
|
// Check application entry signature.
|
|
//
|
|
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 data.
|
|
//
|
|
BlpApplicationParameters = InputParameters;
|
|
BlpApplicationEntry.Attributes = ApplicationEntry->Attributes;
|
|
RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID));
|
|
BlpApplicationEntry.Options = &ApplicationEntry->Options;
|
|
|
|
//
|
|
// Initialize memory manager.
|
|
//
|
|
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.
|
|
|
|
Arguments:
|
|
|
|
InputParameters - pointer to the input parameters structure.
|
|
|
|
LibraryParameters - pointer to the library parameters structure.
|
|
|
|
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 if successful.
|
|
Error status if an error is encountered.
|
|
|
|
--*/
|
|
|
|
{
|
|
return STATUS_SUCCESS;
|
|
}
|