/** @file
Implementation for handling the User Interface option processing.


Copyright (c) 2004 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FormDisplay.h"

#define MAX_TIME_OUT_LEN  0x10

/**
  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.

**/
VOID
NewStrCat (
  IN OUT CHAR16  *Destination,
  IN     UINTN   DestMax,
  IN     CHAR16  *Source
  )
{
  UINTN  Length;

  for (Length = 0; Destination[Length] != 0; Length++) {
  }

  //
  // We now have the length of the original string
  // We can safely assume for now that we are concatenating a narrow value to this string.
  // For instance, the string is "XYZ" and cat'ing ">"
  // If this assumption changes, we need to make this routine a bit more complex
  //
  Destination[Length] = NARROW_CHAR;
  Length++;

  StrCpyS (Destination + Length, DestMax - Length, Source);
}

/**
  Get UINT64 type value.

  @param  Value                  Input Hii value.

  @retval UINT64                 Return the UINT64 type value.

**/
UINT64
HiiValueToUINT64 (
  IN EFI_HII_VALUE  *Value
  )
{
  UINT64  RetVal;

  RetVal = 0;

  switch (Value->Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      RetVal = Value->Value.u8;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      RetVal = Value->Value.u16;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      RetVal = Value->Value.u32;
      break;

    case EFI_IFR_TYPE_BOOLEAN:
      RetVal = Value->Value.b;
      break;

    case EFI_IFR_TYPE_DATE:
      RetVal = *(UINT64 *)&Value->Value.date;
      break;

    case EFI_IFR_TYPE_TIME:
      RetVal = (*(UINT64 *)&Value->Value.time) & 0xffffff;
      break;

    default:
      RetVal = Value->Value.u64;
      break;
  }

  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.

  @param  Value1                 Expression value to compare on left-hand.
  @param  Value2                 Expression value to compare on right-hand.
  @param  Result                 Return value after compare.
                                 retval 0                      Two operators equal.
                                 return Positive value if Value1 is greater than Value2.
                                 retval Negative value if Value1 is less than Value2.
  @param  HiiHandle              Only required for string compare.

  @retval other                  Could not perform compare on two values.
  @retval EFI_SUCCESS            Compare the value success.

**/
EFI_STATUS
CompareHiiValue (
  IN  EFI_HII_VALUE   *Value1,
  IN  EFI_HII_VALUE   *Value2,
  OUT INTN            *Result,
  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL
  )
{
  INT64   Temp64;
  CHAR16  *Str1;
  CHAR16  *Str2;
  UINTN   Len;
  UINT8   *Buf1;
  UINT16  Buf1Len;
  UINT8   *Buf2;
  UINT16  Buf2Len;

  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
      //
      return EFI_INVALID_PARAMETER;
    }

    if (Value1->Value.string == Value2->Value.string) {
      *Result = 0;
      return EFI_SUCCESS;
    }

    Str1 = GetToken (Value1->Value.string, HiiHandle);
    if (Str1 == NULL) {
      //
      // String not found
      //
      return EFI_NOT_FOUND;
    }

    Str2 = GetToken (Value2->Value.string, HiiHandle);
    if (Str2 == NULL) {
      FreePool (Str1);
      return EFI_NOT_FOUND;
    }

    *Result = StrCmp (Str1, Str2);

    FreePool (Str1);
    FreePool (Str2);

    return EFI_SUCCESS;
  }

  //
  // 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 = Buf1Len > Buf2Len ? 1 : -1;
    }

    return EFI_SUCCESS;
  }

  //
  // Take remain types(integer, boolean, date/time) as integer
  //
  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_UNSUPPORTED;
}

/**
  Search an Option of a Question by its value.

  @param  Question               The Question
  @param  OptionValue            Value for Option to be searched.

  @retval Pointer                Pointer to the found Option.
  @retval NULL                   Option not found.

**/
DISPLAY_QUESTION_OPTION *
ValueToOption (
  IN FORM_DISPLAY_ENGINE_STATEMENT  *Question,
  IN EFI_HII_VALUE                  *OptionValue
  )
{
  LIST_ENTRY               *Link;
  DISPLAY_QUESTION_OPTION  *Option;
  INTN                     Result;
  EFI_HII_VALUE            Value;

  Link = GetFirstNode (&Question->OptionListHead);
  while (!IsNull (&Question->OptionListHead, Link)) {
    Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);

    ZeroMem (&Value, sizeof (EFI_HII_VALUE));
    Value.Type = Option->OptionOpCode->Type;
    CopyMem (&Value.Value, &Option->OptionOpCode->Value, Option->OptionOpCode->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));

    if ((CompareHiiValue (&Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
      return Option;
    }

    Link = GetNextNode (&Question->OptionListHead, Link);
  }

  return NULL;
}

