diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 9a4d9a0..ae291a9 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -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 VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds); -/* XTLDR Configuration data */ +/* XTLDR Configuration */ typedef struct _XTBL_CONFIGURATION { PWCHAR Default; @@ -56,6 +56,22 @@ typedef struct _XTBL_CONFIGURATION PWCHAR Tune; } 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 */ typedef struct _XTBL_STATUS { diff --git a/xtldr2/config.c b/xtldr2/config.c index 0ff3e73..7bdf1c8 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -9,6 +9,234 @@ #include +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. * @@ -27,7 +255,7 @@ */ XTCDECL EFI_STATUS -BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, +BlpReadConfigurationFile(IN CONST PWCHAR ConfigDirectory, IN CONST PWCHAR ConfigFile, OUT PCHAR *ConfigData) { @@ -63,35 +291,7 @@ BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, BlCloseVolume(DiskHandle); /* Return read status */ - 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 -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); - } - } + return Status; } /** diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index c01b55c..d8ae19b 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -168,14 +168,19 @@ BlpInitializeSerialPort(IN ULONG PortNumber, IN ULONG BaudRate); XTCDECL -EFI_STATUS -BlpLoadConfigurationFile(IN CONST PWCHAR ConfigDirectory, - IN CONST PWCHAR ConfigFile, - OUT PCHAR *ConfigData); +VOID +BlpParseCommandLine(VOID); XTCDECL -VOID -BlpParseCommandLineOptions(VOID); +EFI_STATUS +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 EFI_STATUS