/** @file
Utility functions for UI presentation.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 - 2022 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Setup.h"

BOOLEAN                   mHiiPackageListUpdated;
UI_MENU_SELECTION         *gCurrentSelection;
EFI_HII_HANDLE            mCurrentHiiHandle   = NULL;
EFI_GUID                  mCurrentFormSetGuid = {
  0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }
};
UINT16                    mCurrentFormId     = 0;
EFI_EVENT                 mValueChangedEvent = NULL;
LIST_ENTRY                mRefreshEventList  = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);
UINT16                    mCurFakeQestId;
FORM_DISPLAY_ENGINE_FORM  gDisplayFormData;
BOOLEAN                   mFinishRetrieveCall = FALSE;

/**
  Check whether the ConfigAccess protocol is available.

  @param FormSet           FormSet of which the ConfigAcces protocol need to be checked.

  @retval EFI_SUCCESS     The function executed successfully.

**/
EFI_STATUS
CheckConfigAccess (
  IN FORM_BROWSER_FORMSET  *FormSet
  )
{
  EFI_STATUS  Status;

  Status = gBS->HandleProtocol (
                  FormSet->DriverHandle,
                  &gEfiHiiConfigAccessProtocolGuid,
                  (VOID **)&FormSet->ConfigAccess
                  );
  if (EFI_ERROR (Status)) {
    //
    // Configuration Driver don't attach ConfigAccess protocol to its HII package
    // list, then there will be no configuration action required.
    // Or the ConfigAccess protocol has been uninstalled.
    //
    FormSet->ConfigAccess = NULL;
  }

  return EFI_SUCCESS;
}

/**
  Evaluate all expressions in a Form.

  @param  FormSet        FormSet this Form belongs to.
  @param  Form           The Form.

  @retval EFI_SUCCESS    The expression evaluated successfuly

**/
EFI_STATUS
EvaluateFormExpressions (
  IN FORM_BROWSER_FORMSET  *FormSet,
  IN FORM_BROWSER_FORM     *Form
  )
{
  EFI_STATUS       Status;
  LIST_ENTRY       *Link;
  FORM_EXPRESSION  *Expression;

  Link = GetFirstNode (&Form->ExpressionListHead);
  while (!IsNull (&Form->ExpressionListHead, Link)) {
    Expression = FORM_EXPRESSION_FROM_LINK (Link);
    Link       = GetNextNode (&Form->ExpressionListHead, Link);

    if ((Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF) ||
        (Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) ||
        (Expression->Type == EFI_HII_EXPRESSION_WARNING_IF) ||
        (Expression->Type == EFI_HII_EXPRESSION_WRITE) ||
        ((Expression->Type == EFI_HII_EXPRESSION_READ) && (Form->FormType != STANDARD_MAP_FORM_TYPE)))
    {
      //
      // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
      //
      continue;
    }

    Status = EvaluateExpression (FormSet, Form, Expression);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Base on the opcode buffer info to get the display statement.

  @param OpCode    The input opcode buffer for this statement.

  @retval Statement  The statement use this opcode buffer.

**/
FORM_DISPLAY_ENGINE_STATEMENT *
GetDisplayStatement (
  IN EFI_IFR_OP_HEADER  *OpCode
  )
{
  FORM_DISPLAY_ENGINE_STATEMENT  *DisplayStatement;
  LIST_ENTRY                     *Link;

  Link = GetFirstNode (&gDisplayFormData.StatementListHead);
  while (!IsNull (&gDisplayFormData.StatementListHead, Link)) {
    DisplayStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);

    if (DisplayStatement->OpCode == OpCode) {
      return DisplayStatement;
    }

    Link = GetNextNode (&gDisplayFormData.StatementListHead, Link);
  }

  return NULL;
}

/**
  Free the refresh event list.

**/
VOID
FreeRefreshEvent (
  VOID
  )
{
  LIST_ENTRY                       *Link;
  FORM_BROWSER_REFRESH_EVENT_NODE  *EventNode;

  while (!IsListEmpty (&mRefreshEventList)) {
    Link      = GetFirstNode (&mRefreshEventList);
    EventNode = FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link);
    RemoveEntryList (&EventNode->Link);

    gBS->CloseEvent (EventNode->RefreshEvent);

    FreePool (EventNode);
  }
}

/**
  Check whether this statement value is changed. If yes, update the statement value and return TRUE;
  else return FALSE.

  @param Statement           The statement need to check.

**/
VOID
UpdateStatement (
  IN OUT FORM_BROWSER_STATEMENT  *Statement
  )
{
  GetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);

  //
  // Reset FormPackage update flag
  //
  mHiiPackageListUpdated = FALSE;

  //
  // Question value may be changed, need invoke its Callback()
  //
  ProcessCallBackFunction (gCurrentSelection, gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, EFI_BROWSER_ACTION_RETRIEVE, FALSE);

  if (mHiiPackageListUpdated) {
    //
    // Package list is updated, force to reparse IFR binary of target Formset
    //
    mHiiPackageListUpdated    = FALSE;
    gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;
  }
}

/**
  Refresh the question which has refresh guid event attribute.

  @param Event    The event which has this function related.
  @param Context  The input context info related to this event or the status code return to the caller.
**/
VOID
EFIAPI
RefreshEventNotifyForStatement (
  IN      EFI_EVENT  Event,
  IN      VOID       *Context
  )
{
  FORM_BROWSER_STATEMENT  *Statement;

  Statement = (FORM_BROWSER_STATEMENT *)Context;
  UpdateStatement (Statement);
  gBS->SignalEvent (mValueChangedEvent);
}

/**
  Refresh the questions within this form.

  @param Event    The event which has this function related.
  @param Context  The input context info related to this event or the status code return to the caller.
**/
VOID
EFIAPI
RefreshEventNotifyForForm (
  IN      EFI_EVENT  Event,
  IN      VOID       *Context
  )
{
  gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;

  gBS->SignalEvent (mValueChangedEvent);
}

/**
  Create refresh hook event for statement which has refresh event or interval.

  @param Statement           The statement need to check.

**/
VOID
CreateRefreshEventForStatement (
  IN     FORM_BROWSER_STATEMENT  *Statement
  )
{
  EFI_STATUS                       Status;
  EFI_EVENT                        RefreshEvent;
  FORM_BROWSER_REFRESH_EVENT_NODE  *EventNode;

  //
  // If question has refresh guid, create the notify function.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  RefreshEventNotifyForStatement,
                  Statement,
                  &Statement->RefreshGuid,
                  &RefreshEvent
                  );
  ASSERT_EFI_ERROR (Status);

  EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
  ASSERT (EventNode != NULL);
  EventNode->RefreshEvent = RefreshEvent;
  InsertTailList (&mRefreshEventList, &EventNode->Link);
}

/**
  Create refresh hook event for form which has refresh event or interval.

  @param Form           The form need to check.

**/
VOID
CreateRefreshEventForForm (
  IN     FORM_BROWSER_FORM  *Form
  )
{
  EFI_STATUS                       Status;
  EFI_EVENT                        RefreshEvent;
  FORM_BROWSER_REFRESH_EVENT_NODE  *EventNode;

  //
  // If question has refresh guid, create the notify function.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  RefreshEventNotifyForForm,
                  Form,
                  &Form->RefreshGuid,
                  &RefreshEvent
                  );
  ASSERT_EFI_ERROR (Status);

  EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
  ASSERT (EventNode != NULL);
  EventNode->RefreshEvent = RefreshEvent;
  InsertTailList (&mRefreshEventList, &EventNode->Link);
}

