Initial code for reading configuration from a file
Some checks failed
Builds / ExectOS (amd64) (push) Failing after 19s
Builds / ExectOS (i686) (push) Failing after 15s

This commit is contained in:
Rafal Kupiec 2023-12-09 23:45:41 +01:00
parent b57ee630fd
commit a06f32c61d
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
3 changed files with 258 additions and 37 deletions

View File

@ -45,7 +45,7 @@ typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PVOID *ProtocolHandler, IN PEFI_G
typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize);
typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds);
/* XTLDR Configuration data */ /* XTLDR Configuration */
typedef struct _XTBL_CONFIGURATION typedef struct _XTBL_CONFIGURATION
{ {
PWCHAR Default; PWCHAR Default;
@ -56,6 +56,22 @@ typedef struct _XTBL_CONFIGURATION
PWCHAR Tune; PWCHAR Tune;
} XTBL_CONFIGURATION, *PXTBL_CONFIGURATION; } XTBL_CONFIGURATION, *PXTBL_CONFIGURATION;
/* XTLDR Configuration data */
typedef struct _XTBL_INI_OPTION
{
LIST_ENTRY Flink;
PWCHAR Name;
PWCHAR Value;
} XTBL_INI_OPTION, *PXTBL_INI_OPTION;
/* XTLDR Configuration section */
typedef struct _XTBL_INI_SECTION
{
LIST_ENTRY Flink;
LIST_ENTRY Options;
PWCHAR SectionName;
} XTBL_INI_SECTION, *PXTBL_INI_SECTION;
/* XTLDR Status data */ /* XTLDR Status data */
typedef struct _XTBL_STATUS typedef struct _XTBL_STATUS
{ {

View File

@ -9,6 +9,234 @@
#include <xtldr.h> #include <xtldr.h>
XTCDECL
EFI_STATUS
BlpLoadConfiguration()
{
EFI_STATUS Status;
PLIST_ENTRY Configuration;
PCHAR ConfigData;
/* Initialize configuration pointer */
Configuration = NULL;
/* Read data from configuration file */
Status = BlpReadConfigurationFile(L"\\EFI\\BOOT\\", L"XTLDR.INI", &ConfigData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load configuration */
BlDebugPrint(L"Failed to load configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n");
return Status;
}
/* Parse configuration data */
Status = BlpParseConfigurationFile(ConfigData, Configuration);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to parse configuration */
BlDebugPrint(L"Failed to parse configuration file (FS0:/EFI/BOOT/XTLDR.INI)\n");
return Status;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Parses command line arguments and updates global configuration.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlpParseCommandLine(VOID)
{
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
EFI_STATUS Status;
/* Handle loaded image protocol */
Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage);
if(Status == STATUS_EFI_SUCCESS)
{
/* Check if launched from UEFI shell */
if(LoadedImage && LoadedImage->LoadOptions)
{
/* Update global boot loader configuration */
BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions);
}
}
}
XTCDECL
EFI_STATUS
BlpParseConfigurationFile(IN CONST PCHAR RawConfig,
OUT PLIST_ENTRY Configuration)
{
SIZE_T SectionLength, KeyLength, ValueLength;
PCHAR InputData, Key, SectionName, Value;
PXTBL_INI_SECTION Section;
PXTBL_INI_OPTION Option;
EFI_STATUS Status;
/* Initialize pointers */
InputData = RawConfig;
Section = NULL;
Option = NULL;
SectionName = NULL;
Key = NULL;
Value = NULL;
/* Analyze configuration data until end of file is reached */
while(*InputData != 0)
{
if(*InputData == ';' || *InputData == '#')
{
/* Skip comment until end of the line */
while(*InputData != 0 && *InputData != '\n')
{
/* Advance to the next character */
InputData++;
}
}
else if(*InputData == ' ' || *InputData == '\t' || *InputData == '\r' || *InputData == '\n')
{
/* Skip whitespaces */
InputData++;
}
else if(*InputData == '[')
{
/* Skip leading bracket */
InputData++;
/* Store section name */
SectionName = InputData;
/* Find end of the section name */
while(*InputData != ']' && *InputData != 0 && *InputData != '\n')
{
/* Advance to the next character */
InputData++;
}
/* Check if end of the section name is reached */
if(*InputData != ']')
{
/* Section name does not end */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Mark end of the section name and advance to the next character */
*InputData = 0;
InputData++;
/* Remove leading and trailing spaces from section name */
SectionName = RtlTrimString(SectionName);
/* Find length of the section name */
SectionLength = RtlStringLength(SectionName, 0);
/* Allocate memory for new section */
Status = BlMemoryAllocatePool(sizeof(XTBL_INI_SECTION), (PVOID*)&Section);
if(Status == STATUS_EFI_SUCCESS)
{
/* Allocate more memory for section name */
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName);
}
if(Status != STATUS_EFI_SUCCESS)
{
/* Some memory allocation failed */
return Status;
}
/* Initialize new section and add it to the list */
RtlInitializeListHead(&Section->Options);
RtlStringToWideString(Section->SectionName, &SectionName, SectionLength + 1);
RtlInsertTailList(Configuration, &Section->Flink);
}
else
{
/* Store key */
Key = InputData;
/* Find end of the key */
while(*InputData != '=' && *InputData != 0 && *InputData != '\n')
{
/* Advance to the next character */
InputData++;
}
/* Check if end of the key is reached */
if(*InputData != '=')
{
/* Key name does not end */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Mark end of the key and advance to the next character */
*InputData = 0;
InputData++;
/* Skip all leading spaces in the value */
while(*InputData == ' ')
{
/* Advance to the next character */
InputData++;
}
/* Store value */
Value = InputData;
/* Find end of the value */
while(*InputData != 0 && *InputData != '\n')
{
/* Advance to the next character */
InputData++;
}
/* Mark end of the value and advance to the next character */
*InputData = 0;
InputData++;
/* Remove leading and trailing spaces from key and value */
Key = RtlTrimString(Key);
Value = RtlTrimString(Value);
/* Find length of the key and its value */
KeyLength = RtlStringLength(Key, 0);
ValueLength = RtlStringLength(Value, 0);
/* Allocate memory for new option */
Status = BlMemoryAllocatePool(sizeof(XTBL_INI_OPTION), (PVOID*)&Option);
if(Status == STATUS_EFI_SUCCESS)
{
/* Allocate more memory for option name */
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);
if(Status == STATUS_EFI_SUCCESS)
{
/* Allocate even more memory for option value */
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);
}
}
if(Status != STATUS_EFI_SUCCESS)
{
/* Some memory allocation failed */
return Status;
}
/* Initialize new option and add it to the list */
RtlStringToWideString(Option->Name, &Key, RtlStringLength(Key, 0) + 1);
RtlStringToWideString(Option->Value, &Value, RtlStringLength(Value, 0) + 1);
RtlInsertTailList(&Section->Options, &Option->Flink);
}
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Loads configuration file from the specified directory on the FS0:/ drive. * Loads configuration file from the specified directory on the FS0:/ drive.
* *
@ -27,7 +255,7 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory,
IN CONST PWCHAR ConfigFile, IN CONST PWCHAR ConfigFile,
OUT PCHAR *ConfigData) OUT PCHAR *ConfigData)
{ {
@ -63,35 +291,7 @@ BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory,
BlCloseVolume(DiskHandle); BlCloseVolume(DiskHandle);
/* Return read status */ /* Return read status */
return STATUS_EFI_SUCCESS; return Status;
}
/**
* Parses command line arguments and updates global configuration.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlpParseCommandLineOptions(VOID)
{
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
EFI_STATUS Status;
/* Handle loaded image protocol */
Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage);
if(Status == STATUS_EFI_SUCCESS)
{
/* Check if launched from UEFI shell */
if(LoadedImage && LoadedImage->LoadOptions)
{
/* Update global boot loader configuration */
BlpUpdateGlobalConfiguration(LoadedImage->LoadOptions);
}
}
} }
/** /**

View File

@ -168,14 +168,19 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
IN ULONG BaudRate); IN ULONG BaudRate);
XTCDECL XTCDECL
EFI_STATUS VOID
BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, BlpParseCommandLine(VOID);
IN CONST PWCHAR ConfigFile,
OUT PCHAR *ConfigData);
XTCDECL XTCDECL
VOID EFI_STATUS
BlpParseCommandLineOptions(VOID); BlpParseConfigurationFile(IN CONST PCHAR RawConfig,
OUT PLIST_ENTRY Configuration);
XTCDECL
EFI_STATUS
BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory,
IN CONST PWCHAR ConfigFile,
OUT PCHAR *ConfigData);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS