]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
MdeModulePkg/EbcDxe: Fix spelling mistake
[mirror_edk2.git] / MdeModulePkg / Universal / DisplayEngineDxe / ProcessOptions.c
index cf9f6836b3e4d47312def718942eed3f11bd789c..c02e36a63ad3ce50e6b357a636d518f6e2a731e1 100644 (file)
@@ -2,31 +2,20 @@
 Implementation for handling the User Interface option processing.\r
 \r
 \r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2020, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "FormDisplay.h"\r
 \r
-typedef struct {\r
-  EFI_EVENT   SyncEvent;\r
-  UINT8       *TimeOut;\r
-  CHAR16      *ErrorInfo;\r
-} WARNING_IF_CONTEXT;\r
-\r
 #define MAX_TIME_OUT_LEN  0x10\r
 \r
 /**\r
   Concatenate a narrow string to another string.\r
 \r
   @param Destination The destination string.\r
+  @param DestMax     The Max length of destination string.\r
   @param Source      The source string. The string to be concatenated.\r
                      to the end of Destination.\r
 \r
@@ -34,6 +23,7 @@ typedef struct {
 VOID\r
 NewStrCat (\r
   IN OUT CHAR16               *Destination,\r
+  IN     UINTN                DestMax,\r
   IN     CHAR16               *Source\r
   )\r
 {\r
@@ -51,7 +41,158 @@ NewStrCat (
   Destination[Length] = NARROW_CHAR;\r
   Length++;\r
 \r
-  StrCpy (Destination + Length, Source);\r
+  StrCpyS (Destination + Length, DestMax - Length, Source);\r
+}\r
+\r
+/**\r
+  Get UINT64 type value.\r
+\r
+  @param  Value                  Input Hii value.\r
+\r
+  @retval UINT64                 Return the UINT64 type value.\r
+\r
+**/\r
+UINT64\r
+HiiValueToUINT64 (\r
+  IN EFI_HII_VALUE      *Value\r
+  )\r
+{\r
+  UINT64  RetVal;\r
+\r
+  RetVal = 0;\r
+\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    RetVal = Value->Value.u8;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    RetVal = Value->Value.u16;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    RetVal = Value->Value.u32;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    RetVal = Value->Value.b;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_DATE:\r
+    RetVal = *(UINT64*) &Value->Value.date;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_TIME:\r
+    RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;\r
+    break;\r
+\r
+  default:\r
+    RetVal = Value->Value.u64;\r
+    break;\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type.\r
+\r
+  EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+  EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+  @param  Value                  Expression value to compare on.\r
+\r
+  @retval TRUE                   This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+  @retval FALSE                  This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInBuffer (\r
+  IN  EFI_HII_VALUE   *Value\r
+  )\r
+{\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_BUFFER:\r
+  case EFI_IFR_TYPE_DATE:\r
+  case EFI_IFR_TYPE_TIME:\r
+  case EFI_IFR_TYPE_REF:\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64\r
+\r
+  @param  Value                  Expression value to compare on.\r
+\r
+  @retval TRUE                   This value type can be transter to EFI_IFR_TYPE_BUFFER type.\r
+  @retval FALSE                  This value type can't be transter to EFI_IFR_TYPE_BUFFER type.\r
+\r
+**/\r
+BOOLEAN\r
+IsTypeInUINT64 (\r
+  IN  EFI_HII_VALUE   *Value\r
+  )\r
+{\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    return TRUE;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Return the buffer length and buffer pointer for this value.\r
+\r
+  EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to\r
+  EFI_IFR_TYPE_BUFFER when do the value compare.\r
+\r
+  @param  Value                  Expression value to compare on.\r
+  @param  Buf                    Return the buffer pointer.\r
+  @param  BufLen                 Return the buffer length.\r
+\r
+**/\r
+VOID\r
+GetBufAndLenForValue (\r
+  IN  EFI_HII_VALUE   *Value,\r
+  OUT UINT8           **Buf,\r
+  OUT UINT16          *BufLen\r
+  )\r
+{\r
+  switch (Value->Type) {\r
+  case EFI_IFR_TYPE_BUFFER:\r
+    *Buf    = Value->Buffer;\r
+    *BufLen = Value->BufferLen;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_DATE:\r
+    *Buf    = (UINT8 *) (&Value->Value.date);\r
+    *BufLen = (UINT16) sizeof (EFI_HII_DATE);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_TIME:\r
+    *Buf    = (UINT8 *) (&Value->Value.time);\r
+    *BufLen = (UINT16) sizeof (EFI_HII_TIME);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_REF:\r
+    *Buf    = (UINT8 *) (&Value->Value.ref);\r
+    *BufLen = (UINT16) sizeof (EFI_HII_REF);\r
+    break;\r
+\r
+  default:\r
+    *Buf    = NULL;\r
+    *BufLen = 0;\r
+  }\r
 }\r
 \r
 /**\r
@@ -81,21 +222,12 @@ CompareHiiValue (
   CHAR16  *Str1;\r
   CHAR16  *Str2;\r
   UINTN   Len;\r
+  UINT8   *Buf1;\r
+  UINT16  Buf1Len;\r
+  UINT8   *Buf2;\r
+  UINT16  Buf2Len;\r
 \r
-  if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
-    if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  }\r
-\r
-  if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
-    if (Value1->Type != Value2->Type) {\r
-      //\r
-      // Both Operator should be type of String\r
-      //\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
+  if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) {\r
     if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
       //\r
       // StringId 0 is reserved\r
@@ -130,39 +262,41 @@ CompareHiiValue (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
-    if (Value1->Type != Value2->Type) {\r
-      //\r
-      // Both Operator should be type of Buffer.\r
-      //\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-    Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
-    *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
-    if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
-    {\r
+  //\r
+  // Take types(date, time, ref, buffer) as buffer\r
+  //\r
+  if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) {\r
+    GetBufAndLenForValue(Value1, &Buf1, &Buf1Len);\r
+    GetBufAndLenForValue(Value2, &Buf2, &Buf2Len);\r
+\r
+    Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;\r
+    *Result = CompareMem (Buf1, Buf2, Len);\r
+    if ((*Result == 0) && (Buf1Len != Buf2Len)) {\r
       //\r
       // In this case, means base on samll number buffer, the data is same\r
       // So which value has more data, which value is bigger.\r
       //\r
-      *Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
+      *Result = Buf1Len > Buf2Len ? 1 : -1;\r
     }\r
     return EFI_SUCCESS;\r
-  }  \r
+  }\r
 \r
   //\r
   // Take remain types(integer, boolean, date/time) as integer\r
   //\r
-  Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
-  if (Temp64 > 0) {\r
-    *Result = 1;\r
-  } else if (Temp64 < 0) {\r
-    *Result = -1;\r
-  } else {\r
-    *Result = 0;\r
+  if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) {\r
+    Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);\r
+    if (Temp64 > 0) {\r
+      *Result = 1;\r
+    } else if (Temp64 < 0) {\r
+      *Result = -1;\r
+    } else {\r
+      *Result = 0;\r
+    }\r
+    return EFI_SUCCESS;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  return EFI_UNSUPPORTED;\r
 }\r
 \r
 /**\r
@@ -193,7 +327,7 @@ ValueToOption (
     ZeroMem (&Value, sizeof (EFI_HII_VALUE));\r
     Value.Type = Option->OptionOpCode->Type;\r
     CopyMem (&Value.Value, &Option->OptionOpCode->Value, Option->OptionOpCode->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
-    \r
+\r
     if ((CompareHiiValue (&Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
       return Option;\r
     }\r
@@ -301,12 +435,12 @@ SetArrayData (
   @param  Type                   Type of the data in this array.\r
   @param  Value                  The value to be find.\r
   @param  Index                  The index in the array which has same value with Value.\r
-  \r
+\r
   @retval   TRUE Found the value in the array.\r
   @retval   FALSE Not found the value.\r
 \r
 **/\r
-BOOLEAN \r
+BOOLEAN\r
 FindArrayData (\r
   IN VOID                     *Array,\r
   IN UINT8                    Type,\r
@@ -317,7 +451,7 @@ FindArrayData (
   UINTN  Count;\r
   UINT64 TmpValue;\r
   UINT64 ValueComp;\r
-  \r
+\r
   ASSERT (Array != NULL);\r
 \r
   Count    = 0;\r
@@ -428,7 +562,6 @@ PrintFormattedNumber (
 \r
   default:\r
     return EFI_UNSUPPORTED;\r
-    break;\r
   }\r
 \r
   UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);\r
@@ -617,143 +750,6 @@ RefreshTimeOutProcess (
   *(EventInfo->TimeOut) -= 1;\r
 }\r
 \r
-/**\r
-  Show the warning message.\r
-\r
-  @param   RetInfo    The input warning string and timeout info.\r
-\r
-**/\r
-VOID\r
-WarningIfCheck (\r
-  IN STATEMENT_ERROR_INFO  *RetInfo\r
-  )\r
-{\r
-  CHAR16             *ErrorInfo;\r
-  EFI_EVENT          WaitList[2];\r
-  EFI_EVENT          RefreshIntervalEvent;\r
-  EFI_EVENT          TimeOutEvent;\r
-  UINT8              TimeOut;\r
-  EFI_STATUS         Status;\r
-  UINTN              Index;\r
-  WARNING_IF_CONTEXT EventContext;\r
-  EFI_INPUT_KEY      Key;\r
-\r
-  TimeOutEvent         = NULL;\r
-  RefreshIntervalEvent = NULL;\r
-\r
-  ASSERT (RetInfo->StringId != 0);\r
-  ErrorInfo = GetToken (RetInfo->StringId, gFormData->HiiHandle);\r
-  TimeOut   = RetInfo->TimeOut;\r
-  if (RetInfo->TimeOut == 0) {\r
-    do {\r
-      CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
-    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-  } else {\r
-    Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    EventContext.SyncEvent = TimeOutEvent;\r
-    EventContext.TimeOut   = &TimeOut;\r
-    EventContext.ErrorInfo = ErrorInfo;\r
-\r
-    Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    //\r
-    // Show the dialog first to avoid long time not reaction.\r
-    //\r
-    gBS->SignalEvent (RefreshIntervalEvent);\r
-\r
-    Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    while (TRUE) {\r
-      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-      if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
-        break;\r
-      }\r
-\r
-      if (Status != EFI_NOT_READY) {\r
-        continue;\r
-      }\r
-\r
-      WaitList[0] = TimeOutEvent;\r
-      WaitList[1] = gST->ConIn->WaitForKey;\r
-\r
-      Status = gBS->WaitForEvent (2, WaitList, &Index);\r
-      ASSERT_EFI_ERROR (Status);\r
-\r
-      if (Index == 0) {\r
-        //\r
-        // Timeout occur, close the hoot time out event.\r
-        //\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  gBS->CloseEvent (TimeOutEvent);\r
-  gBS->CloseEvent (RefreshIntervalEvent);\r
-\r
-  FreePool (ErrorInfo);\r
-}\r
-\r
-/**\r
-  Process validate for one question.\r
-\r
-  @param  Question               The question need to be validate.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval EFI_INVALID_PARAMETER  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS \r
-ValidateQuestion (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question\r
-  )\r
-{\r
-  CHAR16                          *ErrorInfo;\r
-  EFI_INPUT_KEY                   Key;\r
-  EFI_STATUS                      Status;\r
-  STATEMENT_ERROR_INFO            RetInfo;\r
-  UINT32                          RetVal;\r
-\r
-  if (Question->ValidateQuestion == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Status = EFI_SUCCESS; \r
-  RetVal = Question->ValidateQuestion(gFormData, Question, &gUserInput->InputValue, &RetInfo);\r
\r
-  switch (RetVal) {\r
-  case INCOSISTENT_IF_TRUE:\r
-    //\r
-    // Condition meet, show up error message\r
-    //\r
-    ASSERT (RetInfo.StringId != 0);\r
-    ErrorInfo = GetToken (RetInfo.StringId, gFormData->HiiHandle);\r
-    do {\r
-      CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
-    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-    FreePool (ErrorInfo);\r
-\r
-    Status = EFI_INVALID_PARAMETER;\r
-    break;\r
-\r
-  case WARNING_IF_TRUE:\r
-    //\r
-    // Condition meet, show up warning message\r
-    //\r
-    WarningIfCheck (&RetInfo);\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
   Display error message for invalid password.\r
 \r
@@ -802,7 +798,7 @@ PasswordProcess (
 \r
   StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));\r
   ASSERT (StringPtr);\r
-  \r
+\r
   //\r
   // Use a NULL password to test whether old password is required\r
   //\r
@@ -810,8 +806,13 @@ PasswordProcess (
   Status = Question->PasswordCheck (gFormData, Question, StringPtr);\r
   if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {\r
     //\r
-    // Password can't be set now. \r
+    // Password can't be set now.\r
     //\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      do {\r
+        CreateDialog (&Key, gEmptyString, gPasswordUnsupported, gPressEnter, gEmptyString, NULL);\r
+      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+    }\r
     FreePool (StringPtr);\r
     return EFI_SUCCESS;\r
   }\r
@@ -822,6 +823,7 @@ PasswordProcess (
     //\r
     Status = ReadString (MenuOption, gPromptForPassword, StringPtr);\r
     if (EFI_ERROR (Status)) {\r
+      ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
       FreePool (StringPtr);\r
       return Status;\r
     }\r
@@ -839,12 +841,12 @@ PasswordProcess (
       } else {\r
         Status = EFI_SUCCESS;\r
       }\r
-\r
+      ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
       FreePool (StringPtr);\r
       return Status;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Ask for new password\r
   //\r
@@ -855,10 +857,11 @@ PasswordProcess (
     // Reset state machine for password\r
     //\r
     Question->PasswordCheck (gFormData, Question, NULL);\r
+    ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
     FreePool (StringPtr);\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Confirm new password\r
   //\r
@@ -870,37 +873,29 @@ PasswordProcess (
     // Reset state machine for password\r
     //\r
     Question->PasswordCheck (gFormData, Question, NULL);\r
+    ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
+    ZeroMem (TempString, (Maximum + 1) * sizeof (CHAR16));\r
     FreePool (StringPtr);\r
     FreePool (TempString);\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Compare two typed-in new passwords\r
   //\r
-  if (StrCmp (StringPtr, TempString) == 0) {     \r
+  if (StrCmp (StringPtr, TempString) == 0) {\r
     gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);\r
     gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
     gUserInput->InputValue.Type = Question->CurrentValue.Type;\r
     gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);\r
-    FreePool (StringPtr); \r
 \r
-    Status = ValidateQuestion (Question);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      //\r
-      // Reset state machine for password\r
-      //\r
-      Question->PasswordCheck (gFormData, Question, NULL);\r
-    }\r
-\r
-    return Status;\r
+    Status = EFI_SUCCESS;\r
   } else {\r
     //\r
     // Reset state machine for password\r
     //\r
     Question->PasswordCheck (gFormData, Question, NULL);\r
-  \r
+\r
     //\r
     // Two password mismatch, prompt error message\r
     //\r
@@ -910,13 +905,124 @@ PasswordProcess (
 \r
     Status = EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+  ZeroMem (TempString, (Maximum + 1) * sizeof (CHAR16));\r
+  ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
   FreePool (TempString);\r
   FreePool (StringPtr);\r
 \r
   return Status;\r
 }\r
 \r
+/**\r
+  Print some debug message about mismatched menu info.\r
+\r
+  @param  MenuOption             The MenuOption for this Question.\r
+\r
+**/\r
+VOID\r
+PrintMismatchMenuInfo (\r
+  IN  UI_MENU_OPTION              *MenuOption\r
+)\r
+{\r
+  CHAR16                          *FormTitleStr;\r
+  CHAR16                          *FormSetTitleStr;\r
+  CHAR16                          *OneOfOptionStr;\r
+  CHAR16                          *QuestionName;\r
+  LIST_ENTRY                      *Link;\r
+  FORM_DISPLAY_ENGINE_STATEMENT   *Question;\r
+  EFI_IFR_ORDERED_LIST            *OrderList;\r
+  UINT8                           Index;\r
+  EFI_HII_VALUE                   HiiValue;\r
+  EFI_HII_VALUE                   *QuestionValue;\r
+  DISPLAY_QUESTION_OPTION         *Option;\r
+  UINT8                           *ValueArray;\r
+  UINT8                           ValueType;\r
+  EFI_IFR_FORM_SET                *FormsetBuffer;\r
+  UINTN                           FormsetBufferSize;\r
+\r
+  Question = MenuOption->ThisTag;\r
+  HiiGetFormSetFromHiiHandle (gFormData->HiiHandle, &FormsetBuffer, &FormsetBufferSize);\r
+\r
+  FormSetTitleStr = GetToken (FormsetBuffer->FormSetTitle, gFormData->HiiHandle);\r
+  FormTitleStr = GetToken (gFormData->FormTitle, gFormData->HiiHandle);\r
+\r
+  DEBUG ((DEBUG_ERROR, "\n[%a]: Mismatch Formset    : Formset Guid = %g,  FormSet title = %s\n", gEfiCallerBaseName, &gFormData->FormSetGuid, FormSetTitleStr));\r
+  DEBUG ((DEBUG_ERROR, "[%a]: Mismatch Form       : FormId = %d,  Form title = %s.\n", gEfiCallerBaseName, gFormData->FormId, FormTitleStr));\r
+\r
+  if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+    QuestionName = GetToken (((EFI_IFR_ORDERED_LIST*)MenuOption->ThisTag->OpCode)->Question.Header.Prompt, gFormData->HiiHandle);\r
+    Link = GetFirstNode (&Question->OptionListHead);\r
+    Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
+    ValueType = Option->OptionOpCode->Type;\r
+    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch Error      : OrderedList value in the array doesn't match with option value.\n", gEfiCallerBaseName));\r
+    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OrderedList: Name = %s.\n", gEfiCallerBaseName, QuestionName));\r
+    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OrderedList: OrderedList array value :\n", gEfiCallerBaseName));\r
+\r
+    OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;\r
+    for (Index = 0; Index < OrderList->MaxContainers; Index++) {\r
+      ValueArray = Question->CurrentValue.Buffer;\r
+      HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
+      DEBUG ((DEBUG_ERROR, "                                       Value[%d] =%ld.\n", Index, HiiValue.Value.u64));\r
+    }\r
+  } else if (Question->OpCode->OpCode == EFI_IFR_ONE_OF_OP) {\r
+    QuestionName = GetToken (((EFI_IFR_ONE_OF*)MenuOption->ThisTag->OpCode)->Question.Header.Prompt, gFormData->HiiHandle);\r
+    QuestionValue = &Question->CurrentValue;\r
+    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch Error      : OneOf value doesn't match with option value.\n", gEfiCallerBaseName));\r
+    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : Name = %s.\n", gEfiCallerBaseName, QuestionName));\r
+    switch (QuestionValue->Type) {\r
+      case EFI_IFR_TYPE_NUM_SIZE_64:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %ld.\n",gEfiCallerBaseName, QuestionValue->Value.u64));\r
+        break;\r
+\r
+      case EFI_IFR_TYPE_NUM_SIZE_32:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %d.\n",gEfiCallerBaseName, QuestionValue->Value.u32));\r
+        break;\r
+\r
+      case EFI_IFR_TYPE_NUM_SIZE_16:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %d.\n",gEfiCallerBaseName, QuestionValue->Value.u16));\r
+        break;\r
+\r
+      case EFI_IFR_TYPE_NUM_SIZE_8:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %d.\n",gEfiCallerBaseName, QuestionValue->Value.u8));\r
+        break;\r
+\r
+      default:\r
+        ASSERT (FALSE);\r
+        break;\r
+    }\r
+  }\r
+\r
+  Index = 0;\r
+  Link = GetFirstNode (&Question->OptionListHead);\r
+  while (!IsNull (&Question->OptionListHead, Link)) {\r
+    Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
+    OneOfOptionStr = GetToken (Option->OptionOpCode->Option, gFormData->HiiHandle);\r
+    switch (Option->OptionOpCode->Type) {\r
+      case EFI_IFR_TYPE_NUM_SIZE_64:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %ld,  Option Name = %s.\n",gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u64, OneOfOptionStr));\r
+        break;\r
+\r
+      case EFI_IFR_TYPE_NUM_SIZE_32:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %d,  Option Name = %s.\n",gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u32, OneOfOptionStr));\r
+        break;\r
+\r
+      case EFI_IFR_TYPE_NUM_SIZE_16:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %d,  Option Name = %s.\n",gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u16, OneOfOptionStr));\r
+        break;\r
+\r
+      case EFI_IFR_TYPE_NUM_SIZE_8:\r
+        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %d,  Option Name = %s.\n",gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u8, OneOfOptionStr));\r
+        break;\r
+\r
+      default:\r
+        ASSERT (FALSE);\r
+        break;\r
+    }\r
+    Link = GetNextNode (&Question->OptionListHead, Link);\r
+    Index++;\r
+  }\r
+}\r
+\r
 /**\r
   Process a Question's Option (whether selected or un-selected).\r
 \r
@@ -954,16 +1060,15 @@ ProcessOptions (
   UINTN                           Index2;\r
   UINT8                           *ValueArray;\r
   UINT8                           ValueType;\r
-  EFI_STRING_ID                   StringId;\r
   EFI_IFR_ORDERED_LIST            *OrderList;\r
   BOOLEAN                         ValueInvalid;\r
+  UINTN                           MaxLen;\r
 \r
   Status        = EFI_SUCCESS;\r
 \r
   StringPtr     = NULL;\r
   Character[1]  = L'\0';\r
   *OptionString = NULL;\r
-  StringId      = 0;\r
   ValueInvalid  = FALSE;\r
 \r
   ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
@@ -1000,7 +1105,8 @@ ProcessOptions (
       // We now know how many strings we will have, so we can allocate the\r
       // space required for the array or strings.\r
       //\r
-      *OptionString = AllocateZeroPool (OrderList->MaxContainers * BufferSize);\r
+      MaxLen = OrderList->MaxContainers * BufferSize / sizeof (CHAR16);\r
+      *OptionString = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
       ASSERT (*OptionString);\r
 \r
       HiiValue.Type = ValueType;\r
@@ -1016,6 +1122,11 @@ ProcessOptions (
 \r
         OneOfOption = ValueToOption (Question, &HiiValue);\r
         if (OneOfOption == NULL) {\r
+          //\r
+          // Print debug msg for the mistach menu.\r
+          //\r
+          PrintMismatchMenuInfo (MenuOption);\r
+\r
           if (SkipErrorValue) {\r
             //\r
             // Just try to get the option string, skip the value which not has option.\r
@@ -1035,13 +1146,13 @@ ProcessOptions (
           // Exit current DisplayForm with new value.\r
           //\r
           gUserInput->SelectedStatement = Question;\r
-          \r
+          gMisMatch = TRUE;\r
           ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen);\r
           ASSERT (ValueArray != NULL);\r
           gUserInput->InputValue.Buffer    = ValueArray;\r
           gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
           gUserInput->InputValue.Type      = Question->CurrentValue.Type;\r
-          \r
+\r
           Link = GetFirstNode (&Question->OptionListHead);\r
           Index2 = 0;\r
           while (!IsNull (&Question->OptionListHead, Link) && Index2 < OrderList->MaxContainers) {\r
@@ -1058,14 +1169,14 @@ ProcessOptions (
         }\r
 \r
         Character[0] = LEFT_ONEOF_DELIMITER;\r
-        NewStrCat (OptionString[0], Character);\r
+        NewStrCat (OptionString[0], MaxLen, Character);\r
         StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
         ASSERT (StringPtr != NULL);\r
-        NewStrCat (OptionString[0], StringPtr);\r
+        NewStrCat (OptionString[0], MaxLen, StringPtr);\r
         Character[0] = RIGHT_ONEOF_DELIMITER;\r
-        NewStrCat (OptionString[0], Character);\r
+        NewStrCat (OptionString[0], MaxLen, Character);\r
         Character[0] = CHAR_CARRIAGE_RETURN;\r
-        NewStrCat (OptionString[0], Character);\r
+        NewStrCat (OptionString[0], MaxLen, Character);\r
         FreePool (StringPtr);\r
       }\r
 \r
@@ -1088,19 +1199,24 @@ ProcessOptions (
           continue;\r
         }\r
 \r
+        //\r
+        // Print debug msg for the mistach menu.\r
+        //\r
+        PrintMismatchMenuInfo (MenuOption);\r
+\r
         if (SkipErrorValue) {\r
           //\r
           // Not report error, just get the correct option string info.\r
           //\r
           Character[0] = LEFT_ONEOF_DELIMITER;\r
-          NewStrCat (OptionString[0], Character);\r
+          NewStrCat (OptionString[0], MaxLen, Character);\r
           StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
           ASSERT (StringPtr != NULL);\r
-          NewStrCat (OptionString[0], StringPtr);\r
+          NewStrCat (OptionString[0], MaxLen, StringPtr);\r
           Character[0] = RIGHT_ONEOF_DELIMITER;\r
-          NewStrCat (OptionString[0], Character);\r
+          NewStrCat (OptionString[0], MaxLen, Character);\r
           Character[0] = CHAR_CARRIAGE_RETURN;\r
-          NewStrCat (OptionString[0], Character);\r
+          NewStrCat (OptionString[0], MaxLen, Character);\r
           FreePool (StringPtr);\r
 \r
           continue;\r
@@ -1120,14 +1236,14 @@ ProcessOptions (
           // Exit current DisplayForm with new value.\r
           //\r
           gUserInput->SelectedStatement = Question;\r
-          \r
+          gMisMatch = TRUE;\r
           ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer);\r
           ASSERT (ValueArray != NULL);\r
           gUserInput->InputValue.Buffer    = ValueArray;\r
           gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
           gUserInput->InputValue.Type      = Question->CurrentValue.Type;\r
         }\r
-       \r
+\r
         SetArrayData (ValueArray, ValueType, Index++, OneOfOption->OptionOpCode->Value.u64);\r
       }\r
 \r
@@ -1152,15 +1268,21 @@ ProcessOptions (
       //\r
       Status = GetSelectionInputPopUp (MenuOption);\r
     } else {\r
+      MaxLen = BufferSize / sizeof(CHAR16);\r
       *OptionString = AllocateZeroPool (BufferSize);\r
       ASSERT (*OptionString);\r
 \r
       OneOfOption = ValueToOption (Question, QuestionValue);\r
       if (OneOfOption == NULL) {\r
+        //\r
+        // Print debug msg for the mistach menu.\r
+        //\r
+        PrintMismatchMenuInfo (MenuOption);\r
+\r
         if (SkipErrorValue) {\r
           //\r
           // Not report error, just get the correct option string info.\r
-          //          \r
+          //\r
           Link = GetFirstNode (&Question->OptionListHead);\r
           OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
         } else {\r
@@ -1178,10 +1300,26 @@ ProcessOptions (
           Link = GetFirstNode (&Question->OptionListHead);\r
           Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
 \r
-          CopyMem (&gUserInput->InputValue.Value, &Option->OptionOpCode->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
           gUserInput->InputValue.Type = Option->OptionOpCode->Type;\r
+          switch (gUserInput->InputValue.Type) {\r
+          case EFI_IFR_TYPE_NUM_SIZE_8:\r
+            gUserInput->InputValue.Value.u8 = Option->OptionOpCode->Value.u8;\r
+            break;\r
+          case EFI_IFR_TYPE_NUM_SIZE_16:\r
+            CopyMem (&gUserInput->InputValue.Value.u16, &Option->OptionOpCode->Value.u16, sizeof (UINT16));\r
+            break;\r
+          case EFI_IFR_TYPE_NUM_SIZE_32:\r
+            CopyMem (&gUserInput->InputValue.Value.u32, &Option->OptionOpCode->Value.u32, sizeof (UINT32));\r
+            break;\r
+          case EFI_IFR_TYPE_NUM_SIZE_64:\r
+            CopyMem (&gUserInput->InputValue.Value.u64, &Option->OptionOpCode->Value.u64, sizeof (UINT64));\r
+            break;\r
+          default:\r
+            ASSERT (FALSE);\r
+            break;\r
+          }\r
           gUserInput->SelectedStatement = Question;\r
-\r
+          gMisMatch = TRUE;\r
           FreePool (*OptionString);\r
           *OptionString = NULL;\r
           return EFI_NOT_FOUND;\r
@@ -1189,12 +1327,12 @@ ProcessOptions (
       }\r
 \r
       Character[0] = LEFT_ONEOF_DELIMITER;\r
-      NewStrCat (OptionString[0], Character);\r
+      NewStrCat (OptionString[0], MaxLen, Character);\r
       StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
       ASSERT (StringPtr != NULL);\r
-      NewStrCat (OptionString[0], StringPtr);\r
+      NewStrCat (OptionString[0], MaxLen, StringPtr);\r
       Character[0] = RIGHT_ONEOF_DELIMITER;\r
-      NewStrCat (OptionString[0], Character);\r
+      NewStrCat (OptionString[0], MaxLen, Character);\r
 \r
       FreePool (StringPtr);\r
     }\r
@@ -1211,8 +1349,8 @@ ProcessOptions (
       //\r
       // Perform inconsistent check\r
       //\r
-      return ValidateQuestion (Question);\r
-    } else {    \r
+      return EFI_SUCCESS;\r
+    } else {\r
       *OptionString = AllocateZeroPool (BufferSize);\r
       ASSERT (*OptionString);\r
 \r
@@ -1263,19 +1401,31 @@ ProcessOptions (
       switch (MenuOption->Sequence) {\r
       case 0:\r
         *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
-        UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);\r
+        if (QuestionValue->Value.date.Month == 0xff){\r
+          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??");\r
+        } else {\r
+          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);\r
+        }\r
         *(OptionString[0] + 3) = DATE_SEPARATOR;\r
         break;\r
 \r
       case 1:\r
         SetUnicodeMem (OptionString[0], 4, L' ');\r
-        UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);\r
+        if (QuestionValue->Value.date.Day == 0xff){\r
+          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??");\r
+        } else {\r
+          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);\r
+        }\r
         *(OptionString[0] + 6) = DATE_SEPARATOR;\r
         break;\r
 \r
       case 2:\r
         SetUnicodeMem (OptionString[0], 7, L' ');\r
-        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);\r
+        if (QuestionValue->Value.date.Year == 0xff){\r
+          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"????");\r
+        } else {\r
+          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);\r
+        }\r
         *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;\r
         break;\r
       }\r
@@ -1295,19 +1445,31 @@ ProcessOptions (
       switch (MenuOption->Sequence) {\r
       case 0:\r
         *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
-        UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);\r
+        if (QuestionValue->Value.time.Hour == 0xff){\r
+          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??");\r
+        } else {\r
+          UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);\r
+        }\r
         *(OptionString[0] + 3) = TIME_SEPARATOR;\r
         break;\r
 \r
       case 1:\r
         SetUnicodeMem (OptionString[0], 4, L' ');\r
-        UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);\r
+        if (QuestionValue->Value.time.Minute == 0xff){\r
+          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??");\r
+        } else {\r
+          UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);\r
+        }\r
         *(OptionString[0] + 6) = TIME_SEPARATOR;\r
         break;\r
 \r
       case 2:\r
         SetUnicodeMem (OptionString[0], 7, L' ');\r
-        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);\r
+        if (QuestionValue->Value.time.Second == 0xff){\r
+          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"??");\r
+        } else {\r
+          UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);\r
+        }\r
         *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;\r
         break;\r
       }\r
@@ -1325,13 +1487,13 @@ ProcessOptions (
         FreePool (StringPtr);\r
         return Status;\r
       }\r
-      \r
+\r
       gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);\r
       gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
       gUserInput->InputValue.Type = Question->CurrentValue.Type;\r
       gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);\r
       FreePool (StringPtr);\r
-      return ValidateQuestion (Question);\r
+      return EFI_SUCCESS;\r
     } else {\r
       *OptionString = AllocateZeroPool (BufferSize);\r
       ASSERT (*OptionString);\r
@@ -1427,5 +1589,5 @@ ProcessHelpString (
     FreePool (OutputString);\r
   }\r
 \r
-  return TotalRowNum; \r
+  return TotalRowNum;\r
 }\r