]> code.delx.au - refind/blobdiff - refind/main.c
Removed BIOS Boot Partition detection; version 0.3.5 release.
[refind] / refind / main.c
index 6bdc3a16880528a09767c05a8276f457036503b7..1f574383154a95e6c3b2fd6f121bc81d07f2b518 100644 (file)
@@ -85,7 +85,7 @@ static REFIT_MENU_ENTRY MenuEntryExit     = { L"Exit rEFInd", TAG_EXIT, 1, 0, 0,
 static REFIT_MENU_SCREEN MainMenu       = { L"Main Menu", NULL, 0, NULL, 0, NULL, 0, L"Automatic boot" };
 static REFIT_MENU_SCREEN AboutMenu      = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL };
 
-REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 20, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               {TAG_SHELL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
 
 // Structure used to hold boot loader filenames and time stamps in
@@ -104,7 +104,7 @@ static VOID AboutrEFInd(VOID)
 {
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.3.1.2");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.3.5");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
@@ -273,8 +273,8 @@ static CHAR16 * FindInitrd(IN CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume) {
    while ((DirIterNext(&DirIter, 2, L"init*", &DirEntry)) && (InitrdName == NULL)) {
       InitrdVersion = FindNumbers(DirEntry->FileName);
       if (KernelVersion != NULL) {
-            if (StriCmp(InitrdVersion, KernelVersion) == 0)
-               InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
+         if (StriCmp(InitrdVersion, KernelVersion) == 0)
+            InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
       } else {
          if (InitrdVersion == NULL)
             InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
@@ -296,6 +296,66 @@ LOADER_ENTRY * AddPreparedLoaderEntry(LOADER_ENTRY *Entry) {
    return(Entry);
 } // LOADER_ENTRY * AddPreparedLoaderEntry()
 
+// Creates a copy of a menu screen.
+// Returns a pointer to the copy of the menu screen.
+static REFIT_MENU_SCREEN* CopyMenuScreen(REFIT_MENU_SCREEN *Entry) {
+   REFIT_MENU_SCREEN *NewEntry;
+   UINTN i;
+
+   NewEntry = AllocateZeroPool(sizeof(REFIT_MENU_SCREEN));
+   if ((Entry != NULL) && (NewEntry != NULL)) {
+      CopyMem(NewEntry, Entry, sizeof(REFIT_MENU_SCREEN));
+      NewEntry->Title = StrDuplicate(Entry->Title);
+      NewEntry->TimeoutText = StrDuplicate(Entry->TimeoutText);
+      if (Entry->TitleImage != NULL) {
+         NewEntry->TitleImage = AllocatePool(sizeof(EG_IMAGE));
+         if (NewEntry->TitleImage != NULL)
+            CopyMem(NewEntry->TitleImage, Entry->TitleImage, sizeof(EG_IMAGE));
+      } // if
+      NewEntry->InfoLines = (CHAR16**) AllocateZeroPool(Entry->InfoLineCount * (sizeof(CHAR16*)));
+      for (i = 0; i < Entry->InfoLineCount && NewEntry->InfoLines; i++) {
+         NewEntry->InfoLines[i] = StrDuplicate(Entry->InfoLines[i]);
+      } // for
+      NewEntry->Entries = (REFIT_MENU_ENTRY**) AllocateZeroPool(Entry->EntryCount * (sizeof (REFIT_MENU_ENTRY*)));
+      for (i = 0; i < Entry->EntryCount && NewEntry->Entries; i++) {
+         AddMenuEntry(NewEntry, Entry->Entries[i]);
+      } // for
+   } // if
+   return (NewEntry);
+} // static REFIT_MENU_SCREEN* CopyMenuScreen()
+
+// Creates a copy of a menu entry. Intended to enable moving a stack-based
+// menu entry (such as the ones for the "reboot" and "exit" functions) to
+// to the heap. This enables easier deletion of the whole set of menu
+// entries when re-scanning.
+// Returns a pointer to the copy of the menu entry.
+static REFIT_MENU_ENTRY* CopyMenuEntry(REFIT_MENU_ENTRY *Entry) {
+   REFIT_MENU_ENTRY *NewEntry;
+
+   NewEntry = AllocateZeroPool(sizeof(REFIT_MENU_ENTRY));
+   if ((Entry != NULL) && (NewEntry != NULL)) {
+      CopyMem(NewEntry, Entry, sizeof(REFIT_MENU_ENTRY));
+      NewEntry->Title = StrDuplicate(Entry->Title);
+      if (Entry->BadgeImage != NULL) {
+         NewEntry->BadgeImage = AllocatePool(sizeof(EG_IMAGE));
+         if (NewEntry->BadgeImage != NULL)
+            CopyMem(NewEntry->BadgeImage, Entry->BadgeImage, sizeof(EG_IMAGE));
+      }
+      if (Entry->Image != NULL) {
+         NewEntry->Image = AllocatePool(sizeof(EG_IMAGE));
+         if (NewEntry->Image != NULL)
+            CopyMem(NewEntry->Image, Entry->Image, sizeof(EG_IMAGE));
+      }
+      if (Entry->SubScreen != NULL) {
+         NewEntry->SubScreen = CopyMenuScreen(Entry->SubScreen);
+//          NewEntry->SubScreen = AllocatePool(sizeof(REFIT_MENU_SCREEN));
+//          if (NewEntry->SubScreen != NULL)
+//             CopyMem(NewEntry->SubScreen, Entry->SubScreen, sizeof(REFIT_MENU_SCREEN));
+      }
+   } // if
+   return (NewEntry);
+} // REFIT_MENU_ENTRY* CopyMenuEntry()
+
 // Creates a new LOADER_ENTRY data structure and populates it with
 // default values from the specified Entry, or NULL values if Entry
 // is unspecified (NULL).
@@ -604,6 +664,9 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, IN REFIT_VOLUME
       Entry->OSType = 'E';
       if (ShortcutLetter == 0)
          ShortcutLetter = 'L';
+   } else if (StriSubCmp(L"grub", FileName)) {
+      Entry->OSType = 'G';
+      ShortcutLetter = 'G';
    } else if (StriCmp(FileName, L"cdboot.efi") == 0 ||
               StriCmp(FileName, L"bootmgr.efi") == 0 ||
               StriCmp(FileName, L"Bootmgfw.efi") == 0) {
@@ -635,7 +698,6 @@ LOADER_ENTRY * AddLoaderEntry(IN CHAR16 *LoaderPath, IN CHAR16 *LoaderTitle, IN
    Entry = InitializeLoaderEntry(NULL);
    if (Entry != NULL) {
       Entry->Title = StrDuplicate((LoaderTitle != NULL) ? LoaderTitle : LoaderPath);
-//      Entry->Title = StrDuplicate(LoaderTitle);
       Entry->me.Title = PoolPrint(L"Boot %s from %s", (LoaderTitle != NULL) ? LoaderTitle : LoaderPath, Volume->VolName);
       Entry->me.Row = 0;
       Entry->me.BadgeImage = Volume->VolBadgeImage;
@@ -1173,10 +1235,10 @@ static VOID ScanLegacyExternal(VOID)
 
 static VOID StartTool(IN LOADER_ENTRY *Entry)
 {
-    BeginExternalScreen(Entry->UseGraphicsMode, Entry->me.Title + 6);  // assumes "Start <title>" as assigned below
-    StartEFIImage(Entry->DevicePath, Entry->LoadOptions, Basename(Entry->LoaderPath),
-                  Basename(Entry->LoaderPath), NULL, TRUE);
-    FinishExternalScreen();
+   BeginExternalScreen(Entry->UseGraphicsMode, Entry->me.Title + 6);  // assumes "Start <title>" as assigned below
+   StartEFIImage(Entry->DevicePath, Entry->LoadOptions, Basename(Entry->LoaderPath),
+                 Basename(Entry->LoaderPath), NULL, TRUE);
+   FinishExternalScreen();
 } /* static VOID StartTool() */
 
 static LOADER_ENTRY * AddToolEntry(IN CHAR16 *LoaderPath, IN CHAR16 *LoaderTitle, IN EG_IMAGE *Image,
@@ -1383,31 +1445,36 @@ static VOID ScanForBootloaders(VOID) {
 // reboot, etc.)
 static VOID ScanForTools(VOID) {
    CHAR16 *FileName = NULL;
+   REFIT_MENU_ENTRY *TempMenuEntry;
    UINTN i, j;
 
    for (i = 0; i < NUM_TOOLS; i++) {
       switch(GlobalConfig.ShowTools[i]) {
          case TAG_SHUTDOWN:
-            MenuEntryShutdown.Image = BuiltinIcon(BUILTIN_ICON_FUNC_SHUTDOWN);
-            AddMenuEntry(&MainMenu, &MenuEntryShutdown);
+            TempMenuEntry = CopyMenuEntry(&MenuEntryShutdown);
+            TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_SHUTDOWN);
+            AddMenuEntry(&MainMenu, TempMenuEntry);
             break;
          case TAG_REBOOT:
-            MenuEntryReset.Image = BuiltinIcon(BUILTIN_ICON_FUNC_RESET);
-            AddMenuEntry(&MainMenu, &MenuEntryReset);
+            TempMenuEntry = CopyMenuEntry(&MenuEntryReset);
+            TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_RESET);
+            AddMenuEntry(&MainMenu, TempMenuEntry);
             break;
          case TAG_ABOUT:
-            MenuEntryAbout.Image = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-            AddMenuEntry(&MainMenu, &MenuEntryAbout);
+            TempMenuEntry = CopyMenuEntry(&MenuEntryAbout);
+            TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
+            AddMenuEntry(&MainMenu, TempMenuEntry);
             break;
          case TAG_EXIT:
-            MenuEntryExit.Image = BuiltinIcon(BUILTIN_ICON_FUNC_EXIT);
-            AddMenuEntry(&MainMenu, &MenuEntryExit);
+            TempMenuEntry = CopyMenuEntry(&MenuEntryExit);
+            TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_EXIT);
+            AddMenuEntry(&MainMenu, TempMenuEntry);
             break;
          case TAG_SHELL:
             j = 0;
             while ((FileName = FindCommaDelimited(SHELL_NAMES, j++)) != NULL) {
                if (FileExists(SelfRootDir, FileName)) {
-                  AddToolEntry(FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL), 'E', FALSE);
+                  AddToolEntry(FileName, L"EFI Shell", BuiltinIcon(BUILTIN_ICON_TOOL_SHELL), 'S', FALSE);
                }
             } // while
             break;
@@ -1433,10 +1500,11 @@ EFI_STATUS
 EFIAPI
 efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
 {
-    EFI_STATUS Status;
-    BOOLEAN MainLoopRunning = TRUE;
-    REFIT_MENU_ENTRY *ChosenEntry;
-    UINTN MenuExit;
+    EFI_STATUS         Status;
+    BOOLEAN            MainLoopRunning = TRUE;
+    REFIT_MENU_ENTRY   *ChosenEntry;
+    UINTN              MenuExit;
+    CHAR16             *Selection;
 
     // bootstrap
     InitializeLib(ImageHandle, SystemTable);
@@ -1459,17 +1527,20 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
     ScanForBootloaders();
     ScanForTools();
 
+    Selection = StrDuplicate(GlobalConfig.DefaultSelection);
     while (MainLoopRunning) {
-        MenuExit = RunMainMenu(&MainMenu, GlobalConfig.DefaultSelection, &ChosenEntry);
+        MenuExit = RunMainMenu(&MainMenu, Selection, &ChosenEntry);
 
         // We don't allow exiting the main menu with the Escape key.
         if (MenuExit == MENU_EXIT_ESCAPE) {
-           // Commented-out below: Was part of an attempt to get rEFInd to
-           // re-scan disk devices on pressing Esc; but doesn't work (yet), so
-           // removed....
-//             ReadConfig();
-//             ScanForBootloaders();
-//             SetupScreen();
+            FreeList((VOID ***) &(MainMenu.Entries), &MainMenu.EntryCount);
+            MainMenu.Entries = NULL;
+            MainMenu.EntryCount = 0;
+            ReadConfig();
+            ConnectAllDriversToAllControllers();
+            ScanForBootloaders();
+            ScanForTools();
+            SetupScreen();
             continue;
         }
 
@@ -1508,8 +1579,10 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
                 return EFI_SUCCESS;
                 break;
 
-        }
-    }
+        } // switch()
+        FreePool(Selection);
+        Selection = StrDuplicate(ChosenEntry->Title);
+    } // while()
 
     // If we end up here, things have gone wrong. Try to reboot, and if that
     // fails, go into an endless loop.