/**

  Initialize the Display statement structure data.

  @param DisplayStatement      Pointer to the display Statement data strucure.
  @param Statement             The statement need to check.
**/
VOID
InitializeDisplayStatement (
  IN OUT FORM_DISPLAY_ENGINE_STATEMENT  *DisplayStatement,
  IN     FORM_BROWSER_STATEMENT         *Statement
  )
{
  LIST_ENTRY                     *Link;
  QUESTION_OPTION                *Option;
  DISPLAY_QUESTION_OPTION        *DisplayOption;
  FORM_DISPLAY_ENGINE_STATEMENT  *ParentStatement;

  DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
  DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
  DisplayStatement->OpCode    = Statement->OpCode;
  InitializeListHead (&DisplayStatement->NestStatementList);
  InitializeListHead (&DisplayStatement->OptionListHead);

  if ((EvaluateExpressionList (Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut) || Statement->Locked) {
    DisplayStatement->Attribute |= HII_DISPLAY_GRAYOUT;
  }

  if ((Statement->ValueExpression != NULL) || ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {
    DisplayStatement->Attribute |= HII_DISPLAY_READONLY;
  }

  //
  // Initilize the option list in statement.
  //
  Link = GetFirstNode (&Statement->OptionListHead);
  while (!IsNull (&Statement->OptionListHead, Link)) {
    Option = QUESTION_OPTION_FROM_LINK (Link);
    Link   = GetNextNode (&Statement->OptionListHead, Link);
    if ((Option->SuppressExpression != NULL) &&
        ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress)))
    {
      continue;
    }

    DisplayOption = AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION));
    ASSERT (DisplayOption != NULL);

    DisplayOption->ImageId      = Option->ImageId;
    DisplayOption->Signature    = DISPLAY_QUESTION_OPTION_SIGNATURE;
    DisplayOption->OptionOpCode = Option->OpCode;
    InsertTailList (&DisplayStatement->OptionListHead, &DisplayOption->Link);
  }

  CopyMem (&DisplayStatement->CurrentValue, &Statement->HiiValue, sizeof (EFI_HII_VALUE));

  //
  // Some special op code need an extra buffer to save the data.
  // Such as string, password, orderedlist...
  //
  if (Statement->BufferValue != NULL) {
    //
    // Ordered list opcode may not initilized, get default value here.
    //
    if ((Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) && (GetArrayData (Statement->BufferValue, Statement->ValueType, 0) == 0)) {
      GetQuestionDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, 0);
    }

    DisplayStatement->CurrentValue.Buffer    = AllocateCopyPool (Statement->StorageWidth, Statement->BufferValue);
    DisplayStatement->CurrentValue.BufferLen = Statement->StorageWidth;
  }

  DisplayStatement->SettingChangedFlag = Statement->ValueChanged;

  //
  // Get the highlight statement for current form.
  //
  if (((gCurrentSelection->QuestionId != 0) && (Statement->QuestionId == gCurrentSelection->QuestionId)) ||
      ((mCurFakeQestId != 0) && (Statement->FakeQuestionId == mCurFakeQestId)))
  {
    gDisplayFormData.HighLightedStatement = DisplayStatement;
  }

  //
  // Create the refresh event process function.
  //
  if (!IsZeroGuid (&Statement->RefreshGuid)) {
    CreateRefreshEventForStatement (Statement);
  }

  //
  // For RTC type of date/time, set default refresh interval to be 1 second.
  //
  if (((Statement->Operand == EFI_IFR_DATE_OP) || (Statement->Operand == EFI_IFR_TIME_OP)) && (Statement->Storage == NULL)) {
    Statement->RefreshInterval = 1;
  }

  //
  // Create the refresh guid hook event.
  // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
  //
  if ((!IsZeroGuid (&Statement->RefreshGuid)) || (Statement->RefreshInterval != 0)) {
    gDisplayFormData.FormRefreshEvent = mValueChangedEvent;
  }

  //
  // Save the password check function for later use.
  //
  if (Statement->Operand == EFI_IFR_PASSWORD_OP) {
    DisplayStatement->PasswordCheck = PasswordCheck;
  }

  //
  // If this statement is nest in the subtitle, insert to the host statement.
  // else insert to the form it belongs to.
  //
  if (Statement->ParentStatement != NULL) {
    ParentStatement = GetDisplayStatement (Statement->ParentStatement->OpCode);
    ASSERT (ParentStatement != NULL);
    InsertTailList (&ParentStatement->NestStatementList, &DisplayStatement->DisplayLink);
  } else {
    InsertTailList (&gDisplayFormData.StatementListHead, &DisplayStatement->DisplayLink);
  }
}

/**
  Process for the refresh interval statement.

  @param Event    The Event need to be process
  @param Context  The context of the event.

**/
VOID
EFIAPI
RefreshIntervalProcess (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  FORM_BROWSER_STATEMENT  *Statement;
  LIST_ENTRY              *Link;

  Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
  while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
    Link      = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);

    if (Statement->RefreshInterval == 0) {
      continue;
    }

    UpdateStatement (Statement);
  }

  gBS->SignalEvent (mValueChangedEvent);
}

/**

  Make a copy of the global hotkey info.

**/
VOID
UpdateHotkeyList (
  VOID
  )
{
  BROWSER_HOT_KEY  *HotKey;
  BROWSER_HOT_KEY  *CopyKey;
  LIST_ENTRY       *Link;

  Link = GetFirstNode (&gBrowserHotKeyList);
  while (!IsNull (&gBrowserHotKeyList, Link)) {
    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);

    CopyKey = AllocateCopyPool (sizeof (BROWSER_HOT_KEY), HotKey);
    ASSERT (CopyKey != NULL);
    CopyKey->KeyData = AllocateCopyPool (sizeof (EFI_INPUT_KEY), HotKey->KeyData);
    ASSERT (CopyKey->KeyData != NULL);
    CopyKey->HelpString = AllocateCopyPool (StrSize (HotKey->HelpString), HotKey->HelpString);
    ASSERT (CopyKey->HelpString != NULL);

    InsertTailList (&gDisplayFormData.HotKeyListHead, &CopyKey->Link);

    Link = GetNextNode (&gBrowserHotKeyList, Link);
  }
}

/**

  Get the extra question attribute from override question list.

  @param    QuestionId    The question id for this request question.

  @retval   The attribute for this question or NULL if not found this
            question in the list.

**/
UINT32
ProcessQuestionExtraAttr (
  IN   EFI_QUESTION_ID  QuestionId
  )
{
  LIST_ENTRY                   *Link;
  QUESTION_ATTRIBUTE_OVERRIDE  *QuestionDesc;

  //
  // Return HII_DISPLAY_NONE if input a invalid question id.
  //
  if (QuestionId == 0) {
    return HII_DISPLAY_NONE;
  }

  Link = GetFirstNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead);
  while (!IsNull (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link)) {
    QuestionDesc = FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link);
    Link         = GetNextNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link);

    if ((QuestionDesc->QuestionId == QuestionId) &&
        (QuestionDesc->FormId     == gCurrentSelection->FormId) &&
        (QuestionDesc->HiiHandle  == gCurrentSelection->Handle) &&
        CompareGuid (&QuestionDesc->FormSetGuid, &gCurrentSelection->FormSetGuid))
    {
      return QuestionDesc->Attribute;
    }
  }

  return HII_DISPLAY_NONE;
}

/**

  Enum all statement in current form, find all the statement can be display and
  add to the display form.

**/
VOID
AddStatementToDisplayForm (
  VOID
  )
{
  EFI_STATUS                       Status;
  LIST_ENTRY                       *Link;
  FORM_BROWSER_STATEMENT           *Statement;
  FORM_DISPLAY_ENGINE_STATEMENT    *DisplayStatement;
  UINT8                            MinRefreshInterval;
  EFI_EVENT                        RefreshIntervalEvent;
  FORM_BROWSER_REFRESH_EVENT_NODE  *EventNode;
  BOOLEAN                          FormEditable;
  UINT32                           ExtraAttribute;

  MinRefreshInterval = 0;
  FormEditable       = FALSE;

  //
  // Process the statement outside the form, these statements are not recognized
  // by browser core.
  //
  Link = GetFirstNode (&gCurrentSelection->FormSet->StatementListOSF);
  while (!IsNull (&gCurrentSelection->FormSet->StatementListOSF, Link)) {
    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
    Link      = GetNextNode (&gCurrentSelection->FormSet->StatementListOSF, Link);

    DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
    ASSERT (DisplayStatement != NULL);
    DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
    DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
    DisplayStatement->OpCode    = Statement->OpCode;

    InitializeListHead (&DisplayStatement->NestStatementList);
    InitializeListHead (&DisplayStatement->OptionListHead);

    InsertTailList (&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);
  }

  //
  // treat formset as statement outside the form,get its opcode.
  //
  DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
  ASSERT (DisplayStatement != NULL);

  DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
  DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
  DisplayStatement->OpCode    = gCurrentSelection->FormSet->OpCode;

  InitializeListHead (&DisplayStatement->NestStatementList);
  InitializeListHead (&DisplayStatement->OptionListHead);

  InsertTailList (&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);

  //
  // Process the statement in this form.
  //
  Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
  while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
    Link      = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);

    //
    // This statement can't be show, skip it.
    //
    if (EvaluateExpressionList (Statement->Expression, FALSE, NULL, NULL) > ExpressGrayOut) {
      continue;
    }

    //
    // Check the extra attribute.
    //
    ExtraAttribute = ProcessQuestionExtraAttr (Statement->QuestionId);
    if ((ExtraAttribute & HII_DISPLAY_SUPPRESS) != 0) {
      continue;
    }

    DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
    ASSERT (DisplayStatement != NULL);

    //
    // Initialize this statement and add it to the display form.
    //
    InitializeDisplayStatement (DisplayStatement, Statement);

    //
    // Set the extra attribute.
    //
    DisplayStatement->Attribute |= ExtraAttribute;

    if (Statement->Storage != NULL) {
      FormEditable = TRUE;
    }

    //
    // Get the minimal refresh interval value for later use.
    //
    if ((Statement->RefreshInterval != 0) &&
        ((MinRefreshInterval == 0) || (Statement->RefreshInterval < MinRefreshInterval)))
    {
      MinRefreshInterval = Statement->RefreshInterval;
    }
  }

  //
  // Create the periodic timer for refresh interval statement.
  //
  if (MinRefreshInterval != 0) {
    Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshIntervalProcess, NULL, &RefreshIntervalEvent);
    ASSERT_EFI_ERROR (Status);
    Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, MinRefreshInterval * ONE_SECOND);
    ASSERT_EFI_ERROR (Status);

    EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
    ASSERT (EventNode != NULL);
    EventNode->RefreshEvent = RefreshIntervalEvent;
    InsertTailList (&mRefreshEventList, &EventNode->Link);
  }

  //
  // Create the refresh event process function for Form.
  //
  if (!IsZeroGuid (&gCurrentSelection->Form->RefreshGuid)) {
    CreateRefreshEventForForm (gCurrentSelection->Form);
    if (gDisplayFormData.FormRefreshEvent == NULL) {
      gDisplayFormData.FormRefreshEvent = mValueChangedEvent;
    }
  }

  //
  // Update hotkey list field.
  //
  if ((gBrowserSettingScope == SystemLevel) || FormEditable) {
    UpdateHotkeyList ();
  }
}

