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
{
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.3.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");
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);
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).
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) {
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;
// 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;
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);
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;
}
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.