/**
  Return data element in an Array by its Index.

  @param  Array                  The data array.
  @param  Type                   Type of the data in this array.
  @param  Index                  Zero based index for data in this array.

  @retval Value                  The data to be returned

**/
UINT64
GetArrayData (
  IN VOID   *Array,
  IN UINT8  Type,
  IN UINTN  Index
  )
{
  UINT64  Data;

  ASSERT (Array != NULL);

  Data = 0;
  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      Data = (UINT64)*(((UINT8 *)Array) + Index);
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      Data = (UINT64)*(((UINT16 *)Array) + Index);
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      Data = (UINT64)*(((UINT32 *)Array) + Index);
      break;

    case EFI_IFR_TYPE_NUM_SIZE_64:
      Data = (UINT64)*(((UINT64 *)Array) + Index);
      break;

    default:
      break;
  }

  return Data;
}

/**
  Set value of a data element in an Array by its Index.

  @param  Array                  The data array.
  @param  Type                   Type of the data in this array.
  @param  Index                  Zero based index for data in this array.
  @param  Value                  The value to be set.

**/
VOID
SetArrayData (
  IN VOID    *Array,
  IN UINT8   Type,
  IN UINTN   Index,
  IN UINT64  Value
  )
{
  ASSERT (Array != NULL);

  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      *(((UINT8 *)Array) + Index) = (UINT8)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      *(((UINT16 *)Array) + Index) = (UINT16)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      *(((UINT32 *)Array) + Index) = (UINT32)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_64:
      *(((UINT64 *)Array) + Index) = (UINT64)Value;
      break;

    default:
      break;
  }
}

/**
  Check whether this value already in the array, if yes, return the index.

  @param  Array                  The data array.
  @param  Type                   Type of the data in this array.
  @param  Value                  The value to be find.
  @param  Index                  The index in the array which has same value with Value.

  @retval   TRUE Found the value in the array.
  @retval   FALSE Not found the value.

**/
BOOLEAN
FindArrayData (
  IN VOID    *Array,
  IN UINT8   Type,
  IN UINT64  Value,
  OUT UINTN  *Index OPTIONAL
  )
{
  UINTN   Count;
  UINT64  TmpValue;
  UINT64  ValueComp;

  ASSERT (Array != NULL);

  Count    = 0;
  TmpValue = 0;

  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
      ValueComp = (UINT8)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      ValueComp = (UINT16)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      ValueComp = (UINT32)Value;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_64:
      ValueComp = (UINT64)Value;
      break;

    default:
      ValueComp = 0;
      break;
  }

  while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {
    if (ValueComp == TmpValue) {
      if (Index != NULL) {
        *Index = Count;
      }

      return TRUE;
    }

    Count++;
  }

  return FALSE;
}

/**
  Print Question Value according to it's storage width and display attributes.

  @param  Question               The Question to be printed.
  @param  FormattedNumber        Buffer for output string.
  @param  BufferSize             The FormattedNumber buffer size in bytes.

  @retval EFI_SUCCESS            Print success.
  @retval EFI_BUFFER_TOO_SMALL   Buffer size is not enough for formatted number.

**/
EFI_STATUS
PrintFormattedNumber (
  IN FORM_DISPLAY_ENGINE_STATEMENT  *Question,
  IN OUT CHAR16                     *FormattedNumber,
  IN UINTN                          BufferSize
  )
{
  INT64            Value;
  CHAR16           *Format;
  EFI_HII_VALUE    *QuestionValue;
  EFI_IFR_NUMERIC  *NumericOp;

  if (BufferSize < (21 * sizeof (CHAR16))) {
    return EFI_BUFFER_TOO_SMALL;
  }

  QuestionValue = &Question->CurrentValue;
  NumericOp     = (EFI_IFR_NUMERIC *)Question->OpCode;

  Value = (INT64)QuestionValue->Value.u64;
  switch (NumericOp->Flags & EFI_IFR_DISPLAY) {
    case EFI_IFR_DISPLAY_INT_DEC:
      switch (QuestionValue->Type) {
        case EFI_IFR_NUMERIC_SIZE_1:
          Value = (INT64)((INT8)QuestionValue->Value.u8);
          break;

        case EFI_IFR_NUMERIC_SIZE_2:
          Value = (INT64)((INT16)QuestionValue->Value.u16);
          break;

        case EFI_IFR_NUMERIC_SIZE_4:
          Value = (INT64)((INT32)QuestionValue->Value.u32);
          break;

        case EFI_IFR_NUMERIC_SIZE_8:
        default:
          break;
      }

      if (Value < 0) {
        Value  = -Value;
        Format = L"-%ld";
      } else {
        Format = L"%ld";
      }

      break;

    case EFI_IFR_DISPLAY_UINT_DEC:
      Format = L"%ld";
      break;

    case EFI_IFR_DISPLAY_UINT_HEX:
      Format = L"%lx";
      break;

    default:
      return EFI_UNSUPPORTED;
  }

  UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);

  return EFI_SUCCESS;
}