/**

  Initialize the SettingChangedFlag variable in the display form.

**/
VOID
UpdateDataChangedFlag (
  VOID
  )
{
  LIST_ENTRY            *Link;
  FORM_BROWSER_FORMSET  *LocalFormSet;

  gDisplayFormData.SettingChangedFlag = FALSE;

  if (IsNvUpdateRequiredForForm (gCurrentSelection->Form)) {
    gDisplayFormData.SettingChangedFlag = TRUE;
    return;
  }

  //
  // Base on the system level to check whether need to show the NV flag.
  //
  switch (gBrowserSettingScope) {
    case SystemLevel:
      //
      // Check the maintain list to see whether there is any change.
      //
      Link = GetFirstNode (&gBrowserFormSetList);
      while (!IsNull (&gBrowserFormSetList, Link)) {
        LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
        if (IsNvUpdateRequiredForFormSet (LocalFormSet)) {
          gDisplayFormData.SettingChangedFlag = TRUE;
          return;
        }

        Link = GetNextNode (&gBrowserFormSetList, Link);
      }

      break;

    case FormSetLevel:
      if (IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet)) {
        gDisplayFormData.SettingChangedFlag = TRUE;
        return;
      }

      break;

    default:
      break;
  }
}

/**

  Initialize the Display form structure data.

**/
VOID
InitializeDisplayFormData (
  VOID
  )
{
  EFI_STATUS  Status;

  gDisplayFormData.Signature   = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;
  gDisplayFormData.Version     = FORM_DISPLAY_ENGINE_VERSION_1;
  gDisplayFormData.ImageId     = 0;
  gDisplayFormData.AnimationId = 0;

  InitializeListHead (&gDisplayFormData.StatementListHead);
  InitializeListHead (&gDisplayFormData.StatementListOSF);
  InitializeListHead (&gDisplayFormData.HotKeyListHead);

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_CALLBACK,
                  EfiEventEmptyFunction,
                  NULL,
                  &mValueChangedEvent
                  );
  ASSERT_EFI_ERROR (Status);
}

/**

  Free the kotkey info saved in form data.

**/
VOID
FreeHotkeyList (
  VOID
  )
{
  BROWSER_HOT_KEY  *HotKey;
  LIST_ENTRY       *Link;

  while (!IsListEmpty (&gDisplayFormData.HotKeyListHead)) {
    Link   = GetFirstNode (&gDisplayFormData.HotKeyListHead);
    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);

    RemoveEntryList (&HotKey->Link);

    FreePool (HotKey->KeyData);
    FreePool (HotKey->HelpString);
    FreePool (HotKey);
  }
}

/**

  Update the Display form structure data.

**/
VOID
UpdateDisplayFormData (
  VOID
  )
{
  gDisplayFormData.FormTitle = gCurrentSelection->Form->FormTitle;
  gDisplayFormData.FormId    = gCurrentSelection->FormId;
  gDisplayFormData.HiiHandle = gCurrentSelection->Handle;
  CopyGuid (&gDisplayFormData.FormSetGuid, &gCurrentSelection->FormSetGuid);

  gDisplayFormData.Attribute  = 0;
  gDisplayFormData.Attribute |= gCurrentSelection->Form->ModalForm ? HII_DISPLAY_MODAL : 0;
  gDisplayFormData.Attribute |= gCurrentSelection->Form->Locked    ? HII_DISPLAY_LOCK  : 0;

  gDisplayFormData.FormRefreshEvent     = NULL;
  gDisplayFormData.HighLightedStatement = NULL;

  UpdateDataChangedFlag ();

  AddStatementToDisplayForm ();
}

/**

  Free the Display Statement structure data.

  @param   StatementList         Point to the statement list which need to be free.

**/
VOID
FreeStatementData (
  LIST_ENTRY  *StatementList
  )
{
  LIST_ENTRY                     *Link;
  LIST_ENTRY                     *OptionLink;
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
  DISPLAY_QUESTION_OPTION        *Option;

  //
  // Free Statements/Questions
  //
  while (!IsListEmpty (StatementList)) {
    Link      = GetFirstNode (StatementList);
    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);

    //
    // Free Options List
    //
    while (!IsListEmpty (&Statement->OptionListHead)) {
      OptionLink = GetFirstNode (&Statement->OptionListHead);
      Option     = DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink);
      RemoveEntryList (&Option->Link);
      FreePool (Option);
    }

    //
    // Free nest statement List
    //
    if (!IsListEmpty (&Statement->NestStatementList)) {
      FreeStatementData (&Statement->NestStatementList);
    }

    RemoveEntryList (&Statement->DisplayLink);
    FreePool (Statement);
  }
}

/**

  Free the Display form structure data.

**/
VOID
FreeDisplayFormData (
  VOID
  )
{
  FreeStatementData (&gDisplayFormData.StatementListHead);
  FreeStatementData (&gDisplayFormData.StatementListOSF);

  FreeRefreshEvent ();

  FreeHotkeyList ();
}

/**

  Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.

  @param DisplayStatement        The input FORM_DISPLAY_ENGINE_STATEMENT.

  @retval FORM_BROWSER_STATEMENT  The return FORM_BROWSER_STATEMENT info.

**/
FORM_BROWSER_STATEMENT *
GetBrowserStatement (
  IN FORM_DISPLAY_ENGINE_STATEMENT  *DisplayStatement
  )
{
  FORM_BROWSER_STATEMENT  *Statement;
  LIST_ENTRY              *Link;

  Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
  while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);

    if (Statement->OpCode == DisplayStatement->OpCode) {
      return Statement;
    }

    Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
  }

  return NULL;
}

/**
  Update the ValueChanged status for questions in this form.

  @param  FormSet                FormSet data structure.
  @param  Form                   Form data structure.

**/
VOID
UpdateStatementStatusForForm (
  IN FORM_BROWSER_FORMSET  *FormSet,
  IN FORM_BROWSER_FORM     *Form
  )
{
  LIST_ENTRY              *Link;
  FORM_BROWSER_STATEMENT  *Question;

  Link = GetFirstNode (&Form->StatementListHead);
  while (!IsNull (&Form->StatementListHead, Link)) {
    Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
    Link     = GetNextNode (&Form->StatementListHead, Link);

    //
    // For password opcode, not set the the value changed flag.
    //
    if (Question->Operand == EFI_IFR_PASSWORD_OP) {
      continue;
    }

    IsQuestionValueChanged (FormSet, Form, Question, GetSetValueWithBuffer);
  }
}

/**
  Update the ValueChanged status for questions in this formset.

  @param  FormSet                FormSet data structure.

**/
VOID
UpdateStatementStatusForFormSet (
  IN FORM_BROWSER_FORMSET  *FormSet
  )
{
  LIST_ENTRY         *Link;
  FORM_BROWSER_FORM  *Form;

  Link = GetFirstNode (&FormSet->FormListHead);
  while (!IsNull (&FormSet->FormListHead, Link)) {
    Form = FORM_BROWSER_FORM_FROM_LINK (Link);
    Link = GetNextNode (&FormSet->FormListHead, Link);

    UpdateStatementStatusForForm (FormSet, Form);
  }
}

/**
  Update the ValueChanged status for questions.

  @param  FormSet                FormSet data structure.
  @param  Form                   Form data structure.
  @param  SettingScope           Setting Scope for Default action.

**/
VOID
UpdateStatementStatus (
  IN FORM_BROWSER_FORMSET   *FormSet,
  IN FORM_BROWSER_FORM      *Form,
  IN BROWSER_SETTING_SCOPE  SettingScope
  )
{
  LIST_ENTRY            *Link;
  FORM_BROWSER_FORMSET  *LocalFormSet;

  switch (SettingScope) {
    case SystemLevel:
      Link = GetFirstNode (&gBrowserFormSetList);
      while (!IsNull (&gBrowserFormSetList, Link)) {
        LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
        Link         = GetNextNode (&gBrowserFormSetList, Link);
        if (!ValidateFormSet (LocalFormSet)) {
          continue;
        }

        UpdateStatementStatusForFormSet (LocalFormSet);
      }

      break;

    case FormSetLevel:
      UpdateStatementStatusForFormSet (FormSet);
      break;

    case FormLevel:
      UpdateStatementStatusForForm (FormSet, Form);
      break;

    default:
      break;
  }
}

