20#include <Guid/FileInfo.h>
22#include <Protocol/SimpleFileSystem.h>
29#include <Library/BaseLib.h>
30#include <Library/BaseMemoryLib.h>
32#include <Library/DevicePathLib.h>
33#include <Library/MemoryAllocationLib.h>
34#include <Library/PrintLib.h>
35#include <Library/UefiBootServicesTableLib.h>
77 EFI_REMOVABLE_MEDIA_FILE_NAME
89 IN OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
97 OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
103 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
104 OUT CHAR16 **BootPathName,
105 OUT EFI_HANDLE *Device,
106 OUT EFI_HANDLE *ApfsVolumeHandle
112 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
114 OUT CHAR16 **FullPathName,
116 OUT EFI_FILE_PROTOCOL **Root,
117 OUT EFI_HANDLE *DeviceHandle
123 IN EFI_HANDLE
Handle OPTIONAL,
125 OUT UINTN *NumberOfEntries
152 IN EFI_FILE_HANDLE Root,
153 IN CONST CHAR16 *FileName
157 EFI_FILE_HANDLE FileHandle;
167 if (!EFI_ERROR (Status)) {
168 FileHandle->Close (FileHandle);
178 IN EFI_FILE_PROTOCOL *Root,
183 if ((ContainerInfo == NULL) && (VolumeInfo == NULL)) {
184 return EFI_INVALID_PARAMETER;
187 if (VolumeInfo != NULL) {
191 sizeof (**VolumeInfo),
195 if (*VolumeInfo == NULL) {
196 DEBUG ((DEBUG_VERBOSE,
"OCBP: APFS Volume Info is missing\n"));
197 return EFI_NOT_FOUND;
202 "OCBP: APFS Volume Info - %p (%u, %g, %u)\n",
204 (*VolumeInfo)->Always1,
205 &(*VolumeInfo)->Uuid,
210 if (ContainerInfo != NULL) {
214 sizeof (**ContainerInfo),
218 if (*ContainerInfo == NULL) {
220 if (VolumeInfo != NULL) {
221 FreePool (*VolumeInfo);
224 return EFI_NOT_FOUND;
229 "OCBP: APFS Container Info - %p (%u, %g)\n",
231 (*ContainerInfo)->Always1,
232 &(*ContainerInfo)->Uuid
242 IN EFI_FILE_PROTOCOL *Root,
243 OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
251 sizeof (EFI_DEVICE_PATH_PROTOCOL),
257 return EFI_NOT_FOUND;
262 if (!IsDevicePathValid (*
FilePath, FilePathSize)) {
266 return EFI_NOT_FOUND;
279 IN EFI_HANDLE Device,
280 IN EFI_FILE_PROTOCOL *Root,
281 OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
286 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
287 EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker;
288 FILEPATH_DEVICE_PATH *FolderDevicePath;
289 UINTN DevicePathSize;
290 UINTN BooterDirPathSize;
291 UINTN BooterPathSize;
294 Status = EFI_NOT_FOUND;
299 sizeof (EFI_DEVICE_PATH_PROTOCOL),
303 if (DevicePath == NULL) {
310 if (!IsDevicePathValid (DevicePath, DevicePathSize)) {
312 FreePool (DevicePath);
313 return EFI_NOT_FOUND;
318 DevicePathWalker = DevicePath;
320 while (!IsDevicePathEnd (DevicePathWalker)) {
321 if ( (DevicePathType (DevicePathWalker) == MEDIA_DEVICE_PATH)
322 && (DevicePathSubType (DevicePathWalker) == MEDIA_FILEPATH_DP))
324 FolderDevicePath = (FILEPATH_DEVICE_PATH *)DevicePathWalker;
327 BooterPath = AllocateZeroPool (BooterPathSize);
329 if (BooterPath != NULL) {
333 CopyMem (BooterPath, FolderDevicePath->PathName, BooterDirPathSize);
335 Status = EFI_SUCCESS;
337 Status = EFI_OUT_OF_RESOURCES;
343 DevicePathWalker = NextDevicePathNode (DevicePathWalker);
346 FreePool (DevicePath);
348 if (EFI_ERROR (Status)) {
349 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: Blessed folder append failed - %r\n", Status));
354 if (EFI_ERROR (Status)) {
355 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: Blessed folder %s is missing - %r\n", BooterPath, Status));
356 return EFI_NOT_FOUND;
359 *
FilePath = FileDevicePath (Device, BooterPath);
365 IN EFI_HANDLE Device,
366 IN EFI_FILE_PROTOCOL *Root,
367 IN CONST CHAR16 **PredefinedPaths,
368 IN UINTN NumPredefinedPaths,
369 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL,
370 IN CHAR16 *Prefix OPTIONAL
379 for (Index = 0; Index < NumPredefinedPaths; ++Index) {
386 if (Prefix != NULL) {
394 if (!EFI_ERROR (Status)) {
397 "OCBP: Predefined %s %s was found\n",
398 Prefix != NULL ? Prefix : L
"<nil>",
401 if (DevicePath != NULL) {
405 if (Prefix != NULL) {
406 ASSERT (Prefix[0] != L
'\\');
407 FullPathSize = StrSize (Prefix) + StrSize (
PathName);
408 FullPath = AllocatePool (FullPathSize);
409 if (FullPath != NULL) {
410 UnicodeSPrint (FullPath, FullPathSize, L
"\\%s%s", Prefix,
PathName);
411 *DevicePath = FileDevicePath (Device, FullPath);
414 return EFI_OUT_OF_RESOURCES;
417 *DevicePath = FileDevicePath (Device,
PathName);
421 ASSERT (DevicePath == NULL || *DevicePath != NULL);
426 "OCBP: Predefined %s %s is missing - %r\n",
427 Prefix != NULL ? Prefix : L
"<nil>",
434 return EFI_NOT_FOUND;
440 IN EFI_HANDLE Device,
441 OUT EFI_GUID *ContainerGuid,
442 OUT EFI_GUID *VolumeGuid,
448 EFI_FILE_PROTOCOL *Root;
449 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
455 Status =
gBS->HandleProtocol (
460 if (EFI_ERROR (Status)) {
464 Status = FileSystem->OpenVolume (FileSystem, &Root);
465 if (EFI_ERROR (Status)) {
473 if (EFI_ERROR (Status)) {
474 return EFI_NOT_FOUND;
479 &ApfsVolumeInfo->
Uuid
482 *VolumeRole = ApfsVolumeInfo->
Role;
486 &ApfsContainerInfo->
Uuid
489 FreePool (ApfsVolumeInfo);
490 FreePool (ApfsContainerInfo);
498 IN EFI_HANDLE Device,
499 IN EFI_FILE_PROTOCOL *PrebootRoot,
500 IN CHAR16 *VolumeDirectoryName,
501 IN CONST CHAR16 **PredefinedPaths,
502 IN UINTN NumPredefinedPaths,
503 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL
507 EFI_FILE_PROTOCOL *VolumeDirectoryHandle;
508 EFI_FILE_INFO *VolumeDirectoryInfo;
512 &VolumeDirectoryHandle,
518 if (EFI_ERROR (Status)) {
519 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: Missing partition %s on preboot - %r\n", VolumeDirectoryName, Status));
522 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: Found partition %s on preboot\n", VolumeDirectoryName));
526 VolumeDirectoryHandle,
528 sizeof (*VolumeDirectoryInfo),
532 if (VolumeDirectoryInfo == NULL) {
533 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: Missing volume file info %s - %r\n", VolumeDirectoryName, Status));
534 VolumeDirectoryHandle->Close (VolumeDirectoryHandle);
535 return EFI_NOT_FOUND;
538 Status = EFI_NOT_FOUND;
542 "OCBP: Want predefined list for APFS %u at %s\n",
543 VolumeDirectoryInfo->Attribute,
547 if ((VolumeDirectoryInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
550 VolumeDirectoryHandle,
558 FreePool (VolumeDirectoryInfo);
559 VolumeDirectoryHandle->Close (VolumeDirectoryHandle);
573 IN EFI_HANDLE Device,
574 IN EFI_FILE_PROTOCOL *PrebootRoot,
575 IN CONST GUID *ContainerUuid,
576 IN CONST CHAR16 *VolumeUuid OPTIONAL,
577 IN CONST CHAR16 **PredefinedPaths,
578 IN UINTN NumPredefinedPaths,
579 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL,
580 OUT EFI_HANDLE *VolumeHandle OPTIONAL
584 EFI_STATUS TmpStatus;
586 UINTN NumberOfHandles;
587 EFI_HANDLE *HandleBuffer;
589 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
590 EFI_FILE_PROTOCOL *HandleRoot;
593 CHAR16 VolumeDirectoryName[GUID_STRING_LENGTH+1];
594 EFI_DEVICE_PATH_PROTOCOL *VolumeDevPath;
595 EFI_DEVICE_PATH_PROTOCOL *TempDevPath;
596 BOOLEAN ContainerMatch;
598 ASSERT (VolumeUuid == NULL || (VolumeUuid != NULL && VolumeHandle != NULL && *VolumeHandle == NULL));
601 Status =
gBS->LocateHandleBuffer (
609 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: %u filesystems for APFS - %r\n", (UINT32)NumberOfHandles, Status));
611 if (EFI_ERROR (Status)) {
615 Status = EFI_NOT_FOUND;
617 for (Index = 0; Index < NumberOfHandles; ++Index) {
618 TmpStatus =
gBS->HandleProtocol (
623 if (EFI_ERROR (TmpStatus)) {
626 "OCBP: Borked APFS filesystem %u of %u - %r\n",
628 (UINT32)NumberOfHandles,
634 TmpStatus = FileSystem->OpenVolume (FileSystem, &HandleRoot);
635 if (EFI_ERROR (TmpStatus)) {
638 "OCBP: Borked APFS root volume %u of %u - %r\n",
640 (UINT32)NumberOfHandles,
648 HandleRoot->Close (HandleRoot);
650 if (EFI_ERROR (TmpStatus)) {
653 "OCBP: No APFS info %u of %u - %r\n",
655 (UINT32)NumberOfHandles,
665 "OCBP: APFS match container %g vs %g for %u of %u - %d\n",
666 &ContainerInfo->
Uuid,
669 (UINT32)NumberOfHandles,
673 if (!ContainerMatch) {
674 FreePool (ContainerInfo);
675 FreePool (VolumeInfo);
681 sizeof (VolumeDirectoryName),
686 FreePool (ContainerInfo);
687 FreePool (VolumeInfo);
689 if ((VolumeUuid != NULL) && (StrStr (VolumeUuid, VolumeDirectoryName) != NULL)) {
690 *VolumeHandle = HandleBuffer[Index];
699 DevicePath != NULL ? &VolumeDevPath : NULL
702 if (EFI_ERROR (TmpStatus)) {
705 "OCBP: No APFS booter %u of %u for %s - %r\n",
707 (UINT32)NumberOfHandles,
712 Status = EFI_SUCCESS;
716 "OCBP: Found APFS booter %u of %u for %s (%p)\n",
718 (UINT32)NumberOfHandles,
723 if (DevicePath != NULL) {
724 TempDevPath = *DevicePath;
729 if (TempDevPath != NULL) {
730 FreePool (TempDevPath);
736 FreePool (HandleBuffer);
740 "OCBP: APFS bless for %g:%s is %r\n",
752 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
753 OUT CHAR16 **BootPathName,
754 IN BOOLEAN DirectoryOnly
761 CHAR16 *FilePathName;
763 if ( (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH)
764 && (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP))
768 PathName = AllocatePool (PathNameSize);
770 return EFI_OUT_OF_RESOURCES;
775 (FILEPATH_DEVICE_PATH *)DevicePath,
787 while (*FilePathName != L
'\\') {
788 *FilePathName = L
'\0';
792 StrCpyS (
PathName, PathNameSize, L
"\\");
796 PathName = AllocateZeroPool (
sizeof (L
"\\"));
799 return EFI_OUT_OF_RESOURCES;
802 StrCpyS (
PathName,
sizeof (L
"\\"), L
"\\");
812 IN EFI_HANDLE DeviceHandle,
814 IN CONST CHAR16 **PredefinedPaths,
815 IN UINTN NumPredefinedPaths,
816 OUT EFI_HANDLE *ApfsVolumeHandle
821 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
822 EFI_FILE_PROTOCOL *Root;
824 CHAR16 *FilePathName;
833 return EFI_INVALID_PARAMETER;
836 Status =
gBS->HandleProtocol (
842 if (EFI_ERROR (Status)) {
846 Status = FileSystem->OpenVolume (FileSystem, &Root);
847 if (EFI_ERROR (Status)) {
852 if (!EFI_ERROR (Status)) {
859 &ContainerInfo->
Uuid,
867 FreePool (ContainerInfo);
877 IN EFI_HANDLE Device,
878 IN CONST CHAR16 **PredefinedPaths,
879 IN UINTN NumPredefinedPaths,
880 IN OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
885 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
886 EFI_FILE_PROTOCOL *Root;
894 Status =
gBS->HandleProtocol (
900 if (EFI_ERROR (Status)) {
904 Status = FileSystem->OpenVolume (FileSystem, &Root);
906 if (EFI_ERROR (Status)) {
911 if (EFI_ERROR (Status)) {
913 if (EFI_ERROR (Status)) {
933 IN EFI_HANDLE Device,
934 IN OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
937 if ((Device == NULL) || (
FilePath == NULL)) {
938 return EFI_INVALID_PARAMETER;
951 IN EFI_HANDLE Device,
952 IN CONST CHAR16 **PredefinedPaths,
953 IN UINTN NumPredefinedPaths,
954 OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
958 EFI_STATUS TmpStatus;
960 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
961 EFI_FILE_PROTOCOL *Root;
971 Status =
gBS->HandleProtocol (
976 if (EFI_ERROR (Status)) {
981 Status = FileSystem->OpenVolume (FileSystem, &Root);
982 if (EFI_ERROR (Status)) {
988 if (!EFI_ERROR (Status)) {
989 Status = EFI_NOT_FOUND;
992 if (EFI_ERROR (TmpStatus)) {
1002 &ContainerInfo->
Uuid,
1009 if (!EFI_ERROR (TmpStatus)) {
1014 FreePool (VolumeInfo);
1015 FreePool (ContainerInfo);
1018 if (EFI_ERROR (Status)) {
1020 if (EFI_ERROR (Status)) {
1041 IN EFI_HANDLE Device,
1043 OUT EFI_DEVICE_PATH_PROTOCOL **
FilePath
1046 if ((Device == NULL) || (
FilePath == NULL)) {
1047 return EFI_INVALID_PARAMETER;
1060 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1061 OUT CHAR16 **BootPathName,
1062 OUT EFI_HANDLE *Device,
1063 IN BOOLEAN DirectoryOnly
1068 ASSERT (DevicePath != NULL);
1069 ASSERT (BootPathName != NULL);
1072 *BootPathName = NULL;
1075 Status =
gBS->LocateDevicePath (
1080 if (EFI_ERROR (Status)) {
1089 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1090 OUT CHAR16 **BootPathName,
1091 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **FileSystem
1097 ASSERT (DevicePath != NULL);
1098 ASSERT (BootPathName != NULL);
1099 ASSERT (FileSystem != NULL);
1108 if (EFI_ERROR (Status)) {
1112 Status =
gBS->HandleProtocol (
1118 if (EFI_ERROR (Status)) {
1119 FreePool (BootPathName);
1120 BootPathName = NULL;
1128 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1129 OUT CHAR16 **BootPathName
1134 ASSERT (DevicePath != NULL);
1135 ASSERT (BootPathName != NULL);
1148 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1149 IN CONST CHAR16 **PredefinedPaths,
1150 IN UINTN NumPredefinedPaths,
1151 OUT CHAR16 **BootPathName,
1152 OUT EFI_HANDLE *Device,
1153 OUT EFI_HANDLE *ApfsVolumeHandle
1158 ASSERT (DevicePath != NULL);
1159 ASSERT (BootPathName != NULL);
1161 ASSERT (ApfsVolumeHandle != NULL);
1169 if (EFI_ERROR (Status)) {
1177 *ApfsVolumeHandle = NULL;
1192 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1193 OUT CHAR16 **BootPathName,
1194 OUT EFI_HANDLE *Device,
1195 OUT EFI_HANDLE *ApfsVolumeHandle
1200 if ( (DevicePath == NULL)
1201 || (BootPathName == NULL)
1203 || (ApfsVolumeHandle == NULL))
1205 return EFI_INVALID_PARAMETER;
1216 if (EFI_ERROR (Status)) {
1217 *BootPathName = NULL;
1219 *ApfsVolumeHandle = NULL;
1228 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1230 IN CONST CHAR16 **PredefinedPaths,
1231 IN UINTN NumPredefinedPaths,
1232 OUT CHAR16 **FullPathName,
1233 OUT EFI_FILE_PROTOCOL **Root,
1234 OUT EFI_HANDLE *DeviceHandle
1241 CHAR16 *BootPathName;
1243 EFI_HANDLE VolumeHandle;
1249 GUID ContainerGuid2;
1254 EFI_HANDLE *HandleBuffer;
1257 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
1259 CHAR16 *FullPathBuffer;
1260 UINTN FullPathNameSize;
1262 EFI_FILE_PROTOCOL *NewHandle;
1264 EFI_FILE_INFO *FileInfo;
1266 ASSERT (DevicePath != NULL);
1268 ASSERT (FullPathName != NULL);
1270 ASSERT (DeviceHandle != NULL);
1274 *FullPathName = NULL;
1285 if (EFI_ERROR (Status)) {
1286 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: APFS recovery boot info failed - %r\n", Status));
1287 return EFI_NOT_FOUND;
1290 if (VolumeHandle == NULL) {
1291 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: APFS recovery volume handle missing - %s\n", BootPathName));
1292 FreePool (BootPathName);
1293 return EFI_NOT_FOUND;
1296 FreePool (BootPathName);
1305 if (EFI_ERROR (Status)) {
1306 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: APFS recovery volume info missing\n"));
1307 return EFI_NOT_FOUND;
1310 Status =
gBS->LocateHandleBuffer (
1318 if (EFI_ERROR (Status)) {
1319 DEBUG ((
DEBUG_BULK_INFO,
"OCBP: APFS recovery simple fs missing - %r\n", Status));
1323 Result = EFI_NOT_FOUND;
1325 for (Index = 0; Index < NoHandles; ++Index) {
1326 ZeroMem (&ContainerGuid2,
sizeof (ContainerGuid2));
1327 ZeroMem (&VolumeGuid2,
sizeof (VolumeGuid2));
1331 HandleBuffer[Index],
1339 "OCBP: APFS recovery info %u/%u due to %g/%g/%X - %r\n",
1344 (UINT32)VolumeRole2,
1348 if ( EFI_ERROR (Status)
1350 || !
CompareGuid (&ContainerGuid2, &ContainerGuid))
1355 Status =
gBS->HandleProtocol (
1356 HandleBuffer[Index],
1358 (VOID **)&FileSystem
1360 if (EFI_ERROR (Status)) {
1364 Status = FileSystem->OpenVolume (FileSystem, Root);
1365 if (EFI_ERROR (Status)) {
1369 FullPathNameSize =
sizeof (CHAR16) + StrSize (
PathName);
1370 FullPathNameSize += GUID_STRING_LENGTH *
sizeof (CHAR16);
1371 FullPathBuffer = AllocateZeroPool (FullPathNameSize);
1373 if (FullPathBuffer == NULL) {
1374 (*Root)->Close (*Root);
1398 if (EFI_ERROR (Status)) {
1399 (*Root)->Close (*Root);
1400 FreePool (FullPathBuffer);
1411 if (FileInfo != NULL) {
1412 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
1413 *FullPathName = FullPathBuffer;
1414 *DeviceHandle = HandleBuffer[Index];
1415 Result = EFI_SUCCESS;
1418 FreePool (FileInfo);
1421 NewHandle->Close (NewHandle);
1423 if (!EFI_ERROR (Result)) {
1427 (*Root)->Close (*Root);
1428 FreePool (FullPathBuffer);
1431 FreePool (HandleBuffer);
1439 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1441 OUT CHAR16 **FullPathName,
1443 OUT EFI_FILE_PROTOCOL **Root,
1444 OUT EFI_HANDLE *DeviceHandle
1447 if ( (DevicePath == NULL)
1449 || (FullPathName == NULL)
1452 || (DeviceHandle == NULL))
1454 return EFI_INVALID_PARAMETER;
1472 IN EFI_HANDLE
Handle OPTIONAL,
1474 OUT UINTN *NumberOfEntries
1479 UINTN NumberOfHandles;
1480 EFI_HANDLE *HandleBuffer;
1482 GUID *ContainerGuids;
1483 UINTN NumberOfContainers;
1484 UINTN NumberOfVolumeInfos;
1489 BOOLEAN GuidPresent;
1490 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
1491 EFI_FILE_PROTOCOL *Root;
1492 EFI_FILE_PROTOCOL *NewHandle;
1493 CHAR16 VolumePathName[GUID_STRING_LENGTH + 1];
1494 EFI_FILE_INFO *FileInfo;
1497 ASSERT (Volumes != NULL);
1498 ASSERT (NumberOfEntries != NULL);
1500 Status =
gBS->LocateHandleBuffer (
1508 if (EFI_ERROR (Status)) {
1512 VolumeInfo = AllocateZeroPool (NumberOfHandles *
sizeof (*VolumeInfo));
1513 ContainerGuids = AllocateZeroPool (NumberOfHandles *
sizeof (*ContainerGuids));
1515 if ((VolumeInfo == NULL) || (ContainerGuids == NULL)) {
1516 Status = EFI_OUT_OF_RESOURCES;
1519 if (EFI_ERROR (Status)) {
1520 FreePool (HandleBuffer);
1522 if (VolumeInfo != NULL) {
1523 FreePool (VolumeInfo);
1526 if (ContainerGuids != NULL) {
1527 FreePool (ContainerGuids);
1533 NumberOfVolumeInfos = 0;
1534 NumberOfContainers = 0;
1536 for (Index = 0; Index < NumberOfHandles; ++Index) {
1538 HandleBuffer[Index],
1539 &VolumeInfo[NumberOfVolumeInfos].ContainerGuid,
1540 &VolumeInfo[NumberOfVolumeInfos].VolumeGuid,
1541 &VolumeInfo[NumberOfVolumeInfos].VolumeRole
1544 if (EFI_ERROR (Status)) {
1548 VolumeInfo[NumberOfVolumeInfos].
Handle = HandleBuffer[Index];
1550 GuidPresent = FALSE;
1551 for (Index2 = 0; Index2 < NumberOfContainers; ++Index2) {
1552 if (
CompareGuid (&ContainerGuids[Index2], &VolumeInfo[NumberOfVolumeInfos].ContainerGuid)) {
1560 &ContainerGuids[NumberOfContainers],
1561 &VolumeInfo[NumberOfVolumeInfos].ContainerGuid
1564 if ((Index2 != 0) && (HandleBuffer[Index] ==
Handle)) {
1568 NumberOfContainers *
sizeof (ContainerGuids[0])
1572 &VolumeInfo[NumberOfVolumeInfos].ContainerGuid
1576 ++NumberOfContainers;
1579 ++NumberOfVolumeInfos;
1582 Status = EFI_SUCCESS;
1584 if (NumberOfVolumeInfos > 0) {
1585 ApfsVolumes = AllocateZeroPool (
1586 NumberOfVolumeInfos *
sizeof (*ApfsVolumes)
1588 if (ApfsVolumes == NULL) {
1589 Status = EFI_OUT_OF_RESOURCES;
1592 Status = EFI_NOT_FOUND;
1595 if (EFI_ERROR (Status)) {
1596 FreePool (HandleBuffer);
1597 FreePool (VolumeInfo);
1598 FreePool (ContainerGuids);
1602 *Volumes = ApfsVolumes;
1603 *NumberOfEntries = 0;
1605 for (Index = 0; Index < NumberOfContainers; ++Index) {
1606 for (Index2 = 0; Index2 < NumberOfVolumeInfos; ++Index2) {
1608 || !
CompareGuid (&ContainerGuids[Index], &VolumeInfo[Index2].ContainerGuid))
1613 Status =
gBS->HandleProtocol (
1614 VolumeInfo[Index2].
Handle,
1616 (VOID **)&FileSystem
1618 if (EFI_ERROR (Status)) {
1622 Status = FileSystem->OpenVolume (FileSystem, &Root);
1623 if (EFI_ERROR (Status)) {
1630 for (Index3 = 0; Index3 < NumberOfVolumeInfos; ++Index3) {
1631 if ( ((VolumeInfo[Index2].VolumeRole &
1633 || !
CompareGuid (&ContainerGuids[Index], &VolumeInfo[Index3].ContainerGuid))
1640 sizeof (VolumePathName),
1642 &VolumeInfo[Index3].VolumeGuid
1653 if (EFI_ERROR (Status)) {
1664 NewHandle->Close (NewHandle);
1666 if (FileInfo != NULL) {
1667 if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) != 0) {
1668 ApfsRoot = ApfsVolumes[*NumberOfEntries];
1671 StrSize (VolumePathName),
1674 ApfsRoot->
Root = Root;
1676 ++(*NumberOfEntries);
1679 FreePool (FileInfo);
1685 FreePool (VolumeInfo);
1686 FreePool (ContainerGuids);
1687 FreePool (HandleBuffer);
1689 if (!EFI_ERROR (Status) && (*NumberOfEntries == 0)) {
1690 Status = EFI_NOT_FOUND;
1699 IN EFI_HANDLE
Handle OPTIONAL,
1701 OUT UINTN *NumberOfEntries
1704 if ((Volumes == NULL) || (NumberOfEntries == NULL)) {
1705 return EFI_INVALID_PARAMETER;
1717 IN BOOLEAN Reinstall
1727 if (EFI_ERROR (Status)) {
1728 DEBUG ((DEBUG_ERROR,
"OCBP: Uninstall failed - %r\n", Status));
1732 Status =
gBS->LocateProtocol (
1738 if (!EFI_ERROR (Status)) {
1744 Status =
gBS->InstallMultipleProtocolInterfaces (
1751 if (EFI_ERROR (Status)) {
#define APPLE_APFS_VOLUME_ROLE_RECOVERY
UINT32 APPLE_APFS_VOLUME_ROLE
EFI_GUID gAppleApfsVolumeInfoGuid
EFI_GUID gAppleApfsContainerInfoGuid
#define APPLE_APFS_VOLUME_ROLE_PREBOOT
EFI_GUID gAppleBlessedSystemFileInfoGuid
A global variable storing the GUID of the APPLE_BLESSED_SYSTEM_FILE_INFO_GUID.
EFI_GUID gAppleBlessedSystemFolderInfoGuid
A global variable storing the GUID of the APPLE_BLESSED_SYSTEM_FOLDER_INFO_GUID.
#define APPLE_BOOT_POLICY_PROTOCOL_REVISION
EFI_GUID gAppleBootPolicyProtocolGuid
#define ARRAY_SIZE(Array)
#define APPLE_BOOTER_ROOT_FILE_NAME
#define APPLE_BOOTER_DEFAULT_FILE_NAME
#define MS_BOOTER_DEFAULT_FILE_NAME
EFI_STATUS OcBootPolicyGetAllApfsRecoveryFilePath(IN EFI_HANDLE Handle OPTIONAL, OUT VOID **Volumes, OUT UINTN *NumberOfEntries)
STATIC EFI_STATUS InternalGetBootPathName(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT CHAR16 **BootPathName, IN BOOLEAN DirectoryOnly)
EFI_STATUS EFIAPI BootPolicyGetAllApfsRecoveryFilePath(IN EFI_HANDLE Handle OPTIONAL, OUT VOID **Volumes, OUT UINTN *NumberOfEntries)
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR16 * gAppleBootPolicyPredefinedPaths[]
APPLE_BOOT_POLICY_PROTOCOL * OcAppleBootPolicyInstallProtocol(IN BOOLEAN Reinstall)
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN gAppleBootPolicyNumPredefinedPaths
STATIC EFI_STATUS InternalGetBooterFromBlessedSystemFilePath(IN EFI_FILE_PROTOCOL *Root, OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
STATIC EFI_STATUS InternalGetApfsVolumeInfo(IN EFI_HANDLE Device, OUT EFI_GUID *ContainerGuid, OUT EFI_GUID *VolumeGuid, OUT APPLE_APFS_VOLUME_ROLE *VolumeRole)
STATIC EFI_STATUS OcBootPolicyDevicePathToDirPathAndApfsHandle(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, OUT CHAR16 **BootPathName, OUT EFI_HANDLE *Device, OUT EFI_HANDLE *ApfsVolumeHandle)
STATIC EFI_STATUS InternalGetBooterFromBlessedSystemFolderPath(IN EFI_HANDLE Device, IN EFI_FILE_PROTOCOL *Root, OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
EFI_STATUS OcBootPolicyDevicePathToFilePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT CHAR16 **BootPathName)
EFI_STATUS EFIAPI BootPolicyDevicePathToDirPath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT CHAR16 **BootPathName, OUT EFI_HANDLE *Device, OUT EFI_HANDLE *ApfsVolumeHandle)
STATIC EFI_STATUS InternalFileExists(IN EFI_FILE_HANDLE Root, IN CONST CHAR16 *FileName)
EFI_STATUS EFIAPI BootPolicyGetBootFileEx(IN EFI_HANDLE Device, IN BOOT_POLICY_ACTION Action, OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
EFI_STATUS OcGetBooterFromPredefinedPathList(IN EFI_HANDLE Device, IN EFI_FILE_PROTOCOL *Root, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, IN CHAR16 *Prefix OPTIONAL)
EFI_STATUS EFIAPI BootPolicyGetBootFile(IN EFI_HANDLE Device, IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
STATIC EFI_STATUS InternalGetApfsVolumeHandle(IN EFI_HANDLE DeviceHandle, IN CHAR16 *PathName, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, OUT EFI_HANDLE *ApfsVolumeHandle)
EFI_STATUS OcBootPolicyGetBootFileEx(IN EFI_HANDLE Device, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
EFI_STATUS OcBootPolicyDevicePathToDirPath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT CHAR16 **BootPathName, OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **FileSystem)
EFI_STATUS EFIAPI BootPolicyGetApfsRecoveryFilePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *PathName, OUT CHAR16 **FullPathName, OUT VOID **Reserved, OUT EFI_FILE_PROTOCOL **Root, OUT EFI_HANDLE *DeviceHandle)
STATIC APPLE_BOOT_POLICY_PROTOCOL mAppleBootPolicyProtocol
STATIC EFI_STATUS InternalGetApfsSpecialFileInfo(IN EFI_FILE_PROTOCOL *Root, IN OUT APPLE_APFS_VOLUME_INFO **VolumeInfo OPTIONAL, IN OUT APPLE_APFS_CONTAINER_INFO **ContainerInfo OPTIONAL)
EFI_STATUS OcBootPolicyGetApfsRecoveryFilePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *PathName, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, OUT CHAR16 **FullPathName, OUT EFI_FILE_PROTOCOL **Root, OUT EFI_HANDLE *DeviceHandle)
EFI_STATUS InternalBootPolicyDevicePathToDirPath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT CHAR16 **BootPathName, OUT EFI_HANDLE *Device, IN BOOLEAN DirectoryOnly)
STATIC EFI_STATUS InternalGetBooterFromApfsVolumePredefinedPathList(IN EFI_HANDLE Device, IN EFI_FILE_PROTOCOL *PrebootRoot, IN CHAR16 *VolumeDirectoryName, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL)
EFI_STATUS OcBootPolicyGetBootFile(IN EFI_HANDLE Device, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath)
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN gAppleBootPolicyCoreNumPredefinedPaths
STATIC EFI_STATUS InternalGetBooterFromApfsPredefinedPathList(IN EFI_HANDLE Device, IN EFI_FILE_PROTOCOL *PrebootRoot, IN CONST GUID *ContainerUuid, IN CONST CHAR16 *VolumeUuid OPTIONAL, IN CONST CHAR16 **PredefinedPaths, IN UINTN NumPredefinedPaths, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath OPTIONAL, OUT EFI_HANDLE *VolumeHandle OPTIONAL)
CHAR16 PathName[DMG_FILE_PATH_LEN]
DMG_FILEPATH_DEVICE_PATH FilePath
VOID DebugPrintHexDump(IN UINTN ErrorLevel, IN CONST CHAR8 *Message, IN UINT8 *Bytes, IN UINTN Size)
VOID DebugPrintDevicePath(IN UINTN ErrorLevel, IN CONST CHAR8 *Message, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL)
UINTN OcFileDevicePathNameSize(IN CONST FILEPATH_DEVICE_PATH *FilePath)
EFI_DEVICE_PATH_PROTOCOL * OcAppendDevicePathInstanceDedupe(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance)
VOID OcFileDevicePathFullName(OUT CHAR16 *PathName, IN CONST FILEPATH_DEVICE_PATH *FilePath, IN UINTN PathNameSize)
UINTN OcFileDevicePathFullNameSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID * OcGetFileInfo(IN EFI_FILE_PROTOCOL *File, IN EFI_GUID *InformationType, IN UINTN MinFileInfoSize, OUT UINTN *RealFileInfoSize 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)
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
BOOLEAN HasValidGuidStringPrefix(IN CONST CHAR16 *String)
#define L_STR_SIZE(String)
APPLE_EVENT_HANDLE Handle
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_GUID gEfiFileInfoGuid
EFI_GUID gEfiSimpleFileSystemProtocolGuid
APPLE_APFS_VOLUME_ROLE VolumeRole
APPLE_APFS_VOLUME_ROLE Role