-0.8.8 (3/??/2015):
+0.8.8 (6/??/2015):
------------------
+- Added new Linux root (/) partition auto-discovery feature, based on
+ Freedesktop.org's Discoverable Partitions Spec (DPS)
+ (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/):
+ If no refind_linux.conf file or /etc/fstab file is found, and if a
+ partition with the correct DPS type code for the system architecture is
+ found, rEFInd adds "ro root=/dev/disk/by-partuuid/{GUID}" to the kernel
+ options. This will not help on LVM setups, and will get it right for only
+ one installation on systems with multiple Linux installations, but it may
+ help some users, if/when the DPS type codes become more common.
+
- Fixed bug that caused a rEFInd crash if an empty refind_linux.conf
file was encountered.
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />\r
</head>\r
\r
+<meta name="viewport" content="width=device-width, initial-scale=1">\r
+\r
<body>\r
<h1>The rEFInd Boot Manager:<br />What's Your Boot Mode?</h1>\r
\r
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Configuring the Boot Manager</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Using EFI Drivers</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />rEFInd Features</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Getting rEFInd</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Installing rEFInd</h1>
<p class="sidebar"><b>Warning:</b> Windows 8 implements a fast shutdown feature that helps speed up shutdown and startup operations on a single-boot computer. Unfortunately, this feature can cause filesystem corruption if it's used on a multi-boot computer. You can disable the feature by launching an Administrator Command Prompt window and typing <tt class="userinput">powercfg /h off</tt> in it.</p>
+<p>I know relatively little about Windows EFI management tools; however, I do know that at least two relevant tools exist: the standard <tt>bcdedit</tt> and the third-party <i>EasyUEFI.</i></p>
+
+<p>The <a href="http://www.easyuefi.com/index-us.html">EasyUEFI tool</a> is a free (as in beer) GUI tool for managing EFI boot programs. I've only tried it once, and it seemed fairly intuitive and easy to use, but I don't have detailed instructions on how to use it. If you want to use EasyUEFI, you'll have to use it in place of <tt>bcdedit</tt> at the end of the following procedure.</p>
+
<p>Attempt this method of installation only on a UEFI-based PC; this method will not work on Windows that's installed on a Mac in BIOS/CSM/legacy mode. To install rEFInd under Windows, you must first find a way to access the ESP, which Windows normally hides from view. One way to accomplish this goal, and to proceed forward once the ESP is accessible, is as follows:</p>
<ol>
<li>Type <b><tt>rename refind.conf-sample refind.conf</tt></b> to rename rEFInd's configuration file.</li>
+<p class="sidebar"><b>Note:</b> I've heard from a couple of Windows 10 users that the <tt>bcdedit</tt> commands described here don't work. I don't yet know if this is a coincidence or if Microsoft has changed <tt>bcdedit</tt> in such a way that these instructions no longer apply. If you run into this problem, either try using EasyUEFI or use another installation method, such as the <a href="#linux">Linux method</a> from a Linux emergency boot disc.</p>
+
<li>Type <b><tt>bcdedit /set {bootmgr} path \EFI\refind\refind_x64.efi</tt></b> to set rEFInd as the default EFI boot program. Note that <tt>{bootmgr}</tt> is entered as such; that's not a notation for a variable. Also, change <tt>refind_x64.efi</tt> to <tt>refind_ia32.efi</tt> on systems with 32-bit EFIs. Such computers are rare, and most of them are tablets. Check your Windows bit depth to determine which binary you should use.</li>
<li>If you like, type <b><tt>bcdedit /set {bootmgr} description "<i>rEFInd description</i>"</tt></b> to set a description (change <tt><i>rEFInd description</i></tt> as you see fit).</li>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Methods of Booting Linux</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Revisions</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Managing Secure Boot</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Theming rEFInd</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />The Future of rEFInd</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />Using rEFInd</h1>
<link href="../Styles/styles.css" rel="stylesheet" type="text/css" />
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
<h1>The rEFInd Boot Manager:<br />rEFInd and Yosemite</h1>
return Options;
} // GenerateOptionsFromEtcFstab()
+// Create options from partition type codes. Specifically, if the earlier
+// partition scan found a partition with a type code corresponding to a root
+// filesystem according to the Freedesktop.org Discoverable Partitions Spec
+// (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/),
+// this function returns an appropriate file with two lines, one with
+// "ro root=PARTUUID={GUID}" and the other with that plus "single".
+// Note that this function returns the LAST partition found with the
+// appropriate type code, so this will work poorly on dual-boot systems or
+// if the type code is set incorrectly.
+static REFIT_FILE * GenerateOptionsFromPartTypes(VOID) {
+ REFIT_FILE *Options = NULL;
+ CHAR16 *Line, *GuidString;
+
+ if (GlobalConfig.DiscoveredRoot) {
+ Options = AllocateZeroPool(sizeof(REFIT_FILE));
+ if (Options) {
+ Options->Encoding = ENCODING_UTF16_LE;
+ GuidString = GuidAsString(&(GlobalConfig.DiscoveredRoot->PartGuid));
+ ToLower(GuidString);
+ if (GuidString) {
+ Line = PoolPrint(L"\"Boot with normal options\" \"ro root=/dev/disk/by-partuuid/%s\"\n", GuidString);
+ MergeStrings((CHAR16 **) &(Options->Buffer), Line, 0);
+ MyFreePool(Line);
+ Line = PoolPrint(L"\"Boot into single-user mode\" \"ro root=/dev/disk/by-partuuid/%s single\"\n", GuidString);
+ MergeStrings((CHAR16**) &(Options->Buffer), Line, 0);
+ MyFreePool(Line);
+ MyFreePool(GuidString);
+ } // if (GuidString)
+ Options->BufferSize = StrLen((CHAR16*) Options->Buffer) * sizeof(CHAR16);
+
+ Options->Current8Ptr = (CHAR8 *)Options->Buffer;
+ Options->End8Ptr = Options->Current8Ptr + Options->BufferSize;
+ Options->Current16Ptr = (CHAR16 *)Options->Buffer;
+ Options->End16Ptr = Options->Current16Ptr + (Options->BufferSize >> 1);
+ } // if (Options allocated OK)
+ } // if (partition has root GUID)
+ return Options;
+} // REFIT_FILE * GenerateOptionsFromPartTypes()
// Read a Linux kernel options file for a Linux boot loader into memory. The LoaderPath
// and Volume variables identify the location of the options file, but not its name --
} else { // a filename string is NULL
GoOn = FALSE;
} // if/else
- if (!FileFound)
- File = GenerateOptionsFromEtcFstab(Volume);
MyFreePool(OptionsFilename);
MyFreePool(FullFilename);
OptionsFilename = FullFilename = NULL;
} while (GoOn);
+ if (!FileFound) {
+ // No refind_linux.conf file; look for /etc/fstab and try to pull values from there....
+ File = GenerateOptionsFromEtcFstab(Volume);
+ // If still no joy, try to use Freedesktop.org Discoverable Partitions Spec....
+ if (!File)
+ File = GenerateOptionsFromPartTypes();
+ } // if
return (File);
} // static REFIT_FILE * ReadLinuxOptionsFile()
CHAR16 *PartName;
EFI_GUID VolUuid;
EFI_GUID PartGuid;
+ EFI_GUID PartTypeGuid;
UINTN VolNumber;
EG_IMAGE *VolIconImage;
EG_IMAGE *VolBadgeImage;
} LEGACY_ENTRY;
typedef struct {
- BOOLEAN TextOnly;
- BOOLEAN ScanAllLinux;
- BOOLEAN DeepLegacyScan;
- BOOLEAN EnableAndLockVMX;
- UINTN RequestedScreenWidth;
- UINTN RequestedScreenHeight;
- UINTN BannerBottomEdge;
- UINTN RequestedTextMode;
- UINTN Timeout;
- UINTN HideUIFlags;
- UINTN MaxTags; // max. number of OS entries to show simultaneously in graphics mode
- UINTN GraphicsFor;
- UINTN LegacyType;
- UINTN ScanDelay;
- UINTN ScreensaverTime;
- UINTN IconSizes[3];
- UINTN BannerScale;
- CHAR16 *BannerFileName;
- EG_IMAGE *ScreenBackground;
- CHAR16 *ConfigFilename;
- CHAR16 *SelectionSmallFileName;
- CHAR16 *SelectionBigFileName;
- CHAR16 *DefaultSelection;
- CHAR16 *AlsoScan;
- CHAR16 *DontScanVolumes;
- CHAR16 *DontScanDirs;
- CHAR16 *DontScanFiles;
- CHAR16 *WindowsRecoveryFiles;
- CHAR16 *DriverDirs;
- CHAR16 *IconsDir;
- UINTN ShowTools[NUM_TOOLS];
- CHAR8 ScanFor[NUM_SCAN_OPTIONS]; // codes of types of loaders for which to scan
+ BOOLEAN TextOnly;
+ BOOLEAN ScanAllLinux;
+ BOOLEAN DeepLegacyScan;
+ BOOLEAN EnableAndLockVMX;
+ UINTN RequestedScreenWidth;
+ UINTN RequestedScreenHeight;
+ UINTN BannerBottomEdge;
+ UINTN RequestedTextMode;
+ UINTN Timeout;
+ UINTN HideUIFlags;
+ UINTN MaxTags; // max. number of OS entries to show simultaneously in graphics mode
+ UINTN GraphicsFor;
+ UINTN LegacyType;
+ UINTN ScanDelay;
+ UINTN ScreensaverTime;
+ UINTN IconSizes[3];
+ UINTN BannerScale;
+ REFIT_VOLUME *DiscoveredRoot;
+ CHAR16 *BannerFileName;
+ EG_IMAGE *ScreenBackground;
+ CHAR16 *ConfigFilename;
+ CHAR16 *SelectionSmallFileName;
+ CHAR16 *SelectionBigFileName;
+ CHAR16 *DefaultSelection;
+ CHAR16 *AlsoScan;
+ CHAR16 *DontScanVolumes;
+ CHAR16 *DontScanDirs;
+ CHAR16 *DontScanFiles;
+ CHAR16 *WindowsRecoveryFiles;
+ CHAR16 *DriverDirs;
+ CHAR16 *IconsDir;
+ UINTN ShowTools[NUM_TOOLS];
+ CHAR8 ScanFor[NUM_SCAN_OPTIONS]; // codes of types of loaders for which to scan
} REFIT_CONFIG;
// Global variables
return Status;
} // EFI_STATUS ReadGptData()
+// // Look in gPartitions for a partition with the specified Guid. If found, return
+// // a pointer to that partition's name string. If not found, return a NULL pointer.
+// // The calling function is responsible for freeing the returned memory.
+// CHAR16 * PartNameFromGuid(EFI_GUID *Guid) {
+// UINTN i;
+// CHAR16 *Found = NULL;
+// GPT_DATA *GptData;
+//
+// if ((Guid == NULL) || (gPartitions == NULL))
+// return NULL;
+//
+// GptData = gPartitions;
+// while ((GptData != NULL) && (!Found)) {
+// i = 0;
+// while ((i < GptData->Header->entry_count) && (!Found)) {
+// if (GuidsAreEqual((EFI_GUID*) &(GptData->Entries[i].partition_guid), Guid))
+// Found = StrDuplicate(GptData->Entries[i].name);
+// else
+// i++;
+// } // while(scanning entries)
+// GptData = GptData->NextEntry;
+// } // while(scanning GPTs)
+// return Found;
+// } // CHAR16 * PartNameFromGuid()
+
// Look in gPartitions for a partition with the specified Guid. If found, return
-// a pointer to that partition's name string. If not found, return a NULL pointer.
+// a pointer to that partition's data. If not found, return a NULL pointer.
// The calling function is responsible for freeing the returned memory.
-CHAR16 * PartNameFromGuid(EFI_GUID *Guid) {
+GPT_ENTRY * FindPartWithGuid(EFI_GUID *Guid) {
UINTN i;
- CHAR16 *Found = NULL;
+ GPT_ENTRY *Found = NULL;
GPT_DATA *GptData;
if ((Guid == NULL) || (gPartitions == NULL))
while ((GptData != NULL) && (!Found)) {
i = 0;
while ((i < GptData->Header->entry_count) && (!Found)) {
- if (GuidsAreEqual((EFI_GUID*) &(GptData->Entries[i].partition_guid), Guid))
- Found = StrDuplicate(GptData->Entries[i].name);
- else
+ if (GuidsAreEqual((EFI_GUID*) &(GptData->Entries[i].partition_guid), Guid)) {
+ Found = AllocateZeroPool(sizeof(GPT_ENTRY));
+ CopyMem(Found, &GptData->Entries[i], sizeof(GPT_ENTRY));
+ } else {
i++;
+ } // if/else
} // while(scanning entries)
GptData = GptData->NextEntry;
} // while(scanning GPTs)
return Found;
-} // CHAR16 * PartNameFromGuid()
+} // GPT_ENTRY * FindPartWithGuid()
// Erase the gPartitions linked-list data structure
VOID ForgetPartitionTables(VOID) {
VOID ClearGptData(GPT_DATA *Data);
EFI_STATUS ReadGptData(REFIT_VOLUME *Volume, GPT_DATA **Data);
-CHAR16 * PartNameFromGuid(EFI_GUID *Guid);
+// CHAR16 * PartNameFromGuid(EFI_GUID *Guid);
+GPT_ENTRY * FindPartWithGuid(EFI_GUID *Guid);
VOID ForgetPartitionTables(VOID);
VOID AddPartitionTable(REFIT_VOLUME *Volume);
return FoundName;
} // static CHAR16 *GetVolumeName()
-// Determine the unique GUID and name of the volume and store them.
+// Determine the unique GUID, type code GUID, and name of the volume and store them.
static VOID SetPartGuidAndName(REFIT_VOLUME *Volume, EFI_DEVICE_PATH_PROTOCOL *DevicePath) {
HARDDRIVE_DEVICE_PATH *HdDevicePath;
+ GPT_ENTRY *PartInfo;
- if (Volume == NULL)
+ if ((Volume == NULL) || (DevicePath == NULL))
return;
if ((DevicePath->Type == MEDIA_DEVICE_PATH) && (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) {
HdDevicePath = (HARDDRIVE_DEVICE_PATH*) DevicePath;
if (HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) {
Volume->PartGuid = *((EFI_GUID*) HdDevicePath->Signature);
- Volume->PartName = PartNameFromGuid(&(Volume->PartGuid));
- } // if
- } // if
+ PartInfo = FindPartWithGuid(&(Volume->PartGuid));
+ if (PartInfo) {
+ Volume->PartName = StrDuplicate(PartInfo->name);
+ CopyMem(&(Volume->PartTypeGuid), PartInfo->type_guid, sizeof(EFI_GUID));
+ if (GuidsAreEqual (&(Volume->PartTypeGuid), &gFreedesktopRootGuid)) {
+ GlobalConfig.DiscoveredRoot = Volume;
+ Print(L"Found match!\n");
+ PauseForKey();
+ } // if (GUIDs match)
+ } // if (PartInfo exists)
+ } // if (GPT disk)
+ } // if (disk device)
} // VOID SetPartGuid()
// Return TRUE if NTFS boot files are found or if Volume is unreadable,
LastBufferSize = BufferSize = 256;
Buffer = AllocatePool(BufferSize);
for (IterCount = 0; ; IterCount++) {
+ Print(L"In DirNextEntry(), about to call Directory->Read()\n");
Status = refit_call3_wrapper(Directory->Read, Directory, &BufferSize, Buffer);
if (Status != EFI_BUFFER_TOO_SMALL || IterCount >= 4)
break;
return (Found);
} // BOOLEAN StriSubCmp()
+// Convert input string to all-lowercase.
+VOID ToLower(CHAR16 * MyString) {
+ UINTN i = 0;
+
+ if (MyString) {
+ while (MyString[i] != L'\0') {
+ if ((MyString[i] >= L'A') && (MyString[i] <= L'Z'))
+ MyString[i] = MyString[i] - L'A' + L'a';
+ i++;
+ } // while
+ } // if
+} // VOID ToLower()
+
// Merges two strings, creating a new one and returning a pointer to it.
// If AddChar != 0, the specified character is placed between the two original
// strings (unless the first string is NULL or empty). The original input
// Returns TRUE if the two GUIDs are equal, FALSE otherwise
BOOLEAN GuidsAreEqual(EFI_GUID *Guid1, EFI_GUID *Guid2) {
return (CompareMem(Guid1, Guid2, 16) == 0);
-} // BOOLEAN CompareGuids()
+} // BOOLEAN GuidsAreEqual()
// Partition names to be ignored when setting volume name
#define IGNORE_PARTITION_NAMES L"Microsoft basic data,Linux filesystem,Apple HFS/HFS+"
+extern EFI_GUID gFreedesktopRootGuid;
+
EFI_STATUS InitRefitLib(IN EFI_HANDLE ImageHandle);
VOID UninitRefitLib(VOID);
EFI_STATUS ReinitRefitLib(VOID);
VOID ReinitVolumes(VOID);
BOOLEAN StriSubCmp(IN CHAR16 *TargetStr, IN CHAR16 *BigStr);
+VOID ToLower(CHAR16 * MyString);
VOID MergeStrings(IN OUT CHAR16 **First, IN CHAR16 *Second, CHAR16 AddChar);
CHAR16 *FindExtension(IN CHAR16 *Path);
CHAR16 *FindLastDirName(IN CHAR16 *Path);
#define FALLBACK_FULLNAME L"EFI\\BOOT\\bootx64.efi"
#define FALLBACK_BASENAME L"bootx64.efi"
#define EFI_STUB_ARCH 0x8664
+EFI_GUID gFreedesktopRootGuid = { 0x4f68bce3, 0xe8cd, 0x4db1, { 0x96, 0xe7, 0xfb, 0xca, 0xf9, 0x84, 0xb7, 0x09 }};
#elif defined (EFI32)
#define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\EFI\\tools\\shellia32.efi,\\shell.efi,\\shellia32.efi"
#define GPTSYNC_NAMES L"\\EFI\\tools\\gptsync.efi,\\EFI\\tools\\gptsync_ia32.efi"
#define FALLBACK_FULLNAME L"EFI\\BOOT\\bootia32.efi"
#define FALLBACK_BASENAME L"bootia32.efi"
#define EFI_STUB_ARCH 0x014c
+EFI_GUID gFreedesktopRootGuid = { 0x44479540, 0xf297, 0x41b2, { 0x9a, 0xf7, 0xd1, 0x31, 0xd5, 0xf0, 0x45, 0x8a }};
#else
#define SHELL_NAMES L"\\EFI\\tools\\shell.efi,\\shell.efi"
#define GPTSYNC_NAMES L"\\EFI\\tools\\gptsync.efi"
#define DRIVER_DIRS L"drivers"
#define FALLBACK_FULLNAME L"EFI\\BOOT\\boot.efi" /* Not really correct */
#define FALLBACK_BASENAME L"boot.efi" /* Not really correct */
+// Below is GUID for ARM64
+EFI_GUID gFreedesktopRootGuid = { 0xb921b045, 0x1df0, 0x41c3, { 0xaf, 0x44, 0x4c, 0x6f, 0x28, 0x0d, 0x3f, 0xae }};
#endif
#define FAT_ARCH 0x0ef1fab9 /* ID for Apple "fat" binary */
REFIT_CONFIG GlobalConfig = { FALSE, TRUE, FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC,
0, 0, { DEFAULT_BIG_ICON_SIZE / 4, DEFAULT_SMALL_ICON_SIZE, DEFAULT_BIG_ICON_SIZE }, BANNER_NOSCALE,
- NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
{ TAG_SHELL, TAG_MEMTEST, TAG_GDISK, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL,
TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0, 0, 0 }
};
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.7.4");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.8.7.12");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2015 Roderick W. Smith");
BOOLEAN ScanFallbackLoader = TRUE;
BOOLEAN FoundBRBackup = FALSE;
- if ((Volume->RootDir != NULL) && (Volume->VolName != NULL) && (Volume->IsReadable)) {
+ if (Volume && (Volume->RootDir != NULL) && (Volume->VolName != NULL) && (Volume->IsReadable)) {
MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS);
if (GlobalConfig.ScanAllLinux)
MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
ScanFallbackLoader = FALSE;
}
StrCpy(FileName, L"EFI\\Microsoft\\Boot\\bootmgfw.efi");
- if (FileExists(Volume->RootDir, FileName) && !FilenameIn(Volume, L"EFI\\Microsoft\\Boot", L"bootmgfw.efi", GlobalConfig.DontScanFiles)) {
+ if (FileExists(Volume->RootDir, FileName) &&
+ !FilenameIn(Volume, L"EFI\\Microsoft\\Boot", L"bootmgfw.efi", GlobalConfig.DontScanFiles)) {
if (FoundBRBackup)
AddLoaderEntry(FileName, L"Supposed Microsoft EFI boot (probably GRUB)", Volume);
else