/**

  Process the action request in user input.

  @param Action                  The user input action request info.
  @param DefaultId               The user input default Id info.

  @retval EFI_SUCESSS            This function always return successfully for now.

**/
EFI_STATUS
ProcessAction (
  IN UINT32  Action,
  IN UINT16  DefaultId
  )
{
  //
  // This is caused by use press ESC, and it should not combine with other action type.
  //
  if ((Action & BROWSER_ACTION_FORM_EXIT) == BROWSER_ACTION_FORM_EXIT) {
    FindNextMenu (gCurrentSelection, FormLevel);
    return EFI_SUCCESS;
  }

  //
  // Below is normal hotkey trigged action, these action maybe combine with each other.
  //
  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
    DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
  }

  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
    ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE, FALSE);
    UpdateStatementStatus (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
  }

  if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {
    SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
  }

  if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {
    gResetRequiredFormLevel   = TRUE;
    gResetRequiredSystemLevel = TRUE;
  }

  if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {
    //
    // Form Exit without saving, Similar to ESC Key.
    // FormSet Exit without saving, Exit SendForm.
    // System Exit without saving, CallExitHandler and Exit SendForm.
    //
    DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
    if ((gBrowserSettingScope == FormLevel) || (gBrowserSettingScope == FormSetLevel)) {
      FindNextMenu (gCurrentSelection, gBrowserSettingScope);
    } else if (gBrowserSettingScope == SystemLevel) {
      if (ExitHandlerFunction != NULL) {
        ExitHandlerFunction ();
      }

      gCurrentSelection->Action = UI_ACTION_EXIT;
    }
  }

  return EFI_SUCCESS;
}

/**
  Check whether the formset guid is in this Hii package list.

  @param  HiiHandle              The HiiHandle for this HII package list.
  @param  FormSetGuid            The formset guid for the request formset.

  @retval TRUE                   Find the formset guid.
  @retval FALSE                  Not found the formset guid.

**/
BOOLEAN
GetFormsetGuidFromHiiHandle (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_GUID        *FormSetGuid
  )
{
  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;
  UINTN                        BufferSize;
  UINT32                       Offset;
  UINT32                       Offset2;
  UINT32                       PackageListLength;
  EFI_HII_PACKAGE_HEADER       PackageHeader;
  UINT8                        *Package;
  UINT8                        *OpCodeData;
  EFI_STATUS                   Status;
  BOOLEAN                      FindGuid;

  BufferSize     = 0;
  HiiPackageList = NULL;
  FindGuid       = FALSE;

  Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HiiPackageList = AllocatePool (BufferSize);
    ASSERT (HiiPackageList != NULL);

    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
  }

  if (EFI_ERROR (Status) || (HiiPackageList == NULL)) {
    return FALSE;
  }

  //
  // Get Form package from this HII package List
  //
  Offset  = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
  Offset2 = 0;
  CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));

  while (Offset < PackageListLength) {
    Package = ((UINT8 *)HiiPackageList) + Offset;
    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
    Offset += PackageHeader.Length;

    if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
      //
      // Search FormSet in this Form Package
      //
      Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
      while (Offset2 < PackageHeader.Length) {
        OpCodeData = Package + Offset2;

        if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
          if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
            FindGuid = TRUE;
            break;
          }
        }

        Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;
      }
    }

    if (FindGuid) {
      break;
    }
  }

  FreePool (HiiPackageList);

  return FindGuid;
}

/**
  Find HII Handle in the HII database associated with given Device Path.

  If DevicePath is NULL, then ASSERT.

  @param  DevicePath             Device Path associated with the HII package list
                                 handle.
  @param  FormsetGuid            The formset guid for this formset.

  @retval Handle                 HII package list Handle associated with the Device
                                        Path.
  @retval NULL                   Hii Package list handle is not found.

**/
EFI_HII_HANDLE
DevicePathToHiiHandle (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN EFI_GUID                  *FormsetGuid
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *TmpDevicePath;
  UINTN                     Index;
  EFI_HANDLE                Handle;
  EFI_HANDLE                DriverHandle;
  EFI_HII_HANDLE            *HiiHandles;
  EFI_HII_HANDLE            HiiHandle;

  ASSERT (DevicePath != NULL);

  TmpDevicePath = DevicePath;
  //
  // Locate Device Path Protocol handle buffer
  //
  Status = gBS->LocateDevicePath (
                  &gEfiDevicePathProtocolGuid,
                  &TmpDevicePath,
                  &DriverHandle
                  );
  if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {
    return NULL;
  }

  //
  // Retrieve all HII Handles from HII database
  //
  HiiHandles = HiiGetHiiHandles (NULL);
  if (HiiHandles == NULL) {
    return NULL;
  }

  //
  // Search Hii Handle by Driver Handle
  //
  HiiHandle = NULL;
  for (Index = 0; HiiHandles[Index] != NULL; Index++) {
    Status = mHiiDatabase->GetPackageListHandle (
                             mHiiDatabase,
                             HiiHandles[Index],
                             &Handle
                             );
    if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
      if (GetFormsetGuidFromHiiHandle (HiiHandles[Index], FormsetGuid)) {
        HiiHandle = HiiHandles[Index];
        break;
      }

      if (HiiHandle != NULL) {
        break;
      }
    }
  }

  FreePool (HiiHandles);
  return HiiHandle;
}

/**
  Find HII Handle in the HII database associated with given form set guid.

  If FormSetGuid is NULL, then ASSERT.

  @param  ComparingGuid          FormSet Guid associated with the HII package list
                                 handle.

  @retval Handle                 HII package list Handle associated with the Device
                                        Path.
  @retval NULL                   Hii Package list handle is not found.

**/
EFI_HII_HANDLE
FormSetGuidToHiiHandle (
  EFI_GUID  *ComparingGuid
  )
{
  EFI_HII_HANDLE  *HiiHandles;
  EFI_HII_HANDLE  HiiHandle;
  UINTN           Index;

  ASSERT (ComparingGuid != NULL);

  HiiHandle = NULL;
  //
  // Get all the Hii handles
  //
  HiiHandles = HiiGetHiiHandles (NULL);
  ASSERT (HiiHandles != NULL);

  //
  // Search for formset of each class type
  //
  for (Index = 0; HiiHandles[Index] != NULL; Index++) {
    if (GetFormsetGuidFromHiiHandle (HiiHandles[Index], ComparingGuid)) {
      HiiHandle = HiiHandles[Index];
      break;
    }

    if (HiiHandle != NULL) {
      break;
    }
  }

  FreePool (HiiHandles);

  return HiiHandle;
}

/**
  check how to process the changed data in current form or form set.

  @param Selection       On input, Selection tell setup browser the information
                         about the Selection, form and formset to be displayed.
                         On output, Selection return the screen item that is selected
                         by user.

  @param Scope           Data save or discard scope, form or formset.

  @retval                TRUE   Success process the changed data, will return to the parent form.
  @retval                FALSE  Reject to process the changed data, will stay at  current form.
**/
BOOLEAN
ProcessChangedData (
  IN OUT UI_MENU_SELECTION      *Selection,
  IN     BROWSER_SETTING_SCOPE  Scope
  )
{
  BOOLEAN     RetValue;
  EFI_STATUS  Status;

  RetValue = TRUE;
  switch (mFormDisplay->ConfirmDataChange ()) {
    case BROWSER_ACTION_DISCARD:
      DiscardForm (Selection->FormSet, Selection->Form, Scope);
      break;

    case BROWSER_ACTION_SUBMIT:
      Status = SubmitForm (Selection->FormSet, Selection->Form, Scope);
      if (EFI_ERROR (Status)) {
        RetValue = FALSE;
      }

      break;

    case BROWSER_ACTION_NONE:
      RetValue = FALSE;
      break;

    default:
      //
      // if Invalid value return, process same as BROWSER_ACTION_NONE.
      //
      RetValue = FALSE;
      break;
  }

  return RetValue;
}

/**
  Find parent formset menu(the first menu which has different formset) for current menu.
  If not find, just return to the first menu.

  @param Selection    The selection info.

**/
VOID
FindParentFormSet (
  IN OUT   UI_MENU_SELECTION  *Selection
  )
{
  FORM_ENTRY_INFO  *CurrentMenu;
  FORM_ENTRY_INFO  *ParentMenu;

  CurrentMenu = Selection->CurrentMenu;
  ParentMenu  = UiFindParentMenu (CurrentMenu, FormSetLevel);

  if (ParentMenu != NULL) {
    CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));
    Selection->Handle     = ParentMenu->HiiHandle;
    Selection->FormId     = ParentMenu->FormId;
    Selection->QuestionId = ParentMenu->QuestionId;
  } else {
    Selection->FormId     = CurrentMenu->FormId;
    Selection->QuestionId = CurrentMenu->QuestionId;
  }

  Selection->Statement = NULL;
}

