X-Git-Url: https://code.delx.au/refind/blobdiff_plain/1a20b0a72c2e35ab33246c6886d39e8e0d0c10d7..19c2b1980d47f06866ac8e71d080a28a58f1a45e:/refind/main.c diff --git a/refind/main.c b/refind/main.c index 290d73e..1034927 100644 --- a/refind/main.c +++ b/refind/main.c @@ -64,10 +64,6 @@ // // variables -// #ifdef EFIX64 -// foo -// #endif - #define MACOSX_LOADER_PATH L"System\\Library\\CoreServices\\boot.efi" #if defined (EFIX64) #define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellx64.efi,\\shellx64.efi" @@ -110,8 +106,8 @@ static REFIT_MENU_SCREEN MainMenu = { L"Main Menu", NULL, 0, NULL, 0, NULL L"Insert or F2 for more options; Esc to refresh" }; static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL, L"Press Enter to return to main menu", L"" }; -REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, {TAG_SHELL, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }}; // Structure used to hold boot loader filenames and time stamps in @@ -132,7 +128,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.2.3"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.5.4"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith"); @@ -572,7 +568,17 @@ VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume) { SubEntry->LoadOptions = L"-v -s"; AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry); } // if - } // not single-user + } // single-user mode allowed + + if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_SAFEMODE)) { + SubEntry = InitializeLoaderEntry(Entry); + if (SubEntry != NULL) { + SubEntry->me.Title = L"Boot Mac OS X in safe mode"; + SubEntry->UseGraphicsMode = FALSE; + SubEntry->LoadOptions = L"-v -x"; + AddMenuEntry(SubScreen, (REFIT_MENU_ENTRY *)SubEntry); + } // if + } // safe mode allowed // check for Apple hardware diagnostics StrCpy(DiagsFileName, L"System\\Library\\CoreServices\\.diagnostics\\diags.efi"); @@ -598,12 +604,12 @@ VOID GenerateSubScreen(LOADER_ENTRY *Entry, IN REFIT_VOLUME *Volume) { // earlier.... if ((SubScreen->Entries != NULL) && (SubScreen->Entries[0] != NULL)) { MyFreePool(SubScreen->Entries[0]->Title); - SubScreen->Entries[0]->Title = StrDuplicate(TokenList[0]); + SubScreen->Entries[0]->Title = TokenList[0] ? StrDuplicate(TokenList[0]) : StrDuplicate(L"Boot Linux"); } // if FreeTokenLine(&TokenList, &TokenCount); while ((TokenCount = ReadTokenLine(File, &TokenList)) > 1) { SubEntry = InitializeLoaderEntry(Entry); - SubEntry->me.Title = StrDuplicate(TokenList[0]); + SubEntry->me.Title = TokenList[0] ? StrDuplicate(TokenList[0]) : StrDuplicate(L"Boot Linux"); MyFreePool(SubEntry->LoadOptions); SubEntry->LoadOptions = AddInitrdToOptions(TokenList[1], InitrdName); FreeTokenLine(&TokenList, &TokenCount); @@ -705,23 +711,26 @@ static CHAR16 * GetMainLinuxOptions(IN CHAR16 * LoaderPath, IN REFIT_VOLUME *Vol // code and shortcut letter. For Linux EFI stub loaders, also sets kernel options // that will (with luck) work fairly automatically. VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Volume) { - CHAR16 IconFileName[256]; - CHAR16 *FileName, *PathOnly, *OSIconName = NULL, *Temp, *SubString; + CHAR16 *FileName, *PathOnly, *IconNames = NULL, *NoExtension, *OSIconName = NULL, *Temp, *SubString; CHAR16 ShortcutLetter = 0; - UINTN i, Length; + UINTN i = 0, Length; FileName = Basename(LoaderPath); PathOnly = FindPath(LoaderPath); + NoExtension = StripEfiExtension(FileName); // locate a custom icon for the loader // Anything found here takes precedence over the "hints" in the OSIconName variable - StrCpy(IconFileName, LoaderPath); - ReplaceEfiExtension(IconFileName, L".icns"); - if (FileExists(Volume->RootDir, IconFileName)) { - Entry->me.Image = LoadIcns(Volume->RootDir, IconFileName, 128); - } else if ((StrLen(PathOnly) == 0) && (Volume->VolIconImage != NULL)) { + while ((Temp = FindCommaDelimited(ICON_EXTENSIONS, i++)) != NULL) { + MergeStrings(&IconNames, NoExtension, L','); + MergeStrings(&IconNames, Temp, L'.'); + MyFreePool(Temp); + } + if (!Entry->me.Image) + Entry->me.Image = LoadIcns(Volume->RootDir, IconNames, 128); + if (!Entry->me.Image) Entry->me.Image = Volume->VolIconImage; - } // icon matched to loader or volume + MyFreePool(IconNames); // Begin creating icon "hints" by using last part of directory path leading // to the loader @@ -896,7 +905,8 @@ static VOID CleanUpLoaderList(struct LOADER_LIST *LoaderList) { // Returns FALSE if the specified file/volume matches the GlobalConfig.DontScanDirs // or GlobalConfig.DontScanVolumes specification, or if Path points to a volume // other than the one specified by Volume. Returns TRUE if none of these conditions -// is true. Also reduces *Path to a path alone, with no volume specification. +// is met -- that is, if the path is eligible for scanning. Also reduces *Path to a +// path alone, with no volume specification. static BOOLEAN ShouldScan(REFIT_VOLUME *Volume, CHAR16 *Path) { CHAR16 *VolName = NULL, *DontScanDir; UINTN i = 0, VolNum; @@ -911,7 +921,7 @@ static BOOLEAN ShouldScan(REFIT_VOLUME *Volume, CHAR16 *Path) { if (VolName != NULL) { if ((StriCmp(VolName, Volume->VolName) == 0) && (StriCmp(DontScanDir, Path) == 0)) ScanIt = FALSE; - if ((VolName[0] == L'f') && (VolName[1] == L's') && (VolName[2] >= L'0') && (VolName[2] <= '9')) { + if ((StrLen(VolName) > 2) && (VolName[0] == L'f') && (VolName[1] == L's') && (VolName[2] >= L'0') && (VolName[2] <= L'9')) { VolNum = Atoi(VolName + 2); if ((VolNum == Volume->VolNumber) && (StriCmp(DontScanDir, Path) == 0)) ScanIt = FALSE; @@ -946,6 +956,7 @@ static VOID ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16 *P Extension = FindExtension(DirEntry->FileName); if (DirEntry->FileName[0] == '.' || StriCmp(Extension, L".icns") == 0 || + StriCmp(Extension, L".png") == 0 || StriSubCmp(L"shell", DirEntry->FileName) || IsIn(DirEntry->FileName, GlobalConfig.DontScanFiles)) continue; // skip this @@ -985,7 +996,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { REFIT_DIR_ITER EfiDirIter; EFI_FILE_INFO *EfiDirEntry; CHAR16 FileName[256], *Directory, *MatchPatterns, *VolName = NULL; - UINTN i, Length; + UINTN i, Length, VolNum; MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS); if (GlobalConfig.ScanAllLinux) @@ -1031,10 +1042,14 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { // Scan user-specified (or additional default) directories.... i = 0; while ((Directory = FindCommaDelimited(GlobalConfig.AlsoScan, i++)) != NULL) { + VolNum = VOL_DONTSCAN; SplitVolumeAndFilename(&Directory, &VolName); CleanUpPathNameSlashes(Directory); Length = StrLen(Directory); - if ((Length > 0) && ((VolName == NULL) || (StriCmp(VolName, Volume->VolName) == 0))) + if (VolName && (Length > 0) && (StrLen(VolName) > 2) && (VolName[0] == L'f') && (VolName[1] == L's') && + (VolName[2] >= L'0') && (VolName[2] <= L'9')) + VolNum = Atoi(VolName + 2); + if ((Length > 0) && ((VolName == NULL) || (StriCmp(VolName, Volume->VolName) == 0) || (Volume->VolNumber == VolNum))) ScanLoaderDir(Volume, Directory, MatchPatterns); MyFreePool(Directory); MyFreePool(VolName); @@ -1906,7 +1921,7 @@ static VOID ScanForTools(VOID) { } // while if (FileExists(SelfDir, L"MokManager.efi")) { MyFreePool(FileName); - FileName = StrDuplicate(SelfDirPath); + FileName = SelfDirPath ? StrDuplicate(SelfDirPath) : NULL; MergeStrings(&FileName, L"\\MokManager.efi", 0); SPrint(Description, 255, L"MOK Key Manager at %s", FileName); AddToolEntry(SelfLoadedImage->DeviceHandle, FileName, Description, @@ -2003,7 +2018,7 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) BOOLEAN MokProtocol; REFIT_MENU_ENTRY *ChosenEntry; UINTN MenuExit, i; - CHAR16 *Selection; + CHAR16 *Selection = NULL; EG_PIXEL BGColor; // bootstrap @@ -2017,6 +2032,7 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) FindLegacyBootType(); if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC) CopyMem(GlobalConfig.ScanFor, "ihebocm ", NUM_SCAN_OPTIONS); + ScanVolumes(); ReadConfig(CONFIG_FILE_NAME); InitScreen(); @@ -2027,12 +2043,12 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) refit_call4_wrapper(BS->SetWatchdogTimer, 0x0000, 0x0000, 0x0000, NULL); // further bootstrap (now with config available) - SetupScreen(); MokProtocol = SecureBootSetup(); - ScanVolumes(); +// ScanVolumes(); LoadDrivers(); ScanForBootloaders(); ScanForTools(); + SetupScreen(); if (GlobalConfig.ScanDelay > 0) { BGColor.b = 255; @@ -2045,7 +2061,9 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) RescanAll(); } // if - Selection = StrDuplicate(GlobalConfig.DefaultSelection); + if (GlobalConfig.DefaultSelection) + Selection = StrDuplicate(GlobalConfig.DefaultSelection); + while (MainLoopRunning) { MenuExit = RunMainMenu(&MainMenu, Selection, &ChosenEntry);