]> code.delx.au - refind/commitdiff
New re-scan feature: Press Esc to re-scan filesystems.
authorsrs5694 <srs5694@users.sourceforge.net>
Fri, 11 May 2012 17:21:31 +0000 (13:21 -0400)
committersrs5694 <srs5694@users.sourceforge.net>
Fri, 11 May 2012 17:21:31 +0000 (13:21 -0400)
Make.common
NEWS.txt
refind.conf-sample
refind/config.c
refind/lib.h
refind/main.c

index edfe4602753629e0b1082f4f75b52d96fdfe7984..5661e3d0f1274000a2c76933971c6e0bf358c0d4 100644 (file)
@@ -15,6 +15,7 @@ CPPFLAGS        = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol -DCONFIG_
 
 OPTIMFLAGS      = -O2 -fno-strict-aliasing
 DEBUGFLAGS      = -Wall
+#CFLAGS          = $(ARCH3264) $(OPTIMFLAGS) -fpic -fshort-wchar $(DEBUGFLAGS)
 CFLAGS          = $(ARCH3264) $(OPTIMFLAGS) -fno-stack-protector -fpic -fshort-wchar $(DEBUGFLAGS)
 ASFLAGS         = $(ARCH3264)
 LDFLAGS         = -nostdlib -znocombreloc
@@ -107,6 +108,6 @@ endif
 # utility rules
 
 clean:
-       rm -f $(TARGET) *~ *.so $(OBJS)
+       rm -f $(TARGET) *~ *.so $(OBJS) *.efi
 
 # EOF
index 8fb2dc561244584317bc21c4580d0ec12873cec3..3fdb726c2aeee2afb05df1230c936857f43e7d19 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,3 +1,16 @@
+0.3.5 (?/??/2012):
+------------------
+
+- Added re-scan feature: Press the Esc key to have rEFInd re-read its 
+  configuration file, tell the EFI to scan for new filesystems, and re-scan
+  those filesystems for boot loaders. The main purpose is to enable
+  scanning a new removable medium that you insert after launching rEFInd;
+  however, it can also be used to immediately implement changes to the
+  configuration file or new drivers you load from an EFI shell.
+
+- Fixed a bug that could cause the scroll-right arrow to be replaced by the
+  scroll-left arrow under some circumstances.
+
 0.3.4 (5/9/2012):
 -----------------
 
index ec8e696d16071f070e0be7e8c3fc8e63513afaeb..7e7855566559dbb21cfa1a20cc96915c98618dd7 100644 (file)
@@ -238,4 +238,5 @@ menuentry "Windows via shell script" {
        icon \EFI\refind\icons\os_win.icns
        loader \EFI\tools\shell.efi
        options "fs0:\EFI\tools\launch_windows.nsh"
+       disabled
 }
