diff --git a/Include/Library/OcBootManagementLib.h b/Include/Library/OcBootManagementLib.h index 53ade500..97c3af63 100755 --- a/Include/Library/OcBootManagementLib.h +++ b/Include/Library/OcBootManagementLib.h @@ -17,6 +17,8 @@ #include +#include + /** Discovered boot entry. Note, inner resources must be freed with OcResetBootEntry. @@ -509,4 +511,16 @@ OcGetFileSystemPolicyType ( IN EFI_HANDLE Handle ); +/** + Get loaded image protocol for Apple bootloader. + + @param[in] Handle Image handle. + + @retval loaded image protocol or NULL for non Apple images. +**/ +EFI_LOADED_IMAGE_PROTOCOL * +OcGetAppleBootLoadedImage ( + IN EFI_HANDLE ImageHandle + ); + #endif // OC_BOOT_MANAGEMENT_LIB_H diff --git a/Library/OcBootManagementLib/PolicyManagement.c b/Library/OcBootManagementLib/PolicyManagement.c index f14dd8d8..0018a52a 100644 --- a/Library/OcBootManagementLib/PolicyManagement.c +++ b/Library/OcBootManagementLib/PolicyManagement.c @@ -27,12 +27,15 @@ #include #include #include +#include #include #include #include #include +#include #include +#include #include #include #include @@ -179,3 +182,45 @@ InternalCheckScanPolicy ( return RETURN_SUCCESS; } + +EFI_LOADED_IMAGE_PROTOCOL * +OcGetAppleBootLoadedImage ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *CurrNode; + FILEPATH_DEVICE_PATH *LastNode; + BOOLEAN IsMacOS; + UINTN PathLen; + UINTN Index; + + IsMacOS = FALSE; + + Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage); + + if (!EFI_ERROR (Status) && LoadedImage->FilePath) { + LastNode = NULL; + + for (CurrNode = LoadedImage->FilePath; !IsDevicePathEnd (CurrNode); CurrNode = NextDevicePathNode (CurrNode)) { + if (DevicePathType (CurrNode) == MEDIA_DEVICE_PATH && DevicePathSubType (CurrNode) == MEDIA_FILEPATH_DP) { + LastNode = (FILEPATH_DEVICE_PATH *) CurrNode; + } + } + + if (LastNode != NULL) { + // + // Detect macOS by boot.efi in the bootloader name. + // + PathLen = OcFileDevicePathNameLen (LastNode); + if (PathLen >= L_STR_LEN ("boot.efi")) { + Index = PathLen - L_STR_LEN ("boot.efi"); + IsMacOS = (Index == 0 || LastNode->PathName[Index - 1] == L'\\') + && CompareMem (&LastNode->PathName[Index], L"boot.efi", L_STR_SIZE (L"boot.efi")) == 0; + } + } + } + + return IsMacOS ? LoadedImage : NULL; +}