/**
  Process the goto op code, update the info in the selection structure.

  @param Statement    The statement belong to goto op code.
  @param Selection    The selection info.

  @retval EFI_SUCCESS    The menu process successfully.
  @return Other value if the process failed.
**/
EFI_STATUS
ProcessGotoOpCode (
  IN OUT   FORM_BROWSER_STATEMENT  *Statement,
  IN OUT   UI_MENU_SELECTION       *Selection
  )
{
  CHAR16                    *StringPtr;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  FORM_BROWSER_FORM         *RefForm;
  EFI_STATUS                Status;
  EFI_HII_HANDLE            HiiHandle;

  Status    = EFI_SUCCESS;
  StringPtr = NULL;
  HiiHandle = NULL;

  //
  // Prepare the device path check, get the device path info first.
  //
  if (Statement->HiiValue.Value.ref.DevicePath != 0) {
    StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
  }

  //
  // Check whether the device path string is a valid string.
  //
  if ((Statement->HiiValue.Value.ref.DevicePath != 0) && (StringPtr != NULL) && (StringPtr[0] != L'\0')) {
    if (Selection->Form->ModalForm) {
      return Status;
    }

    //
    // Goto another Hii Package list
    //
    if (mPathFromText != NULL) {
      DevicePath = mPathFromText->ConvertTextToDevicePath (StringPtr);
      if (DevicePath != NULL) {
        HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);
        FreePool (DevicePath);
      }

      FreePool (StringPtr);
    } else {
      //
      // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
      //
      PopupErrorMessage (BROWSER_PROTOCOL_NOT_FOUND, NULL, NULL, NULL);
      FreePool (StringPtr);
      return Status;
    }

    if (HiiHandle != Selection->Handle) {
      //
      // Goto another Formset, check for uncommitted data
      //
      if (((gBrowserSettingScope == FormLevel) || (gBrowserSettingScope == FormSetLevel)) &&
          IsNvUpdateRequiredForFormSet (Selection->FormSet))
      {
        if (!ProcessChangedData (Selection, FormSetLevel)) {
          return EFI_SUCCESS;
        }
      }
    }

    Selection->Action = UI_ACTION_REFRESH_FORMSET;
    Selection->Handle = HiiHandle;
    if (Selection->Handle == NULL) {
      //
      // If target Hii Handle not found, exit current formset.
      //
      FindParentFormSet (Selection);
      return EFI_SUCCESS;
    }

    CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
    Selection->FormId     = Statement->HiiValue.Value.ref.FormId;
    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
  } else if (!IsZeroGuid (&Statement->HiiValue.Value.ref.FormSetGuid)) {
    if (Selection->Form->ModalForm) {
      return Status;
    }

    if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &Selection->FormSetGuid)) {
      //
      // Goto another Formset, check for uncommitted data
      //
      if (((gBrowserSettingScope == FormLevel) || (gBrowserSettingScope == FormSetLevel)) &&
          IsNvUpdateRequiredForFormSet (Selection->FormSet))
      {
        if (!ProcessChangedData (Selection, FormSetLevel)) {
          return EFI_SUCCESS;
        }
      }
    }

    Selection->Action = UI_ACTION_REFRESH_FORMSET;
    Selection->Handle = FormSetGuidToHiiHandle (&Statement->HiiValue.Value.ref.FormSetGuid);
    if (Selection->Handle == NULL) {
      //
      // If target Hii Handle not found, exit current formset.
      //
      FindParentFormSet (Selection);
      return EFI_SUCCESS;
    }

    CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
    Selection->FormId     = Statement->HiiValue.Value.ref.FormId;
    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
  } else if (Statement->HiiValue.Value.ref.FormId != 0) {
    //
    // Goto another Form, check for uncommitted data
    //
    if (Statement->HiiValue.Value.ref.FormId != Selection->FormId) {
      if (((gBrowserSettingScope == FormLevel) && IsNvUpdateRequiredForForm (Selection->Form))) {
        if (!ProcessChangedData (Selection, FormLevel)) {
          return EFI_SUCCESS;
        }
      }
    }

    RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
    if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
      if (EvaluateExpressionList (RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {
        //
        // Form is suppressed.
        //
        PopupErrorMessage (BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);
        return EFI_SUCCESS;
      }
    }

    Selection->FormId     = Statement->HiiValue.Value.ref.FormId;
    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
  } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
  }

  return Status;
}

/**
  Process Question Config.

  @param  Selection              The UI menu selection.
  @param  Question               The Question to be peocessed.

  @retval EFI_SUCCESS            Question Config process success.
  @retval Other                  Question Config process fail.

**/
EFI_STATUS
ProcessQuestionConfig (
  IN  UI_MENU_SELECTION       *Selection,
  IN  FORM_BROWSER_STATEMENT  *Question
  )
{
  EFI_STATUS  Status;
  CHAR16      *ConfigResp;
  CHAR16      *Progress;

  if (Question->QuestionConfig == 0) {
    return EFI_SUCCESS;
  }

  //
  // Get <ConfigResp>
  //
  ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);
  if (ConfigResp == NULL) {
    return EFI_NOT_FOUND;
  } else if (ConfigResp[0] == L'\0') {
    return EFI_SUCCESS;
  }

  //
  // Send config to Configuration Driver
  //
  Status = mHiiConfigRouting->RouteConfig (
                                mHiiConfigRouting,
                                ConfigResp,
                                &Progress
                                );

  return Status;
}

/**

  Process the user input data.

  @param UserInput               The user input data.

  @retval EFI_SUCESSS            This function always return successfully for now.

**/
EFI_STATUS
ProcessUserInput (
  IN USER_INPUT  *UserInput
  )
{
  EFI_STATUS              Status;
  FORM_BROWSER_STATEMENT  *Statement;

  Status    = EFI_SUCCESS;
  Statement = NULL;

  //
  // When Exit from FormDisplay function, one of the below two cases must be true.
  //
  ASSERT (UserInput->Action != 0 || UserInput->SelectedStatement != NULL);

  //
  // Remove the last highligh question id, this id will update when show next form.
  //
  gCurrentSelection->QuestionId = 0;
  if (UserInput->SelectedStatement != NULL) {
    Statement = GetBrowserStatement (UserInput->SelectedStatement);
    ASSERT (Statement != NULL);

    //
    // This question is the current user select one,record it and later
    // show it as the highlight question.
    //
    gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;
    //
    // For statement like text, actio, it not has question id.
    // So use FakeQuestionId to save the question.
    //
    if (gCurrentSelection->CurrentMenu->QuestionId == 0) {
      mCurFakeQestId = Statement->FakeQuestionId;
    } else {
      mCurFakeQestId = 0;
    }
  }

  //
  // First process the Action field in USER_INPUT.
  //
  if (UserInput->Action != 0) {
    Status                       = ProcessAction (UserInput->Action, UserInput->DefaultId);
    gCurrentSelection->Statement = NULL;
  } else {
    ASSERT (Statement != NULL);
    gCurrentSelection->Statement = Statement;
    switch (Statement->Operand) {
      case EFI_IFR_REF_OP:
        Status = ProcessGotoOpCode (Statement, gCurrentSelection);
        break;

      case EFI_IFR_ACTION_OP:
        //
        // Process the Config string <ConfigResp>
        //
        Status = ProcessQuestionConfig (gCurrentSelection, Statement);
        break;

      case EFI_IFR_RESET_BUTTON_OP:
        //
        // Reset Question to default value specified by DefaultId
        //
        Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE, FALSE);
        UpdateStatementStatus (gCurrentSelection->FormSet, NULL, FormSetLevel);
        break;

      default:
        switch (Statement->Operand) {
          case EFI_IFR_STRING_OP:
            DeleteString (Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);
            Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;
            CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN)UserInput->InputValue.BufferLen);
            FreePool (UserInput->InputValue.Buffer);
            break;

          case EFI_IFR_PASSWORD_OP:
            if (UserInput->InputValue.Buffer == NULL) {
              //
              // User not input new password, just return.
              //
              break;
            }

            DeleteString (Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);
            Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;
            CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN)UserInput->InputValue.BufferLen);
            ZeroMem (UserInput->InputValue.Buffer, (UINTN)UserInput->InputValue.BufferLen);
            FreePool (UserInput->InputValue.Buffer);
            //
            // Two password match, send it to Configuration Driver
            //
            if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
              PasswordCheck (NULL, UserInput->SelectedStatement, (CHAR16 *)Statement->BufferValue);
              //
              // Clean the value after saved it.
              //
              ZeroMem (Statement->BufferValue, (UINTN)UserInput->InputValue.BufferLen);
              HiiSetString (gCurrentSelection->FormSet->HiiHandle, Statement->HiiValue.Value.string, (CHAR16 *)Statement->BufferValue, NULL);
            } else {
              SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);
            }

            break;

          case EFI_IFR_ORDERED_LIST_OP:
            CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, UserInput->InputValue.BufferLen);
            break;

          default:
            CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));
            break;
        }

        break;
    }
  }

  return Status;
}

