From: srs5694 Date: Thu, 2 Jan 2014 02:08:04 +0000 (-0500) Subject: Can now specify complete paths, optionally including volumes, in X-Git-Url: https://code.delx.au/refind/commitdiff_plain/0189958c722bdd4e7f323d59f81e25579bb0aad2 Can now specify complete paths, optionally including volumes, in dont_scan_files in refind.conf. --- diff --git a/NEWS.txt b/NEWS.txt index fcbfbcc..e2485d4 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,16 @@ 0.7.7 (12/??/2013): ------------------- +- Can now specify complete paths, optionally including volumes, in + dont_scan_files. + +- Added shimx64.efi to the default dont_scan_files list. + +- Added windows_recovery_files token, to specify what program(s) launch a + Windows recovery utility; and the "windows_recovery" option to + "showtools," to control whether or not to display the Windows recovery + utility on the second row of icons. + - The use_graphics_for, also_scan_dirs, dont_scan_dirs, dont_scan_files, and scan_driver_dirs tokens in refind.conf now support "+" as the first option, which causes the remaining options to be added to the default diff --git a/docs/refind/configfile.html b/docs/refind/configfile.html index 94a5b70..248af25 100644 --- a/docs/refind/configfile.html +++ b/docs/refind/configfile.html @@ -306,7 +306,7 @@ timeout 20 dont_scan_files or don't_scan_files filename(s) - Adds the specified filename or filenames to a filename "blacklist"—these files are not included as boot loader options even if they're found on the disk. This is useful to exclude support programs (such as shim.efi and MokManager.efi) and drivers from your OS list. The default value is shim.efi, shim-fedora.efi, PreLoader.efi, TextMode.efi, ebounce.efi, GraphicsConsole.efi, MokManager.efi, HashTool.efi, HashTool-signed.efi. To add files to the default list rather than replace the list, specify + as the first option, as in dont_scan_files + badloader.efi. + Adds the specified filename or filenames to a filename "blacklist"—these files are not included as boot loader options even if they're found on the disk. This is useful to exclude support programs (such as shim.efi and MokManager.efi) and drivers from your OS list. The default value is shim.efi, shim-fedora.efi, shimx64.efi, PreLoader.efi, TextMode.efi, ebounce.efi, GraphicsConsole.efi, MokManager.efi, HashTool.efi, HashTool-signed.efi. To add files to the default list rather than replace the list, specify + as the first option, as in dont_scan_files + badloader.efi. windows_recovery_files diff --git a/refind.conf-sample b/refind.conf-sample index 15beb1f..1a65a3a 100644 --- a/refind.conf-sample +++ b/refind.conf-sample @@ -242,12 +242,15 @@ timeout 20 # the main binary or if you want to "blacklist" certain loaders by # name rather than location, use this option. Note that this will # NOT prevent certain binaries from showing up in the second-row -# set of tools. Most notably, MokManager.efi is in this blacklist, -# but will show up as a tool if present in certain directories. You -# can control the tools row with the showtools token. -# The default is shim.efi,PreLoader.efi,TextMode.efi,ebounce.efi, -# GraphicsConsole.efi,MokManager.efi,HashTool.efi,HashTool-signed.efi, -# bootmgr.efi +# set of tools. Most notably, various Secure Boot and recovery +# tools are present in this list, but may appear as second-row +# items. +# The file may be specified as a bare name (e.g., "notme.efi"), as +# a complete filename (e.g., "/EFI/somedir/notme.efi"), or as a +# complete filename with volume (e.g., "SOMEDISK:/EFI/somedir/notme.efi"). +# The default is shim.efi,shim-fedora.efi,shimx64.efi,PreLoader.efi, +# TextMode.efi,ebounce.efi,GraphicsConsole.efi,MokManager.efi,HashTool.efi, +# HashTool-signed.efi,bootmgr.efi # #dont_scan_files shim.efi,MokManager.efi diff --git a/refind/config.c b/refind/config.c index cfd3f78..c56c54f 100644 --- a/refind/config.c +++ b/refind/config.c @@ -631,6 +631,8 @@ VOID ReadConfig(CHAR16 *FileName) FreeTokenLine(&TokenList, &TokenCount); } + if ((GlobalConfig.DontScanFiles) && (GlobalConfig.WindowsRecoveryFiles)) + MergeStrings(&(GlobalConfig.DontScanFiles), GlobalConfig.WindowsRecoveryFiles, L','); MyFreePool(File.Buffer); } /* VOID ReadConfig() */ diff --git a/refind/config.h b/refind/config.h index 45d1924..bbaa63b 100644 --- a/refind/config.h +++ b/refind/config.h @@ -81,7 +81,7 @@ typedef struct { #define CONFIG_FILE_NAME L"refind.conf" // Note: Below is combined with MOK_NAMES to make default -#define DONT_SCAN_FILES L"shim.efi,shim-fedora.efi,PreLoader.efi,TextMode.efi,ebounce.efi,GraphicsConsole.efi,bootmgr.efi" +#define DONT_SCAN_FILES L"shim.efi,shim-fedora.efi,shimx64.efi,PreLoader.efi,TextMode.efi,ebounce.efi,GraphicsConsole.efi,bootmgr.efi" #define DONT_SCAN_VOLUMES L"Recovery HD,LRS_ESP" #define ALSO_SCAN_DIRS L"boot" diff --git a/refind/lib.c b/refind/lib.c index c6a9257..a3a8cfe 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -1548,7 +1548,8 @@ CHAR16 *FindPath(IN CHAR16* FullPath) { LastBackslash = i; } // for PathOnly = StrDuplicate(FullPath); - PathOnly[LastBackslash] = 0; + if (PathOnly != NULL) + PathOnly[LastBackslash] = 0; } // if return (PathOnly); } @@ -1706,6 +1707,36 @@ INTN FindSubString(IN CHAR16 *SmallString, IN CHAR16 *BigString) { return Position; } // INTN FindSubString() +// Take an input path name, which may include a volume specification and/or +// a path, and return separate volume, path, and file names. For instance, +// "BIGVOL:\EFI\ubuntu\grubx64.efi" will return a VolName of "BIGVOL", a Path +// of "EFI\ubuntu", and a Filename of "grubx64.efi". If an element is missing, +// the returned pointer is NULL. The calling function is responsible for +// freeing the allocated memory. +VOID SplitPathName(CHAR16 *InPath, CHAR16 **VolName, CHAR16 **Path, CHAR16 **Filename) { + CHAR16 *Temp = NULL; + + MyFreePool(*VolName); + MyFreePool(*Path); + MyFreePool(*Filename); + *VolName = *Path = *Filename = NULL; + Temp = StrDuplicate(InPath); + SplitVolumeAndFilename(&Temp, VolName); // VolName is NULL or has volume; Temp has rest of path + CleanUpPathNameSlashes(Temp); + *Path = FindPath(Temp); // *Path has path (may be 0-length); Temp unchanged. + *Filename = StrDuplicate(Temp + StrLen(*Path)); + CleanUpPathNameSlashes(*Filename); + if (StrLen(*Path) == 0) { + MyFreePool(*Path); + *Path = NULL; + } + if (StrLen(*Filename) == 0) { + MyFreePool(*Filename); + *Filename = NULL; + } + MyFreePool(Temp); +} // VOID SplitPathName + // Returns TRUE if SmallString is an element in the comma-delimited List, // FALSE otherwise. Performs comparison case-insensitively (except on // buggy EFIs with case-sensitive StriCmp() functions). @@ -1720,9 +1751,63 @@ BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List) { Found = TRUE; } // while } // if - return Found; + return Found; } // BOOLEAN IsIn() +// Returns TRUE if specified Volume, Directory, and Filename correspond to an +// element in the comma-delimited List, FALSE otherwise. Note that Directory and +// Filename must *NOT* include a volume or path specification (that's part of +// the Volume variable), but the List elements may. Performs comparison +// case-insensitively (except on buggy EFIs with case-sensitive StriCmp() +// functions). +BOOLEAN FilenameIn(REFIT_VOLUME *Volume, CHAR16 *Directory, CHAR16 *Filename, CHAR16 *List) { + UINTN i = 0; + BOOLEAN Found = FALSE; + CHAR16 *OneElement; + CHAR16 *TargetVolName = NULL, *TargetPath = NULL, *TargetFilename = NULL; + + if (Filename && List) { + while (!Found && (OneElement = FindCommaDelimited(List, i++))) { + Found = TRUE; + SplitPathName(OneElement, &TargetVolName, &TargetPath, &TargetFilename); + VolumeNumberToName(Volume, &TargetVolName); + if (((TargetVolName != NULL) && ((Volume == NULL) || (StriCmp(TargetVolName, Volume->VolName) != 0))) || + ((TargetPath != NULL) && (StriCmp(TargetPath, Directory) != 0)) || + ((TargetFilename != NULL) && (StriCmp(TargetFilename, Filename) != 0))) { + Found = FALSE; + } // if + MyFreePool(OneElement); + } // while + } // if + + MyFreePool(TargetVolName); + MyFreePool(TargetPath); + MyFreePool(TargetFilename); + return Found; +} // BOOLEAN FilenameIn() + +// If *VolName is of the form "fs#", where "#" is a number, and if Volume points +// to this volume number, returns with *VolName changed to the volume name, as +// stored in the Volume data structure. +// Returns TRUE if this substitution was made, FALSE otherwise. +BOOLEAN VolumeNumberToName(REFIT_VOLUME *Volume, CHAR16 **VolName) { + BOOLEAN MadeSubstitution = FALSE; + UINTN VolNum; + + if ((VolName == NULL) || (*VolName == NULL)) + return 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) { + MyFreePool(*VolName); + *VolName = StrDuplicate(Volume->VolName); + MadeSubstitution = TRUE; + } // if + } // if + return MadeSubstitution; +} // BOOLEAN VolumeMatchesNumber() + // Implement FreePool the way it should have been done to begin with, so that // it doesn't throw an ASSERT message if fed a NULL pointer.... VOID MyFreePool(IN VOID *Pointer) { diff --git a/refind/lib.h b/refind/lib.h index bc3f870..b0f555d 100644 --- a/refind/lib.h +++ b/refind/lib.h @@ -115,7 +115,10 @@ BOOLEAN SplitVolumeAndFilename(IN OUT CHAR16 **Path, OUT CHAR16 **VolName); CHAR16 *FindNumbers(IN CHAR16 *InString); CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index); INTN FindSubString(IN CHAR16 *SmallString, IN CHAR16 *BigString); -BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List); +VOID SplitPathName(CHAR16 *InPath, CHAR16 **VolName, CHAR16 **Path, CHAR16 **Filename); +BOOLEAN IsIn(IN CHAR16 *Filename, IN CHAR16 *List); +BOOLEAN FilenameIn(IN REFIT_VOLUME *Volume, IN CHAR16 *Directory, IN CHAR16 *Filename, IN CHAR16 *List); +BOOLEAN VolumeNumberToName(REFIT_VOLUME *Volume, CHAR16 **VolName); VOID MyFreePool(IN OUT VOID *Pointer); BOOLEAN EjectMedia(VOID); diff --git a/refind/main.c b/refind/main.c index 30895bb..407239f 100644 --- a/refind/main.c +++ b/refind/main.c @@ -155,7 +155,7 @@ static VOID AboutrEFInd(VOID) { if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.6.2"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.6.3"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith"); @@ -1084,7 +1084,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)) @@ -1096,15 +1096,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); @@ -1115,14 +1109,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; @@ -1257,7 +1247,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) @@ -1308,7 +1298,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; @@ -1321,7 +1311,7 @@ static VOID ScanEfiFiles(REFIT_VOLUME *Volume) { // 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; @@ -1329,7 +1319,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; @@ -1339,14 +1329,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