X-Git-Url: https://code.delx.au/refind/blobdiff_plain/0b30b4435acdda47d9b598c25dd215ec6ba505a4..0189958c722bdd4e7f323d59f81e25579bb0aad2:/refind/config.c diff --git a/refind/config.c b/refind/config.c index ee9c818..c56c54f 100644 --- a/refind/config.c +++ b/refind/config.c @@ -60,6 +60,9 @@ #define ENCODING_UTF8 (1) #define ENCODING_UTF16_LE (2) +#define GetTime ST->RuntimeServices->GetTime +#define LAST_MINUTE 1439 /* Last minute of a day */ + static REFIT_MENU_ENTRY MenuEntryReturn = { L"Return to Main Menu", TAG_RETURN, 0, 0, 0, NULL, NULL, NULL }; // @@ -305,8 +308,12 @@ VOID FreeTokenLine(IN OUT CHAR16 ***TokenList, IN OUT UINTN *TokenCount) // handle a parameter with a single integer argument static VOID HandleInt(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT UINTN *Value) { - if (TokenCount == 2) - *Value = Atoi(TokenList[1]); + if (TokenCount == 2) { + if (StriCmp(TokenList[1], L"-1") == 0) + *Value = -1; + else + *Value = Atoi(TokenList[1]); + } } // handle a parameter with a single string argument @@ -317,22 +324,91 @@ static VOID HandleString(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 } // 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. 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; + + TimeLength = StrLen(TimeString); + while (i < TimeLength) { + if (TimeString[i] == L':') { + Hour = Minute; + Minute = 0; + } // if + if ((TimeString[i] >= L'0') && (TimeString[i] <= '9')) { + Minute *= 10; + Minute += (TimeString[i] - L'0'); + } // if + i++; + } // while + return (Hour * 60 + Minute); +} // BOOLEAN HandleTime() + +// 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) { + EFI_STATUS Status; + EFI_TIME CurrentTime; + UINTN StartTime = LAST_MINUTE + 1, EndTime = LAST_MINUTE + 1, Now; + BOOLEAN SetIt = FALSE; + + StartTime = HandleTime(TokenList[2]); + EndTime = HandleTime(TokenList[3]); + + 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 + Print(L"Warning: Impossible system time: %d:%d\n", CurrentTime.Hour, CurrentTime.Minute); + return; + } // if impossible time + + if (StartTime < EndTime) { // Time range does NOT cross midnight + if ((Now >= StartTime) && (Now <= EndTime)) + SetIt = TRUE; + } else { // Time range DOES cross midnight + if ((Now >= StartTime) && (Now <= EndTime)) + SetIt = TRUE; + } // if/else time range crosses midnight + + if (SetIt) { + MyFreePool(*Default); + *Default = StrDuplicate(TokenList[1]); + } // if (SetIt) + } // if ((StartTime <= LAST_MINUTE) && (EndTime <= LAST_MINUTE)) +} // VOID SetDefaultByTime() + // read config file VOID ReadConfig(CHAR16 *FileName) { @@ -344,7 +420,7 @@ VOID ReadConfig(CHAR16 *FileName) UINTN TokenCount, i; // 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); @@ -365,6 +441,7 @@ 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 if (!FileExists(SelfDir, FileName)) { @@ -441,6 +518,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)); @@ -462,6 +542,8 @@ 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) { @@ -483,7 +565,11 @@ VOID ReadConfig(CHAR16 *FileName) HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionBigFileName)); } else if (StriCmp(TokenList[0], L"default_selection") == 0) { - HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection)); + if (TokenCount == 4) { + SetDefaultByTime(TokenList, &(GlobalConfig.DefaultSelection)); + } else { + HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection)); + } } else if (StriCmp(TokenList[0], L"textonly") == 0) { if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) { @@ -506,7 +592,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; @@ -534,7 +621,8 @@ VOID ReadConfig(CHAR16 *FileName) } 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"include") == 0) && (TokenCount == 2) && + (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0)) { if (StriCmp(TokenList[1], FileName) != 0) { ReadConfig(TokenList[1]); } @@ -543,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() */ @@ -773,7 +863,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]); }