/**

  Display form and wait for user to select one menu option, then return it.

  @retval EFI_SUCESSS            This function always return successfully for now.

**/
EFI_STATUS
DisplayForm (
  VOID
  )
{
  EFI_STATUS       Status;
  USER_INPUT       UserInput;
  FORM_ENTRY_INFO  *CurrentMenu;

  ZeroMem (&UserInput, sizeof (USER_INPUT));

  //
  // Update the menu history data.
  //
  CurrentMenu = UiFindMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid, gCurrentSelection->FormId);
  if (CurrentMenu == NULL) {
    //
    // Current menu not found, add it to the menu tree
    //
    CurrentMenu = UiAddMenuList (
                    gCurrentSelection->Handle,
                    &gCurrentSelection->FormSetGuid,
                    gCurrentSelection->FormId,
                    gCurrentSelection->QuestionId
                    );
    ASSERT (CurrentMenu != NULL);
  }

  //
  // Back up the form view history data for this form.
  //
  UiCopyMenuList (&gCurrentSelection->Form->FormViewListHead, &mPrivateData.FormBrowserEx2.FormViewHistoryHead);

  gCurrentSelection->CurrentMenu = CurrentMenu;

  if (gCurrentSelection->QuestionId == 0) {
    //
    // Highlight not specified, fetch it from cached menu
    //
    gCurrentSelection->QuestionId = CurrentMenu->QuestionId;
  }

  Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  UpdateDisplayFormData ();

  ASSERT (gDisplayFormData.BrowserStatus == BROWSER_SUCCESS);
  Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);
  if (EFI_ERROR (Status)) {
    FreeDisplayFormData ();
    return Status;
  }

  CheckConfigAccess (gCurrentSelection->FormSet);

  Status = ProcessUserInput (&UserInput);
  FreeDisplayFormData ();
  return Status;
}

/**
  Functions which are registered to receive notification of
  database events have this prototype. The actual event is encoded
  in NotifyType. The following table describes how PackageType,
  PackageGuid, Handle, and Package are used for each of the
  notification types.

  @param PackageType  Package type of the notification.

  @param PackageGuid  If PackageType is
                      EFI_HII_PACKAGE_TYPE_GUID, then this is
                      the pointer to the GUID from the Guid
                      field of EFI_HII_PACKAGE_GUID_HEADER.
                      Otherwise, it must be NULL.

  @param Package  Points to the package referred to by the
                  notification Handle The handle of the package
                  list which contains the specified package.

  @param Handle       The HII handle.

  @param NotifyType   The type of change concerning the
                      database. See
                      EFI_HII_DATABASE_NOTIFY_TYPE.

**/
EFI_STATUS
EFIAPI
FormUpdateNotify (
  IN UINT8                         PackageType,
  IN CONST EFI_GUID                *PackageGuid,
  IN CONST EFI_HII_PACKAGE_HEADER  *Package,
  IN EFI_HII_HANDLE                Handle,
  IN EFI_HII_DATABASE_NOTIFY_TYPE  NotifyType
  )
{
  mHiiPackageListUpdated = TRUE;

  return EFI_SUCCESS;
}

/**
  Update the NV flag info for this form set.

  @param  FormSet                FormSet data structure.

**/
BOOLEAN
IsNvUpdateRequiredForFormSet (
  IN FORM_BROWSER_FORMSET  *FormSet
  )
{
  LIST_ENTRY         *Link;
  FORM_BROWSER_FORM  *Form;
  BOOLEAN            RetVal;

  //
  // Not finished question initialization, return FALSE.
  //
  if (!FormSet->QuestionInited) {
    return FALSE;
  }

  RetVal = FALSE;

  Link = GetFirstNode (&FormSet->FormListHead);
  while (!IsNull (&FormSet->FormListHead, Link)) {
    Form = FORM_BROWSER_FORM_FROM_LINK (Link);

    RetVal = IsNvUpdateRequiredForForm (Form);
    if (RetVal) {
      break;
    }

    Link = GetNextNode (&FormSet->FormListHead, Link);
  }

  return RetVal;
}

/**
  Update the NvUpdateRequired flag for a form.

  @param  Form                Form data structure.

**/
BOOLEAN
IsNvUpdateRequiredForForm (
  IN FORM_BROWSER_FORM  *Form
  )
{
  LIST_ENTRY              *Link;
  FORM_BROWSER_STATEMENT  *Statement;

  Link = GetFirstNode (&Form->StatementListHead);
  while (!IsNull (&Form->StatementListHead, Link)) {
    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);

    if (Statement->ValueChanged) {
      return TRUE;
    }

    Link = GetNextNode (&Form->StatementListHead, Link);
  }

  return FALSE;
}

/**
  Find menu which will show next time.

  @param Selection       On input, Selection tell setup browser the information
                         about the Selection, form and formset to be displayed.
                         On output, Selection return the screen item that is selected
                         by user.
  @param SettingLevel    Input Settting level, if it is FormLevel, just exit current form.
                         else, we need to exit current formset.

  @retval TRUE           Exit current form.
  @retval FALSE          User press ESC and keep in current form.
**/
BOOLEAN
FindNextMenu (
  IN OUT UI_MENU_SELECTION      *Selection,
  IN     BROWSER_SETTING_SCOPE  SettingLevel
  )
{
  FORM_ENTRY_INFO        *CurrentMenu;
  FORM_ENTRY_INFO        *ParentMenu;
  BROWSER_SETTING_SCOPE  Scope;

  CurrentMenu = Selection->CurrentMenu;
  Scope       = FormSetLevel;

  ParentMenu = UiFindParentMenu (CurrentMenu, SettingLevel);
  while (ParentMenu != NULL && !ValidateHiiHandle (ParentMenu->HiiHandle)) {
    ParentMenu = UiFindParentMenu (ParentMenu, SettingLevel);
  }

  if (ParentMenu != NULL) {
    if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
      Scope = FormLevel;
    } else {
      Scope = FormSetLevel;
    }
  }

  //
  // Form Level Check whether the data is changed.
  //
  if (((gBrowserSettingScope == FormLevel) && IsNvUpdateRequiredForForm (Selection->Form)) ||
      ((gBrowserSettingScope == FormSetLevel) && IsNvUpdateRequiredForFormSet (Selection->FormSet) && (Scope == FormSetLevel)))
  {
    if (!ProcessChangedData (Selection, gBrowserSettingScope)) {
      return FALSE;
    }
  }

  if (ParentMenu != NULL) {
    //
    // ParentMenu is found. Then, go to it.
    //
    if (Scope == FormLevel) {
      Selection->Action = UI_ACTION_REFRESH_FORM;
    } else {
      Selection->Action = UI_ACTION_REFRESH_FORMSET;
      CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));
      Selection->Handle = ParentMenu->HiiHandle;
    }

    Selection->Statement = NULL;

    Selection->FormId     = ParentMenu->FormId;
    Selection->QuestionId = ParentMenu->QuestionId;

    //
    // Clear highlight record for this menu
    //
    CurrentMenu->QuestionId = 0;
    return FALSE;
  }

  //
  // Current in root page, exit the SendForm
  //
  Selection->Action = UI_ACTION_EXIT;

  return TRUE;
}

/**
  Reconnect the controller.

  @param DriverHandle          The controller handle which need to be reconnect.

  @retval   TRUE     do the reconnect behavior success.
  @retval   FALSE    do the reconnect behavior failed.

**/
BOOLEAN
ReconnectController (
  IN EFI_HANDLE  DriverHandle
  )
{
  EFI_STATUS  Status;

  Status = gBS->DisconnectController (DriverHandle, NULL, NULL);
  if (!EFI_ERROR (Status)) {
    Status = gBS->ConnectController (DriverHandle, NULL, NULL, TRUE);
  }

  return Status == EFI_SUCCESS;
}