/**
  Draw a pop up windows based on the dimension, number of lines and
  strings specified.

  @param RequestedWidth  The width of the pop-up.
  @param NumberOfLines   The number of lines.
  @param Marker          The variable argument list for the list of string to be printed.

**/
VOID
CreateSharedPopUp (
  IN  UINTN    RequestedWidth,
  IN  UINTN    NumberOfLines,
  IN  VA_LIST  Marker
  )
{
  UINTN   Index;
  UINTN   Count;
  CHAR16  Character;
  UINTN   Start;
  UINTN   End;
  UINTN   Top;
  UINTN   Bottom;
  CHAR16  *String;
  UINTN   DimensionsWidth;
  UINTN   DimensionsHeight;

  DimensionsWidth  = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;
  DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;

  gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());

  if ((RequestedWidth + 2) > DimensionsWidth) {
    RequestedWidth = DimensionsWidth - 2;
  }

  //
  // Subtract the PopUp width from total Columns, allow for one space extra on
  // each end plus a border.
  //
  Start = (DimensionsWidth - RequestedWidth - 2) / 2 + gStatementDimensions.LeftColumn + 1;
  End   = Start + RequestedWidth + 1;

  Top    = ((DimensionsHeight - NumberOfLines - 2) / 2) + gStatementDimensions.TopRow - 1;
  Bottom = Top + NumberOfLines + 2;

  Character = BOXDRAW_DOWN_RIGHT;
  PrintCharAt (Start, Top, Character);
  Character = BOXDRAW_HORIZONTAL;
  for (Index = Start; Index + 2 < End; Index++) {
    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
  }

  Character = BOXDRAW_DOWN_LEFT;
  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
  Character = BOXDRAW_VERTICAL;

  Count = 0;
  for (Index = Top; Index + 2 < Bottom; Index++, Count++) {
    String = VA_ARG (Marker, CHAR16 *);

    //
    // This will clear the background of the line - we never know who might have been
    // here before us.  This differs from the next clear in that it used the non-reverse
    // video for normal printing.
    //
    if (GetStringWidth (String) / 2 > 1) {
      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
    }

    //
    // Passing in a space results in the assumption that this is where typing will occur
    //
    if (String[0] == L' ') {
      ClearLines (Start + 1, End - 1, Index + 1, Index + 1, GetPopupInverseColor ());
    }

    //
    // Passing in a NULL results in a blank space
    //
    if (String[0] == CHAR_NULL) {
      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
    }

    PrintStringAt (
      ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gStatementDimensions.LeftColumn + 1,
      Index + 1,
      String
      );
    gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
    PrintCharAt (Start, Index + 1, Character);
    PrintCharAt (End - 1, Index + 1, Character);
  }

  Character = BOXDRAW_UP_RIGHT;
  PrintCharAt (Start, Bottom - 1, Character);
  Character = BOXDRAW_HORIZONTAL;
  for (Index = Start; Index + 2 < End; Index++) {
    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
  }

  Character = BOXDRAW_UP_LEFT;
  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
}

/**
  Draw a pop up windows based on the dimension, number of lines and
  strings specified.

  @param RequestedWidth  The width of the pop-up.
  @param NumberOfLines   The number of lines.
  @param ...             A series of text strings that displayed in the pop-up.

**/
VOID
EFIAPI
CreateMultiStringPopUp (
  IN  UINTN  RequestedWidth,
  IN  UINTN  NumberOfLines,
  ...
  )
{
  VA_LIST  Marker;

  VA_START (Marker, NumberOfLines);

  CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);

  VA_END (Marker);
}

/**
  Process nothing.

  @param Event    The Event need to be process
  @param Context  The context of the event.

**/
VOID
EFIAPI
EmptyEventProcess (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
}

/**
  Process for the refresh interval statement.

  @param Event    The Event need to be process
  @param Context  The context of the event.

**/
VOID
EFIAPI
RefreshTimeOutProcess (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  WARNING_IF_CONTEXT  *EventInfo;
  CHAR16              TimeOutString[MAX_TIME_OUT_LEN];

  EventInfo = (WARNING_IF_CONTEXT *)Context;

  if (*(EventInfo->TimeOut) == 0) {
    gBS->CloseEvent (Event);

    gBS->SignalEvent (EventInfo->SyncEvent);
    return;
  }

  UnicodeSPrint (TimeOutString, MAX_TIME_OUT_LEN, L"%d", *(EventInfo->TimeOut));

  CreateDialog (NULL, gEmptyString, EventInfo->ErrorInfo, gPressEnter, gEmptyString, TimeOutString, NULL);

  *(EventInfo->TimeOut) -= 1;
}

