Redesign a way of storing module information; this allows to store more data in a single section, like license or a list of authors, as well as solves the problem with different module name lengths
This commit is contained in:
parent
4b34f7db4b
commit
17c50ea912
@ -12,9 +12,17 @@
|
|||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
|
||||||
|
|
||||||
/* Boot Loader module segment macros */
|
/* Boot Loader module information macros */
|
||||||
#define XTBL_MODDEPS SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][9]
|
#define MODULE_AUTHOR(_author) XTBL_MODULE_INFO(author, author, _author)
|
||||||
#define XTBL_MODINFO SEGMENT(".modinfo") CONST WCHAR XtBlpInfo[]
|
#define MODULE_DEPENDENCY(_softdeps) XTBL_MODULE_INFO(softdeps, softdeps, _softdeps)
|
||||||
|
#define MODULE_DESCRIPTION(_description) XTBL_MODULE_INFO(description, description, _description)
|
||||||
|
#define MODULE_LICENSE(_license) XTBL_MODULE_INFO(license, license, _license)
|
||||||
|
#define MODULE_VERSION(_version) XTBL_MODULE_INFO(version, version, _version)
|
||||||
|
|
||||||
|
/* Boot Loader module information segment macro */
|
||||||
|
#define XTBL_MODULE_INFO(Tag, Name, Data) STATIC CONST WCHAR UNIQUE(Name)[] \
|
||||||
|
USED SEGMENT(".modinfo") ALIGN(1) \
|
||||||
|
= STRINGIFY(Tag) "=" Data
|
||||||
|
|
||||||
/* XTLDR directories */
|
/* XTLDR directories */
|
||||||
#define XTBL_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\"
|
#define XTBL_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\"
|
||||||
|
@ -190,6 +190,13 @@ typedef struct _XTBL_MEMORY_MAPPING
|
|||||||
LOADER_MEMORY_TYPE MemoryType;
|
LOADER_MEMORY_TYPE MemoryType;
|
||||||
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
||||||
|
|
||||||
|
/* XTLDR Module dependencies data */
|
||||||
|
typedef struct _XTBL_MODULE_AUTHORS
|
||||||
|
{
|
||||||
|
LIST_ENTRY Flink;
|
||||||
|
PWCHAR AuthorName;
|
||||||
|
} XTBL_MODULE_AUTHORS, *PXTBL_MODULE_AUTHORS;
|
||||||
|
|
||||||
/* XTLDR Module dependencies data */
|
/* XTLDR Module dependencies data */
|
||||||
typedef struct _XTBL_MODULE_DEPS
|
typedef struct _XTBL_MODULE_DEPS
|
||||||
{
|
{
|
||||||
@ -203,6 +210,9 @@ typedef struct _XTBL_MODULE_INFO
|
|||||||
LIST_ENTRY Flink;
|
LIST_ENTRY Flink;
|
||||||
PWCHAR ModuleName;
|
PWCHAR ModuleName;
|
||||||
PWCHAR ModuleDescription;
|
PWCHAR ModuleDescription;
|
||||||
|
PWCHAR License;
|
||||||
|
PWCHAR Version;
|
||||||
|
LIST_ENTRY Authors;
|
||||||
LIST_ENTRY Dependencies;
|
LIST_ENTRY Dependencies;
|
||||||
PVOID ModuleBase;
|
PVOID ModuleBase;
|
||||||
ULONGLONG ModuleSize;
|
ULONGLONG ModuleSize;
|
||||||
|
@ -282,6 +282,7 @@ typedef struct _XTBL_FRAMEBUFFER_PROTOCOL XTBL_FRAMEBUFFER_PROTOCOL, *PXTBL_FRAM
|
|||||||
typedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
|
typedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
|
||||||
typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||||
typedef struct _XTBL_MEMORY_MAPPING XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
typedef struct _XTBL_MEMORY_MAPPING XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;
|
||||||
|
typedef struct _XTBL_MODULE_AUTHORS XTBL_MODULE_AUTHORS, *PXTBL_MODULE_AUTHORS;
|
||||||
typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;
|
typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;
|
||||||
typedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;
|
typedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;
|
||||||
typedef struct _XTBL_PAGE_MAPPING XTBL_PAGE_MAPPING, *PXTBL_PAGE_MAPPING;
|
typedef struct _XTBL_PAGE_MAPPING XTBL_PAGE_MAPPING, *PXTBL_PAGE_MAPPING;
|
||||||
|
@ -444,6 +444,19 @@ XTCDECL
|
|||||||
LOADER_MEMORY_TYPE
|
LOADER_MEMORY_TYPE
|
||||||
BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlpGetModuleInformation(IN PWCHAR SectionData,
|
||||||
|
IN ULONG SectionSize,
|
||||||
|
OUT PXTBL_MODULE_INFO ModuleInfo);
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlpGetModuleInfoStrings(IN PWCHAR SectionData,
|
||||||
|
IN ULONG SectionSize,
|
||||||
|
OUT PWCHAR **ModInfo,
|
||||||
|
OUT PULONG InfoCount);
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Dummy module information */
|
/* Dummy module information */
|
||||||
XTBL_MODINFO = L"ACPI support";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
|
MODULE_DESCRIPTION(L"ACPI support");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to get XSDP. If it is not found or checksum mismatch, it will try to get RSDP instead.
|
* Attempts to get XSDP. If it is not found or checksum mismatch, it will try to get RSDP instead.
|
||||||
|
@ -9,8 +9,11 @@
|
|||||||
#include <beep.h>
|
#include <beep.h>
|
||||||
|
|
||||||
|
|
||||||
/* Dummy module information */
|
/* Beep module information */
|
||||||
XTBL_MODINFO = L"Plays a GRUB compatible tune via PC speaker";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
|
MODULE_DESCRIPTION(L"Plays a GRUB compatible tune via PC speaker");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables the PC speaker.
|
* Disables the PC speaker.
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* ChainLoader module information */
|
/* ChainLoader module information */
|
||||||
XTBL_MODINFO = L"XTLDR Chain Loader";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
|
MODULE_DESCRIPTION(L"XTLDR Chain Loader");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chainloads another boot loader.
|
* Chainloads another boot loader.
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Dummy module information */
|
/* Dummy module information */
|
||||||
XTBL_MODINFO = L"XTLDR Dummy Module";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
|
MODULE_DESCRIPTION(L"XTLDR Dummy Module");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stub boot routine.
|
* Stub boot routine.
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* PE/COFF_O module information */
|
/* PE/COFF_O module information */
|
||||||
XTBL_MODINFO = L"EFI FB (FrameBuffer) support";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
|
MODULE_DESCRIPTION(L"EFI FB (FrameBuffer) support");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an EFI Frame Buffer protocol driver name used for initialization.
|
* Provides an EFI Frame Buffer protocol driver name used for initialization.
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* PE/COFF_O module information */
|
/* PE/COFF_O module information */
|
||||||
XTBL_MODINFO = L"Basic PE/COFF executable file format support";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
|
MODULE_DESCRIPTION(L"Basic PE/COFF executable file format support");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the address of the entry point.
|
* Returns the address of the entry point.
|
||||||
|
@ -10,8 +10,11 @@
|
|||||||
|
|
||||||
|
|
||||||
/* XTOS module information */
|
/* XTOS module information */
|
||||||
XTBL_MODINFO = L"XTOS boot protocol support";
|
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
|
||||||
XTBL_MODDEPS = {L"acpi", L"framebuf", L"pecoff"};
|
MODULE_DESCRIPTION(L"XTOS boot protocol support");
|
||||||
|
MODULE_DEPENDENCY(L"acpi framebuf pecoff");
|
||||||
|
MODULE_LICENSE(L"GPLv3");
|
||||||
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/* EFI XT Loader Protocol */
|
/* EFI XT Loader Protocol */
|
||||||
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||||
|
332
xtldr/protocol.c
332
xtldr/protocol.c
@ -129,6 +129,7 @@ EFI_STATUS
|
|||||||
BlLoadModule(IN PWCHAR ModuleName)
|
BlLoadModule(IN PWCHAR ModuleName)
|
||||||
{
|
{
|
||||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
|
PLIST_ENTRY DepsListEntry, ModuleListEntry;
|
||||||
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
||||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||||
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
||||||
@ -136,15 +137,14 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||||
PPECOFF_IMAGE_DOS_HEADER DosHeader;
|
PPECOFF_IMAGE_DOS_HEADER DosHeader;
|
||||||
PPECOFF_IMAGE_PE_HEADER PeHeader;
|
PPECOFF_IMAGE_PE_HEADER PeHeader;
|
||||||
PXTBL_MODULE_DEPS ModuleDependencies;
|
PXTBL_MODULE_DEPS ModuleDependency;
|
||||||
PXTBL_MODULE_INFO ModuleInfo;
|
PXTBL_MODULE_INFO ModuleInfo;
|
||||||
PLIST_ENTRY ModuleListEntry;
|
|
||||||
WCHAR ModuleFileName[24];
|
WCHAR ModuleFileName[24];
|
||||||
USHORT SectionIndex;
|
USHORT SectionIndex;
|
||||||
|
PWCHAR SectionData;
|
||||||
SIZE_T ModuleSize;
|
SIZE_T ModuleSize;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
PVOID ModuleData;
|
PVOID ModuleData;
|
||||||
PWCHAR DepsData;
|
|
||||||
|
|
||||||
ModuleListEntry = BlpLoadedModules.Flink;
|
ModuleListEntry = BlpLoadedModules.Flink;
|
||||||
while(ModuleListEntry != &BlpLoadedModules)
|
while(ModuleListEntry != &BlpLoadedModules)
|
||||||
@ -217,9 +217,8 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero module information block and initialize dependencies list */
|
/* Zero module information block */
|
||||||
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
||||||
RtlInitializeListHead(&ModuleInfo->Dependencies);
|
|
||||||
|
|
||||||
/* Setup PE/COFF EFI image headers */
|
/* Setup PE/COFF EFI image headers */
|
||||||
DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;
|
DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;
|
||||||
@ -227,51 +226,44 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
||||||
PeHeader->FileHeader.SizeOfOptionalHeader);
|
PeHeader->FileHeader.SizeOfOptionalHeader);
|
||||||
|
|
||||||
/* Look for .moddeps and .modinfo sections */
|
/* Look for .modinfo section */
|
||||||
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
||||||
{
|
{
|
||||||
/* Check section name */
|
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0)
|
||||||
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0)
|
|
||||||
{
|
{
|
||||||
/* Store address of .moddeps data segment */
|
/* Module information section found */
|
||||||
DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
SectionData = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||||
|
|
||||||
/* Iterate over all dependencies stored */
|
/* Get module information */
|
||||||
while(*DepsData != 0)
|
Status = BlpGetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Load dependency module */
|
/* Failed to read module information */
|
||||||
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData);
|
return Status;
|
||||||
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%zX)\n", DepsData, Status);
|
|
||||||
return STATUS_EFI_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for module dependency */
|
|
||||||
Status = BlAllocateMemoryPool(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 += 9;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0)
|
|
||||||
{
|
|
||||||
/* Store module description */
|
|
||||||
ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, store module name */
|
/* Iterate through module dependencies */
|
||||||
ModuleInfo->ModuleName = ModuleName;
|
DepsListEntry = ModuleInfo->Dependencies.Flink;
|
||||||
|
while(DepsListEntry != &ModuleInfo->Dependencies)
|
||||||
|
{
|
||||||
|
/* Get module dependency information */
|
||||||
|
ModuleDependency = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink);
|
||||||
|
|
||||||
|
/* Load dependency module */
|
||||||
|
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName);
|
||||||
|
Status = BlLoadModule(ModuleDependency->ModuleName);
|
||||||
|
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%zX)\n", ModuleDependency->ModuleName, Status);
|
||||||
|
return STATUS_EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next dependency */
|
||||||
|
DepsListEntry = DepsListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup module device path */
|
/* Setup module device path */
|
||||||
ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
||||||
@ -287,6 +279,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
||||||
|
|
||||||
/* Load EFI image */
|
/* Load EFI image */
|
||||||
|
BlDebugPrint(L"Starting module '%S' ...\n", ModuleName);
|
||||||
Status = BlLoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle);
|
Status = BlLoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -326,7 +319,8 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save module information */
|
/* Save additional module information, not found in '.modinfo' section */
|
||||||
|
ModuleInfo->ModuleName = ModuleName;
|
||||||
ModuleInfo->ModuleBase = LoadedImage->ImageBase;
|
ModuleInfo->ModuleBase = LoadedImage->ImageBase;
|
||||||
ModuleInfo->ModuleSize = LoadedImage->ImageSize;
|
ModuleInfo->ModuleSize = LoadedImage->ImageSize;
|
||||||
ModuleInfo->Revision = LoadedImage->Revision;
|
ModuleInfo->Revision = LoadedImage->Revision;
|
||||||
@ -383,7 +377,7 @@ BlLoadModules(IN PWCHAR ModulesList)
|
|||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to load module, print error message and set new return value */
|
/* Failed to load module, print error message and set new return value */
|
||||||
BlDebugPrint(L"ERROR: Failed to load module '%S', (Status Code: 0x%zX)\n", Module, Status);
|
BlDebugPrint(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status);
|
||||||
ReturnStatus = STATUS_EFI_LOAD_ERROR;
|
ReturnStatus = STATUS_EFI_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +583,258 @@ BlRegisterBootProtocol(IN PWCHAR SystemType,
|
|||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads information from the '.modinfo' section and populates the module information structure.
|
||||||
|
*
|
||||||
|
* @param SectionData
|
||||||
|
* Supplies a pointer to the module's information section data.
|
||||||
|
*
|
||||||
|
* @param SectionSize
|
||||||
|
* Supplies an expected size of the section data.
|
||||||
|
*
|
||||||
|
* @param ModuleInfo
|
||||||
|
* Supplies a pointer to the module information structure that will be filled by data from module's info section.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlpGetModuleInformation(IN PWCHAR SectionData,
|
||||||
|
IN ULONG SectionSize,
|
||||||
|
OUT PXTBL_MODULE_INFO ModuleInfo)
|
||||||
|
{
|
||||||
|
PXTBL_MODULE_DEPS ModuleDependencies;
|
||||||
|
PXTBL_MODULE_AUTHORS ModuleAuthors;
|
||||||
|
PWCHAR Dependency, Key, LastStr;
|
||||||
|
ULONG Index, Count;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
PWCHAR *Strings;
|
||||||
|
|
||||||
|
/* Initialize authors and dependencies lists */
|
||||||
|
RtlInitializeListHead(&ModuleInfo->Authors);
|
||||||
|
RtlInitializeListHead(&ModuleInfo->Dependencies);
|
||||||
|
|
||||||
|
/* Get information strings from '.modinfo' section */
|
||||||
|
Status = BlpGetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to get information strings */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse information strings */
|
||||||
|
for(Index = 0; Index < Count; Index++)
|
||||||
|
{
|
||||||
|
/* Store the key */
|
||||||
|
Key = Strings[Index];
|
||||||
|
|
||||||
|
/* Find the end of the key and the beginning of the value */
|
||||||
|
while(*Strings[Index] != L'=' && *Strings[Index] != L'\0' && *Strings[Index] != L'\n')
|
||||||
|
{
|
||||||
|
/* Move to the next character */
|
||||||
|
Strings[Index]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure value is NULL-terminated */
|
||||||
|
*Strings[Index] = L'\0';
|
||||||
|
Strings[Index]++;
|
||||||
|
|
||||||
|
/* Parse information string key */
|
||||||
|
if(RtlCompareWideString(Key, L"author", 6) == 0)
|
||||||
|
{
|
||||||
|
/* Allocate memory for module author */
|
||||||
|
Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory allocation failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store module's author */
|
||||||
|
ModuleAuthors->AuthorName = Strings[Index];
|
||||||
|
RtlInsertTailList(&ModuleInfo->Authors, &ModuleAuthors->Flink);
|
||||||
|
}
|
||||||
|
else if(RtlCompareWideString(Key, L"description", 11) == 0)
|
||||||
|
{
|
||||||
|
/* Store module's description */
|
||||||
|
ModuleInfo->ModuleDescription = Strings[Index];
|
||||||
|
}
|
||||||
|
else if(RtlCompareWideString(Key, L"license", 7) == 0)
|
||||||
|
{
|
||||||
|
/* Store module's license */
|
||||||
|
ModuleInfo->License = Strings[Index];
|
||||||
|
}
|
||||||
|
else if(RtlCompareWideString(Key, L"softdeps", 6) == 0)
|
||||||
|
{
|
||||||
|
/* Tokenize value to get module's single dependency */
|
||||||
|
Dependency = RtlTokenizeWideString(Strings[Index], L" ", &LastStr);
|
||||||
|
while(Dependency != NULL)
|
||||||
|
{
|
||||||
|
/* Allocate memory for module dependency */
|
||||||
|
Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Memory allocation failure */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store module's dependency */
|
||||||
|
ModuleDependencies->ModuleName = Dependency;
|
||||||
|
RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink);
|
||||||
|
|
||||||
|
/* Get next dependency from single value if available */
|
||||||
|
Dependency = RtlTokenizeWideString(NULL, L" ", &LastStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(RtlCompareWideString(Key, L"version", 7) == 0)
|
||||||
|
{
|
||||||
|
/* Store module's version */
|
||||||
|
ModuleInfo->Version = Strings[Index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads raw data from the '.modinfo' section and populates an array of strings.
|
||||||
|
*
|
||||||
|
* @param SectionData
|
||||||
|
* Supplies a pointer to the module's information section data.
|
||||||
|
*
|
||||||
|
* @param SectionSize
|
||||||
|
* Supplies an expected size of the section data.
|
||||||
|
*
|
||||||
|
* @param ModInfo
|
||||||
|
* Supplies a pointer to memory area, where an array of strings read from the section will be stored.
|
||||||
|
*
|
||||||
|
* @param InfoCount
|
||||||
|
* Supplies a pointer to variable that will receive the number of strings found in the section.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
BlpGetModuleInfoStrings(IN PWCHAR SectionData,
|
||||||
|
IN ULONG SectionSize,
|
||||||
|
OUT PWCHAR **ModInfo,
|
||||||
|
OUT PULONG InfoCount)
|
||||||
|
{
|
||||||
|
ULONG Count, Index, ArrayIndex;
|
||||||
|
PCWSTR InfoStrings;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
PWCHAR *Array;
|
||||||
|
PWCHAR String;
|
||||||
|
|
||||||
|
/* Check input parameters */
|
||||||
|
InfoStrings = SectionData;
|
||||||
|
if(!InfoStrings || !SectionSize)
|
||||||
|
{
|
||||||
|
/* Invalid input parameters */
|
||||||
|
return STATUS_EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip zero padding */
|
||||||
|
while(InfoStrings[0] == L'\0' && SectionSize > 1)
|
||||||
|
{
|
||||||
|
/* Get next character and decrement section size */
|
||||||
|
InfoStrings++;
|
||||||
|
SectionSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there is at least one string available */
|
||||||
|
if(SectionSize <= 1)
|
||||||
|
{
|
||||||
|
/* No strings found */
|
||||||
|
return STATUS_EFI_END_OF_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count number of strings */
|
||||||
|
Index = 0;
|
||||||
|
Count = 0;
|
||||||
|
while(Index < SectionSize)
|
||||||
|
{
|
||||||
|
/* Get to the next string */
|
||||||
|
if(InfoStrings[Index] != L'\0')
|
||||||
|
{
|
||||||
|
/* Get next character */
|
||||||
|
Index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip zero padding */
|
||||||
|
while(InfoStrings[Index] == L'\0' && Index < SectionSize)
|
||||||
|
{
|
||||||
|
/* Get next character */
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New string found, increment counter */
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there is no missing string */
|
||||||
|
if(InfoStrings[Index - 1] != L'\0')
|
||||||
|
{
|
||||||
|
/* One more string available */
|
||||||
|
Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for array of strings */
|
||||||
|
Status = BlAllocateMemoryPool(SectionSize + 1 + sizeof(PWCHAR) * (Count + 1), (PVOID *)&Array);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to allocate memory */
|
||||||
|
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cioy strings read from '.modinfo' section */
|
||||||
|
String = (PWCHAR)(Array + Count + 1);
|
||||||
|
RtlCopyMemory(String, InfoStrings, SectionSize);
|
||||||
|
|
||||||
|
/* Make sure last string is NULL-terminated */
|
||||||
|
String[SectionSize] = L'\0';
|
||||||
|
Array[Count] = NULL;
|
||||||
|
Array[0] = String;
|
||||||
|
|
||||||
|
/* Parse strings into array */
|
||||||
|
Index = 0;
|
||||||
|
ArrayIndex = 1;
|
||||||
|
while(Index < SectionSize && ArrayIndex < Count)
|
||||||
|
{
|
||||||
|
/* Get to the next string */
|
||||||
|
if(String[Index] != L'\0')
|
||||||
|
{
|
||||||
|
/* Get next character */
|
||||||
|
Index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip zero padding */
|
||||||
|
while(InfoStrings[Index] == L'\0' && Index < SectionSize)
|
||||||
|
{
|
||||||
|
/* Get next character */
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push string into array */
|
||||||
|
Array[ArrayIndex] = &String[Index];
|
||||||
|
ArrayIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return array of strings and its size */
|
||||||
|
*ModInfo = Array;
|
||||||
|
*InfoCount = Count;
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine installs XTLDR protocol for further usage by modules.
|
* This routine installs XTLDR protocol for further usage by modules.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user