11#include <Library/BaseLib.h>
12#include <Library/DevicePathLib.h>
13#include <Library/MemoryAllocationLib.h>
19#include <Library/PrintLib.h>
20#include <Library/SortLib.h>
21#include <Library/UefiBootServicesTableLib.h>
43#define BOOT_DIR L"\\boot"
47#define OSTREE_DIR L"\\ostree"
53#define LOADER_ENTRIES_DIR L"loader\\entries"
54#define GRUB2_GRUB_CFG L"grub2\\grub.cfg"
55#define GRUB2_GRUBENV L"grub2\\grubenv"
56#define GRUB2_GRUBENV_SIZE SIZE_1KB
58#define BLSPEC_SUFFIX_CONF L".conf"
59#define BLSPEC_PREFIX_AUTO L"auto-"
68#define MAX_LOADER_ENTRY_NAME_LEN (127)
69#define MAX_LOADER_ENTRY_FILE_INFO_SIZE ( \
70 SIZE_OF_EFI_FILE_INFO + \
71 (MAX_LOADER_ENTRY_NAME_LEN + L_STR_LEN (BLSPEC_SUFFIX_CONF) + 1) * sizeof (CHAR16) \
78#define MAX_LOADER_ENTRY_FILE_SIZE SIZE_4KB
164 IN CONST CHAR16 *FileName,
165 IN OUT CHAR8 *Content,
184 if (!((Ch ==
'\0') || (Ch ==
'\t') || (Ch ==
'\n') || ((Ch >= 20) && (Ch < 128)))) {
185 DEBUG ((DEBUG_WARN,
"LNX: Invalid char 0x%x in %s\n", Ch, FileName));
186 return EFI_INVALID_PARAMETER;
191 if ((Ch ==
'\n') || (Ch ==
'\0')) {
195 }
else if ((Ch ==
' ') || (Ch ==
'\t')) {
196 }
else if (Ch ==
'#') {
199 *Key = &Content[*
Pos];
213 if ((Ch ==
'\n') || (Ch ==
'\0')) {
217 }
else if ((Ch ==
' ') || (Ch ==
'\t')) {
218 Content[*
Pos] =
'\0';
225 if ((Ch ==
'\n') || (Ch ==
'\0')) {
229 }
else if ((Ch ==
' ') || (Ch ==
'\t')) {
231 *Value = &Content[*
Pos];
239 if ((Ch ==
'\n') || (Ch ==
'\0')) {
240 if (LastSpace != NULL) {
243 Content[*
Pos] =
'\0';
247 }
else if ((Ch ==
' ') || (Ch ==
'\t')) {
248 LastSpace = &Content[*
Pos];
257 return EFI_INVALID_PARAMETER;
263 }
while (Ch !=
'\0' && !IsComplete);
266 return EFI_NOT_FOUND;
312 FreePool (Entry->
Title);
320 FreePool (Entry->
Linux);
325 if (Entry->
OcId != NULL) {
326 FreePool (Entry->
OcId);
337 IN CONST BOOLEAN Grub2,
338 IN OUT CHAR8 **Target,
339 IN CONST CHAR8 *Value
342 if (!Grub2 || (*Target == NULL)) {
343 if (*Target != NULL) {
347 *Target = AllocateCopyPool (AsciiStrSize (Value), Value);
348 if (*Target == NULL) {
349 return EFI_OUT_OF_RESOURCES;
359 IN CONST BOOLEAN Grub2,
361 IN CONST CHAR8 *Value
366 if (Grub2 && (Array->Items != NULL)) {
371 if (NewItem == NULL) {
372 return EFI_OUT_OF_RESOURCES;
375 *NewItem = AllocateCopyPool (AsciiStrSize (Value), Value);
376 if (*NewItem == NULL) {
377 return EFI_OUT_OF_RESOURCES;
385 IN CONST CHAR16 *FileName,
386 IN OUT CHAR8 *Content,
388 IN CONST BOOLEAN Grub2
398 Status = EFI_SUCCESS;
411 if (Status == EFI_NOT_FOUND) {
415 if (EFI_ERROR (Status)) {
419 if (AsciiStrCmp (Key,
"title") == 0) {
421 }
else if (AsciiStrCmp (Key,
"version") == 0) {
423 }
else if (AsciiStrCmp (Key,
"linux") == 0) {
425 }
else if (AsciiStrCmp (Key,
"options") == 0) {
427 }
else if (AsciiStrCmp (Key,
"initrd") == 0) {
431 if (EFI_ERROR (Status)) {
450 if (Entry->Options->Count > 0) {
452 if (EFI_ERROR (Status)) {
460 if (DefaultOptionsVar != NULL) {
461 if (DefaultOptionsVar->
Errors != 0) {
462 DEBUG ((DEBUG_WARN,
"LNX: Unusable grub var $%a - 0x%x\n",
"default_kernelopts", DefaultOptionsVar->
Errors));
463 return EFI_INVALID_PARAMETER;
466 DEBUG ((DEBUG_INFO,
"LNX: Using $%a\n",
"default_kernelopts"));
473 if (EFI_ERROR (Status)) {
478 if (Options == NULL) {
479 FreePool (NewOptions);
480 return EFI_OUT_OF_RESOURCES;
483 *Options = NewOptions;
505 UINTN SplitInitrdsIndex;
507 if (Entry->Initrds->Count == 0) {
512 if (EFI_ERROR (Status)) {
518 for (OptionsIndex = 0; OptionsIndex < Entry->Initrds->Count; OptionsIndex++) {
522 if (EFI_ERROR (Status)) {
526 for (SplitInitrdsIndex = 0; SplitInitrdsIndex < SplitInitrds->
Count; SplitInitrdsIndex++) {
528 if (EFI_ERROR (Status)) {
534 if (EFI_ERROR (Status)) {
539 if (EFI_ERROR (Status)) {
544 ASSERT (ExpandedInitrds->
Count >= Entry->Initrds->Count);
547 Entry->Initrds = ExpandedInitrds;
555 EFI_FILE_HANDLE Directory,
556 EFI_FILE_INFO *FileInfo,
558 VOID *Context OPTIONAL
561 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
562 return EFI_NOT_FOUND;
569 if ((FileInfo->FileName[0] == L
'.') ||
572 return EFI_NOT_FOUND;
576 return EFI_NOT_FOUND;
603 CHAR16 *VersionStart;
609 ASSERT (FileName != NULL);
615 VersionEnd = &FileName[StrLen (FileName)];
623 if ((Split != NULL) && ((Split == FileName) || (VersionEnd == Split + 1))) {
628 VersionStart = FileName;
631 VersionStart = Split + 1;
640 OcId = AllocatePool (IdEnd - FileName + 1);
642 return EFI_OUT_OF_RESOURCES;
645 Status = UnicodeStrnToAsciiStrS (FileName, IdEnd - FileName, OcId, IdEnd - FileName + 1, &NumCopied);
646 ASSERT_EFI_ERROR (Status);
647 ASSERT (NumCopied == (UINTN)(IdEnd - FileName));
651 if (Entry->Version == NULL) {
652 Version = AllocatePool (VersionEnd - VersionStart + 1);
654 return EFI_OUT_OF_RESOURCES;
657 Status = UnicodeStrnToAsciiStrS (VersionStart, VersionEnd - VersionStart,
Version, VersionEnd - VersionStart + 1, &NumCopied);
658 ASSERT_EFI_ERROR (Status);
659 ASSERT (NumCopied == (UINTN)(VersionEnd - VersionStart));
679 IN CONST EFI_FILE_HANDLE Directory,
680 IN CONST CHAR16 *DirName,
681 IN OUT CHAR8 **FileName
685 EFI_FILE_PROTOCOL *File;
692 ASSERT (FileName != NULL);
693 ASSERT (*FileName != NULL);
695 FileNameLen = AsciiStrLen (*FileName);
696 DirNameLen = StrLen (DirName);
698 MaxPathSize = (DirNameLen + FileNameLen + 1) *
sizeof (CHAR16);
700 Path = AllocatePool (MaxPathSize);
702 return EFI_OUT_OF_RESOURCES;
705 UnicodeSPrintAsciiFormat (Path, MaxPathSize,
"%a", *FileName);
708 Status =
OcSafeFileOpen (Directory, &File, Path, EFI_FILE_MODE_READ, 0);
709 if (!EFI_ERROR (Status)) {
715 if (DirNameLen <= 1) {
716 DEBUG ((DEBUG_WARN,
"LNX: %a not found - %r\n", *FileName, Status));
721 UnicodeSPrintAsciiFormat (Path, MaxPathSize,
"%s%a", DirName, *FileName);
724 Status =
OcSafeFileOpen (Directory, &File, Path, EFI_FILE_MODE_READ, 0);
725 if (!EFI_ERROR (Status)) {
730 AsciiSPrint ((CHAR8 *)Path, MaxPathSize,
"%s%a", DirName, *FileName);
732 FreePool (*FileName);
733 *FileName = (CHAR8 *)Path;
737 DEBUG ((DEBUG_WARN,
"LNX: %a not found (searched %s and %s) - %r\n", *FileName,
ROOT_DIR, DirName, Status));
760 for (Index = 0; Index < Options->Count; Index++) {
765 OptionCopy = AllocateCopyPool (AsciiStrSize (*Option), *Option);
766 if (OptionCopy == NULL) {
771 if (EFI_ERROR (Status)) {
772 DEBUG ((DEBUG_WARN,
"LNX: Error parsing Options[%u]=<%a> - %r\n", Index, *Option, Status));
773 FreePool (OptionCopy);
779 FreePool (ParsedVars);
780 FreePool (OptionCopy);
793 EFI_FILE_HANDLE Directory
797 EFI_FILE_PROTOCOL *OstreeFile;
800 if (EFI_ERROR (Status)) {
805 if (EFI_ERROR (Status)) {
806 DEBUG ((DEBUG_WARN,
"LNX: %s found but not a %a - %r\n",
OSTREE_DIR,
"directory", Status));
809 OstreeFile->Close (OstreeFile);
811 return !EFI_ERROR (Status);
817 EFI_FILE_HANDLE Directory,
818 EFI_FILE_INFO *FileInfo,
820 VOID *Context OPTIONAL
837 DEBUG ((DEBUG_WARN,
"LNX: Entry filename overlong: %s...\n", FileInfo->FileName));
839 return EFI_NOT_FOUND;
843 DEBUG ((DEBUG_WARN,
"LNX: Entry file size overlong: %s\n", FileInfo->FileName));
844 return EFI_NOT_FOUND;
849 "LNX: Reading %s...\n",
854 if (Content == NULL) {
855 return EFI_OUT_OF_RESOURCES;
860 return EFI_OUT_OF_RESOURCES;
864 if (EFI_ERROR (Status)) {
869 if (Entry->
Linux == NULL) {
872 "LNX: No linux line, ignoring\n"
875 return EFI_NOT_FOUND;
880 if (!EFI_ERROR (Status)) {
884 if (EFI_ERROR (Status)) {
894 if (!EFI_ERROR (Status)) {
895 for (Index = 0; Index < Entry->
Initrds->
Count; Index++) {
898 if (EFI_ERROR (Status)) {
904 if (EFI_ERROR (Status)) {
917 DEBUG ((DEBUG_WARN,
"LNX: Missing root option, %s %afound - %afixing\n",
OSTREE_DIR,
"not ",
"not "));
919 DEBUG ((DEBUG_INFO,
"LNX: Missing root option, %s %afound - %afixing\n",
OSTREE_DIR,
"",
""));
921 if (EFI_ERROR (Status)) {
932 if (EFI_ERROR (Status)) {
943 EFI_FILE_HANDLE Directory,
944 EFI_FILE_INFO *FileInfo,
946 VOID *Context OPTIONAL
952 if (EFI_ERROR (Status)) {
957 if (EFI_ERROR (Status)) {
958 DEBUG ((DEBUG_WARN,
"LNX: Error processing %s - %r\n", FileInfo->FileName, Status));
964 return EFI_NOT_FOUND;
981 Status = EFI_SUCCESS;
985 if (EFI_ERROR (Status)) {
997 IN EFI_FILE_PROTOCOL *RootDirectory,
1000 OUT UINTN *NumEntries
1004 EFI_FILE_PROTOCOL *EntriesDirectory;
1010 if (EFI_ERROR (Status)) {
1014 Status = EFI_SUCCESS;
1023 if (GrubCfg == NULL) {
1028 if (!EFI_ERROR (Status)) {
1033 if (GrubEnv == NULL) {
1038 "LNX: Reading %s\n",
1044 if (!EFI_ERROR (Status)) {
1047 "LNX: Reading %s\n",
1053 if ( !EFI_ERROR (Status)
1058 "LNX: Fix TuneD vars\n"
1070 if (!EFI_ERROR (Status)) {
1073 if ((EarlyInitrdVar != NULL) &&
1074 (EarlyInitrdVar->
Value != NULL) &&
1075 (EarlyInitrdVar->
Value[0] !=
'\0')
1078 DEBUG ((DEBUG_INFO,
"LNX: grub var $%a is present but currently unsupported - aborting\n",
"early_initrd"));
1079 Status = EFI_INVALID_PARAMETER;
1084 if (!EFI_ERROR (Status)) {
1087 Status = EFI_OUT_OF_RESOURCES;
1092 if (!EFI_ERROR (Status)) {
1107 if (GrubEnv != NULL) {
1111 if (GrubCfg != NULL) {
1115 EntriesDirectory->Close (EntriesDirectory);
1123 IN EFI_FILE_PROTOCOL *Directory,
1126 OUT UINTN *NumEntries
1134 (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) ? DEBUG_WARN : DEBUG_INFO,
1135 "LNX: ScanLoaderEntries %s - %r\n",
1145 IN EFI_FILE_PROTOCOL *RootDirectory,
1147 OUT UINTN *NumEntries
1151 EFI_FILE_PROTOCOL *AdditionalScanDirectory;
1154 if (EFI_ERROR (Status)) {
1156 if (!EFI_ERROR (Status)) {
1158 AdditionalScanDirectory->Close (AdditionalScanDirectory);
1169 OUT UINTN *NumEntries
1180 UINTN OptionsLength;
1182 StringBuffer = NULL;
1185 if (PickerEntries == NULL) {
1186 return EFI_OUT_OF_RESOURCES;
1189 Status = EFI_SUCCESS;
1194 if (PickerEntry == NULL) {
1195 Status = EFI_OUT_OF_RESOURCES;
1199 PickerEntry->
Path = AllocateCopyPool (AsciiStrSize (Entry->
Linux), Entry->
Linux);
1200 if (PickerEntry->
Path == NULL) {
1201 Status = EFI_OUT_OF_RESOURCES;
1209 if (StringBuffer == NULL) {
1210 Status = EFI_OUT_OF_RESOURCES;
1214 for (OptionsIndex = 0; OptionsIndex < Entry->
Initrds->
Count; OptionsIndex++) {
1217 if (EFI_ERROR (Status)) {
1222 if (EFI_ERROR (Status)) {
1227 if (EFI_ERROR (Status)) {
1232 if (EFI_ERROR (Status)) {
1236 for (OptionsIndex = 0; OptionsIndex < Entry->
Options->
Count; OptionsIndex++) {
1238 OptionsLength = AsciiStrLen (*Options);
1239 ASSERT (OptionsLength != 0);
1240 if (OptionsLength == 0) {
1244 if ((*Options)[OptionsLength - 1] ==
' ') {
1249 if (EFI_ERROR (Status)) {
1253 if (OptionsIndex < Entry->Options->Count - 1) {
1255 if (EFI_ERROR (Status)) {
1261 if (EFI_ERROR (Status)) {
1271 if (StringBuffer == NULL) {
1272 Status = EFI_OUT_OF_RESOURCES;
1281 if (EFI_ERROR (Status)) {
1288 if (EFI_ERROR (Status)) {
1294 if (EFI_ERROR (Status)) {
1302 if (PickerEntry->
Flavour == NULL) {
1303 Status = EFI_OUT_OF_RESOURCES;
1308 PickerEntry->
Id = AllocateCopyPool (AsciiStrSize (Entry->
OcId), Entry->
OcId);
1309 if (PickerEntry->
Id == NULL) {
1310 Status = EFI_OUT_OF_RESOURCES;
1318 PickerEntry->
Tool = FALSE;
1321 if (EFI_ERROR (Status)) {
1322 if (StringBuffer != NULL) {
1328 ASSERT (StringBuffer == NULL);
1354 if (!EFI_ERROR (Status)) {
1355 FreePool (Entry->
Title);
1380 if (EFI_ERROR (Status)) {
1418 if (AsciiStrCmp (Entry->
OcId, MatchEntry->
OcId) == 0) {
1435 IN EFI_FILE_PROTOCOL *RootDirectory,
1445 if (Entry->Title != NULL) {
1449 ASSERT (Entry->OcFlavour == NULL);
1451 if (Variant != NULL) {
1454 Entry->OcFlavour = AllocatePool (
Length + 1);
1455 if (Entry->OcFlavour == NULL) {
1456 return EFI_OUT_OF_RESOURCES;
1459 NumPrinted = AsciiSPrint (Entry->OcFlavour,
Length + 1,
"%a:%a", Variant,
"Linux");
1463 Entry->OcFlavour = AllocateCopyPool (AsciiStrSize (Variant), Variant);
1464 if (Entry->OcFlavour == NULL) {
1465 return EFI_OUT_OF_RESOURCES;
1469 if (Entry->Title == NULL) {
1470 Entry->Title = AllocateCopyPool (AsciiStrSize (Variant), Variant);
1471 if (Entry->Title == NULL) {
1472 return EFI_OUT_OF_RESOURCES;
1482 IN EFI_FILE_PROTOCOL *RootDirectory
1489 Status = EFI_SUCCESS;
1495 if (EFI_ERROR (Status)) {
1508 IN EFI_FILE_PROTOCOL *RootDirectory,
1510 OUT UINTN *NumEntries
1515 Status = EFI_SUCCESS;
1533 if (!EFI_ERROR (Status)) {
1540 if (!EFI_ERROR (Status)) {
1544 if (!EFI_ERROR (Status)) {
#define ARRAY_SIZE(Array)
EFI_STATUS InsertRootOption(IN OC_FLEX_ARRAY *Options)
EFI_STATUS InternalProcessGrubCfg(IN OUT CHAR8 *Content)
EFI_STATUS InternalProcessGrubEnv(IN OUT CHAR8 *Content, IN CONST UINTN Length)
EFI_STATUS InternalInitGrubVars(VOID)
EFI_STATUS InternalSetGrubVar(CHAR8 *Key, CHAR8 *Value, UINTN Errors)
VOID InternalFreeGrubVars(VOID)
EFI_STATUS InternalExpandGrubVars(IN CONST CHAR8 *Value, IN OUT CHAR8 **Result)
GRUB_VAR * InternalGetGrubVar(IN CONST CHAR8 *Key)
EFI_STATUS InternalExpandGrubVarsForArray(IN OUT OC_FLEX_ARRAY *Options)
#define LINUX_BOOT_ALLOW_CONF_AUTO_ROOT
OC_FLEX_ARRAY * gLoaderEntries
VOID InternalFreePickerEntry(IN OC_PICKER_ENTRY *Entry)
#define LINUX_BOOT_FIX_TUNED
#define LINUX_BOOT_ADD_DEBUG_INFO
#define LINUX_BOOT_USE_LATEST
INTN EFIAPI InternalReverseVersionCompare(IN CONST VOID *Version1, IN CONST VOID *Version2)
OC_PICKER_CONTEXT * gPickerContext
#define LINUX_BOOT_LOG_VERBOSE
enum ENTRY_PARSE_STATE_ ENTRY_PARSE_STATE
STATIC BOOLEAN HasOstreeDir(EFI_FILE_HANDLE Directory)
STATIC CHAR8 * mLinuxVariants[]
STATIC EFI_STATUS DoProcessLoaderEntry(EFI_FILE_HANDLE Directory, EFI_FILE_INFO *FileInfo, UINTN FileInfoSize, VOID *Context OPTIONAL)
#define LOADER_ENTRIES_DIR
STATIC EFI_STATUS ProcessLoaderEntry(EFI_FILE_HANDLE Directory, EFI_FILE_INFO *FileInfo, UINTN FileInfoSize, VOID *Context OPTIONAL)
EFI_STATUS InternalScanLoaderEntries(IN EFI_FILE_PROTOCOL *RootDirectory, OUT OC_PICKER_ENTRY **Entries, OUT UINTN *NumEntries)
STATIC EFI_STATUS DoConvertLoaderEntriesToBootEntries(OUT OC_PICKER_ENTRY **Entries, OUT UINTN *NumEntries)
STATIC EFI_STATUS AppendVersions(VOID)
STATIC EFI_STATUS ApplyDefaults(IN EFI_FILE_PROTOCOL *RootDirectory)
STATIC EFI_STATUS ExpandInitrds(IN OUT LOADER_ENTRY *Entry)
STATIC EFI_STATUS ExpandReplaceOptions(IN OUT LOADER_ENTRY *Entry)
EFI_STATUS InternalConvertLoaderEntriesToBootEntries(IN EFI_FILE_PROTOCOL *RootDirectory, OUT OC_PICKER_ENTRY **Entries, OUT UINTN *NumEntries)
STATIC EFI_STATUS DoScanLoaderEntries(IN EFI_FILE_PROTOCOL *Directory, IN CHAR16 *DirName, OUT OC_PICKER_ENTRY **Entries, OUT UINTN *NumEntries)
VOID InternalFreeLoaderEntry(LOADER_ENTRY *Entry)
#define MAX_LOADER_ENTRY_NAME_LEN
#define MAX_LOADER_ENTRY_FILE_INFO_SIZE
#define BLSPEC_PREFIX_AUTO
STATIC EFI_STATUS EntryApplyDefaults(IN EFI_FILE_PROTOCOL *RootDirectory, IN LOADER_ENTRY *Entry)
STATIC EFI_STATUS FindLoaderFile(IN CONST EFI_FILE_HANDLE Directory, IN CONST CHAR16 *DirName, IN OUT CHAR8 **FileName)
STATIC EFI_STATUS DisambiguateDuplicates(VOID)
STATIC EFI_STATUS ScanLoaderEntriesAtDirectory(IN EFI_FILE_PROTOCOL *RootDirectory, IN CHAR16 *DirName, OUT OC_PICKER_ENTRY **Entries, OUT UINTN *NumEntries)
#define MAX_LOADER_ENTRY_FILE_SIZE
STATIC BOOLEAN HasRootOption(IN OC_FLEX_ARRAY *Options)
STATIC EFI_STATUS FixTuneDVars(VOID)
STATIC EFI_STATUS EntryCopyMultipleValue(IN CONST BOOLEAN Grub2, IN OC_FLEX_ARRAY *Array, IN CONST CHAR8 *Value)
STATIC EFI_STATUS AppendVersion(LOADER_ENTRY *Entry)
#define GRUB2_GRUBENV_SIZE
LOADER_ENTRY * InternalAllocateLoaderEntry(VOID)
STATIC EFI_STATUS GetLoaderEntryLine(IN CONST CHAR16 *FileName, IN OUT CHAR8 *Content, IN OUT UINTN *Pos, OUT CHAR8 **Key, OUT CHAR8 **Value)
STATIC CHAR8 * ExtractVariantFrom(IN CHAR8 *String)
#define BLSPEC_SUFFIX_CONF
EFI_STATUS InternalIdVersionFromFileName(IN OUT LOADER_ENTRY *Entry, IN CHAR16 *FileName)
STATIC EFI_STATUS EntryCopySingleValue(IN CONST BOOLEAN Grub2, IN OUT CHAR8 **Target, IN CONST CHAR8 *Value)
STATIC EFI_STATUS DoFilterLoaderEntry(EFI_FILE_HANDLE Directory, EFI_FILE_INFO *FileInfo, UINTN FileInfoSize, VOID *Context OPTIONAL)
STATIC CHAR8 * mTuneDVars[]
EFI_STATUS InternalProcessLoaderEntryFile(IN CONST CHAR16 *FileName, IN OUT CHAR8 *Content, OUT LOADER_ENTRY *Entry, IN CONST BOOLEAN Grub2)
STATIC_ASSERT(BYTES_PER_PIXEL==sizeof(UINT32), "Non 4-byte pixels are unsupported!")
OC_PARSED_VAR * OcParsedVarsItemAt(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST UINTN Index)
BOOLEAN OcHasParsedVar(IN CONST OC_FLEX_ARRAY *ParsedVars, IN CONST VOID *Name, IN CONST OC_STRING_FORMAT StringFormat)
EFI_STATUS OcParseVars(IN VOID *StrVars, OUT OC_FLEX_ARRAY **ParsedVars, IN CONST OC_STRING_FORMAT StringFormat, IN CONST BOOLEAN TokensOnly)
EFI_STATUS OcEnsureDirectoryFile(IN EFI_FILE_PROTOCOL *File, IN BOOLEAN IsDirectory)
VOID * OcReadFileFromDirectory(IN CONST EFI_FILE_PROTOCOL *RootDirectory, IN CONST CHAR16 *FilePath, OUT UINT32 *FileSize OPTIONAL, IN UINT32 MaxFileSize OPTIONAL)
EFI_STATUS OcScanDirectory(IN EFI_FILE_HANDLE Directory, IN OC_PROCESS_DIRECTORY_ENTRY ProcessEntry, IN OUT VOID *Context OPTIONAL)
EFI_STATUS OcSafeFileOpen(IN CONST EFI_FILE_PROTOCOL *Directory, OUT EFI_FILE_PROTOCOL **NewHandle, IN CONST CHAR16 *FileName, IN CONST UINT64 OpenMode, IN CONST UINT64 Attributes)
VOID OcFlexArrayFree(IN OUT OC_FLEX_ARRAY **FlexArray)
CHAR8 * OcAsciiStringBufferFreeContainer(IN OUT OC_ASCII_STRING_BUFFER **StringBuffer)
OC_FLEX_ARRAY * OcFlexArrayInit(IN CONST UINTN ItemSize, IN CONST OC_FLEX_ARRAY_FREE_ITEM FreeItem OPTIONAL)
VOID(* OC_FLEX_ARRAY_FREE_ITEM)(IN VOID *Item)
EFI_STATUS OcAsciiStringBufferAppendN(IN OUT OC_ASCII_STRING_BUFFER *Buffer, IN CONST CHAR8 *AppendString, OPTIONAL IN CONST UINTN Length)
VOID OcFlexArrayFreePointerItem(IN VOID *Item)
VOID OcFlexArrayFreeContainer(IN OUT OC_FLEX_ARRAY **FlexArray, IN OUT VOID **Items, IN OUT UINTN *Count)
VOID * OcFlexArrayAddItem(IN OUT OC_FLEX_ARRAY *FlexArray)
EFI_STATUS OcAsciiStringBufferAppend(IN OUT OC_ASCII_STRING_BUFFER *Buffer, IN CONST CHAR8 *AppendString OPTIONAL)
VOID * OcFlexArrayItemAt(IN CONST OC_FLEX_ARRAY *FlexArray, IN CONST UINTN Index)
VOID OcFlexArrayDiscardItem(IN OUT OC_FLEX_ARRAY *FlexArray, IN CONST BOOLEAN FreeItem)
EFI_STATUS EFIAPI OcAsciiStringBufferSPrint(IN OUT OC_ASCII_STRING_BUFFER *Buffer, IN CONST CHAR8 *FormatString,...)
OC_ASCII_STRING_BUFFER * OcAsciiStringBufferInit(VOID)
VOID OcAsciiStringBufferFree(IN OUT OC_ASCII_STRING_BUFFER **StringBuffer)
CHAR8 * OcAsciiToLower(CHAR8 *Str)
CHAR16 *EFIAPI OcStrChr(IN CONST CHAR16 *String, IN CHAR16 Char)
VOID AsciiUnixSlashes(IN OUT CHAR8 *String)
#define L_STR_LEN(String)
VOID UnicodeUefiSlashes(IN OUT CHAR16 *String)
CHAR8 *EFIAPI OcAsciiStriStr(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString)
BOOLEAN EFIAPI OcUnicodeEndsWith(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
BOOLEAN DuplicateIdScanned