21#include <Library/BaseLib.h>
22#include <Library/BaseMemoryLib.h>
24#include <Library/DevicePathLib.h>
25#include <Library/MemoryAllocationLib.h>
30#include <Library/PrintLib.h>
31#include <Library/UefiBootServicesTableLib.h>
35 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
36 IN CONST CHAR16 *DirectoryName,
37 IN CONST CHAR16 *Filename,
38 IN UINT32 MaxFileSize,
39 IN UINT32 MinFileSize,
41 OUT UINT32 *DataSize OPTIONAL
49 Result = BaseOverflowAddUN (
50 StrSize (DirectoryName),
51 StrSize (Filename) -
sizeof (CHAR16),
55 return EFI_OUT_OF_RESOURCES;
58 FilePath = AllocatePool (FilePathSize);
61 return EFI_OUT_OF_RESOURCES;
64 UnicodeSPrint (
FilePath, FilePathSize, L
"%s%s", DirectoryName, Filename);
69 if (*FileData == NULL) {
73 if (FileReadSize < MinFileSize) {
75 return EFI_UNSUPPORTED;
78 if (DataSize != NULL) {
79 *DataSize = FileReadSize;
87 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
88 IN CONST CHAR16 *BootDirectoryName,
89 IN CONST CHAR16 *LabelFilename
93 CHAR8 *AsciiDiskLabel;
94 CHAR16 *UnicodeDiskLabel;
95 UINT32 DiskLabelLength;
103 (VOID **)&AsciiDiskLabel,
107 if (EFI_ERROR (Status)) {
112 if (UnicodeDiskLabel != NULL) {
116 FreePool (AsciiDiskLabel);
118 return UnicodeDiskLabel;
123 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
124 IN CONST CHAR16 *BootDirectoryName
128 CHAR8 *AsciiContentFlavour;
136 (VOID **)&AsciiContentFlavour,
140 if (EFI_ERROR (Status)) {
146 return AsciiContentFlavour;
152 IN CHAR8 *SystemVersionData,
153 IN UINT32 SystemVersionDataSize,
154 OUT CHAR8 *AppleVersion
162 CONST CHAR8 *CurrentKey;
166 Document =
XmlDocumentParse (SystemVersionData, SystemVersionDataSize, FALSE);
168 if (Document == NULL) {
169 return EFI_NOT_FOUND;
174 if (RootDict == NULL) {
176 return EFI_NOT_FOUND;
179 Status = EFI_NOT_FOUND;
182 for (Index = 0; Index < DictSize; Index++) {
185 if ((CurrentKey == NULL) || (AsciiStrCmp (CurrentKey,
"ProductUserVisibleVersion") != 0)) {
193 Status = EFI_UNSUPPORTED;
195 Status = EFI_SUCCESS;
213 CHAR16 *RecoveryName;
214 UINTN RecoveryNameSize;
219 RecoveryNameSize =
L_STR_SIZE (L
"Recovery ") + AsciiStrLen (
Version) *
sizeof (CHAR16);
220 RecoveryName = AllocatePool (RecoveryNameSize);
221 if (RecoveryName != NULL) {
222 UnicodeSPrint (RecoveryName, RecoveryNameSize, L
"Recovery %a",
Version);
233 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
234 IN CONST CHAR16 *DirectoryName,
235 OUT CHAR8 *AppleVersion
239 CHAR8 *SystemVersionData;
240 UINT32 SystemVersionDataSize;
245 L
"SystemVersion.plist",
248 (VOID **)&SystemVersionData,
249 &SystemVersionDataSize
252 if (EFI_ERROR (Status)) {
253 return EFI_NOT_FOUND;
257 FreePool (SystemVersionData);
264 IN EFI_HANDLE Device,
265 OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath,
270 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
271 EFI_FILE_PROTOCOL *Root;
272 EFI_FILE_PROTOCOL *Recovery;
274 EFI_DEVICE_PATH_PROTOCOL *TmpPath;
276 CHAR16 *DevicePathText;
278 Status =
gBS->HandleProtocol (
283 if (EFI_ERROR (Status)) {
287 Status = FileSystem->OpenVolume (FileSystem, &Root);
288 if (EFI_ERROR (Status)) {
298 sizeof (EFI_DEVICE_PATH_PROTOCOL),
310 if (IsDevicePathValid (*
FilePath, FilePathSize)) {
319 sizeof (EFI_DEVICE_PATH_PROTOCOL),
323 if (TmpPath != NULL) {
324 if ( IsDevicePathValid (TmpPath, TmpPathSize)
327 DEBUG ((DEBUG_INFO,
"Skipping equal alternate device path %p\n", Device));
328 Status = EFI_ALREADY_STARTED;
336 if (!EFI_ERROR (Status)) {
343 if (TmpPath != NULL) {
351 Status = EFI_NOT_FOUND;
361 Status =
OcSafeFileOpen (Root, &Recovery, L
"\\com.apple.recovery.boot", EFI_FILE_MODE_READ, 0);
362 if (!EFI_ERROR (Status)) {
366 Root->Close (Recovery);
367 Status = EFI_NOT_FOUND;
370 if (TmpPath != NULL) {
374 DevicePathText = ConvertDevicePathToText (*
FilePath, FALSE, FALSE);
375 if (DevicePathText != NULL) {
376 DEBUG ((DEBUG_INFO,
"OCB: Got recovery dp %s\n", DevicePathText));
377 FreePool (DevicePathText);
381 Status = EFI_SUCCESS;
385 Status = EFI_NOT_FOUND;
400 OUT VOID **ImageData,
401 OUT UINT32 *DataLength
404 ASSERT (DataLength != NULL);
407 Scale == 2 ? L
".disk_label_2x" : L
".disk_label",
423 OUT VOID **ImageData,
424 OUT UINT32 *DataLength
427 ASSERT (DataLength != NULL);
444 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
445 IN CONST CHAR16 *FileName,
446 IN CONST CHAR16 *DebugBootEntryName,
447 IN CONST CHAR8 *DebugFileType,
448 IN UINT32 MaxFileSize,
449 IN UINT32 MinFileSize,
451 OUT UINT32 *DataLength OPTIONAL,
452 IN BOOLEAN SearchAtLeaf,
453 IN BOOLEAN SearchAtRoot
457 CHAR16 *BootDirectoryName;
459 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
461 ASSERT (SearchAtLeaf || SearchAtRoot);
462 ASSERT (DevicePath != NULL);
463 ASSERT (FileData != NULL);
466 if (DataLength != NULL) {
476 if (EFI_ERROR (Status)) {
480 Status = EFI_NOT_FOUND;
494 if (!EFI_ERROR (Status) || !SearchAtRoot) {
497 "OCB: Get %a for %s - %r\n",
503 FreePool (BootDirectoryName);
508 GuidPrefix = BootDirectoryName[0] ==
'\\' ? &BootDirectoryName[1] : &BootDirectoryName[0];
510 GuidPrefix[GUID_STRING_LENGTH+1] =
'\0';
519 if (GuidPrefix != NULL) {
530 Status = EFI_UNSUPPORTED;
537 if (EFI_ERROR (Status)) {
551 "OCB: Get %a for %s %s - %r\n",
558 FreePool (BootDirectoryName);
566 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
567 IN CONST CHAR16 *FileName,
568 IN CONST CHAR8 *DebugFileType,
569 IN UINT32 MaxFileSize,
570 IN UINT32 MinFileSize,
572 OUT UINT32 *DataLength OPTIONAL,
573 IN BOOLEAN SearchAtLeaf,
574 IN BOOLEAN SearchAtRoot
595 IN CONST CHAR16 *FileName,
596 IN CONST CHAR8 *DebugFileType,
597 IN UINT32 MaxFileSize,
598 IN UINT32 MinFileSize,
600 OUT UINT32 *DataLength OPTIONAL,
601 IN BOOLEAN SearchAtLeaf,
602 IN BOOLEAN SearchAtRoot
606 return EFI_NOT_FOUND;
610 BootEntry->DevicePath,
646 VersionLength = AsciiStrLen (
Version);
647 FlavourLength = AsciiStrLen (Flavour);
649 for (Index = 0; Index < FlavourLength; Index++) {
650 if (Flavour[Index] ==
':') {
655 Size = 2 * (FlavourLength + 1) + VersionLength * (SepCount + 1);
661 NewFlavour = AllocatePool (
Size);
662 if (NewFlavour == NULL) {
675 Pos += VersionLength;
680 }
while (*
End !=
'\0');
698 CHAR16 *BootDirectoryName;
701 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
702 CHAR8 *ContentFlavour;
706 AppleVersion[0] =
'\0';
716 BootEntry->DevicePath,
721 if (EFI_ERROR (Status)) {
729 if (BootEntry->Name == NULL) {
752 DEBUG ((DEBUG_INFO,
"OCB: Trying to detect Microsoft BCD\n"));
753 Status =
OcReadFileSize (FileSystem, L
"\\EFI\\Microsoft\\Boot\\BCD", &BcdSize);
754 if (!EFI_ERROR (Status)) {
759 if ((BootEntry->Type ==
OC_BOOT_WINDOWS) && (BootEntry->Name == NULL)) {
760 BootEntry->Name = AllocateCopyPool (
sizeof (L
"Windows"), L
"Windows");
764 BootEntry->IsAppleInstaller = (StrStr (BootDirectoryName, L
"com.apple.installer") != NULL);
765 if (BootEntry->Name == NULL) {
771 if (BootEntry->IsAppleInstaller) {
772 BootEntry->Name = AllocateCopyPool (
L_STR_SIZE (L
"macOS Installer"), L
"macOS Installer");
775 if (BootEntry->Name != NULL) {
776 if ( (StrCmp (BootEntry->Name, L
"Recovery HD") == 0)
777 || (StrCmp (BootEntry->Name, L
"Recovery") == 0))
784 if (EFI_ERROR (Status)) {
789 }
else if (StrCmp (BootEntry->Name, L
"Preboot") == 0) {
796 TmpBootName = AllocateCopyPool (
sizeof (L
"Macintosh HD"), L
"Macintosh HD");
801 if (TmpBootName != NULL) {
802 FreePool (BootEntry->Name);
803 BootEntry->Name = TmpBootName;
809 if (BootEntry->Name == NULL) {
810 FreePool (BootDirectoryName);
811 return EFI_NOT_FOUND;
814 BootEntry->PathName = BootDirectoryName;
823 if ((BootEntry->Flavour == NULL) || (AsciiStrCmp (BootEntry->Flavour,
OC_FLAVOUR_AUTO) == 0)) {
824 switch (BootEntry->Type) {
845 ContentFlavour = NULL;
848 DEBUG ((DEBUG_ERROR,
"OCB: Entry kind %d unsupported for flavour\n", BootEntry->Type));
849 ContentFlavour = NULL;
854 if (ContentFlavour == NULL) {
856 }
else if ( (AppleVersion[0] !=
'\0')
863 Dot = AsciiStrStr (AppleVersion,
".");
865 if ( (Dot - AppleVersion ==
sizeof (
"10") - 1)
870 Dot = AsciiStrStr (Dot,
".");
883 if ((ContentFlavour == NULL) && (BootEntry->Flavour == NULL)) {
887 if (ContentFlavour != NULL) {
888 if (BootEntry->Flavour != NULL) {
889 FreePool (BootEntry->Flavour);
892 BootEntry->Flavour = ContentFlavour;
EFI_GUID gAppleBlessedOsxFolderInfoGuid
A global variable storing the GUID of the APPLE_BLESSED_OSX_FOLDER_INFO_GUID.
EFI_GUID gAppleBlessedSystemFolderInfoGuid
A global variable storing the GUID of the APPLE_BLESSED_SYSTEM_FOLDER_INFO_GUID.
EFI_DEVICE_PATH_PROTOCOL End
EFI_STATUS EFIAPI InternalGetBootEntryFile(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *FileName, IN CONST CHAR16 *DebugBootEntryName, IN CONST CHAR8 *DebugFileType, IN UINT32 MaxFileSize, IN UINT32 MinFileSize, OUT VOID **FileData, OUT UINT32 *DataLength OPTIONAL, IN BOOLEAN SearchAtLeaf, IN BOOLEAN SearchAtRoot)
EFI_STATUS EFIAPI OcGetBootEntryIcon(IN OC_PICKER_CONTEXT *Context, IN OC_BOOT_ENTRY *BootEntry, OUT VOID **ImageData, OUT UINT32 *DataLength)
EFI_STATUS InternalGetRecoveryOsBooter(IN EFI_HANDLE Device, OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, IN BOOLEAN Basic)
EFI_STATUS InternalReadBootEntryFile(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *DirectoryName, IN CONST CHAR16 *Filename, IN UINT32 MaxFileSize, IN UINT32 MinFileSize, OUT VOID **FileData, OUT UINT32 *DataSize OPTIONAL)
CHAR16 * InternalGetAppleDiskLabel(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *BootDirectoryName, IN CONST CHAR16 *LabelFilename)
EFI_STATUS InternalDescribeBootEntry(IN OC_BOOT_CONTEXT *BootContext, IN OUT OC_BOOT_ENTRY *BootEntry)
EFI_STATUS EFIAPI OcGetBootEntryFileFromDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *FileName, IN CONST CHAR8 *DebugFileType, IN UINT32 MaxFileSize, IN UINT32 MinFileSize, OUT VOID **FileData, OUT UINT32 *DataLength OPTIONAL, IN BOOLEAN SearchAtLeaf, IN BOOLEAN SearchAtRoot)
EFI_STATUS EFIAPI OcGetBootEntryLabelImage(IN OC_PICKER_CONTEXT *Context, IN OC_BOOT_ENTRY *BootEntry, IN UINT8 Scale, OUT VOID **ImageData, OUT UINT32 *DataLength)
STATIC CHAR16 * InternalGetAppleRecoveryName(IN CHAR8 *Version)
EFI_STATUS EFIAPI OcGetBootEntryFile(IN OC_BOOT_ENTRY *BootEntry, IN CONST CHAR16 *FileName, IN CONST CHAR8 *DebugFileType, IN UINT32 MaxFileSize, IN UINT32 MinFileSize, OUT VOID **FileData, OUT UINT32 *DataLength OPTIONAL, IN BOOLEAN SearchAtLeaf, IN BOOLEAN SearchAtRoot)
STATIC EFI_STATUS GetAppleVersionFromPlist(IN CHAR8 *SystemVersionData, IN UINT32 SystemVersionDataSize, OUT CHAR8 *AppleVersion)
STATIC CHAR8 * InternalAddAppleVersion(IN CHAR8 *Flavour, IN CHAR8 *Version)
CHAR8 * InternalGetContentFlavour(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *BootDirectoryName)
STATIC EFI_STATUS InternalGetAppleVersion(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *DirectoryName, OUT CHAR8 *AppleVersion)
#define OC_APPLE_VERSION_MAX_SIZE
EFI_STATUS OcBootPolicyDevicePathToDirPath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT CHAR16 **BootPathName, OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **FileSystem)
DMG_FILEPATH_DEVICE_PATH FilePath
DMG_SIZE_DEVICE_PATH Size
#define OC_FLAVOUR_WINDOWS
#define OC_FLAVOUR_APPLE_RECOVERY
#define OC_BOOT_APPLE_TIME_MACHINE
#define OC_BOOT_APPLE_ANY
#define OC_BOOT_EXTERNAL_TOOL
#define OC_FLAVOUR_APPLE_TIME_MACHINE
#define OC_FLAVOUR_APPLE_OS
#define OC_BOOT_EXTERNAL_OS
#define OC_ATTR_USE_FLAVOUR_ICON
#define OC_BOOT_APPLE_RECOVERY
#define OC_FLAVOUR_APPLE_FW
#define OC_BOOT_APPLE_FW_UPDATE
EFI_DEVICE_PATH_PROTOCOL * TrailedBooterDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL * AppendFileNameDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *FileName)
BOOLEAN EFIAPI IsDevicePathEqual(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2)
CHAR16 * OcGetVolumeLabel(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem)
EFI_STATUS OcReadFileSize(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *FilePath, OUT UINT32 *Size)
VOID * OcGetFileInfo(IN EFI_FILE_PROTOCOL *File, IN EFI_GUID *InformationType, IN UINTN MinFileInfoSize, OUT UINTN *RealFileInfoSize OPTIONAL)
#define OC_MAX_VOLUME_LABEL_SIZE
VOID * OcReadFile(IN CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *FilePath, OUT UINT32 *FileSize OPTIONAL, IN CONST UINT32 MaxFileSize OPTIONAL)
#define OC_MAX_CONTENT_FLAVOUR_SIZE
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 AsciiFilterString(IN OUT CHAR8 *String, IN BOOLEAN SingleLine)
BOOLEAN HasValidGuidStringPrefix(IN CONST CHAR16 *String)
#define L_STR_SIZE(String)
CHAR16 * AsciiStrCopyToUnicode(IN CONST CHAR8 *String, IN UINTN Length)
VOID UnicodeFilterString(IN OUT CHAR16 *String, IN BOOLEAN SingleLine)
BOOLEAN EFIAPI OcAsciiStartsWith(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
XML_DOCUMENT * XmlDocumentParse(IN OUT CHAR8 *Buffer, IN UINT32 Length, IN BOOLEAN WithRefs)
CONST CHAR8 * PlistKeyValue(IN XML_NODE *Node OPTIONAL)
CONST CHAR8 * XmlNodeContent(IN CONST XML_NODE *Node)
UINT32 PlistDictChildren(IN CONST XML_NODE *Node)
XML_NODE * PlistNodeCast(IN XML_NODE *Node OPTIONAL, IN PLIST_NODE_TYPE Type)
XML_NODE * PlistDocumentRoot(IN CONST XML_DOCUMENT *Document)
VOID XmlDocumentFree(IN OUT XML_DOCUMENT *Document)
XML_NODE * PlistDictChild(IN CONST XML_NODE *Node, IN UINT32 Child, OUT XML_NODE **Value OPTIONAL)
EFI_GUID gEfiSimpleFileSystemProtocolGuid
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)