X-Git-Url: https://code.delx.au/refind/blobdiff_plain/6ef8bde9b1d4e01507fe8a3ee6441b3266625145..cff588e1b33df1c292b3ae11a880e89092221b5f:/refind/main.c diff --git a/refind/main.c b/refind/main.c index 83c44e7..3581067 100644 --- a/refind/main.c +++ b/refind/main.c @@ -56,7 +56,9 @@ #include "../include/syslinux_mbr.h" #ifdef __MAKEWITH_GNUEFI +#ifndef EFI_SECURITY_VIOLATION #define EFI_SECURITY_VIOLATION EFIERR (26) +#endif #else #include "../EfiLib/BdsHelper.h" #include "../EfiLib/legacy.h" @@ -130,9 +132,10 @@ static REFIT_MENU_SCREEN MainMenu = { L"Main Menu", NULL, 0, NULL, 0, NULL 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, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - { TAG_SHELL, TAG_MEMTEST, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, - TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 } + BANNER_NOSCALE, + NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + { TAG_SHELL, TAG_MEMTEST, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, + TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 } }; EFI_GUID GlobalGuid = EFI_GLOBAL_VARIABLE; @@ -153,7 +156,7 @@ static VOID AboutrEFInd(VOID) { if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.5.2"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.7"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith"); @@ -930,7 +933,7 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo } // if // detect specific loaders - if (StriSubCmp(L"bzImage", LoaderPath) || StriSubCmp(L"vmlinuz", LoaderPath)) { + if (StriSubCmp(L"bzImage", FileName) || StriSubCmp(L"vmlinuz", FileName)) { GuessLinuxDistribution(&OSIconName, Volume, LoaderPath); MergeStrings(&OSIconName, L"linux", L','); Entry->OSType = 'L'; @@ -1082,7 +1085,7 @@ static VOID CleanUpLoaderList(struct LOADER_LIST *LoaderList) { // eligible for scanning. static BOOLEAN ShouldScan(REFIT_VOLUME *Volume, CHAR16 *Path) { CHAR16 *VolName = NULL, *DontScanDir, *PathCopy = NULL; - UINTN i = 0, VolNum; + UINTN i = 0; BOOLEAN ScanIt = TRUE; if (IsIn(Volume->VolName, GlobalConfig.DontScanVolumes)) @@ -1094,15 +1097,9 @@ static BOOLEAN ShouldScan(REFIT_VOLUME *Volume, CHAR16 *Path) { // See if Path includes an explicit volume declaration that's NOT Volume.... PathCopy = StrDuplicate(Path); if (SplitVolumeAndFilename(&PathCopy, &VolName)) { - if (StriCmp(VolName, Volume->VolName) != 0) { - 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) { - ScanIt = FALSE; - } - } else { - ScanIt = FALSE; - } + VolumeNumberToName(Volume, &VolName); + if (VolName && StriCmp(VolName, Volume->VolName) != 0) { + ScanIt = FALSE; } // if } // if Path includes volume specification MyFreePool(PathCopy); @@ -1113,14 +1110,10 @@ static BOOLEAN ShouldScan(REFIT_VOLUME *Volume, CHAR16 *Path) { while ((DontScanDir = FindCommaDelimited(GlobalConfig.DontScanDirs, i++)) && ScanIt) { SplitVolumeAndFilename(&DontScanDir, &VolName); CleanUpPathNameSlashes(DontScanDir); + VolumeNumberToName(Volume, &VolName); if (VolName != NULL) { if ((StriCmp(VolName, Volume->VolName) == 0) && (StriCmp(DontScanDir, Path) == 0)) ScanIt = FALSE; - 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; - } } else { if (StriCmp(DontScanDir, Path) == 0) ScanIt = FALSE; @@ -1255,7 +1248,7 @@ static BOOLEAN ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16 (StriCmp(DirEntry->FileName, FALLBACK_BASENAME) == 0 && (StriCmp(Path, L"EFI\\BOOT") == 0)) || StriSubCmp(L"shell", DirEntry->FileName) || IsSymbolicLink(Volume, Path, DirEntry) || /* is symbolic link */ - IsIn(DirEntry->FileName, GlobalConfig.DontScanFiles)) + FilenameIn(Volume, Path, DirEntry->FileName, GlobalConfig.DontScanFiles)) continue; // skip this if (Path) @@ -1306,7 +1299,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { EFI_STATUS Status; REFIT_DIR_ITER EfiDirIter; EFI_FILE_INFO *EfiDirEntry; - CHAR16 FileName[256], *Directory, *MatchPatterns, *VolName = NULL, *SelfPath; + CHAR16 FileName[256], *Directory = NULL, *MatchPatterns, *VolName = NULL, *SelfPath; UINTN i, Length; BOOLEAN ScanFallbackLoader = TRUE; BOOLEAN FoundBRBackup = FALSE; @@ -1315,11 +1308,11 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { if (GlobalConfig.ScanAllLinux) MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L','); - if ((Volume->RootDir != NULL) && (Volume->VolName != NULL)) { + if ((Volume->RootDir != NULL) && (Volume->VolName != NULL) && (Volume->IsReadable)) { // check for Mac OS X boot loader if (ShouldScan(Volume, L"System\\Library\\CoreServices")) { StrCpy(FileName, MACOSX_LOADER_PATH); - if (FileExists(Volume->RootDir, FileName) && !IsIn(L"boot.efi", GlobalConfig.DontScanFiles)) { + if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, Directory, L"boot.efi", GlobalConfig.DontScanFiles)) { AddLoaderEntry(FileName, L"Mac OS X", Volume); if (DuplicatesFallback(Volume, FileName)) ScanFallbackLoader = FALSE; @@ -1327,7 +1320,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { // check for XOM StrCpy(FileName, L"System\\Library\\CoreServices\\xom.efi"); - if (FileExists(Volume->RootDir, FileName) && !IsIn(L"boot.efi", GlobalConfig.DontScanFiles)) { + if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, Directory, L"boot.efi", GlobalConfig.DontScanFiles)) { AddLoaderEntry(FileName, L"Windows XP (XoM)", Volume); if (DuplicatesFallback(Volume, FileName)) ScanFallbackLoader = FALSE; @@ -1337,14 +1330,14 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { // check for Microsoft boot loader/menu if (ShouldScan(Volume, L"EFI\\Microsoft\\Boot")) { StrCpy(FileName, L"EFI\\Microsoft\\Boot\\bkpbootmgfw.efi"); - if (FileExists(Volume->RootDir, FileName) && !IsIn(L"bkpbootmgfw.efi", GlobalConfig.DontScanFiles)) { + if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, Directory, L"bkpbootmgfw.efi", GlobalConfig.DontScanFiles)) { AddLoaderEntry(FileName, L"Microsoft EFI boot (Boot Repair backup)", Volume); FoundBRBackup = TRUE; if (DuplicatesFallback(Volume, FileName)) ScanFallbackLoader = FALSE; } StrCpy(FileName, L"EFI\\Microsoft\\Boot\\bootmgfw.efi"); - if (FileExists(Volume->RootDir, FileName) && !IsIn(L"bootmgfw.efi", GlobalConfig.DontScanFiles)) { + if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, Directory, L"bootmgfw.efi", GlobalConfig.DontScanFiles)) { if (FoundBRBackup) AddLoaderEntry(FileName, L"Supposed Microsoft EFI boot (probably GRUB)", Volume); else @@ -2184,7 +2177,7 @@ static VOID ScanForBootloaders(VOID) { ScanLegacyExternal(); break; case 'm': case 'M': - ScanUserConfigured(CONFIG_FILE_NAME); + ScanUserConfigured(GlobalConfig.ConfigFilename); break; case 'e': case 'E': ScanExternal(); @@ -2233,7 +2226,7 @@ static VOID FindTool(CHAR16 *Locations, CHAR16 *Names, CHAR16 *Description, UINT // Add the second-row tags containing built-in and external tools (EFI shell, // reboot, etc.) static VOID ScanForTools(VOID) { - CHAR16 *FileName = NULL, *MokLocations, Description[256]; + CHAR16 *FileName = NULL, *VolName = NULL, *MokLocations, Description[256]; REFIT_MENU_ENTRY *TempMenuEntry; UINTN i, j, VolumeIndex; UINT64 osind; @@ -2311,12 +2304,31 @@ static VOID ScanForTools(VOID) { SPrint(Description, 255, L"Apple Recovery on %s", Volumes[VolumeIndex]->VolName); AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description, BuiltinIcon(BUILTIN_ICON_TOOL_APPLE_RESCUE), 'R', TRUE); - } + } // if } // for MyFreePool(FileName); FileName = NULL; break; + case TAG_WINDOWS_RECOVERY: + j = 0; + while ((FileName = FindCommaDelimited(GlobalConfig.WindowsRecoveryFiles, j++)) != NULL) { + SplitVolumeAndFilename(&FileName, &VolName); + for (VolumeIndex = 0; VolumeIndex < VolumesCount; VolumeIndex++) { + if ((Volumes[VolumeIndex]->RootDir != NULL) && (FileExists(Volumes[VolumeIndex]->RootDir, FileName)) && + ((VolName == NULL) || (StriCmp(VolName, Volumes[VolumeIndex]->VolName) == 0))) { + SPrint(Description, 255, L"Microsoft Recovery on %s", Volumes[VolumeIndex]->VolName); + AddToolEntry(Volumes[VolumeIndex]->DeviceHandle, FileName, Description, + BuiltinIcon(BUILTIN_ICON_TOOL_WINDOWS_RESCUE), 'R', TRUE); + } // if + } // for + } // while + MyFreePool(FileName); + FileName = NULL; + MyFreePool(VolName); + VolName = NULL; + break; + case TAG_MOK_TOOL: FindTool(MokLocations, MOK_NAMES, L"MOK utility utility", BUILTIN_ICON_TOOL_MOK_TOOL); break; @@ -2341,7 +2353,7 @@ VOID RescanAll(VOID) { FreeList((VOID ***) &(MainMenu.Entries), &MainMenu.EntryCount); MainMenu.Entries = NULL; MainMenu.EntryCount = 0; - ReadConfig(CONFIG_FILE_NAME); + ReadConfig(GlobalConfig.ConfigFilename); ConnectAllDriversToAllControllers(); ScanVolumes(); ScanForBootloaders(); @@ -2401,6 +2413,37 @@ static BOOLEAN SecureBootUninstall(VOID) { return Success; } // VOID SecureBootUninstall +// Sets the global configuration filename; will be CONFIG_FILE_NAME unless the +// "-c" command-line option is set, in which case that takes precedence. +// If an error is encountered, leaves the value alone (it should be set to +// CONFIG_FILE_NAME when GlobalConfig is initialized). +static VOID SetConfigFilename(EFI_HANDLE ImageHandle) { + EFI_LOADED_IMAGE *Info; + CHAR16 *Options, *FileName; + EFI_STATUS Status; + INTN Where; + + Status = uefi_call_wrapper(BS->HandleProtocol, 3, ImageHandle, + &LoadedImageProtocol, (VOID **) &Info); + if ((Status == EFI_SUCCESS) && (Info->LoadOptionsSize > 0)) { + Options = (CHAR16 *) Info->LoadOptions; + Where = FindSubString(L" -c ", Options); + if (Where >= 0) { + FileName = StrDuplicate(&Options[Where + 4]); + Where = FindSubString(L" ", FileName); + if (Where > 0) + FileName[Where] = L'\0'; + + if (FileExists(SelfDir, FileName)) { + GlobalConfig.ConfigFilename = FileName; + } else { + Print(L"Specified configuration file (%s) doesn't exist; using\n'refind.conf' default\n", FileName); + MyFreePool(FileName); + } // if/else + } // if + } // if +} // VOID SetConfigFilename() + // // main entry point // @@ -2427,7 +2470,8 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) FindLegacyBootType(); if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC) CopyMem(GlobalConfig.ScanFor, "ihebocm ", NUM_SCAN_OPTIONS); - ReadConfig(CONFIG_FILE_NAME); + SetConfigFilename(ImageHandle); + ReadConfig(GlobalConfig.ConfigFilename); ScanVolumes(); InitScreen();