Skip to content

Commit

Permalink
OpenLegacyBoot: Switch to Block I/O for legacy detection
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldfish64 committed Aug 19, 2023
1 parent ed62e4e commit c70ad78
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 151 deletions.
12 changes: 10 additions & 2 deletions Include/Acidanthera/Library/OcBootManagementLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ EFI_STATUS
typedef
EFI_STATUS
(*OC_BOOT_EXTERNAL_SYSTEM_ACTION) (
IN OUT OC_PICKER_CONTEXT *PickerContext,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
IN OUT OC_PICKER_CONTEXT *PickerContext,
IN VOID *ActionContext
);

/**
Expand All @@ -227,6 +227,10 @@ typedef struct OC_BOOT_ENTRY_ {
//
OC_BOOT_EXTERNAL_SYSTEM_ACTION ExternalSystemAction;
//
// Action to perform on execution. Only valid for external boot system entries.
//
VOID *ExternalSystemActionContext;
//
// Id under which to save entry as default.
//
CHAR16 *Id;
Expand Down Expand Up @@ -626,6 +630,10 @@ typedef struct {
// External boot system action. Boot Entry Protocol only. Optional.
//
OC_BOOT_EXTERNAL_SYSTEM_ACTION ExternalSystemAction;
//
// External boot system action context. Boot Entry Protocol only. Optional.
//
VOID *ExternalSystemActionContext;
} OC_PICKER_ENTRY;

/**
Expand Down
17 changes: 6 additions & 11 deletions Library/OcBootManagementLib/BootEntryManagement.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,16 +720,11 @@ InternalAddBootEntryFromCustomEntry (
));

if (CustomEntry->ExternalSystemAction) {
BootEntry->Type = OC_BOOT_EXTERNAL_SYSTEM;
BootEntry->ExternalSystemAction = CustomEntry->ExternalSystemAction;
BootEntry->AudioBasePath = CustomEntry->AudioBasePath;
BootEntry->AudioBaseType = CustomEntry->AudioBaseType;
BootEntry->DevicePath = DevicePathFromHandle (FileSystem->Handle);

if (BootEntry->DevicePath == NULL) {
FreeBootEntry (BootEntry);
return EFI_OUT_OF_RESOURCES;
}
BootEntry->Type = OC_BOOT_EXTERNAL_SYSTEM;
BootEntry->ExternalSystemAction = CustomEntry->ExternalSystemAction;
BootEntry->ExternalSystemActionContext = CustomEntry->ExternalSystemActionContext;
BootEntry->AudioBasePath = CustomEntry->AudioBasePath;
BootEntry->AudioBaseType = CustomEntry->AudioBaseType;
} else if (CustomEntry->SystemAction) {
BootEntry->Type = OC_BOOT_SYSTEM;
BootEntry->SystemAction = CustomEntry->SystemAction;
Expand Down Expand Up @@ -2516,7 +2511,7 @@ OcLoadBootEntry (

if ((BootEntry->Type & OC_BOOT_EXTERNAL_SYSTEM) != 0) {
ASSERT (BootEntry->ExternalSystemAction != NULL);
return BootEntry->ExternalSystemAction (Context, BootEntry->DevicePath);
return BootEntry->ExternalSystemAction (Context, BootEntry->ExternalSystemActionContext);
}

if ((BootEntry->Type & OC_BOOT_SYSTEM) != 0) {
Expand Down
7 changes: 6 additions & 1 deletion Platform/OpenLegacyBoot/LegacyBootInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ typedef enum OC_LEGACY_OS_TYPE_ {
OcLegacyOsTypeIsoLinux
} OC_LEGACY_OS_TYPE;

typedef struct {
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
} LEGACY_ENTRY_CONTEXT;

EFI_STATUS
InternalGetBiosDiskNumber (
IN THUNK_CONTEXT *ThunkContext,
Expand All @@ -58,7 +62,8 @@ InternalLoadAppleLegacyInterface (

OC_LEGACY_OS_TYPE
InternalGetPartitionLegacyOsType (
IN EFI_HANDLE PartitionHandle
IN EFI_HANDLE PartitionHandle,
IN BOOLEAN IsCdRomSupported
);

EFI_STATUS
Expand Down
108 changes: 46 additions & 62 deletions Platform/OpenLegacyBoot/LegacyBootSupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ static CONST EFI_DEVICE_PATH_PROTOCOL *AppleLegacyInterfaceMediaDevicePathPath

#define MAX_APPLE_LEGACY_DEVICE_PATHS 16

// STATIC
STATIC
BOOLEAN
CheckLegacySignature (
IN CONST CHAR8 *SignatureStr,
IN MASTER_BOOT_RECORD *Pbr
IN CONST CHAR8 *SignatureStr,
IN CONST UINT8 *Buffer,
IN CONST UINTN BufferSize
)
{
UINT32 Offset;
Expand All @@ -35,8 +36,8 @@ CheckLegacySignature (
(CONST UINT8 *)SignatureStr,
NULL,
(CONST UINT32)AsciiStrLen (SignatureStr),
Pbr->BootStrapCode,
sizeof (Pbr->BootStrapCode),
Buffer,
BufferSize,
&Offset
);
}
Expand Down Expand Up @@ -272,107 +273,90 @@ InternalLoadAppleLegacyInterface (

OC_LEGACY_OS_TYPE
InternalGetPartitionLegacyOsType (
IN EFI_HANDLE PartitionHandle
IN EFI_HANDLE PartitionHandle,
IN BOOLEAN IsCdRomSupported
)
{
EFI_STATUS Status;
MASTER_BOOT_RECORD *Mbr;
UINTN MbrSize;
OC_LEGACY_OS_TYPE LegacyOsType;

EFI_STATUS Status;
UINT8 *Buffer;
UINTN BufferSize;
MASTER_BOOT_RECORD *Mbr;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
OC_DISK_CONTEXT DiskContext;
EFI_HANDLE DiskHandle;
OC_LEGACY_OS_TYPE LegacyOsType;

ASSERT (PartitionHandle != NULL);

//
// Read MBR of whole disk.
//
DevicePath = DevicePathFromHandle (PartitionHandle);
if (DevicePath == NULL) {
return OcLegacyOsTypeNone;
}

DebugPrintDevicePath (DEBUG_INFO, "OLB: Reading MBR for disk", DevicePath);

DiskHandle = OcPartitionGetDiskHandle (DevicePath);
if (DiskHandle == NULL) {
return OcLegacyOsTypeNone;
}

Mbr = OcGetDiskMbrTable (DiskHandle, TRUE);
if (Mbr == NULL) {
DEBUG ((DEBUG_INFO, "OLB: Disk does not contain a valid MBR partition table\n"));
return OcLegacyOsTypeNone;
}

//
// For hard disk devices, get PBR sector instead.
// For CD devices, validate El-Torito structures.
// For hard disk and USB devices, validate MBR and PBR of target partition.
//
if (!OcIsDiskCdRom (DevicePath)) {
FreePool (Mbr);
if (OcIsDiskCdRom (DevicePath)) {
if (!IsCdRomSupported) {
DEBUG ((DEBUG_INFO, "OLB: CD-ROM boot not supported on this platform\n"));
return OcLegacyOsTypeNone;
}

//
// Retrieve the first sector of the partition.
//
DebugPrintDevicePath (DEBUG_INFO, "OLB: Reading PBR for partition", DevicePath);
Status = OcDiskInitializeContext (
&DiskContext,
PartitionHandle,
TRUE
);
DebugPrintDevicePath (DEBUG_INFO, "OLB: Reading El-Torito for CDROM", DevicePath);
Status = OcDiskReadElTorito (DevicePath, &Buffer, &BufferSize);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OLB: Failed reading El-Torito - %r\n", Status));
return OcLegacyOsTypeNone;
}

MbrSize = ALIGN_VALUE (sizeof (*Mbr), DiskContext.BlockSize);
Mbr = (MASTER_BOOT_RECORD *)AllocatePool (MbrSize);
} else {
DebugPrintDevicePath (DEBUG_INFO, "OLB: Reading MBR for parent disk", DevicePath);
Mbr = OcGetDiskMbrTable (DiskHandle, TRUE);
if (Mbr == NULL) {
DEBUG ((DEBUG_INFO, "OLB: Buffer allocation error\n"));
DEBUG ((DEBUG_INFO, "OLB: Disk does not contain a valid MBR\n"));
return OcLegacyOsTypeNone;
}

Status = OcDiskRead (
&DiskContext,
0,
MbrSize,
Mbr
);
if (EFI_ERROR (Status)) {
FreePool (Mbr);
FreePool (Mbr);

//
// Retrieve PBR for partition.
//
DebugPrintDevicePath (DEBUG_INFO, "OLB: Reading PBR for partition", DevicePath);
Mbr = OcGetDiskMbrTable (PartitionHandle, FALSE);
if (Mbr == NULL) {
DEBUG ((DEBUG_INFO, "OLB: Partition does not contain a valid PBR\n"));
return OcLegacyOsTypeNone;
}
}

DebugPrintHexDump (DEBUG_INFO, "OLB: MbrHEX", Mbr->BootStrapCode, sizeof (Mbr->BootStrapCode));

//
// Validate signature in MBR.
//
if (Mbr->Signature != MBR_SIGNATURE) {
FreePool (Mbr);
return OcLegacyOsTypeNone;
Buffer = (UINT8 *)Mbr;
BufferSize = sizeof (*Mbr);
}

DebugPrintHexDump (DEBUG_INFO, "OLB: PbrHEX", Buffer, BufferSize);

//
// Validate sector contents and check for known signatures
// indicating the partition is bootable.
//
if (CheckLegacySignature ("BOOTMGR", Mbr)) {
if (CheckLegacySignature ("BOOTMGR", Buffer, BufferSize)) {
LegacyOsType = OcLegacyOsTypeWindowsBootmgr;
} else if (CheckLegacySignature ("NTLDR", Mbr)) {
} else if (CheckLegacySignature ("NTLDR", Buffer, BufferSize)) {
LegacyOsType = OcLegacyOsTypeWindowsNtldr;
} else if ( CheckLegacySignature ("ISOLINUX", Mbr)
|| CheckLegacySignature ("isolinux", Mbr))
} else if ( CheckLegacySignature ("ISOLINUX", Buffer, BufferSize)
|| CheckLegacySignature ("isolinux", Buffer, BufferSize))
{
LegacyOsType = OcLegacyOsTypeIsoLinux;
} else {
LegacyOsType = OcLegacyOsTypeNone;
DEBUG ((DEBUG_INFO, "OLB: Unknown legacy bootsector signature\n"));
}

FreePool (Mbr);
FreePool (Buffer);

return LegacyOsType;
}
Expand Down Expand Up @@ -441,7 +425,7 @@ InternalLoadLegacyPbr (

Mbr = OcGetDiskMbrTable (DiskHandle, TRUE);
if (Mbr == NULL) {
DEBUG ((DEBUG_INFO, "OLB: Disk does not contain a valid MBR partition table\n"));
DEBUG ((DEBUG_INFO, "OLB: Disk does not contain a valid MBR\n"));
FreePool (Pbr);
return EFI_INVALID_PARAMETER;
}
Expand Down
Loading

0 comments on commit c70ad78

Please sign in to comment.