8#include <Library/BaseMemoryLib.h>
9#include <Library/DebugLib.h>
10#include <Library/MemoryAllocationLib.h>
13#include <Library/PrintLib.h>
14#include <Library/UefiLib.h>
15#include <Library/UefiBootServicesTableLib.h>
16#include <Library/UefiRuntimeServicesTableLib.h>
37#define SHIFT_TOKEN(pos, token, offset) do {\
38 CopyMem ((UINT8 *)(token) + (offset), (token), (UINT8 *)(pos) - (UINT8 *)(token)); \
39 (token) = (UINT8 *)(token) + (offset); \
51 ZeroMem (Arguments,
sizeof (*Arguments));
64 Arguments->KernelAddrP = &BA1->
kaddr;
70 Arguments->SystemTable = (EFI_SYSTEM_TABLE *)(UINTN)BA1->
efiSystemTable;
82 Arguments->KernelAddrP = &BA2->
kaddr;
88 Arguments->SystemTable = (EFI_SYSTEM_TABLE *)(UINTN)BA2->
efiSystemTable;
98 IN CONST CHAR8 *CommandLine,
99 IN CONST CHAR8 *Argument,
100 IN CONST UINTN ArgumentLength,
101 OUT UINTN *ValueLength OPTIONAL
107 Str = AsciiStrStr (CommandLine, Argument);
114 if (!Str || ((Str != CommandLine) && (*(Str - 1) !=
' ')) ||
115 ((Str[ArgumentLength] !=
' ') && (Str[ArgumentLength] !=
'\0') &&
116 (Str[ArgumentLength - 1] !=
'=')))
121 Str += ArgumentLength;
123 if (ValueLength != NULL) {
124 StrEnd = AsciiStrStr (Str,
" ");
125 if (StrEnd == NULL) {
126 *ValueLength = AsciiStrLen (Str);
128 *ValueLength = StrEnd - Str;
137 IN OUT CHAR8 *CommandLine,
138 IN CONST CHAR8 *Argument
143 UINTN ArgumentLength;
145 ArgumentLength = AsciiStrLen (Argument);
149 Match = AsciiStrStr (Match, Argument);
150 if ( (Match != NULL) && ((Match == CommandLine) || (*(Match - 1) ==
' '))
151 && ( (Match[ArgumentLength - 1] ==
'=')
152 || (Match[ArgumentLength] ==
' ')
153 || (Match[ArgumentLength] ==
'\0')))
155 while (*Match !=
' ' && *Match !=
'\0') {
158 }
else if (Match != NULL) {
161 }
while (Match != NULL);
166 Updated = CommandLine;
168 while (CommandLine[0] ==
' ') {
172 while (CommandLine[0] !=
'\0') {
173 while (CommandLine[0] ==
' ' && CommandLine[1] ==
' ') {
177 *Updated++ = *CommandLine++;
180 ZeroMem (Updated, CommandLine - Updated);
186 IN OUT CHAR8 *CommandLine,
187 IN CONST CHAR8 *Argument,
188 IN CONST UINTN ArgumentLength
192 UINTN
Len = AsciiStrLen (CommandLine);
194 if (Context != NULL) {
196 if (EFI_ERROR (Status)) {
197 if (Status != EFI_ABORTED) {
210 DEBUG ((DEBUG_INFO,
"OCB: boot-args are invalid, ignoring\n"));
216 *CommandLine++ =
' ';
219 AsciiStrnCpyS (CommandLine, ArgumentLength + 1, Argument, ArgumentLength + 1);
225 IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
226 IN CONST CHAR8 **Arguments,
227 IN UINT32 ArgumentCount,
232 UINTN ArgumentLength;
234 CHAR16 *NewArguments;
237 ASSERT (LoadedImage != NULL);
238 ASSERT (Arguments != NULL);
239 ASSERT (ArgumentCount > 0);
246 for (Index = 0; Index < ArgumentCount; ++Index) {
247 ArgumentLength = AsciiStrSize (Arguments[Index]);
248 if (BaseOverflowAddUN (TotalLength, ArgumentLength, &TotalLength)) {
253 if (BaseOverflowMulUN (TotalLength,
sizeof (CHAR16), &TotalLength)) {
257 Replace |= LoadedImage->LoadOptionsSize <
sizeof (CHAR16);
259 && BaseOverflowTriAddUN (TotalLength,
sizeof (CHAR16), LoadedImage->LoadOptionsSize, &TotalLength))
264 NewArguments = AllocatePool (TotalLength);
265 if (NewArguments == NULL) {
269 Walker = NewArguments;
270 for (Index = 0; Index < ArgumentCount; ++Index) {
275 ArgumentLength = AsciiStrLen (Arguments[Index]);
276 AsciiStrToUnicodeStrS (
281 Walker += ArgumentLength;
286 CopyMem (Walker, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);
287 Walker += LoadedImage->LoadOptionsSize /
sizeof (CHAR16);
291 LoadedImage->LoadOptions = NewArguments;
292 LoadedImage->LoadOptionsSize = (UINT32)TotalLength;
299 IN EFI_LOADED_IMAGE *LoadedImage OPTIONAL,
300 IN EFI_GET_VARIABLE GetVariable OPTIONAL,
301 IN CONST CHAR8 *Argument,
302 IN CONST UINTN ArgumentLength,
303 IN OUT CHAR8 **Value OPTIONAL
309 UINTN BootArgsVarLen;
314 CONST CHAR8 *ArgValue;
315 UINTN ArgValueLength;
319 if (LoadedImage != NULL) {
320 Options = (CHAR16 *)LoadedImage->LoadOptions;
321 OptionsSize = LoadedImage->LoadOptionsSize /
sizeof (CHAR16);
323 if ((Options != NULL) && (OptionsSize > 0)) {
328 LastIndex = OptionsSize - 1;
329 Last = Options[LastIndex];
330 Options[LastIndex] =
'\0';
335 if (ArgValue != NULL) {
342 Options[LastIndex] = Last;
350 BootArgsVarLen =
sizeof (BootArgsVar);
351 Status = (GetVariable != NULL ? GetVariable :
gRT->GetVariable)(
359 if (!EFI_ERROR (Status) && (BootArgsVarLen > 0)) {
363 BootArgsVar[BootArgsVarLen-1] =
'\0';
366 if (ArgValue != NULL) {
372 if (HasArgument && (Value != NULL)) {
373 *Value = AllocateCopyPool (AsciiStrnSizeS (ArgValue, ArgValueLength), ArgValue);
374 if (*Value == NULL) {
385 IN UINT32 LoadOptionsSize,
386 IN CONST VOID *LoadOptions
390 (((LoadOptions) == NULL) == ((LoadOptionsSize) == 0))
391 && ((LoadOptionsSize) %
sizeof (CHAR16) == 0)
394 ((LoadOptions) == NULL)
395 || (((CHAR16 *)(LoadOptions))[((LoadOptionsSize) / 2) - 1] == CHAR_NULL)
403 IN UINT32 LoadOptionsSize,
404 IN CONST VOID *LoadOptions
408 ((LoadOptions) != NULL)
409 && ((LoadOptionsSize) >=
sizeof (CHAR16))
410 && (((LoadOptionsSize) %
sizeof (CHAR16)) == 0)
411 && (((CHAR16 *)(LoadOptions))[((LoadOptionsSize) / 2) - 1] == CHAR_NULL)
417 IN CONST EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
423 ASSERT (LoadedImage != NULL);
424 ASSERT (ParsedVars != NULL);
428 DEBUG ((DEBUG_ERROR,
"OCB: Invalid LoadOptions (%p:%u)\n", LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize));
429 return EFI_INVALID_PARAMETER;
432 if (!
OcHasLoadOptions (LoadedImage->LoadOptionsSize, LoadedImage->LoadOptions)) {
433 DEBUG ((
OC_TRACE_PARSE_VARS,
"OCB: No LoadOptions (%p:%u)\n", LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize));
434 return EFI_NOT_FOUND;
439 if (Status == EFI_INVALID_PARAMETER) {
440 DEBUG ((DEBUG_ERROR,
"OCB: Failed to parse LoadOptions (%p:%u)\n", LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize));
441 }
else if (Status == EFI_NOT_FOUND) {
442 DEBUG ((DEBUG_WARN,
"OCB: Empty LoadOptions\n"));
453 IN CONST BOOLEAN TokensOnly
469 if ((StrVars == NULL) || ((StringFormat ==
OcStringFormatUnicode) ? (((CHAR16 *)StrVars)[0] == CHAR_NULL) : (((CHAR8 *)StrVars)[0] ==
'\0'))) {
471 return EFI_NOT_FOUND;
475 if (*ParsedVars == NULL) {
476 return EFI_OUT_OF_RESOURCES;
483 QuoteChar = CHAR_NULL;
494 if (Option == NULL) {
496 return EFI_OUT_OF_RESOURCES;
503 OriginalValue = Value;
523 *((CHAR16 *)
Pos) = CHAR_NULL;
525 *((CHAR8 *)
Pos) =
'\0';
531 OriginalValue = Value;
537 if (Option == NULL) {
539 return EFI_OUT_OF_RESOURCES;
578 QuoteChar = CHAR_NULL;
586 if ((State !=
PARSE_VARS_QUOTED_VALUE) || (NewCh ==
'"') || (NewCh ==
'\\') || (NewCh ==
'$') || (NewCh ==
'`')) {
591 }
else if (Ch == L
'`') {
598 if (
Pos == OriginalValue) {
607 *((CHAR16 *)
Pos) = CHAR_NULL;
611 *((CHAR8 *)
Pos) =
'\0';
619 OriginalValue = NULL;
636 }
while (Ch != CHAR_NULL);
643 DEBUG ((DEBUG_WARN,
"OCB: Invalid vars (%u)\n", State));
645 return EFI_INVALID_PARAMETER;
648 if ((*ParsedVars)->Items == NULL) {
650 return EFI_NOT_FOUND;
682 if (ParsedVars == NULL) {
686 ASSERT (ParsedVars->Items != NULL);
688 for (Index = 0; Index < ParsedVars->Count; ++Index) {
699 if (AsciiStrCmp (Option->
Ascii.
Name, Name) == 0) {
719 IN CONST CHAR16 *Name,
729 IN CONST CHAR8 *Name,
760 return EFI_NOT_FOUND;
763 if (StrValue == NULL) {
764 return EFI_NOT_FOUND;
769 Status = StrHexToUintnS (StrValue, NULL, Value);
771 Status = StrDecimalToUintnS (StrValue, NULL, Value);
775 Status = AsciiStrHexToUintnS (StrValue, NULL, Value);
777 Status = AsciiStrDecimalToUintnS (StrValue, NULL, Value);
796 return EFI_NOT_FOUND;
799 if (StrValue == NULL) {
800 return EFI_NOT_FOUND;
804 Status = StrToGuid (StrValue, Value);
806 Status = AsciiStrToGuid (StrValue, Value);
#define kBootArgsFlagCSRActiveConfig
#define kBootArgsVersion1
EFI_GUID gAppleBootVariableGuid
VOID OcRemoveArgumentFromCmd(IN OUT CHAR8 *CommandLine, IN CONST CHAR8 *Argument)
enum PARSE_VARS_STATE_ PARSE_VARS_STATE
OC_PARSED_VAR * OcParsedVarsItemAt(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST UINTN Index)
BOOLEAN EFIAPI OcHasLoadOptions(IN UINT32 LoadOptionsSize, IN CONST VOID *LoadOptions)
EFI_STATUS OcParseLoadOptions(IN CONST EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, OUT OC_FLEX_ARRAY **ParsedVars)
EFI_STATUS OcParsedVarsGetInt(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST VOID *Name, OUT UINTN *Value, IN CONST OC_STRING_FORMAT StringFormat)
BOOLEAN OcParsedVarsGetAsciiStr(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST CHAR8 *Name, OUT CHAR8 **Value)
BOOLEAN OcHasParsedVar(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST VOID *Name, IN CONST OC_STRING_FORMAT StringFormat)
CONST CHAR8 * OcGetArgumentFromCmd(IN CONST CHAR8 *CommandLine, IN CONST CHAR8 *Argument, IN CONST UINTN ArgumentLength, OUT UINTN *ValueLength OPTIONAL)
BOOLEAN OcParsedVarsGetStr(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST VOID *Name, OUT VOID **Value, IN CONST OC_STRING_FORMAT StringFormat)
BOOLEAN OcAppendArgumentToCmd(IN OUT OC_PICKER_CONTEXT *Context OPTIONAL, IN OUT CHAR8 *CommandLine, IN CONST CHAR8 *Argument, IN CONST UINTN ArgumentLength)
BOOLEAN OcAppendArgumentsToLoadedImage(IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN CONST CHAR8 **Arguments, IN UINT32 ArgumentCount, IN BOOLEAN Replace)
EFI_STATUS OcParseVars(IN VOID *StrVars, OUT OC_FLEX_ARRAY **ParsedVars, IN CONST OC_STRING_FORMAT StringFormat, IN CONST BOOLEAN TokensOnly)
BOOLEAN OcCheckArgumentFromEnv(IN EFI_LOADED_IMAGE *LoadedImage OPTIONAL, IN EFI_GET_VARIABLE GetVariable OPTIONAL, IN CONST CHAR8 *Argument, IN CONST UINTN ArgumentLength, IN OUT CHAR8 **Value OPTIONAL)
EFI_STATUS OcParsedVarsGetGuid(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST VOID *Name, OUT EFI_GUID *Value, IN CONST OC_STRING_FORMAT StringFormat)
BOOLEAN EFIAPI OcValidLoadOptions(IN UINT32 LoadOptionsSize, IN CONST VOID *LoadOptions)
#define SHIFT_TOKEN(pos, token, offset)
VOID OcParseBootArgs(OUT OC_BOOT_ARGUMENTS *Arguments, IN VOID *BootArgs)
BOOLEAN OcParsedVarsGetUnicodeStr(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST CHAR16 *Name, OUT CHAR16 **Value)
@ PARSE_VARS_QUOTED_VALUE
@ PARSE_VARS_SHELL_EXPANSION
EFI_STATUS InternalRunRequestPrivilege(IN OC_PICKER_CONTEXT *PickerContext, IN OC_PRIVILEGE_LEVEL Level)
#define OC_TRACE_PARSE_VARS
#define MAX_LOAD_OPTIONS_SIZE
VOID OcFlexArrayFree(IN OUT OC_FLEX_ARRAY **FlexArray)
OC_FLEX_ARRAY * OcFlexArrayInit(IN CONST UINTN ItemSize, IN CONST OC_FLEX_ARRAY_FREE_ITEM FreeItem OPTIONAL)
VOID * OcFlexArrayAddItem(IN OUT OC_FLEX_ARRAY *FlexArray)
VOID * OcFlexArrayItemAt(IN CONST OC_FLEX_ARRAY *FlexArray, IN CONST UINTN Index)
enum _OC_STRING_FORMAT OC_STRING_FORMAT
BOOLEAN EFIAPI OcUnicodeStartsWith(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
BOOLEAN EFIAPI OcAsciiStartsWith(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
BOOLEAN OcIsSpaceOrNull(CHAR16 Ch)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
CHAR8 CommandLine[BOOT_LINE_LENGTH]
UINT32 MemoryMapDescriptorVersion
UINT64 efiRuntimeServicesVirtualPageStart
UINT32 MemoryMapDescriptorSize
UINT32 efiRuntimeServicesPageStart
UINT64 efiRuntimeServicesVirtualPageStart
UINT32 MemoryMapDescriptorSize
UINT32 efiRuntimeServicesPageStart
UINT32 MemoryMapDescriptorVersion
CHAR8 CommandLine[BOOT_LINE_LENGTH]
OC_PARSED_VAR_ASCII Ascii
OC_PARSED_VAR_UNICODE Unicode