/**
  Display error message for invalid password.

**/
VOID
PasswordInvalid (
  VOID
  )
{
  EFI_INPUT_KEY  Key;

  //
  // Invalid password, prompt error message
  //
  do {
    CreateDialog (&Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString, NULL);
  } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
}

/**
  Process password op code.

  @param  MenuOption             The menu for current password op code.

  @retval EFI_SUCCESS            Question Option process success.
  @retval Other                  Question Option process fail.

**/
EFI_STATUS
PasswordProcess (
  IN  UI_MENU_OPTION  *MenuOption
  )
{
  CHAR16                         *StringPtr;
  CHAR16                         *TempString;
  UINTN                          Maximum;
  EFI_STATUS                     Status;
  EFI_IFR_PASSWORD               *PasswordInfo;
  FORM_DISPLAY_ENGINE_STATEMENT  *Question;
  EFI_INPUT_KEY                  Key;

  Question     = MenuOption->ThisTag;
  PasswordInfo = (EFI_IFR_PASSWORD *)Question->OpCode;
  Maximum      = PasswordInfo->MaxSize;
  Status       = EFI_SUCCESS;

  StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
  ASSERT (StringPtr);

  //
  // Use a NULL password to test whether old password is required
  //
  *StringPtr = 0;
  Status     = Question->PasswordCheck (gFormData, Question, StringPtr);
  if ((Status == EFI_NOT_AVAILABLE_YET) || (Status == EFI_UNSUPPORTED)) {
    //
    // 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;
  }

  if (EFI_ERROR (Status)) {
    //
    // Old password exist, ask user for the old password
    //
    Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
    if (EFI_ERROR (Status)) {
      ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
      FreePool (StringPtr);
      return Status;
    }

    //
    // Check user input old password
    //
    Status = Question->PasswordCheck (gFormData, Question, StringPtr);
    if (EFI_ERROR (Status)) {
      if (Status == EFI_NOT_READY) {
        //
        // Typed in old password incorrect
        //
        PasswordInvalid ();
      } else {
        Status = EFI_SUCCESS;
      }

      ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
      FreePool (StringPtr);
      return Status;
    }
  }

  //
  // Ask for new password
  //
  ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
  Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
  if (EFI_ERROR (Status)) {
    //
    // Reset state machine for password
    //
    Question->PasswordCheck (gFormData, Question, NULL);
    ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
    FreePool (StringPtr);
    return Status;
  }

  //
  // Confirm new password
  //
  TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
  ASSERT (TempString);
  Status = ReadString (MenuOption, gConfirmPassword, TempString);
  if (EFI_ERROR (Status)) {
    //
    // Reset state machine for password
    //
    Question->PasswordCheck (gFormData, Question, NULL);
    ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
    ZeroMem (TempString, (Maximum + 1) * sizeof (CHAR16));
    FreePool (StringPtr);
    FreePool (TempString);
    return Status;
  }

  //
  // Compare two typed-in new passwords
  //
  if (StrCmp (StringPtr, TempString) == 0) {
    gUserInput->InputValue.Buffer       = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);
    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);

    Status = EFI_SUCCESS;
  } else {
    //
    // Reset state machine for password
    //
    Question->PasswordCheck (gFormData, Question, NULL);

    //
    // Two password mismatch, prompt error message
    //
    do {
      CreateDialog (&Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString, NULL);
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    Status = EFI_INVALID_PARAMETER;
  }

  ZeroMem (TempString, (Maximum + 1) * sizeof (CHAR16));
  ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
  FreePool (TempString);
  FreePool (StringPtr);

  return Status;
}

