mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcBootManagementLib: Implement FAT image loading
This commit is contained in:
parent
17e99ea36b
commit
40f81f29f7
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
249
Library/OcBootManagementLib/ImageLoader.c
Normal file
249
Library/OcBootManagementLib/ImageLoader.c
Normal 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;
|
||||
}
|
||||
@ -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.
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
DefaultEntryChoice.c
|
||||
DmgBootSupport.c
|
||||
HotKeySupport.c
|
||||
ImageLoader.c
|
||||
PolicyManagement.c
|
||||
OcBootManagementLib.c
|
||||
VariableManagement.c
|
||||
|
||||
@ -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.
|
||||
//
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user