[FREELDR:NTLDR] Normalize the boot options as soon as possible, and fix the algorithm

Use `NtLdrGetNextOption()` to loop over each individual option and move
it to its proper place. This automatically trims any '/' option
separator, including repeated ones and whitespaces, and allow for
straightforward replacement with one single space.
This commit is contained in:
Hermès Bélusca-Maïto
2022-04-03 02:48:36 +02:00
parent e87a74f131
commit 1ac657ed0e
3 changed files with 58 additions and 28 deletions

View File

@@ -509,7 +509,7 @@ LoadReactOSSetup(
PSETUP_LOADER_BLOCK SetupBlock;
CHAR BootPath[MAX_PATH];
CHAR FilePath[MAX_PATH];
CHAR UserBootOptions[256];
CHAR UserBootOptions[MAX_OPTIONS_LENGTH+1];
PCSTR BootOptions;
static PCSTR SourcePaths[] =
@@ -606,8 +606,7 @@ LoadReactOSSetup(
BootOptions = GetArgumentValue(Argc, Argv, "Options");
if (!BootOptions)
BootOptions = "";
TRACE("BootOptions: '%s'\n", BootOptions);
TRACE("BootOptions(1): '%s'\n", BootOptions);
/* Check if a RAM disk file was given */
FileName = (PSTR)NtLdrGetOptionEx(BootOptions, "RDPATH=", &FileNameLength);
@@ -650,7 +649,6 @@ LoadReactOSSetup(
TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath);
// UseLocalSif = NtLdrGetOption(BootOptions, "USELOCALSIF");
if (NtLdrGetOption(BootOptions, "SIFOPTIONSOVERRIDE"))
{
PCSTR OptionsToRemove[2] = {"SIFOPTIONSOVERRIDE", NULL};
@@ -665,8 +663,6 @@ LoadReactOSSetup(
FALSE,
NULL,
OptionsToRemove);
BootOptions = UserBootOptions;
}
else // if (!*BootOptions || NtLdrGetOption(BootOptions, "SIFOPTIONSADD"))
{
@@ -778,11 +774,15 @@ LoadReactOSSetup(
FrLdrHeapFree(ExtraOptions, TAG_BOOT_OPTIONS);
if (HigherPriorityOptions)
FrLdrHeapFree(HigherPriorityOptions, TAG_BOOT_OPTIONS);
BootOptions = UserBootOptions;
}
TRACE("BootOptions: '%s'\n", BootOptions);
/* Append boot-time options */
AppendBootTimeOptions(UserBootOptions);
/* Post-process the boot options */
NtLdrNormalizeOptions(UserBootOptions);
BootOptions = UserBootOptions;
TRACE("BootOptions(2): '%s'\n", BootOptions);
/* Handle the SOS option */
SosEnabled = !!NtLdrGetOption(BootOptions, "SOS");

View File

@@ -130,13 +130,12 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
{
/*
* Examples of correct options and paths:
* CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
* CHAR Options[] = "/NODEBUG";
* CHAR Options[] = "DEBUGPORT=COM1 BAUDRATE=115200";
* CHAR Options[] = "NODEBUG";
* CHAR SystemRoot[] = "\\WINNT\\";
* CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
*/
PSTR LoadOptions, NewLoadOptions;
CHAR HalPath[] = "\\";
CHAR ArcBoot[MAX_PATH+1];
CHAR MiscFiles[MAX_PATH+1];
@@ -188,18 +187,9 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
RtlStringCbCopyA(LoaderBlock->NtHalPathName, sizeof(WinLdrSystemBlock->NtHalPathName), HalPath);
LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
/* Fill LoadOptions and strip the '/' switch symbol in front of each option */
NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
/* Fill LoadOptions */
LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
RtlStringCbCopyA(LoaderBlock->LoadOptions, sizeof(WinLdrSystemBlock->LoadOptions), Options);
do
{
while (*LoadOptions == '/')
++LoadOptions;
*NewLoadOptions++ = *LoadOptions;
} while (*LoadOptions++);
LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
/* ARC devices */
@@ -1142,6 +1132,39 @@ WinLdrInitErrataInf(
return TRUE;
}
/**
* @brief
* Normalize in-place the NT boot options by removing any leading '/',
* normalizing TABs to spaces, etc.
**/
VOID
NtLdrNormalizeOptions(
_Inout_ PSTR LoadOptions)
{
PCHAR NewOptions = LoadOptions;
PCSTR Options, Option;
ULONG OptionLength;
/* Normalize the boot options by successively enumerating each and
* copying them back, stripping and replacing any extra separator
* by one single space. */
Options = LoadOptions;
while ((Option = NtLdrGetNextOption(&Options, &OptionLength)))
{
if (NewOptions > LoadOptions)
*NewOptions++ = ' ';
/* If necessary, move the current option back */
ASSERT(NewOptions <= Option);
if (NewOptions < Option)
RtlMoveMemory(NewOptions, Option, OptionLength * sizeof(CHAR));
NewOptions += OptionLength;
}
/* NUL-terminate */
*NewOptions = ANSI_NULL;
}
ARC_STATUS
LoadAndBootWindows(
IN ULONG Argc,
@@ -1158,7 +1181,7 @@ LoadAndBootWindows(
PLOADER_PARAMETER_BLOCK LoaderBlock;
CHAR BootPath[MAX_PATH];
CHAR FilePath[MAX_PATH];
CHAR BootOptions[256];
CHAR BootOptions[MAX_OPTIONS_LENGTH+1];
/* Retrieve the (mandatory) boot type */
ArgValue = GetArgumentValue(Argc, Argv, "BootType");
@@ -1240,9 +1263,7 @@ LoadAndBootWindows(
ArgValue = GetArgumentValue(Argc, Argv, "Options");
if (ArgValue && *ArgValue)
RtlStringCbCopyA(BootOptions, sizeof(BootOptions), ArgValue);
/* Append boot-time options */
AppendBootTimeOptions(BootOptions);
TRACE("BootOptions(1): '%s'\n", BootOptions);
/*
* Set the "/HAL=" and "/KERNEL=" options if needed.
@@ -1277,7 +1298,12 @@ LoadAndBootWindows(
}
}
TRACE("BootOptions: '%s'\n", BootOptions);
/* Append boot-time options */
AppendBootTimeOptions(BootOptions);
/* Post-process the boot options */
NtLdrNormalizeOptions(BootOptions);
TRACE("BootOptions(2): '%s'\n", BootOptions);
/* Check if a RAM disk file was given */
FileName = NtLdrGetOptionEx(BootOptions, "RDPATH=", &FileNameLength);

View File

@@ -84,6 +84,10 @@ NtLdrOutputLoadMsg(
_In_ PCSTR FileName,
_In_opt_ PCSTR Description);
VOID
NtLdrNormalizeOptions(
_Inout_ PSTR LoadOptions);
PVOID WinLdrLoadModule(PCSTR ModuleName, PULONG Size,
TYPE_OF_MEMORY MemoryType);