From: srs5694 Date: Sat, 5 Jan 2013 19:57:23 +0000 (-0500) Subject: New ability to specify volume labels in "dont_scan_dirs" token to X-Git-Url: https://code.delx.au/refind/commitdiff_plain/39f21d099c9fb310bae28b54dc68d266ed610ed7 New ability to specify volume labels in "dont_scan_dirs" token to limit blacklist to just one volume. --- diff --git a/Makefile b/Makefile index e219fef..e5e157b 100644 --- a/Makefile +++ b/Makefile @@ -16,22 +16,22 @@ EFILIB_DIR=EfiLib all: tiano gnuefi: - make -C $(LIBEG_DIR) - make -C $(MOK_DIR) - make -C $(LOADER_DIR) -# make -C $(FS_DIR) all_gnuefi + +make -C $(LIBEG_DIR) + +make -C $(MOK_DIR) + +make -C $(LOADER_DIR) +# +make -C $(FS_DIR) all_gnuefi fs: - make -C $(FS_DIR) + +make -C $(FS_DIR) fs_gnuefi: - make -C $(FS_DIR) all_gnuefi + +make -C $(FS_DIR) all_gnuefi tiano: - make AR_TARGET=EfiLib -C $(EFILIB_DIR) -f Make.tiano - make AR_TARGET=libeg -C $(LIBEG_DIR) -f Make.tiano - make AR_TARGET=mok -C $(MOK_DIR) -f Make.tiano - make BUILDME=refind DLL_TARGET=refind -C $(LOADER_DIR) -f Make.tiano + +make AR_TARGET=EfiLib -C $(EFILIB_DIR) -f Make.tiano + +make AR_TARGET=libeg -C $(LIBEG_DIR) -f Make.tiano + +make AR_TARGET=mok -C $(MOK_DIR) -f Make.tiano + +make BUILDME=refind DLL_TARGET=refind -C $(LOADER_DIR) -f Make.tiano clean: make -C $(LIBEG_DIR) clean diff --git a/NEWS.txt b/NEWS.txt index a6a8859..c5ce404 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,12 @@ 0.6.3 (?/?/2013): ----------------- +- Added the ability to specify a volume name or number in the + "dont_scan_dirs" token. + +- Fixed a bug that caused removable EFI media to not appear in scan lists + if rEFInd was installed as EFI/BOOT/boot{arch}.efi on a hard disk. + - Modified ISO-9660 driver so that it can handle discs with other than 2048-byte sectors. This makes it useful for reading "hybrid ISO" images burned to USB flash disks. diff --git a/docs/refind/configfile.html b/docs/refind/configfile.html index 345608e..9fa9eaa 100644 --- a/docs/refind/configfile.html +++ b/docs/refind/configfile.html @@ -225,7 +225,7 @@ timeout 20 dont_scan_dirs or don't_scan_dirs directory path(s) - Adds the specified directory or directories to a directory "blacklist"—these directories are not scanned for boot loaders, on any partition. This may be useful to keep duplicate boot loaders out of the menu (say, if EFI/Boot/bootx64.efi is a duplicate of another boot loader); or to keep drivers or utilities out of the boot menu, if you've stored them in a subdirectory of EFI. This option takes precedence over also_scan_dirs; if a directory appears in both lists, it will not be scanned. + Adds the specified directory or directories to a directory "blacklist"—these directories are not scanned for boot loaders. You may optionally precede a directory path with a volume name and a colon to limit the blacklist to that volume. For instance, EFI/BOOT prevents scanning the EFI/BOOT directory on all volumes, whereas ESP:EFI/BOOT blocks scans of EFI/BOOT on the volume called ESP but not on other volumes. You can use a filesystem number, as in fs0, in place of a volume name. This token may be useful to keep duplicate boot loaders out of the menu (say, if EFI/BOOT/bootx64.efi is a duplicate of another boot loader); or to keep drivers or utilities out of the boot menu, if you've stored them in a subdirectory of EFI. This option takes precedence over also_scan_dirs; if a directory appears in both lists, it will not be scanned. dont_scan_files or don't_scan_files diff --git a/filesystems/Makefile b/filesystems/Makefile index bc22314..cf60067 100644 --- a/filesystems/Makefile +++ b/filesystems/Makefile @@ -18,23 +18,23 @@ all: $(FILESYSTEMS) ext2: rm -f fsw_efi.obj - make DRIVERNAME=ext2 -f Make.tiano + +make DRIVERNAME=ext2 -f Make.tiano ext4: rm -f fsw_efi.obj - make DRIVERNAME=ext4 -f Make.tiano + +make DRIVERNAME=ext4 -f Make.tiano reiserfs: rm -f fsw_efi.obj - make DRIVERNAME=reiserfs -f Make.tiano + +make DRIVERNAME=reiserfs -f Make.tiano iso9660: rm -f fsw_efi.obj - make DRIVERNAME=iso9660 -f Make.tiano + +make DRIVERNAME=iso9660 -f Make.tiano hfs: rm -f fsw_efi.obj - make DRIVERNAME=hfs -f Make.tiano + +make DRIVERNAME=hfs -f Make.tiano # Build the drivers with GNU-EFI.... @@ -44,29 +44,29 @@ all_gnuefi: $(FILESYSTEMS_GNUEFI) ext2_gnuefi: rm -f fsw_efi.o - make DRIVERNAME=ext2 -f Make.gnuefi + +make DRIVERNAME=ext2 -f Make.gnuefi ext4_gnuefi: rm -f fsw_efi.o - make DRIVERNAME=ext4 -f Make.gnuefi + +make DRIVERNAME=ext4 -f Make.gnuefi reiserfs_gnuefi: rm -f fsw_efi.o - make DRIVERNAME=reiserfs -f Make.gnuefi + +make DRIVERNAME=reiserfs -f Make.gnuefi iso9660_gnuefi: rm -f fsw_efi.o - make DRIVERNAME=iso9660 -f Make.gnuefi + +make DRIVERNAME=iso9660 -f Make.gnuefi hfs_gnuefi: rm -f fsw_efi.o - make DRIVERNAME=hfs -f Make.gnuefi + +make DRIVERNAME=hfs -f Make.gnuefi # utility rules clean: rm -f *~ *.bak *.o *.obj *.so *.efi *.dll err.txt $(TEXTFILES) - make -C test clean + +make -C test clean install: diff --git a/mkdistrib b/mkdistrib index 972d74e..45fa0df 100755 --- a/mkdistrib +++ b/mkdistrib @@ -56,7 +56,7 @@ zip -9r refind-src-$1.zip refind-$1 # Build the IA32 binaries cd refind-$1 ARCH=ia32 make -j4 -ARCH=ia32 make -j4 fs +ARCH=ia32 make fs mkdir -p refind-bin-$1/refind/drivers_ia32 cp --preserve=timestamps drivers_ia32/*_ia32.efi refind-bin-$1/refind/drivers_ia32/ cp --preserve=timestamps filesystems/LICENSE*txt refind-bin-$1/refind/drivers_ia32/ @@ -66,7 +66,7 @@ cp refind/refind_ia32.efi $StartDir/ # Build the X64 binaries make clean make -j4 -make -j4 fs +make fs mkdir -p refind-bin-$1/refind/drivers_x64 cp -a icons refind-bin-$1/refind/ if [[ $SignIt == 1 ]] ; then diff --git a/refind/config.c b/refind/config.c index b1e0929..63d0f31 100644 --- a/refind/config.c +++ b/refind/config.c @@ -341,6 +341,7 @@ VOID ReadConfig(CHAR16 *FileName) REFIT_FILE File; CHAR16 **TokenList; CHAR16 *FlagName; + CHAR16 *SelfPath = NULL; UINTN TokenCount, i; // Set a few defaults only if we're loading the default file. @@ -350,7 +351,14 @@ VOID ReadConfig(CHAR16 *FileName) // MyFreePool(GlobalConfig.DontScanVolumes); // GlobalConfig.DontScanVolumes = StrDuplicate(L" "); MyFreePool(GlobalConfig.DontScanDirs); - GlobalConfig.DontScanDirs = StrDuplicate(SelfDirPath); + if (SelfVolume->VolName) { + SelfPath = StrDuplicate(SelfVolume->VolName); + } else { + SelfPath = AllocateZeroPool(256 * sizeof(CHAR16)); + SPrint(SelfPath, 255, L"fs%d", SelfVolume->VolNumber); + } // if/else + MergeStrings(&SelfPath, SelfDirPath, L':'); + GlobalConfig.DontScanDirs = SelfPath; MyFreePool(GlobalConfig.DontScanFiles); GlobalConfig.DontScanFiles = StrDuplicate(DONT_SCAN_FILES); } diff --git a/refind/global.h b/refind/global.h index 8fa2320..9d6b667 100644 --- a/refind/global.h +++ b/refind/global.h @@ -144,6 +144,7 @@ typedef struct { EFI_HANDLE DeviceHandle; EFI_FILE *RootDir; CHAR16 *VolName; + UINTN VolNumber; EG_IMAGE *VolIconImage; EG_IMAGE *VolBadgeImage; UINTN DiskKind; diff --git a/refind/lib.c b/refind/lib.c index b04b2d4..3c9e4c4 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -929,7 +929,7 @@ VOID ScanVolumes(VOID) MBR_PARTITION_INFO *MbrTable; UINTN PartitionIndex; UINT8 *SectorBuffer1, *SectorBuffer2; - UINTN SectorSum, i; + UINTN SectorSum, i, VolNumber = 0; MyFreePool(Volumes); Volumes = NULL; @@ -949,6 +949,8 @@ VOID ScanVolumes(VOID) Volume = AllocateZeroPool(sizeof(REFIT_VOLUME)); Volume->DeviceHandle = Handles[HandleIndex]; ScanVolume(Volume); + if (Volume->IsReadable) + Volume->VolNumber = VolNumber++; AddListElement((VOID ***) &Volumes, &VolumesCount, Volume); @@ -1520,6 +1522,39 @@ VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **Devi MyFreePool(DeviceString); } // VOID FindVolumeAndFilename() +// Splits a volume/filename string (e.g., "fs0:\EFI\BOOT") into separate +// volume and filename components (e.g., "fs0" and "\EFI\BOOT"), returning +// the filename component in the original *Path variable and the split-off +// volume component in the *VolName variable. +// Returns TRUE if both components are found, FALSE otherwise. +BOOLEAN SplitVolumeAndFilename(IN OUT CHAR16 **Path, OUT CHAR16 **VolName) { + UINTN i = 0, Length; + CHAR16 *Filename; + + if (*Path == NULL) + return FALSE; + + if (*VolName != NULL) { + MyFreePool(*VolName); + *VolName = NULL; + } + + Length = StrLen(*Path); + while ((i < Length) && ((*Path)[i] != L':')) { + i++; + } // while + + if (i < Length) { + Filename = StrDuplicate((*Path) + i + 1); + (*Path)[i] = 0; + *VolName = *Path; + *Path = Filename; + return TRUE; + } else { + return FALSE; + } +} // BOOLEAN SplitVolumeAndFilename() + // Returns all the digits in the input string, including intervening // non-digit characters. For instance, if InString is "foo-3.3.4-7.img", // this function returns "3.3.4-7". If InString contains no digits, diff --git a/refind/lib.h b/refind/lib.h index f1e2885..35a3740 100644 --- a/refind/lib.h +++ b/refind/lib.h @@ -109,6 +109,7 @@ CHAR16 *FindExtension(IN CHAR16 *Path); CHAR16 *FindLastDirName(IN CHAR16 *Path); CHAR16 *FindPath(IN CHAR16* FullPath); VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **DeviceVolume, OUT CHAR16 **loader); +BOOLEAN SplitVolumeAndFilename(IN OUT CHAR16 **Path, OUT CHAR16 **VolName); CHAR16 *FindNumbers(IN CHAR16 *InString); CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index); BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List); diff --git a/refind/main.c b/refind/main.c index 7dbc80a..67381c6 100644 --- a/refind/main.c +++ b/refind/main.c @@ -132,7 +132,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.2.1"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.2.2"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith"); @@ -893,6 +893,42 @@ static VOID CleanUpLoaderList(struct LOADER_LIST *LoaderList) { } // while } // static VOID CleanUpLoaderList() +// 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. +static BOOLEAN ShouldScan(REFIT_VOLUME *Volume, CHAR16 *Path) { + CHAR16 *VolName = NULL, *DontScanDir; + UINTN i = 0, VolNum; + BOOLEAN ScanIt = TRUE; + + if (IsIn(Volume->VolName, GlobalConfig.DontScanVolumes)) { + Print(L"Not scanning volume %s\n", Volume->VolName); + PauseForKey(); + return FALSE; + } + + while ((DontScanDir = FindCommaDelimited(GlobalConfig.DontScanDirs, i++)) && ScanIt) { + SplitVolumeAndFilename(&DontScanDir, &VolName); + CleanUpPathNameSlashes(DontScanDir); + if (VolName != NULL) { + if ((StriCmp(VolName, Volume->VolName) == 0) && (StriCmp(DontScanDir, Path))) + ScanIt = FALSE; + if ((VolName[0] == L'f') && (VolName[1] == L's') && (VolName[2] >= L'0') && (VolName[2] <= '9')) { + VolNum = Atoi(VolName + 2); + if ((VolNum == Volume->VolNumber) && (StriCmp(DontScanDir, Path))) + ScanIt = FALSE; + } + } else { + if (StriCmp(DontScanDir, Path) == 0) + ScanIt = FALSE; + } + MyFreePool(DontScanDir); + DontScanDir = NULL; + } + return ScanIt; +} // BOOLEAN ShouldScan() + // Scan an individual directory for EFI boot loader files and, if found, // add them to the list. Sorts the entries within the loader directory // so that the most recent one appears first in the list. @@ -906,8 +942,9 @@ static VOID ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16 *P if ((!SelfDirPath || !Path || ((StriCmp(Path, SelfDirPath) == 0) && (Volume->DeviceHandle != SelfVolume->DeviceHandle)) || (StriCmp(Path, SelfDirPath) != 0)) && - (!IsIn(Path, GlobalConfig.DontScanDirs)) && - (!IsIn(Volume->VolName, GlobalConfig.DontScanVolumes))) { + (ShouldScan(Volume, Path))) { +// (!IsIn(Path, GlobalConfig.DontScanDirs)) && +// (!IsIn(Volume->VolName, GlobalConfig.DontScanVolumes))) { // look through contents of the directory DirIterOpen(Volume->RootDir, Path, &DirIter); while (DirIterNext(&DirIter, 2, Pattern, &DirEntry)) {