mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
Partially fix APFS recovery detection
This commit is contained in:
parent
5e3dc3c6df
commit
b13c2a493e
@ -47,4 +47,30 @@ OcDescribeBootEntry (
|
||||
IN OUT CHAR16 **BootPathName OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Discovered boot entry.
|
||||
Note, DevicePath must be freed.
|
||||
**/
|
||||
typedef struct OC_BOOT_ENTRY_ {
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
BOOLEAN PrefersDmgBoot;
|
||||
} OC_BOOT_ENTRY;
|
||||
|
||||
/**
|
||||
@param[in] BootPolicy Apple Boot Policy Protocol.
|
||||
@param[in] Mode Lookup mode.
|
||||
@param[out] BootEntries List of boot entries (allocated from pool).
|
||||
@param[out] Count Number of boot entries.
|
||||
|
||||
@retval EFI_SUCCESS The entry point is executed successfully.
|
||||
@retval EFI_ALREADY_STARTED The protocol has already been installed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
OcScanForBootEntries (
|
||||
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
|
||||
IN UINT32 Mode,
|
||||
OUT OC_BOOT_ENTRY **BootEntries,
|
||||
OUT UINTN *Count
|
||||
);
|
||||
|
||||
#endif // OC_APPLE_BOOT_POLICY_LIB_H
|
||||
|
||||
@ -556,9 +556,10 @@ HasValidGuidStringPrefix (
|
||||
}
|
||||
|
||||
for (Index = 0; Index < GuidLength; ++Index) {
|
||||
if ((Index == 8 || Index == 12 || Index == 16 || Index == 20)
|
||||
&& String[Index] != '-') {
|
||||
return FALSE;
|
||||
if (Index == 8 || Index == 13 || Index == 18 || Index == 23) {
|
||||
if (String[Index] != '-') {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (!(String[Index] >= L'0' && String[Index] <= L'9')
|
||||
&& !(String[Index] >= L'A' && String[Index] <= L'F')
|
||||
&& !(String[Index] >= L'a' && String[Index] <= L'f')) {
|
||||
@ -1035,12 +1036,12 @@ BootPolicyGetPathNameOnApfsRecovery (
|
||||
}
|
||||
|
||||
NewHandle->Close (NewHandle);
|
||||
(*Root)->Close (*Root);
|
||||
|
||||
if (!EFI_ERROR (Result)) {
|
||||
break;
|
||||
}
|
||||
|
||||
(*Root)->Close (*Root);
|
||||
FreePool (FullPathBuffer);
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@
|
||||
gAppleApfsVolumeInfoGuid ## SOMETIMES_CONSUMES
|
||||
gAppleBlessedSystemFileInfoGuid ## SOMETIMES_CONSUMES
|
||||
gAppleBlessedSystemFolderInfoGuid ## SOMETIMES_CONSUMES
|
||||
gAppleBlessedAlternateOsInfoGuid ## SOMETIMES_CONSUMES
|
||||
gEfiFileInfoGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[Protocols]
|
||||
|
||||
@ -36,7 +36,8 @@ STATIC
|
||||
CHAR16 *
|
||||
GetAppleDiskLabel (
|
||||
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
|
||||
IN CONST CHAR16 *BootDirectoryName
|
||||
IN CONST CHAR16 *BootDirectoryName,
|
||||
IN CONST CHAR16 *LabelFilename
|
||||
)
|
||||
{
|
||||
CHAR16 *DiskLabelPath;
|
||||
@ -45,14 +46,14 @@ GetAppleDiskLabel (
|
||||
CHAR16 *UnicodeDiskLabel;
|
||||
UINTN DiskLabelLength;
|
||||
|
||||
DiskLabelPathSize = StrSize (BootDirectoryName) + L_STR_SIZE_NT (L".disk_label.contentDetails");
|
||||
DiskLabelPathSize = StrSize (BootDirectoryName) + StrLen (LabelFilename);
|
||||
DiskLabelPath = AllocatePool (DiskLabelPathSize);
|
||||
|
||||
if (DiskLabelPath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UnicodeSPrint (DiskLabelPath, DiskLabelPathSize, L"%s.disk_label.contentDetails", BootDirectoryName);
|
||||
UnicodeSPrint (DiskLabelPath, DiskLabelPathSize, L"%s%s", BootDirectoryName, LabelFilename);
|
||||
AsciiDiskLabel = (CHAR8 *) ReadFile (FileSystem, DiskLabelPath, &DiskLabelLength);
|
||||
FreePool (DiskLabelPath);
|
||||
|
||||
@ -158,6 +159,54 @@ GetAppleRecoveryName (
|
||||
return UnicodeDiskLabel;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetAlternateOsBooter (
|
||||
IN EFI_HANDLE Device,
|
||||
OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
|
||||
EFI_FILE_PROTOCOL *Root;
|
||||
UINTN FilePathSize;
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
Device,
|
||||
&gEfiSimpleFileSystemProtocolGuid,
|
||||
(VOID **) &FileSystem
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = FileSystem->OpenVolume (FileSystem, &Root);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*FilePath = (EFI_DEVICE_PATH_PROTOCOL *) GetFileInfo (
|
||||
Root,
|
||||
&gAppleBlessedAlternateOsInfoGuid,
|
||||
sizeof (EFI_DEVICE_PATH_PROTOCOL),
|
||||
&FilePathSize
|
||||
);
|
||||
|
||||
if (*FilePath != NULL) {
|
||||
if (!IsDevicePathValid(*FilePath, FilePathSize)) {
|
||||
FreePool (*FilePath);
|
||||
*FilePath = NULL;
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Root->Close (Root);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
OcDescribeBootEntry (
|
||||
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
|
||||
@ -198,7 +247,13 @@ OcDescribeBootEntry (
|
||||
}
|
||||
|
||||
if (BootEntryName != NULL) {
|
||||
*BootEntryName = GetAppleDiskLabel (FileSystem, BootDirectoryName);
|
||||
//
|
||||
// Try to use APFS-style label or legacy HFS one.
|
||||
//
|
||||
*BootEntryName = GetAppleDiskLabel (FileSystem, BootDirectoryName, L".contentDetails");
|
||||
if (*BootEntryName == NULL) {
|
||||
*BootEntryName = GetAppleDiskLabel (FileSystem, BootDirectoryName, L".disk_label.contentDetails");
|
||||
}
|
||||
if (*BootEntryName == NULL) {
|
||||
*BootEntryName = GetVolumeLabel (FileSystem);
|
||||
if (*BootEntryName != NULL && !StrCmp (*BootEntryName, L"Recovery HD")) {
|
||||
@ -223,4 +278,98 @@ OcDescribeBootEntry (
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
OcScanForBootEntries (
|
||||
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
|
||||
IN UINT32 Mode,
|
||||
OUT OC_BOOT_ENTRY **BootEntries,
|
||||
OUT UINTN *Count
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN NoHandles;
|
||||
EFI_HANDLE *Handles;
|
||||
UINTN Index;
|
||||
OC_BOOT_ENTRY *Entries;
|
||||
UINTN EntryIndex;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
CHAR16 *RecoveryPath;
|
||||
VOID *Reserved;
|
||||
EFI_FILE_PROTOCOL *RecoveryRoot;
|
||||
EFI_HANDLE RecoveryDeviceHandle;
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiSimpleFileSystemProtocolGuid,
|
||||
NULL,
|
||||
&NoHandles,
|
||||
&Handles
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (NoHandles == 0) {
|
||||
FreePool (Handles);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Entries = AllocateZeroPool (NoHandles * 2 * sizeof (OC_BOOT_ENTRY));
|
||||
if (Entries == NULL) {
|
||||
FreePool (Handles);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
EntryIndex = 0;
|
||||
|
||||
for (Index = 0; Index < NoHandles; ++Index) {
|
||||
Status = BootPolicy->GetBootFileEx (
|
||||
Handles[Index],
|
||||
APPLE_BOOT_POLICY_MODE_1,
|
||||
&DevicePath
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Entries[EntryIndex].DevicePath = DevicePath;
|
||||
|
||||
++EntryIndex;
|
||||
|
||||
Status = BootPolicy->GetPathNameOnApfsRecovery (
|
||||
DevicePath,
|
||||
L"",
|
||||
&RecoveryPath,
|
||||
&Reserved,
|
||||
&RecoveryRoot,
|
||||
&RecoveryDeviceHandle
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DevicePath = FileDevicePath (RecoveryDeviceHandle, RecoveryPath);
|
||||
FreePool (RecoveryPath);
|
||||
RecoveryRoot->Close (RecoveryRoot);
|
||||
} else {
|
||||
Status = GetAlternateOsBooter (Handles[Index], &DevicePath);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Entries[EntryIndex].DevicePath = DevicePath;
|
||||
Entries[EntryIndex].PrefersDmgBoot = TRUE;
|
||||
|
||||
++EntryIndex;
|
||||
}
|
||||
|
||||
FreePool (Handles);
|
||||
|
||||
*BootEntries = Entries;
|
||||
*Count = EntryIndex;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user