X-Git-Url: https://code.delx.au/refind/blobdiff_plain/6ef8bde9b1d4e01507fe8a3ee6441b3266625145..2cc79ea9b33424d5fc32f15683adf7c956656b9b:/refind/config.c diff --git a/refind/config.c b/refind/config.c index f86edc8..9e5016b 100644 --- a/refind/config.c +++ b/refind/config.c @@ -35,7 +35,7 @@ */ /* - * Modifications copyright (c) 2012-2013 Roderick W. Smith + * Modifications copyright (c) 2012-2014 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 @@ -50,6 +50,7 @@ #include "config.h" #include "screen.h" #include "../include/refit_call_wrapper.h" +#include "../mok/mok.h" // constants @@ -318,60 +319,57 @@ static VOID HandleInt(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT UINTN *Val // handle a parameter with a single string argument static VOID HandleString(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 **Target) { - if (TokenCount == 2) { - MyFreePool(*Target); - *Target = StrDuplicate(TokenList[1]); + if ((TokenCount == 2) && Target) { + if ((StrLen(TokenList[1]) > 1) && (TokenList[1][0] == L'+') && + ((TokenList[1][1] == L',') || (TokenList[1][1] == L' '))) { + if (*Target) { + MergeStrings(Target, TokenList[1] + 2, L','); + } else { + *Target = StrDuplicate(TokenList[1] + 2); + } // if/else + } else { + MyFreePool(*Target); + *Target = StrDuplicate(TokenList[1]); + } // if/else } // if } // static VOID HandleString() -// Handle a parameter with a series of string arguments, to be added to a comma-delimited -// list. Passes each token through the CleanUpPathNameSlashes() function to ensure -// consistency in subsequent comparisons of filenames. +// Handle a parameter with a series of string arguments, to replace or be added to a +// comma-delimited list. Passes each token through the CleanUpPathNameSlashes() function +// to ensure consistency in subsequent comparisons of filenames. If the first +// non-keyword token is "+", the list is added to the existing target string; otherwise, +// the tokens replace the current string. static VOID HandleStrings(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 **Target) { UINTN i; + BOOLEAN AddMode = FALSE; + + if ((TokenCount > 2) && (StriCmp(TokenList[1], L"+") == 0)) { + AddMode = TRUE; + } - if (*Target != NULL) { + if ((*Target != NULL) && !AddMode) { FreePool(*Target); *Target = NULL; } // if for (i = 1; i < TokenCount; i++) { - CleanUpPathNameSlashes(TokenList[i]); - MergeStrings(Target, TokenList[i], L','); - } + if ((i != 1) || !AddMode) { + CleanUpPathNameSlashes(TokenList[i]); + MergeStrings(Target, TokenList[i], L','); + } // if + } // for } // static VOID HandleStrings() // Convert TimeString (in "HH:MM" format) to a pure-minute format. Values should be // in the range from 0 (for 00:00, or midnight) to 1439 (for 23:59; aka LAST_MINUTE). -// Any value outside that range denotes an error in the specification. -// static UINTN HandleTime(IN CHAR16 *TimeString) { -// BOOLEAN Found = FALSE; -// UINTN ColonPosition = 0, Hour = 0, Minute = 0, TimeLength; -// -// Print(L"Entering HandleTime('%s')\n", TimeString); -// TimeLength = StrLen(TimeString); -// for (ColonPosition = 0; (ColonPosition < TimeLength) && !Found; ColonPosition++) { -// Print(L"ColonPosition = %d\n", ColonPosition); -// if (TimeString[ColonPosition] == ':') -// Found = TRUE; -// } // for -// -// if ((ColonPosition == 0) || (ColonPosition > StrLen(TimeString))) -// return (LAST_MINUTE + 1); -// -// Hour = Atoi(TimeString); -// Minute = Atoi(&TimeString[ColonPosition + 1]); -// Print(L"Hour = %d, Minute = %d\n", Hour, Minute); -// return (Hour * 60 + Minute); -// } // BOOLEAN HandleTime() - +// Any value outside that range denotes an error in the specification. Note that if +// the input is a number that includes no colon, this function will return the original +// number in UINTN form. static UINTN HandleTime(IN CHAR16 *TimeString) { UINTN Hour = 0, Minute = 0, TimeLength, i = 0; - BOOLEAN FoundColon = FALSE; TimeLength = StrLen(TimeString); while (i < TimeLength) { if (TimeString[i] == L':') { - FoundColon = TRUE; Hour = Minute; Minute = 0; } // if @@ -381,9 +379,21 @@ static UINTN HandleTime(IN CHAR16 *TimeString) { } // if i++; } // while - return (FoundColon ? Hour * 60 + Minute : LAST_MINUTE + 1); + return (Hour * 60 + Minute); } // BOOLEAN HandleTime() +static BOOLEAN HandleBoolean(IN CHAR16 **TokenList, IN UINTN TokenCount) { + BOOLEAN TruthValue = TRUE; + + if ((TokenCount >= 2) && ((StriCmp(TokenList[1], L"0") == 0) || + (StriCmp(TokenList[1], L"false") == 0) || + (StriCmp(TokenList[1], L"off") == 0))) { + TruthValue = FALSE; + } // if + + return TruthValue; +} // BOOLEAN HandleBoolean + // Sets the default boot loader IF the current time is within the bounds // defined by the third and fourth tokens in the TokenList. static VOID SetDefaultByTime(IN CHAR16 **TokenList, OUT CHAR16 **Default) { @@ -397,6 +407,8 @@ static VOID SetDefaultByTime(IN CHAR16 **TokenList, OUT CHAR16 **Default) { if ((StartTime <= LAST_MINUTE) && (EndTime <= LAST_MINUTE)) { Status = refit_call2_wrapper(GetTime, &CurrentTime, NULL); + if (Status != EFI_SUCCESS) + return; Now = CurrentTime.Hour * 60 + CurrentTime.Minute; if (Now > LAST_MINUTE) { // Shouldn't happen; just being paranoid @@ -428,9 +440,10 @@ VOID ReadConfig(CHAR16 *FileName) CHAR16 *FlagName; CHAR16 *TempStr = NULL; UINTN TokenCount, i; + EFI_GUID RefindGuid = REFIND_GUID_VALUE; // Set a few defaults only if we're loading the default file. - if (StriCmp(FileName, CONFIG_FILE_NAME) == 0) { + if (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0) { MyFreePool(GlobalConfig.AlsoScan); GlobalConfig.AlsoScan = StrDuplicate(ALSO_SCAN_DIRS); MyFreePool(GlobalConfig.DontScanDirs); @@ -451,11 +464,23 @@ VOID ReadConfig(CHAR16 *FileName) MergeStrings(&(GlobalConfig.DontScanFiles), MOK_NAMES, L','); MyFreePool(GlobalConfig.DontScanVolumes); GlobalConfig.DontScanVolumes = StrDuplicate(DONT_SCAN_VOLUMES); + GlobalConfig.WindowsRecoveryFiles = StrDuplicate(WINDOWS_RECOVERY_FILES); + if (GlobalConfig.DefaultSelection != NULL) { + MyFreePool(GlobalConfig.DefaultSelection); + GlobalConfig.DefaultSelection = NULL; + } + Status = EfivarGetRaw(&RefindGuid, L"PreviousBoot", (CHAR8**) &(GlobalConfig.DefaultSelection), &i); + if (Status != EFI_SUCCESS) + GlobalConfig.DefaultSelection = NULL; } // if if (!FileExists(SelfDir, FileName)) { - Print(L"Configuration file '%s' missing!\n", FileName); - return; + Print(L"Configuration file '%s' missing!\n", FileName); + if (!FileExists(SelfDir, L"icons")) { + Print(L"Icons directory doesn't exist; setting textonly = TRUE!\n"); + GlobalConfig.TextOnly = TRUE; + } + return; } Status = ReadFile(SelfDir, FileName, &File, &i); @@ -507,6 +532,9 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.ScanFor[i] = ' '; } + } else if (StriCmp(TokenList[0], L"uefi_deep_legacy_scan") == 0) { + GlobalConfig.DeepLegacyScan = HandleBoolean(TokenList, TokenCount); + } else if ((StriCmp(TokenList[0], L"scan_delay") == 0) && (TokenCount == 2)) { HandleInt(TokenList, TokenCount, &(GlobalConfig.ScanDelay)); @@ -527,6 +555,9 @@ VOID ReadConfig(CHAR16 *FileName) } 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"windows_recovery_files") == 0) { + HandleStrings(TokenList, TokenCount, &(GlobalConfig.WindowsRecoveryFiles)); + } else if (StriCmp(TokenList[0], L"scan_driver_dirs") == 0) { HandleStrings(TokenList, TokenCount, &(GlobalConfig.DriverDirs)); @@ -538,6 +569,8 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.ShowTools[i - 1] = TAG_SHELL; } else if (StriCmp(FlagName, L"gptsync") == 0) { GlobalConfig.ShowTools[i - 1] = TAG_GPTSYNC; + } else if (StriCmp(FlagName, L"gdisk") == 0) { + GlobalConfig.ShowTools[i - 1] = TAG_GDISK; } else if (StriCmp(FlagName, L"about") == 0) { GlobalConfig.ShowTools[i - 1] = TAG_ABOUT; } else if (StriCmp(FlagName, L"exit") == 0) { @@ -548,12 +581,16 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.ShowTools[i - 1] = TAG_SHUTDOWN; } else if (StriCmp(FlagName, L"apple_recovery") == 0) { GlobalConfig.ShowTools[i - 1] = TAG_APPLE_RECOVERY; + } else if (StriCmp(FlagName, L"windows_recovery") == 0) { + GlobalConfig.ShowTools[i - 1] = TAG_WINDOWS_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 if ((StriCmp(FlagName, L"memtest86") == 0) || (StriCmp(FlagName, L"memtest") == 0)) { GlobalConfig.ShowTools[i - 1] = TAG_MEMTEST; + } else if (StriCmp(FlagName, L"netboot") == 0) { + GlobalConfig.ShowTools[i - 1] = TAG_NETBOOT; } else { Print(L" unknown showtools flag: '%s'\n", FlagName); } @@ -562,6 +599,27 @@ VOID ReadConfig(CHAR16 *FileName) } else if (StriCmp(TokenList[0], L"banner") == 0) { HandleString(TokenList, TokenCount, &(GlobalConfig.BannerFileName)); + } else if ((StriCmp(TokenList[0], L"banner_scale") == 0) && (TokenCount == 2)) { + if (StriCmp(TokenList[1], L"noscale") == 0) { + GlobalConfig.BannerScale = BANNER_NOSCALE; + } else if ((StriCmp(TokenList[1], L"fillscreen") == 0) || (StriCmp(TokenList[1], L"fullscreen") == 0)) { + GlobalConfig.BannerScale = BANNER_FILLSCREEN; + } else { + Print(L" unknown banner_type flag: '%s'\n", TokenList[1]); + } // if/else + + } else if ((StriCmp(TokenList[0], L"small_icon_size") == 0) && (TokenCount == 2)) { + HandleInt(TokenList, TokenCount, &i); + if (i >= 32) + GlobalConfig.IconSizes[ICON_SIZE_SMALL] = i; + + } else if ((StriCmp(TokenList[0], L"big_icon_size") == 0) && (TokenCount == 2)) { + HandleInt(TokenList, TokenCount, &i); + if (i >= 32) { + GlobalConfig.IconSizes[ICON_SIZE_BIG] = i; + GlobalConfig.IconSizes[ICON_SIZE_BADGE] = i / 4; + } + } else if (StriCmp(TokenList[0], L"selection_small") == 0) { HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionSmallFileName)); @@ -576,11 +634,7 @@ VOID ReadConfig(CHAR16 *FileName) } } else if (StriCmp(TokenList[0], L"textonly") == 0) { - if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) { - GlobalConfig.TextOnly = FALSE; - } else { - GlobalConfig.TextOnly = TRUE; - } + GlobalConfig.TextOnly = HandleBoolean(TokenList, TokenCount); } else if (StriCmp(TokenList[0], L"textmode") == 0) { HandleInt(TokenList, TokenCount, &(GlobalConfig.RequestedTextMode)); @@ -596,7 +650,8 @@ VOID ReadConfig(CHAR16 *FileName) HandleInt(TokenList, TokenCount, &(GlobalConfig.ScreensaverTime)); } else if (StriCmp(TokenList[0], L"use_graphics_for") == 0) { - GlobalConfig.GraphicsFor = 0; + if ((TokenCount == 2) || ((TokenCount > 2) && (StriCmp(TokenList[1], L"+") != 0))) + GlobalConfig.GraphicsFor = 0; for (i = 1; i < TokenCount; i++) { if (StriCmp(TokenList[i], L"osx") == 0) { GlobalConfig.GraphicsFor |= GRAPHICS_FOR_OSX; @@ -615,16 +670,16 @@ VOID ReadConfig(CHAR16 *FileName) egLoadFont(TokenList[1]); } else if (StriCmp(TokenList[0], L"scan_all_linux_kernels") == 0) { - if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) { - GlobalConfig.ScanAllLinux = FALSE; - } else { - GlobalConfig.ScanAllLinux = TRUE; - } + GlobalConfig.ScanAllLinux = HandleBoolean(TokenList, TokenCount); } 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)) { + } else if (StriCmp(TokenList[0], L"enable_and_lock_vmx") == 0) { + GlobalConfig.EnableAndLockVMX = HandleBoolean(TokenList, TokenCount); + + } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && + (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0)) { if (StriCmp(TokenList[1], FileName) != 0) { ReadConfig(TokenList[1]); } @@ -633,21 +688,33 @@ VOID ReadConfig(CHAR16 *FileName) FreeTokenLine(&TokenList, &TokenCount); } + if ((GlobalConfig.DontScanFiles) && (GlobalConfig.WindowsRecoveryFiles)) + MergeStrings(&(GlobalConfig.DontScanFiles), GlobalConfig.WindowsRecoveryFiles, L','); MyFreePool(File.Buffer); + + if (!FileExists(SelfDir, L"icons") && !FileExists(SelfDir, GlobalConfig.IconsDir)) { + Print(L"Icons directory doesn't exist; setting textonly = TRUE!\n"); + GlobalConfig.TextOnly = TRUE; + } } /* VOID ReadConfig() */ -// Finds a volume with the specified Identifier (a volume label or a number -// followed by a colon, for the moment). If found, sets *Volume to point to -// that volume. If not, leaves it unchanged. +// Finds a volume with the specified Identifier (a filesystem label, a +// partition name, a partition GUID, or a number followed by a colon). If +// found, sets *Volume to point to that volume. If not, leaves it unchanged. // Returns TRUE if a match was found, FALSE if not. static BOOLEAN FindVolume(REFIT_VOLUME **Volume, CHAR16 *Identifier) { - UINTN i = 0, CountedVolumes = 0; + UINTN i = 0, CountedVolumes = 0, Length; INTN Number = -1; - BOOLEAN Found = FALSE; + BOOLEAN Found = FALSE, IdIsGuid = FALSE; + EFI_GUID VolGuid, NullGuid = NULL_GUID_VALUE; - if ((StrLen(Identifier) >= 2) && (Identifier[StrLen(Identifier) - 1] == L':') && + VolGuid = StringAsGuid(Identifier); + Length = StrLen(Identifier); + if ((Length >= 2) && (Identifier[Length - 1] == L':') && (Identifier[0] >= L'0') && (Identifier[0] <= L'9')) { Number = (INTN) Atoi(Identifier); + } else if (IsGuid(Identifier)) { + IdIsGuid = TRUE; } while ((i < VolumesCount) && (!Found)) { if (Number >= 0) { // User specified a volume by number @@ -658,11 +725,18 @@ static BOOLEAN FindVolume(REFIT_VOLUME **Volume, CHAR16 *Identifier) { } CountedVolumes++; } // if - } else { // User specified a volume by label - if (StriCmp(Identifier, Volumes[i]->VolName) == 0) { + } else { // User specified a volume by label or GUID + if ((StriCmp(Identifier, Volumes[i]->VolName) == 0) || + (StriCmp(Identifier, Volumes[i]->PartName) == 0)) { *Volume = Volumes[i]; Found = TRUE; } // if + if (IdIsGuid && !Found) { + if (GuidsAreEqual(&VolGuid, &(Volumes[i]->PartGuid)) && !GuidsAreEqual(&NullGuid, &(Volumes[i]->PartGuid))) { + *Volume = Volumes[i]; + Found = TRUE; + } // if + } // if } // if/else i++; } // while() @@ -783,9 +857,9 @@ static LOADER_ENTRY * AddStanzaEntries(REFIT_FILE *File, REFIT_VOLUME *Volume, C } else if ((StriCmp(TokenList[0], L"icon") == 0) && (TokenCount > 1)) { MyFreePool(Entry->me.Image); - Entry->me.Image = egLoadIcon(CurrentVolume->RootDir, TokenList[1], 128); + Entry->me.Image = egLoadIcon(CurrentVolume->RootDir, TokenList[1], GlobalConfig.IconSizes[ICON_SIZE_BIG]); if (Entry->me.Image == NULL) { - Entry->me.Image = DummyImage(128); + Entry->me.Image = DummyImage(GlobalConfig.IconSizes[ICON_SIZE_BIG]); } } else if ((StriCmp(TokenList[0], L"initrd") == 0) && (TokenCount > 1)) { @@ -863,7 +937,8 @@ VOID ScanUserConfigured(CHAR16 *FileName) } // if/else MyFreePool(Title); - } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && (StriCmp(FileName, CONFIG_FILE_NAME) == 0)) { + } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && + (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0)) { if (StriCmp(TokenList[1], FileName) != 0) { ScanUserConfigured(TokenList[1]); }