/**
  Print some debug message about mismatched menu info.

  @param  MenuOption             The MenuOption for this Question.

**/
VOID
PrintMismatchMenuInfo (
  IN  UI_MENU_OPTION  *MenuOption
  )
{
  CHAR16                         *FormTitleStr;
  CHAR16                         *FormSetTitleStr;
  CHAR16                         *OneOfOptionStr;
  CHAR16                         *QuestionName;
  LIST_ENTRY                     *Link;
  FORM_DISPLAY_ENGINE_STATEMENT  *Question;
  EFI_IFR_ORDERED_LIST           *OrderList;
  UINT8                          Index;
  EFI_HII_VALUE                  HiiValue;
  EFI_HII_VALUE                  *QuestionValue;
  DISPLAY_QUESTION_OPTION        *Option;
  UINT8                          *ValueArray;
  UINT8                          ValueType;
  EFI_IFR_FORM_SET               *FormsetBuffer;
  UINTN                          FormsetBufferSize;

  Question = MenuOption->ThisTag;

  if (!EFI_ERROR (HiiGetFormSetFromHiiHandle (gFormData->HiiHandle, &FormsetBuffer, &FormsetBufferSize))) {
    FormSetTitleStr = GetToken (FormsetBuffer->FormSetTitle, gFormData->HiiHandle);
    FormTitleStr    = GetToken (gFormData->FormTitle, gFormData->HiiHandle);

    DEBUG ((DEBUG_ERROR, "\n[%a]: Mismatch Formset    : Formset Guid = %g,  FormSet title = %s\n", gEfiCallerBaseName, &gFormData->FormSetGuid, FormSetTitleStr));
    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch Form       : FormId = %d,  Form title = %s.\n", gEfiCallerBaseName, gFormData->FormId, FormTitleStr));
  }

  if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {
    QuestionName = GetToken (((EFI_IFR_ORDERED_LIST *)MenuOption->ThisTag->OpCode)->Question.Header.Prompt, gFormData->HiiHandle);
    Link         = GetFirstNode (&Question->OptionListHead);
    Option       = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
    ValueType    = Option->OptionOpCode->Type;
    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch Error      : OrderedList value in the array doesn't match with option value.\n", gEfiCallerBaseName));
    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OrderedList: Name = %s.\n", gEfiCallerBaseName, QuestionName));
    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OrderedList: OrderedList array value :\n", gEfiCallerBaseName));

    OrderList = (EFI_IFR_ORDERED_LIST *)Question->OpCode;
    for (Index = 0; Index < OrderList->MaxContainers; Index++) {
      ValueArray         = Question->CurrentValue.Buffer;
      HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
      DEBUG ((DEBUG_ERROR, "                                       Value[%d] =%ld.\n", Index, HiiValue.Value.u64));
    }
  } else if (Question->OpCode->OpCode == EFI_IFR_ONE_OF_OP) {
    QuestionName  = GetToken (((EFI_IFR_ONE_OF *)MenuOption->ThisTag->OpCode)->Question.Header.Prompt, gFormData->HiiHandle);
    QuestionValue = &Question->CurrentValue;
    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch Error      : OneOf value doesn't match with option value.\n", gEfiCallerBaseName));
    DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : Name = %s.\n", gEfiCallerBaseName, QuestionName));
    switch (QuestionValue->Type) {
      case EFI_IFR_TYPE_NUM_SIZE_64:
        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %ld.\n", gEfiCallerBaseName, QuestionValue->Value.u64));
        break;

      case EFI_IFR_TYPE_NUM_SIZE_32:
        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %d.\n", gEfiCallerBaseName, QuestionValue->Value.u32));
        break;

      case EFI_IFR_TYPE_NUM_SIZE_16:
        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %d.\n", gEfiCallerBaseName, QuestionValue->Value.u16));
        break;

      case EFI_IFR_TYPE_NUM_SIZE_8:
        DEBUG ((DEBUG_ERROR, "[%a]: Mismatch OneOf      : OneOf value = %d.\n", gEfiCallerBaseName, QuestionValue->Value.u8));
        break;

      default:
        ASSERT (FALSE);
        break;
    }
  }

  Index = 0;
  Link  = GetFirstNode (&Question->OptionListHead);
  while (!IsNull (&Question->OptionListHead, Link)) {
    Option         = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
    OneOfOptionStr = GetToken (Option->OptionOpCode->Option, gFormData->HiiHandle);
    switch (Option->OptionOpCode->Type) {
      case EFI_IFR_TYPE_NUM_SIZE_64:
        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %ld,  Option Name = %s.\n", gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u64, OneOfOptionStr));
        break;

      case EFI_IFR_TYPE_NUM_SIZE_32:
        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %d,  Option Name = %s.\n", gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u32, OneOfOptionStr));
        break;

      case EFI_IFR_TYPE_NUM_SIZE_16:
        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %d,  Option Name = %s.\n", gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u16, OneOfOptionStr));
        break;

      case EFI_IFR_TYPE_NUM_SIZE_8:
        DEBUG ((DEBUG_ERROR, "[%a]: Option %d            : Option Value = %d,  Option Name = %s.\n", gEfiCallerBaseName, Index, Option->OptionOpCode->Value.u8, OneOfOptionStr));
        break;

      default:
        ASSERT (FALSE);
        break;
    }

    Link = GetNextNode (&Question->OptionListHead, Link);
    Index++;
  }
}