index ebc7d083e4f872b09e0594f997284a2a66e3e586..7e99dcf1abfd4d4099669a017573b1eb88069fbe 100644 (file)
@@ -138,18 +138,18 @@ static CHAR16 *ReadLine(REFIT_FILE *File)
 {
     CHAR16  *Line, *q;
     UINTN   LineLength;
-    
+
     if (File->Buffer == NULL)
         return NULL;
-    
+
     if (File->Encoding == ENCODING_ISO8859_1 || File->Encoding == ENCODING_UTF8) {
-        
+
         CHAR8 *p, *LineStart, *LineEnd;
-        
+
         p = File->Current8Ptr;
         if (p >= File->End8Ptr)
             return NULL;
-        
+
         LineStart = p;
         for (; p < File->End8Ptr; p++)
             if (*p == 13 || *p == 10)
@@ -159,12 +159,12 @@ static CHAR16 *ReadLine(REFIT_FILE *File)
             if (*p != 13 && *p != 10)
                 break;
         File->Current8Ptr = p;
-        
+
         LineLength = (UINTN)(LineEnd - LineStart) + 1;
         Line = AllocatePool(LineLength * sizeof(CHAR16));
         if (Line == NULL)
             return NULL;
-        
+
         q = Line;
         if (File->Encoding == ENCODING_ISO8859_1) {
             for (p = LineStart; p < LineEnd; )
@@ -267,40 +267,36 @@ VOID FreeTokenLine(IN OUT CHAR16 ***TokenList, IN OUT UINTN *TokenCount)
     FreeList((VOID ***)TokenList, TokenCount);
 }
 
-//
 // handle a parameter with a single integer argument
-//
-
 static VOID HandleInt(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT UINTN *Value)
 {
-    if (TokenCount < 2) {
-        return;
-    }
-    if (TokenCount > 2) {
-        return;
-    }
-    *Value = Atoi(TokenList[1]);
+    if (TokenCount == 2)
+       *Value = Atoi(TokenList[1]);
 }
 
-//
 // handle a parameter with a single string argument
-//
+static VOID HandleString(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 **Target) {
+   if (TokenCount == 2) {
+      if (*Target != NULL)
+         FreePool(*Target);
+      *Target = StrDuplicate(TokenList[1]);
+   } // if
+} // static VOID HandleString()
 
-static VOID HandleString(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 **Value)
-{
-    if (TokenCount < 2) {
-        return;
-    }
-    if (TokenCount > 2) {
-        return;
-    }
-    *Value = StrDuplicate(TokenList[1]);
-}
+// Handle a parameter with a series of string arguments, to be added to a comma-delimited
+// list
+static VOID HandleStrings(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 **Target) {
+   UINTN i;
 
-//
-// read config file
-//
+   if (*Target != NULL) {
+      FreePool(*Target);
+      *Target = NULL;
+   } // if
+    for (i = 1; i < TokenCount; i++)
+       MergeStrings(Target, TokenList[i], L',');
+} // static VOID HandleStrings()
 
+// read config file
 VOID ReadConfig(VOID)
 {
     EFI_STATUS      Status;
@@ -326,11 +322,7 @@ VOID ReadConfig(VOID)
         if (StriCmp(TokenList[0], L"timeout") == 0) {
             HandleInt(TokenList, TokenCount, &(GlobalConfig.Timeout));
 
-        // Note: I'm using "disable" as equivalent to "hideui" for the moment (as of rEFInd 0.2.4)
-        // because I've folded two options into one and removed some values, so I want to catch
-        // existing configurations as much as possible. The "disable" equivalency to "hideui" will
-        // be removed sooner or later, leaving only "hideui".
-        } else if ((StriCmp(TokenList[0], L"hideui") == 0) || (StriCmp(TokenList[0], L"disable") == 0)) {
+        } else if (StriCmp(TokenList[0], L"hideui") == 0) {
             for (i = 1; i < TokenCount; i++) {
                 FlagName = TokenList[i];
                 if (StriCmp(FlagName, L"banner") == 0) {
@@ -350,10 +342,8 @@ VOID ReadConfig(VOID)
                 }
             }
 
-        } else if ((StriCmp(TokenList[0], L"icons_dir") == 0) && (TokenCount == 2)) {
-           if (GlobalConfig.IconsDir != NULL)
-              FreePool(GlobalConfig.IconsDir);
-           GlobalConfig.IconsDir = StrDuplicate(TokenList[1]);
+        } else if (StriCmp(TokenList[0], L"icons_dir") == 0) {
+           HandleString(TokenList, TokenCount, &(GlobalConfig.IconsDir));
 
         } else if (StriCmp(TokenList[0], L"scanfor") == 0) {
            for (i = 0; i < NUM_SCAN_OPTIONS; i++) {
@@ -364,20 +354,10 @@ VOID ReadConfig(VOID)
            }
 
         } else if (StriCmp(TokenList[0], L"also_scan_dirs") == 0) {
-           if (GlobalConfig.AlsoScan != NULL) {
-              FreePool(GlobalConfig.AlsoScan);
-              GlobalConfig.AlsoScan = NULL;
-           } // if
-           for (i = 1; i < TokenCount; i++)
-              MergeStrings(&GlobalConfig.AlsoScan, TokenList[i], L',');
+            HandleStrings(TokenList, TokenCount, &(GlobalConfig.AlsoScan));
 
         } else if (StriCmp(TokenList[0], L"scan_driver_dirs") == 0) {
-           if (GlobalConfig.DriverDirs != NULL) {
-              FreePool(GlobalConfig.DriverDirs);
-              GlobalConfig.DriverDirs = NULL;
-           } // if
-           for (i = 1; i < TokenCount; i++)
-              MergeStrings(&GlobalConfig.DriverDirs, TokenList[i], L',');
+            HandleStrings(TokenList, TokenCount, &(GlobalConfig.DriverDirs));
 
         } else if (StriCmp(TokenList[0], L"showtools") == 0) {
             SetMem(GlobalConfig.ShowTools, NUM_TOOLS * sizeof(UINTN), 0);
@@ -396,21 +376,21 @@ VOID ReadConfig(VOID)
                 } else if (StriCmp(FlagName, L"shutdown") == 0) {
                    GlobalConfig.ShowTools[i - 1] = TAG_SHUTDOWN;
                 } else {
-                    Print(L" unknown showtools flag: '%s'\n", FlagName);
+                   Print(L" unknown showtools flag: '%s'\n", FlagName);
                 }
             } // showtools options
 
         } else if (StriCmp(TokenList[0], L"banner") == 0) {
-            HandleString(TokenList, TokenCount, &(GlobalConfig.BannerFileName));
+           HandleString(TokenList, TokenCount, &(GlobalConfig.BannerFileName));
 
         } else if (StriCmp(TokenList[0], L"selection_small") == 0) {
-            HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionSmallFileName));
+           HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionSmallFileName));
 
         } else if (StriCmp(TokenList[0], L"selection_big") == 0) {
-            HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionBigFileName));
+           HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionBigFileName));
 
         } else if (StriCmp(TokenList[0], L"default_selection") == 0) {
-            HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection));
+           HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection));
 
         } else if (StriCmp(TokenList[0], L"textonly") == 0) {
             GlobalConfig.TextOnly = TRUE;
@@ -422,8 +402,8 @@ VOID ReadConfig(VOID)
         } else if (StriCmp(TokenList[0], L"scan_all_linux_kernels") == 0) {
            GlobalConfig.ScanAllLinux = TRUE;
 
-        } else if ((StriCmp(TokenList[0], L"max_tags") == 0) && (TokenCount > 1)) {
-           GlobalConfig.MaxTags = Atoi(TokenList[1]);
+        } else if (StriCmp(TokenList[0], L"max_tags") == 0) {
+           HandleInt(TokenList, TokenCount, &(GlobalConfig.MaxTags));
         }
 
         FreeTokenLine(&TokenList, &TokenCount);
