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, 20, 0, 0, NULL, NULL, NULL, NULL,
+REFIT_CONFIG GlobalConfig = { FALSE, 20, 0, 0, NULL, NULL, NULL, NULL, NULL,
{TAG_SHELL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
//
{
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.2.3.4");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.2.6.1");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
if (ErrorInStep != NULL)
*ErrorInStep = 3;
}
-
+
// re-open file handles
ReinitRefitLib();
OUT UINTN *ErrorInStep)
{
EFI_DEVICE_PATH *DevicePaths[2];
-
+
DevicePaths[0] = DevicePath;
DevicePaths[1] = NULL;
return StartEFIImageList(DevicePaths, LoadOptions, LoadOptionsPrefix, ImageTitle, ErrorInStep);
KernelVersion = FindNumbers(FileName);
Path = FindPath(LoaderPath);
+ // Add trailing backslash for root directory; necessary on some systems, but must
+ // NOT be added to all directories, since on other systems, a trailing backslash on
+ // anything but the root directory causes them to flake out!
+ if (StrLen(Path) == 0) {
+ MergeStrings(&Path, L"\\", 0);
+ } // if
DirIterOpen(Volume->RootDir, Path, &DirIter);
+ // Now add a trailing backslash if it was NOT added earlier, for consistency in
+ // building the InitrdName later....
+ if ((StrLen(Path) > 0) && (Path[StrLen(Path) - 1] != L'\\'))
+ MergeStrings(&Path, L"\\", 0);
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);
+ InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
} else {
if (InitrdVersion == NULL)
- InitrdName = PoolPrint(L"%s\\%s", Path, DirEntry->FileName);
+ InitrdName = PoolPrint(L"%s%s", Path, DirEntry->FileName);
} // if/else
if (InitrdVersion != NULL)
FreePool(InitrdVersion);
Entry->Title = NULL;
}
SubScreen = InitializeSubScreen(Entry);
-
+
// loader-specific submenu entries
if (Entry->OSType == 'M') { // entries for Mac OS X
#if defined(EFIX64)
} // if
#endif
- if (!(GlobalConfig.DisableFlags & DISABLE_FLAG_SINGLEUSER)) {
+ if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_SINGLEUSER)) {
SubEntry = InitializeLoaderEntry(Entry);
if (SubEntry != NULL) {
SubEntry->me.Title = L"Boot Mac OS X in verbose mode";
SubEntry->LoadOptions = L"-v";
AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry);
} // if
-
+
#if defined(EFIX64)
SubEntry = InitializeLoaderEntry(Entry);
if (SubEntry != NULL) {
// check for Apple hardware diagnostics
StrCpy(DiagsFileName, L"\\System\\Library\\CoreServices\\.diagnostics\\diags.efi");
- if (FileExists(Volume->RootDir, DiagsFileName) && !(GlobalConfig.DisableFlags & DISABLE_FLAG_HWTEST)) {
+ if (FileExists(Volume->RootDir, DiagsFileName) && !(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HWTEST)) {
SubEntry = InitializeLoaderEntry(Entry);
if (SubEntry != NULL) {
SubEntry->me.Title = L"Run Apple Hardware Test";
AddMenuInfoLine(SubScreen, L"NOTE: This is an example. Entries");
AddMenuInfoLine(SubScreen, L"marked with (*) may not work.");
-
+
} else if (Entry->OSType == 'X') { // entries for xom.efi
// by default, skip the built-in selection and boot from hard disk only
Entry->LoadOptions = L"-s -h";
// that will (with luck) work fairly automatically.
VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, IN REFIT_VOLUME *Volume) {
CHAR16 IconFileName[256];
- CHAR16 *FileName, *OSIconName = NULL, *Temp;
+ CHAR16 *FileName, *PathOnly, *OSIconName = NULL, *Temp;
CHAR16 ShortcutLetter = 0;
FileName = Basename(LoaderPath);
-
+ PathOnly = FindPath(LoaderPath);
+
// locate a custom icon for the loader
StrCpy(IconFileName, LoaderPath);
ReplaceExtension(IconFileName, L".icns");
if (FileExists(Volume->RootDir, IconFileName)) {
Entry->me.Image = LoadIcns(Volume->RootDir, IconFileName, 128);
- } // if
-
+ } else if ((StrLen(PathOnly) == 0) && (Volume->VolIconImage != NULL)) {
+ Entry->me.Image = Volume->VolIconImage;
+ } // icon matched to loader or volume
+
Temp = FindLastDirName(LoaderPath);
MergeStrings(&OSIconName, Temp, L',');
FreePool(Temp);
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->UseGraphicsMode = TRUE;
Entry->OSType = 'M';
Entry->me.ShortcutLetter = ShortcutLetter;
if (Entry->me.Image == NULL)
Entry->me.Image = LoadOSIcon(OSIconName, L"unknown", FALSE);
+ if (PathOnly != NULL)
+ FreePool(PathOnly);
} // VOID SetLoaderDefaults()
-
+
// Add a specified EFI boot loader to the list, using automatic settings
// for icons, options, etc.
LOADER_ENTRY * AddLoaderEntry(IN CHAR16 *LoaderPath, IN CHAR16 *LoaderTitle, IN REFIT_VOLUME *Volume) {
LOADER_ENTRY *Entry;
+ CleanUpPathNameSlashes(LoaderPath);
Entry = InitializeLoaderEntry(NULL);
if (Entry != NULL) {
Entry->Title = StrDuplicate(LoaderTitle);
GenerateSubScreen(Entry, Volume);
AddMenuEntry(&MainMenu, (REFIT_MENU_ENTRY *)Entry);
}
-
+
return(Entry);
} // LOADER_ENTRY * AddLoaderEntry()
EFI_STATUS Status;
REFIT_DIR_ITER DirIter;
EFI_FILE_INFO *DirEntry;
- CHAR16 FileName[256];
+ CHAR16 FileName[256], *SelfPath;
+ UINTN i = 0;
- // Note: SelfDirPath includes a leading backslash ('\'), but Path
- // doesn't, so we rejigger the string to compensate....
- if (!SelfDirPath || !Path || ((StriCmp(Path, &SelfDirPath[1]) == 0) && Volume != SelfVolume) ||
- (StriCmp(Path, &SelfDirPath[1]) != 0)) {
+ // Skip past leading slashes, which are sometimes (but not always) included
+ // in SelfDirPath, to get a path that's known to never include this feature.
+ while ((SelfDirPath != NULL) && (SelfDirPath[i] == L'\\')) {
+ i++;
+ }
+ SelfPath = &SelfDirPath[i]; // NOTE: *DO NOT* call FreePool() on SelfPath!!!
+
+ if (!SelfPath || !Path || ((StriCmp(Path, SelfPath) == 0) && Volume != SelfVolume) ||
+ (StriCmp(Path, SelfPath) != 0)) {
// look through contents of the directory
DirIterOpen(Volume->RootDir, Path, &DirIter);
while (DirIterNext(&DirIter, 2, L"*.efi", &DirEntry)) {
EFI_STATUS Status;
REFIT_DIR_ITER EfiDirIter;
EFI_FILE_INFO *EfiDirEntry;
- CHAR16 FileName[256];
+ CHAR16 FileName[256], *Directory;
+ UINTN i, Length;
if ((Volume->RootDir != NULL) && (Volume->VolName != NULL)) {
// check for Mac OS X boot loader
// scan the root directory for EFI executables
ScanLoaderDir(Volume, NULL);
- // scan the elilo directory (as used on gimli's first Live CD)
- ScanLoaderDir(Volume, L"elilo");
- // scan the boot directory
- ScanLoaderDir(Volume, L"boot");
// scan subdirectories of the EFI directory (as per the standard)
DirIterOpen(Volume->RootDir, L"EFI", &EfiDirIter);
Status = DirIterClose(&EfiDirIter);
if (Status != EFI_NOT_FOUND)
CheckError(Status, L"while scanning the EFI directory");
+
+ // Scan user-specified (or additional default) directories....
+ i = 0;
+ while ((Directory = FindCommaDelimited(GlobalConfig.AlsoScan, i++)) != NULL) {
+ Length = StrLen(Directory);
+ // Some EFI implementations won't read a directory if the path ends in
+ // a backslash, so eliminate this character, if it's present....
+ while ((Length > 0) && (Directory[Length - 1] == L'\\')) {
+ Directory[--Length] = 0;
+ } // while
+ if (Length > 0)
+ ScanLoaderDir(Volume, Directory);
+ FreePool(Directory);
+ } // while
} // if
} // static VOID ScanEfiFiles()
if (PartitionIndex < LogicalPartitionIndex)
break; // stop the loop, no need to touch further EMBRs
}
-
+
}
return EFI_SUCCESS;
REFIT_DIR_ITER DirIter;
EFI_FILE_INFO *DirEntry;
CHAR16 FileName[256];
-
+
// look through contents of the directory
DirIterOpen(SelfRootDir, Path, &DirIter);
while (DirIterNext(&DirIter, 2, L"*.EFI", &DirEntry)) {
if (DirEntry->FileName[0] == '.')
continue; // skip this
-
+
SPrint(FileName, 255, L"%s\\%s", Path, DirEntry->FileName);
Status = StartEFIImage(FileDevicePath(SelfLoadedImage->DeviceHandle, FileName),
L"", DirEntry->FileName, DirEntry->FileName, NULL);
CheckError(Status, FileName);
}
}
-EFI_STATUS
+/* EFI_STATUS
LibScanHandleDatabase (
EFI_HANDLE DriverBindingHandle, OPTIONAL
UINT32 *DriverBindingHandleIndex, OPTIONAL
#define EFI_HANDLE_TYPE_DEVICE_HANDLE 0x080
#define EFI_HANDLE_TYPE_PARENT_HANDLE 0x100
#define EFI_HANDLE_TYPE_CONTROLLER_HANDLE 0x200
-#define EFI_HANDLE_TYPE_CHILD_HANDLE 0x400
+#define EFI_HANDLE_TYPE_CHILD_HANDLE 0x400 */
static EFI_STATUS ConnectAllDriversToAllControllers(VOID)
{
UINTN HandleIndex;
BOOLEAN Parent;
BOOLEAN Device;
-
+
Status = LibLocateHandle(AllHandles,
NULL,
NULL,
&AllHandleBuffer);
if (EFI_ERROR(Status))
return Status;
-
+
for (Index = 0; Index < AllHandleCount; Index++) {
//
// Scan the handle database
&HandleType);
if (EFI_ERROR (Status))
goto Done;
-
+
Device = TRUE;
if (HandleType[Index] & EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE)
Device = FALSE;
if (HandleType[Index] & EFI_HANDLE_TYPE_IMAGE_HANDLE)
Device = FALSE;
-
+
if (Device) {
Parent = FALSE;
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_PARENT_HANDLE)
Parent = TRUE;
}
-
+
if (!Parent) {
if (HandleType[Index] & EFI_HANDLE_TYPE_DEVICE_HANDLE) {
Status = refit_call4_wrapper(BS->ConnectController,
}
}
}
-
+
FreePool (HandleBuffer);
FreePool (HandleType);
}
-
+
Done:
FreePool (AllHandleBuffer);
return Status;
// assign shortcut keys
for (i = 0; i < MainMenu.EntryCount && MainMenu.Entries[i]->Row == 0 && i < 9; i++)
MainMenu.Entries[i]->ShortcutDigit = (CHAR16)('1' + i);
-
+
// wait for user ACK when there were errors
FinishTextScreen(FALSE);
} // static VOID ScanForBootloaders()
AddMenuEntry(&MainMenu, &MenuEntryReset);
break;
case TAG_ABOUT:
- Print(L"Adding menu entry for the 'about' tag....\n");
MenuEntryAbout.Image = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
AddMenuEntry(&MainMenu, &MenuEntryAbout);
break;
while (MainLoopRunning) {
MenuExit = RunMainMenu(&MainMenu, GlobalConfig.DefaultSelection, &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
// SetupScreen();
continue;
}
-
+
switch (ChosenEntry->Tag) {
case TAG_REBOOT: // Reboot
refit_call4_wrapper(RT->ResetSystem, EfiResetCold, EFI_SUCCESS, 0, NULL);
MainLoopRunning = FALSE; // just in case we get this far
break;
-
+
case TAG_SHUTDOWN: // Shut Down
TerminateScreen();
refit_call4_wrapper(RT->ResetSystem, EfiResetShutdown, EFI_SUCCESS, 0, NULL);
MainLoopRunning = FALSE; // just in case we get this far
break;
-
+
case TAG_ABOUT: // About rEFInd
AboutrEFInd();
break;
-
+
case TAG_LOADER: // Boot OS via .EFI loader
StartLoader((LOADER_ENTRY *)ChosenEntry);
break;
-
+
case TAG_LEGACY: // Boot legacy OS
StartLegacy((LEGACY_ENTRY *)ChosenEntry);
break;
-
+
case TAG_TOOL: // Start a EFI tool
StartTool((LOADER_ENTRY *)ChosenEntry);
break;
BeginTextScreen(L" ");
return EFI_SUCCESS;
break;
-
+
}
}