/**
  Process a Question's Option (whether selected or un-selected).

  @param  MenuOption             The MenuOption for this Question.
  @param  Selected               TRUE: if Question is selected.
  @param  OptionString           Pointer of the Option String to be displayed.
  @param  SkipErrorValue         Whether need to return when value without option for it.

  @retval EFI_SUCCESS            Question Option process success.
  @retval Other                  Question Option process fail.

**/
EFI_STATUS
ProcessOptions (
  IN  UI_MENU_OPTION  *MenuOption,
  IN  BOOLEAN         Selected,
  OUT CHAR16          **OptionString,
  IN  BOOLEAN         SkipErrorValue
  )
{
  EFI_STATUS                     Status;
  CHAR16                         *StringPtr;
  UINTN                          Index;
  FORM_DISPLAY_ENGINE_STATEMENT  *Question;
  CHAR16                         FormattedNumber[21];
  UINT16                         Number;
  CHAR16                         Character[2];
  EFI_INPUT_KEY                  Key;
  UINTN                          BufferSize;
  DISPLAY_QUESTION_OPTION        *OneOfOption;
  LIST_ENTRY                     *Link;
  EFI_HII_VALUE                  HiiValue;
  EFI_HII_VALUE                  *QuestionValue;
  DISPLAY_QUESTION_OPTION        *Option;
  UINTN                          Index2;
  UINT8                          *ValueArray;
  UINT8                          ValueType;
  EFI_IFR_ORDERED_LIST           *OrderList;
  BOOLEAN                        ValueInvalid;
  UINTN                          MaxLen;

  Status = EFI_SUCCESS;

  StringPtr     = NULL;
  Character[1]  = L'\0';
  *OptionString = NULL;
  ValueInvalid  = FALSE;

  ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
  BufferSize = (gOptionBlockWidth + 1) * 2 * gStatementDimensions.BottomRow;

  Question      = MenuOption->ThisTag;
  QuestionValue = &Question->CurrentValue;

  switch (Question->OpCode->OpCode) {
    case EFI_IFR_ORDERED_LIST_OP:

      //
      // Check whether there are Options of this OrderedList
      //
      if (IsListEmpty (&Question->OptionListHead)) {
        break;
      }

      OrderList = (EFI_IFR_ORDERED_LIST *)Question->OpCode;

      Link        = GetFirstNode (&Question->OptionListHead);
      OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);

      ValueType  =  OneOfOption->OptionOpCode->Type;
      ValueArray = Question->CurrentValue.Buffer;

      if (Selected) {
        //
        // Go ask for input
        //
        Status = GetSelectionInputPopUp (MenuOption);
      } else {
        //
        // We now know how many strings we will have, so we can allocate the
        // space required for the array or strings.
        //
        MaxLen        = OrderList->MaxContainers * BufferSize / sizeof (CHAR16);
        *OptionString = AllocateZeroPool (MaxLen * sizeof (CHAR16));
        ASSERT (*OptionString);

        HiiValue.Type      = ValueType;
        HiiValue.Value.u64 = 0;
        for (Index = 0; Index < OrderList->MaxContainers; Index++) {
          HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
          if (HiiValue.Value.u64 == 0) {
            //
            // Values for the options in ordered lists should never be a 0
            //
            break;
          }

          OneOfOption = ValueToOption (Question, &HiiValue);
          if (OneOfOption == NULL) {
            //
            // Print debug msg for the mistach menu.
            //
            PrintMismatchMenuInfo (MenuOption);

            if (SkipErrorValue) {
              //
              // Just try to get the option string, skip the value which not has option.
              //
              continue;
            }

            //
            // Show error message
            //
            do {
              CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            //
            // The initial value of the orderedlist is invalid, force to be valid value
            // Exit current DisplayForm with new value.
            //
            gUserInput->SelectedStatement = Question;
            gMisMatch                     = TRUE;
            ValueArray                    = AllocateZeroPool (Question->CurrentValue.BufferLen);
            ASSERT (ValueArray != NULL);
            gUserInput->InputValue.Buffer    = ValueArray;
            gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
            gUserInput->InputValue.Type      = Question->CurrentValue.Type;

            Link   = GetFirstNode (&Question->OptionListHead);
            Index2 = 0;
            while (!IsNull (&Question->OptionListHead, Link) && Index2 < OrderList->MaxContainers) {
              Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
              Link   = GetNextNode (&Question->OptionListHead, Link);
              SetArrayData (ValueArray, ValueType, Index2, Option->OptionOpCode->Value.u64);
              Index2++;
            }

            SetArrayData (ValueArray, ValueType, Index2, 0);

            FreePool (*OptionString);
            *OptionString = NULL;
            return EFI_NOT_FOUND;
          }

          Character[0] = LEFT_ONEOF_DELIMITER;
          NewStrCat (OptionString[0], MaxLen, Character);
          StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
          ASSERT (StringPtr != NULL);
          NewStrCat (OptionString[0], MaxLen, StringPtr);
          Character[0] = RIGHT_ONEOF_DELIMITER;
          NewStrCat (OptionString[0], MaxLen, Character);
          Character[0] = CHAR_CARRIAGE_RETURN;
          NewStrCat (OptionString[0], MaxLen, Character);
          FreePool (StringPtr);
        }

        //
        // If valid option more than the max container, skip these options.
        //
        if (Index >= OrderList->MaxContainers) {
          break;
        }

        //
        // Search the other options, try to find the one not in the container.
        //
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
          Link        = GetNextNode (&Question->OptionListHead, Link);

          if (FindArrayData (ValueArray, ValueType, OneOfOption->OptionOpCode->Value.u64, NULL)) {
            continue;
          }

          //
          // Print debug msg for the mistach menu.
          //
          PrintMismatchMenuInfo (MenuOption);

          if (SkipErrorValue) {
            //
            // Not report error, just get the correct option string info.
            //
            Character[0] = LEFT_ONEOF_DELIMITER;
            NewStrCat (OptionString[0], MaxLen, Character);
            StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
            ASSERT (StringPtr != NULL);
            NewStrCat (OptionString[0], MaxLen, StringPtr);
            Character[0] = RIGHT_ONEOF_DELIMITER;
            NewStrCat (OptionString[0], MaxLen, Character);
            Character[0] = CHAR_CARRIAGE_RETURN;
            NewStrCat (OptionString[0], MaxLen, Character);
            FreePool (StringPtr);

            continue;
          }

          if (!ValueInvalid) {
            ValueInvalid = TRUE;
            //
            // Show error message
            //
            do {
              CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            //
            // The initial value of the orderedlist is invalid, force to be valid value
            // 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;
            gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
            gUserInput->InputValue.Type      = Question->CurrentValue.Type;
          }

          SetArrayData (ValueArray, ValueType, Index++, OneOfOption->OptionOpCode->Value.u64);
        }

        if (ValueInvalid) {
          FreePool (*OptionString);
          *OptionString = NULL;
          return EFI_NOT_FOUND;
        }
      }

      break;

    case EFI_IFR_ONE_OF_OP:
      //
      // Check whether there are Options of this OneOf
      //
      if (IsListEmpty (&Question->OptionListHead)) {
        break;
      }

      if (Selected) {
        //
        // Go ask for input
        //
        Status = GetSelectionInputPopUp (MenuOption);
      } else {
        MaxLen        = BufferSize / sizeof (CHAR16);
        *OptionString = AllocateZeroPool (BufferSize);
        ASSERT (*OptionString);

        OneOfOption = ValueToOption (Question, QuestionValue);
        if (OneOfOption == NULL) {
          //
          // Print debug msg for the mistach menu.
          //
          PrintMismatchMenuInfo (MenuOption);

          if (SkipErrorValue) {
            //
            // Not report error, just get the correct option string info.
            //
            Link        = GetFirstNode (&Question->OptionListHead);
            OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
          } else {
            //
            // Show error message
            //
            do {
              CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            //
            // Force the Question value to be valid
            // Exit current DisplayForm with new value.
            //
            Link   = GetFirstNode (&Question->OptionListHead);
            Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);

            gUserInput->InputValue.Type = Option->OptionOpCode->Type;
            switch (gUserInput->InputValue.Type) {
              case EFI_IFR_TYPE_NUM_SIZE_8:
                gUserInput->InputValue.Value.u8 = Option->OptionOpCode->Value.u8;
                break;
              case EFI_IFR_TYPE_NUM_SIZE_16:
                CopyMem (&gUserInput->InputValue.Value.u16, &Option->OptionOpCode->Value.u16, sizeof (UINT16));
                break;
              case EFI_IFR_TYPE_NUM_SIZE_32:
                CopyMem (&gUserInput->InputValue.Value.u32, &Option->OptionOpCode->Value.u32, sizeof (UINT32));
                break;
              case EFI_IFR_TYPE_NUM_SIZE_64:
                CopyMem (&gUserInput->InputValue.Value.u64, &Option->OptionOpCode->Value.u64, sizeof (UINT64));
                break;
              default:
                ASSERT (FALSE);
                break;
            }

            gUserInput->SelectedStatement = Question;
            gMisMatch                     = TRUE;
            FreePool (*OptionString);
            *OptionString = NULL;
            return EFI_NOT_FOUND;
          }
        }

        Character[0] = LEFT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], MaxLen, Character);
        StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
        ASSERT (StringPtr != NULL);
        NewStrCat (OptionString[0], MaxLen, StringPtr);
        Character[0] = RIGHT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], MaxLen, Character);

        FreePool (StringPtr);
      }

      break;

    case EFI_IFR_CHECKBOX_OP:
      if (Selected) {
        //
        // Since this is a BOOLEAN operation, flip it upon selection
        //
        gUserInput->InputValue.Type    = QuestionValue->Type;
        gUserInput->InputValue.Value.b = (BOOLEAN)(QuestionValue->Value.b ? FALSE : TRUE);

        //
        // Perform inconsistent check
        //
        return EFI_SUCCESS;
      } else {
        *OptionString = AllocateZeroPool (BufferSize);
        ASSERT (*OptionString);

        *OptionString[0] = LEFT_CHECKBOX_DELIMITER;

        if (QuestionValue->Value.b) {
          *(OptionString[0] + 1) = CHECK_ON;
        } else {
          *(OptionString[0] + 1) = CHECK_OFF;
        }

        *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
      }

      break;

    case EFI_IFR_NUMERIC_OP:
      if (Selected) {
        //
        // Go ask for input
        //
        Status = GetNumericInput (MenuOption);
      } else {
        *OptionString = AllocateZeroPool (BufferSize);
        ASSERT (*OptionString);

        *OptionString[0] = LEFT_NUMERIC_DELIMITER;

        //
        // Formatted print
        //
        PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
        Number = (UINT16)GetStringWidth (FormattedNumber);
        CopyMem (OptionString[0] + 1, FormattedNumber, Number);

        *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
      }

      break;

    case EFI_IFR_DATE_OP:
      if (Selected) {
        //
        // This is similar to numerics
        //
        Status = GetNumericInput (MenuOption);
      } else {
        *OptionString = AllocateZeroPool (BufferSize);
        ASSERT (*OptionString);

        switch (MenuOption->Sequence) {
          case 0:
            *OptionString[0] = LEFT_NUMERIC_DELIMITER;
            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' ');
            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' ');
            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;
        }
      }

      break;

    case EFI_IFR_TIME_OP:
      if (Selected) {
        //
        // This is similar to numerics
        //
        Status = GetNumericInput (MenuOption);
      } else {
        *OptionString = AllocateZeroPool (BufferSize);
        ASSERT (*OptionString);

        switch (MenuOption->Sequence) {
          case 0:
            *OptionString[0] = LEFT_NUMERIC_DELIMITER;
            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' ');
            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' ');
            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;
        }
      }

      break;

    case EFI_IFR_STRING_OP:
      if (Selected) {
        StringPtr = AllocateZeroPool (Question->CurrentValue.BufferLen + sizeof (CHAR16));
        ASSERT (StringPtr);
        CopyMem (StringPtr, Question->CurrentValue.Buffer, Question->CurrentValue.BufferLen);

        Status = ReadString (MenuOption, gPromptForData, StringPtr);
        if (EFI_ERROR (Status)) {
          FreePool (StringPtr);
          return Status;
        }

        gUserInput->InputValue.Buffer       = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);
        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);
        return EFI_SUCCESS;
      } else {
        *OptionString = AllocateZeroPool (BufferSize);
        ASSERT (*OptionString);

        if (((CHAR16 *)Question->CurrentValue.Buffer)[0] == 0x0000) {
          *(OptionString[0]) = '_';
        } else {
          if (Question->CurrentValue.BufferLen < BufferSize) {
            BufferSize = Question->CurrentValue.BufferLen;
          }

          CopyMem (OptionString[0], (CHAR16 *)Question->CurrentValue.Buffer, BufferSize);
        }
      }

      break;

    case EFI_IFR_PASSWORD_OP:
      if (Selected) {
        Status = PasswordProcess (MenuOption);
      }

      break;

    default:
      break;
  }

  return Status;
}

