#include "lib.h"
#include "icns.h"
#include "menu.h"
-#include "mok2.h"
+#include "mok.h"
#include "../include/Handle.h"
#include "../include/refit_call_wrapper.h"
#include "driver_support.h"
#define DRIVER_DIRS L"drivers"
#endif
-#define MOK_NAMES L"\\EFI\\tools\\MokManager.efi,\\EFI\\redhat\\MokManager.efi"
+#define MOK_NAMES L"\\EFI\\tools\\MokManager.efi,\\EFI\\redhat\\MokManager.efi,\\EFI\\ubuntu\\MokManager.efi,\\EFI\\suse\\MokManager"
// Filename patterns that identify EFI boot loaders. Note that a single case (either L"*.efi" or
// L"*.EFI") is fine for most systems; but Gigabyte's buggy Hybrid EFI does a case-sensitive
static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL };
REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
{TAG_SHELL, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
// Structure used to hold boot loader filenames and time stamps in
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.7.7");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.4.7.12");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
#if defined(EFI32)
AddMenuInfoLine(&AboutMenu, L" Platform: x86 (32 bit)");
#elif defined(EFIX64)
- AddMenuInfoLine(&AboutMenu, L" Platform: x86_64 (64 bit)");
+ TempStr = AllocateZeroPool(256 * sizeof(CHAR16));
+ SPrint(TempStr, 255, L" Platform: x86_64 (64 bit); Secure Boot %s", secure_mode() ? L"active" : L"inactive");
+ AddMenuInfoLine(&AboutMenu, TempStr);
#else
AddMenuInfoLine(&AboutMenu, L" Platform: unknown");
#endif
RunMenu(&AboutMenu, NULL);
} /* VOID AboutrEFInd() */
+// Launch an EFI binary.
static EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
IN CHAR16 *LoadOptions, IN CHAR16 *LoadOptionsPrefix,
IN CHAR16 *ImageTitle, IN CHAR8 OSType,
if (Verbose)
Print(L"Starting %s\nUsing load options '%s'\n", ImageTitle, FullLoadOptions);
- // load the image into memory (and execute it, in the case of a MOK image).
+ // load the image into memory (and execute it, in the case of a shim/MOK image).
ReturnStatus = Status = EFI_NOT_FOUND; // in case the list is empty
for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) {
- ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
- NULL, 0, &ChildImageHandle);
+ // NOTE: Below commented-out line could be more efficient if the ReadFile() and
+ // FindVolumeAndFilename() calls were moved earlier, but it doesn't work on my
+ // 32-bit Mac Mini or my 64-bit Intel box when launching a Linux kernel; the
+ // kernel returns a "Failed to handle fs_proto" error message.
+ // TODO: Track down the cause of this error and fix it, if possible.
// ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
// ImageData, ImageSize, &ChildImageHandle);
- // TODO: Commented-out version above is more efficient if the below FindVolumeAndFilename()
- // and ReadFile() calls (and surrounding logic) are moved earlier; however, this causes
- // some computers, including my 32-bit Mac Mini and 64-bit Intel machine, to fail when
- // launching a Linux kernel, with a "Failed to handle fs_proto" error message from the
- // kernel. Find out what's causing this and fix it.
- if (ReturnStatus == EFI_ACCESS_DENIED) {
- // TODO: I originally had the next few lines a
+ ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
+ NULL, 0, &ChildImageHandle);
+ if ((Status == EFI_ACCESS_DENIED) && (ShimLoaded())) {
FindVolumeAndFilename(DevicePaths[DevicePathIndex], &DeviceVolume, &loader);
if (DeviceVolume != NULL) {
Status = ReadFile(DeviceVolume->RootDir, loader, &File, &ImageSize);
Status = EFI_NOT_FOUND;
Print(L"Error: device volume not found!\n");
} // if/else
- ReturnStatus = Status = start_image(SelfImageHandle, loader, ImageData, ImageSize, FullLoadOptions, DeviceVolume);
+ if (Status != EFI_NOT_FOUND) {
+ ReturnStatus = Status = start_image(SelfImageHandle, loader, ImageData, ImageSize, FullLoadOptions,
+ DeviceVolume, FileDevicePath(DeviceVolume->DeviceHandle, loader));
+// ReturnStatus = Status = start_image(SelfImageHandle, loader, ImageData, ImageSize, FullLoadOptions,
+// DeviceVolume, DevicePaths[DevicePathIndex]);
+ }
if (ReturnStatus == EFI_SUCCESS) {
UseMok = TRUE;
} // if
- }
+ } // if (UEFI SB failed; use shim)
if (ReturnStatus != EFI_NOT_FOUND) {
break;
}
goto bailout;
}
- if (!UseMok) {
- ReturnStatus = Status = refit_call3_wrapper(BS->HandleProtocol, ChildImageHandle, &LoadedImageProtocol,
- (VOID **) &ChildLoadedImage);
- if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
+ if (!UseMok) {
+ ReturnStatus = Status = refit_call3_wrapper(BS->HandleProtocol, ChildImageHandle, &LoadedImageProtocol,
+ (VOID **) &ChildLoadedImage);
+ if (CheckError(Status, L"while getting a LoadedImageProtocol handle")) {
+ if (ErrorInStep != NULL)
+ *ErrorInStep = 2;
+ goto bailout_unload;
+ }
+ ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions;
+ ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16);
+ // turn control over to the image
+ // TODO: (optionally) re-enable the EFI watchdog timer!
+
+ // close open file handles
+ UninitRefitLib();
+ ReturnStatus = Status = refit_call3_wrapper(BS->StartImage, ChildImageHandle, NULL, NULL);
+ // control returns here when the child image calls Exit()
+ SPrint(ErrorInfo, 255, L"returned from %s", ImageTitle);
+ if (CheckError(Status, ErrorInfo)) {
if (ErrorInStep != NULL)
- *ErrorInStep = 2;
- goto bailout_unload;
- }
- }
-
- if (!UseMok) {
- ChildLoadedImage->LoadOptions = (VOID *)FullLoadOptions;
- ChildLoadedImage->LoadOptionsSize = ((UINT32)StrLen(FullLoadOptions) + 1) * sizeof(CHAR16);
- // turn control over to the image
- // TODO: (optionally) re-enable the EFI watchdog timer!
-
- // close open file handles
- UninitRefitLib();
- ReturnStatus = Status = refit_call3_wrapper(BS->StartImage, ChildImageHandle, NULL, NULL);
- // control returns here when the child image calls Exit()
- SPrint(ErrorInfo, 255, L"returned from %s", ImageTitle);
- if (CheckError(Status, ErrorInfo)) {
- if (ErrorInStep != NULL)
- *ErrorInStep = 3;
- }
+ *ErrorInStep = 3;
+ }
- // re-open file handles
- ReinitRefitLib();
+ // re-open file handles
+ ReinitRefitLib();
} // if
bailout_unload:
// unload the image, we don't care if it works or not...
if (!UseMok)
Status = refit_call1_wrapper(BS->UnloadImage, ChildImageHandle);
+
bailout:
MyFreePool(FullLoadOptions);
return ReturnStatus;
struct LOADER_LIST *LoaderList = NULL, *NewLoader;
if ((!SelfDirPath || !Path || ((StriCmp(Path, SelfDirPath) == 0) && Volume->DeviceHandle != SelfVolume->DeviceHandle) ||
- (StriCmp(Path, SelfDirPath) != 0)) && (!IsIn(Path, GlobalConfig.DontScan))) {
+ (StriCmp(Path, SelfDirPath) != 0)) && (!IsIn(Path, GlobalConfig.DontScanDirs))) {
// look through contents of the directory
DirIterOpen(Volume->RootDir, Path, &DirIter);
while (DirIterNext(&DirIter, 2, Pattern, &DirEntry)) {
Extension = FindExtension(DirEntry->FileName);
if (DirEntry->FileName[0] == '.' ||
- StriCmp(DirEntry->FileName, L"TextMode.efi") == 0 ||
- StriCmp(DirEntry->FileName, L"ebounce.efi") == 0 ||
- StriCmp(DirEntry->FileName, L"GraphicsConsole.efi") == 0 ||
StriCmp(Extension, L".icns") == 0 ||
- StriSubCmp(L"shell", DirEntry->FileName))
+ StriSubCmp(L"shell", DirEntry->FileName) ||
+ IsIn(DirEntry->FileName, GlobalConfig.DontScanFiles))
continue; // skip this
if (Path)
if ((Volume->RootDir != NULL) && (Volume->VolName != NULL)) {
// check for Mac OS X boot loader
- if (!IsIn(L"\\System\\Library\\CoreServices", GlobalConfig.DontScan)) {
+ if (!IsIn(L"\\System\\Library\\CoreServices", GlobalConfig.DontScanDirs)) {
StrCpy(FileName, MACOSX_LOADER_PATH);
- if (FileExists(Volume->RootDir, FileName)) {
+ if (FileExists(Volume->RootDir, FileName) && !IsIn(L"boot.efi", GlobalConfig.DontScanFiles)) {
AddLoaderEntry(FileName, L"Mac OS X", Volume);
}
// check for XOM
StrCpy(FileName, L"\\System\\Library\\CoreServices\\xom.efi");
- if (FileExists(Volume->RootDir, FileName)) {
+ if (FileExists(Volume->RootDir, FileName) && !IsIn(L"boot.efi", GlobalConfig.DontScanFiles)) {
AddLoaderEntry(FileName, L"Windows XP (XoM)", Volume);
}
- } // if Mac directory not in GlobalConfig.DontScan list
+ } // if Mac directory not in GlobalConfig.DontScanDirs list
// check for Microsoft boot loader/menu
StrCpy(FileName, L"\\EFI\\Microsoft\\Boot\\Bootmgfw.efi");
- if (FileExists(Volume->RootDir, FileName) && !IsIn(L"\\EFI\\Microsoft\\Boot", GlobalConfig.DontScan)) {
+ if (FileExists(Volume->RootDir, FileName) && !IsIn(L"\\EFI\\Microsoft\\Boot", GlobalConfig.DontScanDirs) &&
+ !IsIn(L"bootmgfw.efi", GlobalConfig.DontScanFiles)) {
AddLoaderEntry(FileName, L"Microsoft EFI boot", Volume);
}