+// Handle a parameter with a series of hexadecimal arguments, to replace or be added to a
+// linked list of UINT32 values. Any item with a non-hexadecimal value is discarded, as is
+// any value that exceeds MaxValue. If the first non-keyword token is "+", the new list is
+// added to the existing Target; otherwise, the interpreted tokens replace the current
+// Target.
+static VOID HandleHexes(IN CHAR16 **TokenList, IN UINTN TokenCount, IN UINTN MaxValue, OUT UINT32_LIST **Target) {
+ UINTN InputIndex = 1, i;
+ UINT32 Value;
+ UINT32_LIST *EndOfList = NULL;
+ UINT32_LIST *NewEntry;
+
+ if ((TokenCount > 2) && (StrCmp(TokenList[1], L"+") == 0)) {
+ InputIndex = 2;
+ EndOfList = *Target;
+ while (EndOfList && (EndOfList->Next != NULL)) {
+ EndOfList = EndOfList->Next;
+ }
+ } else {
+ EraseUint32List(Target);
+ }
+
+ for (i = InputIndex; i < TokenCount; i++) {
+ if (IsValidHex(TokenList[i])) {
+ Value = (UINT32) StrToHex(TokenList[i], 0, 8);
+ if (Value <= MaxValue) {
+ NewEntry = AllocatePool(sizeof(UINT32_LIST));
+ if (NewEntry) {
+ NewEntry->Value = Value;
+ NewEntry->Next = NULL;
+ if (EndOfList == NULL) {
+ EndOfList = NewEntry;
+ *Target = NewEntry;
+ } else {
+ EndOfList->Next = NewEntry;
+ EndOfList = NewEntry;
+ } // if/else
+ } // if allocated memory for NewEntry
+ } // if (Value < MaxValue)
+ } // if is valid hex value
+ } // for
+} // static VOID HandleHexes()
+
+// 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()
+
+static BOOLEAN HandleBoolean(IN CHAR16 **TokenList, IN UINTN TokenCount) {
+ BOOLEAN TruthValue = TRUE;
+
+ if ((TokenCount >= 2) && ((StrCmp(TokenList[1], L"0") == 0) ||
+ MyStriCmp(TokenList[1], L"false") ||
+ MyStriCmp(TokenList[1], L"off"))) {
+ 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) {
+ EFI_STATUS Status;
+ EFI_TIME CurrentTime;
+ UINTN StartTime, EndTime, 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()
+