mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 20:50:41 +00:00

- Introduce a set of NtLdrGet(Next)Option(Ex) helpers that allow retrieving respectively, the "next" option in an options string, and retrieving a given named option in such an options string, by correctly parsing that string. Valid syntaxes: /OPTION1 /OPTION2/OPTION3 OPTION4 /OPTION5(=...) ... Options separators are slashes, or whitespace (space, tab), mandatory if no slash is used, and otherwise optional. - Use these functions wherever NT load options are being parsed. - Simplify the parsing of /DEBUGPORT=... using these functions. - When parsing the /HAL=... or /KERNEL=... options, only the first encountered one is taken into account, any other ones are discarded. - When parsing the other load options, only their first occurrences are taken into account, any other repetitions are discarded. * The NOPAE option overrides any previous PAE option. * Any NOEXECUTE(=) option should override any previous NOEXECUTE=ALWAYSOFF (or equivalently, EXECUTE) option.
131 lines
3.3 KiB
C
131 lines
3.3 KiB
C
/*
|
|
* PROJECT: FreeLoader
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: NT Kernel Load Options Support Functions
|
|
* COPYRIGHT: Copyright 2020 Hermes Belusca-Maito
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <freeldr.h>
|
|
#include "ntldropts.h"
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
PCSTR
|
|
NtLdrGetNextOption(
|
|
IN OUT PCSTR* Options,
|
|
OUT PULONG OptionLength OPTIONAL)
|
|
{
|
|
PCSTR NextOption;
|
|
PCSTR Option = NULL;
|
|
ULONG Length = 0;
|
|
|
|
if (OptionLength)
|
|
*OptionLength = 0;
|
|
|
|
if (!Options || !*Options)
|
|
return NULL;
|
|
|
|
/* Loop over each option */
|
|
NextOption = *Options;
|
|
while (*NextOption)
|
|
{
|
|
/* Skip possible initial whitespace */
|
|
NextOption += strspn(NextOption, " \t");
|
|
|
|
/* Stop now if we have already found an option.
|
|
* NextOption points to the next following option. */
|
|
if (Option)
|
|
break;
|
|
|
|
/*
|
|
* Check whether a new option starts. Options are delimited
|
|
* with an option separator '/' or with whitespace.
|
|
*/
|
|
if (*NextOption == '/')
|
|
++NextOption;
|
|
|
|
/* Get the actual length of the option until
|
|
* the next whitespace or option separator. */
|
|
Length = (ULONG)strcspn(NextOption, " \t/");
|
|
|
|
/* Retrieve the option if present and go to the beginning of the next one */
|
|
if (Length != 0)
|
|
Option = NextOption;
|
|
|
|
/* Restart after the end of the option */
|
|
NextOption += Length;
|
|
}
|
|
|
|
*Options = NextOption;
|
|
if (Option && OptionLength)
|
|
*OptionLength = Length;
|
|
return Option;
|
|
}
|
|
|
|
/*
|
|
* OptionName specifies the option name, without any leading
|
|
* option separator '/', to search for within the Options.
|
|
* The search is made case-insensitive.
|
|
*/
|
|
PCSTR
|
|
NtLdrGetOptionExN(
|
|
IN PCSTR Options,
|
|
IN PCCH OptionName,
|
|
IN ULONG OptNameLength,
|
|
OUT PULONG OptionLength OPTIONAL)
|
|
{
|
|
PCSTR NextOptions;
|
|
PCSTR Option = NULL;
|
|
ULONG OptLength = 0;
|
|
|
|
if (OptionLength)
|
|
*OptionLength = 0;
|
|
|
|
if (!Options || !*Options)
|
|
return NULL;
|
|
if (!OptionName || (OptNameLength == 0) || !*OptionName)
|
|
return NULL;
|
|
|
|
NextOptions = Options;
|
|
while ((Option = NtLdrGetNextOption(&NextOptions, &OptLength)))
|
|
{
|
|
/*
|
|
* Check whether the option to find exactly matches the current
|
|
* load option, or is a prefix thereof if this is an option with
|
|
* appended data.
|
|
*/
|
|
if ((OptLength >= OptNameLength) &&
|
|
(_strnicmp(Option, OptionName, OptNameLength) == 0))
|
|
{
|
|
if ((OptLength == OptNameLength) ||
|
|
(OptionName[OptNameLength-1] == '=') ||
|
|
(OptionName[OptNameLength-1] == ':'))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Option && OptionLength)
|
|
*OptionLength = OptLength;
|
|
return Option;
|
|
}
|
|
|
|
PCSTR
|
|
NtLdrGetOptionEx(
|
|
IN PCSTR Options,
|
|
IN PCSTR OptionName,
|
|
OUT PULONG OptionLength OPTIONAL)
|
|
{
|
|
return NtLdrGetOptionExN(Options, OptionName, strlen(OptionName), OptionLength);
|
|
}
|
|
|
|
PCSTR
|
|
NtLdrGetOption(
|
|
IN PCSTR Options,
|
|
IN PCSTR OptionName)
|
|
{
|
|
return NtLdrGetOptionEx(Options, OptionName, NULL);
|
|
}
|