X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FDisplayEngineDxe%2FProcessOptions.c;h=557e8ecd9466af49ec051db2e34fb5dd16fb41f2;hb=7155d0a68c37461dcf5f39876d145799be481744;hp=1ab38b1df2e5fd8fbabfcba8874ebb8a97149f3b;hpb=bfae1330cc2e7749fcf349a3a633e2e77f5f01c9;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c index 1ab38b1df2..557e8ecd94 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c @@ -2,7 +2,7 @@ Implementation for handling the User Interface option processing. -Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Concatenate a narrow string to another string. @param Destination The destination string. + @param DestMax The Max length of destination string. @param Source The source string. The string to be concatenated. to the end of Destination. @@ -28,6 +29,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. VOID NewStrCat ( IN OUT CHAR16 *Destination, + IN UINTN DestMax, IN CHAR16 *Source ) { @@ -45,7 +47,7 @@ NewStrCat ( Destination[Length] = NARROW_CHAR; Length++; - StrCpy (Destination + Length, Source); + StrCpyS (Destination + Length, DestMax - Length, Source); } /** @@ -98,6 +100,107 @@ HiiValueToUINT64 ( return RetVal; } +/** + Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type. + + EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to + EFI_IFR_TYPE_BUFFER when do the value compare. + + @param Value Expression value to compare on. + + @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type. + @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type. + +**/ +BOOLEAN +IsTypeInBuffer ( + IN EFI_HII_VALUE *Value + ) +{ + switch (Value->Type) { + case EFI_IFR_TYPE_BUFFER: + case EFI_IFR_TYPE_DATE: + case EFI_IFR_TYPE_TIME: + case EFI_IFR_TYPE_REF: + return TRUE; + + default: + return FALSE; + } +} + +/** + Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64 + + @param Value Expression value to compare on. + + @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type. + @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type. + +**/ +BOOLEAN +IsTypeInUINT64 ( + IN EFI_HII_VALUE *Value + ) +{ + switch (Value->Type) { + case EFI_IFR_TYPE_NUM_SIZE_8: + case EFI_IFR_TYPE_NUM_SIZE_16: + case EFI_IFR_TYPE_NUM_SIZE_32: + case EFI_IFR_TYPE_NUM_SIZE_64: + case EFI_IFR_TYPE_BOOLEAN: + return TRUE; + + default: + return FALSE; + } +} + +/** + Return the buffer length and buffer pointer for this value. + + EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to + EFI_IFR_TYPE_BUFFER when do the value compare. + + @param Value Expression value to compare on. + @param Buf Return the buffer pointer. + @param BufLen Return the buffer length. + +**/ +VOID +GetBufAndLenForValue ( + IN EFI_HII_VALUE *Value, + OUT UINT8 **Buf, + OUT UINT16 *BufLen + ) +{ + switch (Value->Type) { + case EFI_IFR_TYPE_BUFFER: + *Buf = Value->Buffer; + *BufLen = Value->BufferLen; + break; + + case EFI_IFR_TYPE_DATE: + *Buf = (UINT8 *) (&Value->Value.date); + *BufLen = (UINT16) sizeof (EFI_HII_DATE); + break; + + case EFI_IFR_TYPE_TIME: + *Buf = (UINT8 *) (&Value->Value.time); + *BufLen = (UINT16) sizeof (EFI_HII_TIME); + break; + + case EFI_IFR_TYPE_REF: + *Buf = (UINT8 *) (&Value->Value.ref); + *BufLen = (UINT16) sizeof (EFI_HII_REF); + break; + + default: + *Buf = NULL; + *BufLen = 0; + } +} + /** Compare two Hii value. @@ -125,21 +228,12 @@ CompareHiiValue ( CHAR16 *Str1; CHAR16 *Str2; UINTN Len; + UINT8 *Buf1; + UINT16 Buf1Len; + UINT8 *Buf2; + UINT16 Buf2Len; - if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) { - if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) { - return EFI_UNSUPPORTED; - } - } - - if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) { - if (Value1->Type != Value2->Type) { - // - // Both Operator should be type of String - // - return EFI_UNSUPPORTED; - } - + if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) { if (Value1->Value.string == 0 || Value2->Value.string == 0) { // // StringId 0 is reserved @@ -174,22 +268,21 @@ CompareHiiValue ( return EFI_SUCCESS; } - if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) { - if (Value1->Type != Value2->Type) { - // - // Both Operator should be type of Buffer. - // - return EFI_UNSUPPORTED; - } - Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen; - *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len); - if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen)) - { + // + // Take types(date, time, ref, buffer) as buffer + // + if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) { + GetBufAndLenForValue(Value1, &Buf1, &Buf1Len); + GetBufAndLenForValue(Value2, &Buf2, &Buf2Len); + + Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len; + *Result = CompareMem (Buf1, Buf2, Len); + if ((*Result == 0) && (Buf1Len != Buf2Len)) { // // In this case, means base on samll number buffer, the data is same // So which value has more data, which value is bigger. // - *Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1; + *Result = Buf1Len > Buf2Len ? 1 : -1; } return EFI_SUCCESS; } @@ -197,16 +290,19 @@ CompareHiiValue ( // // Take remain types(integer, boolean, date/time) as integer // - Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2); - if (Temp64 > 0) { - *Result = 1; - } else if (Temp64 < 0) { - *Result = -1; - } else { - *Result = 0; + if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) { + Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2); + if (Temp64 > 0) { + *Result = 1; + } else if (Temp64 < 0) { + *Result = -1; + } else { + *Result = 0; + } + return EFI_SUCCESS; } - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } /** @@ -472,7 +568,6 @@ PrintFormattedNumber ( default: return EFI_UNSUPPORTED; - break; } UnicodeSPrint (FormattedNumber, BufferSize, Format, Value); @@ -719,6 +814,11 @@ PasswordProcess ( // // Password can't be set now. // + if (Status == EFI_UNSUPPORTED) { + do { + CreateDialog (&Key, gEmptyString, gPasswordUnsupported, gPressEnter, gEmptyString, NULL); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + } FreePool (StringPtr); return EFI_SUCCESS; } @@ -790,18 +890,8 @@ PasswordProcess ( gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen; gUserInput->InputValue.Type = Question->CurrentValue.Type; gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL); - FreePool (StringPtr); Status = EFI_SUCCESS; - - if (EFI_ERROR (Status)) { - // - // Reset state machine for password - // - Question->PasswordCheck (gFormData, Question, NULL); - } - - return Status; } else { // // Reset state machine for password @@ -817,7 +907,8 @@ PasswordProcess ( Status = EFI_INVALID_PARAMETER; } - + ZeroMem (TempString, (Maximum + 1) * sizeof (CHAR16)); + ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16)); FreePool (TempString); FreePool (StringPtr); @@ -861,16 +952,15 @@ ProcessOptions ( UINTN Index2; UINT8 *ValueArray; UINT8 ValueType; - EFI_STRING_ID StringId; EFI_IFR_ORDERED_LIST *OrderList; BOOLEAN ValueInvalid; + UINTN MaxLen; Status = EFI_SUCCESS; StringPtr = NULL; Character[1] = L'\0'; *OptionString = NULL; - StringId = 0; ValueInvalid = FALSE; ZeroMem (FormattedNumber, 21 * sizeof (CHAR16)); @@ -907,7 +997,8 @@ ProcessOptions ( // We now know how many strings we will have, so we can allocate the // space required for the array or strings. // - *OptionString = AllocateZeroPool (OrderList->MaxContainers * BufferSize); + MaxLen = OrderList->MaxContainers * BufferSize / sizeof (CHAR16); + *OptionString = AllocateZeroPool (MaxLen * sizeof (CHAR16)); ASSERT (*OptionString); HiiValue.Type = ValueType; @@ -942,7 +1033,7 @@ ProcessOptions ( // Exit current DisplayForm with new value. // gUserInput->SelectedStatement = Question; - + gMisMatch = TRUE; ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen); ASSERT (ValueArray != NULL); gUserInput->InputValue.Buffer = ValueArray; @@ -965,14 +1056,14 @@ ProcessOptions ( } Character[0] = LEFT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); ASSERT (StringPtr != NULL); - NewStrCat (OptionString[0], StringPtr); + NewStrCat (OptionString[0], MaxLen, StringPtr); Character[0] = RIGHT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); Character[0] = CHAR_CARRIAGE_RETURN; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); FreePool (StringPtr); } @@ -1000,14 +1091,14 @@ ProcessOptions ( // Not report error, just get the correct option string info. // Character[0] = LEFT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); ASSERT (StringPtr != NULL); - NewStrCat (OptionString[0], StringPtr); + NewStrCat (OptionString[0], MaxLen, StringPtr); Character[0] = RIGHT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); Character[0] = CHAR_CARRIAGE_RETURN; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); FreePool (StringPtr); continue; @@ -1027,7 +1118,7 @@ ProcessOptions ( // Exit current DisplayForm with new value. // gUserInput->SelectedStatement = Question; - + gMisMatch = TRUE; ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer); ASSERT (ValueArray != NULL); gUserInput->InputValue.Buffer = ValueArray; @@ -1059,6 +1150,7 @@ ProcessOptions ( // Status = GetSelectionInputPopUp (MenuOption); } else { + MaxLen = BufferSize / sizeof(CHAR16); *OptionString = AllocateZeroPool (BufferSize); ASSERT (*OptionString); @@ -1104,7 +1196,7 @@ ProcessOptions ( break; } gUserInput->SelectedStatement = Question; - + gMisMatch = TRUE; FreePool (*OptionString); *OptionString = NULL; return EFI_NOT_FOUND; @@ -1112,12 +1204,12 @@ ProcessOptions ( } Character[0] = LEFT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); ASSERT (StringPtr != NULL); - NewStrCat (OptionString[0], StringPtr); + NewStrCat (OptionString[0], MaxLen, StringPtr); Character[0] = RIGHT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], Character); + NewStrCat (OptionString[0], MaxLen, Character); FreePool (StringPtr); } @@ -1186,19 +1278,31 @@ ProcessOptions ( switch (MenuOption->Sequence) { case 0: *OptionString[0] = LEFT_NUMERIC_DELIMITER; - UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month); + if (QuestionValue->Value.date.Month == 0xff){ + UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??"); + } else { + UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month); + } *(OptionString[0] + 3) = DATE_SEPARATOR; break; case 1: SetUnicodeMem (OptionString[0], 4, L' '); - UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day); + if (QuestionValue->Value.date.Day == 0xff){ + UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??"); + } else { + UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day); + } *(OptionString[0] + 6) = DATE_SEPARATOR; break; case 2: SetUnicodeMem (OptionString[0], 7, L' '); - UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year); + if (QuestionValue->Value.date.Year == 0xff){ + UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"????"); + } else { + UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year); + } *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER; break; } @@ -1218,19 +1322,31 @@ ProcessOptions ( switch (MenuOption->Sequence) { case 0: *OptionString[0] = LEFT_NUMERIC_DELIMITER; - UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour); + if (QuestionValue->Value.time.Hour == 0xff){ + UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??"); + } else { + UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour); + } *(OptionString[0] + 3) = TIME_SEPARATOR; break; case 1: SetUnicodeMem (OptionString[0], 4, L' '); - UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute); + if (QuestionValue->Value.time.Minute == 0xff){ + UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??"); + } else { + UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute); + } *(OptionString[0] + 6) = TIME_SEPARATOR; break; case 2: SetUnicodeMem (OptionString[0], 7, L' '); - UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second); + if (QuestionValue->Value.time.Second == 0xff){ + UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"??"); + } else { + UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second); + } *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER; break; }