/**
  Call the call back function for the question and process the return action.

  @param Selection             On input, Selection tell setup browser the information
                               about the Selection, form and formset to be displayed.
                               On output, Selection return the screen item that is selected
                               by user.
  @param FormSet               The formset this question belong to.
  @param Form                  The form this question belong to.
  @param Question              The Question which need to call.
  @param Action                The action request.
  @param SkipSaveOrDiscard     Whether skip save or discard action.

  @retval EFI_SUCCESS          The call back function executes successfully.
  @return Other value if the call back function failed to execute.
**/
EFI_STATUS
ProcessCallBackFunction (
  IN OUT UI_MENU_SELECTION       *Selection,
  IN     FORM_BROWSER_FORMSET    *FormSet,
  IN     FORM_BROWSER_FORM       *Form,
  IN     FORM_BROWSER_STATEMENT  *Question,
  IN     EFI_BROWSER_ACTION      Action,
  IN     BOOLEAN                 SkipSaveOrDiscard
  )
{
  EFI_STATUS                      Status;
  EFI_STATUS                      InternalStatus;
  EFI_BROWSER_ACTION_REQUEST      ActionRequest;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  EFI_HII_VALUE                   *HiiValue;
  EFI_IFR_TYPE_VALUE              *TypeValue;
  FORM_BROWSER_STATEMENT          *Statement;
  BOOLEAN                         SubmitFormIsRequired;
  BOOLEAN                         DiscardFormIsRequired;
  BOOLEAN                         NeedExit;
  LIST_ENTRY                      *Link;
  BROWSER_SETTING_SCOPE           SettingLevel;
  EFI_IFR_TYPE_VALUE              BackUpValue;
  UINT8                           *BackUpBuffer;
  CHAR16                          *NewString;

  ConfigAccess          = FormSet->ConfigAccess;
  SubmitFormIsRequired  = FALSE;
  SettingLevel          = FormSetLevel;
  DiscardFormIsRequired = FALSE;
  NeedExit              = FALSE;
  Status                = EFI_SUCCESS;
  ActionRequest         = EFI_BROWSER_ACTION_REQUEST_NONE;
  BackUpBuffer          = NULL;

  if (ConfigAccess == NULL) {
    return EFI_SUCCESS;
  }

  Link = GetFirstNode (&Form->StatementListHead);
  while (!IsNull (&Form->StatementListHead, Link)) {
    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
    Link      = GetNextNode (&Form->StatementListHead, Link);

    //
    // if Question != NULL, only process the question. Else, process all question in this form.
    //
    if ((Question != NULL) && (Statement != Question)) {
      continue;
    }

    if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {
      continue;
    }

    //
    // Check whether Statement is disabled.
    //
    if (Statement->Expression != NULL) {
      if (EvaluateExpressionList (Statement->Expression, TRUE, FormSet, Form) == ExpressDisable) {
        continue;
      }
    }

    HiiValue  = &Statement->HiiValue;
    TypeValue = &HiiValue->Value;
    if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {
      //
      // For OrderedList, passing in the value buffer to Callback()
      //
      TypeValue = (EFI_IFR_TYPE_VALUE *)Statement->BufferValue;
    }

    //
    // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.
    //
    if (Action == EFI_BROWSER_ACTION_CHANGING) {
      if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {
        BackUpBuffer = AllocateCopyPool (Statement->StorageWidth, Statement->BufferValue);
        ASSERT (BackUpBuffer != NULL);
      } else {
        CopyMem (&BackUpValue, &HiiValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
      }
    }

    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
    Status        = ConfigAccess->Callback (
                                    ConfigAccess,
                                    Action,
                                    Statement->QuestionId,
                                    HiiValue->Type,
                                    TypeValue,
                                    &ActionRequest
                                    );
    if (!EFI_ERROR (Status)) {
      //
      // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue
      //
      if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
        NewString = GetToken (Statement->HiiValue.Value.string, FormSet->HiiHandle);
        ASSERT (NewString != NULL);

        ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);
        if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {
          ZeroMem (Statement->BufferValue, Statement->StorageWidth);
          CopyMem (Statement->BufferValue, NewString, StrSize (NewString));
        } else {
          CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);
        }

        FreePool (NewString);
      }

      //
      // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
      //
      switch (Action) {
        case EFI_BROWSER_ACTION_CHANGED:
          switch (ActionRequest) {
            case EFI_BROWSER_ACTION_REQUEST_RESET:
              DiscardFormIsRequired     = TRUE;
              gResetRequiredFormLevel   = TRUE;
              gResetRequiredSystemLevel = TRUE;
              NeedExit                  = TRUE;
              break;

            case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
              SubmitFormIsRequired = TRUE;
              NeedExit             = TRUE;
              break;

            case EFI_BROWSER_ACTION_REQUEST_EXIT:
              DiscardFormIsRequired = TRUE;
              NeedExit              = TRUE;
              break;

            case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:
              SubmitFormIsRequired = TRUE;
              SettingLevel         = FormLevel;
              NeedExit             = TRUE;
              break;

            case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:
              DiscardFormIsRequired = TRUE;
              SettingLevel          = FormLevel;
              NeedExit              = TRUE;
              break;

            case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY:
              SubmitFormIsRequired = TRUE;
              SettingLevel         = FormLevel;
              break;

            case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD:
              DiscardFormIsRequired = TRUE;
              SettingLevel          = FormLevel;
              break;

            case EFI_BROWSER_ACTION_REQUEST_RECONNECT:
              gCallbackReconnect = TRUE;
              break;

            default:
              break;
          }

          break;

        case EFI_BROWSER_ACTION_CHANGING:
          //
          // Do the question validation.
          //
          Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);
          if (!EFI_ERROR (Status)) {
            //
            // check whether the question value  changed compared with edit buffer before updating edit buffer
            // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function
            //
            IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);
            //
            // According the spec, return value from call back of "changing" and
            // "retrieve" should update to the question's temp buffer.
            //
            SetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);
          }

          break;

        case EFI_BROWSER_ACTION_RETRIEVE:
          //
          // According the spec, return value from call back of "changing" and
          // "retrieve" should update to the question's temp buffer.
          //
          SetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);
          break;

        default:
          break;
      }
    } else {
      //
      // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,
      // then the browser will use the value passed to Callback() and ignore the
      // value returned by Callback().
      //
      if ((Action  == EFI_BROWSER_ACTION_CHANGING) && (Status == EFI_UNSUPPORTED)) {
        if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {
          CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth);
        } else {
          CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));
        }

        //
        // Do the question validation.
        //
        InternalStatus = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);
        if (!EFI_ERROR (InternalStatus)) {
          //
          // check whether the question value  changed compared with edit buffer before updating edit buffer
          // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function
          //
          IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);
          SetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);
        }
      }

      //
      // According the spec, return fail from call back of "changing" and
      // "retrieve", should restore the question's value.
      //
      if ((Action == EFI_BROWSER_ACTION_CHANGING) && (Status != EFI_UNSUPPORTED)) {
        if (Statement->Storage != NULL) {
          GetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);
        } else if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
          ProcessCallBackFunction (Selection, FormSet, Form, Question, EFI_BROWSER_ACTION_RETRIEVE, FALSE);
        }
      }

      if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
        GetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);
      }

      if (Status == EFI_UNSUPPORTED) {
        //
        // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
        //
        Status = EFI_SUCCESS;
      }
    }

    if (BackUpBuffer != NULL) {
      FreePool (BackUpBuffer);
    }

    //
    // If Question != NULL, means just process one question
    // and if code reach here means this question has finished
    // processing, so just break.
    //
    if (Question != NULL) {
      break;
    }
  }

  if (gCallbackReconnect && (EFI_BROWSER_ACTION_CHANGED == Action)) {
    //
    // Confirm changes with user first.
    //
    if (IsNvUpdateRequiredForFormSet (FormSet)) {
      if (BROWSER_ACTION_DISCARD == PopupErrorMessage (BROWSER_RECONNECT_SAVE_CHANGES, NULL, NULL, NULL)) {
        gCallbackReconnect    = FALSE;
        DiscardFormIsRequired = TRUE;
      } else {
        SubmitFormIsRequired = TRUE;
      }
    } else {
      PopupErrorMessage (BROWSER_RECONNECT_REQUIRED, NULL, NULL, NULL);
    }

    //
    // Exit current formset before do the reconnect.
    //
    NeedExit     = TRUE;
    SettingLevel = FormSetLevel;
  }

  if (SubmitFormIsRequired && !SkipSaveOrDiscard) {
    SubmitForm (FormSet, Form, SettingLevel);
  }

  if (DiscardFormIsRequired && !SkipSaveOrDiscard) {
    DiscardForm (FormSet, Form, SettingLevel);
  }

  if (NeedExit) {
    FindNextMenu (Selection, SettingLevel);
  }

  return Status;
}

/**
  Call the retrieve type call back function for one question to get the initialize data.

  This function only used when in the initialize stage, because in this stage, the
  Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.

  @param ConfigAccess          The config access protocol produced by the hii driver.
  @param Statement             The Question which need to call.
  @param FormSet               The formset this question belong to.

  @retval EFI_SUCCESS          The call back function executes successfully.
  @return Other value if the call back function failed to execute.
**/
EFI_STATUS
ProcessRetrieveForQuestion (
  IN     EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess,
  IN     FORM_BROWSER_STATEMENT          *Statement,
  IN     FORM_BROWSER_FORMSET            *FormSet
  )
{
  EFI_STATUS                  Status;
  EFI_BROWSER_ACTION_REQUEST  ActionRequest;
  EFI_HII_VALUE               *HiiValue;
  EFI_IFR_TYPE_VALUE          *TypeValue;
  CHAR16                      *NewString;

  Status        = EFI_SUCCESS;
  ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;

  if (((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) || (ConfigAccess == NULL)) {
    return EFI_UNSUPPORTED;
  }

  HiiValue  = &Statement->HiiValue;
  TypeValue = &HiiValue->Value;
  if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {
    //
    // For OrderedList, passing in the value buffer to Callback()
    //
    TypeValue = (EFI_IFR_TYPE_VALUE *)Statement->BufferValue;
  }

  ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
  Status        = ConfigAccess->Callback (
                                  ConfigAccess,
                                  EFI_BROWSER_ACTION_RETRIEVE,
                                  Statement->QuestionId,
                                  HiiValue->Type,
                                  TypeValue,
                                  &ActionRequest
                                  );
  if (!EFI_ERROR (Status) && (HiiValue->Type == EFI_IFR_TYPE_STRING)) {
    NewString = GetToken (Statement->HiiValue.Value.string, FormSet->HiiHandle);
    ASSERT (NewString != NULL);

    ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);
    if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {
      ZeroMem (Statement->BufferValue, Statement->StorageWidth);
      CopyMem (Statement->BufferValue, NewString, StrSize (NewString));
    } else {
      CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);
    }

    FreePool (NewString);
  }

  return Status;
}

