]> code.delx.au - refind/blobdiff - refind/main.c
New configuration token, deep_uefi_legacy_scan, controls whether to
[refind] / refind / main.c
index 5df0aebbfad9fc3851ab1128f67dfb5faf5a4987..45d544cdf31d99609c801fe52e2c6a6b16043ac3 100644 (file)
 #ifndef EFI_SECURITY_VIOLATION
 #define EFI_SECURITY_VIOLATION    EFIERR (26)
 #endif
-#else
+#endif
+
 #include "../EfiLib/BdsHelper.h"
 #include "../EfiLib/legacy.h"
-#endif // __MAKEWITH_GNUEFI
 
 #ifndef EFI_OS_INDICATIONS_BOOT_TO_FW_UI
 #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
 #endif
 
+#ifdef __MAKEWITH_TIANO
+#define LibLocateHandle gBS->LocateHandleBuffer
+#endif
+
 //
 // constants
 
@@ -135,7 +139,7 @@ static REFIT_MENU_SCREEN MainMenu       = { L"Main Menu", NULL, 0, NULL, 0, NULL
                                             L"Insert or F2 for more options; Esc to refresh" };
 static REFIT_MENU_SCREEN AboutMenu      = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL, L"Press Enter to return to main menu", L"" };
 
-REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0,
+REFIT_CONFIG GlobalConfig = { FALSE, FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0,
                               { DEFAULT_BIG_ICON_SIZE / 4, DEFAULT_SMALL_ICON_SIZE, DEFAULT_BIG_ICON_SIZE }, BANNER_NOSCALE,
                               NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               { TAG_SHELL, TAG_MEMTEST, TAG_GDISK, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL,
@@ -164,7 +168,7 @@ static VOID AboutrEFInd(VOID)
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.0");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.1.1");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2014 Roderick W. Smith");
@@ -907,10 +911,12 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo
 
    // locate a custom icon for the loader
    // Anything found here takes precedence over the "hints" in the OSIconName variable
-   if (!Entry->me.Image)
+   if (!Entry->me.Image) {
       Entry->me.Image = egLoadIconAnyType(Volume->RootDir, PathOnly, NoExtension, GlobalConfig.IconSizes[ICON_SIZE_BIG]);
-   if (!Entry->me.Image)
+   }
+   if (!Entry->me.Image) {
       Entry->me.Image = egCopyImage(Volume->VolIconImage);
+   }
 
    // Begin creating icon "hints" by using last part of directory path leading
    // to the loader
@@ -960,9 +966,6 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo
       Entry->OSType = 'R';
       ShortcutLetter = 'R';
    } else if (StriCmp(LoaderPath, MACOSX_LOADER_PATH) == 0) {
-      if (Volume->VolIconImage != NULL) { // custom icon file found
-         Entry->me.Image = Volume->VolIconImage;
-      }
       MergeStrings(&OSIconName, L"mac", L',');
       Entry->OSType = 'M';
       ShortcutLetter = 'M';
@@ -1245,9 +1248,12 @@ static BOOLEAN HasSignedCounterpart(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN
    MergeStrings(&NewFile, Path, 0);
    MergeStrings(&NewFile, Filename, L'\\');
    MergeStrings(&NewFile, L".efi.signed", 0);
-   if (FileExists(Volume->RootDir, NewFile))
-      retval = TRUE;
-   MyFreePool(NewFile);
+   if (NewFile != NULL) {
+      CleanUpPathNameSlashes(NewFile);
+      if (FileExists(Volume->RootDir, NewFile))
+         retval = TRUE;
+      MyFreePool(NewFile);
+   } // if
 
    return retval;
 } // BOOLEAN HasSignedCounterpart()
@@ -1267,8 +1273,7 @@ static BOOLEAN ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16
     BOOLEAN                 FoundFallbackDuplicate = FALSE;
 
     if ((!SelfDirPath || !Path || ((StriCmp(Path, SelfDirPath) == 0) && (Volume->DeviceHandle != SelfVolume->DeviceHandle)) ||
-           (StriCmp(Path, SelfDirPath) != 0)) &&
-           (ShouldScan(Volume, Path))) {
+           (StriCmp(Path, SelfDirPath) != 0)) && (ShouldScan(Volume, Path))) {
        // look through contents of the directory
        DirIterOpen(Volume->RootDir, Path, &DirIter);
        while (DirIterNext(&DirIter, 2, Pattern, &DirEntry)) {
@@ -1650,7 +1655,6 @@ static VOID StartLegacy(IN LEGACY_ENTRY *Entry)
 } /* static VOID StartLegacy() */
 
 // Start a device on a non-Mac using the EFI_LEGACY_BIOS_PROTOCOL
-#ifdef __MAKEWITH_TIANO
 static VOID StartLegacyUEFI(LEGACY_ENTRY *Entry)
 {
     BeginExternalScreen(TRUE, L"Booting Legacy OS (UEFI mode)");
@@ -1663,7 +1667,6 @@ static VOID StartLegacyUEFI(LEGACY_ENTRY *Entry)
     PauseForKey();
     FinishExternalScreen();
 } // static VOID StartLegacyUEFI()
-#endif // __MAKEWITH_TIANO
 
 static LEGACY_ENTRY * AddLegacyEntry(IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Volume)
 {
@@ -1703,7 +1706,7 @@ static LEGACY_ENTRY * AddLegacyEntry(IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Vo
     Entry->me.BadgeImage   = Volume->VolBadgeImage;
     Entry->Volume          = Volume;
     Entry->LoadOptions     = (Volume->DiskKind == DISK_KIND_OPTICAL) ? L"CD" :
-        ((Volume->DiskKind == DISK_KIND_EXTERNAL) ? L"USB" : L"HD");
+                              ((Volume->DiskKind == DISK_KIND_EXTERNAL) ? L"USB" : L"HD");
     Entry->Enabled         = TRUE;
 
     // create the submenu
@@ -1734,9 +1737,6 @@ static LEGACY_ENTRY * AddLegacyEntry(IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Vo
 } /* static LEGACY_ENTRY * AddLegacyEntry() */
 
 
-#ifdef __MAKEWITH_GNUEFI
-static VOID ScanLegacyUEFI(IN UINTN DiskType){}
-#else
 // default volume badge icon based on disk kind
 static EG_IMAGE * GetDiskBadge(IN UINTN DiskType) {
    EG_IMAGE * Badge = NULL;
@@ -1763,11 +1763,16 @@ static LEGACY_ENTRY * AddLegacyEntryUEFI(BDS_COMMON_OPTION *BdsOption, IN UINT16
     LEGACY_ENTRY            *Entry, *SubEntry;
     REFIT_MENU_SCREEN       *SubScreen;
     CHAR16                  ShortcutLetter = 0;
-    CHAR16 *LegacyDescription = BdsOption->Description;
+    CHAR16 *LegacyDescription = StrDuplicate(BdsOption->Description);
 
     if (IsInSubstring(LegacyDescription, GlobalConfig.DontScanVolumes))
        return NULL;
 
+    // Remove stray spaces, since many EFIs produce descriptions with lots of
+    // extra spaces, especially at the end; this throws off centering of the
+    // description on the screen....
+    LimitStringLength(LegacyDescription, 100);
+
     // prepare the menu entry
     Entry = AllocateZeroPool(sizeof(LEGACY_ENTRY));
     Entry->me.Title = AllocateZeroPool(256 * sizeof(CHAR16));
@@ -1833,9 +1838,9 @@ static VOID ScanLegacyUEFI(IN UINTN DiskType)
 
     // If LegacyBios protocol is not implemented on this platform, then
     //we do not support this type of legacy boot on this machine.
-    Status = gBS->LocateProtocol(&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
+    Status = refit_call3_wrapper(gBS->LocateProtocol, &gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
     if (EFI_ERROR (Status))
-        return;
+       return;
 
     // EFI calls USB drives BBS_HARDDRIVE, but we want to distinguish them,
     // so we set DiskType inappropriately elsewhere in the program and
@@ -1883,7 +1888,6 @@ static VOID ScanLegacyUEFI(IN UINTN DiskType)
         Index++;
     } // while
 } /* static VOID ScanLegacyUEFI() */
-#endif // __MAKEWITH_GNUEFI
 
 static VOID ScanLegacyVolume(REFIT_VOLUME *Volume, UINTN VolumeIndex) {
    UINTN VolumeIndex2;
@@ -2151,20 +2155,15 @@ static VOID LoadDrivers(VOID)
 
 // Determine what (if any) type of legacy (BIOS) boot support is available
 static VOID FindLegacyBootType(VOID) {
-#ifdef __MAKEWITH_TIANO
    EFI_STATUS                Status;
    EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
-#endif
 
    GlobalConfig.LegacyType = LEGACY_TYPE_NONE;
 
-   // UEFI-style legacy BIOS support is available only with the TianoCore EDK2
-   // build environment, and then only with some EFI implementations....
-#ifdef __MAKEWITH_TIANO
-   Status = gBS->LocateProtocol (&gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
+   // UEFI-style legacy BIOS support is available only with some EFI implementations....
+   Status = refit_call3_wrapper(gBS->LocateProtocol, &gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
    if (!EFI_ERROR (Status))
       GlobalConfig.LegacyType = LEGACY_TYPE_UEFI;
-#endif
 
    // Macs have their own system. If the firmware vendor code contains the
    // string "Apple", assume it's available. Note that this overrides the
@@ -2175,30 +2174,24 @@ static VOID FindLegacyBootType(VOID) {
       GlobalConfig.LegacyType = LEGACY_TYPE_MAC;
 } // static VOID FindLegacyBootType
 
-// Warn the user if legacy OS scans are enabled but the firmware or this
-// application can't support them....
-static VOID WarnIfLegacyProblems() {
+// Warn the user if legacy OS scans are enabled but the firmware can't support them....
+static VOID WarnIfLegacyProblems(VOID) {
    BOOLEAN  found = FALSE;
    UINTN    i = 0;
 
    if (GlobalConfig.LegacyType == LEGACY_TYPE_NONE) {
       do {
-         if (GlobalConfig.ScanFor[i] == 'h' || GlobalConfig.ScanFor[i] == 'b' || GlobalConfig.ScanFor[i] == 'c')
+         if (GlobalConfig.ScanFor[i] == 'h' || GlobalConfig.ScanFor[i] == 'b' || GlobalConfig.ScanFor[i] == 'c' ||
+             GlobalConfig.ScanFor[i] == 'H' || GlobalConfig.ScanFor[i] == 'B' || GlobalConfig.ScanFor[i] == 'C')
             found = TRUE;
          i++;
       } while ((i < NUM_SCAN_OPTIONS) && (!found));
+
       if (found) {
          Print(L"NOTE: refind.conf's 'scanfor' line specifies scanning for one or more legacy\n");
-         Print(L"(BIOS) boot options; however, this is not possible because ");
-#ifdef __MAKEWITH_TIANO
-         Print(L"your computer lacks\n");
-         Print(L"the necessary Compatibility Support Module (CSM) support.\n");
-#else
-         Print(L"this program was\n");
-         Print(L"compiled without the necessary support. Please visit\n");
-         Print(L"http://www.rodsbooks.com/refind/getting.html and download and install a rEFInd\n");
-         Print(L"binary built with the TianoCore EDK2 to enable legacy boot support.\n");
-#endif
+         Print(L"(BIOS) boot options; however, this is not possible because your computer lacks\n");
+         Print(L"the necessary Compatibility Support Module (CSM) support or that support is\n");
+         Print(L"disabled in your firmware.\n");
          PauseForKey();
       } // if (found)
    } // if no legacy support
@@ -2207,7 +2200,6 @@ static VOID WarnIfLegacyProblems() {
 // Locates boot loaders. NOTE: This assumes that GlobalConfig.LegacyType is set correctly.
 static VOID ScanForBootloaders(VOID) {
    UINTN    i;
-#ifdef __MAKEWITH_TIANO
    CHAR8    s;
    BOOLEAN  ScanForLegacy = FALSE;
 
@@ -2218,12 +2210,11 @@ static VOID ScanForBootloaders(VOID) {
          ScanForLegacy = TRUE;
    } // for
 
-   // If UEFI & scanning for legacy loaders, update NVRAM boot manager list
-   if ((GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) && ScanForLegacy) {
+   // If UEFI & scanning for legacy loaders & deep legacy scan, update NVRAM boot manager list
+   if ((GlobalConfig.LegacyType == LEGACY_TYPE_UEFI) && ScanForLegacy && GlobalConfig.DeepLegacyScan) {
       BdsDeleteAllInvalidLegacyBootOptions();
       BdsAddNonExistingLegacyBootOptions();
    } // if
-#endif
 
    // scan for loaders and tools, add them to the menu
    for (i = 0; i < NUM_SCAN_OPTIONS; i++) {
@@ -2415,14 +2406,15 @@ static VOID ScanForTools(VOID) {
 } // static VOID ScanForTools
 
 // Rescan for boot loaders
-VOID RescanAll(VOID) {
+static VOID RescanAll(BOOLEAN DisplayMessage) {
    EG_PIXEL           BGColor;
 
    BGColor.b = 255;
    BGColor.g = 175;
    BGColor.r = 100;
    BGColor.a = 0;
-   egDisplayMessage(L"Scanning for new boot loaders; please wait....", &BGColor);
+   if (DisplayMessage)
+      egDisplayMessage(L"Scanning for new boot loaders; please wait....", &BGColor);
    FreeList((VOID ***) &(MainMenu.Entries), &MainMenu.EntryCount);
    MainMenu.Entries = NULL;
    MainMenu.EntryCount = 0;
@@ -2445,7 +2437,7 @@ static VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *System
    gRT = SystemTable->RuntimeServices; // Some BDS functions need gRT to be set
    EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
 
-   InitializeConsoleSim();
+//   InitializeConsoleSim();
 }
 
 #endif
@@ -2544,7 +2536,6 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
        CopyMem(GlobalConfig.ScanFor, "ihebocm   ", NUM_SCAN_OPTIONS);
     SetConfigFilename(ImageHandle);
     ReadConfig(GlobalConfig.ConfigFilename);
-//    ScanVolumes();
 
     InitScreen();
     WarnIfLegacyProblems();
@@ -2566,10 +2557,11 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
        BGColor.g = 175;
        BGColor.r = 100;
        BGColor.a = 0;
-       egDisplayMessage(L"Pausing before disk scan; please wait....", &BGColor);
+       if (GlobalConfig.ScanDelay > 1)
+          egDisplayMessage(L"Pausing before disk scan; please wait....", &BGColor);
        for (i = 0; i < GlobalConfig.ScanDelay; i++)
           refit_call1_wrapper(BS->Stall, 1000000);
-       RescanAll();
+       RescanAll(GlobalConfig.ScanDelay > 1);
     } // if
 
     if (GlobalConfig.DefaultSelection)
@@ -2581,7 +2573,7 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         // The Escape key triggers a re-scan operation....
         if (MenuExit == MENU_EXIT_ESCAPE) {
             MenuExit = 0;
-            RescanAll();
+            RescanAll(TRUE);
             continue;
         }
 
@@ -2611,11 +2603,9 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                 StartLegacy((LEGACY_ENTRY *)ChosenEntry);
                 break;
 
-#ifdef __MAKEWITH_TIANO
             case TAG_LEGACY_UEFI: // Boot a legacy OS on a non-Mac
                 StartLegacyUEFI((LEGACY_ENTRY *)ChosenEntry);
                 break;
-#endif
 
             case TAG_TOOL:     // Start a EFI tool
                 StartTool((LOADER_ENTRY *)ChosenEntry);