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
# utility rules
clean:
- rm -f $(TARGET) *~ *.so $(OBJS)
+ rm -f $(TARGET) *~ *.so $(OBJS) *.efi
# EOF
+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):
-----------------
icon \EFI\refind\icons\os_win.icns
loader \EFI\tools\shell.efi
options "fs0:\EFI\tools\launch_windows.nsh"
+ disabled
}
{
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)
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; )
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;
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) {
}
}
- } 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++) {
}
} 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);
} 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;
} 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);
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);
{
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");
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).
// 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;
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);
// 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;
}