/**
  The worker function that send the displays to the screen. On output,
  the selection made by user is returned.

  @param Selection       On input, Selection tell setup browser the information
                         about the Selection, form and formset to be displayed.
                         On output, Selection return the screen item that is selected
                         by user.

  @retval EFI_SUCCESS    The page is displayed successfully.
  @return Other value if the page failed to be diplayed.

**/
EFI_STATUS
SetupBrowser (
  IN OUT UI_MENU_SELECTION  *Selection
  )
{
  EFI_STATUS                      Status;
  LIST_ENTRY                      *Link;
  EFI_HANDLE                      NotifyHandle;
  FORM_BROWSER_STATEMENT          *Statement;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;

  ConfigAccess = Selection->FormSet->ConfigAccess;

  //
  // Register notify for Form package update
  //
  Status = mHiiDatabase->RegisterPackageNotify (
                           mHiiDatabase,
                           EFI_HII_PACKAGE_FORMS,
                           NULL,
                           FormUpdateNotify,
                           EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
                           &NotifyHandle
                           );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Initialize current settings of Questions in this FormSet
  //
  InitializeCurrentSetting (Selection->FormSet);

  //
  // Initilize Action field.
  //
  Selection->Action = UI_ACTION_REFRESH_FORM;

  //
  // Clean the mCurFakeQestId value is formset refreshed.
  //
  mCurFakeQestId = 0;

  do {
    //
    // Reset Status to prevent the next break from returning incorrect error status.
    //
    Status = EFI_SUCCESS;

    //
    // IFR is updated, force to reparse the IFR binary
    // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and
    // EFI_BROWSER_ACTION_RETRIEVE, so code place here.
    //
    if (mHiiPackageListUpdated) {
      Selection->Action      = UI_ACTION_REFRESH_FORMSET;
      mHiiPackageListUpdated = FALSE;
      break;
    }

    //
    // Initialize Selection->Form
    //
    if (Selection->FormId == 0) {
      //
      // Zero FormId indicates display the first Form in a FormSet
      //
      Link = GetFirstNode (&Selection->FormSet->FormListHead);

      Selection->Form   = FORM_BROWSER_FORM_FROM_LINK (Link);
      Selection->FormId = Selection->Form->FormId;
    } else {
      Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);
    }

    if (Selection->Form == NULL) {
      //
      // No Form to display
      //
      Status = EFI_NOT_FOUND;
      goto Done;
    }

    //
    // Check Form is suppressed.
    //
    if (Selection->Form->SuppressExpression != NULL) {
      if (EvaluateExpressionList (Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {
        //
        // Form is suppressed.
        //
        PopupErrorMessage (BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);
        Status = EFI_NOT_FOUND;
        goto Done;
      }
    }

    //
    // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
    // for each question with callback flag.
    // New form may be the first form, or the different form after another form close.
    //
    if (((Selection->Handle != mCurrentHiiHandle) ||
         (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||
         (Selection->FormId != mCurrentFormId)))
    {
      //
      // Update Retrieve flag.
      //
      mFinishRetrieveCall = FALSE;

      //
      // Keep current form information
      //
      mCurrentHiiHandle = Selection->Handle;
      CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);
      mCurrentFormId = Selection->FormId;

      if (ConfigAccess != NULL) {
        Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);
        if (EFI_ERROR (Status)) {
          goto Done;
        }

        //
        // IFR is updated during callback of EFI_BROWSER_ACTION_FORM_OPEN, force to reparse the IFR binary
        //
        if (mHiiPackageListUpdated) {
          Selection->Action      = UI_ACTION_REFRESH_FORMSET;
          mHiiPackageListUpdated = FALSE;
          break;
        }
      }
    }

    //
    // Load Questions' Value for display
    //
    Status = LoadFormSetConfig (Selection, Selection->FormSet);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    if (!mFinishRetrieveCall) {
      //
      // Finish call RETRIEVE callback for this form.
      //
      mFinishRetrieveCall = TRUE;

      if (ConfigAccess != NULL) {
        Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_RETRIEVE, FALSE);
        if (EFI_ERROR (Status)) {
          goto Done;
        }

        //
        // IFR is updated during callback of open form, force to reparse the IFR binary
        //
        if (mHiiPackageListUpdated) {
          Selection->Action      = UI_ACTION_REFRESH_FORMSET;
          mHiiPackageListUpdated = FALSE;
          break;
        }
      }
    }

    //
    // Display form
    //
    Status = DisplayForm ();
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    //
    // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
    //
    Statement = Selection->Statement;
    if (Statement != NULL) {
      if ((ConfigAccess != NULL) &&
          ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&
          (Statement->Operand != EFI_IFR_PASSWORD_OP))
      {
        Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
        if (Statement->Operand == EFI_IFR_REF_OP) {
          //
          // Process dynamic update ref opcode.
          //
          if (!EFI_ERROR (Status)) {
            Status = ProcessGotoOpCode (Statement, Selection);
          }

          //
          // Callback return error status or status return from process goto opcode.
          //
          if (EFI_ERROR (Status)) {
            //
            // Cross reference will not be taken, restore all essential field
            //
            Selection->Handle = mCurrentHiiHandle;
            CopyMem (&Selection->FormSetGuid, &mCurrentFormSetGuid, sizeof (EFI_GUID));
            Selection->FormId     = mCurrentFormId;
            Selection->QuestionId = 0;
            Selection->Action     = UI_ACTION_REFRESH_FORM;
          }
        }

        if (!EFI_ERROR (Status) &&
            (Statement->Operand != EFI_IFR_REF_OP) &&
            ((Statement->Storage == NULL) || ((Statement->Storage != NULL) && Statement->ValueChanged)))
        {
          //
          // Only question value has been changed, browser will trig CHANGED callback.
          //
          ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);
          //
          // check whether the question value changed compared with buffer value
          // if doesn't change ,set the ValueChanged flag to FALSE ,in order not to display the "configuration changed "information on the screen
          //
          IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);
        }
      } else {
        //
        // Do the question validation.
        //
        Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);
        if (!EFI_ERROR (Status) && (Statement->Operand != EFI_IFR_PASSWORD_OP)) {
          SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);
          //
          // Verify whether question value has checked, update the ValueChanged flag in Question.
          //
          IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);
        }
      }

      //
      // If question has EFI_IFR_FLAG_RESET_REQUIRED/EFI_IFR_FLAG_RECONNECT_REQUIRED flag and without storage
      // and process question success till here, trig the gResetFlag/gFlagReconnect.
      //
      if ((Status == EFI_SUCCESS) &&
          (Statement->Storage == NULL))
      {
        if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {
          gResetRequiredFormLevel   = TRUE;
          gResetRequiredSystemLevel = TRUE;
        }

        if ((Statement->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {
          gFlagReconnect = TRUE;
        }
      }
    }

    //
    // Check whether Exit flag is TRUE.
    //
    if (gExitRequired) {
      switch (gBrowserSettingScope) {
        case SystemLevel:
          Selection->Action = UI_ACTION_EXIT;
          break;

        case FormSetLevel:
        case FormLevel:
          FindNextMenu (Selection, gBrowserSettingScope);
          break;

        default:
          break;
      }

      gExitRequired = FALSE;
    }

    //
    // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
    // for each question with callback flag.
    //
    if ((ConfigAccess != NULL) &&
        ((Selection->Action == UI_ACTION_EXIT) ||
         (Selection->Handle != mCurrentHiiHandle) ||
         (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||
         (Selection->FormId != mCurrentFormId)))
    {
      Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }
  } while (Selection->Action == UI_ACTION_REFRESH_FORM);

Done:
  //
  // Reset current form information to the initial setting when error happens or form exit.
  //
  if (EFI_ERROR (Status) || (Selection->Action == UI_ACTION_EXIT)) {
    mCurrentHiiHandle = NULL;
    CopyGuid (&mCurrentFormSetGuid, &gZeroGuid);
    mCurrentFormId = 0;
  }

  //
  // Unregister notify for Form package update
  //
  mHiiDatabase->UnregisterPackageNotify (
                  mHiiDatabase,
                  NotifyHandle
                  );
  return Status;
}
