Clean up code a bit
This commit is contained in:
parent
1d61b2fb6a
commit
03ffa1d901
@ -105,6 +105,14 @@ BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries,
|
|||||||
OUT PULONG EntriesCount,
|
OUT PULONG EntriesCount,
|
||||||
OUT PULONG DefaultId);
|
OUT PULONG DefaultId);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModule(IN PWCHAR ModuleName);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModules(IN PWCHAR ModulesList);
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BlMemoryAllocatePages(IN UINT64 Pages,
|
BlMemoryAllocatePages(IN UINT64 Pages,
|
||||||
|
@ -9,6 +9,275 @@
|
|||||||
#include <xtldr.h>
|
#include <xtldr.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a specified XTLDR module from disk.
|
||||||
|
*
|
||||||
|
* @param ModuleName
|
||||||
|
* Specifies the name of the module to load.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModule(IN PWCHAR ModuleName)
|
||||||
|
{
|
||||||
|
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
|
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
||||||
|
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||||
|
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
||||||
|
EFI_HANDLE DiskHandle, ModuleHandle;
|
||||||
|
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||||
|
PPECOFF_IMAGE_DOS_HEADER DosHeader;
|
||||||
|
PPECOFF_IMAGE_PE_HEADER PeHeader;
|
||||||
|
PXTBL_MODULE_DEPS ModuleDependencies;
|
||||||
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
|
PLIST_ENTRY ModuleListEntry;
|
||||||
|
WCHAR ModuleFileName[12];
|
||||||
|
USHORT SectionIndex;
|
||||||
|
SIZE_T ModuleSize;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
PVOID ModuleData;
|
||||||
|
PWCHAR DepsData;
|
||||||
|
|
||||||
|
ModuleListEntry = BlpLoadedModules.Flink;
|
||||||
|
while(ModuleListEntry != &BlpLoadedModules)
|
||||||
|
{
|
||||||
|
/* Get module information */
|
||||||
|
ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink);
|
||||||
|
|
||||||
|
if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
|
||||||
|
{
|
||||||
|
/* Module already loaded */
|
||||||
|
BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName);
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the module */
|
||||||
|
ModuleListEntry = ModuleListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print debug message */
|
||||||
|
BlDebugPrint(L"Loading module '%S' ...\n", ModuleName);
|
||||||
|
|
||||||
|
/* Set module path */
|
||||||
|
RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR));
|
||||||
|
RtlConcatenateWideString(ModuleFileName, L".EFI", 0);
|
||||||
|
|
||||||
|
/* Open EFI volume */
|
||||||
|
Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open a volume */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open XTLDR modules directory and close the FS immediately */
|
||||||
|
Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);
|
||||||
|
FsHandle->Close(FsHandle);
|
||||||
|
|
||||||
|
/* Check if directory opened successfully */
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open directory */
|
||||||
|
BlCloseVolume(DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read module file from disk and close EFI volume */
|
||||||
|
Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize);
|
||||||
|
BlCloseVolume(DiskHandle);
|
||||||
|
|
||||||
|
/* Make sure module file was read successfully */
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to read file */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for module information block */
|
||||||
|
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to allocate memory */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero module information block and initialize dependencies list */
|
||||||
|
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
||||||
|
RtlInitializeListHead(&ModuleInfo->Dependencies);
|
||||||
|
|
||||||
|
/* Setup PE/COFF EFI image headers */
|
||||||
|
DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;
|
||||||
|
PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew);
|
||||||
|
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
||||||
|
PeHeader->FileHeader.SizeOfOptionalHeader);
|
||||||
|
|
||||||
|
/* Look for .moddeps and .modinfo sections */
|
||||||
|
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
||||||
|
{
|
||||||
|
/* Check section name */
|
||||||
|
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0)
|
||||||
|
{
|
||||||
|
/* Store address of .moddeps data segment */
|
||||||
|
DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||||
|
|
||||||
|
/* Iterate over all dependencies stored */
|
||||||
|
while(*DepsData != 0)
|
||||||
|
{
|
||||||
|
/* Load dependency module */
|
||||||
|
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData);
|
||||||
|
Status = BlLoadModule(DepsData);
|
||||||
|
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load module, print error message and return status code */
|
||||||
|
BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status);
|
||||||
|
return STATUS_EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for module dependency */
|
||||||
|
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies);
|
||||||
|
if(Status == STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory allocated successfully, store module's dependency */
|
||||||
|
ModuleDependencies->ModuleName = DepsData;
|
||||||
|
RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get next dependency module name */
|
||||||
|
DepsData += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0)
|
||||||
|
{
|
||||||
|
/* Store module description */
|
||||||
|
ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, store module name */
|
||||||
|
ModuleInfo->ModuleName = ModuleName;
|
||||||
|
|
||||||
|
/* Setup module device path */
|
||||||
|
ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
||||||
|
ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;
|
||||||
|
ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;
|
||||||
|
ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;
|
||||||
|
ModuleDevicePath[0].MemoryType = EfiLoaderData;
|
||||||
|
ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData;
|
||||||
|
ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize;
|
||||||
|
ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||||
|
ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;
|
||||||
|
ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;
|
||||||
|
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
||||||
|
|
||||||
|
/* Load EFI image */
|
||||||
|
Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath,
|
||||||
|
ModuleData, ModuleSize, &ModuleHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Check if caused by secure boot */
|
||||||
|
if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1)
|
||||||
|
{
|
||||||
|
/* SecureBoot signature validation failed */
|
||||||
|
BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Failed to load module */
|
||||||
|
BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return error status code */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Access module interface for further module type check */
|
||||||
|
Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage,
|
||||||
|
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open LoadedImage protocol */
|
||||||
|
BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */
|
||||||
|
if(LoadedImage->ImageCodeType != EfiBootServicesCode)
|
||||||
|
{
|
||||||
|
/* Different type set, probably 'runtime driver', refuse to load it */
|
||||||
|
BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n");
|
||||||
|
|
||||||
|
/* Close protocol and skip module */
|
||||||
|
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close loaded image protocol */
|
||||||
|
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||||
|
|
||||||
|
/* Start EFI image */
|
||||||
|
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to start module image */
|
||||||
|
BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add module to the list of loaded modules */
|
||||||
|
RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper routine to load all modules supplied in the configuration file.
|
||||||
|
*
|
||||||
|
* @param ModulesList
|
||||||
|
* Supplies a space separated list of XTLDR modules to load (mostly read from configuration file).
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlLoadModules(IN PWCHAR ModulesList)
|
||||||
|
{
|
||||||
|
PWCHAR LastModule, Module;
|
||||||
|
EFI_STATUS ReturnStatus, Status;
|
||||||
|
|
||||||
|
/* Set default return value */
|
||||||
|
ReturnStatus = STATUS_EFI_SUCCESS;
|
||||||
|
|
||||||
|
if(ModulesList != NULL)
|
||||||
|
{
|
||||||
|
/* Tokenize provided list of modules */
|
||||||
|
Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule);
|
||||||
|
|
||||||
|
/* Iterate over all arguments passed to boot loader */
|
||||||
|
while(Module != NULL)
|
||||||
|
{
|
||||||
|
Status = BlLoadModule(Module);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load module, print error message and set new return value */
|
||||||
|
BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status);
|
||||||
|
ReturnStatus = STATUS_EFI_LOAD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take next module from the list */
|
||||||
|
Module = RtlTokenizeWideString(NULL, L" ", &LastModule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return ReturnStatus;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine locates and opens the requested XT boot loader protocol.
|
* This routine locates and opens the requested XT boot loader protocol.
|
||||||
*
|
*
|
||||||
|
@ -1085,7 +1085,7 @@ BlDisplayBootMenu()
|
|||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to boot OS */
|
/* Failed to boot OS */
|
||||||
BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n",
|
BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n",
|
||||||
MenuEntries[HighligtedEntryId].EntryName, Status);
|
MenuEntries[HighligtedEntryId].EntryName, Status);
|
||||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
|
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
|
||||||
}
|
}
|
||||||
@ -1198,7 +1198,7 @@ BlDisplayBootMenu()
|
|||||||
if(Status != STATUS_SUCCESS)
|
if(Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to boot OS */
|
/* Failed to boot OS */
|
||||||
BlDebugPrint(L"Failed to boot OS '%S' with status code: 0x%lx!\n",
|
BlDebugPrint(L"ERROR: Failed to boot OS '%S' (Status Code: 0x%lx)\n",
|
||||||
MenuEntries[HighligtedEntryId].EntryName, Status);
|
MenuEntries[HighligtedEntryId].EntryName, Status);
|
||||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
|
BlDisplayErrorDialog(L"XTLDR", L"Failed to startup the selected Operating System.");
|
||||||
}
|
}
|
||||||
|
259
xtldr2/xtldr.c
259
xtldr2/xtldr.c
@ -9,14 +9,6 @@
|
|||||||
#include <xtldr.h>
|
#include <xtldr.h>
|
||||||
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
BlLoadModule(IN PWCHAR Module);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
BlLoadModules(IN PWCHAR ModulesList);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a list of operating systems for XTLDR boot menu.
|
* Initializes a list of operating systems for XTLDR boot menu.
|
||||||
*
|
*
|
||||||
@ -166,255 +158,6 @@ BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList)
|
|||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
BlLoadModules(IN PWCHAR ModulesList)
|
|
||||||
{
|
|
||||||
PWCHAR LastModule, Module;
|
|
||||||
EFI_STATUS ReturnStatus, Status;
|
|
||||||
|
|
||||||
/* Set default return value */
|
|
||||||
ReturnStatus = STATUS_EFI_SUCCESS;
|
|
||||||
|
|
||||||
if(ModulesList != NULL)
|
|
||||||
{
|
|
||||||
/* Tokenize provided list of modules */
|
|
||||||
Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule);
|
|
||||||
|
|
||||||
/* Iterate over all arguments passed to boot loader */
|
|
||||||
while(Module != NULL)
|
|
||||||
{
|
|
||||||
Status = BlLoadModule(Module);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to load module, print error message and set new return value */
|
|
||||||
BlDebugPrint(L"Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status);
|
|
||||||
ReturnStatus = STATUS_EFI_LOAD_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Take next module from the list */
|
|
||||||
Module = RtlTokenizeWideString(NULL, L" ", &LastModule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return ReturnStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
BlLoadModule(IN PWCHAR ModuleName)
|
|
||||||
{
|
|
||||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
|
||||||
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
|
||||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
|
||||||
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
|
||||||
EFI_HANDLE DiskHandle, ModuleHandle;
|
|
||||||
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
|
||||||
PPECOFF_IMAGE_DOS_HEADER DosHeader;
|
|
||||||
PPECOFF_IMAGE_PE_HEADER PeHeader;
|
|
||||||
PXTBL_MODULE_DEPS ModuleDependencies;
|
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
|
||||||
PLIST_ENTRY ModuleListEntry;
|
|
||||||
WCHAR ModuleFileName[12];
|
|
||||||
USHORT SectionIndex;
|
|
||||||
SIZE_T ModuleSize;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
PVOID ModuleData;
|
|
||||||
PWCHAR DepsData;
|
|
||||||
|
|
||||||
ModuleListEntry = BlpLoadedModules.Flink;
|
|
||||||
while(ModuleListEntry != &BlpLoadedModules)
|
|
||||||
{
|
|
||||||
/* Get module information */
|
|
||||||
ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink);
|
|
||||||
|
|
||||||
if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
|
|
||||||
{
|
|
||||||
/* Module already loaded */
|
|
||||||
BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName);
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to the module */
|
|
||||||
ModuleListEntry = ModuleListEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print debug message */
|
|
||||||
BlDebugPrint(L"Loading module '%S' ...\n", ModuleName);
|
|
||||||
|
|
||||||
/* Set module path */
|
|
||||||
RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR));
|
|
||||||
RtlConcatenateWideString(ModuleFileName, L".EFI", 0);
|
|
||||||
|
|
||||||
/* Open EFI volume */
|
|
||||||
Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open a volume */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open XTLDR modules directory and close the FS immediately */
|
|
||||||
Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);
|
|
||||||
FsHandle->Close(FsHandle);
|
|
||||||
|
|
||||||
/* Check if directory opened successfully */
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open directory */
|
|
||||||
BlCloseVolume(DiskHandle);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read module file from disk and close EFI volume */
|
|
||||||
Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize);
|
|
||||||
BlCloseVolume(DiskHandle);
|
|
||||||
|
|
||||||
/* Make sure module file was read successfully */
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to read file */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for module information block */
|
|
||||||
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to allocate memory */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero module information block and initialize dependencies list */
|
|
||||||
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
|
||||||
RtlInitializeListHead(&ModuleInfo->Dependencies);
|
|
||||||
|
|
||||||
/* Setup PE/COFF EFI image headers */
|
|
||||||
DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;
|
|
||||||
PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew);
|
|
||||||
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
|
||||||
PeHeader->FileHeader.SizeOfOptionalHeader);
|
|
||||||
|
|
||||||
/* Look for .moddeps and .modinfo sections */
|
|
||||||
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
|
||||||
{
|
|
||||||
/* Check section name */
|
|
||||||
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0)
|
|
||||||
{
|
|
||||||
/* Store address of .moddeps data segment */
|
|
||||||
DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
|
||||||
|
|
||||||
/* Iterate over all dependencies stored */
|
|
||||||
while(*DepsData != 0)
|
|
||||||
{
|
|
||||||
/* Load dependency module */
|
|
||||||
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData);
|
|
||||||
Status = BlLoadModule(DepsData);
|
|
||||||
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to load module, print error message and return status code */
|
|
||||||
BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status);
|
|
||||||
return STATUS_EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for module dependency */
|
|
||||||
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies);
|
|
||||||
if(Status == STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Memory allocated successfully, store module's dependency */
|
|
||||||
ModuleDependencies->ModuleName = DepsData;
|
|
||||||
RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next dependency module name */
|
|
||||||
DepsData += 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0)
|
|
||||||
{
|
|
||||||
/* Store module description */
|
|
||||||
ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, store module name */
|
|
||||||
ModuleInfo->ModuleName = ModuleName;
|
|
||||||
|
|
||||||
/* Setup module device path */
|
|
||||||
ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
|
||||||
ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;
|
|
||||||
ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;
|
|
||||||
ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;
|
|
||||||
ModuleDevicePath[0].MemoryType = EfiLoaderData;
|
|
||||||
ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData;
|
|
||||||
ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize;
|
|
||||||
ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
|
||||||
ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;
|
|
||||||
ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;
|
|
||||||
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
|
||||||
|
|
||||||
/* Load EFI image */
|
|
||||||
Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath,
|
|
||||||
ModuleData, ModuleSize, &ModuleHandle);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Check if caused by secure boot */
|
|
||||||
if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1)
|
|
||||||
{
|
|
||||||
/* SecureBoot signature validation failed */
|
|
||||||
BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Failed to load module */
|
|
||||||
BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return error status code */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Access module interface for further module type check */
|
|
||||||
Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage,
|
|
||||||
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open LoadedImage protocol */
|
|
||||||
BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */
|
|
||||||
if(LoadedImage->ImageCodeType != EfiBootServicesCode)
|
|
||||||
{
|
|
||||||
/* Different type set, probably 'runtime driver', refuse to load it */
|
|
||||||
BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n");
|
|
||||||
|
|
||||||
/* Close protocol and skip module */
|
|
||||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close loaded image protocol */
|
|
||||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
|
||||||
|
|
||||||
/* Start EFI image */
|
|
||||||
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to start module image */
|
|
||||||
BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add module to the list of loaded modules */
|
|
||||||
RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine is the entry point of the XT EFI boot loader.
|
* This routine is the entry point of the XT EFI boot loader.
|
||||||
*
|
*
|
||||||
@ -545,8 +288,6 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
|||||||
|
|
||||||
BlConsolePrint(L"\n\n END OF LIST\n");
|
BlConsolePrint(L"\n\n END OF LIST\n");
|
||||||
|
|
||||||
for(;;);
|
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(BlpStatus.BootMenu != NULL)
|
if(BlpStatus.BootMenu != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user