/**
  Process the help string: Split StringPtr to several lines of strings stored in
  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.

  @param  StringPtr              The entire help string.
  @param  FormattedString        The oupput formatted string.
  @param  EachLineWidth          The max string length of each line in the formatted string.
  @param  RowCount               TRUE: if Question is selected.

**/
UINTN
ProcessHelpString (
  IN  CHAR16  *StringPtr,
  OUT CHAR16  **FormattedString,
  OUT UINT16  *EachLineWidth,
  IN  UINTN   RowCount
  )
{
  UINTN   Index;
  CHAR16  *OutputString;
  UINTN   TotalRowNum;
  UINTN   CheckedNum;
  UINT16  GlyphWidth;
  UINT16  LineWidth;
  UINT16  MaxStringLen;
  UINT16  StringLen;

  TotalRowNum  = 0;
  CheckedNum   = 0;
  GlyphWidth   = 1;
  Index        = 0;
  MaxStringLen = 0;
  StringLen    = 0;

  //
  // Set default help string width.
  //
  LineWidth = (UINT16)(gHelpBlockWidth - 1);

  //
  // Get row number of the String.
  //
  while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
    if (StringLen > MaxStringLen) {
      MaxStringLen = StringLen;
    }

    TotalRowNum++;
    FreePool (OutputString);
  }

  *EachLineWidth = MaxStringLen;

  *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));
  ASSERT (*FormattedString != NULL);

  //
  // Generate formatted help string array.
  //
  GlyphWidth = 1;
  Index      = 0;
  while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
    CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));
    CheckedNum++;
    FreePool (OutputString);
  }

  return TotalRowNum;
}
