]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
1. Support inconsistent if opcode used in string/password opcode.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
index 631f6413b889f65ab6aa2ad7029959153ef5c85d..6d9a555b4920c1e33b88f6102a0215d47f835485 100644 (file)
-/** @file
-Copyright (c) 2004 - 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-  Presentation.c
-
-Abstract:
-
-  Some presentation routines.
-
-
-**/
-
-#include "Setup.h"
-#include "Ui.h"
-
-BOOLEAN            mHiiPackageListUpdated;
-UI_MENU_SELECTION  *gCurrentSelection;
-
-
-/**
-  Clear retangle with specified text attribute.
-
-  @param  LeftColumn     Left column of retangle.
-  @param  RightColumn    Right column of retangle.
-  @param  TopRow         Start row of retangle.
-  @param  BottomRow      End row of retangle.
-  @param  TextAttribute  The character foreground and background.
-
-  @return None.
-
-**/
-VOID
-ClearLines (
-  UINTN                                       LeftColumn,
-  UINTN                                       RightColumn,
-  UINTN                                       TopRow,
-  UINTN                                       BottomRow,
-  UINTN                                       TextAttribute
-  )
-{
-  CHAR16  *Buffer;
-  UINTN   Row;
-
-  //
-  // For now, allocate an arbitrarily long buffer
-  //
-  Buffer = AllocateZeroPool (0x10000);
-  ASSERT (Buffer != NULL);
-
-  //
-  // Set foreground and background as defined
-  //
-  gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
-
-  //
-  // Much faster to buffer the long string instead of print it a character at a time
-  //
-  SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
-
-  //
-  // Clear the desired area with the appropriate foreground/background
-  //
-  for (Row = TopRow; Row <= BottomRow; Row++) {
-    PrintStringAt (LeftColumn, Row, Buffer);
-  }
-
-  gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
-
-  gBS->FreePool (Buffer);
-  return ;
-}
-
-VOID
-NewStrCat (
-  CHAR16                                      *Destination,
-  CHAR16                                      *Source
-  )
-{
-  UINTN Length;
-
-  for (Length = 0; Destination[Length] != 0; Length++)
-    ;
-
-  //
-  // We now have the length of the original string
-  // We can safely assume for now that we are concatenating a narrow value to this string.
-  // For instance, the string is "XYZ" and cat'ing ">"
-  // If this assumption changes, we need to make this routine a bit more complex
-  //
-  Destination[Length] = NARROW_CHAR;
-  Length++;
-
-  StrCpy (Destination + Length, Source);
-}
-
-UINTN
-GetStringWidth (
-  CHAR16                                      *String
-  )
-{
-  UINTN Index;
-  UINTN Count;
-  UINTN IncrementValue;
-
-  Index           = 0;
-  Count           = 0;
-  IncrementValue  = 1;
-
-  do {
-    //
-    // Advance to the null-terminator or to the first width directive
-    //
-    for (;
-         (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
-         Index++, Count = Count + IncrementValue
-        )
-      ;
-
-    //
-    // We hit the null-terminator, we now have a count
-    //
-    if (String[Index] == 0) {
-      break;
-    }
-    //
-    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
-    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
-    //
-    if (String[Index] == NARROW_CHAR) {
-      //
-      // Skip to the next character
-      //
-      Index++;
-      IncrementValue = 1;
-    } else {
-      //
-      // Skip to the next character
-      //
-      Index++;
-      IncrementValue = 2;
-    }
-  } while (String[Index] != 0);
-
-  //
-  // Increment by one to include the null-terminator in the size
-  //
-  Count++;
-
-  return Count * sizeof (CHAR16);
-}
-
-VOID
-DisplayPageFrame (
-  VOID
-  )
-{
-  UINTN                  Index;
-  UINT8                  Line;
-  UINT8                  Alignment;
-  CHAR16                 Character;
-  CHAR16                 *Buffer;
-  CHAR16                 *StrFrontPageBanner;
-  UINTN                  Row;
-  EFI_SCREEN_DESCRIPTOR  LocalScreen;
-
-  ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));
-  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);
-  ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);
-
-  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
-
-  //
-  // For now, allocate an arbitrarily long buffer
-  //
-  Buffer = AllocateZeroPool (0x10000);
-  ASSERT (Buffer != NULL);
-
-  Character = BOXDRAW_HORIZONTAL;
-
-  for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {
-    Buffer[Index] = Character;
-  }
-
-  if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
-    //
-    //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
-    //
-    ClearLines (
-      LocalScreen.LeftColumn,
-      LocalScreen.RightColumn,
-      LocalScreen.TopRow,
-      FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,
-      BANNER_TEXT | BANNER_BACKGROUND
-      );
-    //
-    //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {
-    //
-    for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {
-      //
-      //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
-      //
-      for (Alignment = (UINT8) LocalScreen.LeftColumn;
-           Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;
-           Alignment++
-          ) {
-        if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) {
-          StrFrontPageBanner = GetToken (
-                                BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn],
-                                FrontPageHandle
-                                );
-        } else {
-          continue;
-        }
-
-        switch (Alignment - LocalScreen.LeftColumn) {
-        case 0:
-          //
-          // Handle left column
-          //
-          PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);
-          break;
-
-        case 1:
-          //
-          // Handle center column
-          //
-          PrintStringAt (
-            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
-            Line,
-            StrFrontPageBanner
-            );
-          break;
-
-        case 2:
-          //
-          // Handle right column
-          //
-          PrintStringAt (
-            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
-            Line,
-            StrFrontPageBanner
-            );
-          break;
-        }
-
-        gBS->FreePool (StrFrontPageBanner);
-      }
-    }
-  }
-
-  ClearLines (
-    LocalScreen.LeftColumn,
-    LocalScreen.RightColumn,
-    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,
-    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
-    KEYHELP_TEXT | KEYHELP_BACKGROUND
-    );
-
-  if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
-    ClearLines (
-      LocalScreen.LeftColumn,
-      LocalScreen.RightColumn,
-      LocalScreen.TopRow,
-      LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,
-      TITLE_TEXT | TITLE_BACKGROUND
-      );
-    //
-    // Print Top border line
-    // +------------------------------------------------------------------------------+
-    // ?                                                                             ?
-    // +------------------------------------------------------------------------------+
-    //
-    Character = BOXDRAW_DOWN_RIGHT;
-
-    PrintChar (Character);
-    PrintString (Buffer);
-
-    Character = BOXDRAW_DOWN_LEFT;
-    PrintChar (Character);
-
-    Character = BOXDRAW_VERTICAL;
-    for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
-      PrintCharAt (LocalScreen.LeftColumn, Row, Character);
-      PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
-    }
-
-    Character = BOXDRAW_UP_RIGHT;
-    PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
-    PrintString (Buffer);
-
-    Character = BOXDRAW_UP_LEFT;
-    PrintChar (Character);
-
-    if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
-      //
-      // Print Bottom border line
-      // +------------------------------------------------------------------------------+
-      // ?                                                                             ?
-      // +------------------------------------------------------------------------------+
-      //
-      Character = BOXDRAW_DOWN_RIGHT;
-      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);
-
-      PrintString (Buffer);
-
-      Character = BOXDRAW_DOWN_LEFT;
-      PrintChar (Character);
-      Character = BOXDRAW_VERTICAL;
-      for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;
-           Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
-           Row++
-          ) {
-        PrintCharAt (LocalScreen.LeftColumn, Row, Character);
-        PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
-      }
-
-      Character = BOXDRAW_UP_RIGHT;
-      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
-
-      PrintString (Buffer);
-
-      Character = BOXDRAW_UP_LEFT;
-      PrintChar (Character);
-    }
-  }
-
-  gBS->FreePool (Buffer);
-
-}
-
-
-/**
-  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) {
-      //
-      // Postpone Form validation to Question editing or Form submiting
-      //
-      continue;
-    }
-
-    Status = EvaluateExpression (FormSet, Form, Expression);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/*
-+------------------------------------------------------------------------------+
-?F2=Previous Page                 Setup Page                                  ?
-+------------------------------------------------------------------------------+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-+------------------------------------------------------------------------------+
-?F1=Scroll Help                 F9=Reset to Defaults        F10=Save and Exit ?
-| ^"=Move Highlight          <Spacebar> Toggles Checkbox   Esc=Discard Changes |
-+------------------------------------------------------------------------------+
-*/
-EFI_STATUS
-DisplayForm (
-  IN OUT UI_MENU_SELECTION           *Selection
-  )
-{
-  CHAR16                 *StringPtr;
-  UINT16                 MenuItemCount;
-  EFI_HII_HANDLE         Handle;
-  BOOLEAN                Suppress;
-  EFI_SCREEN_DESCRIPTOR  LocalScreen;
-  UINT16                 Width;
-  UINTN                  ArrayEntry;
-  CHAR16                 *OutputString;
-  LIST_ENTRY             *Link;
-  FORM_BROWSER_STATEMENT *Statement;
-  UINT16                 NumberOfLines;
-  EFI_STATUS             Status;
-
-  Handle        = Selection->Handle;
-  MenuItemCount = 0;
-  ArrayEntry    = 0;
-  OutputString  = NULL;
-
-  UiInitMenu ();
-
-  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
-
-  StringPtr = GetToken (Selection->FormSet->FormSetTitle, Handle);
-
-  if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
-    gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
-    PrintStringAt (
-      (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,
-      LocalScreen.TopRow + 1,
-      StringPtr
-      );
-  }
-
-  if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
-    gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
-
-    //
-    // Display the infrastructure strings
-    //
-    if (!IsListEmpty (&gMenuList)) {
-      PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString);
-    }
-
-    PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString);
-    PrintStringAt (
-      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
-      LocalScreen.BottomRow - 4,
-      gFunctionNineString
-      );
-    PrintStringAt (
-      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
-      LocalScreen.BottomRow - 4,
-      gFunctionTenString
-      );
-    PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
-    PrintStringAt (
-      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
-      LocalScreen.BottomRow - 3,
-      gEscapeString
-      );
-  }
-  //
-  // Remove Buffer allocated for StringPtr after it has been used.
-  //
-  gBS->FreePool (StringPtr);
-
-  //
-  // Evaluate all the Expressions in this Form
-  //
-  Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Link = GetFirstNode (&Selection->Form->StatementListHead);
-  while (!IsNull (&Selection->Form->StatementListHead, Link)) {
-    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
-
-    if (Statement->SuppressExpression != NULL) {
-      Suppress = Statement->SuppressExpression->Result.Value.b;
-    } else {
-      Suppress = FALSE;
-    }
-
-    if (!Suppress) {
-      StringPtr = GetToken (Statement->Prompt, Handle);
-
-      Width     = GetWidth (Statement, Handle);
-
-      NumberOfLines = 1;
-      ArrayEntry = 0;
-      for (; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {
-        //
-        // If there is more string to process print on the next row and increment the Skip value
-        //
-        if (StrLen (&StringPtr[ArrayEntry])) {
-          NumberOfLines++;
-        }
-
-        gBS->FreePool (OutputString);
-      }
-
-      //
-      // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
-      // it in UiFreeMenu.
-      //
-      UiAddMenuOption (StringPtr, Selection->Handle, Statement, NumberOfLines, MenuItemCount);
-      MenuItemCount++;
-    }
-
-    Link = GetNextNode (&Selection->Form->StatementListHead, Link);
-  }
-
-  Status = UiDisplayMenu (Selection);
-
-  UiFreeMenu ();
-
-  return Status;
-}
-
-VOID
-InitializeBrowserStrings (
-  VOID
-  )
-{
-  gFunctionOneString    = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle);
-  gFunctionTwoString    = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle);
-  gFunctionNineString   = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
-  gFunctionTenString    = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
-  gEnterString          = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
-  gEnterCommitString    = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
-  gEscapeString         = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);
-  gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
-  gMoveHighlight        = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
-  gMakeSelection        = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
-  gDecNumericInput      = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);
-  gHexNumericInput      = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle);
-  gToggleCheckBox       = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);
-  gPromptForData        = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
-  gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
-  gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
-  gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
-  gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
-  gPassowordInvalid     = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
-  gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
-  gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
-  gAreYouSure           = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);
-  gYesResponse          = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
-  gNoResponse           = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
-  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
-  gPlusString           = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);
-  gMinusString          = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);
-  gAdjustNumber         = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);
-  return ;
-}
-
-VOID
-FreeBrowserStrings (
-  VOID
-  )
-{
-  SafeFreePool (gFunctionOneString);
-  SafeFreePool (gFunctionTwoString);
-  SafeFreePool (gFunctionNineString);
-  SafeFreePool (gFunctionTenString);
-  SafeFreePool (gEnterString);
-  SafeFreePool (gEnterCommitString);
-  SafeFreePool (gEscapeString);
-  SafeFreePool (gMoveHighlight);
-  SafeFreePool (gMakeSelection);
-  SafeFreePool (gDecNumericInput);
-  SafeFreePool (gHexNumericInput);
-  SafeFreePool (gToggleCheckBox);
-  SafeFreePool (gPromptForData);
-  SafeFreePool (gPromptForPassword);
-  SafeFreePool (gPromptForNewPassword);
-  SafeFreePool (gConfirmPassword);
-  SafeFreePool (gPassowordInvalid);
-  SafeFreePool (gConfirmError);
-  SafeFreePool (gPressEnter);
-  SafeFreePool (gEmptyString);
-  SafeFreePool (gAreYouSure);
-  SafeFreePool (gYesResponse);
-  SafeFreePool (gNoResponse);
-  SafeFreePool (gMiniString);
-  SafeFreePool (gPlusString);
-  SafeFreePool (gMinusString);
-  SafeFreePool (gAdjustNumber);
-  return ;
-}
-
-
-/**
-  Update key's help imformation
-
-  @param  MenuOption     The Menu option
-  @param  Selected       Whether or not a tag be selected
-
-  @return None
-
-**/
-VOID
-UpdateKeyHelp (
-  IN  UI_MENU_OPTION              *MenuOption,
-  IN  BOOLEAN                     Selected
-  )
-{
-  UINTN                  SecCol;
-  UINTN                  ThdCol;
-  UINTN                  LeftColumnOfHelp;
-  UINTN                  RightColumnOfHelp;
-  UINTN                  TopRowOfHelp;
-  UINTN                  BottomRowOfHelp;
-  UINTN                  StartColumnOfHelp;
-  EFI_SCREEN_DESCRIPTOR  LocalScreen;
-  FORM_BROWSER_STATEMENT *Statement;
-
-  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
-
-  SecCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
-  ThdCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;
-
-  StartColumnOfHelp = LocalScreen.LeftColumn + 2;
-  LeftColumnOfHelp  = LocalScreen.LeftColumn + 1;
-  RightColumnOfHelp = LocalScreen.RightColumn - 2;
-  TopRowOfHelp      = LocalScreen.BottomRow - 4;
-  BottomRowOfHelp   = LocalScreen.BottomRow - 3;
-
-  if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) {
-    return ;
-  }
-
-  gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
-
-  Statement = MenuOption->ThisTag;
-  switch (Statement->Operand) {
-  case EFI_IFR_ORDERED_LIST_OP:
-  case EFI_IFR_ONE_OF_OP:
-  case EFI_IFR_NUMERIC_OP:
-  case EFI_IFR_TIME_OP:
-  case EFI_IFR_DATE_OP:
-    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
-
-    if (!Selected) {
-      if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
-        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
-        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
-        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
-        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
-      }
-
-      if ((Statement->Operand == EFI_IFR_DATE_OP) ||
-          (Statement->Operand == EFI_IFR_TIME_OP) ||
-          (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0)) {
-        PrintAt (
-          StartColumnOfHelp,
-          BottomRowOfHelp,
-          L"%c%c%c%c%s",
-          ARROW_UP,
-          ARROW_DOWN,
-          ARROW_RIGHT,
-          ARROW_LEFT,
-          gMoveHighlight
-          );
-        PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);
-      } else {
-        PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
-        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
-      }
-    } else {
-      PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
-
-      //
-      // If it is a selected numeric with manual input, display different message
-      //
-      if ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step == 0)) {
-        PrintStringAt (
-          SecCol,
-          TopRowOfHelp,
-          (Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput
-          );
-      } else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) {
-        PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
-      }
-
-      if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {
-        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
-        PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
-      }
-
-      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
-    }
-    break;
-
-  case EFI_IFR_CHECKBOX_OP:
-    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
-
-    if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
-      PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
-      PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
-      PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
-      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
-    }
-
-    PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
-    PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
-    break;
-
-  case EFI_IFR_REF_OP:
-  case EFI_IFR_PASSWORD_OP:
-  case EFI_IFR_STRING_OP:
-  case EFI_IFR_TEXT_OP:
-  case EFI_IFR_ACTION_OP:
-  case EFI_IFR_RESET_BUTTON_OP:
-    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
-
-    if (!Selected) {
-      if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
-        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
-        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
-        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
-        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
-      }
-
-      PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
-      if (Statement->Operand != EFI_IFR_TEXT_OP) {
-        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
-      }
-    } else {
-      if (Statement->Operand != EFI_IFR_REF_OP) {
-        PrintStringAt (
-          (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,
-          BottomRowOfHelp,
-          gEnterCommitString
-          );
-        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
-      }
-    }
-    break;
-
-  default:
-    break;
-  }
-}
-
-EFI_STATUS
-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;
-}
-
-EFI_STATUS
-SetupBrowser (
-  IN OUT UI_MENU_SELECTION    *Selection
-  )
-{
-  EFI_STATUS                      Status;
-  LIST_ENTRY                      *Link;
-  EFI_BROWSER_ACTION_REQUEST      ActionRequest;
-  EFI_HANDLE                      NotifyHandle;
-  EFI_HII_VALUE                   *HiiValue;
-  FORM_BROWSER_STATEMENT          *Statement;
-  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
-
-  gMenuRefreshHead = NULL;
-  gResetRequired = FALSE;
-  gNvUpdateRequired = FALSE;
-
-  UiInitMenuList ();
-
-  //
-  // Register notify for Form package update
-  //
-  Status = mHiiDatabase->RegisterPackageNotify (
-                           mHiiDatabase,
-                           EFI_HII_PACKAGE_FORM,
-                           NULL,
-                           FormUpdateNotify,
-                           EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
-                           &NotifyHandle
-                           );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  do {
-    //
-    // Displays the Header and Footer borders
-    //
-    DisplayPageFrame ();
-
-    //
-    // 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);
-    }
-
-    //
-    // Load Questions' Value for display
-    //
-    Status = LoadFormConfig (Selection->FormSet, Selection->Form);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-
-    //
-    // Display form
-    //
-    Status = DisplayForm (Selection);
-    if (EFI_ERROR (Status)) {
-      return Status;
-    }
-
-    //
-    // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
-    //
-    Statement = Selection->Statement;
-    if (Statement != NULL) {
-      if (Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) {
-        gResetRequired = TRUE;
-      }
-
-      //
-      // Reset FormPackage update flag
-      //
-      mHiiPackageListUpdated = FALSE;
-
-      if (Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK && Statement->Operand != EFI_IFR_PASSWORD_OP) {
-        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
-
-        HiiValue = &Statement->HiiValue;
-        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
-          //
-          // Create String in HII database for Configuration Driver to retrieve
-          //
-          HiiValue->Value.string = NewString ((CHAR16 *) Statement->BufferValue, Selection->FormSet->HiiHandle);
-        }
-
-        ConfigAccess = Selection->FormSet->ConfigAccess;
-        if (ConfigAccess == NULL) {
-          return EFI_UNSUPPORTED;
-        }
-        Status = ConfigAccess->Callback (
-                                 ConfigAccess,
-                                 EFI_BROWSER_ACTION_CHANGING,
-                                 Statement->QuestionId,
-                                 HiiValue->Type,
-                                 &HiiValue->Value,
-                                 &ActionRequest
-                                 );
-
-        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
-          //
-          // Clean the String in HII Database
-          //
-          DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);
-        }
-
-        if (!EFI_ERROR (Status)) {
-          switch (ActionRequest) {
-          case EFI_BROWSER_ACTION_REQUEST_RESET:
-            gResetRequired = TRUE;
-            break;
-
-          case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
-            SubmitForm (Selection->FormSet, Selection->Form);
-            break;
-
-          case EFI_BROWSER_ACTION_REQUEST_EXIT:
-            Selection->Action = UI_ACTION_EXIT;
-            gNvUpdateRequired = FALSE;
-            break;
-
-          default:
-            break;
-          }
-        }
-      }
-
-      //
-      // Check whether Form Package has been updated during Callback
-      //
-      if (mHiiPackageListUpdated && (Selection->Action == UI_ACTION_REFRESH_FORM)) {
-        //
-        // Force to reparse IFR binary of target Formset
-        //
-        Selection->Action = UI_ACTION_REFRESH_FORMSET;
-      }
-    }
-  } while (Selection->Action == UI_ACTION_REFRESH_FORM);
-
-  //
-  // Unregister notify for Form package update
-  //
-  Status = mHiiDatabase->UnregisterPackageNotify (
-                           mHiiDatabase,
-                           NotifyHandle
-                           );
-  return Status;
-}
+/** @file\r
+Utility functions for UI presentation.\r
+\r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Setup.h"\r
+\r
+BOOLEAN            mHiiPackageListUpdated;\r
+UI_MENU_SELECTION  *gCurrentSelection;\r
+EFI_HII_HANDLE     mCurrentHiiHandle = NULL;\r
+EFI_GUID           mCurrentFormSetGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+UINT16             mCurrentFormId = 0;\r
+\r
+/**\r
+  Clear retangle with specified text attribute.\r
+\r
+  @param  LeftColumn     Left column of retangle.\r
+  @param  RightColumn    Right column of retangle.\r
+  @param  TopRow         Start row of retangle.\r
+  @param  BottomRow      End row of retangle.\r
+  @param  TextAttribute  The character foreground and background.\r
+\r
+**/\r
+VOID\r
+ClearLines (\r
+  IN UINTN               LeftColumn,\r
+  IN UINTN               RightColumn,\r
+  IN UINTN               TopRow,\r
+  IN UINTN               BottomRow,\r
+  IN UINTN               TextAttribute\r
+  )\r
+{\r
+  CHAR16  *Buffer;\r
+  UINTN   Row;\r
+\r
+  //\r
+  // For now, allocate an arbitrarily long buffer\r
+  //\r
+  Buffer = AllocateZeroPool (0x10000);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Set foreground and background as defined\r
+  //\r
+  gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);\r
+\r
+  //\r
+  // Much faster to buffer the long string instead of print it a character at a time\r
+  //\r
+  SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');\r
+\r
+  //\r
+  // Clear the desired area with the appropriate foreground/background\r
+  //\r
+  for (Row = TopRow; Row <= BottomRow; Row++) {\r
+    PrintStringAt (LeftColumn, Row, Buffer);\r
+  }\r
+\r
+  gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);\r
+\r
+  FreePool (Buffer);\r
+  return ;\r
+}\r
+\r
+/**\r
+  Concatenate a narrow string to another string.\r
+\r
+  @param Destination The destination string.\r
+  @param Source      The source string. The string to be concatenated.\r
+                     to the end of Destination.\r
+\r
+**/\r
+VOID\r
+NewStrCat (\r
+  IN OUT CHAR16               *Destination,\r
+  IN     CHAR16               *Source\r
+  )\r
+{\r
+  UINTN Length;\r
+\r
+  for (Length = 0; Destination[Length] != 0; Length++)\r
+    ;\r
+\r
+  //\r
+  // We now have the length of the original string\r
+  // We can safely assume for now that we are concatenating a narrow value to this string.\r
+  // For instance, the string is "XYZ" and cat'ing ">"\r
+  // If this assumption changes, we need to make this routine a bit more complex\r
+  //\r
+  Destination[Length] = NARROW_CHAR;\r
+  Length++;\r
+\r
+  StrCpy (Destination + Length, Source);\r
+}\r
+\r
+/**\r
+  Count the storage space of a Unicode string.\r
+\r
+  This function handles the Unicode string with NARROW_CHAR\r
+  and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR\r
+  does not count in the resultant output. If a WIDE_CHAR is\r
+  hit, then 2 Unicode character will consume an output storage\r
+  space with size of CHAR16 till a NARROW_CHAR is hit.\r
+\r
+  If String is NULL, then ASSERT ().\r
+\r
+  @param String          The input string to be counted.\r
+\r
+  @return Storage space for the input string.\r
+\r
+**/\r
+UINTN\r
+GetStringWidth (\r
+  IN CHAR16               *String\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINTN Count;\r
+  UINTN IncrementValue;\r
+\r
+  ASSERT (String != NULL);\r
+  if (String == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  Index           = 0;\r
+  Count           = 0;\r
+  IncrementValue  = 1;\r
+\r
+  do {\r
+    //\r
+    // Advance to the null-terminator or to the first width directive\r
+    //\r
+    for (;\r
+         (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);\r
+         Index++, Count = Count + IncrementValue\r
+        )\r
+      ;\r
+\r
+    //\r
+    // We hit the null-terminator, we now have a count\r
+    //\r
+    if (String[Index] == 0) {\r
+      break;\r
+    }\r
+    //\r
+    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed\r
+    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)\r
+    //\r
+    if (String[Index] == NARROW_CHAR) {\r
+      //\r
+      // Skip to the next character\r
+      //\r
+      Index++;\r
+      IncrementValue = 1;\r
+    } else {\r
+      //\r
+      // Skip to the next character\r
+      //\r
+      Index++;\r
+      IncrementValue = 2;\r
+    }\r
+  } while (String[Index] != 0);\r
+\r
+  //\r
+  // Increment by one to include the null-terminator in the size\r
+  //\r
+  Count++;\r
+\r
+  return Count * sizeof (CHAR16);\r
+}\r
+\r
+/**\r
+  This function displays the page frame.\r
+\r
+**/\r
+VOID\r
+DisplayPageFrame (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                  Index;\r
+  UINT8                  Line;\r
+  UINT8                  Alignment;\r
+  CHAR16                 Character;\r
+  CHAR16                 *Buffer;\r
+  CHAR16                 *StrFrontPageBanner;\r
+  UINTN                  Row;\r
+  EFI_SCREEN_DESCRIPTOR  LocalScreen;\r
+  UINT8                  RowIdx;\r
+  UINT8                  ColumnIdx;\r
+\r
+  ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);\r
+  ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);\r
+\r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
+  //\r
+  // For now, allocate an arbitrarily long buffer\r
+  //\r
+  Buffer = AllocateZeroPool (0x10000);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  Character = BOXDRAW_HORIZONTAL;\r
+\r
+  for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {\r
+    Buffer[Index] = Character;\r
+  }\r
+\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
+    //\r
+    //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);\r
+    //\r
+    ClearLines (\r
+      LocalScreen.LeftColumn,\r
+      LocalScreen.RightColumn,\r
+      LocalScreen.TopRow,\r
+      FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,\r
+      BANNER_TEXT | BANNER_BACKGROUND\r
+      );\r
+    //\r
+    //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {\r
+    //\r
+    for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {\r
+      //\r
+      //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {\r
+      //\r
+      for (Alignment = (UINT8) LocalScreen.LeftColumn;\r
+           Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;\r
+           Alignment++\r
+          ) {\r
+        RowIdx = (UINT8) (Line - (UINT8) LocalScreen.TopRow);\r
+        ColumnIdx = (UINT8) (Alignment - (UINT8) LocalScreen.LeftColumn);\r
+\r
+        ASSERT (RowIdx < BANNER_HEIGHT);\r
+        ASSERT (ColumnIdx < BANNER_COLUMNS);\r
+\r
+        if (gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {\r
+          StrFrontPageBanner = GetToken (\r
+                                gBannerData->Banner[RowIdx][ColumnIdx],\r
+                                gFrontPageHandle\r
+                                );\r
+        } else {\r
+          continue;\r
+        }\r
+\r
+        switch (Alignment - LocalScreen.LeftColumn) {\r
+        case 0:\r
+          //\r
+          // Handle left column\r
+          //\r
+          PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);\r
+          break;\r
+\r
+        case 1:\r
+          //\r
+          // Handle center column\r
+          //\r
+          PrintStringAt (\r
+            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,\r
+            Line,\r
+            StrFrontPageBanner\r
+            );\r
+          break;\r
+\r
+        case 2:\r
+          //\r
+          // Handle right column\r
+          //\r
+          PrintStringAt (\r
+            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,\r
+            Line,\r
+            StrFrontPageBanner\r
+            );\r
+          break;\r
+        }\r
+\r
+        FreePool (StrFrontPageBanner);\r
+      }\r
+    }\r
+  }\r
+\r
+  ClearLines (\r
+    LocalScreen.LeftColumn,\r
+    LocalScreen.RightColumn,\r
+    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,\r
+    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,\r
+    KEYHELP_TEXT | KEYHELP_BACKGROUND\r
+    );\r
+\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
+    ClearLines (\r
+      LocalScreen.LeftColumn,\r
+      LocalScreen.RightColumn,\r
+      LocalScreen.TopRow,\r
+      LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,\r
+      TITLE_TEXT | TITLE_BACKGROUND\r
+      );\r
+    //\r
+    // Print Top border line\r
+    // +------------------------------------------------------------------------------+\r
+    // ?                                                                             ?\r
+    // +------------------------------------------------------------------------------+\r
+    //\r
+    Character = BOXDRAW_DOWN_RIGHT;\r
+\r
+    PrintChar (Character);\r
+    PrintString (Buffer);\r
+\r
+    Character = BOXDRAW_DOWN_LEFT;\r
+    PrintChar (Character);\r
+\r
+    Character = BOXDRAW_VERTICAL;\r
+    for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {\r
+      PrintCharAt (LocalScreen.LeftColumn, Row, Character);\r
+      PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);\r
+    }\r
+\r
+    Character = BOXDRAW_UP_RIGHT;\r
+    PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);\r
+    PrintString (Buffer);\r
+\r
+    Character = BOXDRAW_UP_LEFT;\r
+    PrintChar (Character);\r
+\r
+    if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
+      //\r
+      // Print Bottom border line\r
+      // +------------------------------------------------------------------------------+\r
+      // ?                                                                             ?\r
+      // +------------------------------------------------------------------------------+\r
+      //\r
+      Character = BOXDRAW_DOWN_RIGHT;\r
+      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);\r
+\r
+      PrintString (Buffer);\r
+\r
+      Character = BOXDRAW_DOWN_LEFT;\r
+      PrintChar (Character);\r
+      Character = BOXDRAW_VERTICAL;\r
+      for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;\r
+           Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;\r
+           Row++\r
+          ) {\r
+        PrintCharAt (LocalScreen.LeftColumn, Row, Character);\r
+        PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);\r
+      }\r
+\r
+      Character = BOXDRAW_UP_RIGHT;\r
+      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);\r
+\r
+      PrintString (Buffer);\r
+\r
+      Character = BOXDRAW_UP_LEFT;\r
+      PrintChar (Character);\r
+    }\r
+  }\r
+\r
+  FreePool (Buffer);\r
+\r
+}\r
+\r
+\r
+/**\r
+  Evaluate all expressions in a Form.\r
+\r
+  @param  FormSet        FormSet this Form belongs to.\r
+  @param  Form           The Form.\r
+\r
+  @retval EFI_SUCCESS    The expression evaluated successfuly\r
+\r
+**/\r
+EFI_STATUS\r
+EvaluateFormExpressions (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form\r
+  )\r
+{\r
+  EFI_STATUS       Status;\r
+  LIST_ENTRY       *Link;\r
+  FORM_EXPRESSION  *Expression;\r
+\r
+  Link = GetFirstNode (&Form->ExpressionListHead);\r
+  while (!IsNull (&Form->ExpressionListHead, Link)) {\r
+    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+    Link = GetNextNode (&Form->ExpressionListHead, Link);\r
+\r
+    if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||\r
+        Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||\r
+        Expression->Type == EFI_HII_EXPRESSION_WRITE ||\r
+        (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {\r
+      //\r
+      // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.\r
+      //\r
+      continue;\r
+    }\r
+\r
+    Status = EvaluateExpression (FormSet, Form, Expression);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/*\r
++------------------------------------------------------------------------------+\r
+?                                 Setup Page                                  ?\r
++------------------------------------------------------------------------------+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
++------------------------------------------------------------------------------+\r
+?F1=Scroll Help                 F9=Reset to Defaults        F10=Save and Exit ?\r
+| ^"=Move Highlight          <Spacebar> Toggles Checkbox   Esc=Discard Changes |\r
++------------------------------------------------------------------------------+\r
+*/\r
+\r
+/**\r
+\r
+\r
+  Display form and wait for user to select one menu option, then return it.\r
+\r
+  @param Selection       On input, Selection tell setup browser the information\r
+                         about the Selection, form and formset to be displayed.\r
+                         On output, Selection return the screen item that is selected\r
+                         by user.\r
+  @retval EFI_SUCESSS            This function always return successfully for now.\r
+\r
+**/\r
+EFI_STATUS\r
+DisplayForm (\r
+  IN OUT UI_MENU_SELECTION           *Selection\r
+  )\r
+{\r
+  CHAR16                 *StringPtr;\r
+  UINT16                 MenuItemCount;\r
+  EFI_HII_HANDLE         Handle;\r
+  BOOLEAN                Suppress;\r
+  EFI_SCREEN_DESCRIPTOR  LocalScreen;\r
+  UINT16                 Width;\r
+  UINTN                  ArrayEntry;\r
+  CHAR16                 *OutputString;\r
+  LIST_ENTRY             *Link;\r
+  FORM_BROWSER_STATEMENT *Statement;\r
+  UINT16                 NumberOfLines;\r
+  EFI_STATUS             Status;\r
+  UI_MENU_OPTION         *MenuOption;\r
+\r
+  Handle        = Selection->Handle;\r
+  MenuItemCount = 0;\r
+  ArrayEntry    = 0;\r
+  OutputString  = NULL;\r
+\r
+  UiInitMenu ();\r
+\r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
+  StringPtr = GetToken (Selection->Form->FormTitle, Handle);\r
+\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
+    gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
+    PrintStringAt (\r
+      (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,\r
+      LocalScreen.TopRow + 1,\r
+      StringPtr\r
+      );\r
+  }\r
+\r
+  //\r
+  // Remove Buffer allocated for StringPtr after it has been used.\r
+  //\r
+  FreePool (StringPtr);\r
+\r
+  //\r
+  // Evaluate all the Expressions in this Form\r
+  //\r
+  Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Selection->FormEditable = FALSE;\r
+  Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+  while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+\r
+    if (Statement->SuppressExpression != NULL) {\r
+      Suppress = Statement->SuppressExpression->Result.Value.b;\r
+    } else {\r
+      Suppress = FALSE;\r
+    }\r
+\r
+    if (Statement->DisableExpression != NULL) {\r
+      Suppress = (BOOLEAN) (Suppress || Statement->DisableExpression->Result.Value.b);\r
+    }\r
+\r
+    if (!Suppress) {\r
+      StringPtr = GetToken (Statement->Prompt, Handle);\r
+\r
+      Width     = GetWidth (Statement, Handle);\r
+\r
+      NumberOfLines = 1;\r
+      ArrayEntry = 0;\r
+      for (; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {\r
+        //\r
+        // If there is more string to process print on the next row and increment the Skip value\r
+        //\r
+        if (StrLen (&StringPtr[ArrayEntry]) != 0) {\r
+          NumberOfLines++;\r
+        }\r
+\r
+        FreePool (OutputString);\r
+      }\r
+\r
+      //\r
+      // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do\r
+      // it in UiFreeMenu.\r
+      //\r
+      MenuOption = UiAddMenuOption (StringPtr, Selection->Handle, Statement, NumberOfLines, MenuItemCount);\r
+      MenuItemCount++;\r
+\r
+      if (MenuOption->IsQuestion && !MenuOption->ReadOnly) {\r
+        //\r
+        // At least one item is not readonly, this Form is considered as editable\r
+        //\r
+        Selection->FormEditable = TRUE;\r
+      }\r
+    }\r
+\r
+    Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+  }\r
+\r
+  Status = UiDisplayMenu (Selection);\r
+\r
+  UiFreeMenu ();\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Initialize the HII String Token to the correct values.\r
+\r
+**/\r
+VOID\r
+InitializeBrowserStrings (\r
+  VOID\r
+  )\r
+{\r
+  gFunctionNineString   = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);\r
+  gFunctionTenString    = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);\r
+  gEnterString          = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);\r
+  gEnterCommitString    = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);\r
+  gEnterEscapeString    = GetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), gHiiHandle);\r
+  gEscapeString         = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);\r
+  gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);\r
+  gMoveHighlight        = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);\r
+  gMakeSelection        = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);\r
+  gDecNumericInput      = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);\r
+  gHexNumericInput      = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle);\r
+  gToggleCheckBox       = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);\r
+  gPromptForData        = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);\r
+  gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);\r
+  gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);\r
+  gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);\r
+  gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);\r
+  gPassowordInvalid     = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);\r
+  gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);\r
+  gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
+  gAreYouSure           = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);\r
+  gYesResponse          = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);\r
+  gNoResponse           = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);\r
+  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);\r
+  gPlusString           = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);\r
+  gMinusString          = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);\r
+  gAdjustNumber         = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);\r
+  gSaveChanges          = GetToken (STRING_TOKEN (SAVE_CHANGES), gHiiHandle);\r
+  gOptionMismatch       = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);\r
+  gFormSuppress         = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);\r
+  return ;\r
+}\r
+\r
+/**\r
+  Free up the resource allocated for all strings required\r
+  by Setup Browser.\r
+\r
+**/\r
+VOID\r
+FreeBrowserStrings (\r
+  VOID\r
+  )\r
+{\r
+  FreePool (gFunctionNineString);\r
+  FreePool (gFunctionTenString);\r
+  FreePool (gEnterString);\r
+  FreePool (gEnterCommitString);\r
+  FreePool (gEnterEscapeString);\r
+  FreePool (gEscapeString);\r
+  FreePool (gMoveHighlight);\r
+  FreePool (gMakeSelection);\r
+  FreePool (gDecNumericInput);\r
+  FreePool (gHexNumericInput);\r
+  FreePool (gToggleCheckBox);\r
+  FreePool (gPromptForData);\r
+  FreePool (gPromptForPassword);\r
+  FreePool (gPromptForNewPassword);\r
+  FreePool (gConfirmPassword);\r
+  FreePool (gPassowordInvalid);\r
+  FreePool (gConfirmError);\r
+  FreePool (gPressEnter);\r
+  FreePool (gEmptyString);\r
+  FreePool (gAreYouSure);\r
+  FreePool (gYesResponse);\r
+  FreePool (gNoResponse);\r
+  FreePool (gMiniString);\r
+  FreePool (gPlusString);\r
+  FreePool (gMinusString);\r
+  FreePool (gAdjustNumber);\r
+  FreePool (gSaveChanges);\r
+  FreePool (gOptionMismatch);\r
+  FreePool (gFormSuppress);\r
+  return ;\r
+}\r
+\r
+\r
+/**\r
+  Update key's help imformation.\r
+\r
+  @param Selection       Tell setup browser the information about the Selection\r
+  @param  MenuOption     The Menu option\r
+  @param  Selected       Whether or not a tag be selected\r
+\r
+**/\r
+VOID\r
+UpdateKeyHelp (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption,\r
+  IN  BOOLEAN                     Selected\r
+  )\r
+{\r
+  UINTN                  SecCol;\r
+  UINTN                  ThdCol;\r
+  UINTN                  LeftColumnOfHelp;\r
+  UINTN                  RightColumnOfHelp;\r
+  UINTN                  TopRowOfHelp;\r
+  UINTN                  BottomRowOfHelp;\r
+  UINTN                  StartColumnOfHelp;\r
+  EFI_SCREEN_DESCRIPTOR  LocalScreen;\r
+  FORM_BROWSER_STATEMENT *Statement;\r
+\r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
+  SecCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
+  ThdCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;\r
+\r
+  StartColumnOfHelp = LocalScreen.LeftColumn + 2;\r
+  LeftColumnOfHelp  = LocalScreen.LeftColumn + 1;\r
+  RightColumnOfHelp = LocalScreen.RightColumn - 2;\r
+  TopRowOfHelp      = LocalScreen.BottomRow - 4;\r
+  BottomRowOfHelp   = LocalScreen.BottomRow - 3;\r
+\r
+  gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+  Statement = MenuOption->ThisTag;\r
+  switch (Statement->Operand) {\r
+  case EFI_IFR_ORDERED_LIST_OP:\r
+  case EFI_IFR_ONE_OF_OP:\r
+  case EFI_IFR_NUMERIC_OP:\r
+  case EFI_IFR_TIME_OP:\r
+  case EFI_IFR_DATE_OP:\r
+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+    if (!Selected) {\r
+      if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
+        if (Selection->FormEditable) {\r
+          PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
+          PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
+        }\r
+        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
+      }\r
+\r
+      if ((Statement->Operand == EFI_IFR_DATE_OP) ||\r
+          (Statement->Operand == EFI_IFR_TIME_OP)) {\r
+        PrintAt (\r
+          StartColumnOfHelp,\r
+          BottomRowOfHelp,\r
+          L"%c%c%c%c%s",\r
+          ARROW_UP,\r
+          ARROW_DOWN,\r
+          ARROW_RIGHT,\r
+          ARROW_LEFT,\r
+          gMoveHighlight\r
+          );\r
+        PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);\r
+      } else {\r
+        PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
+        if (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0) {\r
+          PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);\r
+        } else {\r
+          PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
+        }\r
+      }\r
+    } else {\r
+      PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);\r
+\r
+      //\r
+      // If it is a selected numeric with manual input, display different message\r
+      //\r
+      if ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step == 0)) {\r
+        PrintStringAt (\r
+          SecCol,\r
+          TopRowOfHelp,\r
+          ((Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput\r
+          );\r
+      } else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) {\r
+        PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
+      }\r
+\r
+      if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {\r
+        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);\r
+        PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);\r
+      }\r
+\r
+      PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_CHECKBOX_OP:\r
+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+    if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
+      if (Selection->FormEditable) {\r
+        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
+        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
+      }\r
+      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
+    }\r
+\r
+    PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
+    PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);\r
+    break;\r
+\r
+  case EFI_IFR_REF_OP:\r
+  case EFI_IFR_PASSWORD_OP:\r
+  case EFI_IFR_STRING_OP:\r
+  case EFI_IFR_TEXT_OP:\r
+  case EFI_IFR_ACTION_OP:\r
+  case EFI_IFR_RESET_BUTTON_OP:\r
+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+    if (!Selected) {\r
+      if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
+        if (Selection->FormEditable) {\r
+          PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
+          PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
+        }\r
+        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
+      }\r
+\r
+      PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
+      if (Statement->Operand != EFI_IFR_TEXT_OP) {\r
+        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
+      }\r
+    } else {\r
+      if (Statement->Operand != EFI_IFR_REF_OP) {\r
+        PrintStringAt (\r
+          (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,\r
+          BottomRowOfHelp,\r
+          gEnterCommitString\r
+          );\r
+        PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);\r
+      }\r
+    }\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+/**\r
+  Functions which are registered to receive notification of\r
+  database events have this prototype. The actual event is encoded\r
+  in NotifyType. The following table describes how PackageType,\r
+  PackageGuid, Handle, and Package are used for each of the\r
+  notification types.\r
+\r
+  @param PackageType  Package type of the notification.\r
+\r
+  @param PackageGuid  If PackageType is\r
+                      EFI_HII_PACKAGE_TYPE_GUID, then this is\r
+                      the pointer to the GUID from the Guid\r
+                      field of EFI_HII_PACKAGE_GUID_HEADER.\r
+                      Otherwise, it must be NULL.\r
+\r
+  @param Package  Points to the package referred to by the\r
+                  notification Handle The handle of the package\r
+                  list which contains the specified package.\r
+\r
+  @param Handle       The HII handle.\r
+\r
+  @param NotifyType   The type of change concerning the\r
+                      database. See\r
+                      EFI_HII_DATABASE_NOTIFY_TYPE.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FormUpdateNotify (\r
+  IN UINT8                              PackageType,\r
+  IN CONST EFI_GUID                     *PackageGuid,\r
+  IN CONST EFI_HII_PACKAGE_HEADER       *Package,\r
+  IN EFI_HII_HANDLE                     Handle,\r
+  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType\r
+  )\r
+{\r
+  mHiiPackageListUpdated = TRUE;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The worker function that send the displays to the screen. On output,\r
+  the selection made by user is returned.\r
+\r
+  @param Selection       On input, Selection tell setup browser the information\r
+                         about the Selection, form and formset to be displayed.\r
+                         On output, Selection return the screen item that is selected\r
+                         by user.\r
+\r
+  @retval EFI_SUCCESS    The page is displayed successfully.\r
+  @return Other value if the page failed to be diplayed.\r
+\r
+**/\r
+EFI_STATUS\r
+SetupBrowser (\r
+  IN OUT UI_MENU_SELECTION    *Selection\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  LIST_ENTRY                      *Link;\r
+  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
+  EFI_HANDLE                      NotifyHandle;\r
+  EFI_HII_VALUE                   *HiiValue;\r
+  EFI_IFR_TYPE_VALUE              *TypeValue;\r
+  FORM_BROWSER_STATEMENT          *Statement;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  FORM_BROWSER_FORMSET            *FormSet;\r
+  EFI_INPUT_KEY                   Key;\r
+  BOOLEAN                         SubmitFormIsRequired;\r
+\r
+  gMenuRefreshHead = NULL;\r
+  gResetRequired = FALSE;\r
+  FormSet = Selection->FormSet;\r
+  ConfigAccess = Selection->FormSet->ConfigAccess;\r
+\r
+  //\r
+  // Register notify for Form package update\r
+  //\r
+  Status = mHiiDatabase->RegisterPackageNotify (\r
+                           mHiiDatabase,\r
+                           EFI_HII_PACKAGE_FORMS,\r
+                           NULL,\r
+                           FormUpdateNotify,\r
+                           EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
+                           &NotifyHandle\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Initialize current settings of Questions in this FormSet\r
+  //\r
+  Status = InitializeCurrentSetting (Selection->FormSet);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  do {\r
+    //\r
+    // Initialize Selection->Form\r
+    //\r
+    if (Selection->FormId == 0) {\r
+      //\r
+      // Zero FormId indicates display the first Form in a FormSet\r
+      //\r
+      Link = GetFirstNode (&Selection->FormSet->FormListHead);\r
+\r
+      Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+      Selection->FormId = Selection->Form->FormId;\r
+    } else {\r
+      Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);\r
+    }\r
+\r
+    if (Selection->Form == NULL) {\r
+      //\r
+      // No Form to display\r
+      //\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Check Form is suppressed.\r
+    //\r
+    if (Selection->Form->SuppressExpression != NULL) {\r
+      Status = EvaluateExpression (Selection->FormSet, Selection->Form, Selection->Form->SuppressExpression);\r
+      if (EFI_ERROR (Status) || (Selection->Form->SuppressExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN)) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+\r
+      if (Selection->Form->SuppressExpression->Result.Value.b) {\r
+        //\r
+        // Form is suppressed. \r
+        //\r
+        do {\r
+          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);\r
+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+        Status = EFI_NOT_FOUND;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Reset FormPackage update flag\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+\r
+    //\r
+    // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
+    // for each question with callback flag.\r
+    // New form may be the first form, or the different form after another form close.\r
+    //\r
+    if ((ConfigAccess != NULL) &&\r
+        ((Selection->Handle != mCurrentHiiHandle) ||\r
+        (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+        (Selection->FormId != mCurrentFormId))) {\r
+\r
+      //\r
+      // Keep current form information\r
+      //\r
+      mCurrentHiiHandle   = Selection->Handle;\r
+      CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
+      mCurrentFormId      = Selection->FormId;\r
+\r
+      //\r
+      // Go through each statement in this form\r
+      //\r
+      SubmitFormIsRequired = FALSE;\r
+      Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+      while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+        Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+        Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+        \r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Check whether Statement is disabled.\r
+        //\r
+        if (Statement->DisableExpression != NULL) {\r
+          Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression);\r
+          if (!EFI_ERROR (Status) && \r
+              (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && \r
+              (Statement->DisableExpression->Result.Value.b)) {\r
+            continue;\r
+          }\r
+        }\r
+\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_FORM_OPEN,\r
+                                 Statement->QuestionId,\r
+                                 EFI_IFR_TYPE_UNDEFINED,\r
+                                 NULL,\r
+                                 &ActionRequest\r
+                                 );\r
+\r
+        if (!EFI_ERROR (Status)) {\r
+          switch (ActionRequest) {\r
+          case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+            gResetRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+            SubmitFormIsRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (SubmitFormIsRequired) {\r
+        SubmitForm (Selection->FormSet, Selection->Form);\r
+      }\r
+      //\r
+      // EXIT requests to close form.\r
+      //\r
+      if (Selection->Action == UI_ACTION_EXIT) {\r
+        goto Done;\r
+      }\r
+      //\r
+      // IFR is updated during callback of open form, force to reparse the IFR binary\r
+      //\r
+      if (mHiiPackageListUpdated) {\r
+        Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+        mHiiPackageListUpdated = FALSE;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Load Questions' Value for display\r
+    //\r
+    Status = LoadFormSetConfig (Selection, Selection->FormSet);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // EXIT requests to close form.\r
+    //\r
+    if (Selection->Action == UI_ACTION_EXIT) {\r
+      goto Done;\r
+    }\r
+    //\r
+    // IFR is updated during callback of read value, force to reparse the IFR binary\r
+    //\r
+    if (mHiiPackageListUpdated) {\r
+      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+      mHiiPackageListUpdated = FALSE;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Displays the Header and Footer borders\r
+    //\r
+    DisplayPageFrame ();\r
+\r
+    //\r
+    // Display form\r
+    //\r
+    Status = DisplayForm (Selection);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Check Selected Statement (if press ESC, Selection->Statement will be NULL)\r
+    //\r
+    Statement = Selection->Statement;\r
+    if (Statement != NULL) {\r
+      if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED) {\r
+        gResetRequired = TRUE;\r
+      }\r
+\r
+      //\r
+      // Reset FormPackage update flag\r
+      //\r
+      mHiiPackageListUpdated = FALSE;\r
+\r
+      if ((ConfigAccess != NULL) && \r
+          ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
+          (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
+\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+\r
+        HiiValue = &Statement->HiiValue;\r
+        TypeValue = &HiiValue->Value;\r
+        if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+          //\r
+          // For OrderedList, passing in the value buffer to Callback()\r
+          //\r
+          TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
+        }\r
+\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_CHANGING,\r
+                                 Statement->QuestionId,\r
+                                 HiiValue->Type,\r
+                                 TypeValue,\r
+                                 &ActionRequest\r
+                                 );\r
+\r
+        if (!EFI_ERROR (Status)) {\r
+          switch (ActionRequest) {\r
+          case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+            gResetRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+            SubmitForm (Selection->FormSet, Selection->Form);\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+        } else if (Status != EFI_UNSUPPORTED) {\r
+          //\r
+          // Callback return error status other than EFI_UNSUPPORTED\r
+          //\r
+          if (Statement->Operand == EFI_IFR_REF_OP) {\r
+            //\r
+            // Cross reference will not be taken\r
+            //\r
+            Selection->FormId = Selection->Form->FormId;\r
+            Selection->QuestionId = 0;\r
+          }\r
+        }\r
+      }\r
+\r
+      //\r
+      // Check whether Form Package has been updated during Callback\r
+      //\r
+      if (mHiiPackageListUpdated && (Selection->Action == UI_ACTION_REFRESH_FORM)) {\r
+        //\r
+        // Force to reparse IFR binary of target Formset\r
+        //\r
+        mHiiPackageListUpdated = FALSE;\r
+        Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
+    // for each question with callback flag.\r
+    //\r
+    if ((ConfigAccess != NULL) && \r
+        ((Selection->Action == UI_ACTION_EXIT) || \r
+         (Selection->Handle != mCurrentHiiHandle) ||\r
+         (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+         (Selection->FormId != mCurrentFormId))) {\r
+      //\r
+      // Go through each statement in this form\r
+      //\r
+      SubmitFormIsRequired = FALSE;\r
+      Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+      while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+        Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+        Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+        \r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+          continue;\r
+        }\r
+\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_FORM_CLOSE,\r
+                                 Statement->QuestionId,\r
+                                 EFI_IFR_TYPE_UNDEFINED,\r
+                                 NULL,\r
+                                 &ActionRequest\r
+                                 );\r
+\r
+        if (!EFI_ERROR (Status)) {\r
+          switch (ActionRequest) {\r
+          case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+            gResetRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+            SubmitFormIsRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (SubmitFormIsRequired) {\r
+        SubmitForm (Selection->FormSet, Selection->Form);\r
+      }\r
+    }\r
+  } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
+\r
+  //\r
+  // Record the old formset\r
+  //\r
+  if (gOldFormSet != NULL) {\r
+    DestroyFormSet (gOldFormSet);\r
+  }\r
+  gOldFormSet = FormSet;\r
+\r
+Done:\r
+  //\r
+  // Reset current form information to the initial setting when error happens or form exit.\r
+  //\r
+  if (EFI_ERROR (Status) || Selection->Action == UI_ACTION_EXIT) {\r
+    mCurrentHiiHandle = NULL;\r
+    CopyGuid (&mCurrentFormSetGuid, &gZeroGuid);\r
+    mCurrentFormId = 0;\r
+  }\r
+\r
+  //\r
+  // Unregister notify for Form package update\r
+  //\r
+  mHiiDatabase->UnregisterPackageNotify (\r
+                   mHiiDatabase,\r
+                   NotifyHandle\r
+                   );\r
+  return Status;\r
+}\r