From cb7f4deb3730a983c8b438afd14df49b45fcc356 Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Sun, 3 Dec 2023 18:23:50 +0100 Subject: [PATCH 1/6] INI configuration parser for XTLDR --- ExectOS.code-workspace | 3 ++ sdk/xtdk/bmtypes.h | 13 +++++ xtldr2/config.c | 105 ++++++++++++++++++++++++++++++++++++++ xtldr2/includes/bootman.h | 5 ++ xtldr2/xtldr.c | 7 +++ 5 files changed, 133 insertions(+) diff --git a/ExectOS.code-workspace b/ExectOS.code-workspace index 6c383fe..1647a29 100644 --- a/ExectOS.code-workspace +++ b/ExectOS.code-workspace @@ -20,5 +20,8 @@ } }, "terminal.integrated.defaultProfile.linux": "xtchain", + "files.associations": { + "globals.h": "c" + }, } } \ No newline at end of file diff --git a/sdk/xtdk/bmtypes.h b/sdk/xtdk/bmtypes.h index 8f75f5a..c5cda46 100644 --- a/sdk/xtdk/bmtypes.h +++ b/sdk/xtdk/bmtypes.h @@ -11,6 +11,19 @@ #include +typedef struct _XTBL_INI_SECTION +{ + LIST_ENTRY Flink; + LIST_ENTRY Options; + PWCHAR SectionName; +} XTBL_INI_SECTION, *PXTBL_INI_SECTION; + +typedef struct _XTBL_INI_OPTION +{ + LIST_ENTRY Flink; + PWCHAR Name; + PWCHAR Value; +} XTBL_INI_OPTION, *PXTBL_INI_OPTION; /* XTLDR configuration data */ typedef struct _XTBM_CONFIGURATION diff --git a/xtldr2/config.c b/xtldr2/config.c index 2c8ac23..cf5ffb0 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -4,10 +4,115 @@ * FILE: xtldr/config.c * DESCRIPTION: XT Boot Loader Configuration * DEVELOPERS: Rafal Kupiec + * Jozef Nagy */ #include +/** + * Parses configuration INI file contents. + * + * @param FileContents + * Supplies a pointer to a wide string containing contents of the configuration file. + * + * @param Sections + * Supplies a pointer to a linked list which will be written by this routine. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +XTSTATUS +BlConfigParseIniFile(IN PWCHAR FileContents, + OUT PLIST_ENTRY Sections) +{ + PWCHAR Argument, LastArg, CurrentSectionName; + SIZE_T Length; + + /* Set a default section name */ + CurrentSectionName = L"Unknown"; + + /* Tokenize provided options */ + Argument = RtlWideStringTokenize(FileContents, L"\r\n", &LastArg); + + /* Iterate over all arguments passed to boot loader */ + while(Argument != NULL) + { + /* Check every line */ + if(RtlWideStringCompare(Argument, L"[", 1) == 0) + { + /* Skip to the section name */ + Argument += 1; + Length = RtlWideStringLength(Argument, 0); + + /* Everything until ']' belongs to the section's name */ + // CurrentSectionName = RtlWideStringTokenize(Argument, L"]", &LastArg); + BlConsolePrint(L"New section: %S\n", CurrentSectionName); + } + else if(RtlWideStringCompare(Argument, L"Default=", 8) == 0) + { + /* Skip to the argument value and calculate argument length */ + Argument += 8; + Length = RtlWideStringLength(Argument, 0); + + /* Set a default section */ + BlConsolePrint(L"Setting DEFAULT value to %S\n", Argument); + } + else if(RtlWideStringCompare(Argument, L"Debug=", 6) == 0) + { + /* Skip to the argument value */ + Argument += 6; + Length = RtlWideStringLength(Argument, 0); + + /* Set a debug port and baud rate */ + BlConsolePrint(L"Setting DEBUG value to %S\n", Argument); + } + else if(RtlWideStringCompare(Argument, L"Theme=", 6) == 0) + { + /* Skip to the argument value */ + Argument += 6; + Length = RtlWideStringLength(Argument, 0); + + /* Set a theme name */ + BlConsolePrint(L"Setting THEME value to %S\n", Argument); + } + else if(RtlWideStringCompare(Argument, L"Timeout=", 8) == 0) + { + /* Skip to the argument value */ + Argument += 8; + Length = RtlWideStringLength(Argument, 0); + + /* Set a timeout */ + BlConsolePrint(L"Setting TIMEOUT value to %S\n", Argument); + } + else if(RtlWideStringCompare(Argument, L"Tune=", 5) == 0) + { + /* Skip to the argument value */ + Argument += 5; + Length = RtlWideStringLength(Argument, 0); + + /* Set a tune */ + BlConsolePrint(L"Setting TUNE value to %S\n", Argument); + } + else if(RtlWideStringCompare(Argument, L"#", 1) == 0) + { + /* We can safely ignore a comment */ + Argument += 1; + } + else + { + /* Configuration file might be corrupt */ + BlConsolePrint(L"Unknown argument: %S\n", Argument); + return STATUS_INVALID_PARAMETER; + } + + /* Take next argument */ + Argument = RtlWideStringTokenize(NULL, L"\n", &LastArg); + } + + return STATUS_SUCCESS; +} /** * Parses command line arguments and updates global configuration. diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index a4665fa..e2a05b1 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -79,6 +79,11 @@ BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...); +XTCDECL +XTSTATUS +BlConfigParseIniFile(IN PWCHAR FileContents, + OUT PLIST_ENTRY Sections); + XTCDECL VOID BlpConfigParseCommandLine(VOID); diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 8a6bb3f..76940fc 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -28,15 +28,22 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { EFI_STATUS Status; + LIST_ENTRY ConfigSections; /* Set the system table and image handle */ EfiImageHandle = ImageHandle; EfiSystemTable = SystemTable; + + RtlInitializeListHead(&ConfigSections); + /* Initialize UEFI console and early print XTLDR version */ BlConsoleInitialize(); BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); + /* Parse INI Configuration file */ + BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\r\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\r\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\r\n#\r\n# Basic section is [XTLDR] which contains a bootloader specific options:\r\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\r\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\r\n# Default - specifies which operating system listen in config file will be started if no choice is made\r\n# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel\r\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\r\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\r\n#\r\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\r\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\r\n# by the XT Boot Loader. The available options are:\r\n# SystemName - sets a long operating system name that will be shown on the boot menu\r\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\r\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\r\n# KernelFile - sets kernel filename with optional path relative to SystemPath\r\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\r\n# HalFile - sets HAL filename with optional path relative to SystemPath\r\n# Parameters - specifies extra boot options for the kernel\r\n[XTLDR]Tune=400 880 2 988 2 783 2 392 2 587 3Debug=COM1,115200Timeout=30Theme=FancyDefault=ExectOS[ExectOS]SystemName=\"ExectOS Operating System\"SystemType=XTOSSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOSKernelFile=xtoskrnl.exeParameters=DEBUG DEBUGPORT=COM1,115200[Windows]SystemName=\"Microsoft Windows 2000\"SystemType=NT50SystemPath=multi(0)disk(0)rdisk(0)partition(2)/WindowsKernelFile=ntoskrnl.exeHalFile=hal.dllParameters=/NOGUIBOOT /MININT[Linux]SystemName=\"GNU/Linux\"SystemType=LINUXSystemPath=multi(0)disk(0)rdisk(0)partition(3)/bootKernelFile=vmlinuzInitrdFile=initramfs.cpio.gzParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); + /* Temporary infinite loop */ for(;;); -- 2.50.1 From 36df83431b83c0eda57b494a292fc883b50a60e5 Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Sun, 3 Dec 2023 18:36:05 +0100 Subject: [PATCH 2/6] Ignore newlines in INI parser --- CMakeLists.txt | 2 +- xtldr2/config.c | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9bf79e..c635dc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR}) add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]") # Set the virtual disk image size (in MiB) -set_disk_image_size(128) +set_disk_image_size(16) # Build all subprojects add_subdirectory(bootdata) diff --git a/xtldr2/config.c b/xtldr2/config.c index cf5ffb0..885910e 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -40,7 +40,17 @@ BlConfigParseIniFile(IN PWCHAR FileContents, while(Argument != NULL) { /* Check every line */ - if(RtlWideStringCompare(Argument, L"[", 1) == 0) + if(RtlWideStringCompare(Argument, L"\r\n", 2) == 0) + { + /* We can safely ignore a newline */ + Argument += 2; + } + else if(RtlWideStringCompare(Argument, L"#", 1) == 0) + { + /* We can safely ignore a comment */ + Argument += 1; + } + else if(RtlWideStringCompare(Argument, L"[", 1) == 0) { /* Skip to the section name */ Argument += 1; @@ -95,11 +105,6 @@ BlConfigParseIniFile(IN PWCHAR FileContents, /* Set a tune */ BlConsolePrint(L"Setting TUNE value to %S\n", Argument); } - else if(RtlWideStringCompare(Argument, L"#", 1) == 0) - { - /* We can safely ignore a comment */ - Argument += 1; - } else { /* Configuration file might be corrupt */ -- 2.50.1 From 25e3ec112d172a130e0217d48479af431e3662cf Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Wed, 6 Dec 2023 16:18:13 +0100 Subject: [PATCH 3/6] Partial BlConfigParseIniFile() implementation --- CMakeLists.txt | 2 +- xtldr2/config.c | 125 +++++++++++++++++--------------------- xtldr2/includes/globals.h | 1 - xtldr2/xtldr.c | 5 +- 4 files changed, 61 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c635dc0..b9bf79e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR}) add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]") # Set the virtual disk image size (in MiB) -set_disk_image_size(16) +set_disk_image_size(128) # Build all subprojects add_subdirectory(bootdata) diff --git a/xtldr2/config.c b/xtldr2/config.c index 885910e..b10257b 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -13,7 +13,7 @@ * Parses configuration INI file contents. * * @param FileContents - * Supplies a pointer to a wide string containing contents of the configuration file. + * Supplies a pointer to a string containing contents of the configuration file. * * @param Sections * Supplies a pointer to a linked list which will be written by this routine. @@ -27,93 +27,82 @@ XTSTATUS BlConfigParseIniFile(IN PWCHAR FileContents, OUT PLIST_ENTRY Sections) { - PWCHAR Argument, LastArg, CurrentSectionName; - SIZE_T Length; + PWCHAR Line, LastLine, Key, Value; + SIZE_T Length, KeyLength; - /* Set a default section name */ - CurrentSectionName = L"Unknown"; + UINT Error; + + /* There's not error at the moment */ + Error = 0; /* Tokenize provided options */ - Argument = RtlWideStringTokenize(FileContents, L"\r\n", &LastArg); + Line = RtlWideStringTokenize(FileContents, L"\n", &LastLine); - /* Iterate over all arguments passed to boot loader */ - while(Argument != NULL) + while(Line != NULL) { - /* Check every line */ - if(RtlWideStringCompare(Argument, L"\r\n", 2) == 0) - { - /* We can safely ignore a newline */ - Argument += 2; - } - else if(RtlWideStringCompare(Argument, L"#", 1) == 0) - { - /* We can safely ignore a comment */ - Argument += 1; - } - else if(RtlWideStringCompare(Argument, L"[", 1) == 0) - { - /* Skip to the section name */ - Argument += 1; - Length = RtlWideStringLength(Argument, 0); + Length = RtlWideStringLength(Line, 0); - /* Everything until ']' belongs to the section's name */ - // CurrentSectionName = RtlWideStringTokenize(Argument, L"]", &LastArg); - BlConsolePrint(L"New section: %S\n", CurrentSectionName); - } - else if(RtlWideStringCompare(Argument, L"Default=", 8) == 0) + /* Don't parse a blank line */ + if(Length <= 0) { - /* Skip to the argument value and calculate argument length */ - Argument += 8; - Length = RtlWideStringLength(Argument, 0); - - /* Set a default section */ - BlConsolePrint(L"Setting DEFAULT value to %S\n", Argument); + continue; } - else if(RtlWideStringCompare(Argument, L"Debug=", 6) == 0) - { - /* Skip to the argument value */ - Argument += 6; - Length = RtlWideStringLength(Argument, 0); - /* Set a debug port and baud rate */ - BlConsolePrint(L"Setting DEBUG value to %S\n", Argument); + /* Parse */ + if (Length < 1) + { + /* Blank line */ } - else if(RtlWideStringCompare(Argument, L"Theme=", 6) == 0) + else if (RtlWideStringCompare(Line, L"#", 1) == 0 || + RtlWideStringCompare(Line, L";", 1) == 0) { - /* Skip to the argument value */ - Argument += 6; - Length = RtlWideStringLength(Argument, 0); - - /* Set a theme name */ - BlConsolePrint(L"Setting THEME value to %S\n", Argument); + /* Don't parse a comment */ } - else if(RtlWideStringCompare(Argument, L"Timeout=", 8) == 0) + else if (RtlWideStringCompare(Line, L"[", 1) == 0 && + RtlWideStringCompare(Line + Length - 3, L"]", 1) == 0) { - /* Skip to the argument value */ - Argument += 8; - Length = RtlWideStringLength(Argument, 0); + + /* Remove brackets around section name */ + PWCHAR SectionName = Line + 1; + SectionName[Length - 3] = 0; - /* Set a timeout */ - BlConsolePrint(L"Setting TIMEOUT value to %S\n", Argument); - } - else if(RtlWideStringCompare(Argument, L"Tune=", 5) == 0) - { - /* Skip to the argument value */ - Argument += 5; - Length = RtlWideStringLength(Argument, 0); - - /* Set a tune */ - BlConsolePrint(L"Setting TUNE value to %S\n", Argument); + /* Save section name */ + BlConsolePrint(L"Section: %S\n", SectionName); } else { - /* Configuration file might be corrupt */ - BlConsolePrint(L"Unknown argument: %S\n", Argument); + KeyLength = 0; + + /* Set key=value pair to the entire line for further processing */ + Value = Line; + Key = Line; + + /* Get the value */ + while(Value != 0 && + RtlWideStringCompare(Value, L"=", 1) != 0) + { + Value++; + KeyLength++; + } + + /* Get rid of the leading '=' */ + Value++; + + /* Set the key */ + Key[KeyLength] = 0; + + BlConsolePrint(L"Key: %S\n Value: %S\n", Key, Value); + } + + if(Error == 1) + { + /* Display error message and exit */ + BlConsolePrint(L"Syntax error\n"); return STATUS_INVALID_PARAMETER; } - /* Take next argument */ - Argument = RtlWideStringTokenize(NULL, L"\n", &LastArg); + /* Take next line */ + Line = RtlWideStringTokenize(NULL, L"\n", &LastLine); } return STATUS_SUCCESS; diff --git a/xtldr2/includes/globals.h b/xtldr2/includes/globals.h index d9e1419..5b652fc 100644 --- a/xtldr2/includes/globals.h +++ b/xtldr2/includes/globals.h @@ -11,7 +11,6 @@ #include - /* XT Boot Loader configuration data */ EXTERN XTBM_CONFIGURATION BlpConfiguration; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index 76940fc..feac3d5 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -39,10 +39,11 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, /* Initialize UEFI console and early print XTLDR version */ BlConsoleInitialize(); - BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Parse INI Configuration file */ - BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\r\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\r\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\r\n#\r\n# Basic section is [XTLDR] which contains a bootloader specific options:\r\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\r\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\r\n# Default - specifies which operating system listen in config file will be started if no choice is made\r\n# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel\r\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\r\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\r\n#\r\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\r\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\r\n# by the XT Boot Loader. The available options are:\r\n# SystemName - sets a long operating system name that will be shown on the boot menu\r\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\r\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\r\n# KernelFile - sets kernel filename with optional path relative to SystemPath\r\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\r\n# HalFile - sets HAL filename with optional path relative to SystemPath\r\n# Parameters - specifies extra boot options for the kernel\r\n[XTLDR]Tune=400 880 2 988 2 783 2 392 2 587 3Debug=COM1,115200Timeout=30Theme=FancyDefault=ExectOS[ExectOS]SystemName=\"ExectOS Operating System\"SystemType=XTOSSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOSKernelFile=xtoskrnl.exeParameters=DEBUG DEBUGPORT=COM1,115200[Windows]SystemName=\"Microsoft Windows 2000\"SystemType=NT50SystemPath=multi(0)disk(0)rdisk(0)partition(2)/WindowsKernelFile=ntoskrnl.exeHalFile=hal.dllParameters=/NOGUIBOOT /MININT[Linux]SystemName=\"GNU/Linux\"SystemType=LINUXSystemPath=multi(0)disk(0)rdisk(0)partition(3)/bootKernelFile=vmlinuzInitrdFile=initramfs.cpio.gzParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); + BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\n#\n# Basic section is [XTLDR] which contains a bootloader specific options:\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\n# Default - specifies which operating system listen in config file will be started if no choice is made\n# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\n#\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\n# by the XT Boot Loader. The available options are:\n# SystemName - sets a long operating system name that will be shown on the boot menu\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\n# KernelFile - sets kernel filename with optional path relative to SystemPath\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\n# HalFile - sets HAL filename with optional path relative to SystemPath\n# Parameters - specifies extra boot options for the kernel\n[XTLDR]Tune=400 880 2 988 2 783 2 392 2 587 3Debug=COM1,115200Timeout=30Theme=FancyDefault=ExectOS[ExectOS]SystemName=\"ExectOS Operating System\"SystemType=XTOSSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOSKernelFile=xtoskrnl.exeParameters=DEBUG DEBUGPORT=COM1,115200[Windows]SystemName=\"Microsoft Windows 2000\"SystemType=NT50SystemPath=multi(0)disk(0)rdisk(0)partition(2)/WindowsKernelFile=ntoskrnl.exeHalFile=hal.dllParameters=/NOGUIBOOT /MININT[Linux]SystemName=\"GNU/Linux\"SystemType=LINUXSystemPath=multi(0)disk(0)rdisk(0)partition(3)/bootKernelFile=vmlinuzInitrdFile=initramfs.cpio.gzParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); + + BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Temporary infinite loop */ for(;;); -- 2.50.1 From e8574a6d8c231812754c38e4b6df922adb5b1d42 Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Wed, 6 Dec 2023 16:27:10 +0100 Subject: [PATCH 4/6] Removed useless length check in BlConfigParseIniFile() --- xtldr2/config.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/xtldr2/config.c b/xtldr2/config.c index e854c55..aa7f10e 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -42,12 +42,6 @@ BlConfigParseIniFile(IN PWCHAR FileContents, { Length = RtlWideStringLength(Line, 0); - /* Don't parse a blank line */ - if(Length <= 0) - { - continue; - } - /* Parse */ if (Length < 1) { -- 2.50.1 From fabadd013cd577e61c78081e52ddae5c2621023d Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Wed, 6 Dec 2023 21:08:46 +0100 Subject: [PATCH 5/6] Rewrite INI parser --- CMakeLists.txt | 2 +- xtldr2/config.c | 109 ++++++++++++++++++++++++++---------------------- xtldr2/xtldr.c | 4 +- 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9bf79e..c635dc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR}) add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]") # Set the virtual disk image size (in MiB) -set_disk_image_size(128) +set_disk_image_size(16) # Build all subprojects add_subdirectory(bootdata) diff --git a/xtldr2/config.c b/xtldr2/config.c index aa7f10e..d5aa967 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -13,7 +13,7 @@ * Parses configuration INI file contents. * * @param FileContents - * Supplies a pointer to a string containing contents of the configuration file. + * Supplies a pointer to a wide string containing contents of the configuration file. * * @param Sections * Supplies a pointer to a linked list which will be written by this routine. @@ -27,76 +27,83 @@ XTSTATUS BlConfigParseIniFile(IN PWCHAR FileContents, OUT PLIST_ENTRY Sections) { - PWCHAR Line, LastLine, Key, Value; - SIZE_T Length, KeyLength; + PWCHAR CurrentSectionName, Key, Value; + PWCHAR Input; + UINT SectionLength, KeyLength, ValueLength; - UINT Error; + Input = FileContents; + CurrentSectionName = L"None"; - /* There's not error at the moment */ - Error = 0; - - /* Tokenize provided options */ - Line = RtlWideStringTokenize(FileContents, L"\n", &LastLine); - - while(Line != NULL) + while(*Input != 0) { - Length = RtlWideStringLength(Line, 0); + SectionLength = 0; + KeyLength = 0; + ValueLength = 0; - /* Parse */ - if (Length < 1) + if(*Input == ';' || *Input == '#') { - /* Blank line */ + /* Skip comments */ + while(*Input != 0 && *Input != '\n') + { + Input++; + } } - else if (RtlWideStringCompare(Line, L"#", 1) == 0 || - RtlWideStringCompare(Line, L";", 1) == 0) + else if(*Input == '\n') { - /* Don't parse a comment */ + /* Skip newline */ + Input++; } - else if (RtlWideStringCompare(Line, L"[", 1) == 0 && - RtlWideStringCompare(Line + Length - 3, L"]", 1) == 0) + else if(*Input == '[') { - - /* Remove brackets around section name */ - PWCHAR SectionName = Line + 1; - SectionName[Length - 3] = 0; + /* Get the section name */ + Input++; + CurrentSectionName = Input; - /* Save section name */ - BlConsolePrint(L"Section: %S\n", SectionName); + /* Skip to the next line */ + while(*Input != ']' && *Input != 0 && *Input != '\n') + { + Input++; + SectionLength++; + } + CurrentSectionName[SectionLength] = 0; + Input++; + + BlConsolePrint(L"[%S]\n", CurrentSectionName); } else { - KeyLength = 0; - - /* Set key=value pair to the entire line for further processing */ - Value = Line; - Key = Line; - - /* Get the value */ - while(Value != 0 && - RtlWideStringCompare(Value, L"=", 1) != 0) + /* Get the length of key */ + while(*Input != '=' && *Input != 0 && *Input != '\n') { - Value++; + Input++; KeyLength++; } - /* Get rid of the leading '=' */ - Value++; - - /* Set the key */ + /* Set key */ + Input -= KeyLength; + Key = Input; Key[KeyLength] = 0; + BlConsolePrint(L"%S=", Key); - BlConsolePrint(L"Key: %S\n Value: %S\n", Key, Value); + /* Skip to the value */ + Input += KeyLength + 1; + + /* Get the length of value */ + while(*Input != 0 && *Input != '\n') + { + Input++; + ValueLength++; + } + + /* Set value */ + Input -= ValueLength; + Value = Input; + Value[ValueLength] = 0; + BlConsolePrint(L"%S\n", Value); + Input += ValueLength; + + Input++; } - - if(Error == 1) - { - /* Display error message and exit */ - BlConsolePrint(L"Syntax error\n"); - return STATUS_INVALID_PARAMETER; - } - - /* Take next line */ - Line = RtlWideStringTokenize(NULL, L"\n", &LastLine); } return STATUS_SUCCESS; diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index b21c1c8..b76332b 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -38,13 +38,13 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, RtlInitializeListHead(&ConfigSections); /* Initialize UEFI console and early print XTLDR version */ - BlConsoleInitialize(); + BlpConsoleInitialize(); /* Parse INI Configuration file */ - BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\n#\n# Basic section is [XTLDR] which contains a bootloader specific options:\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\n# Default - specifies which operating system listen in config file will be started if no choice is made\n# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\n#\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\n# by the XT Boot Loader. The available options are:\n# SystemName - sets a long operating system name that will be shown on the boot menu\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\n# KernelFile - sets kernel filename with optional path relative to SystemPath\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\n# HalFile - sets HAL filename with optional path relative to SystemPath\n# Parameters - specifies extra boot options for the kernel\n[XTLDR]Tune=400 880 2 988 2 783 2 392 2 587 3Debug=COM1,115200Timeout=30Theme=FancyDefault=ExectOS[ExectOS]SystemName=\"ExectOS Operating System\"SystemType=XTOSSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOSKernelFile=xtoskrnl.exeParameters=DEBUG DEBUGPORT=COM1,115200[Windows]SystemName=\"Microsoft Windows 2000\"SystemType=NT50SystemPath=multi(0)disk(0)rdisk(0)partition(2)/WindowsKernelFile=ntoskrnl.exeHalFile=hal.dllParameters=/NOGUIBOOT /MININT[Linux]SystemName=\"GNU/Linux\"SystemType=LINUXSystemPath=multi(0)disk(0)rdisk(0)partition(3)/bootKernelFile=vmlinuzInitrdFile=initramfs.cpio.gzParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); /* Initialize XTLDR and early print XTLDR version */ BlpInitializeEfiBootLoader(); + BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\n#\n# Basic section is [XTLDR] which contains a bootloader specific options:\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\n# Default - specifies which operating system listen in config file will be started if no choice is made\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\n#\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\n# by the XT Boot Loader. The available options are:\n# SystemName - sets a long operating system name that will be shown on the boot menu\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\n# KernelFile - sets kernel filename with optional path relative to SystemPath\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\n# HalFile - sets HAL filename with optional path relative to SystemPath\n# Parameters - specifies extra boot options for the kernel\n\n[XTLDR]\nTune=400 880 2 988 2 783 2 392 2 587 3\nDebug=COM1,115200\nTimeout=30\nDefault=ExectOS\n\n[ExectOS]\nSystemName=\"ExectOS Operating System\"\nSystemType=XTOS\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS\nKernelFile=xtoskrnl.exe\nParameters=DEBUG DEBUGPORT=COM1,115200\n\n[Windows]\nSystemName=\"Microsoft Windows 2000\"\nSystemType=NT50\nSystemPath=multi(0)disk(0)rdisk(0)partition(2)/Windows\nKernelFile=ntoskrnl.exe\nHalFile=hal.dll\nParameters=/NOGUIBOOT /MININT\n\n[Linux]\nSystemName=\"GNU/Linux\"\nSystemType=LINUX\nSystemPath=multi(0)disk(0)rdisk(0)partition(3)/boot\nKernelFile=vmlinuz\nInitrdFile=initramfs.cpio.gz\nParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Parse configuration options passed from UEFI shell */ -- 2.50.1 From 46682dcf65f355f4daa3ffb9ff7f44995983f9a9 Mon Sep 17 00:00:00 2001 From: Jozef Nagy Date: Wed, 6 Dec 2023 22:49:10 +0100 Subject: [PATCH 6/6] Removed debugging junk for BlpConfigParseIniFile() --- CMakeLists.txt | 2 +- xtldr2/config.c | 31 +++++++++---------------------- xtldr2/includes/bootman.h | 10 +++++----- xtldr2/xtldr.c | 7 ------- 4 files changed, 15 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c635dc0..b9bf79e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ file(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR}) add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_PATH_PREFIX}\\\" - 1 : sizeof XTOS_SOURCE_DIR]") # Set the virtual disk image size (in MiB) -set_disk_image_size(16) +set_disk_image_size(128) # Build all subprojects add_subdirectory(bootdata) diff --git a/xtldr2/config.c b/xtldr2/config.c index d5aa967..ebedca7 100644 --- a/xtldr2/config.c +++ b/xtldr2/config.c @@ -18,14 +18,14 @@ * @param Sections * Supplies a pointer to a linked list which will be written by this routine. * - * @return This routine returns a status code. + * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL -XTSTATUS -BlConfigParseIniFile(IN PWCHAR FileContents, - OUT PLIST_ENTRY Sections) +VOID +BlpConfigParseIniFile(IN PWCHAR FileContents, + OUT PLIST_ENTRY SectionsHead) { PWCHAR CurrentSectionName, Key, Value; PWCHAR Input; @@ -62,31 +62,24 @@ BlConfigParseIniFile(IN PWCHAR FileContents, /* Skip to the next line */ while(*Input != ']' && *Input != 0 && *Input != '\n') { - Input++; SectionLength++; + Input++; } - CurrentSectionName[SectionLength] = 0; Input++; - - BlConsolePrint(L"[%S]\n", CurrentSectionName); } else { /* Get the length of key */ while(*Input != '=' && *Input != 0 && *Input != '\n') { - Input++; KeyLength++; + Input++; } /* Set key */ - Input -= KeyLength; - Key = Input; + Key = Input - KeyLength; Key[KeyLength] = 0; - BlConsolePrint(L"%S=", Key); - - /* Skip to the value */ - Input += KeyLength + 1; + Input++; /* Get the length of value */ while(*Input != 0 && *Input != '\n') @@ -96,17 +89,11 @@ BlConfigParseIniFile(IN PWCHAR FileContents, } /* Set value */ - Input -= ValueLength; - Value = Input; + Value = Input - ValueLength; Value[ValueLength] = 0; - BlConsolePrint(L"%S\n", Value); - Input += ValueLength; - Input++; } } - - return STATUS_SUCCESS; } /** diff --git a/xtldr2/includes/bootman.h b/xtldr2/includes/bootman.h index 5b03b5b..ba0b842 100644 --- a/xtldr2/includes/bootman.h +++ b/xtldr2/includes/bootman.h @@ -79,6 +79,11 @@ XTCDECL EFI_STATUS BlpActivateSerialIOController(); +XTCDECL +VOID +BlpConfigParseIniFile(IN PWCHAR FileContents, + OUT PLIST_ENTRY SectionsHead); + XTCDECL VOID BlpParseCommandLineOptions(VOID); @@ -123,11 +128,6 @@ BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine, IN PUINT16 Format, IN ...); -XTCDECL -XTSTATUS -BlConfigParseIniFile(IN PWCHAR FileContents, - OUT PLIST_ENTRY Sections); - XTCDECL VOID BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine, diff --git a/xtldr2/xtldr.c b/xtldr2/xtldr.c index b76332b..5e33e75 100644 --- a/xtldr2/xtldr.c +++ b/xtldr2/xtldr.c @@ -28,23 +28,16 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle, IN PEFI_SYSTEM_TABLE SystemTable) { EFI_STATUS Status; - LIST_ENTRY ConfigSections; /* Set the system table and image handle */ EfiImageHandle = ImageHandle; EfiSystemTable = SystemTable; - - RtlInitializeListHead(&ConfigSections); - /* Initialize UEFI console and early print XTLDR version */ BlpConsoleInitialize(); - /* Parse INI Configuration file */ - /* Initialize XTLDR and early print XTLDR version */ BlpInitializeEfiBootLoader(); - BlConfigParseIniFile(L"# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\n#\n# Basic section is [XTLDR] which contains a bootloader specific options:\n# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\n# it is also possible to specify custom port address with: COM0:[address],[baud_rate]\n# Default - specifies which operating system listen in config file will be started if no choice is made\n# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically\n# Tune - plays a tune on the pcspeaker right before the XTLDR loads\n#\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\n# by the XT Boot Loader. The available options are:\n# SystemName - sets a long operating system name that will be shown on the boot menu\n# SystemType - specifies an OS type from a predefined list of supported boot protocols\n# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\n# KernelFile - sets kernel filename with optional path relative to SystemPath\n# InitrdFile - sets initramfs image filename with optional path relative to SystemPath\n# HalFile - sets HAL filename with optional path relative to SystemPath\n# Parameters - specifies extra boot options for the kernel\n\n[XTLDR]\nTune=400 880 2 988 2 783 2 392 2 587 3\nDebug=COM1,115200\nTimeout=30\nDefault=ExectOS\n\n[ExectOS]\nSystemName=\"ExectOS Operating System\"\nSystemType=XTOS\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS\nKernelFile=xtoskrnl.exe\nParameters=DEBUG DEBUGPORT=COM1,115200\n\n[Windows]\nSystemName=\"Microsoft Windows 2000\"\nSystemType=NT50\nSystemPath=multi(0)disk(0)rdisk(0)partition(2)/Windows\nKernelFile=ntoskrnl.exe\nHalFile=hal.dll\nParameters=/NOGUIBOOT /MININT\n\n[Linux]\nSystemName=\"GNU/Linux\"\nSystemType=LINUX\nSystemPath=multi(0)disk(0)rdisk(0)partition(3)/boot\nKernelFile=vmlinuz\nInitrdFile=initramfs.cpio.gz\nParameters=root=/dev/xvda3 rootfstype=ext4", &ConfigSections); BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); /* Parse configuration options passed from UEFI shell */ -- 2.50.1