OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
BootArguments.c
Go to the documentation of this file.
1
7
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>
17
19
20/*
21 Shell var and load options processing states.
22*/
31
32//
33// Shift memory from token start to current position forwards by offset bytes
34// and update token to point to shifted start (thereby discarding offset bytes
35// from the token ending at current position).
36//
37#define SHIFT_TOKEN(pos, token, offset) do {\
38 CopyMem ((UINT8 *)(token) + (offset), (token), (UINT8 *)(pos) - (UINT8 *)(token)); \
39 (token) = (UINT8 *)(token) + (offset); \
40} while (0)
41
42VOID
44 OUT OC_BOOT_ARGUMENTS *Arguments,
45 IN VOID *BootArgs
46 )
47{
48 BootArgs1 *BA1 = (BootArgs1 *)BootArgs;
49 BootArgs2 *BA2 = (BootArgs2 *)BootArgs;
50
51 ZeroMem (Arguments, sizeof (*Arguments));
52
53 if (BA1->Version == kBootArgsVersion1) {
54 //
55 // Pre Lion
56 //
57 Arguments->MemoryMap = &BA1->MemoryMap;
58 Arguments->MemoryMapSize = &BA1->MemoryMapSize;
59 Arguments->MemoryMapDescriptorSize = &BA1->MemoryMapDescriptorSize;
60 Arguments->MemoryMapDescriptorVersion = &BA1->MemoryMapDescriptorVersion;
61
62 Arguments->CommandLine = &BA1->CommandLine[0];
63
64 Arguments->KernelAddrP = &BA1->kaddr;
65 Arguments->SystemTableP = &BA1->efiSystemTable;
66 Arguments->RuntimeServicesPG = &BA1->efiRuntimeServicesPageStart;
67 Arguments->RuntimeServicesV = &BA1->efiRuntimeServicesVirtualPageStart;
68 Arguments->DeviceTreeP = &BA1->deviceTreeP;
69 Arguments->DeviceTreeLength = &BA1->deviceTreeLength;
70 Arguments->SystemTable = (EFI_SYSTEM_TABLE *)(UINTN)BA1->efiSystemTable;
71 } else {
72 //
73 // Lion and newer
74 //
75 Arguments->MemoryMap = &BA2->MemoryMap;
76 Arguments->MemoryMapSize = &BA2->MemoryMapSize;
77 Arguments->MemoryMapDescriptorSize = &BA2->MemoryMapDescriptorSize;
78 Arguments->MemoryMapDescriptorVersion = &BA2->MemoryMapDescriptorVersion;
79
80 Arguments->CommandLine = &BA2->CommandLine[0];
81
82 Arguments->KernelAddrP = &BA2->kaddr;
83 Arguments->SystemTableP = &BA2->efiSystemTable;
84 Arguments->RuntimeServicesPG = &BA2->efiRuntimeServicesPageStart;
85 Arguments->RuntimeServicesV = &BA2->efiRuntimeServicesVirtualPageStart;
86 Arguments->DeviceTreeP = &BA2->deviceTreeP;
87 Arguments->DeviceTreeLength = &BA2->deviceTreeLength;
88 Arguments->SystemTable = (EFI_SYSTEM_TABLE *)(UINTN)BA2->efiSystemTable;
89
91 Arguments->CsrActiveConfig = &BA2->csrActiveConfig;
92 }
93 }
94}
95
96CONST CHAR8 *
98 IN CONST CHAR8 *CommandLine,
99 IN CONST CHAR8 *Argument,
100 IN CONST UINTN ArgumentLength,
101 OUT UINTN *ValueLength OPTIONAL
102 )
103{
104 CHAR8 *Str;
105 CHAR8 *StrEnd;
106
107 Str = AsciiStrStr (CommandLine, Argument);
108
109 //
110 // Invalidate found boot arg if:
111 // - it is neither the beginning of Cmd, nor has space prefix -> boot arg is a suffix of another arg
112 // - it has neither space suffix, nor \0 suffix, and does not end with = -> boot arg is a prefix of another arg
113 //
114 if (!Str || ((Str != CommandLine) && (*(Str - 1) != ' ')) ||
115 ((Str[ArgumentLength] != ' ') && (Str[ArgumentLength] != '\0') &&
116 (Str[ArgumentLength - 1] != '=')))
117 {
118 return NULL;
119 }
120
121 Str += ArgumentLength;
122
123 if (ValueLength != NULL) {
124 StrEnd = AsciiStrStr (Str, " ");
125 if (StrEnd == NULL) {
126 *ValueLength = AsciiStrLen (Str);
127 } else {
128 *ValueLength = StrEnd - Str;
129 }
130 }
131
132 return Str;
133}
134
135VOID
137 IN OUT CHAR8 *CommandLine,
138 IN CONST CHAR8 *Argument
139 )
140{
141 CHAR8 *Match;
142 CHAR8 *Updated;
143 UINTN ArgumentLength;
144
145 ArgumentLength = AsciiStrLen (Argument);
146 Match = CommandLine;
147
148 do {
149 Match = AsciiStrStr (Match, Argument);
150 if ( (Match != NULL) && ((Match == CommandLine) || (*(Match - 1) == ' '))
151 && ( (Match[ArgumentLength - 1] == '=')
152 || (Match[ArgumentLength] == ' ')
153 || (Match[ArgumentLength] == '\0')))
154 {
155 while (*Match != ' ' && *Match != '\0') {
156 *Match++ = ' ';
157 }
158 } else if (Match != NULL) {
159 ++Match;
160 }
161 } while (Match != NULL);
162
163 //
164 // Write zeroes to reduce data leak
165 //
166 Updated = CommandLine;
167
168 while (CommandLine[0] == ' ') {
169 CommandLine++;
170 }
171
172 while (CommandLine[0] != '\0') {
173 while (CommandLine[0] == ' ' && CommandLine[1] == ' ') {
174 CommandLine++;
175 }
176
177 *Updated++ = *CommandLine++;
178 }
179
180 ZeroMem (Updated, CommandLine - Updated);
181}
182
183BOOLEAN
185 IN OUT OC_PICKER_CONTEXT *Context OPTIONAL,
186 IN OUT CHAR8 *CommandLine,
187 IN CONST CHAR8 *Argument,
188 IN CONST UINTN ArgumentLength
189 )
190{
191 EFI_STATUS Status;
192 UINTN Len = AsciiStrLen (CommandLine);
193
194 if (Context != NULL) {
196 if (EFI_ERROR (Status)) {
197 if (Status != EFI_ABORTED) {
198 ASSERT (FALSE);
199 return FALSE;
200 }
201
202 return TRUE;
203 }
204 }
205
206 //
207 // Account for extra space.
208 //
209 if (Len + ((Len > 0) ? 1 : 0) + ArgumentLength >= BOOT_LINE_LENGTH) {
210 DEBUG ((DEBUG_INFO, "OCB: boot-args are invalid, ignoring\n"));
211 return FALSE;
212 }
213
214 if (Len > 0) {
215 CommandLine += Len;
216 *CommandLine++ = ' ';
217 }
218
219 AsciiStrnCpyS (CommandLine, ArgumentLength + 1, Argument, ArgumentLength + 1);
220 return TRUE;
221}
222
223BOOLEAN
225 IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
226 IN CONST CHAR8 **Arguments,
227 IN UINT32 ArgumentCount,
228 IN BOOLEAN Replace
229 )
230{
231 UINT32 Index;
232 UINTN ArgumentLength;
233 UINTN TotalLength;
234 CHAR16 *NewArguments;
235 CHAR16 *Walker;
236
237 ASSERT (LoadedImage != NULL);
238 ASSERT (Arguments != NULL);
239 ASSERT (ArgumentCount > 0);
240
241 TotalLength = 0;
242
243 //
244 // Count length including spaces between or '\0' for the last argument.
245 //
246 for (Index = 0; Index < ArgumentCount; ++Index) {
247 ArgumentLength = AsciiStrSize (Arguments[Index]);
248 if (BaseOverflowAddUN (TotalLength, ArgumentLength, &TotalLength)) {
249 return FALSE;
250 }
251 }
252
253 if (BaseOverflowMulUN (TotalLength, sizeof (CHAR16), &TotalLength)) {
254 return FALSE;
255 }
256
257 Replace |= LoadedImage->LoadOptionsSize < sizeof (CHAR16);
258 if ( !Replace
259 && BaseOverflowTriAddUN (TotalLength, sizeof (CHAR16), LoadedImage->LoadOptionsSize, &TotalLength))
260 {
261 return FALSE;
262 }
263
264 NewArguments = AllocatePool (TotalLength);
265 if (NewArguments == NULL) {
266 return FALSE;
267 }
268
269 Walker = NewArguments;
270 for (Index = 0; Index < ArgumentCount; ++Index) {
271 if (Index != 0) {
272 *Walker++ = ' ';
273 }
274
275 ArgumentLength = AsciiStrLen (Arguments[Index]);
276 AsciiStrToUnicodeStrS (
277 Arguments[Index],
278 Walker,
279 ArgumentLength + 1
280 );
281 Walker += ArgumentLength;
282 }
283
284 if (!Replace) {
285 *Walker++ = ' ';
286 CopyMem (Walker, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);
287 Walker += LoadedImage->LoadOptionsSize / sizeof (CHAR16);
288 *Walker++ = '\0';
289 }
290
291 LoadedImage->LoadOptions = NewArguments;
292 LoadedImage->LoadOptionsSize = (UINT32)TotalLength;
293
294 return TRUE;
295}
296
297BOOLEAN
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
304 )
305{
306 CHAR16 *Options;
307 UINTN OptionsSize;
308 CHAR8 BootArgsVar[BOOT_LINE_LENGTH];
309 UINTN BootArgsVarLen;
310 EFI_STATUS Status;
311 UINTN LastIndex;
312 CHAR16 Last;
313 BOOLEAN HasArgument;
314 CONST CHAR8 *ArgValue;
315 UINTN ArgValueLength;
316
317 HasArgument = FALSE;
318
319 if (LoadedImage != NULL) {
320 Options = (CHAR16 *)LoadedImage->LoadOptions;
321 OptionsSize = LoadedImage->LoadOptionsSize / sizeof (CHAR16);
322
323 if ((Options != NULL) && (OptionsSize > 0)) {
324 //
325 // Just in case we do not have 0-termination.
326 // This may cut some data with unexpected options, but it is not like we care.
327 //
328 LastIndex = OptionsSize - 1;
329 Last = Options[LastIndex];
330 Options[LastIndex] = '\0';
331
332 UnicodeStrToAsciiStrS (Options, BootArgsVar, BOOT_LINE_LENGTH);
333
334 ArgValue = OcGetArgumentFromCmd (BootArgsVar, Argument, ArgumentLength, &ArgValueLength);
335 if (ArgValue != NULL) {
336 HasArgument = TRUE;
337 }
338
339 //
340 // Options do not belong to us, restore the changed value.
341 //
342 Options[LastIndex] = Last;
343 }
344 }
345
346 if (!HasArgument) {
347 //
348 // Important to avoid triggering boot-args wrapper too early if we have any.
349 //
350 BootArgsVarLen = sizeof (BootArgsVar);
351 Status = (GetVariable != NULL ? GetVariable : gRT->GetVariable)(
352 L"boot-args",
354 NULL,
355 &BootArgsVarLen,
356 BootArgsVar
357 );
358
359 if (!EFI_ERROR (Status) && (BootArgsVarLen > 0)) {
360 //
361 // Just in case we do not have 0-termination
362 //
363 BootArgsVar[BootArgsVarLen-1] = '\0';
364
365 ArgValue = OcGetArgumentFromCmd (BootArgsVar, Argument, ArgumentLength, &ArgValueLength);
366 if (ArgValue != NULL) {
367 HasArgument = TRUE;
368 }
369 }
370 }
371
372 if (HasArgument && (Value != NULL)) {
373 *Value = AllocateCopyPool (AsciiStrnSizeS (ArgValue, ArgValueLength), ArgValue);
374 if (*Value == NULL) {
375 return FALSE;
376 }
377 }
378
379 return HasArgument;
380}
381
382BOOLEAN
383EFIAPI
385 IN UINT32 LoadOptionsSize,
386 IN CONST VOID *LoadOptions
387 )
388{
389 return (
390 (((LoadOptions) == NULL) == ((LoadOptionsSize) == 0))
391 && ((LoadOptionsSize) % sizeof (CHAR16) == 0)
392 && ((LoadOptionsSize) <= MAX_LOAD_OPTIONS_SIZE)
393 && (
394 ((LoadOptions) == NULL)
395 || (((CHAR16 *)(LoadOptions))[((LoadOptionsSize) / 2) - 1] == CHAR_NULL)
396 )
397 );
398}
399
400BOOLEAN
401EFIAPI
403 IN UINT32 LoadOptionsSize,
404 IN CONST VOID *LoadOptions
405 )
406{
407 return (
408 ((LoadOptions) != NULL)
409 && ((LoadOptionsSize) >= sizeof (CHAR16))
410 && (((LoadOptionsSize) % sizeof (CHAR16)) == 0)
411 && (((CHAR16 *)(LoadOptions))[((LoadOptionsSize) / 2) - 1] == CHAR_NULL)
412 );
413}
414
415EFI_STATUS
417 IN CONST EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
418 OUT OC_FLEX_ARRAY **ParsedVars
419 )
420{
421 EFI_STATUS Status;
422
423 ASSERT (LoadedImage != NULL);
424 ASSERT (ParsedVars != NULL);
425 *ParsedVars = NULL;
426
427 if (!OcValidLoadOptions (LoadedImage->LoadOptionsSize, LoadedImage->LoadOptions)) {
428 DEBUG ((DEBUG_ERROR, "OCB: Invalid LoadOptions (%p:%u)\n", LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize));
429 return EFI_INVALID_PARAMETER;
430 }
431
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;
435 }
436
437 Status = OcParseVars (LoadedImage->LoadOptions, ParsedVars, OcStringFormatUnicode, FALSE);
438
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"));
443 }
444
445 return Status;
446}
447
448EFI_STATUS
450 IN VOID *StrVars,
451 OUT OC_FLEX_ARRAY **ParsedVars,
452 IN CONST OC_STRING_FORMAT StringFormat,
453 IN CONST BOOLEAN TokensOnly
454 )
455{
456 VOID *Pos;
457 VOID *NewPos;
458 PARSE_VARS_STATE State;
459 PARSE_VARS_STATE PushState;
460 BOOLEAN Retake;
461 CHAR16 Ch;
462 CHAR16 NewCh;
463 CHAR16 QuoteChar;
464 VOID *Name;
465 VOID *Value;
466 VOID *OriginalValue;
467 OC_PARSED_VAR *Option;
468
469 if ((StrVars == NULL) || ((StringFormat == OcStringFormatUnicode) ? (((CHAR16 *)StrVars)[0] == CHAR_NULL) : (((CHAR8 *)StrVars)[0] == '\0'))) {
470 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: No vars (%p)\n", StrVars));
471 return EFI_NOT_FOUND;
472 }
473
474 *ParsedVars = OcFlexArrayInit (sizeof (OC_PARSED_VAR), NULL);
475 if (*ParsedVars == NULL) {
476 return EFI_OUT_OF_RESOURCES;
477 }
478
479 Pos = StrVars;
481 PushState = PARSE_VARS_WHITE_SPACE;
482 Retake = FALSE;
483 QuoteChar = CHAR_NULL;
484
485 do {
486 Ch = (StringFormat == OcStringFormatUnicode) ? *((CHAR16 *)Pos) : *((CHAR8 *)Pos);
487 switch (State) {
489 if (Ch == '#') {
490 State = PARSE_VARS_COMMENT;
491 } else if (!OcIsSpaceOrNull (Ch)) {
492 if (TokensOnly) {
493 Option = OcFlexArrayAddItem (*ParsedVars);
494 if (Option == NULL) {
495 OcFlexArrayFree (ParsedVars);
496 return EFI_OUT_OF_RESOURCES;
497 }
498
499 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Value-only token\n"));
500
501 State = PARSE_VARS_VALUE;
502 Value = Pos;
503 OriginalValue = Value;
504 Retake = TRUE;
505 } else {
506 State = PARSE_VARS_NAME;
507 Name = Pos;
508 }
509 }
510
511 break;
512
514 if (Ch == '\n') {
516 }
517
518 break;
519
520 case PARSE_VARS_NAME:
521 if ((Ch == L'=') || OcIsSpaceOrNull (Ch)) {
522 if (StringFormat == OcStringFormatUnicode) {
523 *((CHAR16 *)Pos) = CHAR_NULL;
524 } else {
525 *((CHAR8 *)Pos) = '\0';
526 }
527
528 if (Ch == L'=') {
529 State = PARSE_VARS_VALUE;
530 Value = (UINT8 *)Pos + ((StringFormat == OcStringFormatUnicode) ? sizeof (CHAR16) : sizeof (CHAR8));
531 OriginalValue = Value;
532 } else {
534 }
535
536 Option = OcFlexArrayAddItem (*ParsedVars);
537 if (Option == NULL) {
538 OcFlexArrayFree (ParsedVars);
539 return EFI_OUT_OF_RESOURCES;
540 }
541
542 if (StringFormat == OcStringFormatUnicode) {
543 Option->Unicode.Name = Name;
544 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Name=\"%s\"\n", Name));
545 } else {
546 Option->Ascii.Name = Name;
547 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Name=\"%a\"\n", Name));
548 }
549
550 if (State == PARSE_VARS_WHITE_SPACE) {
551 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: No value %u\n", 1));
552 }
553
554 Name = NULL;
555 }
556
557 break;
558
560 if (Ch == '`') {
561 ASSERT (PushState != PARSE_VARS_WHITE_SPACE);
562 State = PushState;
563 }
564
565 break;
566
567 //
568 // In token value (but not name) we handle sh and grub quoting and string concatenation, e.g. 'abc\'"'\""def becomes abc\'"def.
569 //
570 case PARSE_VARS_VALUE:
572 if ((State != PARSE_VARS_QUOTED_VALUE) && ((Ch == L'\'') || (Ch == L'"'))) {
573 QuoteChar = Ch;
574 SHIFT_TOKEN (Pos, Value, (StringFormat == OcStringFormatUnicode) ? sizeof (CHAR16) : sizeof (CHAR8));
576 } else if ((State == PARSE_VARS_QUOTED_VALUE) && (Ch == QuoteChar)) {
577 SHIFT_TOKEN (Pos, Value, (StringFormat == OcStringFormatUnicode) ? sizeof (CHAR16) : sizeof (CHAR8));
578 QuoteChar = CHAR_NULL;
579 State = PARSE_VARS_VALUE;
580 } else if (((State != PARSE_VARS_QUOTED_VALUE) || (QuoteChar == L'"')) && (Ch == L'\\')) {
581 NewPos = (UINT8 *)Pos + ((StringFormat == OcStringFormatUnicode) ? sizeof (CHAR16) : sizeof (CHAR8));
582 NewCh = (StringFormat == OcStringFormatUnicode) ? *((CHAR16 *)Pos) : *((CHAR8 *)Pos);
583 //
584 // https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
585 //
586 if ((State != PARSE_VARS_QUOTED_VALUE) || (NewCh == '"') || (NewCh == '\\') || (NewCh == '$') || (NewCh == '`')) {
587 SHIFT_TOKEN (Pos, Value, (StringFormat == OcStringFormatUnicode) ? sizeof (CHAR16) : sizeof (CHAR8));
588 Pos = NewPos;
589 Ch = NewCh;
590 }
591 } else if (Ch == L'`') {
592 PushState = State;
594 } else if ((State == PARSE_VARS_VALUE) && OcIsSpaceOrNull (Ch)) {
595 //
596 // Explicitly quoted empty string (e.g. `var=""`) is stored detectably differently from missing value (i.e. `var=`, or just `var`).
597 //
598 if (Pos == OriginalValue) {
599 ASSERT (!TokensOnly);
600 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: No value %u\n", 2));
601 } else {
602 if (PushState != PARSE_VARS_WHITE_SPACE) {
603 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Found shell expansion, cancelling value\n"));
604 PushState = PARSE_VARS_WHITE_SPACE;
605 } else {
606 if (StringFormat == OcStringFormatUnicode) {
607 *((CHAR16 *)Pos) = CHAR_NULL;
608 Option->Unicode.Value = Value;
609 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Value=\"%s\"\n", Value));
610 } else {
611 *((CHAR8 *)Pos) = '\0';
612 Option->Ascii.Value = Value;
613 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Value=\"%a\"\n", Value));
614 }
615 }
616 }
617
618 Value = NULL;
619 OriginalValue = NULL;
620 Option = NULL;
622 }
623
624 break;
625
626 default:
627 ASSERT (FALSE);
628 break;
629 }
630
631 if (Retake) {
632 Retake = FALSE;
633 } else {
634 Pos = (UINT8 *)Pos + ((StringFormat == OcStringFormatUnicode) ? sizeof (CHAR16) : sizeof (CHAR8));
635 }
636 } while (Ch != CHAR_NULL);
637
638 if ((State != PARSE_VARS_WHITE_SPACE) || (PushState != PARSE_VARS_WHITE_SPACE)) {
639 //
640 // E.g. for GRUB config files this may potentially be caused by a file
641 // neither we nor the user directly controls, so better warn than error.
642 //
643 DEBUG ((DEBUG_WARN, "OCB: Invalid vars (%u)\n", State));
644 OcFlexArrayFree (ParsedVars);
645 return EFI_INVALID_PARAMETER;
646 }
647
648 if ((*ParsedVars)->Items == NULL) {
649 OcFlexArrayFree (ParsedVars);
650 return EFI_NOT_FOUND;
651 }
652
653 return EFI_SUCCESS;
654}
655
658 IN CONST OC_FLEX_ARRAY *ParsedVars,
659 IN CONST UINTN Index
660 )
661{
662 OC_PARSED_VAR *Option;
663
664 Option = OcFlexArrayItemAt (ParsedVars, Index);
665 return Option;
666}
667
668BOOLEAN
670 IN CONST OC_FLEX_ARRAY *ParsedVars,
671 IN CONST VOID *Name,
672 OUT VOID **Value,
673 IN CONST OC_STRING_FORMAT StringFormat
674 )
675{
676 UINTN Index;
677 OC_PARSED_VAR *Option;
678
679 ASSERT (Name != NULL);
680 ASSERT (Value != NULL);
681
682 if (ParsedVars == NULL) {
683 return FALSE;
684 }
685
686 ASSERT (ParsedVars->Items != NULL);
687
688 for (Index = 0; Index < ParsedVars->Count; ++Index) {
689 Option = OcFlexArrayItemAt (ParsedVars, Index);
690 if (StringFormat == OcStringFormatUnicode) {
691 ASSERT (Option->Unicode.Name != NULL);
692 if (StrCmp (Option->Unicode.Name, Name) == 0) {
693 *Value = Option->Unicode.Value;
694 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Using \"%s\"=\"%s\"\n", Name, *Value));
695 return TRUE;
696 }
697 } else {
698 ASSERT (Option->Ascii.Name != NULL);
699 if (AsciiStrCmp (Option->Ascii.Name, Name) == 0) {
700 *Value = Option->Ascii.Value;
701 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: Using \"%a\"=\"%a\"\n", Name, *Value));
702 return TRUE;
703 }
704 }
705 }
706
707 if (StringFormat == OcStringFormatUnicode) {
708 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: No value for \"%s\"\n", Name));
709 } else {
710 DEBUG ((OC_TRACE_PARSE_VARS, "OCB: No value for \"%a\"\n", Name));
711 }
712
713 return FALSE;
714}
715
716BOOLEAN
718 IN CONST OC_FLEX_ARRAY *ParsedVars,
719 IN CONST CHAR16 *Name,
720 OUT CHAR16 **Value
721 )
722{
723 return OcParsedVarsGetStr (ParsedVars, Name, (VOID **)Value, OcStringFormatUnicode);
724}
725
726BOOLEAN
728 IN CONST OC_FLEX_ARRAY *ParsedVars,
729 IN CONST CHAR8 *Name,
730 OUT CHAR8 **Value
731 )
732{
733 return OcParsedVarsGetStr (ParsedVars, Name, (VOID **)Value, OcStringFormatAscii);
734}
735
736BOOLEAN
738 IN CONST OC_FLEX_ARRAY *ParsedVars,
739 IN CONST VOID *Name,
740 IN CONST OC_STRING_FORMAT StringFormat
741 )
742{
743 VOID *Value;
744
745 return OcParsedVarsGetStr (ParsedVars, Name, &Value, StringFormat);
746}
747
748EFI_STATUS
750 IN CONST OC_FLEX_ARRAY *ParsedVars,
751 IN CONST VOID *Name,
752 OUT UINTN *Value,
753 IN CONST OC_STRING_FORMAT StringFormat
754 )
755{
756 EFI_STATUS Status;
757 VOID *StrValue;
758
759 if (!OcParsedVarsGetStr (ParsedVars, Name, &StrValue, StringFormat)) {
760 return EFI_NOT_FOUND;
761 }
762
763 if (StrValue == NULL) {
764 return EFI_NOT_FOUND;
765 }
766
767 if (StringFormat == OcStringFormatUnicode) {
768 if (OcUnicodeStartsWith (StrValue, L"0x", TRUE)) {
769 Status = StrHexToUintnS (StrValue, NULL, Value);
770 } else {
771 Status = StrDecimalToUintnS (StrValue, NULL, Value);
772 }
773 } else {
774 if (OcAsciiStartsWith (StrValue, "0x", TRUE)) {
775 Status = AsciiStrHexToUintnS (StrValue, NULL, Value);
776 } else {
777 Status = AsciiStrDecimalToUintnS (StrValue, NULL, Value);
778 }
779 }
780
781 return Status;
782}
783
784EFI_STATUS
786 IN CONST OC_FLEX_ARRAY *ParsedVars,
787 IN CONST VOID *Name,
788 OUT EFI_GUID *Value,
789 IN CONST OC_STRING_FORMAT StringFormat
790 )
791{
792 EFI_STATUS Status;
793 VOID *StrValue;
794
795 if (!OcParsedVarsGetStr (ParsedVars, Name, &StrValue, StringFormat)) {
796 return EFI_NOT_FOUND;
797 }
798
799 if (StrValue == NULL) {
800 return EFI_NOT_FOUND;
801 }
802
803 if (StringFormat == OcStringFormatUnicode) {
804 Status = StrToGuid (StrValue, Value);
805 } else {
806 Status = AsciiStrToGuid (StrValue, Value);
807 }
808
809 return Status;
810}
#define kBootArgsFlagCSRActiveConfig
#define BOOT_LINE_LENGTH
#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_STATE_
@ PARSE_VARS_WHITE_SPACE
@ PARSE_VARS_QUOTED_VALUE
@ PARSE_VARS_SHELL_EXPANSION
@ PARSE_VARS_COMMENT
@ PARSE_VARS_VALUE
@ PARSE_VARS_NAME
EFI_STATUS InternalRunRequestPrivilege(IN OC_PICKER_CONTEXT *PickerContext, IN OC_PRIVILEGE_LEVEL Level)
#define OC_TRACE_PARSE_VARS
#define MAX_LOAD_OPTIONS_SIZE
@ OcPrivilegeAuthorized
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)
Definition FlexArray.c:31
VOID * OcFlexArrayAddItem(IN OUT OC_FLEX_ARRAY *FlexArray)
Definition FlexArray.c:136
VOID * OcFlexArrayItemAt(IN CONST OC_FLEX_ARRAY *FlexArray, IN CONST UINTN Index)
Definition FlexArray.c:189
@ OcStringFormatUnicode
Definition OcStringLib.h:51
@ OcStringFormatAscii
Definition OcStringLib.h:50
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)
Definition OcAsciiLib.c:291
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
#define ASSERT(x)
Definition coder.h:55
#define Len
Definition deflate.h:82
ush Pos
Definition deflate.h:92
UINT32 MemoryMap
UINT16 Version
UINT32 efiSystemTable
CHAR8 CommandLine[BOOT_LINE_LENGTH]
UINT32 MemoryMapDescriptorVersion
UINT64 efiRuntimeServicesVirtualPageStart
UINT32 deviceTreeP
UINT32 MemoryMapDescriptorSize
UINT32 deviceTreeLength
UINT32 efiRuntimeServicesPageStart
UINT32 MemoryMapSize
UINT32 csrActiveConfig
UINT32 efiSystemTable
UINT32 deviceTreeLength
UINT32 MemoryMap
UINT32 MemoryMapSize
UINT32 deviceTreeP
UINT64 efiRuntimeServicesVirtualPageStart
UINT32 MemoryMapDescriptorSize
UINT32 efiRuntimeServicesPageStart
UINT32 MemoryMapDescriptorVersion
CHAR8 CommandLine[BOOT_LINE_LENGTH]
OC_PARSED_VAR_ASCII Ascii
OC_PARSED_VAR_UNICODE Unicode