X-Git-Url: https://code.delx.au/refind/blobdiff_plain/86279b212c60cebaee4296d1b7848dd5514e4b56..c63e9bd427f945b881d337b9fd5d3ff8612f103f:/refind/legacy.c diff --git a/refind/legacy.c b/refind/legacy.c index be79259..aead421 100644 --- a/refind/legacy.c +++ b/refind/legacy.c @@ -37,10 +37,23 @@ * Modifications copyright (c) 2012-2015 Roderick W. Smith * * Modifications distributed under the terms of the GNU General Public - * License (GPL) version 3 (GPLv3), a copy of which must be distributed - * with this source code or binaries made from it. + * License (GPL) version 3 (GPLv3), or (at your option) any later version. * */ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ #include "global.h" #include "icns.h" @@ -50,12 +63,19 @@ #include "refit_call_wrapper.h" #include "screen.h" #include "syslinux_mbr.h" +#include "mystrings.h" #include "../EfiLib/BdsHelper.h" #include "../EfiLib/legacy.h" +#include "Handle.h" extern REFIT_MENU_ENTRY MenuEntryReturn; extern REFIT_MENU_SCREEN MainMenu; +#ifndef __MAKEWITH_GNUEFI +#define LibLocateHandle gBS->LocateHandleBuffer +#define DevicePathProtocol gEfiDevicePathProtocolGuid +#endif + static EFI_STATUS ActivateMbrPartition(IN EFI_BLOCK_IO *BlockIO, IN UINTN PartitionIndex) { EFI_STATUS Status; @@ -153,7 +173,7 @@ static EFI_STATUS ActivateMbrPartition(IN EFI_BLOCK_IO *BlockIO, IN UINTN Partit return EFI_SUCCESS; } /* static EFI_STATUS ActivateMbrPartition() */ -static EFI_GUID AppleVariableVendorID = { 0x7C436110, 0xAB2A, 0x4BBB, 0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82 }; +static EFI_GUID AppleVariableVendorID = { 0x7C436110, 0xAB2A, 0x4BBB, { 0xA8, 0x80, 0xFE, 0x41, 0x99, 0x5C, 0x9F, 0x82 } }; static EFI_STATUS WriteBootDiskHint(IN EFI_DEVICE_PATH *WholeDiskDevicePath) { @@ -168,6 +188,82 @@ static EFI_STATUS WriteBootDiskHint(IN EFI_DEVICE_PATH *WholeDiskDevicePath) return EFI_SUCCESS; } +// +// firmware device path discovery +// + +static UINT8 LegacyLoaderMediaPathData[] = { + 0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B, + 0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B, + 0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00, +}; +static EFI_DEVICE_PATH *LegacyLoaderMediaPath = (EFI_DEVICE_PATH *)LegacyLoaderMediaPathData; + +static VOID ExtractLegacyLoaderPaths(EFI_DEVICE_PATH **PathList, UINTN MaxPaths, EFI_DEVICE_PATH **HardcodedPathList) +{ + EFI_STATUS Status; + UINTN HandleCount = 0; + UINTN HandleIndex, HardcodedIndex; + EFI_HANDLE *Handles; + EFI_HANDLE Handle; + UINTN PathCount = 0; + UINTN PathIndex; + EFI_LOADED_IMAGE *LoadedImage; + EFI_DEVICE_PATH *DevicePath; + BOOLEAN Seen; + + MaxPaths--; // leave space for the terminating NULL pointer + + // get all LoadedImage handles + Status = LibLocateHandle(ByProtocol, &LoadedImageProtocol, NULL, &HandleCount, &Handles); + if (CheckError(Status, L"while listing LoadedImage handles")) { + if (HardcodedPathList) { + for (HardcodedIndex = 0; HardcodedPathList[HardcodedIndex] && PathCount < MaxPaths; HardcodedIndex++) + PathList[PathCount++] = HardcodedPathList[HardcodedIndex]; + } + PathList[PathCount] = NULL; + return; + } + for (HandleIndex = 0; HandleIndex < HandleCount && PathCount < MaxPaths; HandleIndex++) { + Handle = Handles[HandleIndex]; + + Status = refit_call3_wrapper(BS->HandleProtocol, Handle, &LoadedImageProtocol, (VOID **) &LoadedImage); + if (EFI_ERROR(Status)) + continue; // This can only happen if the firmware scewed up, ignore it. + + Status = refit_call3_wrapper(BS->HandleProtocol, LoadedImage->DeviceHandle, &DevicePathProtocol, (VOID **) &DevicePath); + if (EFI_ERROR(Status)) + continue; // This happens, ignore it. + + // Only grab memory range nodes + if (DevicePathType(DevicePath) != HARDWARE_DEVICE_PATH || DevicePathSubType(DevicePath) != HW_MEMMAP_DP) + continue; + + // Check if we have this device path in the list already + // WARNING: This assumes the first node in the device path is unique! + Seen = FALSE; + for (PathIndex = 0; PathIndex < PathCount; PathIndex++) { + if (DevicePathNodeLength(DevicePath) != DevicePathNodeLength(PathList[PathIndex])) + continue; + if (CompareMem(DevicePath, PathList[PathIndex], DevicePathNodeLength(DevicePath)) == 0) { + Seen = TRUE; + break; + } + } + if (Seen) + continue; + + PathList[PathCount++] = AppendDevicePath(DevicePath, LegacyLoaderMediaPath); + } + MyFreePool(Handles); + + if (HardcodedPathList) { + for (HardcodedIndex = 0; HardcodedPathList[HardcodedIndex] && PathCount < MaxPaths; HardcodedIndex++) + PathList[PathCount++] = HardcodedPathList[HardcodedIndex]; + } + PathList[PathCount] = NULL; +} /* VOID ExtractLegacyLoaderPaths() */ + // early 2006 Core Duo / Core Solo models static UINT8 LegacyLoaderDevicePath1Data[] = { 0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,