/** @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));
  if (EventNode == NULL) {
    ASSERT (EventNode != NULL);
    return;
  }

  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));
  if (EventNode == NULL) {
    ASSERT (EventNode != NULL);
    return;
  }

  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));
    if (DisplayOption == NULL) {
      ASSERT (DisplayOption != NULL);
      continue;
    }

    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);
    if (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));
    if (DisplayStatement == NULL) {
      ASSERT (DisplayStatement != NULL);
      return;
    }

    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));
  if (DisplayStatement == NULL) {
    ASSERT (DisplayStatement != NULL);
    return;
  }

  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));
    if (DisplayStatement == NULL) {
      ASSERT (DisplayStatement != NULL);
      continue;
    }

    //
    // 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));
    if (EventNode == NULL) {
      ASSERT (EventNode != NULL);
      return;
    }

    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_SUCCESS            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);
    if (HiiPackageList == NULL) {
      ASSERT (HiiPackageList != NULL);
      return FALSE;
    }

    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);
  if (HiiHandles == NULL ) {
    ASSERT (HiiHandles != NULL);
    return 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_SUCCESS            This function always return successfully for now.
  @retval EFI_NOT_FOUND          The satement associated with the userinput was not found.
**/
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);
    if (Statement == NULL ) {
      ASSERT (Statement != NULL);
      return EFI_NOT_FOUND;
    }

    //
    // 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 if (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_SUCCESS            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
                    );
    if (CurrentMenu == NULL) {
      ASSERT (CurrentMenu != NULL);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // 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);
        if (NewString == NULL) {
          ASSERT (NewString != NULL);
          continue;
        }

        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;

            case EFI_BROWSER_ACTION_REQUEST_QUESTION_APPLY:
              Status = SetQuestionValue (
                         gCurrentSelection->FormSet,
                         gCurrentSelection->Form,
                         Statement,
                         GetSetValueWithHiiDriver
                         );
              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);
    if (NewString == NULL) {
      ASSERT (NewString != NULL);
      return EFI_OUT_OF_RESOURCES;
    }

    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;
}
