*/
/*
- * Modifications copyright (c) 2012 Roderick W. Smith
+ * Modifications copyright (c) 2012-2013 Roderick W. Smith
*
* Modifications distributed under the terms of the GNU General Public
* License (GPL) version 3 (GPLv3), a copy of which must be distributed
// constants
-#define CONFIG_FILE_NAME L"refind.conf"
#define LINUX_OPTIONS_FILENAMES L"refind_linux.conf,refind-linux.conf"
#define MAXCONFIGFILESIZE (128*1024)
return Line;
}
+// Returns FALSE if *p points to the end of a token, TRUE otherwise.
+// Also modifies *p **IF** the first and second characters are both
+// quotes ('"'); it deletes one of them.
+static BOOLEAN KeepReading(IN OUT CHAR16 *p, IN OUT BOOLEAN *IsQuoted) {
+ BOOLEAN MoreToRead = FALSE;
+ CHAR16 *Temp = NULL;
+
+ if ((p == NULL) || (IsQuoted == NULL))
+ return FALSE;
+
+ if (*p == L'\0')
+ return FALSE;
+
+ if ((*p != ' ' && *p != '\t' && *p != '=' && *p != '#' && *p != ',') || *IsQuoted) {
+ MoreToRead = TRUE;
+ }
+ if (*p == L'"') {
+ if (p[1] == L'"') {
+ Temp = StrDuplicate(&p[1]);
+ if (Temp != NULL) {
+ StrCpy(p, Temp);
+ FreePool(Temp);
+ }
+ MoreToRead = TRUE;
+ } else {
+ *IsQuoted = !(*IsQuoted);
+ MoreToRead = FALSE;
+ } // if/else second character is a quote
+ } // if first character is a quote
+
+ return MoreToRead;
+} // BOOLEAN KeepReading()
+
//
// get a line of tokens from a file
//
-
UINTN ReadTokenLine(IN REFIT_FILE *File, OUT CHAR16 ***TokenList)
{
BOOLEAN LineFinished, IsQuoted = FALSE;
p = Line;
LineFinished = FALSE;
while (!LineFinished) {
- // skip whitespace
+ // skip whitespace & find start of token
while ((*p == ' ' || *p == '\t' || *p == '=' || *p == ',') && !IsQuoted)
p++;
if (*p == 0 || *p == '#')
Token = p;
// find end of token
- while (*p && *p != '"' && ((*p != ' ' && *p != '\t' && *p != '=' && *p != '#' && *p != ',') || IsQuoted)) {
- if ((*p == '/') && !IsQuoted) // Switch Unix-style to DOS-style directory separators
- *p = '\\';
+ while (KeepReading(p, &IsQuoted)) {
+ if ((*p == L'/') && !IsQuoted) // Switch Unix-style to DOS-style directory separators
+ *p = L'\\';
p++;
- } // if
- if (*p == '"')
- IsQuoted = !IsQuoted;
- if (*p == 0 || *p == '#')
+ } // while
+ if (*p == L'\0' || *p == L'#')
LineFinished = TRUE;
*p++ = 0;
} // static VOID HandleStrings()
// read config file
-VOID ReadConfig(VOID)
+VOID ReadConfig(CHAR16 *FileName)
{
EFI_STATUS Status;
REFIT_FILE File;
CHAR16 **TokenList;
CHAR16 *FlagName;
+ CHAR16 *SelfPath = NULL;
UINTN TokenCount, i;
- if (!FileExists(SelfDir, CONFIG_FILE_NAME)) {
- Print(L"Configuration file missing!\n");
+ // Set a few defaults only if we're loading the default file.
+ if (StriCmp(FileName, CONFIG_FILE_NAME) == 0) {
+ MyFreePool(GlobalConfig.AlsoScan);
+ GlobalConfig.AlsoScan = StrDuplicate(ALSO_SCAN_DIRS);
+ MyFreePool(GlobalConfig.DontScanDirs);
+ if (SelfVolume) {
+ if (SelfVolume->VolName) {
+ SelfPath = SelfVolume->VolName ? StrDuplicate(SelfVolume->VolName) : NULL;
+ } else {
+ SelfPath = AllocateZeroPool(256 * sizeof(CHAR16));
+ if (SelfPath != NULL)
+ 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);
+ MergeStrings(&(GlobalConfig.DontScanFiles), MOK_NAMES, L',');
+ MyFreePool(GlobalConfig.DontScanVolumes);
+ GlobalConfig.DontScanVolumes = StrDuplicate(DONT_SCAN_VOLUMES);
+ } // if
+
+ if (!FileExists(SelfDir, FileName)) {
+ Print(L"Configuration file '%s' missing!\n", FileName);
return;
}
- Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File, &i);
+ Status = ReadFile(SelfDir, FileName, &File, &i);
if (EFI_ERROR(Status))
return;
- GlobalConfig.DontScan = StrDuplicate(SelfDirPath);
-
for (;;) {
TokenCount = ReadTokenLine(&File, &TokenList);
if (TokenCount == 0)
} else if (StriCmp(FlagName, L"label") == 0) {
GlobalConfig.HideUIFlags |= HIDEUI_FLAG_LABEL;
} else if (StriCmp(FlagName, L"singleuser") == 0) {
- GlobalConfig.HideUIFlags |= HIDEUI_FLAG_SINGLEUSER;
+ GlobalConfig.HideUIFlags |= HIDEUI_FLAG_SINGLEUSER;
} else if (StriCmp(FlagName, L"hwtest") == 0) {
- GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HWTEST;
+ GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HWTEST;
} else if (StriCmp(FlagName, L"arrows") == 0) {
GlobalConfig.HideUIFlags |= HIDEUI_FLAG_ARROWS;
+ } else if (StriCmp(FlagName, L"hints") == 0) {
+ GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HINTS;
+ } else if (StriCmp(FlagName, L"editor") == 0) {
+ GlobalConfig.HideUIFlags |= HIDEUI_FLAG_EDITOR;
+ } else if (StriCmp(FlagName, L"safemode") == 0) {
+ GlobalConfig.HideUIFlags |= HIDEUI_FLAG_SAFEMODE;
} else if (StriCmp(FlagName, L"all") == 0) {
- GlobalConfig.HideUIFlags = HIDEUI_ALL;
+ GlobalConfig.HideUIFlags = HIDEUI_FLAG_ALL;
} else {
Print(L" unknown hideui flag: '%s'\n", FlagName);
}
} else if (StriCmp(TokenList[0], L"also_scan_dirs") == 0) {
HandleStrings(TokenList, TokenCount, &(GlobalConfig.AlsoScan));
+ } else if ((StriCmp(TokenList[0], L"don't_scan_volumes") == 0) || (StriCmp(TokenList[0], L"dont_scan_volumes") == 0)) {
+ // Note: Don't use HandleStrings() because it modifies slashes, which might be present in volume name
+ MyFreePool(GlobalConfig.DontScanVolumes);
+ GlobalConfig.DontScanVolumes = NULL;
+ for (i = 1; i < TokenCount; i++) {
+ MergeStrings(&GlobalConfig.DontScanVolumes, TokenList[i], L',');
+ }
+
} else if ((StriCmp(TokenList[0], L"don't_scan_dirs") == 0) || (StriCmp(TokenList[0], L"dont_scan_dirs") == 0)) {
- HandleStrings(TokenList, TokenCount, &(GlobalConfig.DontScan));
+ HandleStrings(TokenList, TokenCount, &(GlobalConfig.DontScanDirs));
+
+ } else if ((StriCmp(TokenList[0], L"don't_scan_files") == 0) || (StriCmp(TokenList[0], L"dont_scan_files") == 0)) {
+ HandleStrings(TokenList, TokenCount, &(GlobalConfig.DontScanFiles));
} else if (StriCmp(TokenList[0], L"scan_driver_dirs") == 0) {
HandleStrings(TokenList, TokenCount, &(GlobalConfig.DriverDirs));
GlobalConfig.ShowTools[i - 1] = TAG_APPLE_RECOVERY;
} else if (StriCmp(FlagName, L"mok_tool") == 0) {
GlobalConfig.ShowTools[i - 1] = TAG_MOK_TOOL;
+ } else if (StriCmp(FlagName, L"firmware") == 0) {
+ GlobalConfig.ShowTools[i - 1] = TAG_FIRMWARE;
} else {
Print(L" unknown showtools flag: '%s'\n", FlagName);
}
HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection));
} else if (StriCmp(TokenList[0], L"textonly") == 0) {
- GlobalConfig.TextOnly = TRUE;
+ if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) {
+ GlobalConfig.TextOnly = FALSE;
+ } else {
+ GlobalConfig.TextOnly = TRUE;
+ }
+
+ } else if (StriCmp(TokenList[0], L"textmode") == 0) {
+ HandleInt(TokenList, TokenCount, &(GlobalConfig.RequestedTextMode));
- } else if ((StriCmp(TokenList[0], L"resolution") == 0) && (TokenCount == 3)) {
+ } else if ((StriCmp(TokenList[0], L"resolution") == 0) && ((TokenCount == 2) || (TokenCount == 3))) {
GlobalConfig.RequestedScreenWidth = Atoi(TokenList[1]);
- GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
+ if (TokenCount == 3)
+ GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
+ else
+ GlobalConfig.RequestedScreenHeight = 0;
+
+ } else if (StriCmp(TokenList[0], L"screensaver") == 0) {
+ HandleInt(TokenList, TokenCount, &(GlobalConfig.ScreensaverTime));
} else if (StriCmp(TokenList[0], L"use_graphics_for") == 0) {
GlobalConfig.GraphicsFor = 0;
}
} // for (graphics_on tokens)
+ } else if ((StriCmp(TokenList[0], L"font") == 0) && (TokenCount == 2)) {
+ egLoadFont(TokenList[1]);
+
} else if (StriCmp(TokenList[0], L"scan_all_linux_kernels") == 0) {
- GlobalConfig.ScanAllLinux = TRUE;
+ if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) {
+ GlobalConfig.ScanAllLinux = FALSE;
+ } else {
+ GlobalConfig.ScanAllLinux = TRUE;
+ }
} else if (StriCmp(TokenList[0], L"max_tags") == 0) {
HandleInt(TokenList, TokenCount, &(GlobalConfig.MaxTags));
+ } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && (StriCmp(FileName, CONFIG_FILE_NAME) == 0)) {
+ if (StriCmp(TokenList[1], FileName) != 0) {
+ ReadConfig(TokenList[1]);
+ }
+
}
FreeTokenLine(&TokenList, &TokenCount);
} else if ((StriCmp(TokenList[0], L"icon") == 0) && (TokenCount > 1)) {
MyFreePool(Entry->me.Image);
- Entry->me.Image = LoadIcns(CurrentVolume->RootDir, TokenList[1], 128);
+ Entry->me.Image = egLoadIcon(CurrentVolume->RootDir, TokenList[1], 128);
if (Entry->me.Image == NULL) {
Entry->me.Image = DummyImage(128);
}
} // if
if (!DefaultsSet)
- SetLoaderDefaults(Entry, L"\\EFI\\BOOT\\nemo.efi", CurrentVolume); // user included no entry; use bogus one
+ SetLoaderDefaults(Entry, L"\\EFI\\BOOT\\nemo.efi", CurrentVolume); // user included no "loader" line; use bogus one
return(Entry);
} // static VOID AddStanzaEntries()
-// Read the user-configured loaders file, refind_loaders.conf, and add or delete
+// Read the user-configured menu entries from refind.conf and add or delete
// entries based on the contents of that file....
-VOID ScanUserConfigured(VOID)
+VOID ScanUserConfigured(CHAR16 *FileName)
{
EFI_STATUS Status;
REFIT_FILE File;
UINTN TokenCount, size;
LOADER_ENTRY *Entry;
- if (FileExists(SelfDir, CONFIG_FILE_NAME)) {
- Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File, &size);
+ if (FileExists(SelfDir, FileName)) {
+ Status = ReadFile(SelfDir, FileName, &File, &size);
if (EFI_ERROR(Status))
return;
MyFreePool(Entry);
} // if/else
MyFreePool(Title);
- } // if
+
+ } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && (StriCmp(FileName, CONFIG_FILE_NAME) == 0)) {
+ if (StriCmp(TokenList[1], FileName) != 0) {
+ ScanUserConfigured(TokenList[1]);
+ }
+
+ } // if/else if...
FreeTokenLine(&TokenList, &TokenCount);
} // while()
} // if()