index 9f1cb4ebf9e9155a3311f931016fa74daee3c9cf..1cba88a4481d550e2a13b1ad1fc49402e152f642 100644 (file)
@@ -76,7 +76,7 @@ EFI_STATUS ReinitRefitLib(VOID);
 VOID CleanUpPathNameSlashes(IN OUT CHAR16 *PathName);
 VOID CreateList(OUT VOID ***ListPtr, OUT UINTN *ElementCount, IN UINTN InitialElementCount);
 VOID AddListElement(IN OUT VOID ***ListPtr, IN OUT UINTN *ElementCount, IN VOID *NewElement);
-VOID FreeList(IN OUT VOID ***ListPtr, IN OUT UINTN *ElementCount /*, IN Callback*/);
+VOID FreeList(IN OUT VOID ***ListPtr, IN OUT UINTN *ElementCount);
 
 VOID ExtractLegacyLoaderPaths(EFI_DEVICE_PATH **PathList, UINTN MaxPaths, EFI_DEVICE_PATH **HardcodedPathList);
 
index 150be7be8a9b8e80178a8f2379ee81c97d52ee68..cfb6059cc9d379ebef00b1c1512786333cb0255e 100644 (file)
@@ -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.4.1");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.3.4.3");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
@@ -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).
@@ -1385,25 +1445,30 @@ 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;
@@ -1435,11 +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;
-    CHAR16 *Selection;
+    EFI_STATUS         Status;
+    BOOLEAN            MainLoopRunning = TRUE;
+    REFIT_MENU_ENTRY   *ChosenEntry;
+    UINTN              MenuExit;
+    CHAR16             *Selection;
 
     // bootstrap
     InitializeLib(ImageHandle, SystemTable);
@@ -1468,12 +1533,14 @@ efi_main (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
 
         // 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;
         }