OcBootManagementLib: Implement FAT image loading

This commit is contained in:
vit9696 2020-08-17 01:43:19 +03:00
parent 17e99ea36b
commit 40f81f29f7
7 changed files with 271 additions and 3 deletions

View File

@ -14,6 +14,9 @@ OpenCore Changelog
- Reduced OpenCanopy size by restricting boot management access
- Added `BuiltinText` variant for `TextRenderer` for older laptops
- Fixed `SyncRuntimePermissions` creating invalid MAT table
- Added EFI FAT image loading support (macOS 10.8 and earlier)
- Added cacheless kext injection support (macOS 10.9 and earlier)
- Added mkext kext injection support (macOS 10.6 and earlier)
#### v0.6.0
- Fixed sound corruption with AudioDxe

View File

@ -176,4 +176,14 @@ InternalSystemActionResetNvram (
VOID
);
/**
Initialises custom gBS->LoadImage override.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
InternalInitImageLoader (
VOID
);
#endif // BOOT_MANAGEMENET_INTERNAL_H

View File

@ -0,0 +1,249 @@
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BootManagementInternal.h"
#include <Protocol/DevicePath.h>
#include <Protocol/SimpleFileSystem.h>
#include <Guid/AppleVariable.h>
#include <Guid/FileInfo.h>
#include <Guid/GlobalVariable.h>
#include <Guid/OcVariable.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/OcDebugLogLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcDevicePathLib.h>
#include <Library/OcFileLib.h>
#include <Library/OcMachoLib.h>
#include <Library/OcStringLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/PrintLib.h>
STATIC EFI_IMAGE_LOAD mOriginalEfiLoadImage;
STATIC
EFI_STATUS
InternalEfiLoadImageFile (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT UINTN *FileSize,
OUT VOID **FileBuffer
)
{
EFI_STATUS Status;
EFI_FILE_PROTOCOL *File;
VOID *Buffer;
UINT32 Size;
Status = OcOpenFileByDevicePath (
&DevicePath,
&File,
EFI_FILE_MODE_READ,
0
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
Status = GetFileSize (
File,
&Size
);
if (EFI_ERROR (Status) || Size == 0) {
File->Close (File);
return EFI_UNSUPPORTED;
}
Buffer = AllocatePool (Size);
if (Buffer == NULL) {
File->Close (File);
return EFI_OUT_OF_RESOURCES;
}
Status = GetFileData (
File,
0,
Size,
Buffer
);
if (EFI_ERROR (Status)) {
FreePool (Buffer);
File->Close (File);
return EFI_DEVICE_ERROR;
}
*FileBuffer = Buffer;
*FileSize = Size;
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
InternalEfiLoadImageProtocol (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN BOOLEAN UseLoadImage2,
OUT UINTN *FileSize,
OUT VOID **FileBuffer
)
{
//
// TODO: Implement image load protocol if necessary.
//
return EFI_UNSUPPORTED;
}
STATIC
EFI_STATUS
InternalUpdateLoadedImage (
IN EFI_HANDLE ImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_STATUS Status;
EFI_HANDLE DeviceHandle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
Status = gBS->HandleProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &LoadedImage
);
if (EFI_ERROR (Status)) {
return Status;
}
RemainingDevicePath = DevicePath;
Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &RemainingDevicePath, &DeviceHandle);
if (EFI_ERROR (Status)) {
//
// TODO: Handle load protocol if necessary.
//
return Status;
}
if (LoadedImage->DeviceHandle != DeviceHandle) {
LoadedImage->DeviceHandle = DeviceHandle;
LoadedImage->FilePath = DuplicateDevicePath (RemainingDevicePath);
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EFIAPI
InternalEfiLoadImage (
IN BOOLEAN BootPolicy,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
OUT EFI_HANDLE *ImageHandle
)
{
EFI_STATUS Status;
VOID *AllocatedBuffer;
UINT32 RealSize;
if (ParentImageHandle == NULL || ImageHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
if (SourceBuffer == NULL && DevicePath == NULL) {
return EFI_NOT_FOUND;
}
if (SourceBuffer != NULL && SourceSize == 0) {
return EFI_UNSUPPORTED;
}
AllocatedBuffer = NULL;
if (SourceBuffer == NULL) {
Status = InternalEfiLoadImageFile (
DevicePath,
&SourceSize,
&SourceBuffer
);
if (EFI_ERROR (Status)) {
Status = InternalEfiLoadImageProtocol (
DevicePath,
BootPolicy == FALSE,
&SourceSize,
&SourceBuffer
);
}
if (!EFI_ERROR (Status)) {
AllocatedBuffer = SourceBuffer;
}
}
if (SourceBuffer != NULL) {
RealSize = (UINT32) SourceSize;
#ifdef MDE_CPU_IA32
Status = FatFilterArchitecture32 ((UINT8 **) &SourceBuffer, &RealSize);
#else
Status = FatFilterArchitecture64 ((UINT8 **) &SourceBuffer, &RealSize);
#endif
if (!EFI_ERROR (Status)) {
SourceSize = RealSize;
} else if (AllocatedBuffer != NULL) {
SourceBuffer = NULL;
SourceSize = 0;
}
}
Status = mOriginalEfiLoadImage (
BootPolicy,
ParentImageHandle,
DevicePath,
SourceBuffer,
SourceSize,
ImageHandle
);
if (AllocatedBuffer != NULL) {
FreePool (AllocatedBuffer);
}
//
// Some firmwares may not update loaded image protocol fields correctly
// when loading via source buffer. Do it here.
//
if (!EFI_ERROR (Status) && SourceBuffer != NULL && DevicePath != NULL) {
InternalUpdateLoadedImage (*ImageHandle, DevicePath);
}
return Status;
}
EFI_STATUS
InternalInitImageLoader (
VOID
)
{
mOriginalEfiLoadImage = gBS->LoadImage;
gBS->LoadImage = InternalEfiLoadImage;
gBS->Hdr.CRC32 = 0;
gBS->CalculateCrc32 (gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);
return EFI_SUCCESS;
}

View File

@ -508,6 +508,11 @@ OcRunBootPicker (
SaidWelcome = FALSE;
Status = InternalInitImageLoader ();
if (EFI_ERROR (Status)) {
return Status;
}
//
// Reset NVRAM right away if requested by a key combination.
// This function should not return under normal conditions.

View File

@ -41,6 +41,7 @@
DefaultEntryChoice.c
DmgBootSupport.c
HotKeySupport.c
ImageLoader.c
PolicyManagement.c
OcBootManagementLib.c
VariableManagement.c

View File

@ -55,7 +55,8 @@ FatGetArchitectureOffset (
FatHeader = (MACH_FAT_HEADER*) Buffer;
if (FatHeader->Signature != MACH_FAT_BINARY_INVERT_SIGNATURE
&& FatHeader->Signature != MACH_FAT_BINARY_SIGNATURE) {
&& FatHeader->Signature != MACH_FAT_BINARY_SIGNATURE
&& FatHeader->Signature != EFI_FAT_BINARY_SIGNATURE) {
//
// Non-fat binary.
//

View File

@ -12,8 +12,7 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <DebugLib.h>
#include <Library/DebugLib.h>
#include <Library/OcTemplateLib.h>
#include <Library/OcSerializeLib.h>
#include <Library/OcMiscLib.h>