X-Git-Url: https://code.delx.au/refind/blobdiff_plain/012b59e3b9537d04f9bd7f66a3d673fa999e80a4..6ef8bde9b1d4e01507fe8a3ee6441b3266625145:/refind/config.c diff --git a/refind/config.c b/refind/config.c index 97c62d6..f86edc8 100644 --- a/refind/config.c +++ b/refind/config.c @@ -1,5 +1,5 @@ /* - * refit/config.c + * refind/config.c * Configuration file functions * * Copyright (c) 2006 Christoph Pfisterer @@ -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 @@ -333,6 +340,85 @@ static VOID HandleStrings(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16 } } // 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() + +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 + if ((TimeString[i] >= L'0') && (TimeString[i] <= '9')) { + Minute *= 10; + Minute += (TimeString[i] - L'0'); + } // if + i++; + } // while + return (FoundColon ? Hour * 60 + Minute : LAST_MINUTE + 1); +} // 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); + 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) { @@ -340,7 +426,7 @@ VOID ReadConfig(CHAR16 *FileName) REFIT_FILE File; CHAR16 **TokenList; CHAR16 *FlagName; - CHAR16 *SelfPath = NULL; + CHAR16 *TempStr = NULL; UINTN TokenCount, i; // Set a few defaults only if we're loading the default file. @@ -350,15 +436,16 @@ VOID ReadConfig(CHAR16 *FileName) MyFreePool(GlobalConfig.DontScanDirs); if (SelfVolume) { if (SelfVolume->VolName) { - SelfPath = SelfVolume->VolName ? StrDuplicate(SelfVolume->VolName) : NULL; + TempStr = SelfVolume->VolName ? StrDuplicate(SelfVolume->VolName) : NULL; } else { - SelfPath = AllocateZeroPool(256 * sizeof(CHAR16)); - if (SelfPath != NULL) - SPrint(SelfPath, 255, L"fs%d", SelfVolume->VolNumber); + TempStr = AllocateZeroPool(256 * sizeof(CHAR16)); + if (TempStr != NULL) + SPrint(TempStr, 255, L"fs%d", SelfVolume->VolNumber); } // if/else } - MergeStrings(&SelfPath, SelfDirPath, L':'); - GlobalConfig.DontScanDirs = SelfPath; + MergeStrings(&TempStr, SelfDirPath, L':'); + MergeStrings(&TempStr, MEMTEST_LOCATIONS, L','); + GlobalConfig.DontScanDirs = TempStr; MyFreePool(GlobalConfig.DontScanFiles); GlobalConfig.DontScanFiles = StrDuplicate(DONT_SCAN_FILES); MergeStrings(&(GlobalConfig.DontScanFiles), MOK_NAMES, L','); @@ -465,6 +552,8 @@ VOID ReadConfig(CHAR16 *FileName) 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 { Print(L" unknown showtools flag: '%s'\n", FlagName); } @@ -480,7 +569,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)) { @@ -789,7 +882,7 @@ static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { UINTN TokenCount, i; REFIT_FILE *Options = NULL, *Fstab = NULL; EFI_STATUS Status; - CHAR16 **TokenList, Line[513], Root[100]; + CHAR16 **TokenList, *Line, Root[100]; if (FileExists(Volume->RootDir, L"\\etc\\fstab")) { Options = AllocateZeroPool(sizeof(REFIT_FILE)); @@ -804,7 +897,6 @@ static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { Fstab = NULL; } else { // File read; locate root fs and create entries Options->Encoding = ENCODING_UTF16_LE; - Line[0] = '\0'; while ((TokenCount = ReadTokenLine(Fstab, &TokenList)) > 0) { if (TokenCount > 2) { Root[0] = '\0'; @@ -817,9 +909,10 @@ static REFIT_FILE * GenerateOptionsFromEtcFstab(REFIT_VOLUME *Volume) { for (i = 0; i < StrLen(Root); i++) if (Root[i] == '\\') Root[i] = '/'; - SPrint(Line, 512, L"\"Boot with normal options\" \"ro root=%s\"\n", Root); + Line = PoolPrint(L"\"Boot with normal options\" \"ro root=%s\"\n", Root); MergeStrings((CHAR16 **) &(Options->Buffer), Line, 0); - SPrint(Line, 512, L"\"Boot into single-user mode\" \"ro root=%s single\"\n", Root); + MyFreePool(Line); + Line = PoolPrint(L"\"Boot into single-user mode\" \"ro root=%s single\"\n", Root); MergeStrings((CHAR16**) &(Options->Buffer), Line, 0); Options->BufferSize = StrLen((CHAR16*) Options->Buffer) * sizeof(CHAR16); } // if