OcBootManagementLib: Use static functions for Boot Policy

Includes fixing an issue where generic booters were added for file systems that already had a primary booter by the use of "core" Apple Boot Policy predefined paths.
This commit is contained in:
Download-Fritz 2020-05-07 17:34:41 +02:00
parent 913fb12a3f
commit 9440cd057b
8 changed files with 67 additions and 119 deletions

View File

@ -246,10 +246,6 @@ typedef struct OC_BOOT_CONTEXT_ {
// Picker context for externally configured parameters.
//
OC_PICKER_CONTEXT *PickerContext;
//
// Boot policy protocol.
//
APPLE_BOOT_POLICY_PROTOCOL *BootPolicy;
} OC_BOOT_CONTEXT;
/**
@ -688,7 +684,6 @@ struct OC_PICKER_CONTEXT_ {
/**
Get '.disk_label' or '.disk_label_2x' file contents, if exists.
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] BootEntry Located boot entry.
@param[in] Scale User interface scale.
@param[out] ImageData File contents.
@ -699,7 +694,6 @@ struct OC_PICKER_CONTEXT_ {
EFI_STATUS
OcGetBootEntryLabelImage (
IN OC_PICKER_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_BOOT_ENTRY *BootEntry,
IN UINT8 Scale,
OUT VOID **ImageData,
@ -709,7 +703,6 @@ OcGetBootEntryLabelImage (
/**
Get '.VolumeIcon.icns' file contents, if exists.
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] BootEntry Located boot entry.
@param[out] ImageData File contents.
@param[out] DataLength File length.
@ -719,7 +712,6 @@ OcGetBootEntryLabelImage (
EFI_STATUS
OcGetBootEntryIcon (
IN OC_PICKER_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_BOOT_ENTRY *BootEntry,
OUT VOID **ImageData,
OUT UINT32 *DataLength
@ -728,15 +720,13 @@ OcGetBootEntryIcon (
/**
Scan system for boot entries.
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] Context Picker context.
@param[in] Context Picker context.
@retval boot context allocated from pool.
**/
OC_BOOT_CONTEXT *
OcScanForBootEntries (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context
IN OC_PICKER_CONTEXT *Context
);
/**
@ -744,15 +734,13 @@ OcScanForBootEntries (
This is likely to return an incomplete list and can even give NULL,
when only tools and system entries are present.
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] Context Picker context.
@param[in] Context Picker context.
@retval boot context allocated from pool.
**/
OC_BOOT_CONTEXT *
OcScanForDefaultBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context
IN OC_PICKER_CONTEXT *Context
);
/**
@ -853,7 +841,6 @@ OcShowSimpleBootMenu (
/**
Load & start boot entry loader image with given options.
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] Context Picker context.
@param[in] BootEntry Located boot entry.
@param[in] ParentHandle Parent image handle.
@ -862,10 +849,9 @@ OcShowSimpleBootMenu (
**/
EFI_STATUS
OcLoadBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *BootEntry,
IN EFI_HANDLE ParentHandle
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *BootEntry,
IN EFI_HANDLE ParentHandle
);
/**

View File

@ -335,7 +335,6 @@ InternalGetRecoveryOsBooter (
EFI_STATUS
OcGetBootEntryLabelImage (
IN OC_PICKER_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_BOOT_ENTRY *BootEntry,
IN UINT8 Scale,
OUT VOID **ImageData,
@ -345,7 +344,6 @@ OcGetBootEntryLabelImage (
EFI_STATUS Status;
CHAR16 *BootDirectoryName;
EFI_HANDLE Device;
EFI_HANDLE ApfsVolumeHandle;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
*ImageData = NULL;
@ -370,11 +368,10 @@ OcGetBootEntryLabelImage (
ASSERT (BootEntry->DevicePath != NULL);
Status = BootPolicy->DevicePathToDirPath (
Status = OcBootPolicyDevicePathToDirPath (
BootEntry->DevicePath,
&BootDirectoryName,
&Device,
&ApfsVolumeHandle
&Device
);
if (EFI_ERROR (Status)) {
@ -409,7 +406,6 @@ OcGetBootEntryLabelImage (
EFI_STATUS
OcGetBootEntryIcon (
IN OC_PICKER_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_BOOT_ENTRY *BootEntry,
OUT VOID **ImageData,
OUT UINT32 *DataLength
@ -418,7 +414,6 @@ OcGetBootEntryIcon (
EFI_STATUS Status;
CHAR16 *BootDirectoryName;
EFI_HANDLE Device;
EFI_HANDLE ApfsVolumeHandle;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
*ImageData = NULL;
@ -443,11 +438,10 @@ OcGetBootEntryIcon (
ASSERT (BootEntry->DevicePath != NULL);
Status = BootPolicy->DevicePathToDirPath (
Status = OcBootPolicyDevicePathToDirPath (
BootEntry->DevicePath,
&BootDirectoryName,
&Device,
&ApfsVolumeHandle
&Device
);
if (EFI_ERROR (Status)) {
@ -482,15 +476,13 @@ OcGetBootEntryIcon (
EFI_STATUS
InternalDescribeBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OUT OC_BOOT_ENTRY *BootEntry
IN OUT OC_BOOT_ENTRY *BootEntry
)
{
EFI_STATUS Status;
CHAR16 *BootDirectoryName;
CHAR16 *RecoveryBootName;
EFI_HANDLE Device;
EFI_HANDLE ApfsVolumeHandle;
UINT32 BcdSize;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
@ -501,11 +493,10 @@ InternalDescribeBootEntry (
return EFI_SUCCESS;
}
Status = BootPolicy->DevicePathToDirPath (
Status = OcBootPolicyDevicePathToDirPath (
BootEntry->DevicePath,
&BootDirectoryName,
&Device,
&ApfsVolumeHandle
&Device
);
if (EFI_ERROR (Status)) {

View File

@ -433,10 +433,7 @@ AddBootEntryOnFileSystem (
BootEntry->IsFolder = IsFolder;
BootEntry->IsExternal = RecoveryPart ? FileSystem->RecoveryFs->External : FileSystem->External;
Status = InternalDescribeBootEntry (
BootContext->BootPolicy,
BootEntry
);
Status = InternalDescribeBootEntry (BootEntry);
if (EFI_ERROR (Status)) {
FreePool (BootEntry);
return Status;
@ -624,10 +621,12 @@ AddBootEntryFromSystemEntry (
This function may create more than one entry, and for APFS
it will likely produce a sequence of 'OS, RECOVERY' entry pairs.
@param[in,out] BootContext Context of filesystems.
@param[in,out] FileSystem Filesystem to scan for bless.
@param[in] LazyScan Lazy filesystem scanning.
@param[in] Deduplicate Ensure that duplicated entries are not added.
@param[in,out] BootContext Context of filesystems.
@param[in,out] FileSystem Filesystem to scan for bless.
@param[in] PredefinedPaths The predefined boot file locations to scan.
@param[in] NumPredefinedPaths The number of elements in PredefinedPaths.
@param[in] LazyScan Lazy filesystem scanning.
@param[in] Deduplicate Ensure that duplicated entries are not added.
@retval EFI_STATUS for last created option.
**/
@ -636,6 +635,8 @@ EFI_STATUS
AddBootEntryFromBless (
IN OUT OC_BOOT_CONTEXT *BootContext,
IN OUT OC_BOOT_FILESYSTEM *FileSystem,
IN CONST CHAR16 **PredefinedPaths,
IN UINTN NumPredefinedPaths,
IN BOOLEAN LazyScan,
IN BOOLEAN Deduplicate
)
@ -652,7 +653,6 @@ AddBootEntryFromBless (
INTN CmpResult;
EFI_FILE_PROTOCOL *Root;
CHAR16 *RecoveryPath;
VOID *Reserved;
EFI_FILE_PROTOCOL *RecoveryRoot;
EFI_HANDLE RecoveryDeviceHandle;
@ -706,9 +706,10 @@ AddBootEntryFromBless (
// On failure obtain normal bless paths.
//
if (EFI_ERROR (Status)) {
Status = BootContext->BootPolicy->GetBootFileEx (
Status = OcBootPolicyGetBootFileEx (
FileSystem->Handle,
BootPolicyOk,
PredefinedPaths,
NumPredefinedPaths,
&DevicePath
);
}
@ -803,11 +804,12 @@ AddBootEntryFromBless (
//
// Now add APFS recovery (from Recovery partition) right afterwards if present.
//
Status = BootContext->BootPolicy->GetApfsRecoveryFilePath (
Status = OcBootPolicyGetApfsRecoveryFilePath (
NewDevicePath,
L"\\",
PredefinedPaths,
NumPredefinedPaths,
&RecoveryPath,
&Reserved,
&RecoveryRoot,
&RecoveryDeviceHandle
);
@ -1161,10 +1163,15 @@ AddBootEntryFromBootOption (
// - Recovery for this macOS.
// - Another macOS installation.
// We can only detect them with bless, so we invoke bless in deduplication mode.
// We also detect only the Core Apple Boot Policy predefined booter paths to
// avoid detection of e.g. generic booters (such as BOOTx64) to avoid
// duplicates.
//
Status = AddBootEntryFromBless (
BootContext,
FileSystem,
gAppleBootPolicyPredefinedPaths,
gAppleBootPolicyCoreNumPredefinedPaths,
LazyScan,
TRUE
);
@ -1420,9 +1427,8 @@ InternalFileSystemForHandle (
STATIC
OC_BOOT_CONTEXT *
BuildFileSystemList (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context,
IN BOOLEAN Empty
IN OC_PICKER_CONTEXT *Context,
IN BOOLEAN Empty
)
{
OC_BOOT_CONTEXT *BootContext;
@ -1446,7 +1452,6 @@ BuildFileSystemList (
}
BootContext->DefaultEntry = NULL;
BootContext->PickerContext = Context;
BootContext->BootPolicy = BootPolicy;
if (Empty) {
return BootContext;
@ -1494,8 +1499,7 @@ OcFreeBootContext (
OC_BOOT_CONTEXT *
OcScanForBootEntries (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context
IN OC_PICKER_CONTEXT *Context
)
{
OC_BOOT_CONTEXT *BootContext;
@ -1507,7 +1511,6 @@ OcScanForBootEntries (
// Obtain the list of filesystems filtered by scan policy.
//
BootContext = BuildFileSystemList (
BootPolicy,
Context,
FALSE
);
@ -1549,7 +1552,14 @@ OcScanForBootEntries (
// No entries, so we process this directory with Apple Bless.
//
if (IsListEmpty (&FileSystem->BootEntries)) {
AddBootEntryFromBless (BootContext, FileSystem, FALSE, FALSE);
AddBootEntryFromBless (
BootContext,
FileSystem,
gAppleBootPolicyPredefinedPaths,
gAppleBootPolicyNumPredefinedPaths,
FALSE,
FALSE
);
}
//
@ -1573,8 +1583,7 @@ OcScanForBootEntries (
OC_BOOT_CONTEXT *
OcScanForDefaultBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context
IN OC_PICKER_CONTEXT *Context
)
{
OC_BOOT_CONTEXT *BootContext;
@ -1587,11 +1596,7 @@ OcScanForDefaultBootEntry (
//
// Obtain empty list of filesystems.
//
BootContext = BuildFileSystemList (
BootPolicy,
Context,
TRUE
);
BootContext = BuildFileSystemList (Context, TRUE);
if (BootContext == NULL) {
return NULL;
}
@ -1653,7 +1658,14 @@ OcScanForDefaultBootEntry (
continue;
}
AddBootEntryFromBless (BootContext, FileSystem, FALSE, FALSE);
AddBootEntryFromBless (
BootContext,
FileSystem,
gAppleBootPolicyPredefinedPaths,
gAppleBootPolicyNumPredefinedPaths,
FALSE,
FALSE
);
if (BootContext->DefaultEntry != NULL) {
FreePool (Handles);
return BootContext;
@ -1727,10 +1739,9 @@ OcEnumerateEntries (
EFI_STATUS
OcLoadBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *BootEntry,
IN EFI_HANDLE ParentHandle
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *BootEntry,
IN EFI_HANDLE ParentHandle
)
{
EFI_STATUS Status;
@ -1743,7 +1754,6 @@ OcLoadBootEntry (
}
Status = InternalLoadBootEntry (
BootPolicy,
Context,
BootEntry,
ParentHandle,

View File

@ -52,7 +52,6 @@ InternalCheckScanPolicy (
EFI_DEVICE_PATH_PROTOCOL *
InternalLoadDmg (
IN OUT INTERNAL_DMG_LOAD_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN UINT32 Policy
);
@ -92,7 +91,6 @@ InternalGetRecoveryOsBooter (
EFI_STATUS
InternalLoadBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *BootEntry,
IN EFI_HANDLE ParentHandle,
@ -136,15 +134,13 @@ InternalGetBootOptionData (
/**
Describe boot entry contents by setting fields other than DevicePath.
@param[in] BootPolicy Apple Boot Policy Protocol.
@param[in] BootEntry Located boot entry.
@param[in] BootEntry Located boot entry.
@retval EFI_SUCCESS The entry point is described successfully.
**/
EFI_STATUS
InternalDescribeBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OUT OC_BOOT_ENTRY *BootEntry
IN OUT OC_BOOT_ENTRY *BootEntry
);
BOOLEAN

View File

@ -941,7 +941,6 @@ OcRegisterBootOption (
EFI_STATUS
InternalLoadBootEntry (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *BootEntry,
IN EFI_HANDLE ParentHandle,
@ -961,7 +960,6 @@ InternalLoadBootEntry (
CONST CHAR8 *Args;
UINT32 ArgsLen;
ASSERT (BootPolicy != NULL);
ASSERT (BootEntry != NULL);
//
// System entries are not loaded but called directly.
@ -987,11 +985,7 @@ InternalLoadBootEntry (
}
DmgLoadContext->DevicePath = BootEntry->DevicePath;
DevicePath = InternalLoadDmg (
DmgLoadContext,
BootPolicy,
Context->LoadPolicy
);
DevicePath = InternalLoadDmg (DmgLoadContext, Context->LoadPolicy);
if (DevicePath == NULL) {
return EFI_UNSUPPORTED;
}

View File

@ -31,7 +31,6 @@
STATIC
EFI_DEVICE_PATH_PROTOCOL *
InternalGetFirstDeviceBootFilePath (
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN CONST EFI_DEVICE_PATH_PROTOCOL *DmgDevicePath,
IN UINTN DmgDevicePathSize
)
@ -48,7 +47,6 @@ InternalGetFirstDeviceBootFilePath (
EFI_HANDLE *HandleBuffer;
UINTN Index;
ASSERT (BootPolicy != NULL);
ASSERT (DmgDevicePath != NULL);
ASSERT (DmgDevicePathSize >= END_DEVICE_PATH_LENGTH);
@ -90,9 +88,10 @@ InternalGetFirstDeviceBootFilePath (
continue;
}
Status = BootPolicy->GetBootFileEx (
Status = OcBootPolicyGetBootFileEx (
HandleBuffer[Index],
BootPolicyOk,
gAppleBootPolicyPredefinedPaths,
gAppleBootPolicyNumPredefinedPaths,
&BootDevicePath
);
if (!EFI_ERROR (Status)) {
@ -111,7 +110,6 @@ STATIC
EFI_DEVICE_PATH_PROTOCOL *
InternalGetDiskImageBootFile (
OUT INTERNAL_DMG_LOAD_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN UINT32 Policy,
IN UINTN DmgFileSize,
IN VOID *ChunklistBuffer OPTIONAL,
@ -127,7 +125,6 @@ InternalGetDiskImageBootFile (
UINTN DmgDevicePathSize;
ASSERT (Context != NULL);
ASSERT (BootPolicy != NULL);
ASSERT (DmgFileSize > 0);
if (ChunklistBuffer == NULL) {
@ -202,7 +199,6 @@ InternalGetDiskImageBootFile (
}
DevPath = InternalGetFirstDeviceBootFilePath (
BootPolicy,
DmgDevicePath,
DmgDevicePathSize
);
@ -319,7 +315,6 @@ InternalFindDmgChunklist (
EFI_DEVICE_PATH_PROTOCOL *
InternalLoadDmg (
IN OUT INTERNAL_DMG_LOAD_CONTEXT *Context,
IN APPLE_BOOT_POLICY_PROTOCOL *BootPolicy,
IN UINT32 Policy
)
{
@ -343,7 +338,6 @@ InternalLoadDmg (
CHAR16 *DevPathText;
ASSERT (Context != NULL);
ASSERT (BootPolicy != NULL);
DevPath = Context->DevicePath;
Status = OcOpenFileByDevicePath (
@ -472,7 +466,6 @@ InternalLoadDmg (
DevPath = InternalGetDiskImageBootFile (
Context,
BootPolicy,
Policy,
DmgFileSize,
ChunklistBuffer,

View File

@ -501,7 +501,6 @@ OcRunBootPicker (
)
{
EFI_STATUS Status;
APPLE_BOOT_POLICY_PROTOCOL *AppleBootPolicy;
APPLE_KEY_MAP_AGGREGATOR_PROTOCOL *KeyMap;
OC_BOOT_CONTEXT *BootContext;
OC_BOOT_ENTRY *Chosen;
@ -517,12 +516,6 @@ OcRunBootPicker (
return InternalSystemActionResetNvram ();
}
AppleBootPolicy = OcAppleBootPolicyInstallProtocol (FALSE);
if (AppleBootPolicy == NULL) {
DEBUG ((DEBUG_ERROR, "OCB: AppleBootPolicy locate failure\n"));
return EFI_NOT_FOUND;
}
KeyMap = OcAppleKeyMapInstallProtocols (FALSE);
if (KeyMap == NULL) {
DEBUG ((DEBUG_ERROR, "OCB: AppleKeyMap locate failure\n"));
@ -565,10 +558,7 @@ OcRunBootPicker (
// Turbo-boost scanning when bypassing picker.
//
if (Context->PickerCommand == OcPickerDefault) {
BootContext = OcScanForDefaultBootEntry (
AppleBootPolicy,
Context
);
BootContext = OcScanForDefaultBootEntry (Context);
} else {
ASSERT (
Context->PickerCommand == OcPickerShowPicker
@ -576,10 +566,7 @@ OcRunBootPicker (
|| Context->PickerCommand == OcPickerBootAppleRecovery
);
BootContext = OcScanForBootEntries (
AppleBootPolicy,
Context
);
BootContext = OcScanForBootEntries (Context);
}
//
@ -680,7 +667,6 @@ OcRunBootPicker (
}
Status = OcLoadBootEntry (
AppleBootPolicy,
Context,
Chosen,
gImageHandle

View File

@ -729,7 +729,6 @@ BootPickerEntriesAdd (
IN BOOLEAN Default
)
{
APPLE_BOOT_POLICY_PROTOCOL *AppleBootPolicy;
EFI_STATUS Status;
GUI_VOLUME_ENTRY *VolumeEntry;
CONST GUI_IMAGE *SuggestedIcon;
@ -758,16 +757,9 @@ BootPickerEntriesAdd (
return EFI_OUT_OF_RESOURCES;
}
AppleBootPolicy = OcAppleBootPolicyInstallProtocol (FALSE);
if (AppleBootPolicy == NULL) {
DEBUG ((DEBUG_ERROR, "OCUI: AppleBootPolicy locate failure\n"));
return EFI_NOT_FOUND;
}
if (UseDiskLabel) {
Status = OcGetBootEntryLabelImage (
Context,
AppleBootPolicy,
Entry,
GuiContext->Scale,
&IconFileData,
@ -841,7 +833,7 @@ BootPickerEntriesAdd (
VolumeEntry->Context = Entry;
if (UseVolumeIcon) {
Status = OcGetBootEntryIcon (Context, AppleBootPolicy, Entry, &IconFileData, &IconFileSize);
Status = OcGetBootEntryIcon (Context, Entry, &IconFileData, &IconFileSize);
if (!EFI_ERROR (Status)) {
Status = GuiIcnsToImageIcon (