]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Rollback patch 14537 & 14538, because patch 14537 is not tested by Laszlo Ersek,...
authorEric Dong <eric.dong@intel.com>
Mon, 12 Aug 2013 02:03:10 +0000 (02:03 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 12 Aug 2013 02:03:10 +0000 (02:03 +0000)
Signed-off-by: Eric Dong <eric.dong@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14539 6f19259b-4bc3-4df7-8a09-765794883524

42 files changed:
DuetPkg/DuetPkg.fdf
DuetPkg/DuetPkgIa32.dsc
DuetPkg/DuetPkgX64.dsc
MdeModulePkg/Include/Library/CustomizedDisplayLib.h [deleted file]
MdeModulePkg/Include/Protocol/DisplayProtocol.h [deleted file]
MdeModulePkg/Include/Protocol/FormBrowserEx2.h [deleted file]
MdeModulePkg/Library/CustomizedDisplayLib/Colors.h [deleted file]
MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c [deleted file]
MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf [deleted file]
MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni [deleted file]
MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c [deleted file]
MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h [deleted file]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf [deleted file]
MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c [deleted file]
MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h [deleted file]
MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni [deleted file]
MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c [deleted file]
MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c [deleted file]
MdeModulePkg/Universal/SetupBrowserDxe/Colors.h [new file with mode: 0644]
MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
MdeModulePkg/Universal/SetupBrowserDxe/Expression.h [deleted file]
MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c [new file with mode: 0644]
MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg/Universal/SetupBrowserDxe/Print.c [new file with mode: 0644]
MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c [new file with mode: 0644]
MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni [new file with mode: 0644]
MdeModulePkg/Universal/SetupBrowserDxe/Ui.c [new file with mode: 0644]
MdeModulePkg/Universal/SetupBrowserDxe/Ui.h [new file with mode: 0644]
Nt32Pkg/Nt32Pkg.dsc
Nt32Pkg/Nt32Pkg.fdf
OvmfPkg/OvmfPkgIa32.dsc
OvmfPkg/OvmfPkgIa32.fdf
OvmfPkg/OvmfPkgIa32X64.dsc
OvmfPkg/OvmfPkgIa32X64.fdf
OvmfPkg/OvmfPkgX64.dsc
OvmfPkg/OvmfPkgX64.fdf

index 66f8b68ed822cc0c388766c39c136611b71655d1..f6bcdd9fdb63b6695b7da787155182eef70e7006 100644 (file)
@@ -59,7 +59,6 @@ INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
 INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 \r
 INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
 INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
 \r
 INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
 INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
index 117bffb0ece603629b669176ea6db80f376a1cbb..b35ba913ffee38c12b4652040c03e0ea5717fb20 100644 (file)
@@ -85,7 +85,6 @@
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   #\r
   # Platform\r
   #\r
   #\r
   # Platform\r
   #\r
   }\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   }\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 \r
   MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
   MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
 \r
   MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
   MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
index 70b159dd8237db5c731a6bf5dd6f52bdf5414c34..65c0d140192d2a6ebfb0a0467c2618b635b9ac30 100644 (file)
@@ -85,7 +85,6 @@
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   #\r
   # Platform\r
   #\r
   #\r
   # Platform\r
   #\r
   }\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   }\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 \r
   MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
   MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
 \r
   MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
   MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
diff --git a/MdeModulePkg/Include/Library/CustomizedDisplayLib.h b/MdeModulePkg/Include/Library/CustomizedDisplayLib.h
deleted file mode 100644 (file)
index 31e1091..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/** @file\r
-  This library class defines a set of interfaces to customize Display module\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#ifndef __CUSTOMIZED_DISPLAY_LIB_H__\r
-#define __CUSTOMIZED_DISPLAY_LIB_H__\r
-\r
-#include <Protocol/DisplayProtocol.h>\r
-\r
-/**\r
-+------------------------------------------------------------------------------+\r
-|                                 Setup Page                                   |\r
-+------------------------------------------------------------------------------+\r
-\r
-Statement\r
-Statement\r
-Statement\r
-\r
-\r
-\r
-\r
-\r
-+------------------------------------------------------------------------------+\r
-|                                F9=Reset to Defaults        F10=Save          |\r
-| ^"=Move Highlight          <Spacebar> Toggles Checkbox     Esc=Exit          |\r
-+------------------------------------------------------------------------------+\r
-  StatusBar\r
-**/\r
-\r
-/**\r
-  This funtion defines Page Frame and Backgroud. \r
-  \r
-  Based on the above layout, it will be responsible for HeaderHeight, FooterHeight, \r
-  StatusBarHeight and Backgroud. And, it will reserve Screen for Statement. \r
-\r
-  @param[in]  FormData             Form Data to be shown in Page.\r
-  @param[out] ScreenForStatement   Screen to be used for Statement. (Prompt, Value and Help)\r
-  \r
-  @return Status\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DisplayPageFrame (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData,\r
-  OUT EFI_SCREEN_DESCRIPTOR         *ScreenForStatement\r
-  );\r
-\r
-/**\r
-  Clear Screen to the initial state.\r
-**/\r
-VOID\r
-EFIAPI \r
-ClearDisplayPage (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  This function updates customized key panel's help information.\r
-  The library will prepare those Strings for the basic key, ESC, Enter, Up/Down/Left/Right, +/-.\r
-  and arrange them in Footer panel.\r
-  \r
-  @param[in]  FormData       Form Data to be shown in Page. FormData has the highlighted statement. \r
-  @param[in]  Statement      The statement current selected.\r
-  @param[in]  Selected       Whether or not a tag be selected. TRUE means Enter has hit this question.\r
-**/\r
-VOID\r
-EFIAPI\r
-RefreshKeyHelp (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *FormData,\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
-  IN  BOOLEAN                      Selected\r
-  );\r
-\r
-/**\r
-  Update status bar.\r
-\r
-  This function updates the status bar on the bottom of menu screen. It just shows StatusBar. \r
-  Original logic in this function should be splitted out.\r
-\r
-  @param[in]  MessageType            The type of message to be shown. InputError or Configuration Changed. \r
-  @param[in]  State                  Show or Clear Message.\r
-**/\r
-VOID\r
-EFIAPI\r
-UpdateStatusBar (\r
-  IN  UINTN                  MessageType,\r
-  IN  BOOLEAN                State\r
-  );\r
-\r
-/**\r
-  Create popup window. \r
-\r
-  This function draws OEM/Vendor specific pop up windows.\r
-\r
-  @param[out]  Key    User Input Key\r
-  @param       ...    String to be shown in Popup. The variable argument list is terminated by a NULL.\r
-  \r
-**/\r
-VOID\r
-EFIAPI\r
-CreateDialog (\r
-  OUT EFI_INPUT_KEY  *Key,        OPTIONAL\r
-  ...\r
-  );\r
-\r
-/**\r
-  Confirm how to handle the changed data. \r
-  \r
-  @return Action BROWSER_ACTION_SUBMIT, BROWSER_ACTION_DISCARD or other values.\r
-**/\r
-UINTN\r
-EFIAPI\r
-ConfirmDataChange (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  OEM specifies whether Setup exits Page by ESC key.\r
-\r
-  This function customized the behavior that whether Setup exits Page so that \r
-  system able to boot when configuration is not changed.\r
-\r
-  @retval  TRUE     Exits FrontPage\r
-  @retval  FALSE    Don't exit FrontPage.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-FormExitPolicy (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Set Timeout value for a ceratain Form to get user response. \r
-  \r
-  This function allows to set timeout value on a ceratain form if necessary.\r
-  If timeout is not zero, the form will exit if user has no response in timeout. \r
-  \r
-  @param[in]  FormData   Form Data to be shown in Page\r
-\r
-  @return 0     No timeout for this form. \r
-  @return > 0   Timeout value in 100 ns units.\r
-**/\r
-UINT64\r
-EFIAPI\r
-FormExitTimeout (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *FormData\r
-  );\r
-\r
-//\r
-// Print Functions\r
-//\r
-/**\r
-  Prints a unicode string to the default console, at\r
-  the supplied cursor position, using L"%s" format.\r
-\r
-  @param  Column     The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Row        The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  String     String pointer.\r
-\r
-  @return Length of string printed to the console\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintStringAt (\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  IN CHAR16    *String\r
-  );\r
-\r
-\r
-/**\r
-  Prints a unicode string with the specified width to the default console, at\r
-  the supplied cursor position, using L"%s" format.\r
-\r
-  @param  Column     The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Row        The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  String     String pointer.\r
-  @param  Width      Width for String to be printed. If the print length of String < Width, \r
-                     Space char (L' ') will be used to append String. \r
-\r
-  @return Length of string printed to the console\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintStringAtWithWidth (\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  IN CHAR16    *String,\r
-  IN UINTN     Width\r
-  );\r
-\r
-/**\r
-  Prints a chracter to the default console, at\r
-  the supplied cursor position, using L"%c" format.\r
-\r
-  @param  Column     The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Row        The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Character  Character to print.\r
-\r
-  @return Length of string printed to the console.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintCharAt (\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  CHAR16       Character\r
-  );\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
-EFIAPI\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
-//\r
-// Color Setting Functions\r
-//\r
-/**\r
-  Get OEM/Vendor specific popup attribute colors.\r
-\r
-  @retval  Byte code color setting for popup color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetPopupColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific popup attribute colors.\r
-\r
-  @retval  Byte code color setting for popup inverse color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetPopupInverseColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific PickList color attribute.\r
-\r
-  @retval  Byte code color setting for pick list color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetPickListColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific arrow color attribute.\r
-\r
-  @retval  Byte code color setting for arrow color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetArrowColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific info text color attribute.\r
-\r
-  @retval  Byte code color setting for info text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetInfoTextColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific help text color attribute.\r
-\r
-  @retval  Byte code color setting for help text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetHelpTextColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific grayed out text color attribute.\r
-\r
-  @retval  Byte code color setting for grayed out text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetGrayedTextColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific highlighted text color attribute.\r
-\r
-  @retval  Byte code color setting for highlight text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetHighlightTextColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific field text color attribute.\r
-\r
-  @retval  Byte code color setting for field text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetFieldTextColor (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Get OEM/Vendor specific subtitle text color attribute.\r
-\r
-  @retval  Byte code color setting for subtitle text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetSubTitleTextColor (\r
-  VOID\r
-  );\r
-\r
-#endif\r
diff --git a/MdeModulePkg/Include/Protocol/DisplayProtocol.h b/MdeModulePkg/Include/Protocol/DisplayProtocol.h
deleted file mode 100644 (file)
index d4f0deb..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/** @file\r
-  FormDiplay protocol to show Form\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#ifndef __DISPLAY_PROTOCOL_H__\r
-#define __DISPLAY_PROTOCOL_H__\r
-\r
-#include <Protocol/FormBrowser2.h>\r
-\r
-#define EDKII_FORM_DISPLAY_ENGINE_PROTOCOL_GUID  \\r
-  { 0x9bbe29e9, 0xfda1, 0x41ec, { 0xad, 0x52, 0x45, 0x22, 0x13, 0x74, 0x2d, 0x2e } }\r
-\r
-// \r
-// Do nothing.\r
-//\r
-#define BROWSER_ACTION_NONE         BIT16\r
-//\r
-// ESC Exit\r
-//\r
-#define BROWSER_ACTION_FORM_EXIT    BIT17\r
-\r
-#define BROWSER_SUCCESS             0x0\r
-#define BROWSER_ERROR               BIT31\r
-#define BROWSER_SUBMIT_FAIL         BROWSER_ERROR | 0x01\r
-#define BROWSER_NO_SUBMIT_IF        BROWSER_ERROR | 0x02\r
-#define BROWSER_FORM_NOT_FOUND      BROWSER_ERROR | 0x03\r
-#define BROWSER_FORM_SUPPRESS       BROWSER_ERROR | 0x04\r
-#define BROWSER_PROTOCOL_NOT_FOUND  BROWSER_ERROR | 0x05\r
-\r
-#define FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1  0x10000\r
-#define FORM_DISPLAY_ENGINE_VERSION_1            0x10000\r
-\r
-typedef struct {\r
-  //\r
-  // HII Data Type\r
-  //\r
-  UINT8               Type;\r
-  //\r
-  // Buffer Data and Length if Type is EFI_IFR_TYPE_BUFFER or EFI_IFR_TYPE_STRING\r
-  //\r
-  UINT8               *Buffer;\r
-  UINT16              BufferLen;\r
-  EFI_IFR_TYPE_VALUE  Value;\r
-} EFI_HII_VALUE;\r
-\r
-#define DISPLAY_QUESTION_OPTION_SIGNATURE  SIGNATURE_32 ('Q', 'O', 'P', 'T')\r
-\r
-typedef struct {\r
-  UINTN                  Signature;\r
-  LIST_ENTRY             Link;\r
-  //\r
-  // OneOfOption Data\r
-  //\r
-  EFI_IFR_ONE_OF_OPTION  *OptionOpCode;\r
-  //\r
-  // Option ImageId and AnimationId\r
-  //\r
-  EFI_IMAGE_ID           ImageId;\r
-  EFI_ANIMATION_ID       AnimationId;\r
-} DISPLAY_QUESTION_OPTION;\r
-\r
-#define DISPLAY_QUESTION_OPTION_FROM_LINK(a)  CR (a, DISPLAY_QUESTION_OPTION, Link, DISPLAY_QUESTION_OPTION_SIGNATURE)\r
-\r
-typedef struct _FORM_DISPLAY_ENGINE_STATEMENT FORM_DISPLAY_ENGINE_STATEMENT;\r
-typedef struct _FORM_DISPLAY_ENGINE_FORM      FORM_DISPLAY_ENGINE_FORM;\r
-\r
-#define STATEMENT_VALID             0x0\r
-#define STATEMENT_INVALID           BIT31\r
-\r
-#define INCOSISTENT_IF_TRUE         STATEMENT_INVALID | 0x01\r
-#define WARNING_IF_TRUE             STATEMENT_INVALID | 0x02\r
-#define STRING_TOO_LONG             STATEMENT_INVALID | 0x03\r
-// ... to be extended.\r
-\r
-typedef struct {\r
-  //\r
-  // StringId for INCONSITENT_IF or WARNING_IF\r
-  //\r
-  EFI_STRING_ID  StringId;\r
-  //\r
-  // TimeOut for WARNING_IF\r
-  //\r
-  UINT8          TimeOut;\r
-} STATEMENT_ERROR_INFO;\r
-\r
-/**\r
-  Perform value check for a question.\r
-  \r
-  @param  Form       Form where Statement is in.\r
-  @param  Statement  Value will check for it.\r
-  @param  Value      New value will be checked.\r
-  \r
-  @retval Status     Value Status\r
-\r
-**/\r
-typedef\r
-UINT32\r
-(EFIAPI *VALIDATE_QUESTION) (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *Form,\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
-  IN EFI_HII_VALUE                 *Value, \r
-  OUT STATEMENT_ERROR_INFO         *ErrorInfo\r
-  );\r
-\r
-/**\r
-  Perform Password check. \r
-  Passwork may be encrypted by driver that requires the specific check.\r
-  \r
-  @param  Form             Form where Password Statement is in.\r
-  @param  Statement        Password statement\r
-  @param  PasswordString   Password string to be checked. It may be NULL.\r
-                           NULL means to restore password.\r
-                           "" string can be used to checked whether old password does exist.\r
-  \r
-  @return Status     Status of Password check.\r
-**/\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI *PASSWORD_CHECK) (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *Form,\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
-  IN EFI_STRING                    PasswordString  OPTIONAL\r
-  );\r
-\r
-#define FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE  SIGNATURE_32 ('F', 'S', 'T', 'A')\r
-\r
-//\r
-// Attribute for Statement and Form\r
-//\r
-#define HII_DISPLAY_GRAYOUT          BIT0\r
-#define HII_DISPLAY_LOCK             BIT1\r
-#define HII_DISPLAY_READONLY         BIT2\r
-#define HII_DISPLAY_MODAL            BIT3\r
-\r
-struct _FORM_DISPLAY_ENGINE_STATEMENT{\r
-  UINTN                 Signature;\r
-  //\r
-  // Version for future structure extension\r
-  //\r
-  UINTN                 Version;\r
-  //\r
-  // link to all the statement which will show in the display form.\r
-  //\r
-  LIST_ENTRY            DisplayLink;\r
-  //\r
-  // Pointer to statement opcode.\r
-  // for Guided Opcode. All buffers will be here if GUIDED opcode scope is set.\r
-  //\r
-  EFI_IFR_OP_HEADER     *OpCode;\r
-  //\r
-  // Question CurrentValue\r
-  //\r
-  EFI_HII_VALUE         CurrentValue;\r
-  //\r
-  // Flag to describe whether setting is changed or not.\r
-  // Displayer may depend on it to show it with the different color. \r
-  //\r
-  BOOLEAN               SettingChangedFlag;\r
-  //\r
-  // nested Statement list inside of EFI_IFR_SUBTITLE\r
-  //\r
-  LIST_ENTRY            NestStatementList;\r
-  //\r
-  // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)\r
-  //\r
-  LIST_ENTRY            OptionListHead;\r
-  //\r
-  // Statement attributes: GRAYOUT, LOCK and READONLY\r
-  //\r
-  UINT32                Attribute;\r
-\r
-  //\r
-  // ValidateQuestion to do InconsistIf check\r
-  // It may be NULL if any value is valid.\r
-  //\r
-  VALIDATE_QUESTION     ValidateQuestion;\r
-  \r
-  //\r
-  // Password additional check. It may be NULL when the additional check is not required.\r
-  //\r
-  PASSWORD_CHECK        PasswordCheck;\r
-\r
-  //\r
-  // Statement ImageId and AnimationId\r
-  //\r
-  EFI_IMAGE_ID          ImageId;\r
-  EFI_ANIMATION_ID      AnimationId;\r
-};\r
-\r
-#define FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK(a)  CR (a, FORM_DISPLAY_ENGINE_STATEMENT, DisplayLink, FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE)\r
-\r
-#define BROWSER_HOT_KEY_SIGNATURE  SIGNATURE_32 ('B', 'H', 'K', 'S')\r
-\r
-typedef struct {\r
-  UINTN                 Signature;\r
-  LIST_ENTRY            Link;\r
-  \r
-  EFI_INPUT_KEY         *KeyData;\r
-  //\r
-  // Action is Discard, Default, Submit, Reset and Exit.\r
-  //\r
-  UINT32                 Action;\r
-  UINT16                 DefaultId;\r
-  //\r
-  // HotKey Help String\r
-  //\r
-  EFI_STRING             HelpString;\r
-} BROWSER_HOT_KEY;\r
-\r
-#define BROWSER_HOT_KEY_FROM_LINK(a)  CR (a, BROWSER_HOT_KEY, Link, BROWSER_HOT_KEY_SIGNATURE)\r
-\r
-#define FORM_DISPLAY_ENGINE_FORM_SIGNATURE  SIGNATURE_32 ('F', 'F', 'R', 'M')\r
-\r
-struct _FORM_DISPLAY_ENGINE_FORM {\r
-  UINTN                Signature;\r
-  //\r
-  // Version for future structure extension\r
-  //\r
-  UINTN                Version;\r
-  //\r
-  // Statement List inside of Form\r
-  //\r
-  LIST_ENTRY            StatementListHead;\r
-  //\r
-  // Statement List outside of Form  \r
-  //\r
-  LIST_ENTRY            StatementListOSF;\r
-  //\r
-  // The input screen dimenstions info.\r
-  //\r
-  EFI_SCREEN_DESCRIPTOR *ScreenDimensions;\r
-  //\r
-  // FormSet information\r
-  //\r
-  EFI_GUID             FormSetGuid;\r
-  //\r
-  // HiiHandle can be used to get String, Image or Animation\r
-  //\r
-  EFI_HII_HANDLE       HiiHandle;\r
-  \r
-  //\r
-  // Form ID and Title.\r
-  //\r
-  UINT16               FormId;\r
-  EFI_STRING_ID        FormTitle;\r
-  //\r
-  // Form Attributes: Lock, Modal.\r
-  //\r
-  UINT32               Attribute;\r
-  //\r
-  // Flag to describe whether setting is changed or not.\r
-  // Displayer depends on it to show ChangedFlag.\r
-  //\r
-  BOOLEAN              SettingChangedFlag;\r
-\r
-  //\r
-  // Statement to be HighLighted\r
-  //\r
-  FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement;\r
-  //\r
-  // Event to notify Displayer that FormData is updated to be refreshed.\r
-  //\r
-  EFI_EVENT              FormRefreshEvent;\r
-  //\r
-  // Additional Hotkey registered by BrowserEx protocol.\r
-  //\r
-  LIST_ENTRY             HotKeyListHead;\r
-\r
-  //\r
-  // Form ImageId and AnimationId\r
-  //\r
-  EFI_IMAGE_ID         ImageId;\r
-  EFI_ANIMATION_ID     AnimationId;\r
-  \r
-  //\r
-  // If Status is error, display needs to handle it.  \r
-  //\r
-  UINT32               BrowserStatus;\r
-  //\r
-  // String for error status. It may be NULL. \r
-  //\r
-  EFI_STRING           ErrorString;\r
-};\r
-\r
-#define FORM_DISPLAY_ENGINE_FORM_FROM_LINK(a)  CR (a, FORM_DISPLAY_ENGINE_FORM, Link, FORM_DISPLAY_ENGINE_FORM_SIGNATURE)\r
-\r
-typedef struct {\r
-  FORM_DISPLAY_ENGINE_STATEMENT  *SelectedStatement; // Selected Statement and InputValue\r
-  \r
-  EFI_HII_VALUE                  InputValue;\r
-  \r
-  UINT32                         Action;             // If SelectedStatement is NULL, Action will be used.\r
-                                                     // Trig Action (Discard, Default, Submit, Reset and Exit)\r
-  UINT16                         DefaultId;\r
-} USER_INPUT;\r
-\r
-/**\r
-  Display one form, and return user input.\r
-  \r
-  @param FormData                Form Data to be shown.\r
-  @param UserInputData           User input data.\r
-  \r
-  @retval EFI_SUCCESS            Form Data is shown, and user input is got.\r
-**/\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI *FORM_DISPLAY) (\r
-  IN FORM_DISPLAY_ENGINE_FORM  *FormData,\r
-  OUT USER_INPUT               *UserInputData\r
-);\r
-\r
-/**\r
-  Exit Display and Clear Screen to the original state.\r
-\r
-**/\r
-typedef\r
-VOID\r
-(EFIAPI *EXIT_DISPLAY) (\r
-  VOID\r
-);\r
-\r
-/**\r
-  Confirm how to handle the changed data. \r
-  \r
-  @return Action of Submit, Discard and None\r
-**/\r
-typedef\r
-UINTN\r
-(EFIAPI *CONFIRM_DATA_CHANGE) (\r
-  VOID\r
-);\r
-\r
-typedef struct {\r
-  FORM_DISPLAY        FormDisplay;\r
-  EXIT_DISPLAY        ExitDisplay;\r
-  CONFIRM_DATA_CHANGE ConfirmDataChange;\r
-} EDKII_FORM_DISPLAY_ENGINE_PROTOCOL;\r
-\r
-extern EFI_GUID gEdkiiFormDisplayEngineProtocolGuid;\r
-#endif\r
diff --git a/MdeModulePkg/Include/Protocol/FormBrowserEx2.h b/MdeModulePkg/Include/Protocol/FormBrowserEx2.h
deleted file mode 100644 (file)
index 105ac03..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/** @file\r
-  Extension Form Browser Protocol provides the services that can be used to \r
-  register the different hot keys for the standard Browser actions described in UEFI specification.\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#ifndef __FORM_BROWSER_EXTENSION2_H__\r
-#define __FORM_BROWSER_EXTENSION2_H__\r
-\r
-#include <Protocol/FormBrowserEx.h>\r
-\r
-#define EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL_GUID  \\r
-  { 0xa770c357, 0xb693, 0x4e6d, { 0xa6, 0xcf, 0xd2, 0x1c, 0x72, 0x8e, 0x55, 0xb }}\r
-\r
-typedef struct _EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL   EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL;\r
-\r
-#define BROWSER_EXTENSION2_VERSION_1  0x10000\r
-\r
-/**\r
-  Check whether the browser data has been modified.\r
-\r
-  @retval TRUE        Browser data is modified.\r
-  @retval FALSE       No browser data is modified.\r
-\r
-**/\r
-typedef\r
-BOOLEAN\r
-(EFIAPI *IS_BROWSER_DATA_MODIFIED) (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Execute the action requested by the Action parameter.\r
-\r
-  @param[in] Action     Execute the request action.\r
-  @param[in] DefaultId  The default Id info when need to load default value.\r
-\r
-  @retval EFI_SUCCESS              Execute the request action succss.\r
-\r
-**/\r
-typedef \r
-EFI_STATUS \r
-(EFIAPI *EXECUTE_ACTION) (\r
-  IN UINT32        Action,\r
-  IN UINT16        DefaultId\r
-  );\r
-\r
-#define FORM_ENTRY_INFO_SIGNATURE    SIGNATURE_32 ('f', 'e', 'i', 's')\r
-\r
-typedef struct {\r
-  UINTN           Signature;\r
-  LIST_ENTRY      Link;\r
-\r
-  EFI_HII_HANDLE  HiiHandle;\r
-  EFI_GUID        FormSetGuid;\r
-  EFI_FORM_ID     FormId;\r
-  EFI_QUESTION_ID QuestionId;\r
-} FORM_ENTRY_INFO;\r
-\r
-#define FORM_ENTRY_INFO_FROM_LINK(a)  CR (a, FORM_ENTRY_INFO, Link, FORM_ENTRY_INFO_SIGNATURE)\r
-\r
-struct _EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL {\r
-  ///\r
-  /// Version for protocol future extension.\r
-  ///\r
-  UINT32                    Version;\r
-  SET_SCOPE                 SetScope;\r
-  REGISTER_HOT_KEY          RegisterHotKey;\r
-  REGISTER_EXIT_HANDLER     RegiserExitHandler;\r
-  IS_BROWSER_DATA_MODIFIED  IsBrowserDataModified;\r
-  EXECUTE_ACTION            ExecuteAction;\r
-  ///\r
-  /// A list of type FORMID_INFO is Browser View Form History List.\r
-  ///\r
-  LIST_ENTRY                FormViewHistoryHead;\r
-};\r
-\r
-extern EFI_GUID gEdkiiFormBrowserEx2ProtocolGuid;\r
-\r
-#endif\r
-\r
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/Colors.h b/MdeModulePkg/Library/CustomizedDisplayLib/Colors.h
deleted file mode 100644 (file)
index 2db8b99..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/** @file\r
-MACRO definitions for color used in Setup Browser.\r
-\r
-Copyright (c) 2004 - 2011, 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
-// Unicode collation protocol in\r
-\r
-#ifndef _COLORS_H_\r
-#define _COLORS_H_\r
-\r
-//\r
-// Screen Color Settings\r
-//\r
-#define PICKLIST_HIGHLIGHT_TEXT       EFI_WHITE\r
-#define PICKLIST_HIGHLIGHT_BACKGROUND EFI_BACKGROUND_CYAN\r
-#define TITLE_TEXT                    EFI_WHITE\r
-#define TITLE_BACKGROUND              EFI_BACKGROUND_BLUE\r
-#define KEYHELP_TEXT                  EFI_LIGHTGRAY\r
-#define KEYHELP_BACKGROUND            EFI_BACKGROUND_BLACK\r
-#define SUBTITLE_BACKGROUND           EFI_BACKGROUND_LIGHTGRAY\r
-#define BANNER_TEXT                   EFI_BLUE\r
-#define BANNER_BACKGROUND             EFI_BACKGROUND_LIGHTGRAY\r
-#define FIELD_TEXT_GRAYED             EFI_DARKGRAY\r
-#define FIELD_BACKGROUND              EFI_BACKGROUND_LIGHTGRAY\r
-#define POPUP_TEXT                    EFI_LIGHTGRAY\r
-#define POPUP_BACKGROUND              EFI_BACKGROUND_BLUE\r
-#define POPUP_INVERSE_TEXT            EFI_LIGHTGRAY\r
-#define POPUP_INVERSE_BACKGROUND      EFI_BACKGROUND_BLACK\r
-#define HELP_TEXT                     EFI_BLUE\r
-#define ERROR_TEXT                    EFI_RED | EFI_BRIGHT\r
-#define INFO_TEXT                     EFI_YELLOW | EFI_BRIGHT\r
-#define ARROW_TEXT                    EFI_RED | EFI_BRIGHT\r
-#define ARROW_BACKGROUND              EFI_BACKGROUND_LIGHTGRAY\r
-\r
-#endif\r
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c
deleted file mode 100644 (file)
index aa28146..0000000
+++ /dev/null
@@ -1,921 +0,0 @@
-/** @file\r
-\r
-  This library class defines a set of interfaces to customize Display module\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#include "CustomizedDisplayLibInternal.h"\r
-\r
-EFI_GUID          gCustomizedDisplayLibGuid = { 0x99fdc8fd, 0x849b, 0x4eba, { 0xad, 0x13, 0xfb, 0x96, 0x99, 0xc9, 0xa, 0x4d } };\r
-\r
-EFI_HII_HANDLE    mCDLStringPackHandle;\r
-UINT16            gClassOfVfr;                 // Formset class information\r
-BOOLEAN           gLibIsFirstForm = TRUE;\r
-BANNER_DATA       *gBannerData;\r
-\r
-UINTN             gFooterHeight;\r
-\r
-/**\r
-+------------------------------------------------------------------------------+\r
-|                                 Setup Page                                   |\r
-+------------------------------------------------------------------------------+\r
-\r
-Statement\r
-Statement\r
-Statement\r
-\r
-\r
-\r
-\r
-\r
-+------------------------------------------------------------------------------+\r
-|                                F9=Reset to Defaults        F10=Save          |\r
-| ^"=Move Highlight          <Spacebar> Toggles Checkbox     Esc=Exit          |\r
-+------------------------------------------------------------------------------+\r
-  StatusBar\r
-**/\r
-\r
-/**\r
-  This funtion defines Page Frame and Backgroud. \r
-  \r
-  Based on the above layout, it will be responsible for HeaderHeight, FooterHeight, \r
-  StatusBarHeight and Backgroud. And, it will reserve Screen for Statement. \r
-\r
-  @param[in]  FormData             Form Data to be shown in Page.\r
-  @param[out] ScreenForStatement   Screen to be used for Statement. (Prompt, Value and Help)\r
-  \r
-  @return Status\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DisplayPageFrame (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData,\r
-  OUT EFI_SCREEN_DESCRIPTOR         *ScreenForStatement\r
-  )\r
-{\r
-  EFI_STATUS             Status;\r
-\r
-  ASSERT (FormData != NULL && ScreenForStatement != NULL);\r
-  if (FormData == NULL || ScreenForStatement == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Status = ScreenDiemensionInfoValidate (FormData);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
-\r
-  ProcessExternedOpcode(FormData);\r
-\r
-  //\r
-  // Calculate the ScreenForStatement.\r
-  //\r
-  ScreenForStatement->BottomRow   = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight;\r
-  if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
-    ScreenForStatement->TopRow    = gScreenDimensions.TopRow + FRONT_PAGE_HEADER_HEIGHT;\r
-  } else {\r
-    ScreenForStatement->TopRow    = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;\r
-  }\r
-  ScreenForStatement->LeftColumn  = gScreenDimensions.LeftColumn;\r
-  ScreenForStatement->RightColumn = gScreenDimensions.RightColumn;\r
-\r
-  if ((gLibIsFirstForm) || ((FormData->Attribute & HII_DISPLAY_MODAL) != 0)) {\r
-    //\r
-    // Ensure we are in Text mode\r
-    //\r
-    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-    ClearLines (0, gScreenDimensions.RightColumn, 0, gScreenDimensions.BottomRow, KEYHELP_BACKGROUND);\r
-    gLibIsFirstForm = FALSE;\r
-  }\r
-\r
-  //\r
-  // Don't print frame for modal form.\r
-  //\r
-  if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
-    PrintBannerInfo (FormData);\r
-  }\r
-\r
-  PrintFramework (FormData);\r
-\r
-  UpdateStatusBar(NV_UPDATE_REQUIRED, FormData->SettingChangedFlag);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function updates customized key panel's help information.\r
-  The library will prepare those Strings for the basic key, ESC, Enter, Up/Down/Left/Right, +/-.\r
-  and arrange them in Footer panel.\r
-  \r
-  @param[in]  FormData       Form Data to be shown in Page. FormData has the highlighted statement. \r
-  @param[in]  Statement      The statement current selected.\r
-  @param[in]  Selected       Whether or not a tag be selected. TRUE means Enter has hit this question.\r
-**/\r
-VOID\r
-EFIAPI\r
-RefreshKeyHelp (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *FormData,\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\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_IFR_NUMERIC        *NumericOp;\r
-  EFI_IFR_DATE           *DateOp;\r
-  EFI_IFR_TIME           *TimeOp;\r
-  BOOLEAN                HexDisplay;\r
-\r
-  ASSERT (FormData != NULL);\r
-  if (FormData == NULL) {\r
-    return;\r
-  }\r
-\r
-  gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
-\r
-  if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
-    return;\r
-  }\r
-\r
-  SecCol            = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3;\r
-  ThdCol            = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3 * 2;\r
-\r
-  StartColumnOfHelp = gScreenDimensions.LeftColumn + 2;\r
-  LeftColumnOfHelp  = gScreenDimensions.LeftColumn + 1;\r
-  RightColumnOfHelp = gScreenDimensions.RightColumn - 2;\r
-  TopRowOfHelp      = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
-  BottomRowOfHelp   = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;\r
-\r
-  ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
-  if (Statement == NULL) {\r
-    //\r
-    // Print Key for Form without showable statement.\r
-    //\r
-    PrintHotKeyHelpString (FormData);\r
-    PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
-    return;\r
-  }\r
-\r
-  HexDisplay = FALSE;\r
-  NumericOp = NULL;\r
-  DateOp    = NULL;\r
-  TimeOp    = NULL;\r
-  if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) {\r
-    NumericOp = (EFI_IFR_NUMERIC *) Statement->OpCode;\r
-    HexDisplay = (NumericOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;\r
-  } else if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-    DateOp   = (EFI_IFR_DATE *) Statement->OpCode;\r
-    HexDisplay = (DateOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;\r
-  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-    TimeOp  = (EFI_IFR_TIME *) Statement->OpCode;\r
-    HexDisplay = (TimeOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;\r
-  }  \r
-  switch (Statement->OpCode->OpCode) {\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
-    if (!Selected) {\r
-        PrintHotKeyHelpString (FormData);\r
-\r
-      if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
-        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
-      }\r
-\r
-      if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
-          (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {\r
-        PrintAt (\r
-          0, \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, gEnterString);\r
-        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);\r
-      } else {\r
-        PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
-        if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP && NumericOp != NULL && LibGetFieldFromNum(Statement->OpCode) != 0) {\r
-          PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);\r
-        } \r
-        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\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->OpCode->OpCode == EFI_IFR_NUMERIC_OP) || \r
-          (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
-          (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {\r
-        PrintStringAt (\r
-          SecCol,\r
-          TopRowOfHelp,\r
-          HexDisplay ? gHexNumericInput : gDecNumericInput\r
-          );\r
-      } else if (Statement->OpCode->OpCode != EFI_IFR_ORDERED_LIST_OP) {\r
-        PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
-      }\r
-\r
-      if (Statement->OpCode->OpCode == 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
-    PrintHotKeyHelpString (FormData);\r
-\r
-    if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
-      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
-    }\r
-\r
-    PrintAt (0, 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
-  case EFI_IFR_SUBTITLE_OP:\r
-     if (!Selected) {\r
-      PrintHotKeyHelpString (FormData);\r
-\r
-      if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
-        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
-      }\r
-\r
-      PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
-      if (Statement->OpCode->OpCode != EFI_IFR_TEXT_OP && Statement->OpCode->OpCode != EFI_IFR_SUBTITLE_OP) {\r
-        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
-      }\r
-    } else {\r
-      if (Statement->OpCode->OpCode  != EFI_IFR_REF_OP) {\r
-        PrintStringAt (\r
-          (gScreenDimensions.RightColumn - LibGetStringWidth (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
-  Update status bar.\r
-\r
-  This function updates the status bar on the bottom of menu screen. It just shows StatusBar. \r
-  Original logic in this function should be splitted out.\r
-\r
-  @param[in]  MessageType            The type of message to be shown. InputError or Configuration Changed. \r
-  @param[in]  State                  Show or Clear Message.\r
-**/\r
-VOID\r
-EFIAPI\r
-UpdateStatusBar (\r
-  IN  UINTN                  MessageType,\r
-  IN  BOOLEAN                State\r
-  )\r
-{\r
-  UINTN           Index;\r
-  CHAR16          OptionWidth;\r
-\r
-  OptionWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
-\r
-  switch (MessageType) {\r
-  case INPUT_ERROR:\r
-    if (State) {\r
-      gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);\r
-      PrintStringAt (\r
-        gScreenDimensions.LeftColumn + OptionWidth,\r
-        gScreenDimensions.BottomRow - 1,\r
-        gInputErrorMessage\r
-        );\r
-    } else {\r
-      gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND);\r
-      for (Index = 0; Index < (LibGetStringWidth (gInputErrorMessage) - 2) / 2; Index++) {\r
-        PrintStringAt (gScreenDimensions.LeftColumn + OptionWidth + Index, gScreenDimensions.BottomRow - 1, L"  ");\r
-      }\r
-    }\r
-    break;\r
-\r
-  case NV_UPDATE_REQUIRED:\r
-    //\r
-    // Global setting support. Show configuration change on every form.\r
-    //\r
-    if (State) {\r
-      gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);\r
-      PrintStringAt (\r
-        gScreenDimensions.LeftColumn + OptionWidth * 2,\r
-        gScreenDimensions.BottomRow - 1,\r
-        gNvUpdateMessage\r
-        );\r
-    } else {\r
-      gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND);\r
-      for (Index = 0; Index < (LibGetStringWidth (gNvUpdateMessage) - 2) / 2; Index++) {\r
-        PrintStringAt (\r
-          (gScreenDimensions.LeftColumn + OptionWidth * 2 + Index),\r
-          gScreenDimensions.BottomRow - 1,\r
-          L"  "\r
-          );\r
-      }\r
-    }\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  } \r
-}\r
-\r
-/**\r
-  Create popup window. It will replace CreateDialog(). \r
-\r
-  This function draws OEM/Vendor specific pop up windows.\r
-\r
-  @param[out]  Key    User Input Key\r
-  @param       ...    String to be shown in Popup. The variable argument list is terminated by a NULL.\r
-  \r
-**/\r
-VOID\r
-EFIAPI\r
-CreateDialog (\r
-  OUT EFI_INPUT_KEY  *Key,        OPTIONAL\r
-  ...\r
-  )\r
-{\r
-  VA_LIST       Marker;\r
-  EFI_INPUT_KEY KeyValue;\r
-  EFI_STATUS    Status;\r
-  UINTN         LargestString;\r
-  UINTN         LineNum;\r
-  UINTN   Index;\r
-  UINTN   Count;\r
-  CHAR16  Character;\r
-  UINTN   Start;\r
-  UINTN   End;\r
-  UINTN   Top;\r
-  UINTN   Bottom;\r
-  CHAR16  *String;\r
-  UINTN   DimensionsWidth;\r
-  UINTN   DimensionsHeight;\r
-  UINTN   CurrentAttribute;\r
-\r
-  //\r
-  // If screen dimension info is not ready, get it from console.\r
-  //\r
-  if (gScreenDimensions.RightColumn == 0 || gScreenDimensions.BottomRow == 0) {\r
-    ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-    gST->ConOut->QueryMode (\r
-                   gST->ConOut,\r
-                   gST->ConOut->Mode->Mode,\r
-                   &gScreenDimensions.RightColumn,\r
-                   &gScreenDimensions.BottomRow\r
-                   );\r
-  }\r
-\r
-  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
-  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;\r
-\r
-  LargestString = 0;\r
-  LineNum       = 0;\r
-  VA_START (Marker, Key);\r
-  while  ((String = VA_ARG (Marker, CHAR16 *)) != NULL) {\r
-    LineNum ++;\r
-    \r
-    if ((LibGetStringWidth (String) / 2) > LargestString) {\r
-      LargestString = (LibGetStringWidth (String) / 2);\r
-    }\r
-  } \r
-  VA_END (Marker);\r
-\r
-  if ((LargestString + 2) > DimensionsWidth) {\r
-    LargestString = DimensionsWidth - 2;\r
-  }\r
-  \r
-  CurrentAttribute  = gST->ConOut->Mode->Attribute;  \r
-  gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
-  gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-\r
-  //\r
-  // Subtract the PopUp width from total Columns, allow for one space extra on\r
-  // each end plus a border.\r
-  //\r
-  Start     = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;\r
-  End       = Start + LargestString + 1;\r
-\r
-  Top       = ((DimensionsHeight - LineNum - 2) / 2) + gScreenDimensions.TopRow - 1;\r
-  Bottom    = Top + LineNum + 2;\r
-\r
-  Character = BOXDRAW_DOWN_RIGHT;\r
-  PrintCharAt (Start, Top, Character);\r
-  Character = BOXDRAW_HORIZONTAL;\r
-  for (Index = Start; Index + 2 < End; Index++) {\r
-    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-  }\r
-\r
-  Character = BOXDRAW_DOWN_LEFT;\r
-  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-  Character = BOXDRAW_VERTICAL;\r
-\r
-  Count = 0;\r
-  VA_START (Marker, Key);\r
-  for (Index = Top; Index + 2 < Bottom; Index++, Count++) {\r
-    String = VA_ARG (Marker, CHAR16*);\r
-\r
-    if (String[0] == CHAR_NULL) {\r
-      //\r
-      // Passing in a NULL results in a blank space\r
-      //\r
-      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());\r
-    } else if (String[0] == L' ') {\r
-      //\r
-      // Passing in a space results in the assumption that this is where typing will occur\r
-      //\r
-      ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);\r
-      PrintStringAt (\r
-        ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,\r
-        Index + 1,\r
-        String + 1\r
-        );\r
-    } else {\r
-      //\r
-      // This will clear the background of the line - we never know who might have been\r
-      // here before us.  This differs from the next clear in that it used the non-reverse\r
-      // video for normal printing.\r
-      //\r
-      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());\r
-      PrintStringAt (\r
-        ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,\r
-        Index + 1,\r
-        String\r
-        );\r
-    }\r
-\r
-    gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-    PrintCharAt (Start, Index + 1, Character);\r
-    PrintCharAt (End - 1, Index + 1, Character);\r
-  }\r
-  VA_END (Marker);\r
-\r
-  Character = BOXDRAW_UP_RIGHT;\r
-  PrintCharAt (Start, Bottom - 1, Character);\r
-  Character = BOXDRAW_HORIZONTAL;\r
-  for (Index = Start; Index + 2 < End; Index++) {\r
-    PrintCharAt ((UINTN)-1, (UINTN) -1, Character);\r
-  }\r
-\r
-  Character = BOXDRAW_UP_LEFT;\r
-  PrintCharAt ((UINTN)-1, (UINTN) -1, Character);\r
-\r
-  if (Key != NULL) {\r
-    Status = WaitForKeyStroke (&KeyValue);\r
-    ASSERT_EFI_ERROR (Status);\r
-    CopyMem (Key, &KeyValue, sizeof (EFI_INPUT_KEY));\r
-  }\r
-\r
-  gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
-  gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
-}\r
-\r
-/**\r
-  Confirm how to handle the changed data. \r
-  \r
-  @return Action BROWSER_ACTION_SUBMIT, BROWSER_ACTION_DISCARD or other values.\r
-**/\r
-UINTN\r
-EFIAPI\r
-ConfirmDataChange (\r
-  VOID\r
-  )\r
-{\r
-  CHAR16                  YesResponse;\r
-  CHAR16                  NoResponse;\r
-  EFI_INPUT_KEY           Key;\r
-\r
-  gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-  \r
-  YesResponse = gYesResponse[0];\r
-  NoResponse  = gNoResponse[0];\r
-  \r
-  //\r
-  // If NV flag is up, prompt user\r
-  //\r
-  do {\r
-    CreateDialog (&Key, gLibEmptyString, gSaveChanges, gAreYouSure, gLibEmptyString, NULL);\r
-  } while\r
-  (\r
-    (Key.ScanCode != SCAN_ESC) &&\r
-    ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
-    ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
-  );\r
-  \r
-  if (Key.ScanCode == SCAN_ESC) {\r
-    return BROWSER_ACTION_NONE;\r
-  } else if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
-    return BROWSER_ACTION_SUBMIT;\r
-  } else {\r
-    return BROWSER_ACTION_DISCARD;\r
-  }\r
-}\r
-\r
-/**\r
-  OEM specifies whether Setup exits Page by ESC key.\r
-\r
-  This function customized the behavior that whether Setup exits Page so that \r
-  system able to boot when configuration is not changed.\r
-\r
-  @retval  TRUE     Exits FrontPage\r
-  @retval  FALSE    Don't exit FrontPage.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-FormExitPolicy (\r
-  VOID\r
-  )\r
-{\r
-  return gClassOfVfr == FORMSET_CLASS_FRONT_PAGE ? FALSE : TRUE;\r
-}\r
-\r
-/**\r
-  Set Timeout value for a ceratain Form to get user response. \r
-  \r
-  This function allows to set timeout value on a ceratain form if necessary.\r
-  If timeout is not zero, the form will exit if user has no response in timeout. \r
-  \r
-  @param[in]  FormData   Form Data to be shown in Page\r
-\r
-  @return 0     No timeout for this form. \r
-  @return > 0   Timeout value in 100 ns units.\r
-**/\r
-UINT64\r
-EFIAPI\r
-FormExitTimeout (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *FormData\r
-  )\r
-{\r
-  return 0;\r
-}\r
-//\r
-// Print Functions\r
-//\r
-/**\r
-  Prints a unicode string to the default console, at\r
-  the supplied cursor position, using L"%s" format.\r
-\r
-  @param  Column     The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Row        The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  String     String pointer.\r
-\r
-  @return Length of string printed to the console\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintStringAt (\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  IN CHAR16    *String\r
-  )\r
-{\r
-  return PrintAt (0, Column, Row, L"%s", String);\r
-}\r
-\r
-/**\r
-  Prints a unicode string to the default console, at\r
-  the supplied cursor position, using L"%s" format.\r
-\r
-  @param  Column     The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Row        The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  String     String pointer.\r
-  @param  Width      Width for String.\r
-\r
-  @return Length of string printed to the console\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintStringAtWithWidth (\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  IN CHAR16    *String,\r
-  IN UINTN     Width\r
-  )\r
-{\r
-  return PrintAt (Width, Column, Row, L"%s", String);\r
-}\r
-\r
-/**\r
-  Prints a chracter to the default console, at\r
-  the supplied cursor position, using L"%c" format.\r
-\r
-  @param  Column     The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Row        The cursor position to print the string at. When it is -1, use current Position.\r
-  @param  Character  Character to print.\r
-\r
-  @return Length of string printed to the console.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintCharAt (\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  CHAR16       Character\r
-  )\r
-{\r
-  return PrintAt (0, Column, Row, L"%c", Character);\r
-}\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
-EFIAPI\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
-  LibSetUnicodeMem (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
-}\r
-\r
-//\r
-// Color Setting Functions\r
-//\r
-\r
-/**\r
-  Get OEM/Vendor specific popup attribute colors.\r
-\r
-  @retval  Byte code color setting for popup color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetPopupColor (\r
-  VOID\r
-  )\r
-{\r
-  return POPUP_TEXT | POPUP_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific popup attribute colors.\r
-\r
-  @retval  Byte code color setting for popup inverse color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetPopupInverseColor (\r
-  VOID\r
-  )\r
-{\r
-  return POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific PickList color attribute.\r
-\r
-  @retval  Byte code color setting for pick list color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetPickListColor (\r
-  VOID\r
-  )\r
-{\r
-  return PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific arrow color attribute.\r
-\r
-  @retval  Byte code color setting for arrow color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetArrowColor (\r
-  VOID\r
-  )\r
-{\r
-  return ARROW_TEXT | ARROW_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific info text color attribute.\r
-\r
-  @retval  Byte code color setting for info text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetInfoTextColor (\r
-  VOID\r
-  )\r
-{\r
-  return INFO_TEXT | FIELD_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific help text color attribute.\r
-\r
-  @retval  Byte code color setting for help text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetHelpTextColor (\r
-  VOID\r
-  )\r
-{\r
-  return HELP_TEXT | FIELD_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific grayed out text color attribute.\r
-\r
-  @retval  Byte code color setting for grayed out text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetGrayedTextColor (\r
-  VOID\r
-  )\r
-{\r
-  return FIELD_TEXT_GRAYED | FIELD_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific highlighted text color attribute.\r
-\r
-  @retval  Byte code color setting for highlight text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetHighlightTextColor (\r
-  VOID\r
-  )\r
-{\r
-  return PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor);\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific field text color attribute.\r
-\r
-  @retval  Byte code color setting for field text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetFieldTextColor (\r
-  VOID\r
-  )\r
-{\r
-  return PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Get OEM/Vendor specific subtitle text color attribute.\r
-\r
-  @retval  Byte code color setting for subtitle text color.\r
-**/\r
-UINT8\r
-EFIAPI\r
-GetSubTitleTextColor (\r
-  VOID\r
-  )\r
-{\r
-  return PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND;\r
-}\r
-\r
-/**\r
-  Clear Screen to the initial state.\r
-**/\r
-VOID\r
-EFIAPI \r
-ClearDisplayPage (\r
-  VOID\r
-  )\r
-{\r
-  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-  gST->ConOut->ClearScreen (gST->ConOut);\r
-  gLibIsFirstForm = TRUE;\r
-}\r
-\r
-/**\r
-  Constructor of Customized Display Library Instance.\r
-\r
-  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
-  @param  SystemTable   A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CustomizedDisplayLibConstructor (\r
-  IN      EFI_HANDLE                ImageHandle,\r
-  IN      EFI_SYSTEM_TABLE          *SystemTable\r
-  )\r
-{\r
-  mCDLStringPackHandle = HiiAddPackages (&gCustomizedDisplayLibGuid, ImageHandle, CustomizedDisplayLibStrings, NULL);\r
-  ASSERT (mCDLStringPackHandle != NULL);\r
-\r
-  InitializeLibStrings();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Destructor of Customized Display Library Instance.\r
-\r
-  @param  ImageHandle   The firmware allocated handle for the EFI image.\r
-  @param  SystemTable   A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS   The destructor completed successfully.\r
-  @retval Other value   The destructor did not complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CustomizedDisplayLibDestructor (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-  HiiRemovePackages(mCDLStringPackHandle);\r
-  \r
-  FreeLibStrings ();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
deleted file mode 100644 (file)
index ade45b6..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-##\r
-#  This file contains an 'Intel Peripheral Driver' and is        \r
-#  licensed for Intel CPUs and chipsets under the terms of your  \r
-#  license agreement with Intel or your vendor.  This file may   \r
-#  be modified by the user, subject to additional terms of the   \r
-#  license agreement                                             \r
-##\r
-## @file\r
-#  \r
-#  General BDS defines and produce general interfaces for platform BDS driver including:\r
-#  1) BDS boot policy interface;\r
-#  2) BDS boot device connect interface;\r
-#  3) BDS Misc interfaces for mainting boot variable, ouput string, etc.\r
-#  \r
-#  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
-#  This software and associated documentation (if any) is furnished\r
-#  under a license and may only be used or copied in accordance\r
-#  with the terms of the license. Except as permitted by such\r
-#  license, no part of this software or documentation may be\r
-#  reproduced, stored in a retrieval system, or transmitted in any\r
-#  form or by any means without the express written consent of\r
-#  Intel Corporation.\r
-#  \r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = CustomizedDisplayLib\r
-  FILE_GUID                      = 80B92017-EC64-4923-938D-94FAEE85832E\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = CustomizedDisplayLib|DXE_DRIVER UEFI_APPLICATION\r
-  CONSTRUCTOR                    = CustomizedDisplayLibConstructor\r
-  DESTRUCTOR                     = CustomizedDisplayLibDestructor\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources]\r
-  CustomizedDisplayLib.c\r
-  Colors.h\r
-  CustomizedDisplayLibInternal.h\r
-  CustomizedDisplayLibInternal.c\r
-  CustomizedDisplayLib.uni\r
-  \r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
-  MemoryAllocationLib\r
-  BaseLib\r
-  UefiBootServicesTableLib\r
-  UefiDriverEntryPoint\r
-  UefiRuntimeServicesTableLib\r
-  BaseMemoryLib\r
-  DebugLib\r
-  PrintLib\r
-  HiiLib\r
-  DevicePathLib\r
-  PcdLib\r
-\r
-[Guids]\r
-  gEfiIfrTianoGuid\r
-  \r
-[Protocols]\r
-\r
-[Pcd]\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor               ## CONSUMES\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor                  ## CONSUMES\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextHighlightColor         ## CONSUMES\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldBackgroundHighlightColor   ## CONSUMES
\ No newline at end of file
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni
deleted file mode 100644 (file)
index 18a5c3b..0000000
Binary files a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni and /dev/null differ
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c
deleted file mode 100644 (file)
index b6b4055..0000000
+++ /dev/null
@@ -1,914 +0,0 @@
-/** @file\r
-\r
-  This library class defines a set of interfaces to customize Display module\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#include "CustomizedDisplayLibInternal.h"\r
-\r
-EFI_SCREEN_DESCRIPTOR         gScreenDimensions;\r
-CHAR16                        *mLibUnknownString;\r
-extern EFI_HII_HANDLE         mCDLStringPackHandle;\r
-CHAR16                        *mSpaceBuffer;\r
-#define SPACE_BUFFER_SIZE      1000\r
-\r
-//\r
-// Browser Global Strings\r
-//\r
-CHAR16            *gEnterString;\r
-CHAR16            *gEnterCommitString;\r
-CHAR16            *gEnterEscapeString;\r
-CHAR16            *gEscapeString;\r
-CHAR16            *gMoveHighlight;\r
-CHAR16            *gDecNumericInput;\r
-CHAR16            *gHexNumericInput;\r
-CHAR16            *gToggleCheckBox;\r
-CHAR16            *gLibEmptyString;\r
-CHAR16            *gAreYouSure;\r
-CHAR16            *gYesResponse;\r
-CHAR16            *gNoResponse;\r
-CHAR16            *gPlusString;\r
-CHAR16            *gMinusString;\r
-CHAR16            *gAdjustNumber;\r
-CHAR16            *gSaveChanges;\r
-CHAR16            *gNvUpdateMessage;\r
-CHAR16            *gInputErrorMessage;\r
-\r
-/**\r
-\r
-  Print banner info for front page.\r
-\r
-  @param[in]  FormData             Form Data to be shown in Page\r
-  \r
-**/\r
-VOID\r
-PrintBannerInfo ( \r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  )\r
-{\r
-  UINT8                  Line;\r
-  UINT8                  Alignment;\r
-  CHAR16                 *StrFrontPageBanner;\r
-  UINT8                  RowIdx;\r
-  UINT8                  ColumnIdx;\r
-\r
-  //\r
-  //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);\r
-  //\r
-  ClearLines (\r
-    gScreenDimensions.LeftColumn,\r
-    gScreenDimensions.RightColumn,\r
-    gScreenDimensions.TopRow,\r
-    FRONT_PAGE_HEADER_HEIGHT - 1 + gScreenDimensions.TopRow,\r
-    BANNER_TEXT | BANNER_BACKGROUND\r
-    );\r
-\r
-  //\r
-  //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {\r
-  //\r
-  for (Line = (UINT8) gScreenDimensions.TopRow; Line < BANNER_HEIGHT + (UINT8) gScreenDimensions.TopRow; Line++) {\r
-    //\r
-    //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {\r
-    //\r
-    for (Alignment = (UINT8) gScreenDimensions.LeftColumn;\r
-         Alignment < BANNER_COLUMNS + (UINT8) gScreenDimensions.LeftColumn;\r
-         Alignment++\r
-        ) {\r
-      RowIdx    = (UINT8) (Line - (UINT8) gScreenDimensions.TopRow);\r
-      ColumnIdx = (UINT8) (Alignment - (UINT8) gScreenDimensions.LeftColumn);\r
-  \r
-      ASSERT (RowIdx < BANNER_HEIGHT && ColumnIdx < BANNER_COLUMNS);\r
-  \r
-      if (gBannerData!= NULL && gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {\r
-        StrFrontPageBanner = LibGetToken (gBannerData->Banner[RowIdx][ColumnIdx], FormData->HiiHandle);\r
-      } else {\r
-        continue;\r
-      }\r
-  \r
-      switch (Alignment - gScreenDimensions.LeftColumn) {\r
-      case 0:\r
-        //\r
-        // Handle left column\r
-        //\r
-        PrintStringAt (gScreenDimensions.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);\r
-        break;\r
-  \r
-      case 1:\r
-        //\r
-        // Handle center column\r
-        //\r
-        PrintStringAt (\r
-          gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3,\r
-          Line,\r
-          StrFrontPageBanner\r
-          );\r
-        break;\r
-  \r
-      case 2:\r
-        //\r
-        // Handle right column\r
-        //\r
-        PrintStringAt (\r
-          gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) * 2 / 3,\r
-          Line,\r
-          StrFrontPageBanner\r
-          );\r
-        break;\r
-      }\r
-  \r
-      FreePool (StrFrontPageBanner);\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Print framework and form title for a page.\r
-\r
-  @param[in]  FormData             Form Data to be shown in Page\r
-**/\r
-VOID\r
-PrintFramework (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  )\r
-{\r
-  UINTN                  Index;\r
-  CHAR16                 Character;\r
-  CHAR16                 *Buffer;\r
-  UINTN                  Row;\r
-  CHAR16                 *TitleStr;\r
-\r
-  if (gClassOfVfr != FORMSET_CLASS_PLATFORM_SETUP) {\r
-    //\r
-    // Only Setup page needs Framework\r
-    //\r
-    ClearLines (\r
-      gScreenDimensions.LeftColumn,\r
-      gScreenDimensions.RightColumn,\r
-      gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,\r
-      gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1,\r
-      KEYHELP_TEXT | KEYHELP_BACKGROUND\r
-      );\r
-    return;\r
-  }\r
-    \r
-  Buffer = AllocateZeroPool (0x10000);\r
-  ASSERT (Buffer != NULL);\r
-  Character = BOXDRAW_HORIZONTAL;\r
-  for (Index = 0; Index + 2 < (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn); Index++) {\r
-    Buffer[Index] = Character;\r
-  }\r
-\r
-  //\r
-  // Print Top border line\r
-  // +------------------------------------------------------------------------------+\r
-  // ?                                                                             ?\r
-  // +------------------------------------------------------------------------------+\r
-  //\r
-  gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
-  Character = BOXDRAW_DOWN_RIGHT;\r
-\r
-  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow, Character);\r
-  PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
-\r
-  Character = BOXDRAW_DOWN_LEFT;\r
-  PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
-\r
-  Character = BOXDRAW_VERTICAL;\r
-  for (Row = gScreenDimensions.TopRow + 1; Row <= gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {\r
-    PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);\r
-    PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);\r
-  }\r
-  \r
-  //\r
-  // Print Form Title\r
-  //\r
-  ClearLines (\r
-    gScreenDimensions.LeftColumn + 1,\r
-    gScreenDimensions.RightColumn - 1,\r
-    gScreenDimensions.TopRow + 1,\r
-    gScreenDimensions.TopRow + 1,\r
-    TITLE_TEXT | TITLE_BACKGROUND\r
-    );\r
-\r
-  TitleStr = LibGetToken (FormData->FormTitle, FormData->HiiHandle);\r
-  ASSERT (TitleStr != NULL);\r
-  PrintStringAt (\r
-    (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2,\r
-    gScreenDimensions.TopRow + 1,\r
-    TitleStr\r
-    );\r
-  FreePool (TitleStr);\r
-\r
-  Character = BOXDRAW_UP_RIGHT;\r
-  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);\r
-  PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
-\r
-  Character = BOXDRAW_UP_LEFT;\r
-  PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
-\r
-  //\r
-  // Print Bottom border line\r
-  // +------------------------------------------------------------------------------+\r
-  // ?                                                                             ?\r
-  // +------------------------------------------------------------------------------+\r
-  //\r
-  Character = BOXDRAW_DOWN_RIGHT;\r
-  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);\r
-\r
-  PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
-\r
-  Character = BOXDRAW_DOWN_LEFT;\r
-  PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
-  Character = BOXDRAW_VERTICAL;\r
-  for (Row = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
-       Row <= gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;\r
-       Row++\r
-      ) {\r
-    PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);\r
-    PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);\r
-  }\r
-\r
-  Character = BOXDRAW_UP_RIGHT;\r
-  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1, Character);\r
-\r
-  PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
-\r
-  Character = BOXDRAW_UP_LEFT;\r
-  PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
-  \r
-  FreePool (Buffer);\r
-}\r
-\r
-/**\r
-  Process some op code which is not recognized by browser core.\r
-\r
-  @param OpCodeData                  The pointer to the op code buffer.\r
-\r
-  @return EFI_SUCCESS            Pass the statement success.\r
-\r
-**/\r
-VOID\r
-ProcessUserOpcode(\r
-  IN  EFI_IFR_OP_HEADER         *OpCodeData\r
-  )\r
-{\r
-  switch (OpCodeData->OpCode) {\r
-    case EFI_IFR_GUID_OP:     \r
-      if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)((CHAR8*) OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
-        //\r
-        // Tiano specific GUIDed opcodes\r
-        //\r
-        switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
-        case EFI_IFR_EXTEND_OP_LABEL:\r
-          //\r
-          // just ignore label\r
-          //\r
-          break;\r
-\r
-        case EFI_IFR_EXTEND_OP_BANNER:\r
-          //\r
-          // Only in front page form set, we care about the banner data.\r
-          //\r
-          if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
-            //\r
-            // Initialize Driver private data\r
-            //\r
-            if (gBannerData == NULL) {\r
-              gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));\r
-              ASSERT (gBannerData != NULL);\r
-            }\r
-            \r
-            CopyMem (\r
-              &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
-              ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
-              &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
-              sizeof (EFI_STRING_ID)\r
-              );\r
-          }\r
-          break;\r
-\r
-        case EFI_IFR_EXTEND_OP_SUBCLASS:\r
-          if (((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
-            gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;\r
-          }\r
-          break;\r
-\r
-        default:\r
-          break;\r
-        }\r
-      }\r
-      break;\r
-\r
-    default:\r
-      break;\r
-  }\r
-}\r
-\r
-/**\r
-  Process some op codes which is out side of current form.\r
-  \r
-  @param FormData                Pointer to the form data.\r
-\r
-  @return EFI_SUCCESS            Pass the statement success.\r
-\r
-**/\r
-VOID\r
-ProcessExternedOpcode (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  )\r
-{\r
-  LIST_ENTRY                    *Link;\r
-  FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
-\r
-  Link = GetFirstNode (&FormData->StatementListOSF);\r
-  while (!IsNull (&FormData->StatementListOSF, Link)) {\r
-    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&FormData->StatementListOSF, Link);\r
-\r
-    ProcessUserOpcode(Statement->OpCode);\r
-  }\r
-\r
-  Link = GetFirstNode (&FormData->StatementListHead);\r
-  while (!IsNull (&FormData->StatementListHead, Link)) {\r
-    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&FormData->StatementListHead, Link);\r
-\r
-    ProcessUserOpcode(Statement->OpCode);\r
-  }\r
-}\r
-\r
-/**\r
-  Validate the input screen diemenstion info.\r
-\r
-  @param  FormData               The input form data info.\r
-\r
-  @return EFI_SUCCESS            The input screen info is acceptable.\r
-  @return EFI_INVALID_PARAMETER  The input screen info is not acceptable.\r
-\r
-**/\r
-EFI_STATUS \r
-ScreenDiemensionInfoValidate (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  )\r
-{\r
-  LIST_ENTRY           *Link;\r
-  UINTN                Index;\r
-\r
-  //\r
-  // Calculate total number of Register HotKeys. \r
-  //\r
-  Index = 0;\r
-  if (!IsListEmpty (&FormData->HotKeyListHead)){\r
-    Link  = GetFirstNode (&FormData->HotKeyListHead);\r
-    while (!IsNull (&FormData->HotKeyListHead, Link)) {\r
-      Link = GetNextNode (&FormData->HotKeyListHead, Link);\r
-      Index ++;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Show three HotKeys help information on one row.\r
-  //\r
-  gFooterHeight = FOOTER_HEIGHT + (Index / 3);\r
-\r
-\r
-  ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-  gST->ConOut->QueryMode (\r
-                 gST->ConOut,\r
-                 gST->ConOut->Mode->Mode,\r
-                 &gScreenDimensions.RightColumn,\r
-                 &gScreenDimensions.BottomRow\r
-                 );\r
-\r
-  //\r
-  // Check local dimension vs. global dimension.\r
-  //\r
-  if (FormData->ScreenDimensions != NULL) {\r
-    if ((gScreenDimensions.RightColumn < FormData->ScreenDimensions->RightColumn) ||\r
-        (gScreenDimensions.BottomRow < FormData->ScreenDimensions->BottomRow)\r
-        ) {\r
-      return EFI_INVALID_PARAMETER;\r
-    } else {\r
-      //\r
-      // Local dimension validation.\r
-      //\r
-      if ((FormData->ScreenDimensions->RightColumn > FormData->ScreenDimensions->LeftColumn) &&\r
-          (FormData->ScreenDimensions->BottomRow > FormData->ScreenDimensions->TopRow) &&\r
-          ((FormData->ScreenDimensions->RightColumn - FormData->ScreenDimensions->LeftColumn) > 2) &&\r
-          ((FormData->ScreenDimensions->BottomRow - FormData->ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +\r
-            FRONT_PAGE_HEADER_HEIGHT + gFooterHeight + 3)) {\r
-        CopyMem (&gScreenDimensions, (VOID *) FormData->ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-      } else {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Get the string based on the StringId and HII Package List Handle.\r
-\r
-  @param  Token                  The String's ID.\r
-  @param  HiiHandle              The package list in the HII database to search for\r
-                                 the specified string.\r
-\r
-  @return The output string.\r
-\r
-**/\r
-CHAR16 *\r
-LibGetToken (\r
-  IN  EFI_STRING_ID                Token,\r
-  IN  EFI_HII_HANDLE               HiiHandle\r
-  )\r
-{\r
-  EFI_STRING  String;\r
-\r
-  String = HiiGetString (HiiHandle, Token, NULL);\r
-  if (String == NULL) {\r
-    String = AllocateCopyPool (StrSize (mLibUnknownString), mLibUnknownString);\r
-    ASSERT (String != NULL);\r
-  }\r
-\r
-  return (CHAR16 *) String;\r
-}\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
-LibGetStringWidth (\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
-  Show all registered HotKey help strings on bottom Rows.\r
-\r
-  @param FormData          The curent input form data info.\r
-\r
-**/\r
-VOID\r
-PrintHotKeyHelpString (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *FormData\r
-  )\r
-{\r
-  UINTN                  CurrentCol;\r
-  UINTN                  CurrentRow;\r
-  UINTN                  BottomRowOfHotKeyHelp;\r
-  UINTN                  ColumnWidth;\r
-  UINTN                  Index;\r
-  EFI_SCREEN_DESCRIPTOR  LocalScreen;\r
-  LIST_ENTRY             *Link;\r
-  BROWSER_HOT_KEY        *HotKey;\r
-\r
-  if (IsListEmpty (&FormData->HotKeyListHead)) {\r
-    return;\r
-  }\r
-\r
-  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-  ColumnWidth            = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
-  BottomRowOfHotKeyHelp  = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;\r
-\r
-  //\r
-  // Calculate total number of Register HotKeys. \r
-  //\r
-  Index = 0;\r
-  Link  = GetFirstNode (&FormData->HotKeyListHead);\r
-  while (!IsNull (&FormData->HotKeyListHead, Link)) {\r
-    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
-    //\r
-    // Help string can't exceed ColumnWidth. One Row will show three Help information. \r
-    //\r
-    if (StrLen (HotKey->HelpString) > ColumnWidth) {\r
-      HotKey->HelpString[ColumnWidth] = L'\0';\r
-    }\r
-    //\r
-    // Calculate help information Column and Row.\r
-    //\r
-    if ((Index % 3) != 2) {\r
-      CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;\r
-    } else {\r
-      CurrentCol = LocalScreen.LeftColumn + 2;\r
-    }\r
-    CurrentRow = BottomRowOfHotKeyHelp - Index / 3;\r
-    //\r
-    // Print HotKey help string on bottom Row.\r
-    //\r
-    PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);\r
-\r
-    //\r
-    // Get Next Hot Key.\r
-    //\r
-    Link = GetNextNode (&FormData->HotKeyListHead, Link);\r
-    Index ++;\r
-  }\r
-  \r
-  return;\r
-}\r
-\r
-/**\r
-  Get step info from numeric opcode.\r
-  \r
-  @param[in] OpCode     The input numeric op code.\r
-\r
-  @return step info for this opcode.\r
-**/\r
-UINT64\r
-LibGetFieldFromNum (\r
-  IN  EFI_IFR_OP_HEADER     *OpCode\r
-  )\r
-{\r
-  EFI_IFR_NUMERIC       *NumericOp;\r
-  UINT64                Step;\r
-\r
-  NumericOp = (EFI_IFR_NUMERIC *) OpCode;\r
-  \r
-  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-  case EFI_IFR_NUMERIC_SIZE_1:\r
-    Step    = NumericOp->data.u8.Step;\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_2:\r
-    Step    = NumericOp->data.u16.Step;\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_4:\r
-    Step    = NumericOp->data.u32.Step;\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_8:\r
-    Step    = NumericOp->data.u64.Step;\r
-    break;\r
-  \r
-  default:\r
-    Step = 0;\r
-    break;\r
-  }\r
-\r
-  return Step;\r
-}\r
-\r
-/**\r
-  Initialize the HII String Token to the correct values.\r
-\r
-**/\r
-VOID\r
-InitializeLibStrings (\r
-  VOID\r
-  )\r
-{\r
-  mLibUnknownString        = L"!";\r
-\r
-  gEnterString          = LibGetToken (STRING_TOKEN (ENTER_STRING), mCDLStringPackHandle);\r
-  gEnterCommitString    = LibGetToken (STRING_TOKEN (ENTER_COMMIT_STRING), mCDLStringPackHandle);\r
-  gEnterEscapeString    = LibGetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), mCDLStringPackHandle);\r
-  gEscapeString         = LibGetToken (STRING_TOKEN (ESCAPE_STRING), mCDLStringPackHandle);\r
-  gMoveHighlight        = LibGetToken (STRING_TOKEN (MOVE_HIGHLIGHT), mCDLStringPackHandle);\r
-  gDecNumericInput      = LibGetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), mCDLStringPackHandle);\r
-  gHexNumericInput      = LibGetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), mCDLStringPackHandle);\r
-  gToggleCheckBox       = LibGetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), mCDLStringPackHandle);\r
-\r
-  gAreYouSure           = LibGetToken (STRING_TOKEN (ARE_YOU_SURE), mCDLStringPackHandle);\r
-  gYesResponse          = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_YES), mCDLStringPackHandle);\r
-  gNoResponse           = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_NO), mCDLStringPackHandle);\r
-  gPlusString           = LibGetToken (STRING_TOKEN (PLUS_STRING), mCDLStringPackHandle);\r
-  gMinusString          = LibGetToken (STRING_TOKEN (MINUS_STRING), mCDLStringPackHandle);\r
-  gAdjustNumber         = LibGetToken (STRING_TOKEN (ADJUST_NUMBER), mCDLStringPackHandle);\r
-  gSaveChanges          = LibGetToken (STRING_TOKEN (SAVE_CHANGES), mCDLStringPackHandle);\r
-\r
-  gLibEmptyString       = LibGetToken (STRING_TOKEN (EMPTY_STRING), mCDLStringPackHandle);\r
-\r
-  gNvUpdateMessage      = LibGetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), mCDLStringPackHandle);\r
-  gInputErrorMessage    = LibGetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), mCDLStringPackHandle);\r
-  \r
-  //\r
-  // SpaceBuffer;\r
-  //\r
-  mSpaceBuffer = AllocatePool ((SPACE_BUFFER_SIZE + 1) * sizeof (CHAR16));\r
-  ASSERT (mSpaceBuffer != NULL);\r
-  LibSetUnicodeMem (mSpaceBuffer, SPACE_BUFFER_SIZE, L' ');\r
-  mSpaceBuffer[SPACE_BUFFER_SIZE] = L'\0';\r
-}\r
-\r
-\r
-/**\r
-  Free the HII String.\r
-\r
-**/\r
-VOID\r
-FreeLibStrings (\r
-  VOID\r
-  )\r
-{\r
-  FreePool (gEnterString);\r
-  FreePool (gEnterCommitString);\r
-  FreePool (gEnterEscapeString);\r
-  FreePool (gEscapeString);\r
-  FreePool (gMoveHighlight);\r
-  FreePool (gDecNumericInput);\r
-  FreePool (gHexNumericInput);\r
-  FreePool (gToggleCheckBox);\r
-\r
-  FreePool (gAreYouSure);\r
-  FreePool (gYesResponse);\r
-  FreePool (gNoResponse);\r
-  FreePool (gPlusString);\r
-  FreePool (gMinusString);\r
-  FreePool (gAdjustNumber);\r
-  FreePool (gSaveChanges);\r
-\r
-  FreePool (gLibEmptyString);\r
-\r
-  FreePool (gNvUpdateMessage);\r
-  FreePool (gInputErrorMessage);\r
-  \r
-  FreePool (mSpaceBuffer);\r
-}\r
-\r
-/**\r
-  Wait for a key to be pressed by user.\r
-\r
-  @param Key         The key which is pressed by user.\r
-\r
-  @retval EFI_SUCCESS The function always completed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForKeyStroke (\r
-  OUT  EFI_INPUT_KEY           *Key\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       Index;\r
-\r
-  while (TRUE) {\r
-    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);\r
-    if (!EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-\r
-    if (Status != EFI_NOT_READY) {\r
-      continue;\r
-    }\r
-    \r
-    gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);\r
-  }\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Set Buffer to Value for Size bytes.\r
-\r
-  @param  Buffer                 Memory to set.\r
-  @param  Size                   Number of bytes to set\r
-  @param  Value                  Value of the set operation.\r
-\r
-**/\r
-VOID\r
-LibSetUnicodeMem (\r
-  IN VOID   *Buffer,\r
-  IN UINTN  Size,\r
-  IN CHAR16 Value\r
-  )\r
-{\r
-  CHAR16  *Ptr;\r
-\r
-  Ptr = Buffer;\r
-  while ((Size--)  != 0) {\r
-    *(Ptr++) = Value;\r
-  }\r
-}\r
-\r
-/**\r
-  The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
-  protocol instance.\r
-\r
-  @param Width           Width of string to be print.\r
-  @param Column          The position of the output string.\r
-  @param Row             The position of the output string.\r
-  @param Out             The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.\r
-  @param Fmt             The format string.\r
-  @param Args            The additional argument for the variables in the format string.\r
-\r
-  @return Number of Unicode character printed.\r
-\r
-**/\r
-UINTN\r
-PrintInternal (\r
-  IN UINTN                            Width, \r
-  IN UINTN                            Column,\r
-  IN UINTN                            Row,\r
-  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Out,\r
-  IN CHAR16                           *Fmt,\r
-  IN VA_LIST                          Args\r
-  )\r
-{\r
-  CHAR16  *Buffer;\r
-  CHAR16  *BackupBuffer;\r
-  UINTN   Index;\r
-  UINTN   PreviousIndex;\r
-  UINTN   Count;\r
-  UINTN   PrintWidth;\r
-  UINTN   CharWidth;\r
-\r
-  //\r
-  // For now, allocate an arbitrarily long buffer\r
-  //\r
-  Buffer        = AllocateZeroPool (0x10000);\r
-  BackupBuffer  = AllocateZeroPool (0x10000);\r
-  ASSERT (Buffer);\r
-  ASSERT (BackupBuffer);\r
-\r
-  if (Column != (UINTN) -1) {\r
-    Out->SetCursorPosition (Out, Column, Row);\r
-  }\r
-\r
-  UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);\r
-\r
-  Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
-\r
-  Out->SetAttribute (Out, Out->Mode->Attribute);\r
-\r
-  Index         = 0;\r
-  PreviousIndex = 0;\r
-  Count         = 0;\r
-  PrintWidth    = 0;\r
-  CharWidth     = 1;\r
-\r
-  do {\r
-    for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {\r
-      BackupBuffer[Index] = Buffer[Index];\r
-    }\r
-\r
-    if (Buffer[Index] == 0) {\r
-      break;\r
-    }\r
-    //\r
-    // Null-terminate the temporary string\r
-    //\r
-    BackupBuffer[Index] = 0;\r
-\r
-    //\r
-    // Print this out, we are about to switch widths\r
-    //\r
-    Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
-    Count += StrLen (&BackupBuffer[PreviousIndex]);\r
-    PrintWidth += Count * CharWidth;\r
-\r
-    //\r
-    // Preserve the current index + 1, since this is where we will start printing from next\r
-    //\r
-    PreviousIndex = Index + 1;\r
-\r
-    //\r
-    // We are at a narrow or wide character directive.  Set attributes and strip it and print it\r
-    //\r
-    if (Buffer[Index] == NARROW_CHAR) {\r
-      //\r
-      // Preserve bits 0 - 6 and zero out the rest\r
-      //\r
-      Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
-      Out->SetAttribute (Out, Out->Mode->Attribute);\r
-      CharWidth = 1;\r
-    } else {\r
-      //\r
-      // Must be wide, set bit 7 ON\r
-      //\r
-      Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;\r
-      Out->SetAttribute (Out, Out->Mode->Attribute);\r
-      CharWidth = 2;\r
-    }\r
-\r
-    Index++;\r
-\r
-  } while (Buffer[Index] != 0);\r
-\r
-  //\r
-  // We hit the end of the string - print it\r
-  //\r
-  Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
-  Count += StrLen (&BackupBuffer[PreviousIndex]);\r
-  PrintWidth += Count * CharWidth;\r
-  if (PrintWidth < Width) {\r
-    Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
-    Out->SetAttribute (Out, Out->Mode->Attribute);\r
-    Out->OutputString (Out, &mSpaceBuffer[SPACE_BUFFER_SIZE - Width + PrintWidth]);\r
-  }\r
-\r
-  FreePool (Buffer);\r
-  FreePool (BackupBuffer);\r
-  return Count;\r
-}\r
-\r
-/**\r
-  Prints a formatted unicode string to the default console, at\r
-  the supplied cursor position.\r
-\r
-  @param  Width      Width of String to be printed.\r
-  @param  Column     The cursor position to print the string at.\r
-  @param  Row        The cursor position to print the string at.\r
-  @param  Fmt        Format string.\r
-  @param  ...        Variable argument list for format string.\r
-\r
-  @return Length of string printed to the console\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintAt (\r
-  IN UINTN     Width,\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  IN CHAR16    *Fmt,\r
-  ...\r
-  )\r
-{\r
-  VA_LIST Args;\r
-  UINTN   LengthOfPrinted;\r
-\r
-  VA_START (Args, Fmt);\r
-  LengthOfPrinted = PrintInternal (Width, Column, Row, gST->ConOut, Fmt, Args);\r
-  VA_END (Args);\r
-  return LengthOfPrinted;\r
-}\r
-\r
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h
deleted file mode 100644 (file)
index ccbd45f..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/** @file\r
-\r
-  This library class defines a set of interfaces to customize Display module\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#ifndef __CUSTOMIZED_DISPLAY_LIB_INTERNAL_H__\r
-#define __CUSTOMIZED_DISPLAY_LIB_INTERNAL_H__\r
-\r
-\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Protocol/SimpleTextOut.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/FormBrowser2.h>\r
-#include <Protocol/FormBrowserEx2.h>\r
-#include <Protocol/DisplayProtocol.h>\r
-#include <Protocol/DevicePath.h>\r
-#include <Protocol/UnicodeCollation.h>\r
-#include <Protocol/HiiConfigAccess.h>\r
-#include <Protocol/HiiConfigRouting.h>\r
-#include <Protocol/HiiDatabase.h>\r
-#include <Protocol/HiiString.h>\r
-#include <Protocol/UserManager.h>\r
-#include <Protocol/DevicePathFromText.h>\r
-\r
-#include <Guid/MdeModuleHii.h>\r
-#include <Guid/HiiPlatformSetupFormset.h>\r
-#include <Guid/HiiFormMapMethodGuid.h>\r
-\r
-#include <Library/PrintLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/HiiLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/CustomizedDisplayLib.h>\r
-\r
-#include "Colors.h"\r
-\r
-\r
-\r
-#define FORMSET_CLASS_PLATFORM_SETUP         0x0001\r
-#define FORMSET_CLASS_FRONT_PAGE             0x0002\r
-\r
-\r
-#define FRONT_PAGE_HEADER_HEIGHT      6\r
-#define NONE_FRONT_PAGE_HEADER_HEIGHT 3\r
-#define FOOTER_HEIGHT                 4\r
-#define STATUS_BAR_HEIGHT             1\r
-\r
-//\r
-// Screen definitions\r
-//\r
-#define BANNER_HEIGHT                 6\r
-#define BANNER_COLUMNS                3\r
-#define BANNER_LEFT_COLUMN_INDENT     1\r
-\r
-//\r
-// Character definitions\r
-//\r
-#define UPPER_LOWER_CASE_OFFSET 0x20\r
-\r
-//\r
-// This is the Input Error Message\r
-//\r
-#define INPUT_ERROR 1\r
-\r
-//\r
-// This is the NV RAM update required Message\r
-//\r
-#define NV_UPDATE_REQUIRED  2\r
-\r
-typedef struct {\r
-  EFI_STRING_ID  Banner[BANNER_HEIGHT][BANNER_COLUMNS];\r
-} BANNER_DATA;\r
-\r
-extern  UINT16                        gClassOfVfr;                 // Formset class information\r
-extern  BANNER_DATA                   *gBannerData;\r
-extern  EFI_SCREEN_DESCRIPTOR         gScreenDimensions;\r
-extern  UINTN                         gFooterHeight;\r
-\r
-//\r
-// Browser Global Strings\r
-//\r
-extern CHAR16            *gEnterString;\r
-extern CHAR16            *gEnterCommitString;\r
-extern CHAR16            *gEnterEscapeString;\r
-extern CHAR16            *gEscapeString;\r
-extern CHAR16            *gMoveHighlight;\r
-extern CHAR16            *gDecNumericInput;\r
-extern CHAR16            *gHexNumericInput;\r
-extern CHAR16            *gToggleCheckBox;\r
-extern CHAR16            *gLibEmptyString;\r
-extern CHAR16            *gAreYouSure;\r
-extern CHAR16            *gYesResponse;\r
-extern CHAR16            *gNoResponse;\r
-extern CHAR16            *gPlusString;\r
-extern CHAR16            *gMinusString;\r
-extern CHAR16            *gAdjustNumber;\r
-extern CHAR16            *gSaveChanges;\r
-extern CHAR16            *gNvUpdateMessage;\r
-extern CHAR16            *gInputErrorMessage;\r
-/**\r
-\r
-  Print banner info for front page.\r
-\r
-  @param[in]  FormData             Form Data to be shown in Page\r
-  \r
-**/\r
-VOID\r
-PrintBannerInfo ( \r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  );\r
-\r
-/**\r
-  Print framework and form title for a page.\r
-\r
-  @param[in]  FormData             Form Data to be shown in Page\r
-**/\r
-VOID\r
-PrintFramework (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  );\r
-\r
-/**\r
-  Validate the input screen diemenstion info.\r
-\r
-  @param  FormData               The input form data info.\r
-\r
-  @return EFI_SUCCESS            The input screen info is acceptable.\r
-  @return EFI_INVALID_PARAMETER  The input screen info is not acceptable.\r
-\r
-**/\r
-EFI_STATUS \r
-ScreenDiemensionInfoValidate (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  );\r
-\r
-/**\r
-  Get the string based on the StringId and HII Package List Handle.\r
-\r
-  @param  Token                  The String's ID.\r
-  @param  HiiHandle              The package list in the HII database to search for\r
-                                 the specified string.\r
-\r
-  @return The output string.\r
-\r
-**/\r
-CHAR16 *\r
-LibGetToken (\r
-  IN  EFI_STRING_ID                Token,\r
-  IN  EFI_HII_HANDLE               HiiHandle\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
-LibGetStringWidth (\r
-  IN CHAR16               *String\r
-  );\r
-\r
-/**\r
-  Show all registered HotKey help strings on bottom Rows.\r
-\r
-  @param FormData          The curent input form data info.\r
-\r
-**/\r
-VOID\r
-PrintHotKeyHelpString (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *FormData\r
-  );\r
-  \r
-/**\r
-  Get step info from numeric opcode.\r
-  \r
-  @param[in] OpCode     The input numeric op code.\r
-\r
-  @return step info for this opcode.\r
-**/\r
-UINT64\r
-LibGetFieldFromNum (\r
-  IN  EFI_IFR_OP_HEADER     *OpCode\r
-  );\r
-\r
-/**\r
-  Initialize the HII String Token to the correct values.\r
-\r
-**/\r
-VOID\r
-InitializeLibStrings (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Free the HII String.\r
-\r
-**/\r
-VOID\r
-FreeLibStrings (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Wait for a key to be pressed by user.\r
-\r
-  @param Key         The key which is pressed by user.\r
-\r
-  @retval EFI_SUCCESS The function always completed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForKeyStroke (\r
-  OUT  EFI_INPUT_KEY           *Key\r
-  );\r
-\r
-/**\r
-  Set Buffer to Value for Size bytes.\r
-\r
-  @param  Buffer                 Memory to set.\r
-  @param  Size                   Number of bytes to set\r
-  @param  Value                  Value of the set operation.\r
-\r
-**/\r
-VOID\r
-LibSetUnicodeMem (\r
-  IN VOID   *Buffer,\r
-  IN UINTN  Size,\r
-  IN CHAR16 Value\r
-  );\r
-\r
-/**\r
-  Prints a formatted unicode string to the default console, at\r
-  the supplied cursor position.\r
-\r
-  @param  Width      Width of String to be printed.\r
-  @param  Column     The cursor position to print the string at.\r
-  @param  Row        The cursor position to print the string at.\r
-  @param  Fmt        Format string.\r
-  @param  ...        Variable argument list for format string.\r
-\r
-  @return Length of string printed to the console\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-PrintAt (\r
-  IN UINTN     Width,\r
-  IN UINTN     Column,\r
-  IN UINTN     Row,\r
-  IN CHAR16    *Fmt,\r
-  ...\r
-  );\r
-\r
-/**\r
-  Process some op codes which is out side of current form.\r
-  \r
-  @param FormData                Pointer to the form data.\r
-\r
-**/\r
-VOID\r
-ProcessExternedOpcode (\r
-  IN FORM_DISPLAY_ENGINE_FORM       *FormData\r
-  );\r
-\r
-#endif\r
index 4ae24eb80ee86563689e5b52243816ae0e6314c6..31055192973ea8179645fbff4757770d0808ce80 100644 (file)
   #\r
   CpuExceptionHandlerLib|Include/Library/CpuExceptionHandlerLib.h\r
   \r
   #\r
   CpuExceptionHandlerLib|Include/Library/CpuExceptionHandlerLib.h\r
   \r
-  ##  @libraryclass    Provides platform specific display interface.\r
-  #\r
-  CustomizedDisplayLib|Include/Library/CustomizedDisplayLib.h\r
-\r
 [Guids]\r
   ## MdeModule package token space guid\r
   # Include/Guid/MdeModulePkgTokenSpace.h\r
 [Guids]\r
   ## MdeModule package token space guid\r
   # Include/Guid/MdeModulePkgTokenSpace.h\r
   ## Include/Protocol/BootLogo.h\r
   gEfiBootLogoProtocolGuid = { 0xcdea2bd3, 0xfc25, 0x4c1c, { 0xb9, 0x7c, 0xb3, 0x11, 0x86, 0x6, 0x49, 0x90 } }\r
 \r
   ## Include/Protocol/BootLogo.h\r
   gEfiBootLogoProtocolGuid = { 0xcdea2bd3, 0xfc25, 0x4c1c, { 0xb9, 0x7c, 0xb3, 0x11, 0x86, 0x6, 0x49, 0x90 } }\r
 \r
-  ## Include/Protocol/DisplayProtocol.h\r
-  gEdkiiFormDisplayEngineProtocolGuid = { 0x9bbe29e9, 0xfda1, 0x41ec, { 0xad, 0x52, 0x45, 0x22, 0x13, 0x74, 0x2d, 0x2e } }\r
-\r
-  ## Include/Protocol/FormBrowserEx2.h\r
-  gEdkiiFormBrowserEx2ProtocolGuid = { 0xa770c357, 0xb693, 0x4e6d, { 0xa6, 0xcf, 0xd2, 0x1c, 0x72, 0x8e, 0x55, 0xb } }\r
-\r
 [PcdsFeatureFlag]\r
   ## Indicate whether platform can support update capsule across a system reset\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE|BOOLEAN|0x0001001d\r
 [PcdsFeatureFlag]\r
   ## Indicate whether platform can support update capsule across a system reset\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE|BOOLEAN|0x0001001d\r
index 7895834c245fc90b10bfa47427bb8b63c78d5cce..781fbbf3b45a88b9a5003fdbbca6986ffb3688e5 100644 (file)
@@ -76,7 +76,6 @@
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   PalLib|MdePkg/Library/BasePalLibNull/BasePalLibNull.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   PalLib|MdePkg/Library/BasePalLibNull/BasePalLibNull.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   #\r
   # Misc\r
   #\r
   #\r
   # Misc\r
   #\r
 \r
   MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 \r
   MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
   MdeModulePkg/Application/VariableInfo/VariableInfo.inf\r
   MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf\r
   MdeModulePkg/Universal/Variable/Pei/VariablePei.inf\r
   MdeModulePkg/Application/VariableInfo/VariableInfo.inf\r
   MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf\r
   MdeModulePkg/Universal/Variable/Pei/VariablePei.inf\r
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
deleted file mode 100644 (file)
index 323fcad..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-## @file\r
-# The DXE driver produces FORM BROWSER protocols defined in UEFI HII 2.1 specificatin.\r
-#\r
-# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
-#\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
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = DisplayEngine\r
-  FILE_GUID                      = E660EA85-058E-4b55-A54B-F02F83A24707\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  ENTRY_POINT                    = InitializeDisplayEngine\r
-  UNLOAD_IMAGE                   = UnloadDisplayEngine\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources]\r
-  FormDisplayStr.uni\r
-  FormDisplay.c\r
-  FormDisplay.h\r
-  ProcessOptions.c\r
-  InputHandler.c\r
-  \r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-  \r
-[LibraryClasses]\r
-  UefiDriverEntryPoint\r
-  UefiBootServicesTableLib\r
-  DebugLib\r
-  BaseMemoryLib\r
-  BaseLib\r
-  PrintLib\r
-  HiiLib\r
-  MemoryAllocationLib\r
-  CustomizedDisplayLib\r
-\r
-[Protocols]\r
-  gEdkiiFormDisplayEngineProtocolGuid\r
-  gEdkiiFormBrowserEx2ProtocolGuid\r
-\r
-[Guids]\r
-  gEfiIfrTianoGuid                              ## CONSUMES  ## GUID  \r
-  \r
-[Depex]\r
-  gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid AND gEdkiiFormBrowserEx2ProtocolGuid\r
-  \r
-[FeaturePcd]\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement            ## CONSUMES\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu              ## CONSUMES\r
-\r
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
deleted file mode 100644 (file)
index a07cc75..0000000
+++ /dev/null
@@ -1,3255 +0,0 @@
-/** @file\r
-Entry and initialization module for the browser.\r
-\r
-Copyright (c) 2007 - 2013, 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 "FormDisplay.h"\r
-\r
-//\r
-// Search table for UiDisplayMenu()\r
-//\r
-SCAN_CODE_TO_SCREEN_OPERATION     gScanCodeToOperation[] = {\r
-  {\r
-    SCAN_UP,\r
-    UiUp,\r
-  },\r
-  {\r
-    SCAN_DOWN,\r
-    UiDown,\r
-  },\r
-  {\r
-    SCAN_PAGE_UP,\r
-    UiPageUp,\r
-  },\r
-  {\r
-    SCAN_PAGE_DOWN,\r
-    UiPageDown,\r
-  },\r
-  {\r
-    SCAN_ESC,\r
-    UiReset,\r
-  },\r
-  {\r
-    SCAN_LEFT,\r
-    UiLeft,\r
-  },\r
-  {\r
-    SCAN_RIGHT,\r
-    UiRight,\r
-  }\r
-};\r
-\r
-UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);\r
-\r
-SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {\r
-  {\r
-    UiNoOperation,\r
-    CfUiNoOperation,\r
-  },\r
-  {\r
-    UiSelect,\r
-    CfUiSelect,\r
-  },\r
-  {\r
-    UiUp,\r
-    CfUiUp,\r
-  },\r
-  {\r
-    UiDown,\r
-    CfUiDown,\r
-  },\r
-  {\r
-    UiLeft,\r
-    CfUiLeft,\r
-  },\r
-  {\r
-    UiRight,\r
-    CfUiRight,\r
-  },\r
-  {\r
-    UiReset,\r
-    CfUiReset,\r
-  },\r
-  {\r
-    UiPageUp,\r
-    CfUiPageUp,\r
-  },\r
-  {\r
-    UiPageDown,\r
-    CfUiPageDown\r
-  }, \r
-  {\r
-    UiHotKey,\r
-    CfUiHotKey\r
-  }\r
-};\r
-\r
-EFI_GUID  gDisplayEngineGuid = {\r
-  0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}\r
-};\r
-\r
-FORM_ENTRY_INFO               gFormEntryInfo;\r
-UINTN                         gSequence;\r
-EFI_SCREEN_DESCRIPTOR         gStatementDimensions;\r
-BOOLEAN                       mStatementLayoutIsChanged = TRUE;\r
-USER_INPUT                    *gUserInput;\r
-FORM_DISPLAY_ENGINE_FORM      *gFormData;\r
-EFI_HII_HANDLE                gHiiHandle;\r
-UINT16                        gDirection;\r
-LIST_ENTRY                    gMenuOption;\r
-DISPLAY_HIGHLIGHT_MENU_INFO   gHighligthMenuInfo = {0};\r
-BOOLEAN                       mIsFirstForm = TRUE;\r
-FORM_ENTRY_INFO               gOldFormEntry = {0};\r
-\r
-//\r
-// Browser Global Strings\r
-//\r
-CHAR16            *gFormNotFound;\r
-CHAR16            *gNoSubmitIf;\r
-CHAR16            *gBrwoserError;\r
-CHAR16            *gSaveFailed;\r
-CHAR16            *gPromptForData;\r
-CHAR16            *gPromptForPassword;\r
-CHAR16            *gPromptForNewPassword;\r
-CHAR16            *gConfirmPassword;\r
-CHAR16            *gConfirmError;\r
-CHAR16            *gPassowordInvalid;\r
-CHAR16            *gPressEnter;\r
-CHAR16            *gEmptyString;\r
-CHAR16            *gMiniString;\r
-CHAR16            *gOptionMismatch;\r
-CHAR16            *gFormSuppress;\r
-CHAR16            *gProtocolNotFound;\r
-\r
-CHAR16            gPromptBlockWidth;\r
-CHAR16            gOptionBlockWidth;\r
-CHAR16            gHelpBlockWidth;\r
-CHAR16            *mUnknownString;\r
-\r
-FORM_DISPLAY_DRIVER_PRIVATE_DATA  mPrivateData = {\r
-  FORM_DISPLAY_DRIVER_SIGNATURE,\r
-  NULL,\r
-  {\r
-    FormDisplay,\r
-    DriverClearDisplayPage,\r
-    ConfirmDataChange\r
-  }\r
-};\r
-\r
-\r
-/**\r
-  Get the string based on the StringId and HII Package List Handle.\r
-\r
-  @param  Token                  The String's ID.\r
-  @param  HiiHandle              The package list in the HII database to search for\r
-                                 the specified string.\r
-\r
-  @return The output string.\r
-\r
-**/\r
-CHAR16 *\r
-GetToken (\r
-  IN  EFI_STRING_ID                Token,\r
-  IN  EFI_HII_HANDLE               HiiHandle\r
-  )\r
-{\r
-  EFI_STRING  String;\r
-\r
-  String = HiiGetString (HiiHandle, Token, NULL);\r
-  if (String == NULL) {\r
-    String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);\r
-    ASSERT (String != NULL);\r
-  }\r
-\r
-  return (CHAR16 *) String;\r
-}\r
-\r
-\r
-/**\r
-  Initialize the HII String Token to the correct values.\r
-\r
-**/\r
-VOID\r
-InitializeDisplayStrings (\r
-  VOID\r
-  )\r
-{\r
-  mUnknownString        = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);\r
-  gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), 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
-  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);\r
-  gOptionMismatch       = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);\r
-  gFormSuppress         = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);\r
-  gProtocolNotFound     = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);\r
-  gFormNotFound         = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);\r
-  gNoSubmitIf           = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);\r
-  gBrwoserError         = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);\r
-}\r
-\r
-/**\r
-  Free up the resource allocated for all strings required\r
-  by Setup Browser.\r
-\r
-**/\r
-VOID\r
-FreeDisplayStrings (\r
-  VOID\r
-  )\r
-{\r
-  FreePool (mUnknownString);\r
-  FreePool (gEmptyString);\r
-  FreePool (gSaveFailed);\r
-  FreePool (gPromptForData);\r
-  FreePool (gPromptForPassword);\r
-  FreePool (gPromptForNewPassword);\r
-  FreePool (gConfirmPassword);\r
-  FreePool (gConfirmError);\r
-  FreePool (gPassowordInvalid);\r
-  FreePool (gPressEnter);\r
-  FreePool (gMiniString);\r
-  FreePool (gOptionMismatch);\r
-  FreePool (gFormSuppress);\r
-  FreePool (gProtocolNotFound);\r
-  FreePool (gBrwoserError);\r
-  FreePool (gNoSubmitIf);\r
-  FreePool (gFormNotFound);\r
-}\r
-\r
-/**\r
-  Get prompt string id from the opcode data buffer.\r
-\r
-  @param  OpCode                 The input opcode buffer.\r
-\r
-  @return The prompt string id.\r
-\r
-**/\r
-EFI_STRING_ID\r
-GetPrompt (\r
-  IN EFI_IFR_OP_HEADER     *OpCode\r
-  )\r
-{\r
-  EFI_IFR_STATEMENT_HEADER  *Header;\r
-\r
-  if (OpCode->Length <= sizeof (EFI_IFR_OP_HEADER)) {\r
-    return 0;\r
-  }\r
-\r
-  Header = (EFI_IFR_STATEMENT_HEADER  *) (OpCode + 1);\r
-\r
-  return Header->Prompt;\r
-}\r
-\r
-/**\r
-  Get the supported width for a particular op-code\r
-\r
-  @param  Statement              The curent statement.\r
-\r
-  @return Returns the number of CHAR16 characters that is support.\r
-\r
-**/\r
-UINT16\r
-GetWidth (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT        *Statement\r
-  )\r
-{\r
-  CHAR16       *String;\r
-  UINTN        Size;\r
-  UINT16       Width;\r
-  EFI_IFR_TEXT *TestOp;\r
-\r
-  Size = 0;\r
-\r
-  //\r
-  // See if the second text parameter is really NULL\r
-  //\r
-  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {\r
-    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;\r
-    if (TestOp->TextTwo != 0) {\r
-      String = GetToken (TestOp->TextTwo, gFormData->HiiHandle);\r
-      Size   = StrLen (String);\r
-      FreePool (String);\r
-    }\r
-  }\r
-\r
-  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||\r
-      (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||\r
-      (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||\r
-      (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||\r
-      (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||\r
-      //\r
-      // Allow a wide display if text op-code and no secondary text op-code\r
-      //\r
-      ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))\r
-      ) {\r
-    Width = (UINT16) (gPromptBlockWidth + gOptionBlockWidth);\r
-  } else {\r
-    Width = (UINT16) gPromptBlockWidth;\r
-  }\r
-\r
-  return (UINT16) (Width - LEFT_SKIPPED_COLUMNS);\r
-}\r
-\r
-/**\r
-  Will copy LineWidth amount of a string in the OutputString buffer and return the\r
-  number of CHAR16 characters that were copied into the OutputString buffer.\r
-  The output string format is:\r
-    Glyph Info + String info + '\0'.\r
-\r
-  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.\r
-\r
-  @param  InputString            String description for this option.\r
-  @param  LineWidth              Width of the desired string to extract in CHAR16\r
-                                 characters\r
-  @param  GlyphWidth             The glyph width of the begin of the char in the string.\r
-  @param  Index                  Where in InputString to start the copy process\r
-  @param  OutputString           Buffer to copy the string into\r
-\r
-  @return Returns the number of CHAR16 characters that were copied into the OutputString \r
-  buffer, include extra glyph info and '\0' info.\r
-\r
-**/\r
-UINT16\r
-GetLineByWidth (\r
-  IN      CHAR16                      *InputString,\r
-  IN      UINT16                      LineWidth,\r
-  IN OUT  UINT16                      *GlyphWidth,\r
-  IN OUT  UINTN                       *Index,\r
-  OUT     CHAR16                      **OutputString\r
-  )\r
-{\r
-  UINT16          StrOffset;\r
-  UINT16          GlyphOffset;\r
-  UINT16          OriginalGlyphWidth;\r
-  BOOLEAN         ReturnFlag;\r
-  UINT16          LastSpaceOffset;\r
-  UINT16          LastGlyphWidth;\r
-\r
-  if (InputString == NULL || Index == NULL || OutputString == NULL) {\r
-    return 0;\r
-  }\r
-\r
-  if (LineWidth == 0 || *GlyphWidth == 0) {\r
-    return 0;\r
-  }\r
-\r
-  //\r
-  // Save original glyph width.\r
-  //\r
-  OriginalGlyphWidth = *GlyphWidth;\r
-  LastGlyphWidth     = OriginalGlyphWidth;\r
-  ReturnFlag         = FALSE;\r
-  LastSpaceOffset    = 0;\r
-\r
-  //\r
-  // NARROW_CHAR can not be printed in screen, so if a line only contain  the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line  in Screen.\r
-  // To avoid displaying this  empty line in screen,  just skip  the two CHARs here.\r
-  //\r
-  if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {\r
-    *Index = *Index + 2;\r
-  }\r
-\r
-  //\r
-  // Fast-forward the string and see if there is a carriage-return in the string\r
-  //\r
-  for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {\r
-    switch (InputString[*Index + StrOffset]) {\r
-      case NARROW_CHAR:\r
-        *GlyphWidth = 1;\r
-        break;\r
-\r
-      case WIDE_CHAR:\r
-        *GlyphWidth = 2;\r
-        break;\r
-\r
-      case CHAR_CARRIAGE_RETURN:\r
-      case CHAR_LINEFEED:\r
-      case CHAR_NULL:\r
-        ReturnFlag = TRUE;\r
-        break;\r
-\r
-      default:\r
-        GlyphOffset = GlyphOffset + *GlyphWidth;\r
-\r
-        //\r
-        // Record the last space info in this line. Will be used in rewind.\r
-        //\r
-        if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {\r
-          LastSpaceOffset = StrOffset;\r
-          LastGlyphWidth  = *GlyphWidth;\r
-        }\r
-        break;\r
-    }\r
-\r
-    if (ReturnFlag) {\r
-      break;\r
-    }\r
-  } \r
-\r
-  //\r
-  // Rewind the string from the maximum size until we see a space to break the line\r
-  //\r
-  if (GlyphOffset > LineWidth) {\r
-    //\r
-    // Rewind the string to last space char in this line.\r
-    //\r
-    if (LastSpaceOffset != 0) {\r
-      StrOffset   = LastSpaceOffset;\r
-      *GlyphWidth = LastGlyphWidth;\r
-    } else {\r
-      //\r
-      // Roll back to last char in the line width.\r
-      //\r
-      StrOffset--;\r
-    }\r
-  }\r
-\r
-  //\r
-  // The CHAR_NULL has process last time, this time just return 0 to stand for the end.\r
-  //\r
-  if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {\r
-    return 0;\r
-  }\r
-\r
-  //\r
-  // Need extra glyph info and '\0' info, so +2.\r
-  //\r
-  *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));\r
-  if (*OutputString == NULL) {\r
-    return 0;\r
-  }\r
-\r
-  //\r
-  // Save the glyph info at the begin of the string, will used by Print function.\r
-  //\r
-  if (OriginalGlyphWidth == 1) {\r
-    *(*OutputString) = NARROW_CHAR;\r
-  } else  {\r
-    *(*OutputString) = WIDE_CHAR;\r
-  }\r
-\r
-  CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));\r
-\r
-  if (InputString[*Index + StrOffset] == CHAR_SPACE) {\r
-    //\r
-    // Skip the space info at the begin of next line.\r
-    //  \r
-    *Index = (UINT16) (*Index + StrOffset + 1);\r
-  } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {\r
-    //\r
-    // Skip the /n or /n/r info.\r
-    //\r
-    if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {\r
-      *Index = (UINT16) (*Index + StrOffset + 2);\r
-    } else {\r
-      *Index = (UINT16) (*Index + StrOffset + 1);\r
-    }\r
-  } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {\r
-    //\r
-    // Skip the /r or /r/n info.\r
-    //  \r
-    if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {\r
-      *Index = (UINT16) (*Index + StrOffset + 2);\r
-    } else {\r
-      *Index = (UINT16) (*Index + StrOffset + 1);\r
-    }\r
-  } else {\r
-    *Index = (UINT16) (*Index + StrOffset);\r
-  }\r
-\r
-  //\r
-  // Include extra glyph info and '\0' info, so +2.\r
-  //\r
-  return StrOffset + 2;\r
-}\r
-\r
-/**\r
-  Add one menu option by specified description and context.\r
-\r
-  @param  Statement              Statement of this Menu Option.\r
-  @param  MenuItemCount          The index for this Option in the Menu.\r
-  @param  NestIn                 Whether this statement is nest in another statement.\r
-\r
-**/\r
-VOID\r
-UiAddMenuOption (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Statement,\r
-  IN UINT16                          *MenuItemCount,\r
-  IN BOOLEAN                         NestIn\r
-  )\r
-{\r
-  UI_MENU_OPTION   *MenuOption;\r
-  UINTN            Index;\r
-  UINTN            Count;\r
-  CHAR16           *String;\r
-  UINT16           NumberOfLines;\r
-  UINT16           GlyphWidth;\r
-  UINT16           Width;\r
-  UINTN            ArrayEntry;\r
-  CHAR16           *OutputString;\r
-  EFI_STRING_ID    PromptId;\r
-\r
-  NumberOfLines = 1;\r
-  ArrayEntry    = 0;\r
-  GlyphWidth    = 1;\r
-  Count         = 1;\r
-  MenuOption    = NULL;\r
-\r
-  PromptId = GetPrompt (Statement->OpCode);\r
-  ASSERT (PromptId != 0);\r
-\r
-  String = GetToken (PromptId, gFormData->HiiHandle);\r
-  ASSERT (String != NULL);\r
-\r
-  Width  = GetWidth (Statement);\r
-  for (; GetLineByWidth (String, Width, &GlyphWidth,&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 (&String[ArrayEntry]) != 0) {\r
-      NumberOfLines++;\r
-    }\r
-    FreePool (OutputString);\r
-  }\r
-\r
-  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-    //\r
-    // Add three MenuOptions for Date/Time\r
-    // Data format :      [01/02/2004]      [11:22:33]\r
-    // Line number :        0  0    1         0  0  1\r
-    //\r
-    NumberOfLines = 0;\r
-    Count = 3;\r
-  }\r
-\r
-  for (Index = 0; Index < Count; Index++) {\r
-    MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));\r
-    ASSERT (MenuOption);\r
-\r
-    MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;\r
-    MenuOption->Description = String;\r
-    MenuOption->Handle      = gFormData->HiiHandle;\r
-    MenuOption->ThisTag     = Statement;\r
-    MenuOption->NestInStatement = NestIn;\r
-    MenuOption->EntryNumber = *MenuItemCount;\r
-\r
-    if (Index == 2) {\r
-      //\r
-      // Override LineNumber for the MenuOption in Date/Time sequence\r
-      //\r
-      MenuOption->Skip = 1;\r
-    } else {\r
-      MenuOption->Skip = NumberOfLines;\r
-    }\r
-    MenuOption->Sequence = Index;\r
-\r
-    if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {\r
-      MenuOption->GrayOut = TRUE;\r
-    } else {\r
-      MenuOption->GrayOut = FALSE;\r
-    }\r
-\r
-    if ((Statement->Attribute & HII_DISPLAY_LOCK) != 0 || (gFormData->Attribute & HII_DISPLAY_LOCK) != 0) {\r
-      MenuOption->GrayOut = TRUE;\r
-    }\r
-\r
-    //\r
-    // If the form or the question has the lock attribute, deal same as grayout.\r
-    //\r
-    if ((gFormData->Attribute & HII_DISPLAY_LOCK) != 0 || (Statement->Attribute & HII_DISPLAY_LOCK) != 0) {\r
-      MenuOption->GrayOut = TRUE;\r
-    }\r
-\r
-    switch (Statement->OpCode->OpCode) {\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
-    case EFI_IFR_CHECKBOX_OP:\r
-    case EFI_IFR_PASSWORD_OP:\r
-    case EFI_IFR_STRING_OP:\r
-      //\r
-      // User could change the value of these items\r
-      //\r
-      MenuOption->IsQuestion = TRUE;\r
-      break;\r
-    case EFI_IFR_TEXT_OP:\r
-      if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {\r
-        //\r
-        // Initializing GrayOut option as TRUE for Text setup options \r
-        // so that those options will be Gray in colour and un selectable.\r
-        //\r
-        MenuOption->GrayOut = TRUE;\r
-      }\r
-      break;\r
-    default:\r
-      MenuOption->IsQuestion = FALSE;\r
-      break;\r
-    }\r
-\r
-    if ((Statement->Attribute & HII_DISPLAY_READONLY) != 0) {\r
-      MenuOption->ReadOnly = TRUE;\r
-      if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {\r
-        MenuOption->GrayOut = TRUE;\r
-      }\r
-    }\r
-\r
-    InsertTailList (&gMenuOption, &MenuOption->Link);\r
-  }\r
-\r
-  (*MenuItemCount)++;\r
-}\r
-\r
-/**\r
-  Create the menu list base on the form data info.\r
-\r
-**/\r
-VOID\r
-ConvertStatementToMenu (\r
-  VOID\r
-  )\r
-{\r
-  UINT16                        MenuItemCount;\r
-  LIST_ENTRY                    *Link;\r
-  LIST_ENTRY                    *NestLink;\r
-  FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
-  FORM_DISPLAY_ENGINE_STATEMENT *NestStatement;\r
-\r
-  MenuItemCount = 0;\r
-  InitializeListHead (&gMenuOption);\r
-\r
-  Link = GetFirstNode (&gFormData->StatementListHead);\r
-  while (!IsNull (&gFormData->StatementListHead, Link)) {\r
-    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&gFormData->StatementListHead, Link);\r
-\r
-    //\r
-    // Skip the opcode not recognized by Display core.\r
-    //\r
-    if (Statement->OpCode->OpCode == EFI_IFR_GUID_OP) {\r
-      continue;\r
-    }\r
-\r
-    UiAddMenuOption (Statement, &MenuItemCount, FALSE);\r
-\r
-    //\r
-    // Check the statement nest in this host statement.\r
-    //\r
-    NestLink = GetFirstNode (&Statement->NestStatementList);\r
-    while (!IsNull (&Statement->NestStatementList, NestLink)) {\r
-      NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);\r
-      NestLink = GetNextNode (&Statement->NestStatementList, NestLink);\r
-\r
-      UiAddMenuOption (NestStatement, &MenuItemCount, TRUE);\r
-    }\r
-  }\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
-  Base on the input option string to update the skip value for a menu option.\r
-\r
-  @param  MenuOption             The MenuOption to be checked.\r
-  @param  OptionString           The input option string.\r
-\r
-**/\r
-VOID\r
-UpdateSkipInfoForMenu (\r
-  IN UI_MENU_OPTION               *MenuOption,\r
-  IN CHAR16                       *OptionString\r
-  )\r
-{\r
-  UINTN   Index;\r
-  UINT16  Width;\r
-  UINTN   Row;\r
-  CHAR16  *OutputString;\r
-  UINT16  GlyphWidth;\r
-\r
-  Width         = (UINT16) gOptionBlockWidth;\r
-  GlyphWidth    = 1;\r
-  Row           = 1;\r
-\r
-  for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-    if (StrLen (&OptionString[Index]) != 0) {\r
-      Row++;\r
-    }\r
-\r
-    FreePool (OutputString);\r
-  }\r
-\r
-  if ((Row > MenuOption->Skip) && \r
-      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) && \r
-      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP)) {\r
-    MenuOption->Skip = Row;\r
-  }\r
-}\r
-\r
-/**\r
-  Update display lines for a Menu Option.\r
-\r
-  @param  MenuOption             The MenuOption to be checked.\r
-\r
-**/\r
-VOID\r
-UpdateOptionSkipLines (\r
-  IN UI_MENU_OPTION               *MenuOption\r
-  )\r
-{\r
-  CHAR16  *OptionString;\r
-\r
-  OptionString  = NULL;\r
-\r
-  ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);\r
-  if (OptionString != NULL) {\r
-    UpdateSkipInfoForMenu (MenuOption, OptionString);\r
-\r
-    FreePool (OptionString);\r
-  }\r
-\r
-  if ((MenuOption->ThisTag->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {\r
-    OptionString   = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);\r
-\r
-    if (OptionString != NULL) {\r
-      UpdateSkipInfoForMenu (MenuOption, OptionString);\r
-\r
-      FreePool (OptionString);\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Check whether this Menu Option could be highlighted.\r
-\r
-  This is an internal function.\r
-\r
-  @param  MenuOption             The MenuOption to be checked.\r
-\r
-  @retval TRUE                   This Menu Option is selectable.\r
-  @retval FALSE                  This Menu Option could not be selected.\r
-\r
-**/\r
-BOOLEAN\r
-IsSelectable (\r
-  UI_MENU_OPTION   *MenuOption\r
-  )\r
-{\r
-  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||\r
-      MenuOption->GrayOut || MenuOption->ReadOnly) {\r
-    return FALSE;\r
-  } else {\r
-    return TRUE;\r
-  }\r
-}\r
-\r
-/**\r
-  Move to next selectable statement.\r
-\r
-  This is an internal function.\r
-\r
-  @param  GoUp                   The navigation direction. TRUE: up, FALSE: down.\r
-  @param  CurrentPosition        Current position.\r
-  @param  GapToTop               Gap position to top or bottom.\r
-\r
-  @return The row distance from current MenuOption to next selectable MenuOption.\r
-\r
-  @retval -1       Reach the begin of the menu, still can't find the selectable menu.\r
-  @retval Value    Find the selectable menu, maybe the truly selectable, maybe the l\r
-                   last menu showing at current form.\r
-\r
-**/\r
-INTN\r
-MoveToNextStatement (\r
-  IN     BOOLEAN                   GoUp,\r
-  IN OUT LIST_ENTRY                **CurrentPosition,\r
-  IN     UINTN                     GapToTop\r
-  )\r
-{\r
-  INTN             Distance;\r
-  LIST_ENTRY       *Pos;\r
-  UI_MENU_OPTION   *NextMenuOption;\r
-  UI_MENU_OPTION   *PreMenuOption;\r
-\r
-  Distance      = 0;\r
-  Pos           = *CurrentPosition;\r
-  PreMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
-\r
-  while (TRUE) {\r
-    NextMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
-    //\r
-    // NextMenuOption->Row == 0 means this menu has not calculate\r
-    // the NextMenuOption->Skip value yet, just calculate here.\r
-    //\r
-    if (NextMenuOption->Row == 0) {\r
-      UpdateOptionSkipLines (NextMenuOption);\r
-    }\r
-    \r
-    if (GoUp && (PreMenuOption != NextMenuOption)) {\r
-      //\r
-      // In this case, still can't find the selectable menu,\r
-      // return the last one in the showing form.\r
-      //\r
-      if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
-        NextMenuOption = PreMenuOption;\r
-        break;\r
-      }\r
-\r
-      //\r
-      // Current Position doesn't need to be caculated when go up.\r
-      // Caculate distanct at first when go up\r
-      //      \r
-      Distance += NextMenuOption->Skip;\r
-    }\r
-\r
-    if (IsSelectable (NextMenuOption)) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Arrive at begin of the menu list.\r
-    //\r
-    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {\r
-      Distance = -1;\r
-      break;\r
-    }\r
-\r
-    if (!GoUp) {\r
-      //\r
-      // In this case, still can't find the selectable menu,\r
-      // return the last one in the showing form.\r
-      //\r
-      if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
-        NextMenuOption = PreMenuOption;\r
-        break;\r
-      }\r
-\r
-      Distance += NextMenuOption->Skip;\r
-    }\r
-\r
-    PreMenuOption = NextMenuOption;\r
-    Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);\r
-  }\r
-\r
-  *CurrentPosition = &NextMenuOption->Link;\r
-  return Distance;\r
-}\r
-\r
-\r
-/**\r
-  Process option string for date/time opcode.\r
-\r
-  @param  MenuOption              Menu option point to date/time.\r
-  @param  OptionString            Option string input for process.\r
-  @param  AddOptCol               Whether need to update MenuOption->OptCol. \r
-\r
-**/\r
-VOID \r
-ProcessStringForDateTime (\r
-  UI_MENU_OPTION                  *MenuOption,\r
-  CHAR16                          *OptionString,\r
-  BOOLEAN                         AddOptCol\r
-  )\r
-{\r
-  UINTN Index;\r
-  UINTN Count;\r
-  FORM_DISPLAY_ENGINE_STATEMENT          *Statement;\r
-  EFI_IFR_DATE                           *Date;\r
-  EFI_IFR_TIME                           *Time;\r
-\r
-  ASSERT (MenuOption != NULL && OptionString != NULL);\r
-  \r
-  Statement = MenuOption->ThisTag;\r
-  Date      = NULL;\r
-  Time      = NULL;\r
-  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-    Date = (EFI_IFR_DATE *) Statement->OpCode;\r
-  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-    Time = (EFI_IFR_TIME *) Statement->OpCode;\r
-  }\r
-  \r
-  //\r
-  // If leading spaces on OptionString - remove the spaces\r
-  //\r
-  for (Index = 0; OptionString[Index] == L' '; Index++) {\r
-    //\r
-    // Base on the blockspace to get the option column info.\r
-    //\r
-    if (AddOptCol) {\r
-      MenuOption->OptCol++;\r
-    }\r
-  }\r
-  \r
-  for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {\r
-    OptionString[Count] = OptionString[Index];\r
-    Count++;\r
-  }\r
-  OptionString[Count] = CHAR_NULL;\r
-  \r
-  //\r
-  // Enable to suppress field in the opcode base on the flag.\r
-  //\r
-  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-    //\r
-    // OptionString format is: <**:  **: ****>\r
-    //                        |month|day|year|\r
-    //                          4     3    5\r
-    //\r
-    if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {\r
-      //\r
-      // At this point, only "<**:" in the optionstring. \r
-      // Clean the day's ** field, after clean, the format is "<  :"\r
-      //\r
-      SetUnicodeMem (&OptionString[1], 2, L' ');\r
-    } else if ((Date->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {\r
-      //\r
-      // At this point, only "**:" in the optionstring. \r
-      // Clean the month's "**" field, after clean, the format is "  :"\r
-      //                \r
-      SetUnicodeMem (&OptionString[0], 2, L' ');\r
-    } else if ((Date->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {\r
-      //\r
-      // At this point, only "****>" in the optionstring. \r
-      // Clean the year's "****" field, after clean, the format is "  >"\r
-      //                \r
-      SetUnicodeMem (&OptionString[0], 4, L' ');\r
-    }\r
-  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-    //\r
-    // OptionString format is: <**:  **:    **>\r
-    //                        |hour|minute|second|\r
-    //                          4     3      3\r
-    //\r
-    if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {\r
-      //\r
-      // At this point, only "<**:" in the optionstring. \r
-      // Clean the hour's ** field, after clean, the format is "<  :"\r
-      //\r
-      SetUnicodeMem (&OptionString[1], 2, L' ');\r
-    } else if ((Time->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {\r
-      //\r
-      // At this point, only "**:" in the optionstring. \r
-      // Clean the minute's "**" field, after clean, the format is "  :"\r
-      //                \r
-      SetUnicodeMem (&OptionString[0], 2, L' ');\r
-    } else if ((Time->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {\r
-      //\r
-      // At this point, only "**>" in the optionstring. \r
-      // Clean the second's "**" field, after clean, the format is "  >"\r
-      //                \r
-      SetUnicodeMem (&OptionString[0], 2, L' ');\r
-    }\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Adjust Data and Time position accordingly.\r
-  Data format :      [01/02/2004]      [11:22:33]\r
-  Line number :        0  0    1         0  0  1\r
-\r
-  This is an internal function.\r
-\r
-  @param  DirectionUp            the up or down direction. False is down. True is\r
-                                 up.\r
-  @param  CurrentPosition        Current position. On return: Point to the last\r
-                                 Option (Year or Second) if up; Point to the first\r
-                                 Option (Month or Hour) if down.\r
-\r
-  @return Return line number to pad. It is possible that we stand on a zero-advance\r
-  @return data or time opcode, so pad one line when we judge if we are going to scroll outside.\r
-\r
-**/\r
-UINTN\r
-AdjustDateAndTimePosition (\r
-  IN     BOOLEAN                     DirectionUp,\r
-  IN OUT LIST_ENTRY                  **CurrentPosition\r
-  )\r
-{\r
-  UINTN           Count;\r
-  LIST_ENTRY      *NewPosition;\r
-  UI_MENU_OPTION  *MenuOption;\r
-  UINTN           PadLineNumber;\r
-\r
-  PadLineNumber = 0;\r
-  NewPosition   = *CurrentPosition;\r
-  MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);\r
-\r
-  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
-      (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {\r
-    //\r
-    // Calculate the distance from current position to the last Date/Time MenuOption\r
-    //\r
-    Count = 0;\r
-    while (MenuOption->Skip == 0) {\r
-      Count++;\r
-      NewPosition   = NewPosition->ForwardLink;\r
-      MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);\r
-      PadLineNumber = 1;\r
-    }\r
-\r
-    NewPosition = *CurrentPosition;\r
-    if (DirectionUp) {\r
-      //\r
-      // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended\r
-      // to be one that back to the previous set of MenuOptions, we need to advance to the first\r
-      // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate\r
-      // checking can be done.\r
-      //\r
-      while (Count++ < 2) {\r
-        NewPosition = NewPosition->BackLink;\r
-      }\r
-    } else {\r
-      //\r
-      // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended\r
-      // to be one that progresses to the next set of MenuOptions, we need to advance to the last\r
-      // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate\r
-      // checking can be done.\r
-      //\r
-      while (Count-- > 0) {\r
-        NewPosition = NewPosition->ForwardLink;\r
-      }\r
-    }\r
-\r
-    *CurrentPosition = NewPosition;\r
-  }\r
-\r
-  return PadLineNumber;\r
-}\r
-\r
-/**\r
-  Get step info from numeric opcode.\r
-  \r
-  @param[in] OpCode     The input numeric op code.\r
-\r
-  @return step info for this opcode.\r
-**/\r
-UINT64\r
-GetFieldFromNum (\r
-  IN  EFI_IFR_OP_HEADER     *OpCode\r
-  )\r
-{\r
-  EFI_IFR_NUMERIC       *NumericOp;\r
-  UINT64                Step;\r
-\r
-  NumericOp = (EFI_IFR_NUMERIC *) OpCode;\r
-  \r
-  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-  case EFI_IFR_NUMERIC_SIZE_1:\r
-    Step    = NumericOp->data.u8.Step;\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_2:\r
-    Step    = NumericOp->data.u16.Step;\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_4:\r
-    Step    = NumericOp->data.u32.Step;\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_8:\r
-    Step    = NumericOp->data.u64.Step;\r
-    break;\r
-  \r
-  default:\r
-    Step = 0;\r
-    break;\r
-  }\r
-\r
-  return Step;\r
-}\r
-\r
-/**\r
-  Find the registered HotKey based on KeyData.\r
-  \r
-  @param[in] KeyData     A pointer to a buffer that describes the keystroke\r
-                         information for the hot key.\r
-\r
-  @return The registered HotKey context. If no found, NULL will return.\r
-**/\r
-BROWSER_HOT_KEY *\r
-GetHotKeyFromRegisterList (\r
-  IN EFI_INPUT_KEY *KeyData\r
-  )\r
-{\r
-  LIST_ENTRY       *Link;\r
-  BROWSER_HOT_KEY  *HotKey;\r
-\r
-  Link = GetFirstNode (&gFormData->HotKeyListHead);\r
-  while (!IsNull (&gFormData->HotKeyListHead, Link)) {\r
-    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
-    \r
-    if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {\r
-      return HotKey;\r
-    }\r
-\r
-    Link = GetNextNode (&gFormData->HotKeyListHead, Link);\r
-  }\r
-  \r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Determine if the menu is the last menu that can be selected.\r
-\r
-  This is an internal function.\r
-\r
-  @param  Direction              The scroll direction. False is down. True is up.\r
-  @param  CurrentPos             The current focus.\r
-\r
-  @return FALSE -- the menu isn't the last menu that can be selected.\r
-  @return TRUE  -- the menu is the last menu that can be selected.\r
-\r
-**/\r
-BOOLEAN\r
-ValueIsScroll (\r
-  IN  BOOLEAN                     Direction,\r
-  IN  LIST_ENTRY                  *CurrentPos\r
-  )\r
-{\r
-  LIST_ENTRY      *Temp;\r
-\r
-  Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;\r
-\r
-  if (Temp == &gMenuOption) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Wait for a given event to fire, or for an optional timeout to expire.\r
-\r
-  @param  Event                  The event to wait for\r
-\r
-  @retval UI_EVENT_TYPE          The type of the event which is trigged.\r
-\r
-**/\r
-UI_EVENT_TYPE\r
-UiWaitForEvent (\r
-  IN EFI_EVENT                Event\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       Index;\r
-  UINTN       EventNum;\r
-  UINT64      Timeout;\r
-  EFI_EVENT   TimerEvent;\r
-  EFI_EVENT   WaitList[3];\r
-  UI_EVENT_TYPE  EventType;\r
-\r
-  TimerEvent = NULL;\r
-  Timeout    = FormExitTimeout(gFormData);\r
-\r
-  if (Timeout != 0) {\r
-    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
-\r
-    //\r
-    // Set the timer event\r
-    //\r
-    gBS->SetTimer (\r
-          TimerEvent,\r
-          TimerRelative,\r
-          Timeout\r
-          );\r
-  }\r
-  \r
-  WaitList[0] = Event;\r
-  EventNum    = 1;\r
-  if (gFormData->FormRefreshEvent != NULL) {\r
-    WaitList[EventNum] = gFormData->FormRefreshEvent;\r
-    EventNum ++;\r
-  } \r
-\r
-  if (Timeout != 0) {\r
-    WaitList[EventNum] = TimerEvent;\r
-    EventNum ++;\r
-  }\r
-\r
-  Status = gBS->WaitForEvent (EventNum, WaitList, &Index);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  switch (Index) {\r
-  case 0:\r
-   EventType = UIEventKey;\r
-   break;\r
-\r
-  case 1:\r
-    if (gFormData->FormRefreshEvent != NULL) {\r
-      EventType = UIEventDriver;\r
-    } else {\r
-      ASSERT (Timeout != 0 && EventNum == 2);\r
-      EventType = UIEventTimeOut;\r
-    }\r
-    break;\r
-\r
-  default:\r
-    ASSERT (Index == 2 && EventNum == 3);\r
-    EventType = UIEventTimeOut;\r
-    break;\r
-  }\r
-\r
-  if (Timeout != 0) {\r
-    gBS->CloseEvent (TimerEvent);\r
-  }\r
-  \r
-  return EventType;\r
-}\r
-\r
-/**\r
-  Get question id info from the input opcode header.\r
-\r
-  @param  OpCode                 The input opcode header pointer.\r
-\r
-  @retval                        The question id for this opcode.\r
-\r
-**/\r
-EFI_QUESTION_ID\r
-GetQuestionIdInfo (\r
-  IN   EFI_IFR_OP_HEADER     *OpCode\r
-  )\r
-{\r
-  EFI_IFR_QUESTION_HEADER   *QuestionHeader;\r
-\r
-  if (OpCode->Length < sizeof (EFI_IFR_OP_HEADER) + sizeof (EFI_IFR_QUESTION_HEADER)) {\r
-    return 0;\r
-  }\r
-\r
-  QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *) OpCode + sizeof(EFI_IFR_OP_HEADER));\r
-\r
-  return QuestionHeader->QuestionId;\r
-}\r
-\r
-/**\r
-  Find the first menu which will be show at the top.\r
-\r
-  @param  FormData               The data info for this form.\r
-  @param  TopOfScreen            The link_entry pointer to top menu.\r
-  @param  HighlightMenu          The menu which will be highlight.\r
-  @param  SkipValue              The skip value for the top menu.\r
-\r
-**/\r
-VOID\r
-FindTopMenu (\r
-  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,\r
-  OUT LIST_ENTRY                **TopOfScreen,\r
-  OUT LIST_ENTRY                **HighlightMenu,\r
-  OUT INTN                      *SkipValue\r
-  )\r
-{\r
-  LIST_ENTRY                      *Link;\r
-  LIST_ENTRY                      *NewPos;\r
-  UINTN                           TopRow;\r
-  UINTN                           BottomRow;\r
-  UINTN                           Index;\r
-  UI_MENU_OPTION                  *SavedMenuOption;\r
-  UINTN                           EndRow;\r
-\r
-  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;\r
-  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
-\r
-  //\r
-  // If not has input highlight statement, just return the first one in this form.\r
-  //\r
-  if (FormData->HighLightedStatement == NULL) {\r
-    *TopOfScreen   = gMenuOption.ForwardLink;\r
-    *HighlightMenu = gMenuOption.ForwardLink;\r
-    if (!IsListEmpty (&gMenuOption)) {\r
-      MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);\r
-    }\r
-    *SkipValue     = 0;\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Now base on the input highlight menu to find the top menu in this page.\r
-  // Will base on the highlight menu show at the bottom to find the top menu.\r
-  //\r
-  NewPos = gMenuOption.ForwardLink;\r
-  SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-\r
-  while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||\r
-         (SavedMenuOption->Sequence != gSequence)) {\r
-    NewPos     = NewPos->ForwardLink;\r
-    if (NewPos == &gMenuOption) {\r
-      //\r
-      // Not Found it, break\r
-      //\r
-      break;\r
-    }\r
-    SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-  }\r
-  ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);\r
-\r
-  *HighlightMenu = NewPos;\r
-\r
-  AdjustDateAndTimePosition(FALSE, &NewPos);\r
-  SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-  UpdateOptionSkipLines (SavedMenuOption);\r
-\r
-  //\r
-  // If highlight opcode is date/time, keep the highlight row info not change.\r
-  //\r
-  if ((SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP || SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP) &&\r
-      (gHighligthMenuInfo.QuestionId != 0) && \r
-      (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode))) {\r
-    //\r
-    // Still show the highlight menu before exit from display engine.\r
-    //\r
-    EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
-  } else {\r
-    EndRow = BottomRow;\r
-  }\r
-\r
-  //\r
-  // Base on the selected menu will show at the bottome of next page, \r
-  // select the menu show at the top of the next page. \r
-  //\r
-  Link    = NewPos;\r
-  for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {\r
-    Link = Link->BackLink;\r
-    //\r
-    // Already find the first menu in this form, means highlight menu \r
-    // will show in first page of this form.\r
-    //\r
-    if (Link == &gMenuOption) {\r
-      *TopOfScreen   = gMenuOption.ForwardLink;\r
-      *SkipValue     = 0;\r
-      return;\r
-    }\r
-    SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
-    UpdateOptionSkipLines (SavedMenuOption);\r
-    Index += SavedMenuOption->Skip;\r
-  }\r
-\r
-  //\r
-  // Found the menu which will show at the top of the page.\r
-  //\r
-  if (Link == NewPos) {\r
-    //\r
-    // The menu can show more than one pages, just show the menu at the top of the page.\r
-    //\r
-    *SkipValue    = 0;\r
-    *TopOfScreen  = Link;\r
-  } else {\r
-    //\r
-    // Check whether need to skip some line for menu shows at the top of the page.\r
-    //\r
-    *SkipValue = Index - EndRow;\r
-    if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {\r
-      *TopOfScreen     = Link;\r
-    } else {\r
-      *SkipValue       = 0;\r
-      *TopOfScreen     = Link->ForwardLink;\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Display menu and wait for user to select one menu option, then return it.\r
-  If AutoBoot is enabled, then if user doesn't select any option,\r
-  after period of time, it will automatically return the first menu option.\r
-\r
-  @param  FormData               The current form data info.\r
-\r
-  @retval EFI_SUCESSS            Process the user selection success.\r
-  @retval EFI_NOT_FOUND          Process option string for orderedlist/Oneof fail.\r
-\r
-**/\r
-EFI_STATUS\r
-UiDisplayMenu (\r
-  IN  FORM_DISPLAY_ENGINE_FORM  *FormData\r
-  )\r
-{\r
-  INTN                            SkipValue;\r
-  INTN                            Difference;\r
-  UINTN                           DistanceValue;\r
-  UINTN                           Row;\r
-  UINTN                           Col;\r
-  UINTN                           TempRightCol;\r
-  UINTN                           Temp;\r
-  UINTN                           Temp2;\r
-  UINTN                           Temp3;\r
-  UINTN                           TopRow;\r
-  UINTN                           BottomRow;\r
-  UINTN                           OriginalRow;\r
-  UINTN                           Index;\r
-  UINT16                          Width;\r
-  CHAR16                          *StringPtr;\r
-  CHAR16                          *OptionString;\r
-  CHAR16                          *OutputString;\r
-  CHAR16                          *HelpString;\r
-  CHAR16                          *HelpHeaderString;\r
-  CHAR16                          *HelpBottomString;\r
-  BOOLEAN                         NewLine;\r
-  BOOLEAN                         Repaint;\r
-  BOOLEAN                         UpArrow;\r
-  BOOLEAN                         DownArrow;\r
-  EFI_STATUS                      Status;\r
-  EFI_INPUT_KEY                   Key;\r
-  LIST_ENTRY                      *Link;\r
-  LIST_ENTRY                      *NewPos;\r
-  LIST_ENTRY                      *TopOfScreen;\r
-  LIST_ENTRY                      *SavedListEntry;\r
-  UI_MENU_OPTION                  *MenuOption;\r
-  UI_MENU_OPTION                  *NextMenuOption;\r
-  UI_MENU_OPTION                  *SavedMenuOption;\r
-  UI_MENU_OPTION                  *PreviousMenuOption;\r
-  UI_CONTROL_FLAG                 ControlFlag;\r
-  UI_SCREEN_OPERATION             ScreenOperation;\r
-  UINT16                          DefaultId;\r
-  FORM_DISPLAY_ENGINE_STATEMENT   *Statement;\r
-  UINTN                           ModalSkipColumn;\r
-  BROWSER_HOT_KEY                 *HotKey;\r
-  UINTN                           HelpPageIndex;\r
-  UINTN                           HelpPageCount;\r
-  UINTN                           RowCount;\r
-  UINTN                           HelpLine;\r
-  UINTN                           HelpHeaderLine;\r
-  UINTN                           HelpBottomLine;\r
-  BOOLEAN                         MultiHelpPage;\r
-  UINT16                          GlyphWidth;\r
-  UINT16                          EachLineWidth;\r
-  UINT16                          HeaderLineWidth;\r
-  UINT16                          BottomLineWidth;\r
-  EFI_STRING_ID                   HelpInfo;\r
-  UI_EVENT_TYPE                   EventType;\r
-  FORM_DISPLAY_ENGINE_STATEMENT   *InitialHighlight;\r
-\r
-  EventType           = UIEventNone;\r
-  Status              = EFI_SUCCESS;\r
-  HelpString          = NULL;\r
-  HelpHeaderString    = NULL;\r
-  HelpBottomString    = NULL;\r
-  OptionString        = NULL;\r
-  ScreenOperation     = UiNoOperation;\r
-  NewLine             = TRUE;\r
-  DefaultId           = 0;\r
-  HelpPageCount       = 0;\r
-  HelpLine            = 0;\r
-  RowCount            = 0;\r
-  HelpBottomLine      = 0;\r
-  HelpHeaderLine      = 0;\r
-  HelpPageIndex       = 0;\r
-  MultiHelpPage       = FALSE;\r
-  EachLineWidth       = 0;\r
-  HeaderLineWidth     = 0;\r
-  BottomLineWidth     = 0;\r
-  OutputString        = NULL;\r
-  UpArrow             = FALSE;\r
-  DownArrow           = FALSE;\r
-  SkipValue           = 0;\r
-\r
-  NextMenuOption      = NULL;\r
-  PreviousMenuOption  = NULL;\r
-  SavedMenuOption     = NULL;\r
-  HotKey              = NULL;\r
-  Repaint             = TRUE;\r
-  MenuOption          = NULL;\r
-  ModalSkipColumn     = (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;\r
-  InitialHighlight    = gFormData->HighLightedStatement;\r
-\r
-  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
-\r
-  gOptionBlockWidth = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3);\r
-  gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS);\r
-  gHelpBlockWidth   = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS);\r
-\r
-  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;\r
-  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;\r
-\r
-  Row = TopRow;\r
-  if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
-    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + ModalSkipColumn;\r
-  } else {\r
-    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS;\r
-  }\r
-\r
-  FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);\r
-\r
-  gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
-\r
-  ControlFlag = CfInitialization;\r
-  while (TRUE) {\r
-    switch (ControlFlag) {\r
-    case CfInitialization:\r
-      if (IsListEmpty (&gMenuOption)) {\r
-        \r
-        if ((FormData->Attribute & HII_DISPLAY_MODAL) == 0) {\r
-          //\r
-          // Clear Statement range.\r
-          //\r
-          ClearLines (\r
-            gStatementDimensions.LeftColumn,\r
-            gStatementDimensions.RightColumn,\r
-            TopRow - SCROLL_ARROW_HEIGHT,\r
-            BottomRow + SCROLL_ARROW_HEIGHT,\r
-            GetFieldTextColor ()\r
-            );\r
-            \r
-          //\r
-          // Clear Key Range\r
-          //\r
-          RefreshKeyHelp (gFormData, NULL, FALSE);\r
-        }\r
-\r
-        ControlFlag = CfReadKey;\r
-      } else {\r
-        ControlFlag = CfRepaint;\r
-      }\r
-      break;\r
-\r
-    case CfRepaint:\r
-      ControlFlag = CfRefreshHighLight;\r
-\r
-      if (Repaint) {\r
-        //\r
-        // Display menu\r
-        //\r
-        DownArrow       = FALSE;\r
-        UpArrow         = FALSE;\r
-        Row             = TopRow;\r
-\r
-        Temp            = (UINTN) SkipValue;\r
-        Temp2           = (UINTN) SkipValue;\r
-        Temp3           = (UINTN) SkipValue;\r
-\r
-        //\r
-        // 1. Clear the screen.\r
-        //\r
-        if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
-          ClearLines (\r
-            gStatementDimensions.LeftColumn + ModalSkipColumn,\r
-            gStatementDimensions.LeftColumn + ModalSkipColumn + gPromptBlockWidth + gOptionBlockWidth,\r
-            TopRow - SCROLL_ARROW_HEIGHT,\r
-            BottomRow + SCROLL_ARROW_HEIGHT,\r
-            GetFieldTextColor ()\r
-            );\r
-        } else {\r
-          TempRightCol = gStatementDimensions.RightColumn;\r
-          if (!mStatementLayoutIsChanged) {\r
-            TempRightCol = gStatementDimensions.RightColumn - gHelpBlockWidth;\r
-          }\r
-          ClearLines (\r
-            gStatementDimensions.LeftColumn,\r
-            gStatementDimensions.RightColumn,\r
-            TopRow - SCROLL_ARROW_HEIGHT,\r
-            TopRow - 1,\r
-            GetFieldTextColor ()\r
-            );\r
-          ClearLines (\r
-            gStatementDimensions.LeftColumn,\r
-            TempRightCol,\r
-            TopRow,\r
-            BottomRow,\r
-            GetFieldTextColor ()\r
-            );\r
-          ClearLines (\r
-            gStatementDimensions.LeftColumn,\r
-            gStatementDimensions.RightColumn,\r
-            BottomRow + 1,\r
-            BottomRow + SCROLL_ARROW_HEIGHT,\r
-            GetFieldTextColor ()\r
-            );\r
-        }\r
-\r
-        //\r
-        // 2.Paint the menu.\r
-        //\r
-        for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {\r
-          MenuOption          = MENU_OPTION_FROM_LINK (Link);\r
-          MenuOption->Row     = Row;\r
-          MenuOption->Col     = Col;\r
-          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
-            MenuOption->OptCol  = gPromptBlockWidth + 1 + gStatementDimensions.LeftColumn + ModalSkipColumn;\r
-          } else {\r
-            MenuOption->OptCol  = gPromptBlockWidth + 1 + gStatementDimensions.LeftColumn;\r
-          }\r
-\r
-          Statement = MenuOption->ThisTag;\r
-          if (MenuOption->NestInStatement) {\r
-            MenuOption->Col += SUBTITLE_INDENT;\r
-          }\r
-\r
-          if (MenuOption->GrayOut) {\r
-            gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());\r
-          } else {\r
-            if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {\r
-              gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());\r
-            }\r
-          }\r
-\r
-          Width       = GetWidth (Statement);\r
-          OriginalRow = Row;\r
-          GlyphWidth  = 1;\r
-\r
-          if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) {\r
-            //\r
-            // Print Arrow for Goto button.\r
-            //\r
-            PrintCharAt (\r
-              MenuOption->Col - 2,\r
-              Row,\r
-              GEOMETRICSHAPE_RIGHT_TRIANGLE\r
-              );\r
-          }\r
-\r
-          //\r
-          // 2.1. Paint the description.\r
-          //\r
-          for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-            //\r
-            // Temp means need to skip how many lines from the start.\r
-            //\r
-            if ((Temp == 0) && (Row <= BottomRow)) {\r
-              PrintStringAt (MenuOption->Col, Row, OutputString);\r
-            }\r
-            //\r
-            // If there is more string to process print on the next row and increment the Skip value\r
-            //\r
-            if (StrLen (&MenuOption->Description[Index]) != 0) {\r
-              if (Temp == 0) {\r
-                Row++;\r
-              }\r
-            }\r
-\r
-            FreePool (OutputString);\r
-            if (Temp != 0) {\r
-              Temp--;\r
-            }\r
-          }\r
-\r
-          Temp  = 0;\r
-          Row   = OriginalRow;\r
-\r
-          //\r
-          // 2.2. Paint the option string.\r
-          //\r
-          Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);\r
-          //\r
-          // If Error occur, question value update in ProcessOptions.\r
-          // Exit current FormDisplay with new question value.\r
-          //\r
-          if (EFI_ERROR (Status)) {\r
-            return Status;\r
-          }\r
-\r
-          if (OptionString != NULL) {\r
-            if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-              ProcessStringForDateTime(MenuOption, OptionString, TRUE);\r
-            }\r
-\r
-            Width       = (UINT16) gOptionBlockWidth;\r
-            OriginalRow = Row;\r
-            GlyphWidth  = 1;\r
-\r
-            for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-              if ((Temp2 == 0) && (Row <= BottomRow)) {\r
-                PrintStringAt (MenuOption->OptCol, Row, OutputString);\r
-              }\r
-              //\r
-              // If there is more string to process print on the next row and increment the Skip value\r
-              //\r
-              if (StrLen (&OptionString[Index]) != 0) {\r
-                if (Temp2 == 0) {\r
-                  Row++;\r
-                  //\r
-                  // Since the Number of lines for this menu entry may or may not be reflected accurately\r
-                  // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
-                  // some testing to ensure we are keeping this in-sync.\r
-                  //\r
-                  // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
-                  //\r
-                  if ((Row - OriginalRow) >= MenuOption->Skip) {\r
-                    MenuOption->Skip++;\r
-                  }\r
-                }\r
-              }\r
-\r
-              FreePool (OutputString);\r
-              if (Temp2 != 0) {\r
-                Temp2--;\r
-              }\r
-            }\r
-\r
-            Row   = OriginalRow;\r
-\r
-            FreePool (OptionString);\r
-          }\r
-          Temp2 = 0;\r
-\r
-          //\r
-          // If this is a text op with secondary text information\r
-          //\r
-          if ((Statement->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) {\r
-            StringPtr   = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle);\r
-\r
-            Width       = (UINT16) gOptionBlockWidth;\r
-            OriginalRow = Row;\r
-            GlyphWidth = 1;\r
-\r
-            for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-              if ((Temp3 == 0) && (Row <= BottomRow)) {\r
-                PrintStringAt (MenuOption->OptCol, Row, OutputString);\r
-              }\r
-              //\r
-              // If there is more string to process print on the next row and increment the Skip value\r
-              //\r
-              if (StrLen (&StringPtr[Index]) != 0) {\r
-                if (Temp3 == 0) {\r
-                  Row++;\r
-                  //\r
-                  // Since the Number of lines for this menu entry may or may not be reflected accurately\r
-                  // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
-                  // some testing to ensure we are keeping this in-sync.\r
-                  //\r
-                  // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
-                  //\r
-                  if ((Row - OriginalRow) >= MenuOption->Skip) {\r
-                    MenuOption->Skip++;\r
-                  }\r
-                }\r
-              }\r
-\r
-              FreePool (OutputString);\r
-              if (Temp3 != 0) {\r
-                Temp3--;\r
-              }\r
-            }\r
-\r
-            Row = OriginalRow;\r
-            FreePool (StringPtr);\r
-          }\r
-          Temp3 = 0;\r
-\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-\r
-          //\r
-          // 3. Update the row info which will be used by next menu.\r
-          //\r
-          if (Link == TopOfScreen) {\r
-            Row += MenuOption->Skip - SkipValue;\r
-          } else {\r
-            Row += MenuOption->Skip;\r
-          }\r
-\r
-          if (Row > BottomRow) {\r
-            if (!ValueIsScroll (FALSE, Link)) {\r
-              DownArrow = TRUE;\r
-            }\r
-\r
-            Row = BottomRow + 1;\r
-            break;\r
-          }\r
-        }\r
-\r
-        if (!ValueIsScroll (TRUE, TopOfScreen)) {\r
-          UpArrow = TRUE;\r
-        }\r
-\r
-        if (UpArrow) {\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());\r
-          PrintCharAt (\r
-            gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,\r
-            TopRow - SCROLL_ARROW_HEIGHT,\r
-            ARROW_UP\r
-            );\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-        }\r
-\r
-        if (DownArrow) {\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());\r
-          PrintCharAt (\r
-            gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,\r
-            BottomRow + SCROLL_ARROW_HEIGHT,\r
-            ARROW_DOWN\r
-            );\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-        }\r
-\r
-        MenuOption = NULL;\r
-      }\r
-      break;\r
-\r
-    case CfRefreshHighLight:\r
-\r
-      //\r
-      // MenuOption: Last menu option that need to remove hilight\r
-      //             MenuOption is set to NULL in Repaint\r
-      // NewPos:     Current menu option that need to hilight\r
-      //\r
-      ControlFlag = CfUpdateHelpString;\r
-\r
-      if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) {\r
-        Temp = SkipValue;\r
-      } else {\r
-        Temp = 0;\r
-      }\r
-      if (NewPos == TopOfScreen) {\r
-        Temp2 = SkipValue;\r
-      } else {\r
-        Temp2 = 0;\r
-      }\r
-\r
-      if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {\r
-        if (MenuOption != NULL) {\r
-          //\r
-          // Remove highlight on last Menu Option\r
-          //\r
-          gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);\r
-          ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-          if (OptionString != NULL) {\r
-            if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
-                (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)\r
-               ) {\r
-              ProcessStringForDateTime(MenuOption, OptionString, FALSE);\r
-            }\r
-\r
-            Width               = (UINT16) gOptionBlockWidth;\r
-            OriginalRow         = MenuOption->Row;\r
-            GlyphWidth          = 1;\r
-\r
-            for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-              if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {\r
-                PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);\r
-              }\r
-              //\r
-              // If there is more string to process print on the next row and increment the Skip value\r
-              //\r
-              if (StrLen (&OptionString[Index]) != 0) {\r
-                if (Temp == 0) {\r
-                  MenuOption->Row++;\r
-                }\r
-              }\r
-\r
-              FreePool (OutputString);\r
-              if (Temp != 0) {\r
-                Temp--;\r
-              }\r
-            }\r
-\r
-            MenuOption->Row = OriginalRow;\r
-\r
-            FreePool (OptionString);\r
-          } else {\r
-            if (NewLine) {\r
-              if (MenuOption->GrayOut) {\r
-                gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());\r
-              } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {\r
-                gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());\r
-              }\r
-\r
-              OriginalRow = MenuOption->Row;\r
-              Width       = GetWidth (MenuOption->ThisTag);\r
-              GlyphWidth  = 1;\r
-\r
-              for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-                if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {\r
-                  PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);\r
-                }\r
-                //\r
-                // If there is more string to process print on the next row and increment the Skip value\r
-                //\r
-                if (StrLen (&MenuOption->Description[Index]) != 0) {\r
-                  if (Temp == 0) {\r
-                    MenuOption->Row++;\r
-                  }\r
-                }\r
-\r
-                FreePool (OutputString);\r
-                if (Temp != 0) {\r
-                  Temp--;\r
-                }\r
-              }\r
-\r
-              MenuOption->Row = OriginalRow;\r
-              gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-            }\r
-          }\r
-        }\r
-\r
-        //\r
-        // This is the current selected statement\r
-        //\r
-        MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-        Statement = MenuOption->ThisTag;\r
-\r
-        //\r
-        // Get the highlight statement.\r
-        //\r
-        gUserInput->SelectedStatement = Statement;\r
-        gSequence = (UINT16) MenuOption->Sequence;\r
-\r
-        //\r
-        // Record highlight row info for date/time opcode.\r
-        //\r
-        if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-          gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);\r
-          gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;\r
-        } else {\r
-          gHighligthMenuInfo.QuestionId = 0;\r
-          gHighligthMenuInfo.DisplayRow = 0;\r
-        }\r
-\r
-        if (!IsSelectable (MenuOption)) {\r
-          RefreshKeyHelp(gFormData, Statement, FALSE);\r
-          break;\r
-        }\r
-\r
-        //\r
-        // Set reverse attribute\r
-        //\r
-        gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
-        gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);\r
-\r
-        ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);\r
-        if (OptionString != NULL) {\r
-          if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-            ProcessStringForDateTime(MenuOption, OptionString, FALSE);\r
-          }\r
-          Width               = (UINT16) gOptionBlockWidth;\r
-\r
-          OriginalRow         = MenuOption->Row;\r
-          GlyphWidth          = 1;\r
-\r
-          for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-            if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {\r
-              PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);\r
-            }\r
-            //\r
-            // If there is more string to process print on the next row and increment the Skip value\r
-            //\r
-            if (StrLen (&OptionString[Index]) != 0) {\r
-              if (Temp2 == 0) {\r
-              MenuOption->Row++;\r
-              }\r
-            }\r
-\r
-            FreePool (OutputString);\r
-            if (Temp2 != 0) {\r
-              Temp2--;\r
-            }\r
-          }\r
-\r
-          MenuOption->Row = OriginalRow;\r
-\r
-          FreePool (OptionString);\r
-        } else {\r
-          if (NewLine) {\r
-            OriginalRow = MenuOption->Row;\r
-\r
-            Width       = GetWidth (Statement);\r
-            GlyphWidth          = 1;\r
-\r
-            for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
-              if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {\r
-                PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);\r
-              }\r
-              //\r
-              // If there is more string to process print on the next row and increment the Skip value\r
-              //\r
-              if (StrLen (&MenuOption->Description[Index]) != 0) {\r
-                if (Temp2 == 0) {\r
-                  MenuOption->Row++;\r
-                }\r
-              }\r
-\r
-              FreePool (OutputString);\r
-              if (Temp2 != 0) {\r
-                Temp2--;\r
-              }\r
-            }\r
-\r
-            MenuOption->Row = OriginalRow;\r
-\r
-          }\r
-        }\r
-\r
-        RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);\r
-\r
-        //\r
-        // Clear reverse attribute\r
-        //\r
-        gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-      }\r
-      break;\r
-\r
-    case CfUpdateHelpString:\r
-      ControlFlag = CfPrepareToReadKey;\r
-      if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
-        break;\r
-      }\r
-\r
-      if (Repaint || NewLine) {\r
-        //\r
-        // Don't print anything if it is a NULL help token\r
-        //\r
-        ASSERT(MenuOption != NULL);\r
-        HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;\r
-        if (HelpInfo == 0 || !IsSelectable (MenuOption)) {\r
-          StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
-        } else {\r
-          StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
-        }\r
-\r
-        RowCount      = BottomRow - TopRow + 1;\r
-        HelpPageIndex = 0;\r
-        //\r
-        // 1.Calculate how many line the help string need to print.\r
-        //\r
-        if (HelpString != NULL) {\r
-          FreePool (HelpString);\r
-          HelpString = NULL;\r
-        }\r
-        HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);\r
-        FreePool (StringPtr);\r
-\r
-        if (HelpLine > RowCount) {\r
-          MultiHelpPage   = TRUE;\r
-          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);\r
-          if (HelpHeaderString != NULL) {\r
-            FreePool (HelpHeaderString);\r
-            HelpHeaderString = NULL;\r
-          }\r
-          HelpHeaderLine  = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, 0);\r
-          FreePool (StringPtr);\r
-          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);\r
-          if (HelpBottomString != NULL) {\r
-            FreePool (HelpBottomString);\r
-            HelpBottomString = NULL;\r
-          }\r
-          HelpBottomLine  = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, 0);\r
-          FreePool (StringPtr);\r
-          //\r
-          // Calculate the help page count.\r
-          //\r
-          if (HelpLine > 2 * RowCount - 2) {\r
-            HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;\r
-            if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {\r
-              HelpPageCount += 1;\r
-            }\r
-          } else {\r
-            HelpPageCount = 2;\r
-          }\r
-        } else {\r
-          MultiHelpPage = FALSE;\r
-        }\r
-      }\r
-\r
-      //\r
-      // Check whether need to show the 'More(U/u)' at the begin.\r
-      // Base on current direct info, here shows aligned to the right side of the column.\r
-      // If the direction is multi line and aligned to right side may have problem, so \r
-      // add ASSERT code here.\r
-      //\r
-      if (HelpPageIndex > 0) {\r
-        gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());\r
-        for (Index = 0; Index < HelpHeaderLine; Index++) {\r
-          ASSERT (HelpHeaderLine == 1);\r
-          ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));\r
-          PrintStringAtWithWidth (\r
-            gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-            Index + TopRow,\r
-            gEmptyString,\r
-            gHelpBlockWidth\r
-            );\r
-          PrintStringAt (\r
-            gStatementDimensions.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,\r
-            Index + TopRow,\r
-            &HelpHeaderString[Index * HeaderLineWidth]\r
-            );\r
-        }\r
-      }\r
-\r
-      gST->ConOut->SetAttribute (gST->ConOut, GetHelpTextColor ());\r
-      //\r
-      // Print the help string info.\r
-      //\r
-      if (!MultiHelpPage) {\r
-        for (Index = 0; Index < HelpLine; Index++) {\r
-          PrintStringAtWithWidth (\r
-            gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-            Index + TopRow,\r
-            &HelpString[Index * EachLineWidth],\r
-            gHelpBlockWidth\r
-            );\r
-        }\r
-        for (; Index < RowCount; Index ++) {\r
-          PrintStringAtWithWidth (\r
-            gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-            Index + TopRow,\r
-            gEmptyString,\r
-            gHelpBlockWidth\r
-            );\r
-        }\r
-        gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);\r
-      } else  {\r
-        if (HelpPageIndex == 0) {\r
-          for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {\r
-            PrintStringAtWithWidth (\r
-              gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-              Index + TopRow,\r
-              &HelpString[Index * EachLineWidth],\r
-              gHelpBlockWidth\r
-              );\r
-          }\r
-        } else {\r
-          for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) && \r
-              (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {\r
-            PrintStringAtWithWidth (\r
-              gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-              Index + TopRow + HelpHeaderLine,\r
-              &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth],\r
-              gHelpBlockWidth\r
-              );\r
-          }\r
-          if (HelpPageIndex == HelpPageCount - 1) {\r
-            for (; Index < RowCount - HelpHeaderLine; Index ++) {\r
-              PrintStringAtWithWidth (\r
-                gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-                Index + TopRow + HelpHeaderLine,\r
-                gEmptyString,\r
-                gHelpBlockWidth\r
-                );\r
-            }\r
-            gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);\r
-          }\r
-        } \r
-      }\r
-\r
-      //\r
-      // Check whether need to print the 'More(D/d)' at the bottom.\r
-      // Base on current direct info, here shows aligned to the right side of the column.\r
-      // If the direction is multi line and aligned to right side may have problem, so \r
-      // add ASSERT code here.\r
-      //\r
-      if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {\r
-        gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());\r
-        for (Index = 0; Index < HelpBottomLine; Index++) {\r
-          ASSERT (HelpBottomLine == 1);\r
-          ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1)); \r
-          PrintStringAtWithWidth (\r
-            gStatementDimensions.RightColumn - gHelpBlockWidth,\r
-            BottomRow + Index - HelpBottomLine + 1,\r
-            gEmptyString,\r
-            gHelpBlockWidth\r
-            );\r
-          PrintStringAt (\r
-            gStatementDimensions.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,\r
-            BottomRow + Index - HelpBottomLine + 1,\r
-            &HelpBottomString[Index * BottomLineWidth]\r
-            );\r
-        }\r
-      }\r
-      //\r
-      // Reset this flag every time we finish using it.\r
-      //\r
-      Repaint = FALSE;\r
-      NewLine = FALSE;\r
-      break;\r
-\r
-    case CfPrepareToReadKey:\r
-      ControlFlag = CfReadKey;\r
-      ScreenOperation = UiNoOperation;\r
-      break;\r
-\r
-    case CfReadKey:\r
-      ControlFlag = CfScreenOperation;\r
-\r
-      //\r
-      // Wait for user's selection\r
-      //\r
-      while (TRUE) {\r
-        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-        if (!EFI_ERROR (Status)) {\r
-          EventType = UIEventKey;\r
-          break;\r
-        }\r
-\r
-        //\r
-        // If we encounter error, continue to read another key in.\r
-        //\r
-        if (Status != EFI_NOT_READY) {\r
-          continue;\r
-        }\r
-        \r
-        EventType = UiWaitForEvent(gST->ConIn->WaitForKey);\r
-        if (EventType == UIEventKey) {\r
-          gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-        }\r
-        break;\r
-      }\r
-\r
-      if (EventType == UIEventDriver) {\r
-        gUserInput->Action = BROWSER_ACTION_NONE;\r
-        ControlFlag = CfExit;\r
-        break;\r
-      }\r
-      \r
-      if (EventType == UIEventTimeOut) {\r
-        gUserInput->Action = BROWSER_ACTION_FORM_EXIT;\r
-        ControlFlag = CfExit;\r
-        break;\r
-      }\r
-\r
-      switch (Key.UnicodeChar) {\r
-      case CHAR_CARRIAGE_RETURN:\r
-        if(MenuOption == NULL || MenuOption->GrayOut || MenuOption->ReadOnly) {\r
-          ControlFlag = CfReadKey;\r
-          break;\r
-        }\r
-\r
-        ScreenOperation = UiSelect;\r
-        gDirection      = 0;\r
-        break;\r
-\r
-      //\r
-      // We will push the adjustment of these numeric values directly to the input handler\r
-      //  NOTE: we won't handle manual input numeric\r
-      //\r
-      case '+':\r
-      case '-':\r
-        //\r
-        // If the screen has no menu items, and the user didn't select UiReset\r
-        // ignore the selection and go back to reading keys.\r
-        //\r
-        if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {\r
-          ControlFlag = CfReadKey;\r
-          break;\r
-        }\r
-\r
-        ASSERT(MenuOption != NULL);\r
-        Statement = MenuOption->ThisTag;\r
-        if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP)\r
-          || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)\r
-          || ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (GetFieldFromNum(Statement->OpCode) != 0))\r
-        ){\r
-          if (Key.UnicodeChar == '+') {\r
-            gDirection = SCAN_RIGHT;\r
-          } else {\r
-            gDirection = SCAN_LEFT;\r
-          }\r
-          \r
-          Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);\r
-          if (OptionString != NULL) {\r
-            FreePool (OptionString);\r
-          }\r
-          if (EFI_ERROR (Status)) {\r
-            //\r
-            // Repaint to clear possible error prompt pop-up\r
-            //\r
-            Repaint = TRUE;\r
-            NewLine = TRUE;\r
-          } else {\r
-            ControlFlag = CfExit;\r
-          }\r
-        }\r
-        break;\r
-\r
-      case '^':\r
-        ScreenOperation = UiUp;\r
-        break;\r
-\r
-      case 'V':\r
-      case 'v':\r
-        ScreenOperation = UiDown;\r
-        break;\r
-\r
-      case ' ':\r
-        if(IsListEmpty (&gMenuOption)) {\r
-          ControlFlag = CfReadKey;\r
-          break;\r
-        }\r
-        \r
-        ASSERT(MenuOption != NULL);\r
-        if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {\r
-          ScreenOperation = UiSelect;\r
-        }\r
-        break;\r
-\r
-      case 'D':\r
-      case 'd':\r
-        if (!MultiHelpPage) {\r
-          ControlFlag = CfReadKey;\r
-          break;\r
-        }\r
-        ControlFlag    = CfUpdateHelpString;\r
-        HelpPageIndex  = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;\r
-        break;\r
-\r
-      case 'U':\r
-      case 'u':\r
-        if (!MultiHelpPage) {\r
-          ControlFlag = CfReadKey;\r
-          break;\r
-        }\r
-        ControlFlag    = CfUpdateHelpString;\r
-        HelpPageIndex  = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;\r
-        break;\r
-\r
-      case CHAR_NULL:\r
-        for (Index = 0; Index < mScanCodeNumber; Index++) {\r
-          if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {\r
-            ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;\r
-            break;\r
-          }\r
-        }\r
-        \r
-        if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {\r
-          //\r
-          // ModalForm has no ESC key and Hot Key.\r
-          //\r
-          ControlFlag = CfReadKey;\r
-        } else if (Index == mScanCodeNumber) {\r
-          //\r
-          // Check whether Key matches the registered hot key.\r
-          //\r
-          HotKey = NULL;\r
-          HotKey = GetHotKeyFromRegisterList (&Key);\r
-          if (HotKey != NULL) {\r
-            ScreenOperation = UiHotKey;\r
-          }\r
-        }\r
-        break;\r
-      }\r
-      break;\r
-\r
-    case CfScreenOperation:\r
-      if (ScreenOperation != UiReset) {\r
-        //\r
-        // If the screen has no menu items, and the user didn't select UiReset\r
-        // ignore the selection and go back to reading keys.\r
-        //\r
-        if (IsListEmpty (&gMenuOption)) {\r
-          ControlFlag = CfReadKey;\r
-          break;\r
-        }\r
-      }\r
-\r
-      for (Index = 0;\r
-           Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);\r
-           Index++\r
-          ) {\r
-        if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {\r
-          ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;\r
-          break;\r
-        }\r
-      }\r
-      break;\r
-\r
-    case CfUiSelect:\r
-      ControlFlag = CfRepaint;\r
-\r
-      ASSERT(MenuOption != NULL);\r
-      Statement = MenuOption->ThisTag;\r
-      if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {\r
-        break;\r
-      }\r
-\r
-      switch (Statement->OpCode->OpCode) {\r
-      case EFI_IFR_REF_OP:\r
-      case EFI_IFR_ACTION_OP:\r
-      case EFI_IFR_RESET_BUTTON_OP:\r
-        ControlFlag = CfExit;\r
-        break;\r
-\r
-      default:\r
-        //\r
-        // Editable Questions: oneof, ordered list, checkbox, numeric, string, password\r
-        //\r
-        RefreshKeyHelp (gFormData, Statement, TRUE);\r
-        Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);\r
-        \r
-        if (OptionString != NULL) {\r
-          FreePool (OptionString);\r
-        }\r
-        \r
-        if (EFI_ERROR (Status)) {\r
-          Repaint = TRUE;\r
-          NewLine = TRUE;\r
-          RefreshKeyHelp (gFormData, Statement, FALSE);\r
-          break;\r
-        } else {\r
-          ControlFlag = CfExit;\r
-          break;\r
-        }\r
-      }\r
-      break;\r
-\r
-    case CfUiReset:\r
-      //\r
-      // We come here when someone press ESC\r
-      // If the policy is not exit front page when user press ESC, process here.\r
-      //\r
-      if (!FormExitPolicy()) {\r
-        Repaint     = TRUE;\r
-        NewLine     = TRUE;\r
-        ControlFlag = CfRepaint;\r
-        break;\r
-      }\r
-\r
-      //\r
-      // When user press ESC, it will try to show another menu, should clean the gSequence info.\r
-      //\r
-      if (gSequence != 0) {\r
-        gSequence = 0;\r
-      }\r
-\r
-      gUserInput->Action = BROWSER_ACTION_FORM_EXIT;\r
-      ControlFlag = CfExit;\r
-      break;\r
-\r
-    case CfUiHotKey:\r
-      ControlFlag = CfRepaint;\r
-      \r
-      gUserInput->Action = HotKey->Action;\r
-      ControlFlag = CfExit;\r
-      break;\r
-\r
-    case CfUiLeft:\r
-      ControlFlag = CfRepaint;\r
-      ASSERT(MenuOption != NULL);\r
-      if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {\r
-        if (MenuOption->Sequence != 0) {\r
-          //\r
-          // In the middle or tail of the Date/Time op-code set, go left.\r
-          //\r
-          ASSERT(NewPos != NULL);\r
-          NewPos = NewPos->BackLink;\r
-        }\r
-      }\r
-      break;\r
-\r
-    case CfUiRight:\r
-      ControlFlag = CfRepaint;\r
-      ASSERT(MenuOption != NULL);\r
-      if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {\r
-        if (MenuOption->Sequence != 2) {\r
-          //\r
-          // In the middle or tail of the Date/Time op-code set, go left.\r
-          //\r
-          ASSERT(NewPos != NULL);\r
-          NewPos = NewPos->ForwardLink;\r
-        }\r
-      }\r
-      break;\r
-\r
-    case CfUiUp:\r
-      ControlFlag = CfRepaint;\r
-\r
-      SavedListEntry = NewPos;\r
-\r
-      ASSERT(NewPos != NULL);\r
-      //\r
-      // Adjust Date/Time position before we advance forward.\r
-      //\r
-      AdjustDateAndTimePosition (TRUE, &NewPos);\r
-      if (NewPos->BackLink != &gMenuOption) {\r
-        MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-        ASSERT (MenuOption != NULL);\r
-        NewLine    = TRUE;\r
-        NewPos     = NewPos->BackLink;\r
-\r
-        PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-        if (PreviousMenuOption->Row == 0) {\r
-          UpdateOptionSkipLines (PreviousMenuOption);\r
-        }\r
-        DistanceValue = PreviousMenuOption->Skip;\r
-        Difference    = 0;\r
-        if (MenuOption->Row >= DistanceValue + TopRow) {\r
-          Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);\r
-        }\r
-        NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-       \r
-        if (Difference < 0) {\r
-          //\r
-          // We hit the begining MenuOption that can be focused\r
-          // so we simply scroll to the top.\r
-          //\r
-          if (TopOfScreen != gMenuOption.ForwardLink) {\r
-            TopOfScreen = gMenuOption.ForwardLink;\r
-            Repaint     = TRUE;\r
-          } else {\r
-            //\r
-            // Scroll up to the last page when we have arrived at top page.\r
-            //\r
-            NewPos          = &gMenuOption;\r
-            TopOfScreen     = &gMenuOption;\r
-            MenuOption      = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-            ScreenOperation = UiPageUp;\r
-            ControlFlag     = CfScreenOperation;\r
-            break;\r
-          }\r
-        } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {\r
-          //\r
-          // Previous focus MenuOption is above the TopOfScreen, so we need to scroll\r
-          //\r
-          TopOfScreen = NewPos;\r
-          Repaint     = TRUE;\r
-          SkipValue = 0;\r
-        } else if (!IsSelectable (NextMenuOption)) {\r
-          //\r
-          // Continue to go up until scroll to next page or the selectable option is found.\r
-          //\r
-          ScreenOperation = UiUp;\r
-          ControlFlag     = CfScreenOperation;\r
-        }\r
-\r
-        //\r
-        // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
-        //\r
-        AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
-        AdjustDateAndTimePosition (TRUE, &NewPos);\r
-        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-        UpdateStatusBar (INPUT_ERROR, FALSE);\r
-      } else {\r
-        //\r
-        // Scroll up to the last page.\r
-        //\r
-        NewPos          = &gMenuOption;\r
-        TopOfScreen     = &gMenuOption;\r
-        MenuOption      = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-        ScreenOperation = UiPageUp;\r
-        ControlFlag     = CfScreenOperation;\r
-      }\r
-      break;\r
-\r
-    case CfUiPageUp:\r
-      //\r
-      // SkipValue means lines is skipped when show the top menu option.\r
-      //\r
-      ControlFlag     = CfRepaint;\r
-\r
-      ASSERT(NewPos != NULL);\r
-      //\r
-      // Already at the first menu option, Check the skip value.\r
-      //\r
-      if (NewPos->BackLink == &gMenuOption) {\r
-        if (SkipValue == 0) {\r
-          NewLine = FALSE;\r
-          Repaint = FALSE;\r
-        } else {\r
-          NewLine = TRUE;\r
-          Repaint = TRUE;\r
-          SkipValue = 0;\r
-        }\r
-        break;\r
-      }\r
-\r
-      NewLine   = TRUE;\r
-      Repaint   = TRUE;\r
-\r
-      //\r
-      // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one\r
-      // form of options to be show, so just update the SkipValue to show the next\r
-      // parts of options.\r
-      //\r
-      if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {\r
-        SkipValue -= BottomRow - TopRow + 1;\r
-        break;\r
-      }\r
-\r
-      Link      = TopOfScreen;\r
-      //\r
-      // First minus the menu of the top screen, it's value is SkipValue.\r
-      //\r
-      Index     = (BottomRow + 1) - SkipValue;\r
-      while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {\r
-        Link = Link->BackLink;\r
-        PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
-        if (PreviousMenuOption->Row == 0) {\r
-          UpdateOptionSkipLines (PreviousMenuOption);\r
-        }        \r
-        if (Index < PreviousMenuOption->Skip) {\r
-          break;\r
-        }\r
-        Index = Index - PreviousMenuOption->Skip;\r
-      }\r
-      \r
-      if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {\r
-        SkipValue = 0;\r
-        if (TopOfScreen == &gMenuOption) {\r
-          TopOfScreen = gMenuOption.ForwardLink;\r
-          NewPos      = gMenuOption.BackLink;\r
-          MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
-          Repaint = FALSE;\r
-        } else if (TopOfScreen != Link) {\r
-          TopOfScreen = Link;\r
-          NewPos      = Link;\r
-          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
-        } else {\r
-          //\r
-          // Finally we know that NewPos is the last MenuOption can be focused.\r
-          //\r
-          Repaint = FALSE;\r
-          NewPos  = Link;\r
-          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
-        }\r
-      } else {\r
-        if (Index > TopRow) {\r
-          //\r
-          // At here, only case "Index < PreviousMenuOption->Skip" can reach here.\r
-          //\r
-          SkipValue = PreviousMenuOption->Skip - (Index - TopRow);\r
-        } else if (Index == TopRow) {\r
-          SkipValue = 0;\r
-        } else {\r
-          SkipValue = TopRow - Index;\r
-        }\r
-\r
-        //\r
-        // Move to the option in Next page.\r
-        //\r
-        if (TopOfScreen == &gMenuOption) {\r
-          NewPos = gMenuOption.BackLink;\r
-          MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);\r
-        } else {\r
-          NewPos = Link;\r
-          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
-        }\r
-\r
-        //\r
-        // There are more MenuOption needing scrolling up.\r
-        //\r
-        TopOfScreen = Link;\r
-        MenuOption  = NULL;\r
-      }\r
-\r
-      //\r
-      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
-      // Don't do this when we are already in the first page.\r
-      //\r
-      AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
-      AdjustDateAndTimePosition (TRUE, &NewPos);\r
-      break;\r
-\r
-    case CfUiPageDown:\r
-      //\r
-      // SkipValue means lines is skipped when show the top menu option.\r
-      //\r
-      ControlFlag     = CfRepaint;\r
-\r
-      ASSERT (NewPos != NULL);\r
-      if (NewPos->ForwardLink == &gMenuOption) {\r
-        NewLine = FALSE;\r
-        Repaint = FALSE;\r
-        break;\r
-      }\r
-\r
-      NewLine = TRUE;\r
-      Repaint = TRUE;\r
-      Link    = TopOfScreen;\r
-      NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
-      Index = TopRow + NextMenuOption->Skip - SkipValue;\r
-      //\r
-      // Count to the menu option which will show at the top of the next form.\r
-      //\r
-      while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {\r
-        Link           = Link->ForwardLink;\r
-        NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
-        Index = Index + NextMenuOption->Skip;\r
-      }\r
-\r
-      if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {\r
-        //\r
-        // Finally we know that NewPos is the last MenuOption can be focused.\r
-        //\r
-        Repaint = FALSE;\r
-        MoveToNextStatement (TRUE, &Link, Index - TopRow);\r
-      } else {\r
-        //\r
-        // Calculate the skip line for top of screen menu.\r
-        //\r
-        if (Link == TopOfScreen) {\r
-          //\r
-          // The top of screen menu option occupies the entire form.\r
-          //\r
-          SkipValue += BottomRow - TopRow + 1;\r
-        } else {\r
-          SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));\r
-        }\r
-\r
-        TopOfScreen = Link;\r
-        MenuOption = NULL;\r
-        //\r
-        // Move to the Next selectable menu.\r
-        //\r
-        MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);\r
-      }\r
-\r
-      //\r
-      // Save the menu as the next highlight menu.\r
-      //\r
-      NewPos  = Link;\r
-\r
-      //\r
-      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
-      // Don't do this when we are already in the last page.\r
-      //\r
-      AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
-      AdjustDateAndTimePosition (TRUE, &NewPos);\r
-      break;\r
-\r
-    case CfUiDown:\r
-      //\r
-      // SkipValue means lines is skipped when show the top menu option.\r
-      // NewPos  points to the menu which is highlighted now.\r
-      //\r
-      ControlFlag = CfRepaint;\r
-\r
-      //\r
-      // Since the behavior of hitting the down arrow on a Date/Time op-code is intended\r
-      // to be one that progresses to the next set of op-codes, we need to advance to the last\r
-      // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate\r
-      // checking can be done.  The only other logic we need to introduce is that if a Date/Time\r
-      // op-code is the last entry in the menu, we need to rewind back to the first op-code of\r
-      // the Date/Time op-code.\r
-      //\r
-      SavedListEntry = NewPos;\r
-      AdjustDateAndTimePosition (FALSE, &NewPos);\r
-\r
-      if (NewPos->ForwardLink != &gMenuOption) {\r
-        MenuOption      = MENU_OPTION_FROM_LINK (NewPos);\r
-        NewLine         = TRUE;\r
-        NewPos          = NewPos->ForwardLink;\r
-\r
-        Difference      = 0;\r
-        //\r
-        // Current menu not at the bottom of the form.\r
-        //\r
-        if (BottomRow >= MenuOption->Row + MenuOption->Skip) {\r
-          //\r
-          // Find the next selectable menu.\r
-          //\r
-          Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);\r
-          //\r
-          // We hit the end of MenuOption that can be focused\r
-          // so we simply scroll to the first page.\r
-          //\r
-          if (Difference < 0) {\r
-            //\r
-            // Scroll to the first page.\r
-            //\r
-            if (TopOfScreen != gMenuOption.ForwardLink) {\r
-              TopOfScreen = gMenuOption.ForwardLink;\r
-              Repaint     = TRUE;\r
-              MenuOption  = NULL;\r
-            } else {\r
-              MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-            }\r
-            NewPos        = gMenuOption.ForwardLink;\r
-            MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
-\r
-            SkipValue = 0;\r
-            //\r
-            // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
-            //\r
-            AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
-            AdjustDateAndTimePosition (TRUE, &NewPos);\r
-            break;\r
-          }\r
-        }\r
-        NextMenuOption  = MENU_OPTION_FROM_LINK (NewPos);\r
-        if (NextMenuOption->Row == 0) {\r
-          UpdateOptionSkipLines (NextMenuOption);\r
-        }\r
-        DistanceValue  = Difference + NextMenuOption->Skip;\r
-\r
-        Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;\r
-        if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&\r
-            (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||\r
-             NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)\r
-            ) {\r
-          Temp ++;\r
-        }\r
-\r
-        //\r
-        // If we are going to scroll, update TopOfScreen\r
-        //\r
-        if (Temp > BottomRow) {\r
-          do {\r
-            //\r
-            // Is the current top of screen a zero-advance op-code?\r
-            // If so, keep moving forward till we hit a >0 advance op-code\r
-            //\r
-            SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
-\r
-            //\r
-            // If bottom op-code is more than one line or top op-code is more than one line\r
-            //\r
-            if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {\r
-              //\r
-              // Is the bottom op-code greater than or equal in size to the top op-code?\r
-              //\r
-              if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {\r
-                //\r
-                // Skip the top op-code\r
-                //\r
-                TopOfScreen     = TopOfScreen->ForwardLink;\r
-                Difference      = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);\r
-\r
-                SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
-\r
-                //\r
-                // If we have a remainder, skip that many more op-codes until we drain the remainder\r
-                //\r
-                while (Difference >= (INTN) SavedMenuOption->Skip) {\r
-                  //\r
-                  // Since the Difference is greater than or equal to this op-code's skip value, skip it\r
-                  //\r
-                  Difference      = Difference - (INTN) SavedMenuOption->Skip;\r
-                  TopOfScreen     = TopOfScreen->ForwardLink;\r
-                  SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
-                }\r
-                //\r
-                // Since we will act on this op-code in the next routine, and increment the\r
-                // SkipValue, set the skips to one less than what is required.\r
-                //\r
-                SkipValue = Difference - 1;\r
-              } else {\r
-                //\r
-                // Since we will act on this op-code in the next routine, and increment the\r
-                // SkipValue, set the skips to one less than what is required.\r
-                //\r
-                SkipValue += (Temp - BottomRow) - 1;\r
-              }\r
-            } else {\r
-              if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {\r
-                TopOfScreen = TopOfScreen->ForwardLink;\r
-                break;\r
-              }\r
-            }\r
-            //\r
-            // If the op-code at the top of the screen is more than one line, let's not skip it yet\r
-            // Let's set a skip flag to smoothly scroll the top of the screen.\r
-            //\r
-            if (SavedMenuOption->Skip > 1) {\r
-              if (SavedMenuOption == NextMenuOption) {\r
-                SkipValue = 0;\r
-              } else {\r
-                SkipValue++;\r
-              }\r
-            } else if (SavedMenuOption->Skip == 1) {\r
-              SkipValue   = 0;\r
-            } else {\r
-              SkipValue   = 0;\r
-              TopOfScreen = TopOfScreen->ForwardLink;\r
-            }\r
-          } while (SavedMenuOption->Skip == 0);\r
-\r
-          Repaint       = TRUE;\r
-        } else if (!IsSelectable (NextMenuOption)) {\r
-          //\r
-          // Continue to go down until scroll to next page or the selectable option is found.\r
-          //\r
-          ScreenOperation = UiDown;\r
-          ControlFlag     = CfScreenOperation;\r
-        }\r
-\r
-        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-\r
-        UpdateStatusBar (INPUT_ERROR, FALSE);\r
-\r
-      } else {\r
-        //\r
-        // Scroll to the first page.\r
-        //\r
-        if (TopOfScreen != gMenuOption.ForwardLink) {\r
-          TopOfScreen = gMenuOption.ForwardLink;\r
-          Repaint     = TRUE;\r
-          MenuOption  = NULL;\r
-        } else {\r
-          //\r
-          // Need to remove the current highlight menu.\r
-          // MenuOption saved the last highlight menu info.\r
-          //\r
-          MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-        }\r
-\r
-        SkipValue     = 0;\r
-        NewLine       = TRUE;\r
-        //\r
-        // Get the next highlight menu.\r
-        //\r
-        NewPos        = gMenuOption.ForwardLink;\r
-        MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);\r
-      }\r
-\r
-      //\r
-      // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
-      //\r
-      AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
-      AdjustDateAndTimePosition (TRUE, &NewPos);\r
-      break;\r
-\r
-    case CfUiNoOperation:\r
-      ControlFlag = CfRepaint;\r
-      break;\r
-\r
-    case CfExit:\r
-      gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-      if (HelpString != NULL) {\r
-        FreePool (HelpString);\r
-      }\r
-      if (HelpHeaderString != NULL) {\r
-        FreePool (HelpHeaderString);\r
-      }\r
-      if (HelpBottomString != NULL) {\r
-        FreePool (HelpBottomString);\r
-      }\r
-      return EFI_SUCCESS;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Base on the browser status info to show an pop up message.\r
-\r
-**/\r
-VOID\r
-BrowserStatusProcess (\r
-  VOID\r
-  )\r
-{\r
-  CHAR16         *ErrorInfo;\r
-  EFI_INPUT_KEY  Key;\r
-\r
-  if (gFormData->BrowserStatus == BROWSER_SUCCESS) {\r
-    return;\r
-  }\r
-\r
-  if (gFormData->ErrorString != NULL) {\r
-    ErrorInfo = gFormData->ErrorString;\r
-  } else {\r
-    switch (gFormData->BrowserStatus) {\r
-    case BROWSER_SUBMIT_FAIL:\r
-      ErrorInfo = gSaveFailed;\r
-      break;\r
-\r
-    case BROWSER_NO_SUBMIT_IF:\r
-      ErrorInfo = gNoSubmitIf;\r
-      break;\r
-\r
-    case BROWSER_FORM_NOT_FOUND:\r
-      ErrorInfo = gFormNotFound;\r
-      break;\r
-\r
-    case BROWSER_FORM_SUPPRESS:\r
-      ErrorInfo = gFormSuppress;\r
-      break;\r
-\r
-    case BROWSER_PROTOCOL_NOT_FOUND:\r
-      ErrorInfo = gProtocolNotFound;\r
-      break;\r
-\r
-    default:\r
-      ErrorInfo = gBrwoserError;\r
-      break;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Error occur, prompt error message.\r
-  //\r
-  do {\r
-    CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
-  } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-}\r
-\r
-/**\r
-  Display one form, and return user input.\r
-  \r
-  @param FormData                Form Data to be shown.\r
-  @param UserInputData           User input data.\r
-  \r
-  @retval EFI_SUCCESS            1.Form Data is shown, and user input is got.\r
-                                 2.Error info has show and return.\r
-  @retval EFI_INVALID_PARAMETER  The input screen dimension is not valid\r
-  @retval EFI_NOT_FOUND          New form data has some error.\r
-**/\r
-EFI_STATUS\r
-EFIAPI \r
-FormDisplay (\r
-  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,\r
-  OUT USER_INPUT                *UserInputData\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  ASSERT (FormData != NULL);\r
-  if (FormData == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  gUserInput = UserInputData;\r
-  gFormData  = FormData;\r
-\r
-  //\r
-  // Process the status info first.\r
-  //\r
-  BrowserStatusProcess();\r
-  if (UserInputData == NULL) {\r
-    //\r
-    // UserInputData == NULL, means only need to print the error info, return here.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  ConvertStatementToMenu();\r
-\r
-  Status = DisplayPageFrame (FormData, &gStatementDimensions);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Check whether layout is changed.\r
-  //\r
-  if (mIsFirstForm \r
-      || (gOldFormEntry.HiiHandle != FormData->HiiHandle)\r
-      || (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))\r
-      || (gOldFormEntry.FormId != FormData->FormId)) {\r
-    mStatementLayoutIsChanged = TRUE;\r
-  } else {\r
-    mStatementLayoutIsChanged = FALSE;\r
-  }\r
-\r
-  Status = UiDisplayMenu(FormData);\r
-  \r
-  //\r
-  // Backup last form info.\r
-  //\r
-  mIsFirstForm            = FALSE;\r
-  gOldFormEntry.HiiHandle = FormData->HiiHandle;\r
-  CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);\r
-  gOldFormEntry.FormId    = FormData->FormId;\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Clear Screen to the initial state.\r
-**/\r
-VOID\r
-EFIAPI \r
-DriverClearDisplayPage (\r
-  VOID\r
-  )\r
-{\r
-  ClearDisplayPage ();\r
-  mIsFirstForm = TRUE;\r
-}\r
-\r
-/**\r
-  Set Buffer to Value for Size bytes.\r
-\r
-  @param  Buffer                 Memory to set.\r
-  @param  Size                   Number of bytes to set\r
-  @param  Value                  Value of the set operation.\r
-\r
-**/\r
-VOID\r
-SetUnicodeMem (\r
-  IN VOID   *Buffer,\r
-  IN UINTN  Size,\r
-  IN CHAR16 Value\r
-  )\r
-{\r
-  CHAR16  *Ptr;\r
-\r
-  Ptr = Buffer;\r
-  while ((Size--)  != 0) {\r
-    *(Ptr++) = Value;\r
-  }\r
-}\r
-\r
-/**\r
-  Initialize Setup Browser driver.\r
-\r
-  @param ImageHandle     The image handle.\r
-  @param SystemTable     The system table.\r
-\r
-  @retval EFI_SUCCESS    The Setup Browser module is initialized correctly..\r
-  @return Other value if failed to initialize the Setup Browser module.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeDisplayEngine (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_INPUT_KEY                       HotKey;\r
-  EFI_STRING                          NewString;\r
-  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;\r
-\r
-  //\r
-  // Publish our HII data\r
-  //\r
-  gHiiHandle = HiiAddPackages (\r
-                 &gDisplayEngineGuid,\r
-                 ImageHandle,\r
-                 DisplayEngineStrings,\r
-                 NULL\r
-                 );\r
-  ASSERT (gHiiHandle != NULL);\r
-\r
-  //\r
-  // Install Form Display protocol\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &mPrivateData.Handle,\r
-                  &gEdkiiFormDisplayEngineProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &mPrivateData.FromDisplayProt\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  InitializeDisplayStrings();\r
-  \r
-  ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));\r
-  ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));\r
-\r
-  //\r
-  // Use BrowserEx2 protocol to register HotKey.\r
-  // \r
-  Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Register the default HotKey F9 and F10 again.\r
-    //\r
-    HotKey.UnicodeChar = CHAR_NULL;\r
-    HotKey.ScanCode   = SCAN_F10;\r
-    NewString         = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);\r
-    ASSERT (NewString != NULL);\r
-    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);\r
-\r
-    HotKey.ScanCode   = SCAN_F9;\r
-    NewString         = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);\r
-    ASSERT (NewString != NULL);\r
-    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This is the default unload handle for display core drivers.\r
-\r
-  @param[in]  ImageHandle       The drivers' driver image.\r
-\r
-  @retval EFI_SUCCESS           The image is unloaded.\r
-  @retval Others                Failed to unload the image.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UnloadDisplayEngine (\r
-  IN EFI_HANDLE             ImageHandle\r
-  )\r
-{\r
-  HiiRemovePackages(gHiiHandle);\r
-\r
-  FreeDisplayStrings ();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h
deleted file mode 100644 (file)
index 45bcadc..0000000
+++ /dev/null
@@ -1,589 +0,0 @@
-/** @file\r
-  FormDiplay protocol to show Form\r
-\r
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
-#ifndef __FORM_DISPLAY_H__\r
-#define __FORM_DISPLAY_H__\r
-\r
-\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/HiiLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/CustomizedDisplayLib.h>\r
-\r
-#include <Protocol/FormBrowserEx2.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/DisplayProtocol.h>\r
-\r
-#include <Guid/MdeModuleHii.h>\r
-\r
-//\r
-// This is the generated header file which includes whatever needs to be exported (strings + IFR)\r
-//\r
-extern UINT8  DisplayEngineStrings[];\r
-extern EFI_SCREEN_DESCRIPTOR         gStatementDimensions;\r
-extern USER_INPUT                    *gUserInput;\r
-extern FORM_DISPLAY_ENGINE_FORM      *gFormData;\r
-extern EFI_HII_HANDLE                gHiiHandle;\r
-extern UINT16                        gDirection;\r
-extern LIST_ENTRY                    gMenuOption;\r
-\r
-//\r
-// Browser Global Strings\r
-//\r
-extern CHAR16            *gSaveFailed;\r
-extern CHAR16            *gPromptForData;\r
-extern CHAR16            *gPromptForPassword;\r
-extern CHAR16            *gPromptForNewPassword;\r
-extern CHAR16            *gConfirmPassword;\r
-extern CHAR16            *gConfirmError;\r
-extern CHAR16            *gPassowordInvalid;\r
-extern CHAR16            *gPressEnter;\r
-extern CHAR16            *gEmptyString;\r
-extern CHAR16            *gMiniString;\r
-extern CHAR16            *gOptionMismatch;\r
-extern CHAR16            *gFormSuppress;\r
-extern CHAR16            *gProtocolNotFound;\r
-\r
-extern CHAR16            gPromptBlockWidth;\r
-extern CHAR16            gOptionBlockWidth;\r
-extern CHAR16            gHelpBlockWidth;\r
-extern CHAR16            *mUnknownString;\r
-\r
-//\r
-// Screen definitions\r
-//\r
-\r
-#define LEFT_SKIPPED_COLUMNS          3\r
-#define SCROLL_ARROW_HEIGHT           1\r
-#define POPUP_PAD_SPACE_COUNT         5\r
-#define POPUP_FRAME_WIDTH             2\r
-\r
-//\r
-// Display definitions\r
-//\r
-#define LEFT_ONEOF_DELIMITER      L'<'\r
-#define RIGHT_ONEOF_DELIMITER     L'>'\r
-\r
-#define LEFT_NUMERIC_DELIMITER    L'['\r
-#define RIGHT_NUMERIC_DELIMITER   L']'\r
-\r
-#define LEFT_CHECKBOX_DELIMITER   L'['\r
-#define RIGHT_CHECKBOX_DELIMITER  L']'\r
-\r
-#define CHECK_ON                  L'X'\r
-#define CHECK_OFF                 L' '\r
-\r
-#define TIME_SEPARATOR            L':'\r
-#define DATE_SEPARATOR            L'/'\r
-\r
-#define SUBTITLE_INDENT  2\r
-\r
-//\r
-// This is the Input Error Message\r
-//\r
-#define INPUT_ERROR 1\r
-\r
-//\r
-// This is the NV RAM update required Message\r
-//\r
-#define NV_UPDATE_REQUIRED  2\r
-//\r
-// Time definitions\r
-//\r
-#define ONE_SECOND  10000000\r
-\r
-//\r
-// It take 23 characters including the NULL to print a 64 bits number with "[" and "]".\r
-// pow(2, 64) = [18446744073709551616]\r
-//\r
-#define MAX_NUMERIC_INPUT_WIDTH 23\r
-\r
-#define EFI_HII_EXPRESSION_INCONSISTENT_IF   0\r
-#define EFI_HII_EXPRESSION_NO_SUBMIT_IF      1\r
-#define EFI_HII_EXPRESSION_GRAY_OUT_IF       2\r
-#define EFI_HII_EXPRESSION_SUPPRESS_IF       3\r
-#define EFI_HII_EXPRESSION_DISABLE_IF        4\r
-\r
-//\r
-// Character definitions\r
-//\r
-#define CHAR_SPACE              0x0020\r
-\r
-#define FORM_DISPLAY_DRIVER_SIGNATURE SIGNATURE_32 ('F', 'D', 'D', 'V')\r
-typedef struct {\r
-  UINT32                             Signature;\r
-\r
-  EFI_HANDLE                         Handle;\r
-\r
-  //\r
-  // Produced protocol\r
-  //\r
-  EDKII_FORM_DISPLAY_ENGINE_PROTOCOL FromDisplayProt;\r
-} FORM_DISPLAY_DRIVER_PRIVATE_DATA;\r
-\r
-\r
-typedef enum {\r
-  UiNoOperation,\r
-  UiSelect,\r
-  UiUp,\r
-  UiDown,\r
-  UiLeft,\r
-  UiRight,\r
-  UiReset,\r
-  UiPrevious,\r
-  UiPageUp,\r
-  UiPageDown,\r
-  UiHotKey,\r
-  UiMaxOperation\r
-} UI_SCREEN_OPERATION;\r
-\r
-typedef enum {\r
-  CfInitialization,\r
-  CfCheckSelection,\r
-  CfRepaint,\r
-  CfRefreshHighLight,\r
-  CfUpdateHelpString,\r
-  CfPrepareToReadKey,\r
-  CfReadKey,\r
-  CfScreenOperation,\r
-  CfUiSelect,\r
-  CfUiReset,\r
-  CfUiLeft,\r
-  CfUiRight,\r
-  CfUiUp,\r
-  CfUiPageUp,\r
-  CfUiPageDown,\r
-  CfUiDown,\r
-  CfUiDefault,\r
-  CfUiNoOperation,\r
-  CfExit,\r
-  CfUiHotKey,\r
-  CfMaxControlFlag\r
-} UI_CONTROL_FLAG;\r
-\r
-typedef enum {\r
-  UIEventNone,\r
-  UIEventKey,\r
-  UIEventTimeOut,\r
-  UIEventDriver\r
-} UI_EVENT_TYPE;\r
-\r
-typedef struct {\r
-  UINT16              ScanCode;\r
-  UI_SCREEN_OPERATION ScreenOperation;\r
-} SCAN_CODE_TO_SCREEN_OPERATION;\r
-\r
-typedef struct {\r
-  UI_SCREEN_OPERATION ScreenOperation;\r
-  UI_CONTROL_FLAG     ControlFlag;\r
-} SCREEN_OPERATION_T0_CONTROL_FLAG;\r
-\r
-typedef struct {\r
-  EFI_QUESTION_ID    QuestionId;\r
-  UINT16             DisplayRow;\r
-} DISPLAY_HIGHLIGHT_MENU_INFO;\r
-\r
-#define UI_MENU_OPTION_SIGNATURE  SIGNATURE_32 ('u', 'i', 'm', 'm')\r
-\r
-typedef struct {\r
-  UINTN                   Signature;\r
-  LIST_ENTRY              Link;\r
-\r
-  EFI_HII_HANDLE          Handle;\r
-  FORM_DISPLAY_ENGINE_STATEMENT  *ThisTag;\r
-  UINT16                  EntryNumber;\r
-\r
-  UINTN                   Row;\r
-  UINTN                   Col;\r
-  UINTN                   OptCol;\r
-  CHAR16                  *Description;\r
-  UINTN                   Skip;           // Number of lines\r
-\r
-  //\r
-  // Display item sequence for date/time\r
-  //  Date:      Month/Day/Year\r
-  //  Sequence:  0     1   2\r
-  //\r
-  //  Time:      Hour : Minute : Second\r
-  //  Sequence:  0      1        2\r
-  //\r
-  //\r
-  UINTN                   Sequence;\r
-\r
-  BOOLEAN                 GrayOut;\r
-  BOOLEAN                 ReadOnly;\r
-\r
-  //\r
-  // Whether user could change value of this item\r
-  //\r
-  BOOLEAN                 IsQuestion;\r
-  BOOLEAN                 NestInStatement;\r
-} UI_MENU_OPTION;\r
-\r
-#define MENU_OPTION_FROM_LINK(a)  CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)\r
-\r
-/**\r
-  Print Question Value according to it's storage width and display attributes.\r
-\r
-  @param  Question               The Question to be printed.\r
-  @param  FormattedNumber        Buffer for output string.\r
-  @param  BufferSize             The FormattedNumber buffer size in bytes.\r
-\r
-  @retval EFI_SUCCESS            Print success.\r
-  @retval EFI_BUFFER_TOO_SMALL   Buffer size is not enough for formatted number.\r
-\r
-**/\r
-EFI_STATUS\r
-PrintFormattedNumber (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question,\r
-  IN OUT CHAR16               *FormattedNumber,\r
-  IN UINTN                    BufferSize\r
-  );\r
-\r
-/**\r
-  Set value of a data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-  @param  Value                  The value to be set.\r
-\r
-**/\r
-VOID\r
-SetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index,\r
-  IN UINT64                   Value\r
-  );\r
-\r
-/**\r
-  Return data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-\r
-  @retval Value                  The data to be returned\r
-\r
-**/\r
-UINT64\r
-GetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index\r
-  );\r
-  \r
-/**\r
-  Search an Option of a Question by its value.\r
-\r
-  @param  Question               The Question\r
-  @param  OptionValue            Value for Option to be searched.\r
-\r
-  @retval Pointer                Pointer to the found Option.\r
-  @retval NULL                   Option not found.\r
-\r
-**/\r
-DISPLAY_QUESTION_OPTION *\r
-ValueToOption (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question,\r
-  IN EFI_HII_VALUE                   *OptionValue\r
-  );\r
-\r
-/**\r
-  Compare two Hii value.\r
-\r
-  @param  Value1                 Expression value to compare on left-hand.\r
-  @param  Value2                 Expression value to compare on right-hand.\r
-  @param  Result                 Return value after compare.\r
-                                 retval 0                      Two operators equal.\r
-                                 return Positive value if Value1 is greater than Value2.\r
-                                 retval Negative value if Value1 is less than Value2.\r
-  @param  HiiHandle              Only required for string compare.\r
-\r
-  @retval other                  Could not perform compare on two values.\r
-  @retval EFI_SUCCESS            Compare the value success.\r
-\r
-**/\r
-EFI_STATUS\r
-CompareHiiValue (\r
-  IN  EFI_HII_VALUE   *Value1,\r
-  IN  EFI_HII_VALUE   *Value2,\r
-  OUT INTN            *Result,\r
-  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL\r
-  );\r
-\r
-/**\r
-  Draw a pop up windows based on the dimension, number of lines and\r
-  strings specified.\r
-\r
-  @param RequestedWidth  The width of the pop-up.\r
-  @param NumberOfLines   The number of lines.\r
-  @param ...             A series of text strings that displayed in the pop-up.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CreateMultiStringPopUp (\r
-  IN  UINTN                       RequestedWidth,\r
-  IN  UINTN                       NumberOfLines,\r
-  ...\r
-  );\r
-\r
-/**\r
-  Will copy LineWidth amount of a string in the OutputString buffer and return the\r
-  number of CHAR16 characters that were copied into the OutputString buffer.\r
-  The output string format is:\r
-    Glyph Info + String info + '\0'.\r
-\r
-  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.\r
-\r
-  @param  InputString            String description for this option.\r
-  @param  LineWidth              Width of the desired string to extract in CHAR16\r
-                                 characters\r
-  @param  GlyphWidth             The glyph width of the begin of the char in the string.\r
-  @param  Index                  Where in InputString to start the copy process\r
-  @param  OutputString           Buffer to copy the string into\r
-\r
-  @return Returns the number of CHAR16 characters that were copied into the OutputString \r
-  buffer, include extra glyph info and '\0' info.\r
-\r
-**/\r
-UINT16\r
-GetLineByWidth (\r
-  IN      CHAR16                      *InputString,\r
-  IN      UINT16                      LineWidth,\r
-  IN OUT  UINT16                      *GlyphWidth,\r
-  IN OUT  UINTN                       *Index,\r
-  OUT     CHAR16                      **OutputString\r
-  );\r
-\r
-\r
-/**\r
-  Get the string based on the StringId and HII Package List Handle.\r
-\r
-  @param  Token                  The String's ID.\r
-  @param  HiiHandle              The Hii handle for this string package.\r
-\r
-  @return The output string.\r
-\r
-**/\r
-CHAR16 *\r
-GetToken (\r
-  IN  EFI_STRING_ID                Token,\r
-  IN  EFI_HII_HANDLE               HiiHandle\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
-/**\r
-  This routine reads a numeric value from the user input.\r
-\r
-  @param  MenuOption        Pointer to the current input menu.\r
-\r
-  @retval EFI_SUCCESS       If numerical input is read successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-GetNumericInput (\r
-  IN  UI_MENU_OPTION              *MenuOption\r
-  );\r
-\r
-/**\r
-  Get string or password input from user.\r
-\r
-  @param  MenuOption        Pointer to the current input menu.\r
-  @param  Prompt            The prompt string shown on popup window.\r
-  @param  StringPtr         Old user input and destination for use input string.\r
-\r
-  @retval EFI_SUCCESS       If string input is read successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-ReadString (\r
-  IN     UI_MENU_OPTION              *MenuOption,\r
-  IN     CHAR16                      *Prompt,\r
-  IN OUT CHAR16                      *StringPtr\r
-  );\r
-\r
-/**\r
-  Draw a pop up windows based on the dimension, number of lines and\r
-  strings specified.\r
-\r
-  @param RequestedWidth  The width of the pop-up.\r
-  @param NumberOfLines   The number of lines.\r
-  @param Marker          The variable argument list for the list of string to be printed.\r
-\r
-**/\r
-VOID\r
-CreateSharedPopUp (\r
-  IN  UINTN                       RequestedWidth,\r
-  IN  UINTN                       NumberOfLines,\r
-  IN  VA_LIST                     Marker\r
-  );\r
-  \r
-/**\r
-  Wait for a key to be pressed by user.\r
-\r
-  @param Key         The key which is pressed by user.\r
-\r
-  @retval EFI_SUCCESS The function always completed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-WaitForKeyStroke (\r
-  OUT  EFI_INPUT_KEY           *Key\r
-  );\r
-\r
-/**\r
-  Get selection for OneOf and OrderedList (Left/Right will be ignored).\r
-\r
-  @param  MenuOption        Pointer to the current input menu.\r
-\r
-  @retval EFI_SUCCESS       If Option input is processed successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-GetSelectionInputPopUp (\r
-  IN  UI_MENU_OPTION              *MenuOption\r
-  );\r
-\r
-/**\r
-  Process the help string: Split StringPtr to several lines of strings stored in\r
-  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.\r
-\r
-  @param  StringPtr              The entire help string.\r
-  @param  FormattedString        The oupput formatted string.\r
-  @param  EachLineWidth          The max string length of each line in the formatted string.\r
-  @param  RowCount               TRUE: if Question is selected.\r
-\r
-**/\r
-UINTN\r
-ProcessHelpString (\r
-  IN  CHAR16  *StringPtr,\r
-  OUT CHAR16  **FormattedString,\r
-  OUT UINT16  *EachLineWidth,\r
-  IN  UINTN   RowCount\r
-  );\r
-\r
-/**\r
-  Process a Question's Option (whether selected or un-selected).\r
-\r
-  @param  MenuOption             The MenuOption for this Question.\r
-  @param  Selected               TRUE: if Question is selected.\r
-  @param  OptionString           Pointer of the Option String to be displayed.\r
-  @param  SkipErrorValue         Whether need to return when value without option for it.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval Other                  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS\r
-ProcessOptions (\r
-  IN  UI_MENU_OPTION              *MenuOption,\r
-  IN  BOOLEAN                     Selected,\r
-  OUT CHAR16                      **OptionString,\r
-  IN  BOOLEAN                     SkipErrorValue\r
-  );\r
-\r
-/**\r
-  Set Buffer to Value for Size bytes.\r
-\r
-  @param  Buffer                 Memory to set.\r
-  @param  Size                   Number of bytes to set\r
-  @param  Value                  Value of the set operation.\r
-\r
-**/\r
-VOID\r
-SetUnicodeMem (\r
-  IN VOID   *Buffer,\r
-  IN UINTN  Size,\r
-  IN CHAR16 Value\r
-  );\r
-\r
-/**\r
-  Display one form, and return user input.\r
-  \r
-  @param FormData                Form Data to be shown.\r
-  @param UserInputData           User input data.\r
-  \r
-  @retval EFI_SUCCESS            Form Data is shown, and user input is got.\r
-**/\r
-EFI_STATUS\r
-EFIAPI \r
-FormDisplay (\r
-  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,\r
-  OUT USER_INPUT                *UserInputData\r
-  );\r
-\r
-/**\r
-  Clear Screen to the initial state.\r
-**/\r
-VOID\r
-EFIAPI \r
-DriverClearDisplayPage (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Exit Display and Clear Screen to the original state.\r
-\r
-**/\r
-VOID\r
-EFIAPI \r
-ExitDisplay (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Process validate for one question.\r
-\r
-  @param  Question               The question which need to validate.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval Other                  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS \r
-ValidateQuestion (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question\r
-  );\r
-\r
-#endif\r
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni
deleted file mode 100644 (file)
index 0ee7f46..0000000
Binary files a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni and /dev/null differ
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c
deleted file mode 100644 (file)
index a58e12f..0000000
+++ /dev/null
@@ -1,1531 +0,0 @@
-/** @file\r
-Implementation for handling user input from the User Interfaces.\r
-\r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "FormDisplay.h"\r
-\r
-/**\r
-  Get maximum and minimum info from this opcode.\r
-\r
-  @param  OpCode            Pointer to the current input opcode.\r
-  @param  Minimum           The minimum size info for this opcode.\r
-  @param  Maximum           The maximum size info for this opcode.\r
-\r
-**/\r
-VOID\r
-GetFieldFromOp (\r
-  IN   EFI_IFR_OP_HEADER       *OpCode,\r
-  OUT  UINTN                   *Minimum,\r
-  OUT  UINTN                   *Maximum\r
-  )\r
-{\r
-  EFI_IFR_STRING    *StringOp;\r
-  EFI_IFR_PASSWORD  *PasswordOp;\r
-  if (OpCode->OpCode == EFI_IFR_STRING_OP) {\r
-    StringOp = (EFI_IFR_STRING *) OpCode;\r
-    *Minimum = StringOp->MinSize;\r
-    *Maximum = StringOp->MaxSize;    \r
-  } else if (OpCode->OpCode == EFI_IFR_PASSWORD_OP) {\r
-    PasswordOp = (EFI_IFR_PASSWORD *) OpCode;\r
-    *Minimum = PasswordOp->MinSize;\r
-    *Maximum = PasswordOp->MaxSize;       \r
-  } else {\r
-    *Minimum = 0;\r
-    *Maximum = 0;       \r
-  }\r
-}\r
-\r
-/**\r
-  Get string or password input from user.\r
-\r
-  @param  MenuOption        Pointer to the current input menu.\r
-  @param  Prompt            The prompt string shown on popup window.\r
-  @param  StringPtr         Old user input and destination for use input string.\r
-\r
-  @retval EFI_SUCCESS       If string input is read successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-ReadString (\r
-  IN     UI_MENU_OPTION              *MenuOption,\r
-  IN     CHAR16                      *Prompt,\r
-  IN OUT CHAR16                      *StringPtr\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_INPUT_KEY           Key;\r
-  CHAR16                  NullCharacter;\r
-  UINTN                   ScreenSize;\r
-  CHAR16                  Space[2];\r
-  CHAR16                  KeyPad[2];\r
-  CHAR16                  *TempString;\r
-  CHAR16                  *BufferedString;\r
-  UINTN                   Index;\r
-  UINTN                   Index2;\r
-  UINTN                   Count;\r
-  UINTN                   Start;\r
-  UINTN                   Top;\r
-  UINTN                   DimensionsWidth;\r
-  UINTN                   DimensionsHeight;\r
-  UINTN                   CurrentCursor;\r
-  BOOLEAN                 CursorVisible;\r
-  UINTN                   Minimum;\r
-  UINTN                   Maximum;\r
-  FORM_DISPLAY_ENGINE_STATEMENT  *Question;\r
-  BOOLEAN                 IsPassword;\r
-\r
-  DimensionsWidth  = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;\r
-  DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;\r
-\r
-  NullCharacter    = CHAR_NULL;\r
-  ScreenSize       = GetStringWidth (Prompt) / sizeof (CHAR16);\r
-  Space[0]         = L' ';\r
-  Space[1]         = CHAR_NULL;\r
-\r
-  Question         = MenuOption->ThisTag;\r
-  GetFieldFromOp(Question->OpCode, &Minimum, &Maximum);\r
-\r
-  if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) {\r
-    IsPassword = TRUE;\r
-  } else {\r
-    IsPassword = FALSE;\r
-  }\r
-\r
-  TempString = AllocateZeroPool ((Maximum + 1)* sizeof (CHAR16));\r
-  ASSERT (TempString);\r
-\r
-  if (ScreenSize < (Maximum + 1)) {\r
-    ScreenSize = Maximum + 1;\r
-  }\r
-\r
-  if ((ScreenSize + 2) > DimensionsWidth) {\r
-    ScreenSize = DimensionsWidth - 2;\r
-  }\r
-\r
-  BufferedString = AllocateZeroPool (ScreenSize * 2);\r
-  ASSERT (BufferedString);\r
-\r
-  Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1;\r
-  Top   = ((DimensionsHeight - 6) / 2) + gStatementDimensions.TopRow - 1;\r
-\r
-  //\r
-  // Display prompt for string\r
-  //\r
-  // CreateDialog (NULL, "", Prompt, Space, "", NULL);\r
-  CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter);\r
-  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));\r
-\r
-  CursorVisible = gST->ConOut->Mode->CursorVisible;\r
-  gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
-\r
-  CurrentCursor = GetStringWidth (StringPtr) / 2 - 1;\r
-  if (CurrentCursor != 0) {\r
-    //\r
-    // Show the string which has beed saved before.\r
-    //\r
-    SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');\r
-    PrintStringAt (Start + 1, Top + 3, BufferedString);\r
-\r
-    if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {\r
-      Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;\r
-    } else {\r
-      Index = 0;\r
-    }\r
-\r
-    if (IsPassword) {\r
-      gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);\r
-    }\r
-\r
-    for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {\r
-      BufferedString[Count] = StringPtr[Index];\r
-\r
-      if (IsPassword) {\r
-        PrintCharAt ((UINTN)-1, (UINTN)-1, L'*');\r
-      }\r
-    }\r
-\r
-    if (!IsPassword) {\r
-      PrintStringAt (Start + 1, Top + 3, BufferedString);\r
-    }\r
-    \r
-    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-    gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);\r
-  }\r
-  \r
-  do {\r
-    Status = WaitForKeyStroke (&Key);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));\r
-    switch (Key.UnicodeChar) {\r
-    case CHAR_NULL:\r
-      switch (Key.ScanCode) {\r
-      case SCAN_LEFT:\r
-        if (CurrentCursor > 0) {\r
-          CurrentCursor--;\r
-        }\r
-        break;\r
-\r
-      case SCAN_RIGHT:\r
-        if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) {\r
-          CurrentCursor++;\r
-        }\r
-        break;\r
-\r
-      case SCAN_ESC:\r
-        FreePool (TempString);\r
-        FreePool (BufferedString);\r
-        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
-        return EFI_DEVICE_ERROR;\r
-\r
-      default:\r
-        break;\r
-      }\r
-\r
-      break;\r
-\r
-    case CHAR_CARRIAGE_RETURN:\r
-      if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) {\r
-\r
-        FreePool (TempString);\r
-        FreePool (BufferedString);\r
-        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
-        return EFI_SUCCESS;\r
-      } else {\r
-        //\r
-        // Simply create a popup to tell the user that they had typed in too few characters.\r
-        // To save code space, we can then treat this as an error and return back to the menu.\r
-        //\r
-        do {\r
-          CreateDialog (&Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter, NULL);\r
-        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-\r
-        FreePool (TempString);\r
-        FreePool (BufferedString);\r
-        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
-        return EFI_DEVICE_ERROR;\r
-      }\r
-\r
-      break;\r
-\r
-    case CHAR_BACKSPACE:\r
-      if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) {\r
-        for (Index = 0; Index < CurrentCursor - 1; Index++) {\r
-          TempString[Index] = StringPtr[Index];\r
-        }\r
-        Count = GetStringWidth (StringPtr) / 2 - 1;\r
-        if (Count >= CurrentCursor) {\r
-          for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) {\r
-            TempString[Index] = StringPtr[Index2];\r
-          }\r
-          TempString[Index] = CHAR_NULL;\r
-        }\r
-        //\r
-        // Effectively truncate string by 1 character\r
-        //\r
-        StrCpy (StringPtr, TempString);\r
-        CurrentCursor --;\r
-      }\r
-\r
-    default:\r
-      //\r
-      // If it is the beginning of the string, don't worry about checking maximum limits\r
-      //\r
-      if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
-        StrnCpy (StringPtr, &Key.UnicodeChar, 1);\r
-        CurrentCursor++;\r
-      } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
-        KeyPad[0] = Key.UnicodeChar;\r
-        KeyPad[1] = CHAR_NULL;\r
-        Count = GetStringWidth (StringPtr) / 2 - 1;\r
-        if (CurrentCursor < Count) {\r
-          for (Index = 0; Index < CurrentCursor; Index++) {\r
-            TempString[Index] = StringPtr[Index];\r
-          }\r
-                 TempString[Index] = CHAR_NULL;\r
-          StrCat (TempString, KeyPad);\r
-          StrCat (TempString, StringPtr + CurrentCursor);\r
-          StrCpy (StringPtr, TempString);\r
-        } else {\r
-          StrCat (StringPtr, KeyPad);\r
-        }\r
-        CurrentCursor++;\r
-      }\r
-\r
-      //\r
-      // If the width of the input string is now larger than the screen, we nee to\r
-      // adjust the index to start printing portions of the string\r
-      //\r
-      SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');\r
-      PrintStringAt (Start + 1, Top + 3, BufferedString);\r
-\r
-      if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {\r
-        Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;\r
-      } else {\r
-        Index = 0;\r
-      }\r
-\r
-      if (IsPassword) {\r
-        gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);\r
-      }\r
-\r
-      for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {\r
-        BufferedString[Count] = StringPtr[Index];\r
-\r
-        if (IsPassword) {\r
-          PrintCharAt ((UINTN)-1, (UINTN)-1, L'*');\r
-        }\r
-      }\r
-\r
-      if (!IsPassword) {\r
-        PrintStringAt (Start + 1, Top + 3, BufferedString);\r
-      }\r
-      break;\r
-    }\r
-\r
-    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
-    gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3);\r
-  } while (TRUE);\r
-\r
-}\r
-\r
-/**\r
-  Adjust the value to the correct one. Rules follow the sample:\r
-  like:  Year change:  2012.02.29 -> 2013.02.29 -> 2013.02.01\r
-         Month change: 2013.03.29 -> 2013.02.29 -> 2013.02.28\r
-\r
-  @param  QuestionValue     Pointer to current question.\r
-  @param  Sequence          The sequence of the field in the question.\r
-**/\r
-VOID\r
-AdjustQuestionValue (\r
-  IN  EFI_HII_VALUE           *QuestionValue,\r
-  IN  UINT8                   Sequence\r
-  )\r
-{\r
-  UINT8     Month;\r
-  UINT16    Year;\r
-  UINT8     Maximum;\r
-  UINT8     Minimum;\r
-\r
-  Month   = QuestionValue->Value.date.Month;\r
-  Year    = QuestionValue->Value.date.Year;\r
-  Minimum = 1;\r
-\r
-  switch (Month) {\r
-  case 2:\r
-    if ((Year % 4) == 0 && ((Year % 100) != 0 || (Year % 400) == 0)) {\r
-      Maximum = 29;\r
-    } else {\r
-      Maximum = 28;\r
-    }\r
-    break;\r
-  case 4:\r
-  case 6:\r
-  case 9:\r
-  case 11:\r
-    Maximum = 30;\r
-    break;\r
-  default:\r
-    Maximum = 31;\r
-    break;\r
-  }\r
-\r
-  //\r
-  // Change the month area.\r
-  //\r
-  if (Sequence == 0) {\r
-    if (QuestionValue->Value.date.Day > Maximum) {\r
-      QuestionValue->Value.date.Day = Maximum;\r
-    }\r
-  }\r
-  \r
-  //\r
-  // Change the Year area.\r
-  //\r
-  if (Sequence == 2) {\r
-    if (QuestionValue->Value.date.Day > Maximum) {\r
-      QuestionValue->Value.date.Day = Minimum;\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Get field info from numeric opcode.\r
-\r
-  @param  OpCode            Pointer to the current input opcode.\r
-  @param  Minimum           The minimum size info for this opcode.\r
-  @param  Maximum           The maximum size info for this opcode.\r
-  @param  Step              The step size info for this opcode.\r
-  @param  StorageWidth      The storage width info for this opcode.\r
-\r
-**/\r
-VOID\r
-GetValueFromNum (\r
-  IN  EFI_IFR_OP_HEADER     *OpCode,\r
-  OUT UINT64                *Minimum,\r
-  OUT UINT64                *Maximum,\r
-  OUT UINT64                *Step,\r
-  OUT UINT16                *StorageWidth\r
-)\r
-{\r
-  EFI_IFR_NUMERIC       *NumericOp;\r
-\r
-  NumericOp = (EFI_IFR_NUMERIC *) OpCode;\r
-  \r
-  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {\r
-  case EFI_IFR_NUMERIC_SIZE_1:\r
-    *Minimum = NumericOp->data.u8.MinValue;\r
-    *Maximum = NumericOp->data.u8.MaxValue;\r
-    *Step    = NumericOp->data.u8.Step;\r
-    *StorageWidth = (UINT16) sizeof (UINT8);\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_2:\r
-    *Minimum = NumericOp->data.u16.MinValue;\r
-    *Maximum = NumericOp->data.u16.MaxValue;\r
-    *Step    = NumericOp->data.u16.Step;\r
-    *StorageWidth = (UINT16) sizeof (UINT16);\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_4:\r
-    *Minimum = NumericOp->data.u32.MinValue;\r
-    *Maximum = NumericOp->data.u32.MaxValue;\r
-    *Step    = NumericOp->data.u32.Step;\r
-    *StorageWidth = (UINT16) sizeof (UINT32);\r
-    break;\r
-  \r
-  case EFI_IFR_NUMERIC_SIZE_8:\r
-    *Minimum = NumericOp->data.u64.MinValue;\r
-    *Maximum = NumericOp->data.u64.MaxValue;\r
-    *Step    = NumericOp->data.u64.Step;\r
-    *StorageWidth = (UINT16) sizeof (UINT64);\r
-    break;\r
-  \r
-  default:\r
-    break;\r
-  }\r
-\r
-  if (*Maximum == 0) {\r
-    *Maximum = (UINT64) -1;\r
-  }\r
-}\r
-\r
-/**\r
-  This routine reads a numeric value from the user input.\r
-\r
-  @param  MenuOption        Pointer to the current input menu.\r
-\r
-  @retval EFI_SUCCESS       If numerical input is read successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-GetNumericInput (\r
-  IN  UI_MENU_OPTION              *MenuOption\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  UINTN                   Column;\r
-  UINTN                   Row;\r
-  CHAR16                  InputText[MAX_NUMERIC_INPUT_WIDTH];\r
-  CHAR16                  FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1];\r
-  UINT64                  PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3];\r
-  UINTN                   Count;\r
-  UINTN                   Loop;\r
-  BOOLEAN                 ManualInput;\r
-  BOOLEAN                 HexInput;\r
-  BOOLEAN                 DateOrTime;\r
-  UINTN                   InputWidth;\r
-  UINT64                  EditValue;\r
-  UINT64                  Step;\r
-  UINT64                  Minimum;\r
-  UINT64                  Maximum;\r
-  UINTN                   EraseLen;\r
-  UINT8                   Digital;\r
-  EFI_INPUT_KEY           Key;\r
-  EFI_HII_VALUE           *QuestionValue;\r
-  FORM_DISPLAY_ENGINE_STATEMENT  *Question;\r
-  EFI_IFR_NUMERIC                *NumericOp;\r
-  UINT16                         StorageWidth;\r
-\r
-  Column            = MenuOption->OptCol;\r
-  Row               = MenuOption->Row;\r
-  PreviousNumber[0] = 0;\r
-  Count             = 0;\r
-  InputWidth        = 0;\r
-  Digital           = 0;\r
-  StorageWidth      = 0;\r
-  Minimum           = 0;\r
-  Maximum           = 0;\r
-  NumericOp         = NULL;\r
-\r
-  Question      = MenuOption->ThisTag;\r
-  QuestionValue = &Question->CurrentValue;\r
-\r
-  //\r
-  // Only two case, user can enter to this function: Enter and +/- case.\r
-  // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT\r
-  //\r
-  ManualInput        = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE);\r
-\r
-  if ((Question->OpCode->OpCode == EFI_IFR_DATE_OP) || (Question->OpCode->OpCode == EFI_IFR_TIME_OP)) {\r
-    DateOrTime = TRUE;\r
-  } else {\r
-    DateOrTime = FALSE;\r
-  }\r
-\r
-  //\r
-  // Prepare Value to be edit\r
-  //\r
-  EraseLen = 0;\r
-  EditValue = 0;\r
-  if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-    Step = 1;\r
-    Minimum = 1;\r
-\r
-    switch (MenuOption->Sequence) {\r
-    case 0:\r
-      Maximum = 12;\r
-      EraseLen = 4;\r
-      EditValue = QuestionValue->Value.date.Month;\r
-      break;\r
-\r
-    case 1:\r
-      switch (QuestionValue->Value.date.Month) {\r
-      case 2:\r
-        if ((QuestionValue->Value.date.Year % 4) == 0  && \r
-            ((QuestionValue->Value.date.Year % 100) != 0 || \r
-            (QuestionValue->Value.date.Year % 400) == 0)) {\r
-          Maximum = 29;\r
-        } else {\r
-          Maximum = 28;\r
-        }\r
-        break;\r
-      case 4:\r
-      case 6:\r
-      case 9:\r
-      case 11:\r
-        Maximum = 30;\r
-        break;\r
-      default:\r
-        Maximum = 31;\r
-        break;\r
-      } \r
-\r
-      EraseLen = 3;\r
-      EditValue = QuestionValue->Value.date.Day;\r
-      break;\r
-\r
-    case 2:\r
-      Maximum = 0xffff;\r
-      EraseLen = 5;\r
-      EditValue = QuestionValue->Value.date.Year;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-    Step = 1;\r
-    Minimum = 0;\r
-\r
-    switch (MenuOption->Sequence) {\r
-    case 0:\r
-      Maximum = 23;\r
-      EraseLen = 4;\r
-      EditValue = QuestionValue->Value.time.Hour;\r
-      break;\r
-\r
-    case 1:\r
-      Maximum = 59;\r
-      EraseLen = 3;\r
-      EditValue = QuestionValue->Value.time.Minute;\r
-      break;\r
-\r
-    case 2:\r
-      Maximum = 59;\r
-      EraseLen = 3;\r
-      EditValue = QuestionValue->Value.time.Second;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-  } else {\r
-    ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP);\r
-    NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode;\r
-    GetValueFromNum(Question->OpCode, &Minimum, &Maximum, &Step, &StorageWidth);\r
-    EditValue = QuestionValue->Value.u64;\r
-    EraseLen  = gOptionBlockWidth;\r
-  }\r
-\r
-  if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) &&\r
-      ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {\r
-    HexInput = TRUE;\r
-  } else {\r
-    HexInput = FALSE;\r
-  }\r
-\r
-  //\r
-  // Enter from "Enter" input, clear the old word showing.\r
-  //\r
-  if (ManualInput) {\r
-    if (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) {\r
-      if (HexInput) {\r
-        InputWidth = StorageWidth * 2;\r
-      } else {\r
-        switch (StorageWidth) {\r
-        case 1:\r
-          InputWidth = 3;\r
-          break;\r
-\r
-        case 2:\r
-          InputWidth = 5;\r
-          break;\r
-\r
-        case 4:\r
-          InputWidth = 10;\r
-          break;\r
-\r
-        case 8:\r
-          InputWidth = 20;\r
-          break;\r
-\r
-        default:\r
-          InputWidth = 0;\r
-          break;\r
-        }\r
-      }\r
-\r
-      InputText[0] = LEFT_NUMERIC_DELIMITER;\r
-      SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
-      ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH);\r
-      InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
-      InputText[InputWidth + 2] = L'\0';\r
-\r
-      PrintStringAt (Column, Row, InputText);\r
-      Column++;\r
-    }\r
-\r
-    if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-      if (MenuOption->Sequence == 2) {\r
-        InputWidth = 4;\r
-      } else {\r
-        InputWidth = 2;\r
-      }\r
-\r
-      if (MenuOption->Sequence == 0) {\r
-        InputText[0] = LEFT_NUMERIC_DELIMITER;\r
-        SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
-      } else {\r
-        SetUnicodeMem (InputText, InputWidth, L' ');\r
-      }\r
-\r
-      if (MenuOption->Sequence == 2) {\r
-        InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
-      } else {\r
-        InputText[InputWidth + 1] = DATE_SEPARATOR;\r
-      }\r
-      InputText[InputWidth + 2] = L'\0';\r
-\r
-      PrintStringAt (Column, Row, InputText);\r
-      if (MenuOption->Sequence == 0) {\r
-        Column++;\r
-      }\r
-    }\r
-\r
-    if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-      InputWidth = 2;\r
-\r
-      if (MenuOption->Sequence == 0) {\r
-        InputText[0] = LEFT_NUMERIC_DELIMITER;\r
-        SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
-      } else {\r
-        SetUnicodeMem (InputText, InputWidth, L' ');\r
-      }\r
-\r
-      if (MenuOption->Sequence == 2) {\r
-        InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
-      } else {\r
-        InputText[InputWidth + 1] = TIME_SEPARATOR;\r
-      }\r
-      InputText[InputWidth + 2] = L'\0';\r
-\r
-      PrintStringAt (Column, Row, InputText);\r
-      if (MenuOption->Sequence == 0) {\r
-        Column++;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // First time we enter this handler, we need to check to see if\r
-  // we were passed an increment or decrement directive\r
-  //\r
-  do {\r
-    Key.UnicodeChar = CHAR_NULL;\r
-    if (gDirection != 0) {\r
-      Key.ScanCode  = gDirection;\r
-      gDirection    = 0;\r
-      goto TheKey2;\r
-    }\r
-\r
-    Status = WaitForKeyStroke (&Key);\r
-\r
-TheKey2:\r
-    switch (Key.UnicodeChar) {\r
-\r
-    case '+':\r
-    case '-':\r
-      if (Key.UnicodeChar == '+') {\r
-        Key.ScanCode = SCAN_RIGHT;\r
-      } else {\r
-        Key.ScanCode = SCAN_LEFT;\r
-      }\r
-      Key.UnicodeChar = CHAR_NULL;\r
-      goto TheKey2;\r
-\r
-    case CHAR_NULL:\r
-      switch (Key.ScanCode) {\r
-      case SCAN_LEFT:\r
-      case SCAN_RIGHT:\r
-        if (DateOrTime && !ManualInput) {\r
-          //\r
-          // By setting this value, we will return back to the caller.\r
-          // We need to do this since an auto-refresh will destroy the adjustment\r
-          // based on what the real-time-clock is showing.  So we always commit\r
-          // upon changing the value.\r
-          //\r
-          gDirection = SCAN_DOWN;\r
-        }\r
-\r
-        if ((Step != 0) && !ManualInput) {\r
-          if (Key.ScanCode == SCAN_LEFT) {\r
-            if (EditValue >= Minimum + Step) {\r
-              EditValue = EditValue - Step;\r
-            } else if (EditValue > Minimum){\r
-              EditValue = Minimum;\r
-            } else {\r
-              EditValue = Maximum;\r
-            }\r
-          } else if (Key.ScanCode == SCAN_RIGHT) {\r
-            if (EditValue + Step <= Maximum) {\r
-              EditValue = EditValue + Step;\r
-            } else if (EditValue < Maximum) {\r
-              EditValue = Maximum;\r
-            } else {\r
-              EditValue = Minimum;\r
-            }\r
-          }\r
-\r
-          ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
-          if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-            if (MenuOption->Sequence == 2) {\r
-              //\r
-              // Year\r
-              //\r
-              UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINT16) EditValue);\r
-            } else {\r
-              //\r
-              // Month/Day\r
-              //\r
-              UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);\r
-            }\r
-\r
-            if (MenuOption->Sequence == 0) {\r
-              ASSERT (EraseLen >= 2);\r
-              FormattedNumber[EraseLen - 2] = DATE_SEPARATOR;\r
-            } else if (MenuOption->Sequence == 1) {\r
-              ASSERT (EraseLen >= 1);\r
-              FormattedNumber[EraseLen - 1] = DATE_SEPARATOR;\r
-            }\r
-          } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
-            UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);\r
-\r
-            if (MenuOption->Sequence == 0) {\r
-              ASSERT (EraseLen >= 2);\r
-              FormattedNumber[EraseLen - 2] = TIME_SEPARATOR;\r
-            } else if (MenuOption->Sequence == 1) {\r
-              ASSERT (EraseLen >= 1);\r
-              FormattedNumber[EraseLen - 1] = TIME_SEPARATOR;\r
-            }\r
-          } else {\r
-            QuestionValue->Value.u64 = EditValue;\r
-            PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));\r
-          }\r
-\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());\r
-          for (Loop = 0; Loop < EraseLen; Loop++) {\r
-            PrintStringAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");\r
-          }\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
-\r
-          if (MenuOption->Sequence == 0) {\r
-            PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);\r
-            Column = MenuOption->OptCol + 1;\r
-          }\r
-\r
-          PrintStringAt (Column, Row, FormattedNumber);\r
-\r
-          if (!DateOrTime || MenuOption->Sequence == 2) {\r
-            PrintCharAt ((UINTN)-1, (UINTN)-1, RIGHT_NUMERIC_DELIMITER);\r
-          }\r
-        }\r
-\r
-        goto EnterCarriageReturn;\r
-        break;\r
-\r
-      case SCAN_UP:\r
-      case SCAN_DOWN:\r
-        goto EnterCarriageReturn;\r
-\r
-      case SCAN_ESC:\r
-        return EFI_DEVICE_ERROR;\r
-\r
-      default:\r
-        break;\r
-      }\r
-\r
-      break;\r
-\r
-EnterCarriageReturn:\r
-\r
-    case CHAR_CARRIAGE_RETURN:\r
-      //\r
-      // Validate input value with Minimum value.\r
-      //\r
-      if (EditValue < Minimum) {\r
-        UpdateStatusBar (INPUT_ERROR, TRUE);\r
-        break;\r
-      } else {\r
-        UpdateStatusBar (INPUT_ERROR, FALSE);\r
-      }\r
-      \r
-      CopyMem (&gUserInput->InputValue, &Question->CurrentValue, sizeof (EFI_HII_VALUE));\r
-      QuestionValue = &gUserInput->InputValue;\r
-      //\r
-      // Store Edit value back to Question\r
-      //\r
-      if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
-        switch (MenuOption->Sequence) {\r
-        case 0:\r
-          QuestionValue->Value.date.Month = (UINT8) EditValue;\r
-          break;\r
-\r
-        case 1:\r
-          QuestionValue->Value.date.Day = (UINT8) EditValue;\r
-          break;\r
-\r
-        case 2:\r
-          QuestionValue->Value.date.Year = (UINT16) EditValue;\r
-          break;\r
-\r
-        default:\r
-          break;\r
-        }\r
-      } else if (Question->OpCode->OpCode  == EFI_IFR_TIME_OP) {\r
-        switch (MenuOption->Sequence) {\r
-        case 0:\r
-          QuestionValue->Value.time.Hour = (UINT8) EditValue;\r
-          break;\r
-\r
-        case 1:\r
-          QuestionValue->Value.time.Minute = (UINT8) EditValue;\r
-          break;\r
-\r
-        case 2:\r
-          QuestionValue->Value.time.Second = (UINT8) EditValue;\r
-          break;\r
-\r
-        default:\r
-          break;\r
-        }\r
-      } else {\r
-        //\r
-        // Numeric\r
-        //\r
-        QuestionValue->Value.u64 = EditValue;\r
-      }\r
-\r
-      //\r
-      // Adjust the value to the correct one.\r
-      // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01\r
-      //              2013.03.29 -> 2013.02.29 -> 2013.02.28\r
-      //\r
-      if (Question->OpCode->OpCode  == EFI_IFR_DATE_OP && \r
-        (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) {\r
-        AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence);\r
-      }\r
-\r
-      return ValidateQuestion (Question);\r
-      break;\r
-\r
-    case CHAR_BACKSPACE:\r
-      if (ManualInput) {\r
-        if (Count == 0) {\r
-          break;\r
-        }\r
-        //\r
-        // Remove a character\r
-        //\r
-        EditValue = PreviousNumber[Count - 1];\r
-        UpdateStatusBar (INPUT_ERROR,  FALSE);\r
-        Count--;\r
-        Column--;\r
-        PrintStringAt (Column, Row, L" ");\r
-      }\r
-      break;\r
-\r
-    default:\r
-      if (ManualInput) {\r
-        if (HexInput) {\r
-          if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) {\r
-            Digital = (UINT8) (Key.UnicodeChar - L'0');\r
-          } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) {\r
-            Digital = (UINT8) (Key.UnicodeChar - L'A' + 0x0A);\r
-          } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {\r
-            Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A);\r
-          } else {\r
-            UpdateStatusBar (INPUT_ERROR, TRUE);\r
-            break;\r
-          }\r
-        } else {\r
-          if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {\r
-            UpdateStatusBar (INPUT_ERROR, TRUE);\r
-            break;\r
-          }\r
-        }\r
-\r
-        //\r
-        // If Count exceed input width, there is no way more is valid\r
-        //\r
-        if (Count >= InputWidth) {\r
-          break;\r
-        }\r
-        //\r
-        // Someone typed something valid!\r
-        //\r
-        if (Count != 0) {\r
-          if (HexInput) {\r
-            EditValue = LShiftU64 (EditValue, 4) + Digital;\r
-          } else {\r
-            EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');\r
-          }\r
-        } else {\r
-          if (HexInput) {\r
-            EditValue = Digital;\r
-          } else {\r
-            EditValue = Key.UnicodeChar - L'0';\r
-          }\r
-        }\r
-\r
-        if (EditValue > Maximum) {\r
-          UpdateStatusBar (INPUT_ERROR, TRUE);\r
-          ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0]));\r
-          EditValue = PreviousNumber[Count];\r
-          break;\r
-        } else {\r
-          UpdateStatusBar (INPUT_ERROR, FALSE);\r
-        }\r
-\r
-        Count++;\r
-        ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0])));\r
-        PreviousNumber[Count] = EditValue;\r
-\r
-        gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());\r
-        PrintCharAt (Column, Row, Key.UnicodeChar);\r
-        Column++;\r
-      }\r
-      break;\r
-    }\r
-  } while (TRUE);\r
-}\r
-\r
-/**\r
-  Adjust option order base on the question value.\r
-\r
-  @param  Question           Pointer to current question.\r
-  @param  PopUpMenuLines     The line number of the pop up menu.\r
-\r
-  @retval EFI_SUCCESS       If Option input is processed successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-AdjustOptionOrder (\r
-  IN  FORM_DISPLAY_ENGINE_STATEMENT  *Question,\r
-  OUT UINTN                          *PopUpMenuLines\r
-  )\r
-{\r
-  UINTN                   Index;\r
-  EFI_IFR_ORDERED_LIST    *OrderList;\r
-  UINT8                   *ValueArray;\r
-  UINT8                   ValueType;\r
-  LIST_ENTRY              *Link;\r
-  DISPLAY_QUESTION_OPTION *OneOfOption;\r
-  EFI_HII_VALUE           *HiiValueArray;\r
-\r
-  Link        = GetFirstNode (&Question->OptionListHead);\r
-  OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-  ValueArray  = Question->CurrentValue.Buffer;\r
-  ValueType   =  OneOfOption->OptionOpCode->Type;\r
-  OrderList   = (EFI_IFR_ORDERED_LIST *) Question->OpCode;\r
-\r
-  for (Index = 0; Index < OrderList->MaxContainers; Index++) {\r
-    if (GetArrayData (ValueArray, ValueType, Index) == 0) {\r
-      break;\r
-    }\r
-  }\r
-  \r
-  *PopUpMenuLines = Index;\r
-  \r
-  //\r
-  // Prepare HiiValue array\r
-  //  \r
-  HiiValueArray = AllocateZeroPool (*PopUpMenuLines * sizeof (EFI_HII_VALUE));\r
-  ASSERT (HiiValueArray != NULL);\r
-\r
-  for (Index = 0; Index < *PopUpMenuLines; Index++) {\r
-    HiiValueArray[Index].Type = ValueType;\r
-    HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
-  }\r
-  \r
-  for (Index = 0; Index < *PopUpMenuLines; Index++) {\r
-    OneOfOption = ValueToOption (Question, &HiiValueArray[*PopUpMenuLines - Index - 1]);\r
-    if (OneOfOption == NULL) {\r
-      return EFI_NOT_FOUND;\r
-    }\r
-  \r
-    RemoveEntryList (&OneOfOption->Link);\r
-  \r
-    //\r
-    // Insert to head.\r
-    //\r
-    InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);\r
-  }\r
-  \r
-  FreePool (HiiValueArray);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Base on the type to compare the value.\r
-\r
-  @param  Value1                The first value need to compare.\r
-  @param  Value2                The second value need to compare.\r
-  @param  Type                  The value type for above two values.\r
-\r
-  @retval TRUE                  The two value are same.\r
-  @retval FALSE                 The two value are different.\r
-\r
-**/\r
-BOOLEAN\r
-IsValuesEqual (\r
-  IN EFI_IFR_TYPE_VALUE *Value1,\r
-  IN EFI_IFR_TYPE_VALUE *Value2,\r
-  IN UINT8              Type\r
-  )\r
-{\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_BOOLEAN:\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    return (BOOLEAN) (Value1->u8 == Value2->u8);\r
-  \r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    return (BOOLEAN) (Value1->u16 == Value2->u16);\r
-  \r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    return (BOOLEAN) (Value1->u32 == Value2->u32);\r
-  \r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    return (BOOLEAN) (Value1->u64 == Value2->u64);\r
-\r
-  default:\r
-    ASSERT (FALSE);\r
-    return FALSE;\r
-  }\r
-}\r
-\r
-/**\r
-  Base on the type to set the value.\r
-\r
-  @param  Dest                  The dest value.\r
-  @param  Source                The source value.\r
-  @param  Type                  The value type for above two values.\r
-\r
-**/\r
-VOID\r
-SetValuesByType (\r
-  OUT EFI_IFR_TYPE_VALUE *Dest,\r
-  IN  EFI_IFR_TYPE_VALUE *Source,\r
-  IN  UINT8              Type\r
-  )\r
-{\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_BOOLEAN:\r
-    Dest->b = Source->b;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    Dest->u8 = Source->u8;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    Dest->u16 = Source->u16;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    Dest->u32 = Source->u32;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    Dest->u64 = Source->u64;\r
-    break;\r
-\r
-  default:\r
-    ASSERT (FALSE);\r
-    break;\r
-  }\r
-}\r
-\r
-/**\r
-  Get selection for OneOf and OrderedList (Left/Right will be ignored).\r
-\r
-  @param  MenuOption        Pointer to the current input menu.\r
-\r
-  @retval EFI_SUCCESS       If Option input is processed successfully\r
-  @retval EFI_DEVICE_ERROR  If operation fails\r
-\r
-**/\r
-EFI_STATUS\r
-GetSelectionInputPopUp (\r
-  IN  UI_MENU_OPTION              *MenuOption\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_INPUT_KEY           Key;\r
-  UINTN                   Index;\r
-  CHAR16                  *StringPtr;\r
-  CHAR16                  *TempStringPtr;\r
-  UINTN                   Index2;\r
-  UINTN                   TopOptionIndex;\r
-  UINTN                   HighlightOptionIndex;\r
-  UINTN                   Start;\r
-  UINTN                   End;\r
-  UINTN                   Top;\r
-  UINTN                   Bottom;\r
-  UINTN                   PopUpMenuLines;\r
-  UINTN                   MenuLinesInView;\r
-  UINTN                   PopUpWidth;\r
-  CHAR16                  Character;\r
-  INT32                   SavedAttribute;\r
-  BOOLEAN                 ShowDownArrow;\r
-  BOOLEAN                 ShowUpArrow;\r
-  UINTN                   DimensionsWidth;\r
-  LIST_ENTRY              *Link;\r
-  BOOLEAN                 OrderedList;\r
-  UINT8                   *ValueArray;\r
-  UINT8                   *ReturnValue;\r
-  UINT8                   ValueType;\r
-  EFI_HII_VALUE           HiiValue;\r
-  DISPLAY_QUESTION_OPTION         *OneOfOption;\r
-  DISPLAY_QUESTION_OPTION         *CurrentOption;\r
-  FORM_DISPLAY_ENGINE_STATEMENT  *Question;\r
-  INTN                    Result;\r
-  EFI_IFR_ORDERED_LIST    *OrderList;\r
-\r
-  DimensionsWidth   = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;\r
-\r
-  ValueArray        = NULL;\r
-  ValueType         = 0;\r
-  CurrentOption     = NULL;\r
-  ShowDownArrow     = FALSE;\r
-  ShowUpArrow       = FALSE;\r
-\r
-  StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);\r
-  ASSERT (StringPtr);\r
-\r
-  ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE));\r
-\r
-  Question = MenuOption->ThisTag;\r
-  if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
-    Link = GetFirstNode (&Question->OptionListHead);\r
-    OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-    ValueArray = Question->CurrentValue.Buffer;\r
-    ValueType =  OneOfOption->OptionOpCode->Type;\r
-    OrderedList = TRUE;\r
-    OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;\r
-  } else {\r
-    OrderedList = FALSE;\r
-    OrderList = NULL;\r
-  }\r
-\r
-  //\r
-  // Calculate Option count\r
-  //\r
-  PopUpMenuLines = 0;\r
-  if (OrderedList) {\r
-    AdjustOptionOrder(Question, &PopUpMenuLines);\r
-  } else {\r
-    Link = GetFirstNode (&Question->OptionListHead);\r
-    while (!IsNull (&Question->OptionListHead, Link)) {\r
-      OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-      PopUpMenuLines++;\r
-      Link = GetNextNode (&Question->OptionListHead, Link);\r
-    }\r
-  }\r
-\r
-  //\r
-  // Get the number of one of options present and its size\r
-  //\r
-  PopUpWidth = 0;\r
-  HighlightOptionIndex = 0;\r
-  Link = GetFirstNode (&Question->OptionListHead);\r
-  for (Index = 0; Index < PopUpMenuLines; Index++) {\r
-    OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-\r
-    StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
-    if (StrLen (StringPtr) > PopUpWidth) {\r
-      PopUpWidth = StrLen (StringPtr);\r
-    }\r
-    FreePool (StringPtr);\r
-    HiiValue.Type = OneOfOption->OptionOpCode->Type;\r
-    SetValuesByType (&HiiValue.Value, &OneOfOption->OptionOpCode->Value, HiiValue.Type);\r
-    if (!OrderedList && (CompareHiiValue (&Question->CurrentValue, &HiiValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
-      //\r
-      // Find current selected Option for OneOf\r
-      //\r
-      HighlightOptionIndex = Index;\r
-    }\r
-\r
-    Link = GetNextNode (&Question->OptionListHead, Link);\r
-  }\r
-\r
-  //\r
-  // Perform popup menu initialization.\r
-  //\r
-  PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;\r
-\r
-  SavedAttribute = gST->ConOut->Mode->Attribute;\r
-  gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-\r
-  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {\r
-    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;\r
-  }\r
-\r
-  Start  = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gStatementDimensions.LeftColumn;\r
-  End    = Start + PopUpWidth + POPUP_FRAME_WIDTH;\r
-  Top    = gStatementDimensions.TopRow;\r
-  Bottom = gStatementDimensions.BottomRow - 1;\r
-\r
-  MenuLinesInView = Bottom - Top - 1;\r
-  if (MenuLinesInView >= PopUpMenuLines) {\r
-    Top     = Top + (MenuLinesInView - PopUpMenuLines) / 2;\r
-    Bottom  = Top + PopUpMenuLines + 1;\r
-  } else {\r
-    ShowDownArrow = TRUE;\r
-  }\r
-\r
-  if (HighlightOptionIndex > (MenuLinesInView - 1)) {\r
-    TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1;\r
-  } else {\r
-    TopOptionIndex = 0;\r
-  }\r
-\r
-  do {\r
-    //\r
-    // Clear that portion of the screen\r
-    //\r
-    ClearLines (Start, End, Top, Bottom, GetPopupColor ());\r
-\r
-    //\r
-    // Draw "One of" pop-up menu\r
-    //\r
-    Character = BOXDRAW_DOWN_RIGHT;\r
-    PrintCharAt (Start, Top, Character);\r
-    for (Index = Start; Index + 2 < End; Index++) {\r
-      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {\r
-        Character = GEOMETRICSHAPE_UP_TRIANGLE;\r
-      } else {\r
-        Character = BOXDRAW_HORIZONTAL;\r
-      }\r
-\r
-      PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-    }\r
-\r
-    Character = BOXDRAW_DOWN_LEFT;\r
-    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-    Character = BOXDRAW_VERTICAL;\r
-    for (Index = Top + 1; Index < Bottom; Index++) {\r
-      PrintCharAt (Start, Index, Character);\r
-      PrintCharAt (End - 1, Index, Character);\r
-    }\r
-\r
-    //\r
-    // Move to top Option\r
-    //\r
-    Link = GetFirstNode (&Question->OptionListHead);\r
-    for (Index = 0; Index < TopOptionIndex; Index++) {\r
-      Link = GetNextNode (&Question->OptionListHead, Link);\r
-    }\r
-\r
-    //\r
-    // Display the One of options\r
-    //\r
-    Index2 = Top + 1;\r
-    for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {\r
-      OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-      Link = GetNextNode (&Question->OptionListHead, Link);\r
-\r
-      StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
-      ASSERT (StringPtr != NULL);\r
-      //\r
-      // If the string occupies multiple lines, truncate it to fit in one line,\r
-      // and append a "..." for indication.\r
-      //\r
-      if (StrLen (StringPtr) > (PopUpWidth - 1)) {\r
-        TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));\r
-        ASSERT ( TempStringPtr != NULL );\r
-        CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));\r
-        FreePool (StringPtr);\r
-        StringPtr = TempStringPtr;\r
-        StrCat (StringPtr, L"...");\r
-      }\r
-\r
-      if (Index == HighlightOptionIndex) {\r
-          //\r
-          // Highlight the selected one\r
-          //\r
-          CurrentOption = OneOfOption;\r
-\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetPickListColor ());\r
-          PrintStringAt (Start + 2, Index2, StringPtr);\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-        } else {\r
-          gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-          PrintStringAt (Start + 2, Index2, StringPtr);\r
-        }\r
-\r
-      Index2++;\r
-      FreePool (StringPtr);\r
-    }\r
-\r
-    Character = BOXDRAW_UP_RIGHT;\r
-    PrintCharAt (Start, Bottom, Character);\r
-    for (Index = Start; Index + 2 < End; Index++) {\r
-      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {\r
-        Character = GEOMETRICSHAPE_DOWN_TRIANGLE;\r
-      } else {\r
-        Character = BOXDRAW_HORIZONTAL;\r
-      }\r
-\r
-      PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-    }\r
-\r
-    Character = BOXDRAW_UP_LEFT;\r
-    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-\r
-    //\r
-    // Get User selection\r
-    //\r
-    Key.UnicodeChar = CHAR_NULL;\r
-    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {\r
-      Key.ScanCode  = gDirection;\r
-      gDirection    = 0;\r
-      goto TheKey;\r
-    }\r
-\r
-    Status = WaitForKeyStroke (&Key);\r
-\r
-TheKey:\r
-    switch (Key.UnicodeChar) {\r
-    case '+':\r
-      if (OrderedList) {\r
-        if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {\r
-          //\r
-          // Highlight reaches the top of the popup window, scroll one menu item.\r
-          //\r
-          TopOptionIndex--;\r
-          ShowDownArrow = TRUE;\r
-        }\r
-\r
-        if (TopOptionIndex == 0) {\r
-          ShowUpArrow = FALSE;\r
-        }\r
-\r
-        if (HighlightOptionIndex > 0) {\r
-          HighlightOptionIndex--;\r
-\r
-          ASSERT (CurrentOption != NULL);\r
-          SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link);\r
-        }\r
-      }\r
-      break;\r
-\r
-    case '-':\r
-      //\r
-      // If an ordered list op-code, we will allow for a popup of +/- keys\r
-      // to create an ordered list of items\r
-      //\r
-      if (OrderedList) {\r
-        if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&\r
-            (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {\r
-          //\r
-          // Highlight reaches the bottom of the popup window, scroll one menu item.\r
-          //\r
-          TopOptionIndex++;\r
-          ShowUpArrow = TRUE;\r
-        }\r
-\r
-        if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {\r
-          ShowDownArrow = FALSE;\r
-        }\r
-\r
-        if (HighlightOptionIndex < (PopUpMenuLines - 1)) {\r
-          HighlightOptionIndex++;\r
-\r
-          ASSERT (CurrentOption != NULL);\r
-          SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink);\r
-        }\r
-      }\r
-      break;\r
-\r
-    case CHAR_NULL:\r
-      switch (Key.ScanCode) {\r
-      case SCAN_UP:\r
-      case SCAN_DOWN:\r
-        if (Key.ScanCode == SCAN_UP) {\r
-          if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {\r
-            //\r
-            // Highlight reaches the top of the popup window, scroll one menu item.\r
-            //\r
-            TopOptionIndex--;\r
-            ShowDownArrow = TRUE;\r
-          }\r
-\r
-          if (TopOptionIndex == 0) {\r
-            ShowUpArrow = FALSE;\r
-          }\r
-\r
-          if (HighlightOptionIndex > 0) {\r
-            HighlightOptionIndex--;\r
-          }\r
-        } else {\r
-          if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&\r
-              (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {\r
-            //\r
-            // Highlight reaches the bottom of the popup window, scroll one menu item.\r
-            //\r
-            TopOptionIndex++;\r
-            ShowUpArrow = TRUE;\r
-          }\r
-\r
-          if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {\r
-            ShowDownArrow = FALSE;\r
-          }\r
-\r
-          if (HighlightOptionIndex < (PopUpMenuLines - 1)) {\r
-            HighlightOptionIndex++;\r
-          }\r
-        }\r
-        break;\r
-\r
-      case SCAN_ESC:\r
-        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);\r
-\r
-        //\r
-        // Restore link list order for orderedlist\r
-        //\r
-        if (OrderedList) {\r
-          HiiValue.Type = ValueType;\r
-          HiiValue.Value.u64 = 0;\r
-          for (Index = 0; Index < OrderList->MaxContainers; Index++) {\r
-            HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
-            if (HiiValue.Value.u64 == 0) {\r
-              break;\r
-            }\r
-\r
-            OneOfOption = ValueToOption (Question, &HiiValue);\r
-            if (OneOfOption == NULL) {\r
-              return EFI_NOT_FOUND;\r
-            }\r
-\r
-            RemoveEntryList (&OneOfOption->Link);\r
-            InsertTailList (&Question->OptionListHead, &OneOfOption->Link);\r
-          }\r
-        }\r
-\r
-        return EFI_DEVICE_ERROR;\r
-\r
-      default:\r
-        break;\r
-      }\r
-\r
-      break;\r
-\r
-    case CHAR_CARRIAGE_RETURN:\r
-      //\r
-      // return the current selection\r
-      //\r
-      if (OrderedList) {\r
-        ReturnValue = AllocateZeroPool (Question->CurrentValue.BufferLen);\r
-        ASSERT (ReturnValue != NULL);\r
-        Index = 0;\r
-        Link = GetFirstNode (&Question->OptionListHead);\r
-        while (!IsNull (&Question->OptionListHead, Link)) {\r
-          OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-          Link = GetNextNode (&Question->OptionListHead, Link);\r
-\r
-          SetArrayData (ReturnValue, ValueType, Index, OneOfOption->OptionOpCode->Value.u64);\r
-\r
-          Index++;\r
-          if (Index > OrderList->MaxContainers) {\r
-            break;\r
-          }\r
-        }\r
-        if (CompareMem (ReturnValue, ValueArray, Question->CurrentValue.BufferLen) == 0) {\r
-          FreePool (ReturnValue);\r
-          return EFI_DEVICE_ERROR;\r
-        } else {\r
-          gUserInput->InputValue.Buffer = ReturnValue;\r
-          gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
-          Status = EFI_SUCCESS;\r
-        }\r
-      } else {\r
-        ASSERT (CurrentOption != NULL);\r
-        gUserInput->InputValue.Type = CurrentOption->OptionOpCode->Type;\r
-        if (IsValuesEqual (&Question->CurrentValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type)) {\r
-          return EFI_DEVICE_ERROR;\r
-        } else {\r
-          SetValuesByType (&gUserInput->InputValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type);\r
-          Status = EFI_SUCCESS;\r
-        }\r
-      }\r
-\r
-      gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);\r
-\r
-      return ValidateQuestion (Question);\r
-      \r
-    default:\r
-      break;\r
-    }\r
-  } while (TRUE);\r
-\r
-}\r
-\r
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
deleted file mode 100644 (file)
index aca043a..0000000
+++ /dev/null
@@ -1,1286 +0,0 @@
-/** @file\r
-Implementation for handling the User Interface option processing.\r
-\r
-\r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "FormDisplay.h"\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
-  Compare two Hii value.\r
-\r
-  @param  Value1                 Expression value to compare on left-hand.\r
-  @param  Value2                 Expression value to compare on right-hand.\r
-  @param  Result                 Return value after compare.\r
-                                 retval 0                      Two operators equal.\r
-                                 return Positive value if Value1 is greater than Value2.\r
-                                 retval Negative value if Value1 is less than Value2.\r
-  @param  HiiHandle              Only required for string compare.\r
-\r
-  @retval other                  Could not perform compare on two values.\r
-  @retval EFI_SUCCESS            Compare the value success.\r
-\r
-**/\r
-EFI_STATUS\r
-CompareHiiValue (\r
-  IN  EFI_HII_VALUE   *Value1,\r
-  IN  EFI_HII_VALUE   *Value2,\r
-  OUT INTN            *Result,\r
-  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL\r
-  )\r
-{\r
-  INT64   Temp64;\r
-  CHAR16  *Str1;\r
-  CHAR16  *Str2;\r
-  UINTN   Len;\r
-\r
-  if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
-    if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  }\r
-\r
-  if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
-    if (Value1->Type != Value2->Type) {\r
-      //\r
-      // Both Operator should be type of String\r
-      //\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-    if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
-      //\r
-      // StringId 0 is reserved\r
-      //\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if (Value1->Value.string == Value2->Value.string) {\r
-      *Result = 0;\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    Str1 = GetToken (Value1->Value.string, HiiHandle);\r
-    if (Str1 == NULL) {\r
-      //\r
-      // String not found\r
-      //\r
-      return EFI_NOT_FOUND;\r
-    }\r
-\r
-    Str2 = GetToken (Value2->Value.string, HiiHandle);\r
-    if (Str2 == NULL) {\r
-      FreePool (Str1);\r
-      return EFI_NOT_FOUND;\r
-    }\r
-\r
-    *Result = StrCmp (Str1, Str2);\r
-\r
-    FreePool (Str1);\r
-    FreePool (Str2);\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
-    if (Value1->Type != Value2->Type) {\r
-      //\r
-      // Both Operator should be type of Buffer.\r
-      //\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-    Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
-    *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
-    if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
-    {\r
-      //\r
-      // In this case, means base on samll number buffer, the data is same\r
-      // So which value has more data, which value is bigger.\r
-      //\r
-      *Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
-    }\r
-    return EFI_SUCCESS;\r
-  }  \r
-\r
-  //\r
-  // Take remain types(integer, boolean, date/time) as integer\r
-  //\r
-  Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
-  if (Temp64 > 0) {\r
-    *Result = 1;\r
-  } else if (Temp64 < 0) {\r
-    *Result = -1;\r
-  } else {\r
-    *Result = 0;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Search an Option of a Question by its value.\r
-\r
-  @param  Question               The Question\r
-  @param  OptionValue            Value for Option to be searched.\r
-\r
-  @retval Pointer                Pointer to the found Option.\r
-  @retval NULL                   Option not found.\r
-\r
-**/\r
-DISPLAY_QUESTION_OPTION *\r
-ValueToOption (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question,\r
-  IN EFI_HII_VALUE                   *OptionValue\r
-  )\r
-{\r
-  LIST_ENTRY               *Link;\r
-  DISPLAY_QUESTION_OPTION  *Option;\r
-  INTN                     Result;\r
-  EFI_HII_VALUE            Value;\r
-\r
-  Link = GetFirstNode (&Question->OptionListHead);\r
-  while (!IsNull (&Question->OptionListHead, Link)) {\r
-    Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-\r
-    ZeroMem (&Value, sizeof (EFI_HII_VALUE));\r
-    Value.Type = Option->OptionOpCode->Type;\r
-    CopyMem (&Value.Value, &Option->OptionOpCode->Value, Option->OptionOpCode->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
-    \r
-    if ((CompareHiiValue (&Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
-      return Option;\r
-    }\r
-\r
-    Link = GetNextNode (&Question->OptionListHead, Link);\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Return data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-\r
-  @retval Value                  The data to be returned\r
-\r
-**/\r
-UINT64\r
-GetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index\r
-  )\r
-{\r
-  UINT64 Data;\r
-\r
-  ASSERT (Array != NULL);\r
-\r
-  Data = 0;\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    Data = (UINT64) *(((UINT8 *) Array) + Index);\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    Data = (UINT64) *(((UINT16 *) Array) + Index);\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    Data = (UINT64) *(((UINT32 *) Array) + Index);\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    Data = (UINT64) *(((UINT64 *) Array) + Index);\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return Data;\r
-}\r
-\r
-\r
-/**\r
-  Set value of a data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-  @param  Value                  The value to be set.\r
-\r
-**/\r
-VOID\r
-SetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index,\r
-  IN UINT64                   Value\r
-  )\r
-{\r
-\r
-  ASSERT (Array != NULL);\r
-\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-}\r
-\r
-/**\r
-  Check whether this value already in the array, if yes, return the index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Value                  The value to be find.\r
-  @param  Index                  The index in the array which has same value with Value.\r
-  \r
-  @retval   TRUE Found the value in the array.\r
-  @retval   FALSE Not found the value.\r
-\r
-**/\r
-BOOLEAN \r
-FindArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINT64                   Value,\r
-  OUT UINTN                   *Index OPTIONAL\r
-  )\r
-{\r
-  UINTN  Count;\r
-  UINT64 TmpValue;\r
-  UINT64 ValueComp;\r
-  \r
-  ASSERT (Array != NULL);\r
-\r
-  Count    = 0;\r
-  TmpValue = 0;\r
-\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    ValueComp = (UINT8) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    ValueComp = (UINT16) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    ValueComp = (UINT32) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    ValueComp = (UINT64) Value;\r
-    break;\r
-\r
-  default:\r
-    ValueComp = 0;\r
-    break;\r
-  }\r
-\r
-  while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {\r
-    if (ValueComp == TmpValue) {\r
-      if (Index != NULL) {\r
-        *Index = Count;\r
-      }\r
-      return TRUE;\r
-    }\r
-\r
-    Count ++;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Print Question Value according to it's storage width and display attributes.\r
-\r
-  @param  Question               The Question to be printed.\r
-  @param  FormattedNumber        Buffer for output string.\r
-  @param  BufferSize             The FormattedNumber buffer size in bytes.\r
-\r
-  @retval EFI_SUCCESS            Print success.\r
-  @retval EFI_BUFFER_TOO_SMALL   Buffer size is not enough for formatted number.\r
-\r
-**/\r
-EFI_STATUS\r
-PrintFormattedNumber (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question,\r
-  IN OUT CHAR16               *FormattedNumber,\r
-  IN UINTN                    BufferSize\r
-  )\r
-{\r
-  INT64          Value;\r
-  CHAR16         *Format;\r
-  EFI_HII_VALUE  *QuestionValue;\r
-  EFI_IFR_NUMERIC *NumericOp;\r
-\r
-  if (BufferSize < (21 * sizeof (CHAR16))) {\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  QuestionValue = &Question->CurrentValue;\r
-  NumericOp     = (EFI_IFR_NUMERIC *) Question->OpCode;\r
-\r
-  Value = (INT64) QuestionValue->Value.u64;\r
-  switch (NumericOp->Flags & EFI_IFR_DISPLAY) {\r
-  case EFI_IFR_DISPLAY_INT_DEC:\r
-    switch (QuestionValue->Type) {\r
-    case EFI_IFR_NUMERIC_SIZE_1:\r
-      Value = (INT64) ((INT8) QuestionValue->Value.u8);\r
-      break;\r
-\r
-    case EFI_IFR_NUMERIC_SIZE_2:\r
-      Value = (INT64) ((INT16) QuestionValue->Value.u16);\r
-      break;\r
-\r
-    case EFI_IFR_NUMERIC_SIZE_4:\r
-      Value = (INT64) ((INT32) QuestionValue->Value.u32);\r
-      break;\r
-\r
-    case EFI_IFR_NUMERIC_SIZE_8:\r
-    default:\r
-      break;\r
-    }\r
-\r
-    if (Value < 0) {\r
-      Value = -Value;\r
-      Format = L"-%ld";\r
-    } else {\r
-      Format = L"%ld";\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_DISPLAY_UINT_DEC:\r
-    Format = L"%ld";\r
-    break;\r
-\r
-  case EFI_IFR_DISPLAY_UINT_HEX:\r
-    Format = L"%lx";\r
-    break;\r
-\r
-  default:\r
-    return EFI_UNSUPPORTED;\r
-    break;\r
-  }\r
-\r
-  UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Draw a pop up windows based on the dimension, number of lines and\r
-  strings specified.\r
-\r
-  @param RequestedWidth  The width of the pop-up.\r
-  @param NumberOfLines   The number of lines.\r
-  @param Marker          The variable argument list for the list of string to be printed.\r
-\r
-**/\r
-VOID\r
-CreateSharedPopUp (\r
-  IN  UINTN                       RequestedWidth,\r
-  IN  UINTN                       NumberOfLines,\r
-  IN  VA_LIST                     Marker\r
-  )\r
-{\r
-  UINTN   Index;\r
-  UINTN   Count;\r
-  CHAR16  Character;\r
-  UINTN   Start;\r
-  UINTN   End;\r
-  UINTN   Top;\r
-  UINTN   Bottom;\r
-  CHAR16  *String;\r
-  UINTN   DimensionsWidth;\r
-  UINTN   DimensionsHeight;\r
-\r
-  DimensionsWidth   = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;\r
-  DimensionsHeight  = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;\r
-\r
-  gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-\r
-  if ((RequestedWidth + 2) > DimensionsWidth) {\r
-    RequestedWidth = DimensionsWidth - 2;\r
-  }\r
-\r
-  //\r
-  // Subtract the PopUp width from total Columns, allow for one space extra on\r
-  // each end plus a border.\r
-  //\r
-  Start     = (DimensionsWidth - RequestedWidth - 2) / 2 + gStatementDimensions.LeftColumn + 1;\r
-  End       = Start + RequestedWidth + 1;\r
-\r
-  Top       = ((DimensionsHeight - NumberOfLines - 2) / 2) + gStatementDimensions.TopRow - 1;\r
-  Bottom    = Top + NumberOfLines + 2;\r
-\r
-  Character = BOXDRAW_DOWN_RIGHT;\r
-  PrintCharAt (Start, Top, Character);\r
-  Character = BOXDRAW_HORIZONTAL;\r
-  for (Index = Start; Index + 2 < End; Index++) {\r
-    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-  }\r
-\r
-  Character = BOXDRAW_DOWN_LEFT;\r
-  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-  Character = BOXDRAW_VERTICAL;\r
-\r
-  Count = 0;\r
-  for (Index = Top; Index + 2 < Bottom; Index++, Count++) {\r
-    String = VA_ARG (Marker, CHAR16*);\r
-\r
-    //\r
-    // This will clear the background of the line - we never know who might have been\r
-    // here before us.  This differs from the next clear in that it used the non-reverse\r
-    // video for normal printing.\r
-    //\r
-    if (GetStringWidth (String) / 2 > 1) {\r
-      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());\r
-    }\r
-\r
-    //\r
-    // Passing in a space results in the assumption that this is where typing will occur\r
-    //\r
-    if (String[0] == L' ') {\r
-      ClearLines (Start + 1, End - 1, Index + 1, Index + 1, GetPopupInverseColor ());\r
-    }\r
-\r
-    //\r
-    // Passing in a NULL results in a blank space\r
-    //\r
-    if (String[0] == CHAR_NULL) {\r
-      ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());\r
-    }\r
-\r
-    PrintStringAt (\r
-      ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gStatementDimensions.LeftColumn + 1,\r
-      Index + 1,\r
-      String\r
-      );\r
-    gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
-    PrintCharAt (Start, Index + 1, Character);\r
-    PrintCharAt (End - 1, Index + 1, Character);\r
-  }\r
-\r
-  Character = BOXDRAW_UP_RIGHT;\r
-  PrintCharAt (Start, Bottom - 1, Character);\r
-  Character = BOXDRAW_HORIZONTAL;\r
-  for (Index = Start; Index + 2 < End; Index++) {\r
-    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-  }\r
-\r
-  Character = BOXDRAW_UP_LEFT;\r
-  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
-}\r
-\r
-/**\r
-  Draw a pop up windows based on the dimension, number of lines and\r
-  strings specified.\r
-\r
-  @param RequestedWidth  The width of the pop-up.\r
-  @param NumberOfLines   The number of lines.\r
-  @param ...             A series of text strings that displayed in the pop-up.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CreateMultiStringPopUp (\r
-  IN  UINTN                       RequestedWidth,\r
-  IN  UINTN                       NumberOfLines,\r
-  ...\r
-  )\r
-{\r
-  VA_LIST Marker;\r
-\r
-  VA_START (Marker, NumberOfLines);\r
-\r
-  CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);\r
-\r
-  VA_END (Marker);\r
-}\r
-\r
-/**\r
-  Process validate for one question.\r
-\r
-  @param  Question               The question need to be validate.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval EFI_INVALID_PARAMETER  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS \r
-ValidateQuestion (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT   *Question\r
-  )\r
-{\r
-  CHAR16                          *ErrorInfo;\r
-  EFI_INPUT_KEY                   Key;\r
-  EFI_STATUS                      Status;\r
-  STATEMENT_ERROR_INFO            RetInfo;\r
-  UINT32                          RetVal;\r
-\r
-  if (Question->ValidateQuestion == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Status = EFI_SUCCESS; \r
-  RetVal = Question->ValidateQuestion(gFormData, Question, &gUserInput->InputValue, &RetInfo);\r
\r
-  switch (RetVal) {\r
-  case INCOSISTENT_IF_TRUE:\r
-    //\r
-    // Condition meet, show up error message\r
-    //\r
-    ASSERT (RetInfo.StringId != 0);\r
-    ErrorInfo = GetToken (RetInfo.StringId, gFormData->HiiHandle);\r
-    do {\r
-      CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
-    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-    FreePool (ErrorInfo);\r
-\r
-    Status = EFI_INVALID_PARAMETER;\r
-  break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Display error message for invalid password.\r
-\r
-**/\r
-VOID\r
-PasswordInvalid (\r
-  VOID\r
-  )\r
-{\r
-  EFI_INPUT_KEY  Key;\r
-\r
-  //\r
-  // Invalid password, prompt error message\r
-  //\r
-  do {\r
-    CreateDialog (&Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString, NULL);\r
-  } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-}\r
-\r
-/**\r
-  Process password op code.\r
-\r
-  @param  MenuOption             The menu for current password op code.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval Other                  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS\r
-PasswordProcess (\r
-  IN  UI_MENU_OPTION              *MenuOption\r
-  )\r
-{\r
-  CHAR16                          *StringPtr;\r
-  CHAR16                          *TempString;\r
-  UINTN                           Maximum;\r
-  EFI_STATUS                      Status;\r
-  EFI_IFR_PASSWORD                *PasswordInfo;\r
-  FORM_DISPLAY_ENGINE_STATEMENT   *Question;\r
-  EFI_INPUT_KEY                   Key;\r
-\r
-  Question     = MenuOption->ThisTag;\r
-  PasswordInfo = (EFI_IFR_PASSWORD *) Question->OpCode;\r
-  Maximum      = PasswordInfo->MaxSize;\r
-  Status       = EFI_SUCCESS;\r
-\r
-  StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));\r
-  ASSERT (StringPtr);\r
-  \r
-  //\r
-  // Use a NULL password to test whether old password is required\r
-  //\r
-  *StringPtr = 0;\r
-  Status = Question->PasswordCheck (gFormData, Question, StringPtr);\r
-  if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {\r
-    //\r
-    // Password can't be set now. \r
-    //\r
-    FreePool (StringPtr);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // Old password exist, ask user for the old password\r
-    //\r
-    Status = ReadString (MenuOption, gPromptForPassword, StringPtr);\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (StringPtr);\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Check user input old password\r
-    //\r
-    Status = Question->PasswordCheck (gFormData, Question, StringPtr);\r
-    if (EFI_ERROR (Status)) {\r
-      if (Status == EFI_NOT_READY) {\r
-        //\r
-        // Typed in old password incorrect\r
-        //\r
-        PasswordInvalid ();\r
-      } else {\r
-        Status = EFI_SUCCESS;\r
-      }\r
-\r
-      FreePool (StringPtr);\r
-      return Status;\r
-    }\r
-  }\r
-  \r
-  //\r
-  // Ask for new password\r
-  //\r
-  ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
-  Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // Reset state machine for password\r
-    //\r
-    Question->PasswordCheck (gFormData, Question, NULL);\r
-    FreePool (StringPtr);\r
-    return Status;\r
-  }\r
-  \r
-  //\r
-  // Confirm new password\r
-  //\r
-  TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));\r
-  ASSERT (TempString);\r
-  Status = ReadString (MenuOption, gConfirmPassword, TempString);\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // Reset state machine for password\r
-    //\r
-    Question->PasswordCheck (gFormData, Question, NULL);\r
-    FreePool (StringPtr);\r
-    FreePool (TempString);\r
-    return Status;\r
-  }\r
-  \r
-  //\r
-  // Compare two typed-in new passwords\r
-  //\r
-  if (StrCmp (StringPtr, TempString) == 0) {     \r
-    gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);\r
-    gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
-    gUserInput->InputValue.Type = Question->CurrentValue.Type;\r
-    gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);\r
-    FreePool (StringPtr); \r
-\r
-    Status = ValidateQuestion (Question);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      //\r
-      // Reset state machine for password\r
-      //\r
-      Question->PasswordCheck (gFormData, Question, NULL);\r
-    }\r
-\r
-    return Status;\r
-  } else {\r
-    //\r
-    // Reset state machine for password\r
-    //\r
-    Question->PasswordCheck (gFormData, Question, NULL);\r
-  \r
-    //\r
-    // Two password mismatch, prompt error message\r
-    //\r
-    do {\r
-      CreateDialog (&Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString, NULL);\r
-    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-\r
-    Status = EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  FreePool (TempString);\r
-  FreePool (StringPtr);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Process a Question's Option (whether selected or un-selected).\r
-\r
-  @param  MenuOption             The MenuOption for this Question.\r
-  @param  Selected               TRUE: if Question is selected.\r
-  @param  OptionString           Pointer of the Option String to be displayed.\r
-  @param  SkipErrorValue         Whether need to return when value without option for it.\r
-\r
-  @retval EFI_SUCCESS            Question Option process success.\r
-  @retval Other                  Question Option process fail.\r
-\r
-**/\r
-EFI_STATUS\r
-ProcessOptions (\r
-  IN  UI_MENU_OPTION              *MenuOption,\r
-  IN  BOOLEAN                     Selected,\r
-  OUT CHAR16                      **OptionString,\r
-  IN  BOOLEAN                     SkipErrorValue\r
-  )\r
-{\r
-  EFI_STATUS                      Status;\r
-  CHAR16                          *StringPtr;\r
-  UINTN                           Index;\r
-  FORM_DISPLAY_ENGINE_STATEMENT   *Question;\r
-  CHAR16                          FormattedNumber[21];\r
-  UINT16                          Number;\r
-  CHAR16                          Character[2];\r
-  EFI_INPUT_KEY                   Key;\r
-  UINTN                           BufferSize;\r
-  DISPLAY_QUESTION_OPTION         *OneOfOption;\r
-  LIST_ENTRY                      *Link;\r
-  EFI_HII_VALUE                   HiiValue;\r
-  EFI_HII_VALUE                   *QuestionValue;\r
-  DISPLAY_QUESTION_OPTION         *Option;\r
-  UINTN                           Index2;\r
-  UINT8                           *ValueArray;\r
-  UINT8                           ValueType;\r
-  EFI_STRING_ID                   StringId;\r
-  EFI_IFR_ORDERED_LIST            *OrderList;\r
-  BOOLEAN                         ValueInvalid;\r
-\r
-  Status        = EFI_SUCCESS;\r
-\r
-  StringPtr     = NULL;\r
-  Character[1]  = L'\0';\r
-  *OptionString = NULL;\r
-  StringId      = 0;\r
-  ValueInvalid  = FALSE;\r
-\r
-  ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
-  BufferSize = (gOptionBlockWidth + 1) * 2 * gStatementDimensions.BottomRow;\r
-\r
-  Question = MenuOption->ThisTag;\r
-  QuestionValue = &Question->CurrentValue;\r
-\r
-  switch (Question->OpCode->OpCode) {\r
-  case EFI_IFR_ORDERED_LIST_OP:\r
-\r
-    //\r
-    // Check whether there are Options of this OrderedList\r
-    //\r
-    if (IsListEmpty (&Question->OptionListHead)) {\r
-      break;\r
-    }\r
-\r
-    OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;\r
-\r
-    Link = GetFirstNode (&Question->OptionListHead);\r
-    OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-\r
-    ValueType =  OneOfOption->OptionOpCode->Type;\r
-    ValueArray = Question->CurrentValue.Buffer;\r
-\r
-    if (Selected) {\r
-      //\r
-      // Go ask for input\r
-      //\r
-      Status = GetSelectionInputPopUp (MenuOption);\r
-    } else {\r
-      //\r
-      // We now know how many strings we will have, so we can allocate the\r
-      // space required for the array or strings.\r
-      //\r
-      *OptionString = AllocateZeroPool (OrderList->MaxContainers * BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      HiiValue.Type = ValueType;\r
-      HiiValue.Value.u64 = 0;\r
-      for (Index = 0; Index < OrderList->MaxContainers; Index++) {\r
-        HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
-        if (HiiValue.Value.u64 == 0) {\r
-          //\r
-          // Values for the options in ordered lists should never be a 0\r
-          //\r
-          break;\r
-        }\r
-\r
-        OneOfOption = ValueToOption (Question, &HiiValue);\r
-        if (OneOfOption == NULL) {\r
-          if (SkipErrorValue) {\r
-            //\r
-            // Just try to get the option string, skip the value which not has option.\r
-            //\r
-            continue;\r
-          }\r
-\r
-          //\r
-          // Show error message\r
-          //\r
-          do {\r
-            CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);\r
-          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-\r
-          //\r
-          // The initial value of the orderedlist is invalid, force to be valid value\r
-          // Exit current DisplayForm with new value.\r
-          //\r
-          gUserInput->SelectedStatement = Question;\r
-          \r
-          ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen);\r
-          ASSERT (ValueArray != NULL);\r
-          gUserInput->InputValue.Buffer    = ValueArray;\r
-          gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
-          gUserInput->InputValue.Type      = Question->CurrentValue.Type;\r
-          \r
-          Link = GetFirstNode (&Question->OptionListHead);\r
-          Index2 = 0;\r
-          while (!IsNull (&Question->OptionListHead, Link) && Index2 < OrderList->MaxContainers) {\r
-            Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-            Link = GetNextNode (&Question->OptionListHead, Link);\r
-            SetArrayData (ValueArray, ValueType, Index2, Option->OptionOpCode->Value.u64);\r
-            Index2++;\r
-          }\r
-          SetArrayData (ValueArray, ValueType, Index2, 0);\r
-\r
-          FreePool (*OptionString);\r
-          *OptionString = NULL;\r
-          return EFI_NOT_FOUND;\r
-        }\r
-\r
-        Character[0] = LEFT_ONEOF_DELIMITER;\r
-        NewStrCat (OptionString[0], Character);\r
-        StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
-        ASSERT (StringPtr != NULL);\r
-        NewStrCat (OptionString[0], StringPtr);\r
-        Character[0] = RIGHT_ONEOF_DELIMITER;\r
-        NewStrCat (OptionString[0], Character);\r
-        Character[0] = CHAR_CARRIAGE_RETURN;\r
-        NewStrCat (OptionString[0], Character);\r
-        FreePool (StringPtr);\r
-      }\r
-\r
-      //\r
-      // If valid option more than the max container, skip these options.\r
-      //\r
-      if (Index >= OrderList->MaxContainers) {\r
-        break;\r
-      }\r
-\r
-      //\r
-      // Search the other options, try to find the one not in the container.\r
-      //\r
-      Link = GetFirstNode (&Question->OptionListHead);\r
-      while (!IsNull (&Question->OptionListHead, Link)) {\r
-        OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-        Link = GetNextNode (&Question->OptionListHead, Link);\r
-\r
-        if (FindArrayData (ValueArray, ValueType, OneOfOption->OptionOpCode->Value.u64, NULL)) {\r
-          continue;\r
-        }\r
-\r
-        if (SkipErrorValue) {\r
-          //\r
-          // Not report error, just get the correct option string info.\r
-          //\r
-          Character[0] = LEFT_ONEOF_DELIMITER;\r
-          NewStrCat (OptionString[0], Character);\r
-          StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
-          ASSERT (StringPtr != NULL);\r
-          NewStrCat (OptionString[0], StringPtr);\r
-          Character[0] = RIGHT_ONEOF_DELIMITER;\r
-          NewStrCat (OptionString[0], Character);\r
-          Character[0] = CHAR_CARRIAGE_RETURN;\r
-          NewStrCat (OptionString[0], Character);\r
-          FreePool (StringPtr);\r
-\r
-          continue;\r
-        }\r
-\r
-        if (!ValueInvalid) {\r
-          ValueInvalid = TRUE;\r
-          //\r
-          // Show error message\r
-          //\r
-          do {\r
-            CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);\r
-          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-\r
-          //\r
-          // The initial value of the orderedlist is invalid, force to be valid value\r
-          // Exit current DisplayForm with new value.\r
-          //\r
-          gUserInput->SelectedStatement = Question;\r
-          \r
-          ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer);\r
-          ASSERT (ValueArray != NULL);\r
-          gUserInput->InputValue.Buffer    = ValueArray;\r
-          gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
-          gUserInput->InputValue.Type      = Question->CurrentValue.Type;\r
-        }\r
-       \r
-        SetArrayData (ValueArray, ValueType, Index++, OneOfOption->OptionOpCode->Value.u64);\r
-      }\r
-\r
-      if (ValueInvalid) {\r
-        FreePool (*OptionString);\r
-        *OptionString = NULL;\r
-        return EFI_NOT_FOUND;\r
-      }\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_ONE_OF_OP:\r
-    //\r
-    // Check whether there are Options of this OneOf\r
-    //\r
-    if (IsListEmpty (&Question->OptionListHead)) {\r
-      break;\r
-    }\r
-    if (Selected) {\r
-      //\r
-      // Go ask for input\r
-      //\r
-      Status = GetSelectionInputPopUp (MenuOption);\r
-    } else {\r
-      *OptionString = AllocateZeroPool (BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      OneOfOption = ValueToOption (Question, QuestionValue);\r
-      if (OneOfOption == NULL) {\r
-        if (SkipErrorValue) {\r
-          //\r
-          // Not report error, just get the correct option string info.\r
-          //          \r
-          Link = GetFirstNode (&Question->OptionListHead);\r
-          OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-        } else {\r
-          //\r
-          // Show error message\r
-          //\r
-          do {\r
-            CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);\r
-          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
-\r
-          //\r
-          // Force the Question value to be valid\r
-          // Exit current DisplayForm with new value.\r
-          //\r
-          Link = GetFirstNode (&Question->OptionListHead);\r
-          Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);\r
-\r
-          CopyMem (&gUserInput->InputValue.Value, &Option->OptionOpCode->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
-          gUserInput->InputValue.Type = Option->OptionOpCode->Type;\r
-          gUserInput->SelectedStatement = Question;\r
-\r
-          FreePool (*OptionString);\r
-          *OptionString = NULL;\r
-          return EFI_NOT_FOUND;\r
-        }\r
-      }\r
-\r
-      Character[0] = LEFT_ONEOF_DELIMITER;\r
-      NewStrCat (OptionString[0], Character);\r
-      StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);\r
-      ASSERT (StringPtr != NULL);\r
-      NewStrCat (OptionString[0], StringPtr);\r
-      Character[0] = RIGHT_ONEOF_DELIMITER;\r
-      NewStrCat (OptionString[0], Character);\r
-\r
-      FreePool (StringPtr);\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_CHECKBOX_OP:\r
-    if (Selected) {\r
-      //\r
-      // Since this is a BOOLEAN operation, flip it upon selection\r
-      //\r
-      gUserInput->InputValue.Type    = QuestionValue->Type;\r
-      gUserInput->InputValue.Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);\r
-\r
-      //\r
-      // Perform inconsistent check\r
-      //\r
-      return ValidateQuestion (Question);\r
-    } else {    \r
-      *OptionString = AllocateZeroPool (BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      *OptionString[0] = LEFT_CHECKBOX_DELIMITER;\r
-\r
-      if (QuestionValue->Value.b) {\r
-        *(OptionString[0] + 1) = CHECK_ON;\r
-      } else {\r
-        *(OptionString[0] + 1) = CHECK_OFF;\r
-      }\r
-      *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_NUMERIC_OP:\r
-    if (Selected) {\r
-      //\r
-      // Go ask for input\r
-      //\r
-      Status = GetNumericInput (MenuOption);\r
-    } else {\r
-      *OptionString = AllocateZeroPool (BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
-\r
-      //\r
-      // Formatted print\r
-      //\r
-      PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));\r
-      Number = (UINT16) GetStringWidth (FormattedNumber);\r
-      CopyMem (OptionString[0] + 1, FormattedNumber, Number);\r
-\r
-      *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_DATE_OP:\r
-    if (Selected) {\r
-      //\r
-      // This is similar to numerics\r
-      //\r
-      Status = GetNumericInput (MenuOption);\r
-    } else {\r
-      *OptionString = AllocateZeroPool (BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      switch (MenuOption->Sequence) {\r
-      case 0:\r
-        *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
-        UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);\r
-        *(OptionString[0] + 3) = DATE_SEPARATOR;\r
-        break;\r
-\r
-      case 1:\r
-        SetUnicodeMem (OptionString[0], 4, L' ');\r
-        UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);\r
-        *(OptionString[0] + 6) = DATE_SEPARATOR;\r
-        break;\r
-\r
-      case 2:\r
-        SetUnicodeMem (OptionString[0], 7, L' ');\r
-        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);\r
-        *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;\r
-        break;\r
-      }\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_TIME_OP:\r
-    if (Selected) {\r
-      //\r
-      // This is similar to numerics\r
-      //\r
-      Status = GetNumericInput (MenuOption);\r
-    } else {\r
-      *OptionString = AllocateZeroPool (BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      switch (MenuOption->Sequence) {\r
-      case 0:\r
-        *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
-        UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);\r
-        *(OptionString[0] + 3) = TIME_SEPARATOR;\r
-        break;\r
-\r
-      case 1:\r
-        SetUnicodeMem (OptionString[0], 4, L' ');\r
-        UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);\r
-        *(OptionString[0] + 6) = TIME_SEPARATOR;\r
-        break;\r
-\r
-      case 2:\r
-        SetUnicodeMem (OptionString[0], 7, L' ');\r
-        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);\r
-        *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;\r
-        break;\r
-      }\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_STRING_OP:\r
-    if (Selected) {\r
-      StringPtr = AllocateZeroPool (Question->CurrentValue.BufferLen + sizeof (CHAR16));\r
-      ASSERT (StringPtr);\r
-      CopyMem(StringPtr, Question->CurrentValue.Buffer, Question->CurrentValue.BufferLen);\r
-\r
-      Status = ReadString (MenuOption, gPromptForData, StringPtr);\r
-      if (EFI_ERROR (Status)) {\r
-        FreePool (StringPtr);\r
-        return Status;\r
-      }\r
-      \r
-      gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);\r
-      gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;\r
-      gUserInput->InputValue.Type = Question->CurrentValue.Type;\r
-      gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);\r
-      FreePool (StringPtr);\r
-      return ValidateQuestion (Question);\r
-    } else {\r
-      *OptionString = AllocateZeroPool (BufferSize);\r
-      ASSERT (*OptionString);\r
-\r
-      if (((CHAR16 *) Question->CurrentValue.Buffer)[0] == 0x0000) {\r
-        *(OptionString[0]) = '_';\r
-      } else {\r
-        if (Question->CurrentValue.BufferLen < BufferSize) {\r
-          BufferSize = Question->CurrentValue.BufferLen;\r
-        }\r
-        CopyMem (OptionString[0], (CHAR16 *) Question->CurrentValue.Buffer, BufferSize);\r
-      }\r
-    }\r
-    break;\r
-\r
-  case EFI_IFR_PASSWORD_OP:\r
-    if (Selected) {\r
-      Status = PasswordProcess (MenuOption);\r
-    }\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Process the help string: Split StringPtr to several lines of strings stored in\r
-  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.\r
-\r
-  @param  StringPtr              The entire help string.\r
-  @param  FormattedString        The oupput formatted string.\r
-  @param  EachLineWidth          The max string length of each line in the formatted string.\r
-  @param  RowCount               TRUE: if Question is selected.\r
-\r
-**/\r
-UINTN\r
-ProcessHelpString (\r
-  IN  CHAR16  *StringPtr,\r
-  OUT CHAR16  **FormattedString,\r
-  OUT UINT16  *EachLineWidth,\r
-  IN  UINTN   RowCount\r
-  )\r
-{\r
-  UINTN   Index;\r
-  CHAR16  *OutputString;\r
-  UINTN   TotalRowNum;\r
-  UINTN   CheckedNum;\r
-  UINT16  GlyphWidth;\r
-  UINT16  LineWidth;\r
-  UINT16  MaxStringLen;\r
-  UINT16  StringLen;\r
-\r
-  TotalRowNum    = 0;\r
-  CheckedNum     = 0;\r
-  GlyphWidth     = 1;\r
-  Index          = 0;\r
-  MaxStringLen   = 0;\r
-  StringLen      = 0;\r
-\r
-  //\r
-  // Set default help string width.\r
-  //\r
-  LineWidth      = (UINT16) (gHelpBlockWidth - 1);\r
-\r
-  //\r
-  // Get row number of the String.\r
-  //\r
-  while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {\r
-    if (StringLen > MaxStringLen) {\r
-      MaxStringLen = StringLen;\r
-    }\r
-\r
-    TotalRowNum ++;\r
-    FreePool (OutputString);\r
-  }\r
-  *EachLineWidth = MaxStringLen;\r
-\r
-  *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));\r
-  ASSERT (*FormattedString != NULL);\r
-\r
-  //\r
-  // Generate formatted help string array.\r
-  //\r
-  GlyphWidth  = 1;\r
-  Index       = 0;\r
-  while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {\r
-    CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));\r
-    CheckedNum ++;\r
-    FreePool (OutputString);\r
-  }\r
-\r
-  return TotalRowNum; \r
-}\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h b/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h
new file mode 100644 (file)
index 0000000..2db8b99
--- /dev/null
@@ -0,0 +1,44 @@
+/** @file\r
+MACRO definitions for color used in Setup Browser.\r
+\r
+Copyright (c) 2004 - 2011, 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
+// Unicode collation protocol in\r
+\r
+#ifndef _COLORS_H_\r
+#define _COLORS_H_\r
+\r
+//\r
+// Screen Color Settings\r
+//\r
+#define PICKLIST_HIGHLIGHT_TEXT       EFI_WHITE\r
+#define PICKLIST_HIGHLIGHT_BACKGROUND EFI_BACKGROUND_CYAN\r
+#define TITLE_TEXT                    EFI_WHITE\r
+#define TITLE_BACKGROUND              EFI_BACKGROUND_BLUE\r
+#define KEYHELP_TEXT                  EFI_LIGHTGRAY\r
+#define KEYHELP_BACKGROUND            EFI_BACKGROUND_BLACK\r
+#define SUBTITLE_BACKGROUND           EFI_BACKGROUND_LIGHTGRAY\r
+#define BANNER_TEXT                   EFI_BLUE\r
+#define BANNER_BACKGROUND             EFI_BACKGROUND_LIGHTGRAY\r
+#define FIELD_TEXT_GRAYED             EFI_DARKGRAY\r
+#define FIELD_BACKGROUND              EFI_BACKGROUND_LIGHTGRAY\r
+#define POPUP_TEXT                    EFI_LIGHTGRAY\r
+#define POPUP_BACKGROUND              EFI_BACKGROUND_BLUE\r
+#define POPUP_INVERSE_TEXT            EFI_LIGHTGRAY\r
+#define POPUP_INVERSE_BACKGROUND      EFI_BACKGROUND_BLACK\r
+#define HELP_TEXT                     EFI_BLUE\r
+#define ERROR_TEXT                    EFI_RED | EFI_BRIGHT\r
+#define INFO_TEXT                     EFI_YELLOW | EFI_BRIGHT\r
+#define ARROW_TEXT                    EFI_RED | EFI_BRIGHT\r
+#define ARROW_BACKGROUND              EFI_BACKGROUND_LIGHTGRAY\r
+\r
+#endif\r
index 44dae1ba03c76f77d79fdf3d7da0ed31e97910f2..cd29e294385ccc5adf1d58b84ed9bda1317f5594 100644 (file)
@@ -787,7 +787,7 @@ FORM_BROWSER_FORM *
 IdToForm (\r
   IN FORM_BROWSER_FORMSET  *FormSet,\r
   IN UINT16                FormId\r
 IdToForm (\r
   IN FORM_BROWSER_FORMSET  *FormSet,\r
   IN UINT16                FormId\r
-  )\r
+)\r
 {\r
   LIST_ENTRY         *Link;\r
   FORM_BROWSER_FORM  *Form;\r
 {\r
   LIST_ENTRY         *Link;\r
   FORM_BROWSER_FORM  *Form;\r
@@ -2105,7 +2105,7 @@ GetQuestionValueFromForm (
   //\r
   FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
   ASSERT (FormSet != NULL);\r
   //\r
   FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
   ASSERT (FormSet != NULL);\r
-  Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet);\r
+  Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet, FALSE);\r
   if (EFI_ERROR (Status)) {\r
     GetTheVal = FALSE;\r
     goto Done;\r
   if (EFI_ERROR (Status)) {\r
     GetTheVal = FALSE;\r
     goto Done;\r
@@ -2800,7 +2800,7 @@ EvaluateExpression (
             for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
               StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
             }\r
             for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
               StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
             }\r
-            Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);\r
+            Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer);\r
             FreePool (NameValue);\r
             if (!EFI_ERROR (Status)) {\r
               Data1.Value.b = TRUE;\r
             FreePool (NameValue);\r
             if (!EFI_ERROR (Status)) {\r
               Data1.Value.b = TRUE;\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h
deleted file mode 100644 (file)
index 5660a99..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/** @file\r
-Private structure, MACRO and function definitions for User Interface related functionalities.\r
-\r
-Copyright (c) 2004 - 2013, 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
-#ifndef _EXPRESSION_H_\r
-#define _EXPRESSION_H_\r
-\r
-/**\r
-  Get the expression list count.\r
-  \r
-  @param  Level                  Which type this expression belong to. Form, \r
-                                 statement or option?\r
-\r
-  @retval >=0                    The expression count\r
-  @retval -1                     Input parameter error.\r
-\r
-**/\r
-INTN \r
-GetConditionalExpressionCount (\r
-  IN EXPRESS_LEVEL       Level\r
-  );\r
-\r
-/**\r
-  Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetCurrentExpressionStack (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetMapExpressionListStack (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Reset stack pointer to begin of the stack.\r
-\r
-**/\r
-VOID\r
-ResetScopeStack (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Push an Operand onto the Stack\r
-\r
-  @param  Operand                Operand to push.\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
-                                 stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushScope (\r
-  IN UINT8   Operand\r
-  );\r
-\r
-/**\r
-  Get the expression Buffer pointer.\r
-  \r
-  @param  Level                  Which type this expression belong to. Form, \r
-                                 statement or option?\r
-\r
-  @retval  The start pointer of the expression buffer or NULL.\r
-\r
-**/\r
-FORM_EXPRESSION **\r
-GetConditionalExpressionList (\r
-  IN EXPRESS_LEVEL       Level\r
-  );\r
-\r
-/**\r
-  Pop an Operand from the Stack\r
-\r
-  @param  Operand                Operand to pop.\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
-                                 stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopScope (\r
-  OUT UINT8     *Operand\r
-  );\r
-\r
-/**\r
-  Push the list of map expression onto the Stack\r
-\r
-  @param  Pointer                Pointer to the list of map expression to be pushed.\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushMapExpressionList (\r
-  IN VOID  *Pointer\r
-  );\r
-\r
-/**\r
-  Push current expression onto the Stack\r
-\r
-  @param  Pointer                Pointer to current expression.\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushCurrentExpression (\r
-  IN VOID  *Pointer\r
-  );\r
-\r
-/**\r
-  Zero extend integer/boolean/date/time to UINT64 for comparing.\r
-\r
-  @param  Value                  HII Value to be converted.\r
-\r
-**/\r
-VOID\r
-ExtendValueToU64 (\r
-  IN  EFI_HII_VALUE   *Value\r
-  );\r
-\r
-/**\r
-  Push the expression options onto the Stack.\r
-\r
-  @param  Pointer                Pointer to the current expression.\r
-  @param  Level                  Which type this expression belong to. Form, \r
-                                 statement or option?\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PushConditionalExpression (\r
-  IN FORM_EXPRESSION   *Pointer,\r
-  IN EXPRESS_LEVEL     Level\r
-  );\r
-\r
-/**\r
-  Pop the expression options from the Stack\r
-\r
-  @param  Level                  Which type this expression belong to. Form, \r
-                                 statement or option?\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopConditionalExpression (\r
-  IN  EXPRESS_LEVEL      Level\r
-  );\r
-\r
-/**\r
-  Pop the list of map expression from the Stack\r
-\r
-  @param  Pointer                Pointer to the list of map expression to be pop.\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopMapExpressionList (\r
-  OUT VOID    **Pointer\r
-  );\r
-\r
-/**\r
-  Pop current expression from the Stack\r
-\r
-  @param  Pointer                Pointer to current expression to be pop.\r
-\r
-  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-PopCurrentExpression (\r
-  OUT VOID    **Pointer\r
-  );\r
-\r
-/**\r
-  Evaluate the result of a HII expression.\r
-\r
-  If Expression is NULL, then ASSERT.\r
-\r
-  @param  FormSet                FormSet associated with this expression.\r
-  @param  Form                   Form associated with this expression.\r
-  @param  Expression             Expression to be evaluated.\r
-\r
-  @retval EFI_SUCCESS            The expression evaluated successfuly\r
-  @retval EFI_NOT_FOUND          The Question which referenced by a QuestionId\r
-                                 could not be found.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
-                                 stack.\r
-  @retval EFI_ACCESS_DENIED      The pop operation underflowed the stack\r
-  @retval EFI_INVALID_PARAMETER  Syntax error with the Expression\r
-\r
-**/\r
-EFI_STATUS\r
-EvaluateExpression (\r
-  IN FORM_BROWSER_FORMSET  *FormSet,\r
-  IN FORM_BROWSER_FORM     *Form,\r
-  IN OUT FORM_EXPRESSION   *Expression\r
-  );\r
-/**\r
-  Return the result of the expression list. Check the expression list and \r
-  return the highest priority express result.  \r
-  Priority: DisableIf > SuppressIf > GrayOutIf > FALSE\r
-\r
-  @param  ExpList             The input expression list.\r
-  @param  Evaluate            Whether need to evaluate the expression first.\r
-  @param  FormSet             FormSet associated with this expression.\r
-  @param  Form                Form associated with this expression.  \r
-\r
-  @retval EXPRESS_RESULT      Return the higher priority express result. \r
-                              DisableIf > SuppressIf > GrayOutIf > FALSE\r
-\r
-**/\r
-EXPRESS_RESULT \r
-EvaluateExpressionList (\r
-  IN FORM_EXPRESSION_LIST *ExpList,\r
-  IN BOOLEAN              Evaluate,\r
-  IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL\r
-  IN FORM_BROWSER_FORM    *Form OPTIONAL\r
-  );\r
-\r
-/**\r
-  Get Form given its FormId.\r
-\r
-  @param  FormSet                The formset which contains this form.\r
-  @param  FormId                 Id of this form.\r
-\r
-  @retval Pointer                The form.\r
-  @retval NULL                   Specified Form is not found in the formset.\r
-\r
-**/\r
-FORM_BROWSER_FORM *\r
-IdToForm (\r
-  IN FORM_BROWSER_FORMSET  *FormSet,\r
-  IN UINT16                FormId\r
-  );\r
-\r
-#endif // _EXPRESSION_H\r
index 1c3ab2bedca4e1e45b6160c7b1ce027827a4501e..2464aebd095b0b561a2c9f302d52ae1dfabde546 100644 (file)
@@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 UINT16           mStatementIndex;\r
 UINT16           mExpressionOpCodeIndex;\r
 \r
 UINT16           mStatementIndex;\r
 UINT16           mExpressionOpCodeIndex;\r
-EFI_QUESTION_ID  mUsedQuestionId;\r
+\r
 BOOLEAN          mInScopeSubtitle;\r
 extern LIST_ENTRY      gBrowserStorageList;\r
 /**\r
 BOOLEAN          mInScopeSubtitle;\r
 extern LIST_ENTRY      gBrowserStorageList;\r
 /**\r
@@ -42,9 +42,9 @@ CreateStatement (
 \r
   if (Form == NULL) {\r
     //\r
 \r
   if (Form == NULL) {\r
     //\r
-    // Only guid op may out side the form level.\r
+    // We are currently not in a Form Scope, so just skip this Statement\r
     //\r
     //\r
-    ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);\r
+    return NULL;\r
   }\r
 \r
   Statement = &FormSet->StatementBuffer[mStatementIndex];\r
   }\r
 \r
   Statement = &FormSet->StatementBuffer[mStatementIndex];\r
@@ -58,7 +58,6 @@ CreateStatement (
   Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
 \r
   Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
   Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
 \r
   Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
-  Statement->OpCode  = (EFI_IFR_OP_HEADER *) OpCodeData;\r
 \r
   StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
   CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
 \r
   StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
   CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
@@ -83,11 +82,8 @@ CreateStatement (
   //\r
   // Insert this Statement into current Form\r
   //\r
   //\r
   // Insert this Statement into current Form\r
   //\r
-  if (Form == NULL) {\r
-    InsertTailList (&FormSet->StatementListOSF, &Statement->Link);\r
-  } else {\r
-    InsertTailList (&Form->StatementListHead, &Statement->Link);\r
-  }\r
+  InsertTailList (&Form->StatementListHead, &Statement->Link);\r
+\r
   return Statement;\r
 }\r
 \r
   return Statement;\r
 }\r
 \r
@@ -1137,7 +1133,6 @@ ParseOpCodes (
   CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
 \r
   mStatementIndex = 0;\r
   CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
 \r
   mStatementIndex = 0;\r
-  mUsedQuestionId = 1;\r
   FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
   if (FormSet->StatementBuffer == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
   if (FormSet->StatementBuffer == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -1149,7 +1144,6 @@ ParseOpCodes (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  InitializeListHead (&FormSet->StatementListOSF);\r
   InitializeListHead (&FormSet->StorageListHead);\r
   InitializeListHead (&FormSet->DefaultStoreListHead);\r
   InitializeListHead (&FormSet->FormListHead);\r
   InitializeListHead (&FormSet->StorageListHead);\r
   InitializeListHead (&FormSet->DefaultStoreListHead);\r
   InitializeListHead (&FormSet->FormListHead);\r
@@ -1508,6 +1502,7 @@ ParseOpCodes (
       InitializeListHead (&CurrentForm->ConfigRequestHead);\r
 \r
       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
       InitializeListHead (&CurrentForm->ConfigRequestHead);\r
 \r
       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
+      CurrentForm->NvUpdateRequired = FALSE;\r
       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
 \r
       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
 \r
@@ -1544,6 +1539,7 @@ ParseOpCodes (
       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
       ASSERT (CurrentForm != NULL);\r
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
       ASSERT (CurrentForm != NULL);\r
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+      CurrentForm->NvUpdateRequired = FALSE;\r
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
       InitializeListHead (&CurrentForm->ConfigRequestHead);\r
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
       InitializeListHead (&CurrentForm->ConfigRequestHead);\r
@@ -1657,7 +1653,7 @@ ParseOpCodes (
       ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
       ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
-      CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
+\r
       if (Scope != 0) {\r
         mInScopeSubtitle = TRUE;\r
       }\r
       if (Scope != 0) {\r
         mInScopeSubtitle = TRUE;\r
       }\r
@@ -1666,14 +1662,13 @@ ParseOpCodes (
     case EFI_IFR_TEXT_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
     case EFI_IFR_TEXT_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
-      CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
+\r
       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
       break;\r
 \r
     case EFI_IFR_RESET_BUTTON_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
       break;\r
 \r
     case EFI_IFR_RESET_BUTTON_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
       ASSERT (CurrentStatement != NULL);\r
-      CurrentStatement->FakeQuestionId = mUsedQuestionId++;\r
       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
       break;\r
 \r
       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
       break;\r
 \r
@@ -1918,7 +1913,6 @@ ParseOpCodes (
       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
       ASSERT (CurrentOption != NULL);\r
       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
       ASSERT (CurrentOption != NULL);\r
       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
-      CurrentOption->OpCode    = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;\r
 \r
       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
 \r
       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
       CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
@@ -2276,8 +2270,45 @@ ParseOpCodes (
     //\r
     // Vendor specific\r
     //\r
     //\r
     // Vendor specific\r
     //\r
-    case EFI_IFR_GUID_OP:     \r
-      CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+    case EFI_IFR_GUID_OP:\r
+      if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+        //\r
+        // Tiano specific GUIDed opcodes\r
+        //\r
+        switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
+        case EFI_IFR_EXTEND_OP_LABEL:\r
+          //\r
+          // just ignore label\r
+          //\r
+          break;\r
+\r
+        case EFI_IFR_EXTEND_OP_BANNER:\r
+          //\r
+          // By SubClass to get Banner Data from Front Page\r
+          //\r
+          if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
+            CopyMem (\r
+              &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
+              ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
+              &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
+              sizeof (EFI_STRING_ID)\r
+              );\r
+          }\r
+          break;\r
+\r
+        case EFI_IFR_EXTEND_OP_CLASS:\r
+          CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
+          break;\r
+\r
+        case EFI_IFR_EXTEND_OP_SUBCLASS:\r
+          CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+      }\r
+\r
       break;\r
 \r
     //\r
       break;\r
 \r
     //\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
new file mode 100644 (file)
index 0000000..8445907
--- /dev/null
@@ -0,0 +1,1418 @@
+/** @file\r
+Implementation for handling user input from the User Interfaces.\r
+\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Setup.h"\r
+\r
+\r
+/**\r
+  Get string or password input from user.\r
+\r
+  @param  MenuOption        Pointer to the current input menu.\r
+  @param  Prompt            The prompt string shown on popup window.\r
+  @param  StringPtr         Old user input and destination for use input string.\r
+\r
+  @retval EFI_SUCCESS       If string input is read successfully\r
+  @retval EFI_DEVICE_ERROR  If operation fails\r
+\r
+**/\r
+EFI_STATUS\r
+ReadString (\r
+  IN     UI_MENU_OPTION              *MenuOption,\r
+  IN     CHAR16                      *Prompt,\r
+  IN OUT CHAR16                      *StringPtr\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_INPUT_KEY           Key;\r
+  CHAR16                  NullCharacter;\r
+  UINTN                   ScreenSize;\r
+  CHAR16                  Space[2];\r
+  CHAR16                  KeyPad[2];\r
+  CHAR16                  *TempString;\r
+  CHAR16                  *BufferedString;\r
+  UINTN                   Index;\r
+  UINTN                   Index2;\r
+  UINTN                   Count;\r
+  UINTN                   Start;\r
+  UINTN                   Top;\r
+  UINTN                   DimensionsWidth;\r
+  UINTN                   DimensionsHeight;\r
+  UINTN                   CurrentCursor;\r
+  BOOLEAN                 CursorVisible;\r
+  UINTN                   Minimum;\r
+  UINTN                   Maximum;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+  BOOLEAN                 IsPassword;\r
+\r
+  DimensionsWidth  = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
+  DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;\r
+\r
+  NullCharacter    = CHAR_NULL;\r
+  ScreenSize       = GetStringWidth (Prompt) / sizeof (CHAR16);\r
+  Space[0]         = L' ';\r
+  Space[1]         = CHAR_NULL;\r
+\r
+  Question         = MenuOption->ThisTag;\r
+  Minimum          = (UINTN) Question->Minimum;\r
+  Maximum          = (UINTN) Question->Maximum;\r
+\r
+  if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
+    IsPassword = TRUE;\r
+  } else {\r
+    IsPassword = FALSE;\r
+  }\r
+\r
+  TempString = AllocateZeroPool ((Maximum + 1)* sizeof (CHAR16));\r
+  ASSERT (TempString);\r
+\r
+  if (ScreenSize < (Maximum + 1)) {\r
+    ScreenSize = Maximum + 1;\r
+  }\r
+\r
+  if ((ScreenSize + 2) > DimensionsWidth) {\r
+    ScreenSize = DimensionsWidth - 2;\r
+  }\r
+\r
+  BufferedString = AllocateZeroPool (ScreenSize * 2);\r
+  ASSERT (BufferedString);\r
+\r
+  Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1;\r
+  Top   = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;\r
+\r
+  //\r
+  // Display prompt for string\r
+  //\r
+  CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter);\r
+\r
+  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));\r
+\r
+  CursorVisible = gST->ConOut->Mode->CursorVisible;\r
+  gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
+\r
+  CurrentCursor = GetStringWidth (StringPtr) / 2 - 1;\r
+  if (CurrentCursor != 0) {\r
+    //\r
+    // Show the string which has beed saved before.\r
+    //\r
+    SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');\r
+    PrintStringAt (Start + 1, Top + 3, BufferedString);\r
+\r
+    if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {\r
+      Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;\r
+    } else {\r
+      Index = 0;\r
+    }\r
+\r
+    if (IsPassword) {\r
+      gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);\r
+    }\r
+\r
+    for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {\r
+      BufferedString[Count] = StringPtr[Index];\r
+\r
+      if (IsPassword) {\r
+        PrintChar (L'*');\r
+      }\r
+    }\r
+\r
+    if (!IsPassword) {\r
+      PrintStringAt (Start + 1, Top + 3, BufferedString);\r
+    }\r
+    \r
+    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+    gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);\r
+  }\r
+  \r
+  do {\r
+    Status = WaitForKeyStroke (&Key);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));\r
+    switch (Key.UnicodeChar) {\r
+    case CHAR_NULL:\r
+      switch (Key.ScanCode) {\r
+      case SCAN_LEFT:\r
+        if (CurrentCursor > 0) {\r
+          CurrentCursor--;\r
+        }\r
+        break;\r
+\r
+      case SCAN_RIGHT:\r
+        if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) {\r
+          CurrentCursor++;\r
+        }\r
+        break;\r
+\r
+      case SCAN_ESC:\r
+        FreePool (TempString);\r
+        FreePool (BufferedString);\r
+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
+        return EFI_DEVICE_ERROR;\r
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      break;\r
+\r
+    case CHAR_CARRIAGE_RETURN:\r
+      if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) {\r
+\r
+        FreePool (TempString);\r
+        FreePool (BufferedString);\r
+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        //\r
+        // Simply create a popup to tell the user that they had typed in too few characters.\r
+        // To save code space, we can then treat this as an error and return back to the menu.\r
+        //\r
+        do {\r
+          CreateDialog (4, TRUE, 0, NULL, &Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter);\r
+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+        FreePool (TempString);\r
+        FreePool (BufferedString);\r
+        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+        gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+\r
+      break;\r
+\r
+    case CHAR_BACKSPACE:\r
+      if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) {\r
+        for (Index = 0; Index < CurrentCursor - 1; Index++) {\r
+          TempString[Index] = StringPtr[Index];\r
+        }\r
+        Count = GetStringWidth (StringPtr) / 2 - 1;\r
+        if (Count >= CurrentCursor) {\r
+          for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) {\r
+            TempString[Index] = StringPtr[Index2];\r
+          }\r
+          TempString[Index] = CHAR_NULL;\r
+        }\r
+        //\r
+        // Effectively truncate string by 1 character\r
+        //\r
+        StrCpy (StringPtr, TempString);\r
+        CurrentCursor --;\r
+      }\r
+\r
+    default:\r
+      //\r
+      // If it is the beginning of the string, don't worry about checking maximum limits\r
+      //\r
+      if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
+        StrnCpy (StringPtr, &Key.UnicodeChar, 1);\r
+        CurrentCursor++;\r
+      } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
+        KeyPad[0] = Key.UnicodeChar;\r
+        KeyPad[1] = CHAR_NULL;\r
+        Count = GetStringWidth (StringPtr) / 2 - 1;\r
+        if (CurrentCursor < Count) {\r
+          for (Index = 0; Index < CurrentCursor; Index++) {\r
+            TempString[Index] = StringPtr[Index];\r
+          }\r
+                 TempString[Index] = CHAR_NULL;\r
+          StrCat (TempString, KeyPad);\r
+          StrCat (TempString, StringPtr + CurrentCursor);\r
+          StrCpy (StringPtr, TempString);\r
+        } else {\r
+          StrCat (StringPtr, KeyPad);\r
+        }\r
+        CurrentCursor++;\r
+      }\r
+\r
+      //\r
+      // If the width of the input string is now larger than the screen, we nee to\r
+      // adjust the index to start printing portions of the string\r
+      //\r
+      SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');\r
+      PrintStringAt (Start + 1, Top + 3, BufferedString);\r
+\r
+      if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {\r
+        Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;\r
+      } else {\r
+        Index = 0;\r
+      }\r
+\r
+      if (IsPassword) {\r
+        gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);\r
+      }\r
+\r
+      for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {\r
+        BufferedString[Count] = StringPtr[Index];\r
+\r
+        if (IsPassword) {\r
+          PrintChar (L'*');\r
+        }\r
+      }\r
+\r
+      if (!IsPassword) {\r
+        PrintStringAt (Start + 1, Top + 3, BufferedString);\r
+      }\r
+      break;\r
+    }\r
+\r
+    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+    gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3);\r
+  } while (TRUE);\r
+\r
+}\r
+\r
+/**\r
+  Adjust the value to the correct one. Rules follow the sample:\r
+  like:  Year change:  2012.02.29 -> 2013.02.29 -> 2013.02.01\r
+         Month change: 2013.03.29 -> 2013.02.29 -> 2013.02.28\r
+\r
+  @param  Question          Pointer to current question.\r
+  @param  Sequence          The sequence of the field in the question.\r
+**/\r
+VOID\r
+AdjustQuestionValue (\r
+  IN  FORM_BROWSER_STATEMENT  *Question,\r
+  IN  UINT8                   Sequence\r
+  )\r
+{\r
+  UINT8     Month;\r
+  UINT16    Year;\r
+  UINT8     Maximum;\r
+  UINT8     Minimum;\r
+\r
+  if (Question->Operand != EFI_IFR_DATE_OP) {\r
+    return;\r
+  }\r
+\r
+  Month   = Question->HiiValue.Value.date.Month;\r
+  Year    = Question->HiiValue.Value.date.Year;\r
+  Minimum = 1;\r
+\r
+  switch (Month) {\r
+  case 2:\r
+    if ((Year % 4) == 0 && ((Year % 100) != 0 || (Year % 400) == 0)) {\r
+      Maximum = 29;\r
+    } else {\r
+      Maximum = 28;\r
+    }\r
+    break;\r
+  case 4:\r
+  case 6:\r
+  case 9:\r
+  case 11:\r
+    Maximum = 30;\r
+    break;\r
+  default:\r
+    Maximum = 31;\r
+    break;\r
+  }\r
+\r
+  //\r
+  // Change the month area.\r
+  //\r
+  if (Sequence == 0) {\r
+    if (Question->HiiValue.Value.date.Day > Maximum) {\r
+      Question->HiiValue.Value.date.Day = Maximum;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Change the Year area.\r
+  //\r
+  if (Sequence == 2) {\r
+    if (Question->HiiValue.Value.date.Day > Maximum) {\r
+      Question->HiiValue.Value.date.Day = Minimum;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  This routine reads a numeric value from the user input.\r
+\r
+  @param  Selection         Pointer to current selection.\r
+  @param  MenuOption        Pointer to the current input menu.\r
+\r
+  @retval EFI_SUCCESS       If numerical input is read successfully\r
+  @retval EFI_DEVICE_ERROR  If operation fails\r
+\r
+**/\r
+EFI_STATUS\r
+GetNumericInput (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  UINTN                   Column;\r
+  UINTN                   Row;\r
+  CHAR16                  InputText[MAX_NUMERIC_INPUT_WIDTH];\r
+  CHAR16                  FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1];\r
+  UINT64                  PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3];\r
+  UINTN                   Count;\r
+  UINTN                   Loop;\r
+  BOOLEAN                 ManualInput;\r
+  BOOLEAN                 HexInput;\r
+  BOOLEAN                 DateOrTime;\r
+  UINTN                   InputWidth;\r
+  UINT64                  EditValue;\r
+  UINT64                  Step;\r
+  UINT64                  Minimum;\r
+  UINT64                  Maximum;\r
+  UINTN                   EraseLen;\r
+  UINT8                   Digital;\r
+  EFI_INPUT_KEY           Key;\r
+  EFI_HII_VALUE           *QuestionValue;\r
+  FORM_BROWSER_FORM       *Form;\r
+  FORM_BROWSER_FORMSET    *FormSet;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+\r
+  Column            = MenuOption->OptCol;\r
+  Row               = MenuOption->Row;\r
+  PreviousNumber[0] = 0;\r
+  Count             = 0;\r
+  InputWidth        = 0;\r
+  Digital           = 0;\r
+\r
+  FormSet       = Selection->FormSet;\r
+  Form          = Selection->Form;\r
+  Question      = MenuOption->ThisTag;\r
+  QuestionValue = &Question->HiiValue;\r
+  Step          = Question->Step;\r
+  Minimum       = Question->Minimum;\r
+  Maximum       = Question->Maximum;\r
+\r
+  //\r
+  // Only two case, user can enter to this function: Enter and +/- case.\r
+  // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT\r
+  //\r
+  ManualInput        = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE);\r
+\r
+  if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {\r
+    DateOrTime = TRUE;\r
+  } else {\r
+    DateOrTime = FALSE;\r
+  }\r
+\r
+  //\r
+  // Prepare Value to be edit\r
+  //\r
+  EraseLen = 0;\r
+  EditValue = 0;\r
+  if (Question->Operand == EFI_IFR_DATE_OP) {\r
+    Step = 1;\r
+    Minimum = 1;\r
+\r
+    switch (MenuOption->Sequence) {\r
+    case 0:\r
+      Maximum = 12;\r
+      EraseLen = 4;\r
+      EditValue = QuestionValue->Value.date.Month;\r
+      break;\r
+\r
+    case 1:\r
+      switch (QuestionValue->Value.date.Month) {\r
+      case 2:\r
+        if ((QuestionValue->Value.date.Year % 4) == 0  && \r
+            ((QuestionValue->Value.date.Year % 100) != 0 || \r
+            (QuestionValue->Value.date.Year % 400) == 0)) {\r
+          Maximum = 29;\r
+        } else {\r
+          Maximum = 28;\r
+        }\r
+        break;\r
+      case 4:\r
+      case 6:\r
+      case 9:\r
+      case 11:\r
+        Maximum = 30;\r
+        break;\r
+      default:\r
+        Maximum = 31;\r
+        break;\r
+      } \r
+\r
+      EraseLen = 3;\r
+      EditValue = QuestionValue->Value.date.Day;\r
+      break;\r
+\r
+    case 2:\r
+      Maximum = 0xffff;\r
+      EraseLen = 5;\r
+      EditValue = QuestionValue->Value.date.Year;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  } else if (Question->Operand == EFI_IFR_TIME_OP) {\r
+    Step = 1;\r
+    Minimum = 0;\r
+\r
+    switch (MenuOption->Sequence) {\r
+    case 0:\r
+      Maximum = 23;\r
+      EraseLen = 4;\r
+      EditValue = QuestionValue->Value.time.Hour;\r
+      break;\r
+\r
+    case 1:\r
+      Maximum = 59;\r
+      EraseLen = 3;\r
+      EditValue = QuestionValue->Value.time.Minute;\r
+      break;\r
+\r
+    case 2:\r
+      Maximum = 59;\r
+      EraseLen = 3;\r
+      EditValue = QuestionValue->Value.time.Second;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  } else {\r
+    //\r
+    // Numeric\r
+    //\r
+    EraseLen = gOptionBlockWidth;\r
+    EditValue = QuestionValue->Value.u64;\r
+    if (Maximum == 0) {\r
+      Maximum = (UINT64) -1;\r
+    }\r
+  }\r
+\r
+  if ((Question->Operand == EFI_IFR_NUMERIC_OP) &&\r
+      ((Question->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {\r
+    HexInput = TRUE;\r
+  } else {\r
+    HexInput = FALSE;\r
+  }\r
+\r
+  //\r
+  // Enter from "Enter" input, clear the old word showing.\r
+  //\r
+  if (ManualInput) {\r
+    if (Question->Operand == EFI_IFR_NUMERIC_OP) {\r
+      if (HexInput) {\r
+        InputWidth = Question->StorageWidth * 2;\r
+      } else {\r
+        switch (Question->StorageWidth) {\r
+        case 1:\r
+          InputWidth = 3;\r
+          break;\r
+\r
+        case 2:\r
+          InputWidth = 5;\r
+          break;\r
+\r
+        case 4:\r
+          InputWidth = 10;\r
+          break;\r
+\r
+        case 8:\r
+          InputWidth = 20;\r
+          break;\r
+\r
+        default:\r
+          InputWidth = 0;\r
+          break;\r
+        }\r
+      }\r
+\r
+      InputText[0] = LEFT_NUMERIC_DELIMITER;\r
+      SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
+      ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH);\r
+      InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
+      InputText[InputWidth + 2] = L'\0';\r
+\r
+      PrintAt (Column, Row, InputText);\r
+      Column++;\r
+    }\r
+\r
+    if (Question->Operand == EFI_IFR_DATE_OP) {\r
+      if (MenuOption->Sequence == 2) {\r
+        InputWidth = 4;\r
+      } else {\r
+        InputWidth = 2;\r
+      }\r
+\r
+      if (MenuOption->Sequence == 0) {\r
+        InputText[0] = LEFT_NUMERIC_DELIMITER;\r
+        SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
+      } else {\r
+        SetUnicodeMem (InputText, InputWidth, L' ');\r
+      }\r
+\r
+      if (MenuOption->Sequence == 2) {\r
+        InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
+      } else {\r
+        InputText[InputWidth + 1] = DATE_SEPARATOR;\r
+      }\r
+      InputText[InputWidth + 2] = L'\0';\r
+\r
+      PrintAt (Column, Row, InputText);\r
+      if (MenuOption->Sequence == 0) {\r
+        Column++;\r
+      }\r
+    }\r
+\r
+    if (Question->Operand == EFI_IFR_TIME_OP) {\r
+      InputWidth = 2;\r
+\r
+      if (MenuOption->Sequence == 0) {\r
+        InputText[0] = LEFT_NUMERIC_DELIMITER;\r
+        SetUnicodeMem (InputText + 1, InputWidth, L' ');\r
+      } else {\r
+        SetUnicodeMem (InputText, InputWidth, L' ');\r
+      }\r
+\r
+      if (MenuOption->Sequence == 2) {\r
+        InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;\r
+      } else {\r
+        InputText[InputWidth + 1] = TIME_SEPARATOR;\r
+      }\r
+      InputText[InputWidth + 2] = L'\0';\r
+\r
+      PrintAt (Column, Row, InputText);\r
+      if (MenuOption->Sequence == 0) {\r
+        Column++;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // First time we enter this handler, we need to check to see if\r
+  // we were passed an increment or decrement directive\r
+  //\r
+  do {\r
+    Key.UnicodeChar = CHAR_NULL;\r
+    if (gDirection != 0) {\r
+      Key.ScanCode  = gDirection;\r
+      gDirection    = 0;\r
+      goto TheKey2;\r
+    }\r
+\r
+    Status = WaitForKeyStroke (&Key);\r
+\r
+TheKey2:\r
+    switch (Key.UnicodeChar) {\r
+\r
+    case '+':\r
+    case '-':\r
+      if (Key.UnicodeChar == '+') {\r
+        Key.ScanCode = SCAN_RIGHT;\r
+      } else {\r
+        Key.ScanCode = SCAN_LEFT;\r
+      }\r
+      Key.UnicodeChar = CHAR_NULL;\r
+      goto TheKey2;\r
+\r
+    case CHAR_NULL:\r
+      switch (Key.ScanCode) {\r
+      case SCAN_LEFT:\r
+      case SCAN_RIGHT:\r
+        if (DateOrTime && !ManualInput) {\r
+          //\r
+          // By setting this value, we will return back to the caller.\r
+          // We need to do this since an auto-refresh will destroy the adjustment\r
+          // based on what the real-time-clock is showing.  So we always commit\r
+          // upon changing the value.\r
+          //\r
+          gDirection = SCAN_DOWN;\r
+        }\r
+\r
+        if ((Step != 0) && !ManualInput) {\r
+          if (Key.ScanCode == SCAN_LEFT) {\r
+            if (EditValue >= Minimum + Step) {\r
+              EditValue = EditValue - Step;\r
+            } else if (EditValue > Minimum){\r
+              EditValue = Minimum;\r
+            } else {\r
+              EditValue = Maximum;\r
+            }\r
+          } else if (Key.ScanCode == SCAN_RIGHT) {\r
+            if (EditValue + Step <= Maximum) {\r
+              EditValue = EditValue + Step;\r
+            } else if (EditValue < Maximum) {\r
+              EditValue = Maximum;\r
+            } else {\r
+              EditValue = Minimum;\r
+            }\r
+          }\r
+\r
+          ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
+          if (Question->Operand == EFI_IFR_DATE_OP) {\r
+            if (MenuOption->Sequence == 2) {\r
+              //\r
+              // Year\r
+              //\r
+              UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINT16) EditValue);\r
+            } else {\r
+              //\r
+              // Month/Day\r
+              //\r
+              UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);\r
+            }\r
+\r
+            if (MenuOption->Sequence == 0) {\r
+              ASSERT (EraseLen >= 2);\r
+              FormattedNumber[EraseLen - 2] = DATE_SEPARATOR;\r
+            } else if (MenuOption->Sequence == 1) {\r
+              ASSERT (EraseLen >= 1);\r
+              FormattedNumber[EraseLen - 1] = DATE_SEPARATOR;\r
+            }\r
+          } else if (Question->Operand == EFI_IFR_TIME_OP) {\r
+            UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);\r
+\r
+            if (MenuOption->Sequence == 0) {\r
+              ASSERT (EraseLen >= 2);\r
+              FormattedNumber[EraseLen - 2] = TIME_SEPARATOR;\r
+            } else if (MenuOption->Sequence == 1) {\r
+              ASSERT (EraseLen >= 1);\r
+              FormattedNumber[EraseLen - 1] = TIME_SEPARATOR;\r
+            }\r
+          } else {\r
+            QuestionValue->Value.u64 = EditValue;\r
+            PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));\r
+          }\r
+\r
+          gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+          for (Loop = 0; Loop < EraseLen; Loop++) {\r
+            PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");\r
+          }\r
+          gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));\r
+\r
+          if (MenuOption->Sequence == 0) {\r
+            PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);\r
+            Column = MenuOption->OptCol + 1;\r
+          }\r
+\r
+          PrintStringAt (Column, Row, FormattedNumber);\r
+\r
+          if (!DateOrTime || MenuOption->Sequence == 2) {\r
+            PrintChar (RIGHT_NUMERIC_DELIMITER);\r
+          }\r
+        }\r
+\r
+        goto EnterCarriageReturn;\r
+        break;\r
+\r
+      case SCAN_UP:\r
+      case SCAN_DOWN:\r
+        goto EnterCarriageReturn;\r
+\r
+      case SCAN_ESC:\r
+        return EFI_DEVICE_ERROR;\r
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      break;\r
+\r
+EnterCarriageReturn:\r
+\r
+    case CHAR_CARRIAGE_RETURN:\r
+      //\r
+      // Validate input value with Minimum value.\r
+      //\r
+      if (EditValue < Minimum) {\r
+        UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+        break;\r
+      } else {\r
+        UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);\r
+      }\r
+\r
+      //\r
+      // Store Edit value back to Question\r
+      //\r
+      if (Question->Operand == EFI_IFR_DATE_OP) {\r
+        switch (MenuOption->Sequence) {\r
+        case 0:\r
+          QuestionValue->Value.date.Month = (UINT8) EditValue;\r
+          break;\r
+\r
+        case 1:\r
+          QuestionValue->Value.date.Day = (UINT8) EditValue;\r
+          break;\r
+\r
+        case 2:\r
+          QuestionValue->Value.date.Year = (UINT16) EditValue;\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+      } else if (Question->Operand == EFI_IFR_TIME_OP) {\r
+        switch (MenuOption->Sequence) {\r
+        case 0:\r
+          QuestionValue->Value.time.Hour = (UINT8) EditValue;\r
+          break;\r
+\r
+        case 1:\r
+          QuestionValue->Value.time.Minute = (UINT8) EditValue;\r
+          break;\r
+\r
+        case 2:\r
+          QuestionValue->Value.time.Second = (UINT8) EditValue;\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+      } else {\r
+        //\r
+        // Numeric\r
+        //\r
+        QuestionValue->Value.u64 = EditValue;\r
+      }\r
+\r
+      //\r
+      // Adjust the value to the correct one.\r
+      // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01\r
+      //              2013.03.29 -> 2013.02.29 -> 2013.02.28\r
+      //\r
+      if (Question->Operand == EFI_IFR_DATE_OP && \r
+        (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) {\r
+        AdjustQuestionValue (Question, (UINT8)MenuOption->Sequence);\r
+      }\r
+\r
+      //\r
+      // Check to see if the Value is something reasonable against consistency limitations.\r
+      // If not, let's kick the error specified.\r
+      //\r
+      Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Input value is not valid, restore Question Value\r
+        //\r
+        GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+      } else {\r
+        SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+        if (!DateOrTime || (Question->Storage != NULL)) {\r
+          //\r
+          // NV flag is unnecessary for RTC type of Date/Time\r
+          //\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+        }\r
+      }\r
+\r
+      return Status;\r
+      break;\r
+\r
+    case CHAR_BACKSPACE:\r
+      if (ManualInput) {\r
+        if (Count == 0) {\r
+          break;\r
+        }\r
+        //\r
+        // Remove a character\r
+        //\r
+        EditValue = PreviousNumber[Count - 1];\r
+        UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);\r
+        Count--;\r
+        Column--;\r
+        PrintAt (Column, Row, L" ");\r
+      }\r
+      break;\r
+\r
+    default:\r
+      if (ManualInput) {\r
+        if (HexInput) {\r
+          if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) {\r
+            Digital = (UINT8) (Key.UnicodeChar - L'0');\r
+          } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) {\r
+            Digital = (UINT8) (Key.UnicodeChar - L'A' + 0x0A);\r
+          } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {\r
+            Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A);\r
+          } else {\r
+            UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+            break;\r
+          }\r
+        } else {\r
+          if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {\r
+            UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+            break;\r
+          }\r
+        }\r
+\r
+        //\r
+        // If Count exceed input width, there is no way more is valid\r
+        //\r
+        if (Count >= InputWidth) {\r
+          break;\r
+        }\r
+        //\r
+        // Someone typed something valid!\r
+        //\r
+        if (Count != 0) {\r
+          if (HexInput) {\r
+            EditValue = LShiftU64 (EditValue, 4) + Digital;\r
+          } else {\r
+            EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');\r
+          }\r
+        } else {\r
+          if (HexInput) {\r
+            EditValue = Digital;\r
+          } else {\r
+            EditValue = Key.UnicodeChar - L'0';\r
+          }\r
+        }\r
+\r
+        if (EditValue > Maximum) {\r
+          UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+          ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0]));\r
+          EditValue = PreviousNumber[Count];\r
+          break;\r
+        } else {\r
+          UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);\r
+        }\r
+\r
+        Count++;\r
+        ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0])));\r
+        PreviousNumber[Count] = EditValue;\r
+\r
+        PrintCharAt (Column, Row, Key.UnicodeChar);\r
+        Column++;\r
+      }\r
+      break;\r
+    }\r
+  } while (TRUE);\r
+\r
+}\r
+\r
+\r
+/**\r
+  Get selection for OneOf and OrderedList (Left/Right will be ignored).\r
+\r
+  @param  Selection         Pointer to current selection.\r
+  @param  MenuOption        Pointer to the current input menu.\r
+\r
+  @retval EFI_SUCCESS       If Option input is processed successfully\r
+  @retval EFI_DEVICE_ERROR  If operation fails\r
+\r
+**/\r
+EFI_STATUS\r
+GetSelectionInputPopUp (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_INPUT_KEY           Key;\r
+  UINTN                   Index;\r
+  CHAR16                  *StringPtr;\r
+  CHAR16                  *TempStringPtr;\r
+  UINTN                   Index2;\r
+  UINTN                   TopOptionIndex;\r
+  UINTN                   HighlightOptionIndex;\r
+  UINTN                   Start;\r
+  UINTN                   End;\r
+  UINTN                   Top;\r
+  UINTN                   Bottom;\r
+  UINTN                   PopUpMenuLines;\r
+  UINTN                   MenuLinesInView;\r
+  UINTN                   PopUpWidth;\r
+  CHAR16                  Character;\r
+  INT32                   SavedAttribute;\r
+  BOOLEAN                 ShowDownArrow;\r
+  BOOLEAN                 ShowUpArrow;\r
+  UINTN                   DimensionsWidth;\r
+  LIST_ENTRY              *Link;\r
+  BOOLEAN                 OrderedList;\r
+  UINT8                   *ValueArray;\r
+  UINT8                   ValueType;\r
+  EFI_HII_VALUE           HiiValue;\r
+  EFI_HII_VALUE           *HiiValueArray;\r
+  UINTN                   OptionCount;\r
+  QUESTION_OPTION         *OneOfOption;\r
+  QUESTION_OPTION         *CurrentOption;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+  INTN                    Result;\r
+\r
+  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
+\r
+  ValueArray        = NULL;\r
+  ValueType         = 0;\r
+  CurrentOption     = NULL;\r
+  ShowDownArrow     = FALSE;\r
+  ShowUpArrow       = FALSE;\r
+\r
+  StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);\r
+  ASSERT (StringPtr);\r
+\r
+  Question = MenuOption->ThisTag;\r
+  if (Question->Operand == EFI_IFR_ORDERED_LIST_OP) {\r
+    ValueArray = Question->BufferValue;\r
+    ValueType = Question->ValueType;\r
+    OrderedList = TRUE;\r
+  } else {\r
+    OrderedList = FALSE;\r
+  }\r
+\r
+  //\r
+  // Calculate Option count\r
+  //\r
+  if (OrderedList) {\r
+    for (Index = 0; Index < Question->MaxContainers; Index++) {\r
+      if (GetArrayData (ValueArray, ValueType, Index) == 0) {\r
+        break;\r
+      }\r
+    }\r
+\r
+    OptionCount = Index;\r
+  } else {\r
+    OptionCount = 0;\r
+    Link = GetFirstNode (&Question->OptionListHead);\r
+    while (!IsNull (&Question->OptionListHead, Link)) {\r
+      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+      OptionCount++;\r
+\r
+      Link = GetNextNode (&Question->OptionListHead, Link);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Move valid Option to list head.\r
+  //\r
+  PopUpMenuLines = 0;\r
+  if (OrderedList) {\r
+    //\r
+    // Prepare HiiValue array\r
+    //  \r
+    HiiValueArray = AllocateZeroPool (OptionCount * sizeof (EFI_HII_VALUE));\r
+    ASSERT (HiiValueArray != NULL);\r
+    for (Index = 0; Index < OptionCount; Index++) {\r
+      HiiValueArray[Index].Type = ValueType;\r
+      HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
+    }\r
+\r
+    for (Index = 0; Index < OptionCount; Index++) {\r
+      OneOfOption = ValueToOption (Question, &HiiValueArray[OptionCount - Index - 1]);\r
+      if (OneOfOption == NULL) {\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      RemoveEntryList (&OneOfOption->Link);\r
+\r
+      //\r
+      // Insert to head.\r
+      //\r
+      InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);\r
+\r
+      PopUpMenuLines++;\r
+    }\r
+\r
+    FreePool (HiiValueArray);\r
+  } else {\r
+    Link = GetFirstNode (&Question->OptionListHead);\r
+    for (Index = 0; Index < OptionCount; Index++) {\r
+      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+      Link = GetNextNode (&Question->OptionListHead, Link);\r
+      if ((OneOfOption->SuppressExpression != NULL) &&\r
+          EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {\r
+        continue;\r
+      } else {\r
+        PopUpMenuLines++;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get the number of one of options present and its size\r
+  //\r
+  PopUpWidth = 0;\r
+  HighlightOptionIndex = 0;\r
+  Link = GetFirstNode (&Question->OptionListHead);\r
+  for (Index = 0; Index < PopUpMenuLines; Index++) {\r
+    OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+    Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+    if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&\r
+        EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {\r
+      Index--;\r
+      continue;\r
+    }\r
+\r
+    StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);\r
+    if (StrLen (StringPtr) > PopUpWidth) {\r
+      PopUpWidth = StrLen (StringPtr);\r
+    }\r
+    FreePool (StringPtr);\r
+\r
+    if (!OrderedList && (CompareHiiValue (&Question->HiiValue, &OneOfOption->Value, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
+      //\r
+      // Find current selected Option for OneOf\r
+      //\r
+      HighlightOptionIndex = Index;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Perform popup menu initialization.\r
+  //\r
+  PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;\r
+\r
+  SavedAttribute = gST->ConOut->Mode->Attribute;\r
+  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);\r
+\r
+  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {\r
+    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;\r
+  }\r
+\r
+  Start  = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;\r
+  End    = Start + PopUpWidth + POPUP_FRAME_WIDTH;\r
+  Top    = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;\r
+  Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - 1;\r
+\r
+  MenuLinesInView = Bottom - Top - 1;\r
+  if (MenuLinesInView >= PopUpMenuLines) {\r
+    Top     = Top + (MenuLinesInView - PopUpMenuLines) / 2;\r
+    Bottom  = Top + PopUpMenuLines + 1;\r
+  } else {\r
+    ShowDownArrow = TRUE;\r
+  }\r
+\r
+  if (HighlightOptionIndex > (MenuLinesInView - 1)) {\r
+    TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1;\r
+  } else {\r
+    TopOptionIndex = 0;\r
+  }\r
+\r
+  do {\r
+    //\r
+    // Clear that portion of the screen\r
+    //\r
+    ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);\r
+\r
+    //\r
+    // Draw "One of" pop-up menu\r
+    //\r
+    Character = BOXDRAW_DOWN_RIGHT;\r
+    PrintCharAt (Start, Top, Character);\r
+    for (Index = Start; Index + 2 < End; Index++) {\r
+      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {\r
+        Character = GEOMETRICSHAPE_UP_TRIANGLE;\r
+      } else {\r
+        Character = BOXDRAW_HORIZONTAL;\r
+      }\r
+\r
+      PrintChar (Character);\r
+    }\r
+\r
+    Character = BOXDRAW_DOWN_LEFT;\r
+    PrintChar (Character);\r
+    Character = BOXDRAW_VERTICAL;\r
+    for (Index = Top + 1; Index < Bottom; Index++) {\r
+      PrintCharAt (Start, Index, Character);\r
+      PrintCharAt (End - 1, Index, Character);\r
+    }\r
+\r
+    //\r
+    // Move to top Option\r
+    //\r
+    Link = GetFirstNode (&Question->OptionListHead);\r
+    for (Index = 0; Index < TopOptionIndex; Index++) {\r
+      Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+      if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&\r
+          EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {\r
+        Index--;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Display the One of options\r
+    //\r
+    Index2 = Top + 1;\r
+    for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {\r
+      OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+      Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+      if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&\r
+          EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {\r
+        Index--;\r
+        continue;\r
+      }\r
+\r
+      StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);\r
+      ASSERT (StringPtr != NULL);\r
+      //\r
+      // If the string occupies multiple lines, truncate it to fit in one line,\r
+      // and append a "..." for indication.\r
+      //\r
+      if (StrLen (StringPtr) > (PopUpWidth - 1)) {\r
+        TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));\r
+        ASSERT ( TempStringPtr != NULL );\r
+        CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));\r
+        FreePool (StringPtr);\r
+        StringPtr = TempStringPtr;\r
+        StrCat (StringPtr, L"...");\r
+      }\r
+\r
+      if (Index == HighlightOptionIndex) {\r
+          //\r
+          // Highlight the selected one\r
+          //\r
+          CurrentOption = OneOfOption;\r
+\r
+          gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);\r
+          PrintStringAt (Start + 2, Index2, StringPtr);\r
+          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);\r
+        } else {\r
+          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);\r
+          PrintStringAt (Start + 2, Index2, StringPtr);\r
+        }\r
+\r
+      Index2++;\r
+      FreePool (StringPtr);\r
+    }\r
+\r
+    Character = BOXDRAW_UP_RIGHT;\r
+    PrintCharAt (Start, Bottom, Character);\r
+    for (Index = Start; Index + 2 < End; Index++) {\r
+      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {\r
+        Character = GEOMETRICSHAPE_DOWN_TRIANGLE;\r
+      } else {\r
+        Character = BOXDRAW_HORIZONTAL;\r
+      }\r
+\r
+      PrintChar (Character);\r
+    }\r
+\r
+    Character = BOXDRAW_UP_LEFT;\r
+    PrintChar (Character);\r
+\r
+    //\r
+    // Get User selection\r
+    //\r
+    Key.UnicodeChar = CHAR_NULL;\r
+    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {\r
+      Key.ScanCode  = gDirection;\r
+      gDirection    = 0;\r
+      goto TheKey;\r
+    }\r
+\r
+    Status = WaitForKeyStroke (&Key);\r
+\r
+TheKey:\r
+    switch (Key.UnicodeChar) {\r
+    case '+':\r
+      if (OrderedList) {\r
+        if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {\r
+          //\r
+          // Highlight reaches the top of the popup window, scroll one menu item.\r
+          //\r
+          TopOptionIndex--;\r
+          ShowDownArrow = TRUE;\r
+        }\r
+\r
+        if (TopOptionIndex == 0) {\r
+          ShowUpArrow = FALSE;\r
+        }\r
+\r
+        if (HighlightOptionIndex > 0) {\r
+          HighlightOptionIndex--;\r
+\r
+          ASSERT (CurrentOption != NULL);\r
+          SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link);\r
+        }\r
+      }\r
+      break;\r
+\r
+    case '-':\r
+      //\r
+      // If an ordered list op-code, we will allow for a popup of +/- keys\r
+      // to create an ordered list of items\r
+      //\r
+      if (OrderedList) {\r
+        if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&\r
+            (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {\r
+          //\r
+          // Highlight reaches the bottom of the popup window, scroll one menu item.\r
+          //\r
+          TopOptionIndex++;\r
+          ShowUpArrow = TRUE;\r
+        }\r
+\r
+        if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {\r
+          ShowDownArrow = FALSE;\r
+        }\r
+\r
+        if (HighlightOptionIndex < (PopUpMenuLines - 1)) {\r
+          HighlightOptionIndex++;\r
+\r
+          ASSERT (CurrentOption != NULL);\r
+          SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink);\r
+        }\r
+      }\r
+      break;\r
+\r
+    case CHAR_NULL:\r
+      switch (Key.ScanCode) {\r
+      case SCAN_UP:\r
+      case SCAN_DOWN:\r
+        if (Key.ScanCode == SCAN_UP) {\r
+          if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {\r
+            //\r
+            // Highlight reaches the top of the popup window, scroll one menu item.\r
+            //\r
+            TopOptionIndex--;\r
+            ShowDownArrow = TRUE;\r
+          }\r
+\r
+          if (TopOptionIndex == 0) {\r
+            ShowUpArrow = FALSE;\r
+          }\r
+\r
+          if (HighlightOptionIndex > 0) {\r
+            HighlightOptionIndex--;\r
+          }\r
+        } else {\r
+          if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&\r
+              (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {\r
+            //\r
+            // Highlight reaches the bottom of the popup window, scroll one menu item.\r
+            //\r
+            TopOptionIndex++;\r
+            ShowUpArrow = TRUE;\r
+          }\r
+\r
+          if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {\r
+            ShowDownArrow = FALSE;\r
+          }\r
+\r
+          if (HighlightOptionIndex < (PopUpMenuLines - 1)) {\r
+            HighlightOptionIndex++;\r
+          }\r
+        }\r
+        break;\r
+\r
+      case SCAN_ESC:\r
+        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);\r
+\r
+        //\r
+        // Restore link list order for orderedlist\r
+        //\r
+        if (OrderedList) {\r
+          HiiValue.Type = ValueType;\r
+          HiiValue.Value.u64 = 0;\r
+          for (Index = 0; Index < Question->MaxContainers; Index++) {\r
+            HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
+            if (HiiValue.Value.u64 == 0) {\r
+              break;\r
+            }\r
+\r
+            OneOfOption = ValueToOption (Question, &HiiValue);\r
+            if (OneOfOption == NULL) {\r
+              return EFI_NOT_FOUND;\r
+            }\r
+\r
+            RemoveEntryList (&OneOfOption->Link);\r
+            InsertTailList (&Question->OptionListHead, &OneOfOption->Link);\r
+          }\r
+        }\r
+\r
+        return EFI_DEVICE_ERROR;\r
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      break;\r
+\r
+    case CHAR_CARRIAGE_RETURN:\r
+      //\r
+      // return the current selection\r
+      //\r
+      if (OrderedList) {\r
+        Index = 0;\r
+        Link = GetFirstNode (&Question->OptionListHead);\r
+        while (!IsNull (&Question->OptionListHead, Link)) {\r
+          OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+          Link = GetNextNode (&Question->OptionListHead, Link);\r
+\r
+          if ((OneOfOption->SuppressExpression != NULL) &&\r
+              EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {\r
+            continue;\r
+          }\r
+\r
+          SetArrayData (ValueArray, ValueType, Index, OneOfOption->Value.Value.u64);\r
+\r
+          Index++;\r
+          if (Index > Question->MaxContainers) {\r
+            break;\r
+          }\r
+        }\r
+      } else {\r
+        ASSERT (CurrentOption != NULL);\r
+        CopyMem (&Question->HiiValue, &CurrentOption->Value, sizeof (EFI_HII_VALUE));\r
+      }\r
+\r
+      gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);\r
+\r
+      Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Input value is not valid, restore Question Value\r
+        //\r
+        GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
+      } else {\r
+        SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
+        UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+      }\r
+\r
+      return Status;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  } while (TRUE);\r
+\r
+}\r
+\r
+/**\r
+  Wait for a key to be pressed by user.\r
+\r
+  @param Key         The key which is pressed by user.\r
+\r
+  @retval EFI_SUCCESS The function always completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+WaitForKeyStroke (\r
+  OUT  EFI_INPUT_KEY           *Key\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  while (TRUE) {\r
+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    if (Status != EFI_NOT_READY) {\r
+      continue;\r
+    }\r
+\r
+    UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, 0);\r
+  }\r
+  return Status;\r
+}\r
index def18fd9f90b3eaec623fc9107df1d5d4d06da94..4cd71e5d440d04e8653243361d9d1b705045c99d 100644 (file)
@@ -19,1658 +19,863 @@ UI_MENU_SELECTION  *gCurrentSelection;
 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
 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
-EFI_EVENT          mValueChangedEvent = NULL;\r
-LIST_ENTRY         mRefreshEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);\r
-UINT32             gBrowserStatus = BROWSER_SUCCESS;\r
-CHAR16             *gErrorInfo;\r
-UINT16             mCurFakeQestId;\r
-FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\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
-  Add empty function for event process function.\r
-\r
-  @param Event    The Event need to be process\r
-  @param Context  The context of the event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-SetupBrowserEmptyFunction (\r
-  IN  EFI_EVENT    Event,\r
-  IN  VOID         *Context\r
-  )\r
-{\r
-}\r
-\r
-/**\r
-  Base on the opcode buffer info to get the display statement.\r
-\r
-  @param OpCode    The input opcode buffer for this statement.\r
-  \r
-  @retval Statement  The statement use this opcode buffer.\r
-\r
-**/\r
-FORM_DISPLAY_ENGINE_STATEMENT *\r
-GetDisplayStatement (\r
-  IN EFI_IFR_OP_HEADER     *OpCode\r
-  )\r
-{\r
-  FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;\r
-  LIST_ENTRY                    *Link;\r
-\r
-  Link = GetFirstNode (&gDisplayFormData.StatementListHead);\r
-  while (!IsNull (&gDisplayFormData.StatementListHead, Link)) {\r
-    DisplayStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
-\r
-    if (DisplayStatement->OpCode == OpCode) {\r
-      return DisplayStatement;\r
-    }\r
-    Link = GetNextNode (&gDisplayFormData.StatementListHead, Link);\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Free the refresh event list.\r
-\r
-**/\r
-VOID \r
-FreeRefreshEvent (\r
-  VOID\r
-  )\r
-{\r
-  LIST_ENTRY   *Link;\r
-  FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
-\r
-  while (!IsListEmpty (&mRefreshEventList)) {\r
-    Link = GetFirstNode (&mRefreshEventList);\r
-    EventNode = FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link);\r
-    RemoveEntryList (&EventNode->Link);\r
-\r
-    gBS->CloseEvent (EventNode->RefreshEvent);\r
-\r
-    FreePool (EventNode);\r
-  }\r
-}\r
-\r
-/**\r
-  Check whether this statement value is changed. If yes, update the statement value and return TRUE; \r
-  else return FALSE.\r
-\r
-  @param Statement           The statement need to check.\r
-\r
-**/\r
-VOID\r
-UpdateStatement (\r
-  IN OUT FORM_BROWSER_STATEMENT        *Statement\r
-  )\r
-{\r
-  GetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);\r
-\r
-  //\r
-  // Reset FormPackage update flag\r
-  //\r
-  mHiiPackageListUpdated = FALSE;\r
-\r
-  //\r
-  // Question value may be changed, need invoke its Callback()\r
-  //\r
-  ProcessCallBackFunction (gCurrentSelection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
-  \r
-  if (mHiiPackageListUpdated) {\r
-    //\r
-    // Package list is updated, force to reparse IFR binary of target Formset\r
-    //\r
-    mHiiPackageListUpdated = FALSE;\r
-    gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
-  }\r
-}\r
-\r
-/**\r
-  Refresh the question which has refresh guid event attribute.\r
-  \r
-  @param Event    The event which has this function related.     \r
-  @param Context  The input context info related to this event or the status code return to the caller.\r
-**/\r
-VOID\r
-EFIAPI\r
-RefreshEventNotify(\r
-  IN      EFI_EVENT Event,\r
-  IN      VOID      *Context\r
-  )\r
-{\r
-  FORM_BROWSER_STATEMENT        *Statement;\r
-\r
-  Statement = (FORM_BROWSER_STATEMENT *)Context;\r
-  UpdateStatement(Statement);\r
-  gBS->SignalEvent (mValueChangedEvent);\r
-}\r
-\r
-\r
-/**\r
-  Create refresh hook event for statement which has refresh event or interval.\r
-\r
-  @param Statement           The statement need to check.\r
-\r
-**/\r
-VOID\r
-CreateRefreshEvent (\r
-  IN     FORM_BROWSER_STATEMENT        *Statement\r
-  )\r
-{\r
-  EFI_STATUS                      Status;\r
-  EFI_EVENT                       RefreshEvent;\r
-  FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
-\r
-  //\r
-  // If question has refresh guid, create the notify function.\r
-  //\r
-  Status = gBS->CreateEventEx (\r
-                    EVT_NOTIFY_SIGNAL,\r
-                    TPL_CALLBACK,\r
-                    RefreshEventNotify,\r
-                    Statement,\r
-                    &Statement->RefreshGuid,\r
-                    &RefreshEvent);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
-  ASSERT (EventNode != NULL);\r
-  EventNode->RefreshEvent = RefreshEvent;\r
-  InsertTailList(&mRefreshEventList, &EventNode->Link);\r
-}\r
-\r
-/**\r
-  Perform value check for a question.\r
-  \r
-  @param  Question       The question need to do check.\r
-  @param  ErrorInfo      Return info about the error.\r
-  \r
-  @retval  The check result.\r
-**/\r
-UINT32\r
-InConsistentIfCheck (\r
-  IN  FORM_BROWSER_STATEMENT        *Question,\r
-  OUT STATEMENT_ERROR_INFO          *ErrorInfo\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  LIST_ENTRY              *Link;\r
-  FORM_EXPRESSION         *Expression;\r
-  LIST_ENTRY              *ListHead;\r
-  UINT32                  RetVal;\r
-\r
-  RetVal     = STATEMENT_VALID;\r
-  ListHead   = &Question->InconsistentListHead;\r
-\r
-  Link = GetFirstNode (ListHead);\r
-  while (!IsNull (ListHead, Link)) {\r
-    Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
-    Link = GetNextNode (ListHead, Link);\r
-\r
-    //\r
-    // Evaluate the expression\r
-    //\r
-    Status = EvaluateExpression (gCurrentSelection->FormSet, gCurrentSelection->Form, Expression);\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-\r
-    if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) {\r
-      ErrorInfo->StringId = Expression->Error;\r
-      ErrorInfo->TimeOut  = 0;\r
-      RetVal              = INCOSISTENT_IF_TRUE;\r
-      break;\r
-    }\r
-  }\r
-\r
-  return RetVal;\r
-}\r
-\r
-/**\r
-  Perform value check for a question.\r
-  \r
-  @param  Form       Form where Statement is in.\r
-  @param  Statement  Value will check for it.\r
-  @param  InputValue New value will be checked.\r
-  @param  ErrorInfo  Return the error info for this check.\r
-  \r
-  @retval TRUE   Input Value is valid.\r
-  @retval FALSE  Input Value is invalid.\r
-**/\r
-UINT32\r
-EFIAPI\r
-QuestionCheck (\r
-  IN  FORM_DISPLAY_ENGINE_FORM      *Form,\r
-  IN  FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
-  IN  EFI_HII_VALUE                 *InputValue,\r
-  OUT STATEMENT_ERROR_INFO          *ErrorInfo\r
-  )\r
-{\r
-  FORM_BROWSER_STATEMENT  *Question;\r
-  EFI_HII_VALUE           BackUpValue;\r
-  UINT8                   *BackUpBuffer;\r
-  UINT32                  RetVal;\r
-\r
-  BackUpBuffer = NULL;\r
-  RetVal       = STATEMENT_VALID;\r
-\r
-  ASSERT (Form != NULL && Statement != NULL && InputValue != NULL && ErrorInfo != NULL);\r
-\r
-  Question = GetBrowserStatement(Statement);\r
-  ASSERT (Question != NULL);\r
-\r
-  //\r
-  // Back up the quesion value.\r
-  //\r
-  switch (Question->Operand) {\r
-  case EFI_IFR_ORDERED_LIST_OP:\r
-    BackUpBuffer = AllocateCopyPool (Question->StorageWidth, Question->BufferValue);\r
-    ASSERT (BackUpBuffer != NULL);\r
-    CopyMem (Question->BufferValue, InputValue->Buffer, Question->StorageWidth);\r
-    break;\r
-\r
-  default:\r
-    CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
-    CopyMem (&Question->HiiValue, InputValue, sizeof (EFI_HII_VALUE));\r
-    break;\r
-  }\r
-\r
-  //\r
-  // Do the inconsistentif check.\r
-  //\r
-  if (!IsListEmpty (&Question->InconsistentListHead)) {\r
-    RetVal = InConsistentIfCheck(Question, ErrorInfo);\r
-  }\r
-\r
-  //\r
-  // Restore the quesion value.\r
-  //\r
-  switch (Question->Operand) {\r
-  case EFI_IFR_ORDERED_LIST_OP:\r
-    CopyMem (Question->BufferValue, BackUpBuffer, Question->StorageWidth);\r
-    break;\r
-\r
-  default:\r
-    CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
-    break;\r
-  }\r
-\r
-  return RetVal;\r
-}\r
-\r
-/**\r
-\r
-  Initialize the Display statement structure data.\r
-\r
-  @param DisplayStatement      Pointer to the display Statement data strucure.\r
-  @param Statement             The statement need to check.\r
-  @param HostDisplayStatement  Pointer to the display Statement data strucure which is an host statement.\r
-**/\r
-VOID\r
-InitializeDisplayStatement (\r
-  IN OUT FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement,\r
-  IN     FORM_BROWSER_STATEMENT        *Statement,\r
-  IN     FORM_DISPLAY_ENGINE_STATEMENT *HostDisplayStatement\r
-  )\r
-{\r
-  LIST_ENTRY                 *Link;\r
-  QUESTION_OPTION            *Option;\r
-  DISPLAY_QUESTION_OPTION    *DisplayOption;\r
-\r
-  DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
-  DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
-  DisplayStatement->OpCode    = Statement->OpCode;\r
-  InitializeListHead (&DisplayStatement->NestStatementList);\r
-  InitializeListHead (&DisplayStatement->OptionListHead);\r
-\r
-  if ((EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut) || Statement->Locked) {\r
-    DisplayStatement->Attribute |= HII_DISPLAY_GRAYOUT;\r
-  }\r
-  if ((Statement->ValueExpression != NULL) || ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {\r
-    DisplayStatement->Attribute |= HII_DISPLAY_READONLY;\r
-  }\r
-\r
-  //\r
-  // Initilize the option list in statement.\r
-  //\r
-  Link = GetFirstNode (&Statement->OptionListHead);\r
-  while (!IsNull (&Statement->OptionListHead, Link)) {\r
-    Option = QUESTION_OPTION_FROM_LINK (Link);\r
-    Link = GetNextNode (&Statement->OptionListHead, Link);\r
-    if ((Option->SuppressExpression != NULL) &&\r
-        ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
-      continue;\r
-    }\r
-\r
-    DisplayOption = AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION));\r
-    ASSERT (DisplayOption != NULL);\r
-\r
-    DisplayOption->ImageId      = Option->ImageId;\r
-    DisplayOption->Signature    = DISPLAY_QUESTION_OPTION_SIGNATURE;\r
-    DisplayOption->OptionOpCode = Option->OpCode;\r
-    InsertTailList(&DisplayStatement->OptionListHead, &DisplayOption->Link);\r
-  }\r
-\r
-  CopyMem (&DisplayStatement->CurrentValue, &Statement->HiiValue, sizeof (EFI_HII_VALUE));\r
-\r
-  //\r
-  // Some special op code need an extra buffer to save the data.\r
-  // Such as string, password, orderedlist...\r
-  //\r
-  if (Statement->BufferValue != NULL) {\r
-    //\r
-    // Ordered list opcode may not initilized, get default value here.\r
-    //\r
-    if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP && GetArrayData (Statement->BufferValue, Statement->ValueType, 0) == 0) {\r
-      GetQuestionDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, 0);\r
-    }\r
-\r
-    DisplayStatement->CurrentValue.Buffer    = AllocateCopyPool(Statement->StorageWidth,Statement->BufferValue);\r
-    DisplayStatement->CurrentValue.BufferLen = Statement->StorageWidth;\r
-  }\r
-\r
-  DisplayStatement->SettingChangedFlag = Statement->ValueChanged;\r
-\r
-  //\r
-  // Get the highlight statement for current form.\r
-  //\r
-  if (((gCurrentSelection->QuestionId != 0) && (Statement->QuestionId == gCurrentSelection->QuestionId)) ||\r
-      ((mCurFakeQestId != 0) && (Statement->FakeQuestionId == mCurFakeQestId))) {\r
-    gDisplayFormData.HighLightedStatement = DisplayStatement;\r
-  }\r
-\r
-  //\r
-  // Create the refresh event process function.\r
-  //\r
-  if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {\r
-    CreateRefreshEvent (Statement);\r
-  }\r
-\r
-  //\r
-  // For RTC type of date/time, set default refresh interval to be 1 second.\r
-  //\r
-  if ((Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) && Statement->Storage == NULL) {\r
-    Statement->RefreshInterval = 1;\r
-  }\r
-\r
-  //\r
-  // Create the refresh guid hook event.\r
-  // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.\r
-  //\r
-  if ((!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) || (Statement->RefreshInterval != 0)) {\r
-    gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
-  }\r
-\r
-  //\r
-  // Save the password check function for later use.\r
-  //\r
-  if (Statement->Operand == EFI_IFR_PASSWORD_OP) {\r
-    DisplayStatement->PasswordCheck = PasswordCheck;\r
-  }\r
-\r
-  //\r
-  // Save the validate check question for later use.\r
-  //\r
-  if (!IsListEmpty (&Statement->InconsistentListHead)) {\r
-    DisplayStatement->ValidateQuestion = QuestionCheck;\r
-  }\r
-\r
-  //\r
-  // If this statement is nest in the subtitle, insert to the host statement.\r
-  // else insert to the form it belongs to.\r
-  //\r
-  if (Statement->InSubtitle) {\r
-    InsertTailList(&HostDisplayStatement->NestStatementList, &DisplayStatement->DisplayLink);\r
-  } else {\r
-    InsertTailList(&gDisplayFormData.StatementListHead, &DisplayStatement->DisplayLink);\r
-  }\r
-}\r
-\r
-/**\r
-  Process for the refresh interval statement.\r
-\r
-  @param Event    The Event need to be process\r
-  @param Context  The context of the event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-RefreshIntervalProcess (\r
-  IN  EFI_EVENT    Event,\r
-  IN  VOID         *Context\r
-  )\r
-{\r
-  FORM_BROWSER_STATEMENT        *Statement;\r
-  LIST_ENTRY                    *Link;\r
-\r
-  Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
-  while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
-    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
-\r
-    if (Statement->RefreshInterval == 0) {\r
-      continue;\r
-    }\r
-\r
-    UpdateStatement(Statement);\r
-  }\r
-\r
-  gBS->SignalEvent (mValueChangedEvent);\r
-}\r
-\r
-/**\r
-\r
-  Make a copy of the global hotkey info.\r
-\r
-**/\r
-VOID\r
-UpdateHotkeyList (\r
-  VOID\r
-  )\r
-{\r
-  BROWSER_HOT_KEY  *HotKey;\r
-  BROWSER_HOT_KEY  *CopyKey;\r
-  LIST_ENTRY       *Link;\r
-\r
-  Link = GetFirstNode (&gBrowserHotKeyList);\r
-  while (!IsNull (&gBrowserHotKeyList, Link)) {\r
-    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
-\r
-    CopyKey             = AllocateCopyPool(sizeof (BROWSER_HOT_KEY), HotKey);\r
-    CopyKey->KeyData    = AllocateCopyPool(sizeof (EFI_INPUT_KEY), HotKey->KeyData);\r
-    CopyKey->HelpString = AllocateCopyPool(StrSize (HotKey->HelpString), HotKey->HelpString);\r
-\r
-    InsertTailList(&gDisplayFormData.HotKeyListHead, &CopyKey->Link);\r
-\r
-    Link = GetNextNode (&gBrowserHotKeyList, Link);\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Enum all statement in current form, find all the statement can be display and\r
-  add to the display form.\r
-\r
-**/\r
-VOID\r
-AddStatementToDisplayForm (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  LIST_ENTRY                    *Link;\r
-  FORM_BROWSER_STATEMENT        *Statement;\r
-  FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;\r
-  FORM_DISPLAY_ENGINE_STATEMENT *HostDisplayStatement;\r
-  UINT8                         MinRefreshInterval;\r
-  EFI_EVENT                     RefreshIntervalEvent;\r
-  FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
-  BOOLEAN                       FormEditable;\r
-\r
-  HostDisplayStatement = NULL;\r
-  MinRefreshInterval   = 0;\r
-  FormEditable         = FALSE;\r
-\r
-  //\r
-  // Process the statement outside the form, these statements are not recognized\r
-  // by browser core.\r
-  //\r
-  Link = GetFirstNode (&gCurrentSelection->FormSet->StatementListOSF);\r
-  while (!IsNull (&gCurrentSelection->FormSet->StatementListOSF, Link)) {\r
-    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&gCurrentSelection->FormSet->StatementListOSF, Link);\r
-\r
-    DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
-    ASSERT (DisplayStatement != NULL);\r
-    DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
-    DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
-    DisplayStatement->OpCode = Statement->OpCode;\r
-\r
-    InitializeListHead (&DisplayStatement->NestStatementList);\r
-    InitializeListHead (&DisplayStatement->OptionListHead);\r
-\r
-    InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
-  }\r
-\r
-  //\r
-  // Process the statement in this form.\r
-  //\r
-  Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
-  while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
-    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
-\r
-    //\r
-    // This statement can't be show, skip it.\r
-    //\r
-    if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) > ExpressGrayOut) {\r
-      continue;\r
-    }\r
-\r
-    DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
-    ASSERT (DisplayStatement != NULL);\r
-\r
-    //\r
-    // Initialize this statement and add it to the display form.\r
-    //\r
-    InitializeDisplayStatement(DisplayStatement, Statement, HostDisplayStatement);\r
-\r
-    //\r
-    // Save the Host statement info.\r
-    // Host statement may has nest statement follow it.\r
-    //\r
-    if (!Statement->InSubtitle) {\r
-      HostDisplayStatement = DisplayStatement;\r
-    }\r
-\r
-    if (Statement->Storage != NULL) {\r
-      FormEditable = TRUE;\r
-    }\r
-\r
-    //\r
-    // Get the minimal refresh interval value for later use.\r
-    //\r
-    if ((Statement->RefreshInterval != 0) && \r
-      (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval)) {\r
-      MinRefreshInterval = Statement->RefreshInterval;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Create the periodic timer for refresh interval statement.\r
-  //\r
-  if (MinRefreshInterval != 0) {\r
-    Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshIntervalProcess, NULL, &RefreshIntervalEvent);\r
-    ASSERT_EFI_ERROR (Status);\r
-    Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, MinRefreshInterval * ONE_SECOND);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
-    ASSERT (EventNode != NULL);\r
-    EventNode->RefreshEvent = RefreshIntervalEvent;\r
-    InsertTailList(&mRefreshEventList, &EventNode->Link);\r
-  }\r
-\r
-  //\r
-  // Update hotkey list field.\r
-  //\r
-  if (gBrowserSettingScope == SystemLevel || FormEditable) {\r
-    UpdateHotkeyList();\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Initialize the SettingChangedFlag variable in the display form.\r
-\r
-**/\r
-VOID\r
-UpdateDataChangedFlag (\r
-  VOID\r
-  )\r
-{\r
-  LIST_ENTRY           *Link;\r
-  FORM_BROWSER_FORMSET *LocalFormSet;\r
-\r
-  gDisplayFormData.SettingChangedFlag   = FALSE;\r
-\r
-  if (IsNvUpdateRequiredForForm (gCurrentSelection->Form)) {\r
-    gDisplayFormData.SettingChangedFlag = TRUE;\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Base on the system level to check whether need to show the NV flag.\r
-  // \r
-  switch (gBrowserSettingScope) {\r
-  case SystemLevel:\r
-    //\r
-    // Check the maintain list to see whether there is any change.\r
-    //\r
-    Link = GetFirstNode (&gBrowserFormSetList);\r
-    while (!IsNull (&gBrowserFormSetList, Link)) {\r
-      LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
-      if (IsNvUpdateRequiredForFormSet(LocalFormSet)) {\r
-        gDisplayFormData.SettingChangedFlag = TRUE;\r
-        return;\r
-      }\r
-      Link = GetNextNode (&gBrowserFormSetList, Link);\r
-    }\r
-    break;\r
-\r
-  case FormSetLevel:\r
-    if (IsNvUpdateRequiredForFormSet(gCurrentSelection->FormSet)) {\r
-      gDisplayFormData.SettingChangedFlag = TRUE;\r
-      return;\r
-    }\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Initialize the Display form structure data.\r
-\r
-**/\r
-VOID\r
-InitializeDisplayFormData (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  gDisplayFormData.Signature   = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;\r
-  gDisplayFormData.Version     = FORM_DISPLAY_ENGINE_VERSION_1;\r
-  gDisplayFormData.ImageId     = 0;\r
-  gDisplayFormData.AnimationId = 0;\r
-\r
-  InitializeListHead (&gDisplayFormData.StatementListHead);\r
-  InitializeListHead (&gDisplayFormData.StatementListOSF);\r
-  InitializeListHead (&gDisplayFormData.HotKeyListHead);\r
-\r
-  Status = gBS->CreateEvent (\r
-        EVT_NOTIFY_WAIT, \r
-        TPL_CALLBACK,\r
-        SetupBrowserEmptyFunction,\r
-        NULL,\r
-        &mValueChangedEvent\r
-        );\r
-  ASSERT_EFI_ERROR (Status); \r
-}\r
-\r
-/**\r
-\r
-  Free the kotkey info saved in form data.\r
-\r
-**/\r
-VOID\r
-FreeHotkeyList (\r
-  VOID\r
-  )\r
-{\r
-  BROWSER_HOT_KEY  *HotKey;\r
-  LIST_ENTRY       *Link;\r
-\r
-  while (!IsListEmpty (&gDisplayFormData.HotKeyListHead)) {\r
-    Link = GetFirstNode (&gDisplayFormData.HotKeyListHead);\r
-    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
-\r
-    RemoveEntryList (&HotKey->Link);\r
-\r
-    FreePool (HotKey->KeyData);\r
-    FreePool (HotKey->HelpString);\r
-    FreePool (HotKey);\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Update the Display form structure data.\r
-\r
-**/\r
-VOID\r
-UpdateDisplayFormData (\r
-  VOID\r
-  )\r
-{\r
-  gDisplayFormData.FormTitle        = gCurrentSelection->Form->FormTitle;\r
-  gDisplayFormData.FormId           = gCurrentSelection->FormId;\r
-  gDisplayFormData.HiiHandle        = gCurrentSelection->Handle;\r
-  CopyGuid (&gDisplayFormData.FormSetGuid, &gCurrentSelection->FormSetGuid);\r
-\r
-  gDisplayFormData.Attribute        = 0;\r
-  gDisplayFormData.Attribute       |= gCurrentSelection->Form->ModalForm ? HII_DISPLAY_MODAL : 0;\r
-  gDisplayFormData.Attribute       |= gCurrentSelection->Form->Locked    ? HII_DISPLAY_LOCK  : 0;\r
-\r
-  gDisplayFormData.FormRefreshEvent     = NULL;\r
-  gDisplayFormData.HighLightedStatement = NULL;\r
-\r
-  gDisplayFormData.BrowserStatus = gBrowserStatus;\r
-  gDisplayFormData.ErrorString   = gErrorInfo;\r
-\r
-  gBrowserStatus = BROWSER_SUCCESS;\r
-  gErrorInfo     = NULL;\r
-\r
-  UpdateDataChangedFlag ();\r
-\r
-  AddStatementToDisplayForm ();\r
-}\r
-\r
-/**\r
-\r
-  Free the Display Statement structure data.\r
-\r
-  @param   StatementList         Point to the statement list which need to be free.\r
-\r
-**/\r
-VOID\r
-FreeStatementData (\r
-  LIST_ENTRY           *StatementList\r
-  )\r
-{\r
-  LIST_ENTRY                    *Link;\r
-  LIST_ENTRY                    *OptionLink;\r
-  FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
-  DISPLAY_QUESTION_OPTION       *Option;\r
-\r
-  //\r
-  // Free Statements/Questions\r
-  //\r
-  while (!IsListEmpty (StatementList)) {\r
-    Link = GetFirstNode (StatementList);\r
-    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
-\r
-    //\r
-    // Free Options List\r
-    //\r
-    while (!IsListEmpty (&Statement->OptionListHead)) {\r
-      OptionLink = GetFirstNode (&Statement->OptionListHead);\r
-      Option = DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink);\r
-      RemoveEntryList (&Option->Link);\r
-      FreePool (Option);\r
-    }\r
+  Clear retangle with specified text attribute.\r
 \r
 \r
-    //\r
-    // Free nest statement List\r
-    //\r
-    if (!IsListEmpty (&Statement->NestStatementList)) {\r
-      FreeStatementData(&Statement->NestStatementList);\r
-    }\r
-\r
-    RemoveEntryList (&Statement->DisplayLink);\r
-    FreePool (Statement);\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  Free the Display form structure data.\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
 \r
 **/\r
 VOID\r
-FreeDisplayFormData (\r
-  VOID\r
-  )\r
-{\r
-  FreeStatementData (&gDisplayFormData.StatementListHead);\r
-  FreeStatementData (&gDisplayFormData.StatementListOSF);\r
-\r
-  FreeRefreshEvent();\r
-\r
-  FreeHotkeyList();\r
-}\r
-\r
-/**\r
-\r
-  Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.\r
-\r
-  @param DisplayStatement        The input FORM_DISPLAY_ENGINE_STATEMENT.\r
-\r
-  @retval FORM_BROWSER_STATEMENT  The return FORM_BROWSER_STATEMENT info.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-GetBrowserStatement (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement\r
-  )\r
-{\r
-  FORM_BROWSER_STATEMENT *Statement;\r
-  LIST_ENTRY             *Link;\r
-\r
-  Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
-  while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
-    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-\r
-    if (Statement->OpCode == DisplayStatement->OpCode) {\r
-      return Statement;\r
-    }\r
-\r
-    Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-\r
-  Process the action request in user input.\r
-\r
-  @param Action                  The user input action request info.\r
-  @param DefaultId               The user input default Id info.\r
-\r
-  @retval EFI_SUCESSS            This function always return successfully for now.\r
-\r
-**/\r
-EFI_STATUS \r
-ProcessAction (\r
-  IN UINT32        Action,\r
-  IN UINT16        DefaultId\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-\r
-  //\r
-  // This is caused by use press ESC, and it should not combine with other action type.\r
-  //\r
-  if ((Action & BROWSER_ACTION_FORM_EXIT) == BROWSER_ACTION_FORM_EXIT) {\r
-    FindNextMenu (gCurrentSelection, FormLevel);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Below is normal hotkey trigged action, these action maybe combine with each other.\r
-  //\r
-  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
-    DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
-  }\r
-\r
-  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
-    ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);\r
-  }\r
-\r
-  if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
-    Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
-    if (EFI_ERROR (Status)) {\r
-      gBrowserStatus = BROWSER_SUBMIT_FAIL;\r
-    }\r
-  }\r
-\r
-  if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
-    gResetRequired = TRUE;\r
-  }\r
-\r
-  if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
-    //\r
-    // Form Exit without saving, Similar to ESC Key.\r
-    // FormSet Exit without saving, Exit SendForm.\r
-    // System Exit without saving, CallExitHandler and Exit SendForm.\r
-    //\r
-    DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
-    if (gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) {\r
-      FindNextMenu (gCurrentSelection, gBrowserSettingScope);\r
-    } else if (gBrowserSettingScope == SystemLevel) {\r
-      if (ExitHandlerFunction != NULL) {\r
-        ExitHandlerFunction ();\r
-      }\r
-      gCurrentSelection->Action = UI_ACTION_EXIT;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Find HII Handle in the HII database associated with given Device Path.\r
-\r
-  If DevicePath is NULL, then ASSERT.\r
-\r
-  @param  DevicePath             Device Path associated with the HII package list\r
-                                 handle.\r
-\r
-  @retval Handle                 HII package list Handle associated with the Device\r
-                                        Path.\r
-  @retval NULL                   Hii Package list handle is not found.\r
-\r
-**/\r
-EFI_HII_HANDLE\r
-EFIAPI\r
-DevicePathToHiiHandle (\r
-  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath\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
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  EFI_DEVICE_PATH_PROTOCOL    *TmpDevicePath;\r
-  UINTN                       BufferSize;\r
-  UINTN                       HandleCount;\r
-  UINTN                       Index;\r
-  EFI_HANDLE                  Handle;\r
-  EFI_HANDLE                  DriverHandle;\r
-  EFI_HII_HANDLE              *HiiHandles;\r
-  EFI_HII_HANDLE              HiiHandle;\r
-\r
-  ASSERT (DevicePath != NULL);\r
-\r
-  TmpDevicePath = DevicePath;\r
-  //\r
-  // Locate Device Path Protocol handle buffer\r
-  //\r
-  Status = gBS->LocateDevicePath (\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  &TmpDevicePath,\r
-                  &DriverHandle\r
-                  );\r
-  if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Retrieve all HII Handles from HII database\r
-  //\r
-  BufferSize = 0x1000;\r
-  HiiHandles = AllocatePool (BufferSize);\r
-  ASSERT (HiiHandles != NULL);\r
-  Status = mHiiDatabase->ListPackageLists (\r
-                           mHiiDatabase,\r
-                           EFI_HII_PACKAGE_TYPE_ALL,\r
-                           NULL,\r
-                           &BufferSize,\r
-                           HiiHandles\r
-                           );\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    FreePool (HiiHandles);\r
-    HiiHandles = AllocatePool (BufferSize);\r
-    ASSERT (HiiHandles != NULL);\r
-\r
-    Status = mHiiDatabase->ListPackageLists (\r
-                             mHiiDatabase,\r
-                             EFI_HII_PACKAGE_TYPE_ALL,\r
-                             NULL,\r
-                             &BufferSize,\r
-                             HiiHandles\r
-                             );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (HiiHandles);\r
-    return NULL;\r
-  }\r
+  CHAR16  *Buffer;\r
+  UINTN   Row;\r
 \r
   //\r
 \r
   //\r
-  // Search Hii Handle by Driver Handle\r
+  // For now, allocate an arbitrarily long buffer\r
   //\r
   //\r
-  HiiHandle = NULL;\r
-  HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = mHiiDatabase->GetPackageListHandle (\r
-                             mHiiDatabase,\r
-                             HiiHandles[Index],\r
-                             &Handle\r
-                             );\r
-    if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
-      HiiHandle = HiiHandles[Index];\r
-      break;\r
-    }\r
-  }\r
-\r
-  FreePool (HiiHandles);\r
-  return HiiHandle;\r
-}\r
-\r
-/**\r
-  Find HII Handle in the HII database associated with given form set guid.\r
-\r
-  If FormSetGuid is NULL, then ASSERT.\r
-\r
-  @param  ComparingGuid          FormSet Guid associated with the HII package list\r
-                                 handle.\r
+  Buffer = AllocateZeroPool (0x10000);\r
+  ASSERT (Buffer != NULL);\r
 \r
 \r
-  @retval Handle                 HII package list Handle associated with the Device\r
-                                        Path.\r
-  @retval NULL                   Hii Package list handle is not found.\r
-\r
-**/\r
-EFI_HII_HANDLE\r
-FormSetGuidToHiiHandle (\r
-  EFI_GUID     *ComparingGuid\r
-  )\r
-{\r
-  EFI_HII_HANDLE               *HiiHandles;\r
-  UINTN                        Index;\r
-  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
-  UINTN                        BufferSize;\r
-  UINT32                       Offset;\r
-  UINT32                       Offset2;\r
-  UINT32                       PackageListLength;\r
-  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
-  UINT8                        *Package;\r
-  UINT8                        *OpCodeData;\r
-  EFI_STATUS                   Status;\r
-  EFI_HII_HANDLE               HiiHandle;\r
-\r
-  ASSERT (ComparingGuid != NULL);\r
-\r
-  HiiHandle  = NULL;\r
   //\r
   //\r
-  // Get all the Hii handles\r
+  // Set foreground and background as defined\r
   //\r
   //\r
-  HiiHandles = HiiGetHiiHandles (NULL);\r
-  ASSERT (HiiHandles != NULL);\r
+  gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);\r
 \r
   //\r
 \r
   //\r
-  // Search for formset of each class type\r
+  // Much faster to buffer the long string instead of print it a character at a time\r
   //\r
   //\r
-  for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
-    BufferSize = 0;\r
-    HiiPackageList = NULL;\r
-    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
-    if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      HiiPackageList = AllocatePool (BufferSize);\r
-      ASSERT (HiiPackageList != NULL);\r
-\r
-      Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
-    }\r
-    if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
-      return NULL;\r
-    }\r
-\r
-    //\r
-    // Get Form package from this HII package List\r
-    //\r
-    Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-    Offset2 = 0;\r
-    CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
-\r
-    while (Offset < PackageListLength) {\r
-      Package = ((UINT8 *) HiiPackageList) + Offset;\r
-      CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
-      if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
-        //\r
-        // Search FormSet in this Form Package\r
-        //\r
-        Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
-        while (Offset2 < PackageHeader.Length) {\r
-          OpCodeData = Package + Offset2;\r
-\r
-          if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
-            //\r
-            // Try to compare against formset GUID\r
-            //\r
-            if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
-              HiiHandle = HiiHandles[Index];\r
-              break;\r
-            }\r
-          }\r
-\r
-          Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
-        }\r
-      }\r
-      if (HiiHandle != NULL) {\r
-        break;\r
-      }\r
-      Offset += PackageHeader.Length;\r
-    }\r
-    \r
-    FreePool (HiiPackageList);\r
-       if (HiiHandle != NULL) {\r
-               break;\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
   }\r
 \r
-  FreePool (HiiHandles);\r
+  gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);\r
 \r
 \r
-  return HiiHandle;\r
+  FreePool (Buffer);\r
+  return ;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  check how to process the changed data in current form or form set.\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
+  Concatenate a narrow string to another string.\r
 \r
 \r
-  @param Scope           Data save or discard scope, form or formset.\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
-  @retval                TRUE   Success process the changed data, will return to the parent form.\r
-  @retval                FALSE  Reject to process the changed data, will stay at  current form.\r
 **/\r
 **/\r
-BOOLEAN\r
-ProcessChangedData (\r
-  IN OUT UI_MENU_SELECTION       *Selection,\r
-  IN     BROWSER_SETTING_SCOPE   Scope\r
+VOID\r
+NewStrCat (\r
+  IN OUT CHAR16               *Destination,\r
+  IN     CHAR16               *Source\r
   )\r
 {\r
   )\r
 {\r
-  BOOLEAN  RetValue;\r
-\r
-  RetValue = TRUE;\r
-  switch (mFormDisplay->ConfirmDataChange()) {\r
-    case BROWSER_ACTION_DISCARD:\r
-      DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
-      break;\r
-  \r
-    case BROWSER_ACTION_SUBMIT:\r
-      SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
-      break;\r
+  UINTN Length;\r
 \r
 \r
-    case BROWSER_ACTION_NONE:\r
-      RetValue = FALSE;\r
-      break;\r
+  for (Length = 0; Destination[Length] != 0; Length++)\r
+    ;\r
 \r
 \r
-    default:\r
-      //\r
-      // if Invalid value return, process same as BROWSER_ACTION_NONE.\r
-      //\r
-      RetValue = FALSE;\r
-      break;\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
 \r
-  return RetValue;\r
+  StrCpy (Destination + Length, Source);\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Find parent formset menu(the first menu which has different formset) for current menu.\r
-  If not find, just return to the first menu.\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
 \r
-  @param Selection    The selection info.\r
+  @return Storage space for the input string.\r
 \r
 **/\r
 \r
 **/\r
-VOID\r
-FindParentFormSet (\r
-  IN OUT   UI_MENU_SELECTION           *Selection\r
+UINTN\r
+GetStringWidth (\r
+  IN CHAR16               *String\r
   )\r
 {\r
   )\r
 {\r
-  FORM_ENTRY_INFO            *CurrentMenu;\r
-  FORM_ENTRY_INFO            *ParentMenu;\r
+  UINTN Index;\r
+  UINTN Count;\r
+  UINTN IncrementValue;\r
 \r
 \r
-  CurrentMenu = Selection->CurrentMenu;\r
-  ParentMenu  = UiFindParentMenu(CurrentMenu);\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
 \r
   //\r
-  // Find a menu which has different formset guid with current.\r
+  // Increment by one to include the null-terminator in the size\r
   //\r
   //\r
-  while (ParentMenu != NULL && CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
-    CurrentMenu = ParentMenu;\r
-    ParentMenu  = UiFindParentMenu(CurrentMenu);\r
-  }\r
-\r
-  if (ParentMenu != NULL) {\r
-    CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
-    Selection->Handle = ParentMenu->HiiHandle;\r
-    Selection->FormId     = ParentMenu->FormId;\r
-    Selection->QuestionId = ParentMenu->QuestionId;\r
-  } else {\r
-    Selection->FormId     = CurrentMenu->FormId;\r
-    Selection->QuestionId = CurrentMenu->QuestionId;\r
-  }\r
+  Count++;\r
 \r
 \r
-  Selection->Statement  = NULL;\r
+  return Count * sizeof (CHAR16);\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Process the goto op code, update the info in the selection structure.\r
+  This function displays the page frame.\r
 \r
 \r
-  @param Statement    The statement belong to goto op code.\r
-  @param Selection    The selection info.\r
-\r
-  @retval EFI_SUCCESS    The menu process successfully.\r
-  @return Other value if the process failed.\r
+  @param  Selection              Selection contains the information about \r
+                                 the Selection, form and formset to be displayed.\r
+                                 Selection action may be updated in retrieve callback.\r
 **/\r
 **/\r
-EFI_STATUS\r
-ProcessGotoOpCode (\r
-  IN OUT   FORM_BROWSER_STATEMENT      *Statement,\r
-  IN OUT   UI_MENU_SELECTION           *Selection\r
+VOID\r
+DisplayPageFrame (\r
+  IN UI_MENU_SELECTION    *Selection\r
   )\r
 {\r
   )\r
 {\r
-  CHAR16                          *StringPtr;\r
-  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
-  FORM_BROWSER_FORM               *RefForm;\r
-  EFI_STATUS                      Status;\r
-  EFI_HII_HANDLE                  HiiHandle;\r
-  \r
-  Status    = EFI_SUCCESS;\r
-  StringPtr = NULL;\r
-  HiiHandle = NULL;\r
-\r
-  //\r
-  // Prepare the device path check, get the device path info first.\r
-  //\r
-  if (Statement->HiiValue.Value.ref.DevicePath != 0) {\r
-    StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);\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
+  if (Selection->Form->ModalForm) {\r
+    return;\r
   }\r
 \r
   }\r
 \r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
   //\r
   //\r
-  // Check whether the device path string is a valid string.\r
+  // For now, allocate an arbitrarily long buffer\r
   //\r
   //\r
-  if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {\r
-    if (Selection->Form->ModalForm) {\r
-      return Status;\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
 \r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
     //\r
     //\r
-    // Goto another Hii Package list\r
+    //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);\r
     //\r
     //\r
-    if (mPathFromText != NULL) {\r
-      DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);\r
-      if (DevicePath != NULL) {\r
-        HiiHandle = DevicePathToHiiHandle (DevicePath);\r
-        FreePool (DevicePath);\r
-      }\r
-      FreePool (StringPtr);\r
-    } else {\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
       //\r
-      // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.\r
+      //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {\r
       //\r
       //\r
-      gBrowserStatus = BROWSER_PROTOCOL_NOT_FOUND;\r
-      FreePool (StringPtr);\r
-      return Status;\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
 \r
-    if (HiiHandle != Selection->Handle) {\r
-      //\r
-      // Goto another Formset, check for uncommitted data\r
-      //\r
-      if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&\r
-          IsNvUpdateRequiredForFormSet(Selection->FormSet)) {\r
-        if (!ProcessChangedData(Selection, FormSetLevel)) {\r
-          return EFI_SUCCESS;\r
+        switch (Alignment - LocalScreen.LeftColumn) {\r
+        case 0:\r
+          //\r
+          // Handle left column\r
+          //\r
+          PrintStringAt (LocalScreen.LeftColumn + BANNER_LEFT_COLUMN_INDENT, 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
+\r
+        FreePool (StrFrontPageBanner);\r
       }\r
     }\r
       }\r
     }\r
+  }\r
 \r
 \r
-    Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
-    Selection->Handle = HiiHandle;\r
-    if (Selection->Handle == NULL) {\r
-      //\r
-      // If target Hii Handle not found, exit current formset.\r
-      //\r
-      FindParentFormSet(Selection);\r
-      return EFI_SUCCESS;\r
+  ClearLines (\r
+    LocalScreen.LeftColumn,\r
+    LocalScreen.RightColumn,\r
+    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,\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
     }\r
 \r
-    CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
-    Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
-    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
-  } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {\r
-    if (Selection->Form->ModalForm) {\r
-      return Status;\r
-    }\r
-    if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &Selection->FormSetGuid)) {\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
       //\r
-      // Goto another Formset, check for uncommitted data\r
+      // Print Bottom border line\r
+      // +------------------------------------------------------------------------------+\r
+      // ?                                                                             ?\r
+      // +------------------------------------------------------------------------------+\r
       //\r
       //\r
-      if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&\r
-         IsNvUpdateRequiredForFormSet(Selection->FormSet)) {\r
-        if (!ProcessChangedData(Selection, FormSetLevel)) {\r
-          return EFI_SUCCESS;\r
-        }\r
+      Character = BOXDRAW_DOWN_RIGHT;\r
+      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, 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 - gFooterHeight + 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
-    }\r
 \r
 \r
-    Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
-    Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);\r
-    if (Selection->Handle == NULL) {\r
-      //\r
-      // If target Hii Handle not found, exit current formset.\r
-      //\r
-      FindParentFormSet(Selection);\r
-      return EFI_SUCCESS;\r
-    }\r
+      Character = BOXDRAW_UP_RIGHT;\r
+      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);\r
 \r
 \r
-    CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
-    Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
-    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
-  } else if (Statement->HiiValue.Value.ref.FormId != 0) {\r
-    //\r
-    // Goto another Form, check for uncommitted data\r
-    //\r
-    if (Statement->HiiValue.Value.ref.FormId != Selection->FormId) {\r
-      if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm(Selection->Form))) {\r
-        if (!ProcessChangedData (Selection, FormLevel)) {\r
-          return EFI_SUCCESS;\r
-        }\r
-      }\r
-    }\r
+      PrintString (Buffer);\r
 \r
 \r
-    RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);\r
-    if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
-      if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\r
-        //\r
-        // Form is suppressed. \r
-        //\r
-        gBrowserStatus = BROWSER_FORM_SUPPRESS;\r
-        return EFI_SUCCESS;\r
-      }\r
+      Character = BOXDRAW_UP_LEFT;\r
+      PrintChar (Character);\r
     }\r
     }\r
-\r
-    Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
-    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
-  } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {\r
-    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
   }\r
 \r
   }\r
 \r
-  return Status;\r
+  FreePool (Buffer);\r
+\r
 }\r
 \r
 \r
 /**\r
 }\r
 \r
 \r
 /**\r
-  Process Question Config.\r
+  Evaluate all expressions in a Form.\r
 \r
 \r
-  @param  Selection              The UI menu selection.\r
-  @param  Question               The Question to be peocessed.\r
+  @param  FormSet        FormSet this Form belongs to.\r
+  @param  Form           The Form.\r
 \r
 \r
-  @retval EFI_SUCCESS            Question Config process success.\r
-  @retval Other                  Question Config process fail.\r
+  @retval EFI_SUCCESS    The expression evaluated successfuly\r
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-ProcessQuestionConfig (\r
-  IN  UI_MENU_SELECTION       *Selection,\r
-  IN  FORM_BROWSER_STATEMENT  *Question\r
+EvaluateFormExpressions (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form\r
   )\r
 {\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  CHAR16                          *ConfigResp;\r
-  CHAR16                          *Progress;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_STATUS       Status;\r
+  LIST_ENTRY       *Link;\r
+  FORM_EXPRESSION  *Expression;\r
 \r
 \r
-  if (Question->QuestionConfig == 0) {\r
-    return EFI_SUCCESS;\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
 \r
-  //\r
-  // Get <ConfigResp>\r
-  //\r
-  ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);\r
-  if (ConfigResp == NULL) {\r
-    return EFI_NOT_FOUND;\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
 \r
-  //\r
-  // Send config to Configuration Driver\r
-  //\r
-  ConfigAccess = Selection->FormSet->ConfigAccess;\r
-  if (ConfigAccess == NULL) {\r
-    return EFI_UNSUPPORTED;\r
+    Status = EvaluateExpression (FormSet, Form, Expression);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
   }\r
   }\r
-  Status = ConfigAccess->RouteConfig (\r
-                           ConfigAccess,\r
-                           ConfigResp,\r
-                           &Progress\r
-                           );\r
 \r
 \r
-  return Status;\r
+  return EFI_SUCCESS;\r
 }\r
 \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
 \r
-  Process the user input data.\r
 \r
 \r
-  @param UserInput               The user input data.\r
-  @param ChangeHighlight         Whether need to change the highlight statement.  \r
+  Display form and wait for user to select one menu option, then return it.\r
 \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
   @retval EFI_SUCESSS            This function always return successfully for now.\r
 \r
 **/\r
 EFI_STATUS\r
-ProcessUserInput (\r
-  IN USER_INPUT               *UserInput,\r
-  IN BOOLEAN                  ChangeHighlight\r
+DisplayForm (\r
+  IN OUT UI_MENU_SELECTION           *Selection\r
   )\r
 {\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  FORM_BROWSER_STATEMENT        *Statement;\r
+  CHAR16                 *StringPtr;\r
+  UINT16                 MenuItemCount;\r
+  EFI_HII_HANDLE         Handle;\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
+  UINT16                 GlyphWidth;\r
 \r
 \r
-  Status = EFI_SUCCESS;\r
+  Handle        = Selection->Handle;\r
+  MenuItemCount = 0;\r
+  ArrayEntry    = 0;\r
+  OutputString  = NULL;\r
 \r
 \r
-  //\r
-  // When Exit from FormDisplay function, one of the below two cases must be true.\r
-  //\r
-  ASSERT (UserInput->Action != 0 || UserInput->SelectedStatement != NULL);\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
+    if (Selection->Form->ModalForm) {\r
+      gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | EFI_BACKGROUND_BLACK);\r
+    } else {\r
+      gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
+    }\r
+    PrintStringAt (\r
+      (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,\r
+      LocalScreen.TopRow + 1,\r
+      StringPtr\r
+      );\r
+  }\r
 \r
   //\r
 \r
   //\r
-  // Remove the last highligh question id, this id will update when show next form.\r
+  // Remove Buffer allocated for StringPtr after it has been used.\r
   //\r
   //\r
-  gCurrentSelection->QuestionId = 0;\r
+  FreePool (StringPtr);\r
 \r
   //\r
 \r
   //\r
-  // First process the Action field in USER_INPUT.\r
+  // Evaluate all the Expressions in this Form\r
   //\r
   //\r
-  if (UserInput->Action != 0) {\r
-    Status = ProcessAction (UserInput->Action, UserInput->DefaultId);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
 \r
-    //\r
-    // Clear the highlight info.\r
-    //\r
-    gCurrentSelection->Statement = NULL;\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
 \r
-    if (UserInput->SelectedStatement != NULL) {\r
-      Statement = GetBrowserStatement(UserInput->SelectedStatement);\r
-      ASSERT (Statement != NULL);\r
-      //\r
-      // Save the current highlight menu in the menu history data.\r
-      // which will be used when later browse back to this form.\r
-      //\r
-      gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
-      //\r
-      // For statement like text, actio, it not has question id.\r
-      // So use FakeQuestionId to save the question.\r
-      //\r
-      if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
-        mCurFakeQestId = Statement->FakeQuestionId;\r
-      } else {\r
-        mCurFakeQestId = 0;\r
-      }\r
-    }\r
-  } else {\r
-    Statement = GetBrowserStatement(UserInput->SelectedStatement);\r
-    ASSERT (Statement != NULL);\r
+    if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) <= ExpressGrayOut) {\r
+      StringPtr = GetToken (Statement->Prompt, Handle);\r
+      ASSERT (StringPtr != NULL);\r
 \r
 \r
-    gCurrentSelection->Statement = Statement;\r
+      Width     = GetWidth (Statement, Handle);\r
 \r
 \r
-    if (ChangeHighlight) {\r
-      //\r
-      // This question is the current user select one,record it and later\r
-      // show it as the highlight question.\r
-      //\r
-      gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
-      //\r
-      // For statement like text, actio, it not has question id.\r
-      // So use FakeQuestionId to save the question.\r
-      //\r
-      if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
-        mCurFakeQestId = Statement->FakeQuestionId;\r
-      } else {\r
-        mCurFakeQestId = 0;\r
+      NumberOfLines = 1;\r
+      ArrayEntry = 0;\r
+      GlyphWidth = 1;\r
+      for (; GetLineByWidth (StringPtr, Width, &GlyphWidth,&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
 \r
 \r
-    switch (Statement->Operand) {\r
-    case EFI_IFR_REF_OP:\r
-      Status = ProcessGotoOpCode(Statement, gCurrentSelection);\r
-      break;\r
-    \r
-    case EFI_IFR_ACTION_OP:\r
-      //\r
-      // Process the Config string <ConfigResp>\r
-      //\r
-      Status = ProcessQuestionConfig (gCurrentSelection, Statement);\r
-      break;\r
-    \r
-    case EFI_IFR_RESET_BUTTON_OP:\r
       //\r
       //\r
-      // Reset Question to default value specified by DefaultId\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
       //\r
-      Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);\r
-      break;\r
-\r
-    default:\r
-      switch (Statement->Operand) {\r
-      case EFI_IFR_STRING_OP:\r
-        DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
-        Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
-        CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
-        FreePool (UserInput->InputValue.Buffer);\r
-        break;\r
-\r
-      case EFI_IFR_PASSWORD_OP:\r
-        if (UserInput->InputValue.Buffer == NULL) {\r
-          //\r
-          // User not input new password, just return.\r
-          //\r
-          break;\r
-        }\r
+      MenuOption = UiAddMenuOption (StringPtr, Selection->Handle, Selection->Form, Statement, NumberOfLines, MenuItemCount);\r
+      MenuItemCount++;\r
 \r
 \r
-        DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
-        Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
-        CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
-        FreePool (UserInput->InputValue.Buffer);\r
+      if (MenuOption->IsQuestion && !MenuOption->ReadOnly) {\r
         //\r
         //\r
-        // Two password match, send it to Configuration Driver\r
+        // At least one item is not readonly, this Form is considered as editable\r
         //\r
         //\r
-        if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
-          PasswordCheck (NULL, UserInput->SelectedStatement, (CHAR16 *) Statement->BufferValue);\r
-          //\r
-          // Clean the value after saved it.\r
-          //\r
-          ZeroMem (Statement->BufferValue, (UINTN) UserInput->InputValue.BufferLen);\r
-          HiiSetString (gCurrentSelection->FormSet->HiiHandle, Statement->HiiValue.Value.string, (CHAR16*)Statement->BufferValue, NULL);\r
-        } else {\r
-          SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);\r
-        }\r
-        break;\r
-\r
-      case EFI_IFR_ORDERED_LIST_OP:\r
-        CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, UserInput->InputValue.BufferLen);\r
-        break;\r
-\r
-      default:\r
-        CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));\r
-        break;\r
-      }\r
-      if (Statement->Operand != EFI_IFR_PASSWORD_OP) {\r
-        SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
+        Selection->FormEditable = TRUE;\r
       }\r
       }\r
-      break;\r
     }\r
     }\r
+\r
+    Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
   }\r
 \r
   }\r
 \r
+  Status = UiDisplayMenu (Selection);\r
+\r
+  UiFreeMenu ();\r
+\r
   return Status;\r
 }\r
 \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
+  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
+  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
+  gProtocolNotFound     = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);\r
+  return ;\r
+}\r
+\r
+/**\r
+  Free up the resource allocated for all strings required\r
+  by Setup Browser.\r
 \r
 \r
-  Display form and wait for user to select one menu option, then return it.\r
+**/\r
+VOID\r
+FreeBrowserStrings (\r
+  VOID\r
+  )\r
+{\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
+  FreePool (gProtocolNotFound);\r
+  return ;\r
+}\r
 \r
 \r
-  @retval EFI_SUCESSS            This function always return successfully for now.\r
+/**\r
+  Show all registered HotKey help strings on bottom Rows.\r
 \r
 **/\r
 \r
 **/\r
-EFI_STATUS\r
-DisplayForm (\r
+VOID\r
+PrintHotKeyHelpString (\r
   VOID\r
   )\r
 {\r
   VOID\r
   )\r
 {\r
-  EFI_STATUS               Status;\r
-  USER_INPUT               UserInput;\r
-  FORM_ENTRY_INFO          *CurrentMenu;\r
-  BOOLEAN                  ChangeHighlight;\r
+  UINTN                  CurrentCol;\r
+  UINTN                  CurrentRow;\r
+  UINTN                  BottomRowOfHotKeyHelp;\r
+  UINTN                  ColumnWidth;\r
+  UINTN                  Index;\r
+  EFI_SCREEN_DESCRIPTOR  LocalScreen;\r
+  LIST_ENTRY             *Link;\r
+  BROWSER_HOT_KEY        *HotKey;\r
 \r
 \r
-  ZeroMem (&UserInput, sizeof (USER_INPUT));\r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+  ColumnWidth            = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
+  BottomRowOfHotKeyHelp  = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;\r
 \r
   //\r
 \r
   //\r
-  // Update the menu history data.\r
+  // Calculate total number of Register HotKeys. \r
   //\r
   //\r
-  CurrentMenu = UiFindMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid, gCurrentSelection->FormId);\r
-  if (CurrentMenu == NULL) {\r
+  Index = 0;\r
+  Link  = GetFirstNode (&gBrowserHotKeyList);\r
+  while (!IsNull (&gBrowserHotKeyList, Link)) {\r
+    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
     //\r
     //\r
-    // Current menu not found, add it to the menu tree\r
+    // Help string can't exceed ColumnWidth. One Row will show three Help information. \r
     //\r
     //\r
-    CurrentMenu = UiAddMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid,\r
-                                 gCurrentSelection->FormId, gCurrentSelection->QuestionId);\r
-    ASSERT (CurrentMenu != NULL);\r
-  }\r
-  gCurrentSelection->CurrentMenu = CurrentMenu;\r
+    if (StrLen (HotKey->HelpString) > ColumnWidth) {\r
+      HotKey->HelpString[ColumnWidth] = L'\0';\r
+    }\r
+    //\r
+    // Calculate help information Column and Row.\r
+    //\r
+    if ((Index % 3) != 2) {\r
+      CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;\r
+    } else {\r
+      CurrentCol = LocalScreen.LeftColumn + 2;\r
+    }\r
+    CurrentRow = BottomRowOfHotKeyHelp - Index / 3;\r
+    //\r
+    // Print HotKey help string on bottom Row.\r
+    //\r
+    PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);\r
 \r
 \r
-  //\r
-  // Find currrent highlight statement.\r
-  //\r
-  if (gCurrentSelection->QuestionId == 0) {\r
     //\r
     //\r
-    // Highlight not specified, fetch it from cached menu\r
+    // Get Next Hot Key.\r
     //\r
     //\r
-    gCurrentSelection->QuestionId = CurrentMenu->QuestionId;\r
+    Link = GetNextNode (&gBrowserHotKeyList, Link);\r
+    Index ++;\r
   }\r
   }\r
+  \r
+  return;\r
+}\r
 \r
 \r
-  //\r
-  // Evaluate all the Expressions in this Form\r
-  //\r
-  Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+/**\r
+  Update key's help imformation.\r
 \r
 \r
-  UpdateDisplayFormData ();\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
-  //\r
-  // Three possible status maybe return.\r
-  //\r
-  // EFI_INVALID_PARAMETER: The input dimension info is not valid.\r
-  // EFI_NOT_FOUND:         The input value for oneof/orderedlist opcode is not valid\r
-  //                        and an valid value has return.\r
-  // EFI_SUCCESS:           Success shows form and get user input in UserInput paramenter.\r
-  //\r
-  Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);\r
-  if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
-    FreeDisplayFormData();\r
-    return Status;\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
+  gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+  if (Selection->Form->ModalForm) {\r
+    return;\r
   }\r
 \r
   }\r
 \r
-  //\r
-  // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.\r
-  //                           in this case, browser need to change the highlight menu.\r
-  // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist \r
-  //                          opcode and new valid value has return, browser core need to adjust\r
-  //                          value for this opcode and shows this form again.\r
-  //\r
-  ChangeHighlight = (Status == EFI_SUCCESS ? TRUE :FALSE);\r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
 \r
 \r
-  Status = ProcessUserInput (&UserInput, ChangeHighlight);\r
+  SecCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
+  ThdCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3 * 2;\r
 \r
 \r
-  FreeDisplayFormData();\r
+  StartColumnOfHelp = LocalScreen.LeftColumn + 2;\r
+  LeftColumnOfHelp  = LocalScreen.LeftColumn + 1;\r
+  RightColumnOfHelp = LocalScreen.RightColumn - 2;\r
+  TopRowOfHelp      = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
+  BottomRowOfHelp   = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;\r
 \r
 \r
-  return Status;\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
+      //\r
+      // On system setting, HotKey will show on every form.\r
+      //\r
+      if (gBrowserSettingScope == SystemLevel ||\r
+          (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+        PrintHotKeyHelpString ();\r
+      }\r
+\r
+      if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\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, gEnterString);\r
+        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, 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 (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);\r
+        } \r
+        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\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) || \r
+          (Statement->Operand == EFI_IFR_DATE_OP) ||\r
+          (Statement->Operand == EFI_IFR_TIME_OP)) {\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
+    //\r
+    // On system setting, HotKey will show on every form.\r
+    //\r
+    if (gBrowserSettingScope == SystemLevel ||\r
+        (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+      PrintHotKeyHelpString ();\r
+    }\r
+    if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\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
+  case EFI_IFR_SUBTITLE_OP:\r
+    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+    if (!Selected) {\r
+      //\r
+      // On system setting, HotKey will show on every form.\r
+      //\r
+      if (gBrowserSettingScope == SystemLevel ||\r
+          (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+        PrintHotKeyHelpString ();\r
+      }\r
+      if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\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 && Statement->Operand != EFI_IFR_SUBTITLE_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
 }\r
 \r
 /**\r
@@ -1715,136 +920,60 @@ FormUpdateNotify (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Update the NV flag info for this form set.\r
+  check whether the formset need to update the NV.\r
 \r
   @param  FormSet                FormSet data structure.\r
 \r
 \r
   @param  FormSet                FormSet data structure.\r
 \r
+  @retval TRUE                   Need to update the NV.\r
+  @retval FALSE                  No need to update the NV.\r
 **/\r
 **/\r
-BOOLEAN\r
-IsNvUpdateRequiredForFormSet (\r
+BOOLEAN \r
+IsNvUpdateRequired (\r
   IN FORM_BROWSER_FORMSET  *FormSet\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
   FORM_BROWSER_FORM       *Form;\r
   IN FORM_BROWSER_FORMSET  *FormSet\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
   FORM_BROWSER_FORM       *Form;\r
-  BOOLEAN                 RetVal;\r
-\r
-  //\r
-  // Not finished question initialization, return FALSE.\r
-  //\r
-  if (!FormSet->QuestionInited) {\r
-    return FALSE;\r
-  }\r
-\r
-  RetVal = FALSE;\r
 \r
   Link = GetFirstNode (&FormSet->FormListHead);\r
   while (!IsNull (&FormSet->FormListHead, Link)) {\r
     Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
 \r
 \r
   Link = GetFirstNode (&FormSet->FormListHead);\r
   while (!IsNull (&FormSet->FormListHead, Link)) {\r
     Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
 \r
-    RetVal = IsNvUpdateRequiredForForm(Form);\r
-    if (RetVal) {\r
-      break;\r
-    }\r
-\r
-    Link = GetNextNode (&FormSet->FormListHead, Link);\r
-  }\r
-\r
-  return RetVal;\r
-}\r
-\r
-/**\r
-  Update the NvUpdateRequired flag for a form.\r
-\r
-  @param  Form                Form data structure.\r
-\r
-**/\r
-BOOLEAN\r
-IsNvUpdateRequiredForForm (\r
-  IN FORM_BROWSER_FORM    *Form\r
-  )\r
-{\r
-  LIST_ENTRY              *Link;\r
-  FORM_BROWSER_STATEMENT  *Statement;\r
-\r
-  Link = GetFirstNode (&Form->StatementListHead);\r
-  while (!IsNull (&Form->StatementListHead, Link)) {\r
-    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-\r
-    if (Statement->ValueChanged) {\r
+    if (Form->NvUpdateRequired ) {\r
       return TRUE;\r
     }\r
 \r
       return TRUE;\r
     }\r
 \r
-    Link = GetNextNode (&Form->StatementListHead, Link);\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
 /**\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
 /**\r
-  Check whether the storage data for current form set is changed.\r
+  check whether the formset need to update the NV.\r
 \r
 \r
-  @param  FormSet           FormSet data structure.\r
+  @param  FormSet                FormSet data structure.\r
+  @param  SetValue               Whether set new value or clear old value.\r
 \r
 \r
-  @retval TRUE              Data is changed.\r
-  @retval FALSE             Data is not changed.\r
 **/\r
 **/\r
-BOOLEAN \r
-IsStorageDataChangedForFormSet (\r
-  IN FORM_BROWSER_FORMSET             *FormSet\r
+VOID\r
+UpdateNvInfoInForm (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN BOOLEAN               SetValue\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
-  FORMSET_STORAGE         *Storage;\r
-  BROWSER_STORAGE         *BrowserStorage;\r
-  CHAR16                  *ConfigRespNew;\r
-  CHAR16                  *ConfigRespOld;\r
-  BOOLEAN                 RetVal;\r
-\r
-  RetVal        = FALSE;\r
-  ConfigRespNew = NULL;\r
-  ConfigRespOld = NULL;\r
-\r
-  //\r
-  // Request current settings from Configuration Driver\r
-  //\r
-  Link = GetFirstNode (&FormSet->StorageListHead);\r
-  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
-    Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
-    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
-\r
-    BrowserStorage = Storage->BrowserStorage;\r
-\r
-    if (BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
-      continue;\r
-    }\r
-\r
-    if (Storage->ElementCount == 0) {\r
-      continue;\r
-    }\r
-\r
-    StorageToConfigResp (BrowserStorage, &ConfigRespNew, Storage->ConfigRequest, TRUE);\r
-    StorageToConfigResp (BrowserStorage, &ConfigRespOld, Storage->ConfigRequest, FALSE);\r
-    ASSERT (ConfigRespNew != NULL && ConfigRespOld != NULL);\r
-\r
-    if (StrCmp (ConfigRespNew, ConfigRespOld) != 0) {\r
-      RetVal = TRUE;\r
-    }\r
-\r
-    FreePool (ConfigRespNew);\r
-    ConfigRespNew = NULL;\r
+  FORM_BROWSER_FORM       *Form;\r
+  \r
+  Link = GetFirstNode (&FormSet->FormListHead);\r
+  while (!IsNull (&FormSet->FormListHead, Link)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
 \r
 \r
-    FreePool (ConfigRespOld);\r
-    ConfigRespOld = NULL;\r
+    Form->NvUpdateRequired = SetValue;\r
 \r
 \r
-    if (RetVal) {\r
-      break;\r
-    }\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
   }\r
   }\r
-\r
-  return RetVal;\r
 }\r
 }\r
-\r
 /**\r
   Find menu which will show next time.\r
 \r
 /**\r
   Find menu which will show next time.\r
 \r
@@ -1852,79 +981,98 @@ IsStorageDataChangedForFormSet (
                          about the Selection, form and formset to be displayed.\r
                          On output, Selection return the screen item that is selected\r
                          by user.\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
-  @param SettingLevel    Input Settting level, if it is FormLevel, just exit current form. \r
-                         else, we need to exit current formset.\r
+  @param Repaint         Whether need to repaint the menu.\r
+  @param NewLine         Whether need to show at new line.\r
   \r
   \r
-  @retval TRUE           Exit current form.\r
-  @retval FALSE          User press ESC and keep in current form.\r
+  @retval TRUE           Need return.\r
+  @retval FALSE          No need to return.\r
 **/\r
 BOOLEAN\r
 FindNextMenu (\r
 **/\r
 BOOLEAN\r
 FindNextMenu (\r
-  IN OUT UI_MENU_SELECTION        *Selection,\r
-  IN       BROWSER_SETTING_SCOPE  SettingLevel\r
+  IN OUT UI_MENU_SELECTION    *Selection,\r
+  IN     BOOLEAN              *Repaint, \r
+  IN     BOOLEAN              *NewLine  \r
   )\r
 {\r
   )\r
 {\r
-  FORM_ENTRY_INFO            *CurrentMenu;\r
-  FORM_ENTRY_INFO            *ParentMenu;\r
-  BROWSER_SETTING_SCOPE      Scope;\r
+  UI_MENU_LIST            *CurrentMenu;\r
+  CHAR16                  YesResponse;\r
+  CHAR16                  NoResponse;\r
+  EFI_INPUT_KEY           Key;\r
+  BROWSER_SETTING_SCOPE   Scope;\r
   \r
   CurrentMenu = Selection->CurrentMenu;\r
   \r
   CurrentMenu = Selection->CurrentMenu;\r
-  ParentMenu  = NULL;\r
-  Scope       = FormSetLevel;\r
 \r
 \r
-  if (CurrentMenu != NULL && (ParentMenu = UiFindParentMenu(CurrentMenu)) != NULL) {\r
+  if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {\r
     //\r
     // we have a parent, so go to the parent menu\r
     //\r
     //\r
     // we have a parent, so go to the parent menu\r
     //\r
-    if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
-      if (SettingLevel == FormSetLevel) {\r
+    if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {\r
+      //\r
+      // The parent menu and current menu are in the same formset\r
+      //\r
+      Selection->Action = UI_ACTION_REFRESH_FORM;\r
+      Scope             = FormLevel;\r
+    } else {\r
+      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+      CopyMem (&Selection->FormSetGuid, &CurrentMenu->Parent->FormSetGuid, sizeof (EFI_GUID));\r
+      Selection->Handle = CurrentMenu->Parent->HiiHandle;\r
+      Scope             = FormSetLevel;\r
+    }\r
+\r
+    //\r
+    // Form Level Check whether the data is changed.\r
+    //\r
+    if ((gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) ||\r
+        (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequired(Selection->FormSet) && Scope == FormSetLevel)) {\r
+      gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+  \r
+      YesResponse = gYesResponse[0];\r
+      NoResponse  = gNoResponse[0];\r
+  \r
+      //\r
+      // If NV flag is up, prompt user\r
+      //\r
+      do {\r
+        CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);\r
+      } while\r
+      (\r
+        (Key.ScanCode != SCAN_ESC) &&\r
+        ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
+        ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
+      );\r
+  \r
+      if (Key.ScanCode == SCAN_ESC) {\r
         //\r
         //\r
-        // Find a menu which has different formset guid with current.\r
+        // User hits the ESC key, Ingore. \r
         //\r
         //\r
-        while (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
-          CurrentMenu = ParentMenu;\r
-          if ((ParentMenu = UiFindParentMenu(CurrentMenu)) == NULL) {\r
-            break;\r
-          }\r
+        if (Repaint != NULL) {\r
+          *Repaint = TRUE;\r
         }\r
         }\r
-\r
-        if (ParentMenu != NULL) {\r
-          Scope = FormSetLevel;\r
+        if (NewLine != NULL) {\r
+          *NewLine = TRUE;\r
         }\r
         }\r
+\r
+        Selection->Action = UI_ACTION_NONE;\r
+        return FALSE;\r
+      }\r
+  \r
+      if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
+        //\r
+        // If the user hits the YesResponse key\r
+        //\r
+        SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
       } else {\r
       } else {\r
-        Scope = FormLevel;\r
+        //\r
+        // If the user hits the NoResponse key\r
+        //\r
+        DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
       }\r
       }\r
-    } else {\r
-      Scope = FormSetLevel;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Form Level Check whether the data is changed.\r
-  //\r
-  if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm (Selection->Form)) ||\r
-      (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet(Selection->FormSet) && Scope == FormSetLevel)) {\r
-    if (!ProcessChangedData(Selection, Scope)) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  if (ParentMenu != NULL) {\r
-    //\r
-    // ParentMenu is found. Then, go to it.\r
-    //\r
-    if (Scope == FormLevel) {\r
-      Selection->Action = UI_ACTION_REFRESH_FORM;\r
-    } else {\r
-      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
-      CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
-      Selection->Handle = ParentMenu->HiiHandle;\r
     }\r
 \r
     Selection->Statement = NULL;\r
 \r
     }\r
 \r
     Selection->Statement = NULL;\r
 \r
-    Selection->FormId = ParentMenu->FormId;\r
-    Selection->QuestionId = ParentMenu->QuestionId;\r
+    Selection->FormId = CurrentMenu->Parent->FormId;\r
+    Selection->QuestionId = CurrentMenu->Parent->QuestionId;\r
 \r
     //\r
     // Clear highlight record for this menu\r
 \r
     //\r
     // Clear highlight record for this menu\r
@@ -1933,11 +1081,70 @@ FindNextMenu (
     return FALSE;\r
   }\r
 \r
     return FALSE;\r
   }\r
 \r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
+    //\r
+    // We never exit FrontPage, so skip the ESC\r
+    //\r
+    Selection->Action = UI_ACTION_NONE;\r
+    return FALSE;\r
+  }\r
+\r
   //\r
   //\r
-  // Current in root page, exit the SendForm\r
+  // We are going to leave current FormSet, so check uncommited data in this FormSet\r
   //\r
   //\r
-  Selection->Action = UI_ACTION_EXIT;\r
+  if (gBrowserSettingScope != SystemLevel && IsNvUpdateRequired(Selection->FormSet)) {\r
+    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+\r
+    YesResponse = gYesResponse[0];\r
+    NoResponse  = gNoResponse[0];\r
+\r
+    //\r
+    // If NV flag is up, prompt user\r
+    //\r
+    do {\r
+      CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);\r
+    } while\r
+    (\r
+      (Key.ScanCode != SCAN_ESC) &&\r
+      ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
+      ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
+    );\r
+\r
+    if (Key.ScanCode == SCAN_ESC) {\r
+      //\r
+      // User hits the ESC key\r
+      //\r
+      if (Repaint != NULL) {\r
+        *Repaint = TRUE;\r
+      }\r
+\r
+      if (NewLine != NULL) {\r
+        *NewLine = TRUE;\r
+      }\r
+\r
+      Selection->Action = UI_ACTION_NONE;\r
+      return FALSE;\r
+    }\r
 \r
 \r
+    if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
+      //\r
+      // If the user hits the YesResponse key\r
+      //\r
+      SubmitForm (Selection->FormSet, Selection->Form, FormSetLevel);\r
+    } else {\r
+      //\r
+      // If the user hits the NoResponse key\r
+      //\r
+      DiscardForm (Selection->FormSet, Selection->Form, FormSetLevel);\r
+    }\r
+  }\r
+\r
+  Selection->Statement = NULL;\r
+  if (CurrentMenu != NULL) {\r
+    CurrentMenu->QuestionId = 0;\r
+  }\r
+\r
+  Selection->Action = UI_ACTION_EXIT;\r
   return TRUE;\r
 }\r
 \r
   return TRUE;\r
 }\r
 \r
@@ -2039,17 +1246,17 @@ ProcessCallBackFunction (
         case EFI_BROWSER_ACTION_REQUEST_RESET:\r
           DiscardFormIsRequired = TRUE;\r
           gResetRequired = TRUE;\r
         case EFI_BROWSER_ACTION_REQUEST_RESET:\r
           DiscardFormIsRequired = TRUE;\r
           gResetRequired = TRUE;\r
-          NeedExit              = TRUE;\r
+          Selection->Action = UI_ACTION_EXIT;\r
           break;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
           SubmitFormIsRequired = TRUE;\r
           break;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
           SubmitFormIsRequired = TRUE;\r
-          NeedExit              = TRUE;\r
+          Selection->Action = UI_ACTION_EXIT;\r
           break;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
           DiscardFormIsRequired = TRUE;\r
           break;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
           DiscardFormIsRequired = TRUE;\r
-          NeedExit              = TRUE;\r
+          Selection->Action = UI_ACTION_EXIT;\r
           break;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:\r
           break;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:\r
@@ -2060,7 +1267,7 @@ ProcessCallBackFunction (
 \r
         case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:\r
           DiscardFormIsRequired = TRUE;\r
 \r
         case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:\r
           DiscardFormIsRequired = TRUE;\r
-          SettingLevel          = FormLevel;\r
+          SettingLevel          = FormLevel;      \r
           NeedExit              = TRUE;\r
           break;\r
 \r
           NeedExit              = TRUE;\r
           break;\r
 \r
@@ -2113,7 +1320,7 @@ ProcessCallBackFunction (
   }\r
 \r
   if (NeedExit) {\r
   }\r
 \r
   if (NeedExit) {\r
-    FindNextMenu (Selection, SettingLevel);\r
+    FindNextMenu (Selection, NULL, NULL);\r
   }\r
 \r
   return Status;\r
   }\r
 \r
   return Status;\r
@@ -2193,7 +1400,9 @@ SetupBrowser (
   EFI_HANDLE                      NotifyHandle;\r
   FORM_BROWSER_STATEMENT          *Statement;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
   EFI_HANDLE                      NotifyHandle;\r
   FORM_BROWSER_STATEMENT          *Statement;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_INPUT_KEY                   Key;\r
 \r
 \r
+  gMenuRefreshHead = NULL;\r
   ConfigAccess = Selection->FormSet->ConfigAccess;\r
 \r
   //\r
   ConfigAccess = Selection->FormSet->ConfigAccess;\r
 \r
   //\r
@@ -2214,17 +1423,21 @@ SetupBrowser (
   //\r
   // Initialize current settings of Questions in this FormSet\r
   //\r
   //\r
   // Initialize current settings of Questions in this FormSet\r
   //\r
-  InitializeCurrentSetting (Selection->FormSet);\r
-\r
-  //\r
-  // Initilize Action field.\r
-  //\r
-  Selection->Action = UI_ACTION_REFRESH_FORM;\r
+  Status = InitializeCurrentSetting (Selection->FormSet);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
   //\r
 \r
   //\r
-  // Clean the mCurFakeQestId value is formset refreshed.\r
+  // Update gOldFormSet on maintain back up FormSet list.\r
+  // And, make gOldFormSet point to current FormSet. \r
   //\r
   //\r
-  mCurFakeQestId = 0;\r
+  if (gOldFormSet != NULL) {\r
+    RemoveEntryList (&gOldFormSet->Link);\r
+    DestroyFormSet (gOldFormSet);\r
+  }\r
+  gOldFormSet = Selection->FormSet;\r
+  InsertTailList (&gBrowserFormSetList, &gOldFormSet->Link);\r
 \r
   do {\r
     //\r
 \r
   do {\r
     //\r
@@ -2267,7 +1480,10 @@ SetupBrowser (
         //\r
         // Form is suppressed. \r
         //\r
         //\r
         // Form is suppressed. \r
         //\r
-        gBrowserStatus = BROWSER_FORM_SUPPRESS;\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
         Status = EFI_NOT_FOUND;\r
         goto Done;\r
       }\r
@@ -2282,6 +1498,7 @@ SetupBrowser (
         ((Selection->Handle != mCurrentHiiHandle) ||\r
         (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
         (Selection->FormId != mCurrentFormId))) {\r
         ((Selection->Handle != mCurrentHiiHandle) ||\r
         (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
         (Selection->FormId != mCurrentFormId))) {\r
+\r
       //\r
       // Keep current form information\r
       //\r
       //\r
       // Keep current form information\r
       //\r
@@ -2294,6 +1511,12 @@ SetupBrowser (
         goto Done;\r
       }\r
 \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 open form, force to reparse the IFR binary\r
       //\r
       //\r
       // IFR is updated during callback of open form, force to reparse the IFR binary\r
       //\r
@@ -2312,6 +1535,12 @@ SetupBrowser (
       goto Done;\r
     }\r
 \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
     //\r
     // IFR is updated during callback of read value, force to reparse the IFR binary\r
     //\r
@@ -2321,10 +1550,15 @@ SetupBrowser (
       break;\r
     }\r
 \r
       break;\r
     }\r
 \r
+    //\r
+    // Displays the Header and Footer borders\r
+    //\r
+    DisplayPageFrame (Selection);\r
+\r
     //\r
     // Display form\r
     //\r
     //\r
     // Display form\r
     //\r
-    Status = DisplayForm ();\r
+    Status = DisplayForm (Selection);\r
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
@@ -2334,16 +1568,20 @@ SetupBrowser (
     //\r
     Statement = Selection->Statement;\r
     if (Statement != 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
       if ((ConfigAccess != NULL) && \r
           ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
           (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
       if ((ConfigAccess != NULL) && \r
           ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
           (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
-        Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
-        if (Statement->Operand == EFI_IFR_REF_OP) {\r
+        Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);         \r
+        if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {\r
           //\r
           // Process dynamic update ref opcode.\r
           //\r
           if (!EFI_ERROR (Status)) {\r
           //\r
           // Process dynamic update ref opcode.\r
           //\r
           if (!EFI_ERROR (Status)) {\r
-            Status = ProcessGotoOpCode(Statement, Selection);\r
+            Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);\r
           }\r
           \r
           //\r
           }\r
           \r
           //\r
@@ -2364,27 +1602,6 @@ SetupBrowser (
       }\r
     }\r
 \r
       }\r
     }\r
 \r
-    //\r
-    // Check whether Exit flag is TRUE.\r
-    //\r
-    if (gExitRequired) {\r
-      switch (gBrowserSettingScope) {\r
-      case SystemLevel:\r
-        Selection->Action = UI_ACTION_EXIT;\r
-        break;\r
-\r
-      case FormSetLevel:\r
-      case FormLevel:\r
-        FindNextMenu (Selection, gBrowserSettingScope);\r
-        break;\r
-\r
-      default:\r
-        break;\r
-      }\r
-\r
-      gExitRequired = FALSE;\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
     // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
     // for each question with callback flag.\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Print.c b/MdeModulePkg/Universal/SetupBrowserDxe/Print.c
new file mode 100644 (file)
index 0000000..eeadf24
--- /dev/null
@@ -0,0 +1,272 @@
+/** @file\r
+Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very\r
+simple implemenation of SPrint() and Print() to support debug.\r
+\r
+You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a\r
+time. This makes the implementation very simple.\r
+\r
+VSPrint, Print, SPrint format specification has the follwoing form\r
+\r
+%type\r
+\r
+type:\r
+  'S','s' - argument is an Unicode string\r
+  'c' - argument is an ascii character\r
+  '%' - Print a %\r
+\r
+\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Setup.h"\r
+\r
+/**\r
+  The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
+  protocol instance.\r
+\r
+  @param Column          The position of the output string.\r
+  @param Row             The position of the output string.\r
+  @param Out             The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.\r
+  @param Fmt             The format string.\r
+  @param Args            The additional argument for the variables in the format string.\r
+\r
+  @return Number of Unicode character printed.\r
+\r
+**/\r
+UINTN\r
+PrintInternal (\r
+  IN UINTN                            Column,\r
+  IN UINTN                            Row,\r
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Out,\r
+  IN CHAR16                           *Fmt,\r
+  IN VA_LIST                          Args\r
+  )\r
+{\r
+  CHAR16  *Buffer;\r
+  CHAR16  *BackupBuffer;\r
+  UINTN   Index;\r
+  UINTN   PreviousIndex;\r
+  UINTN   Count;\r
+\r
+  //\r
+  // For now, allocate an arbitrarily long buffer\r
+  //\r
+  Buffer        = AllocateZeroPool (0x10000);\r
+  BackupBuffer  = AllocateZeroPool (0x10000);\r
+  ASSERT (Buffer);\r
+  ASSERT (BackupBuffer);\r
+\r
+  if (Column != (UINTN) -1) {\r
+    Out->SetCursorPosition (Out, Column, Row);\r
+  }\r
+\r
+  UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);\r
+\r
+  Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
+\r
+  Out->SetAttribute (Out, Out->Mode->Attribute);\r
+\r
+  Index         = 0;\r
+  PreviousIndex = 0;\r
+  Count         = 0;\r
+\r
+  do {\r
+    for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {\r
+      BackupBuffer[Index] = Buffer[Index];\r
+    }\r
+\r
+    if (Buffer[Index] == 0) {\r
+      break;\r
+    }\r
+    //\r
+    // Null-terminate the temporary string\r
+    //\r
+    BackupBuffer[Index] = 0;\r
+\r
+    //\r
+    // Print this out, we are about to switch widths\r
+    //\r
+    Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
+    Count += StrLen (&BackupBuffer[PreviousIndex]);\r
+\r
+    //\r
+    // Preserve the current index + 1, since this is where we will start printing from next\r
+    //\r
+    PreviousIndex = Index + 1;\r
+\r
+    //\r
+    // We are at a narrow or wide character directive.  Set attributes and strip it and print it\r
+    //\r
+    if (Buffer[Index] == NARROW_CHAR) {\r
+      //\r
+      // Preserve bits 0 - 6 and zero out the rest\r
+      //\r
+      Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
+      Out->SetAttribute (Out, Out->Mode->Attribute);\r
+    } else {\r
+      //\r
+      // Must be wide, set bit 7 ON\r
+      //\r
+      Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;\r
+      Out->SetAttribute (Out, Out->Mode->Attribute);\r
+    }\r
+\r
+    Index++;\r
+\r
+  } while (Buffer[Index] != 0);\r
+\r
+  //\r
+  // We hit the end of the string - print it\r
+  //\r
+  Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
+  Count += StrLen (&BackupBuffer[PreviousIndex]);\r
+\r
+  FreePool (Buffer);\r
+  FreePool (BackupBuffer);\r
+  return Count;\r
+}\r
+\r
+\r
+/**\r
+  Prints a formatted unicode string to the default console.\r
+\r
+  @param  Fmt        Format string\r
+  @param  ...        Variable argument list for format string.\r
+\r
+  @return Length of string printed to the console.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+ConsolePrint (\r
+  IN CHAR16   *Fmt,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Args;\r
+  UINTN   LengthOfPrinted;\r
+\r
+  VA_START (Args, Fmt);\r
+  LengthOfPrinted = PrintInternal ((UINTN) -1, (UINTN) -1, gST->ConOut, Fmt, Args);\r
+  VA_END (Args);\r
+  return LengthOfPrinted;\r
+}\r
+\r
+\r
+/**\r
+  Prints a unicode string to the default console,\r
+  using L"%s" format.\r
+\r
+  @param  String     String pointer.\r
+\r
+  @return Length of string printed to the console\r
+\r
+**/\r
+UINTN\r
+PrintString (\r
+  IN CHAR16       *String\r
+  )\r
+{\r
+  return ConsolePrint (L"%s", String);\r
+}\r
+\r
+\r
+/**\r
+  Prints a chracter to the default console,\r
+  using L"%c" format.\r
+\r
+  @param  Character  Character to print.\r
+\r
+  @return Length of string printed to the console.\r
+\r
+**/\r
+UINTN\r
+PrintChar (\r
+  CHAR16       Character\r
+  )\r
+{\r
+  return ConsolePrint (L"%c", Character);\r
+}\r
+\r
+\r
+/**\r
+  Prints a formatted unicode string to the default console, at\r
+  the supplied cursor position.\r
+\r
+  @param  Column     The cursor position to print the string at.\r
+  @param  Row        The cursor position to print the string at.\r
+  @param  Fmt        Format string.\r
+  @param  ...        Variable argument list for format string.\r
+\r
+  @return Length of string printed to the console\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PrintAt (\r
+  IN UINTN     Column,\r
+  IN UINTN     Row,\r
+  IN CHAR16    *Fmt,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Args;\r
+  UINTN   LengthOfPrinted;\r
+\r
+  VA_START (Args, Fmt);\r
+  LengthOfPrinted = PrintInternal (Column, Row, gST->ConOut, Fmt, Args);\r
+  VA_END (Args);\r
+  return LengthOfPrinted;\r
+}\r
+\r
+\r
+/**\r
+  Prints a unicode string to the default console, at\r
+  the supplied cursor position, using L"%s" format.\r
+\r
+  @param  Column     The cursor position to print the string at.\r
+  @param  Row        The cursor position to print the string at\r
+  @param  String     String pointer.\r
+\r
+  @return Length of string printed to the console\r
+\r
+**/\r
+UINTN\r
+PrintStringAt (\r
+  IN UINTN     Column,\r
+  IN UINTN     Row,\r
+  IN CHAR16    *String\r
+  )\r
+{\r
+  return PrintAt (Column, Row, L"%s", String);\r
+}\r
+\r
+\r
+/**\r
+  Prints a chracter to the default console, at\r
+  the supplied cursor position, using L"%c" format.\r
+\r
+  @param  Column     The cursor position to print the string at.\r
+  @param  Row        The cursor position to print the string at.\r
+  @param  Character  Character to print.\r
+\r
+  @return Length of string printed to the console.\r
+\r
+**/\r
+UINTN\r
+PrintCharAt (\r
+  IN UINTN     Column,\r
+  IN UINTN     Row,\r
+  CHAR16       Character\r
+  )\r
+{\r
+  return PrintAt (Column, Row, L"%c", Character);\r
+}\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
new file mode 100644 (file)
index 0000000..fecb98e
--- /dev/null
@@ -0,0 +1,1075 @@
+/** @file\r
+Implementation for handling the User Interface option processing.\r
+\r
+\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Setup.h"\r
+\r
+\r
+/**\r
+  Process Question Config.\r
+\r
+  @param  Selection              The UI menu selection.\r
+  @param  Question               The Question to be peocessed.\r
+\r
+  @retval EFI_SUCCESS            Question Config process success.\r
+  @retval Other                  Question Config process fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessQuestionConfig (\r
+  IN  UI_MENU_SELECTION       *Selection,\r
+  IN  FORM_BROWSER_STATEMENT  *Question\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  CHAR16                          *ConfigResp;\r
+  CHAR16                          *Progress;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+\r
+  if (Question->QuestionConfig == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Get <ConfigResp>\r
+  //\r
+  ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);\r
+  if (ConfigResp == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Send config to Configuration Driver\r
+  //\r
+  ConfigAccess = Selection->FormSet->ConfigAccess;\r
+  if (ConfigAccess == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Status = ConfigAccess->RouteConfig (\r
+                           ConfigAccess,\r
+                           ConfigResp,\r
+                           &Progress\r
+                           );\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Search an Option of a Question by its value.\r
+\r
+  @param  Question               The Question\r
+  @param  OptionValue            Value for Option to be searched.\r
+\r
+  @retval Pointer                Pointer to the found Option.\r
+  @retval NULL                   Option not found.\r
+\r
+**/\r
+QUESTION_OPTION *\r
+ValueToOption (\r
+  IN FORM_BROWSER_STATEMENT   *Question,\r
+  IN EFI_HII_VALUE            *OptionValue\r
+  )\r
+{\r
+  LIST_ENTRY       *Link;\r
+  QUESTION_OPTION  *Option;\r
+  INTN             Result;\r
+\r
+  Link = GetFirstNode (&Question->OptionListHead);\r
+  while (!IsNull (&Question->OptionListHead, Link)) {\r
+    Option = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+    if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
+      //\r
+      // Check the suppressif condition, only a valid option can be return.\r
+      //\r
+      if ((Option->SuppressExpression == NULL) ||\r
+          ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {\r
+        return Option;\r
+      }\r
+    }\r
+\r
+    Link = GetNextNode (&Question->OptionListHead, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Return data element in an Array by its Index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Index                  Zero based index for data in this array.\r
+\r
+  @retval Value                  The data to be returned\r
+\r
+**/\r
+UINT64\r
+GetArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINTN                    Index\r
+  )\r
+{\r
+  UINT64 Data;\r
+\r
+  ASSERT (Array != NULL);\r
+\r
+  Data = 0;\r
+  switch (Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    Data = (UINT64) *(((UINT8 *) Array) + Index);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    Data = (UINT64) *(((UINT16 *) Array) + Index);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    Data = (UINT64) *(((UINT32 *) Array) + Index);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+    Data = (UINT64) *(((UINT64 *) Array) + Index);\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return Data;\r
+}\r
+\r
+\r
+/**\r
+  Set value of a data element in an Array by its Index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Index                  Zero based index for data in this array.\r
+  @param  Value                  The value to be set.\r
+\r
+**/\r
+VOID\r
+SetArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINTN                    Index,\r
+  IN UINT64                   Value\r
+  )\r
+{\r
+\r
+  ASSERT (Array != NULL);\r
+\r
+  switch (Type) {\r
+  case EFI_IFR_TYPE_NUM_SIZE_8:\r
+    *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_16:\r
+    *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_32:\r
+    *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_NUM_SIZE_64:\r
+    *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+}\r
+\r
+/**\r
+  Check whether this value already in the array, if yes, return the index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Value                  The value to be find.\r
+  @param  Index                  The index in the array which has same value with Value.\r
+  \r
+  @retval   TRUE Found the value in the array.\r
+  @retval   FALSE Not found the value.\r
+\r
+**/\r
+BOOLEAN \r
+FindArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINT64                   Value,\r
+  OUT UINTN                   *Index OPTIONAL\r
+  )\r
+{\r
+  UINTN  Count;\r
+  UINT64 TmpValue;\r
+  \r
+  ASSERT (Array != NULL);\r
+\r
+  Count    = 0;\r
+  TmpValue = 0;\r
+\r
+  while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {\r
+    if (Value == TmpValue) {\r
+      if (Index != NULL) {\r
+        *Index = Count;\r
+      }\r
+      return TRUE;\r
+    }\r
+\r
+    Count ++;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Print Question Value according to it's storage width and display attributes.\r
+\r
+  @param  Question               The Question to be printed.\r
+  @param  FormattedNumber        Buffer for output string.\r
+  @param  BufferSize             The FormattedNumber buffer size in bytes.\r
+\r
+  @retval EFI_SUCCESS            Print success.\r
+  @retval EFI_BUFFER_TOO_SMALL   Buffer size is not enough for formatted number.\r
+\r
+**/\r
+EFI_STATUS\r
+PrintFormattedNumber (\r
+  IN FORM_BROWSER_STATEMENT   *Question,\r
+  IN OUT CHAR16               *FormattedNumber,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  INT64          Value;\r
+  CHAR16         *Format;\r
+  EFI_HII_VALUE  *QuestionValue;\r
+\r
+  if (BufferSize < (21 * sizeof (CHAR16))) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  QuestionValue = &Question->HiiValue;\r
+\r
+  Value = (INT64) QuestionValue->Value.u64;\r
+  switch (Question->Flags & EFI_IFR_DISPLAY) {\r
+  case EFI_IFR_DISPLAY_INT_DEC:\r
+    switch (QuestionValue->Type) {\r
+    case EFI_IFR_NUMERIC_SIZE_1:\r
+      Value = (INT64) ((INT8) QuestionValue->Value.u8);\r
+      break;\r
+\r
+    case EFI_IFR_NUMERIC_SIZE_2:\r
+      Value = (INT64) ((INT16) QuestionValue->Value.u16);\r
+      break;\r
+\r
+    case EFI_IFR_NUMERIC_SIZE_4:\r
+      Value = (INT64) ((INT32) QuestionValue->Value.u32);\r
+      break;\r
+\r
+    case EFI_IFR_NUMERIC_SIZE_8:\r
+    default:\r
+      break;\r
+    }\r
+\r
+    if (Value < 0) {\r
+      Value = -Value;\r
+      Format = L"-%ld";\r
+    } else {\r
+      Format = L"%ld";\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_DISPLAY_UINT_DEC:\r
+    Format = L"%ld";\r
+    break;\r
+\r
+  case EFI_IFR_DISPLAY_UINT_HEX:\r
+    Format = L"%lx";\r
+    break;\r
+\r
+  default:\r
+    return EFI_UNSUPPORTED;\r
+    break;\r
+  }\r
+\r
+  UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Password may be stored as encrypted by Configuration Driver. When change a\r
+  password, user will be challenged with old password. To validate user input old\r
+  password, we will send the clear text to Configuration Driver via Callback().\r
+  Configuration driver is responsible to check the passed in password and return\r
+  the validation result. If validation pass, state machine in password Callback()\r
+  will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.\r
+  After user type in new password twice, Callback() will be invoked to send the\r
+  new password to Configuration Driver.\r
+\r
+  @param  Selection              Pointer to UI_MENU_SELECTION.\r
+  @param  MenuOption             The MenuOption for this password Question.\r
+  @param  String                 The clear text of password.\r
+\r
+  @retval EFI_NOT_AVAILABLE_YET  Callback() request to terminate password input.\r
+  @return In state of BROWSER_STATE_VALIDATE_PASSWORD:\r
+  @retval EFI_SUCCESS            Password correct, Browser will prompt for new\r
+                                 password.\r
+  @retval EFI_NOT_READY          Password incorrect, Browser will show error\r
+                                 message.\r
+  @retval Other                  Browser will do nothing.\r
+  @return In state of BROWSER_STATE_SET_PASSWORD:\r
+  @retval EFI_SUCCESS            Set password success.\r
+  @retval Other                  Set password failed.\r
+\r
+**/\r
+EFI_STATUS\r
+PasswordCallback (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption,\r
+  IN  CHAR16                      *String\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
+  EFI_IFR_TYPE_VALUE              IfrTypeValue;\r
+\r
+  ConfigAccess = Selection->FormSet->ConfigAccess;\r
+  if (ConfigAccess == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Prepare password string in HII database\r
+  //\r
+  if (String != NULL) {\r
+    IfrTypeValue.string = NewString (String, Selection->FormSet->HiiHandle);\r
+  } else {\r
+    IfrTypeValue.string = 0;\r
+  }\r
+\r
+  //\r
+  // Send password to Configuration Driver for validation\r
+  //\r
+  Status = ConfigAccess->Callback (\r
+                           ConfigAccess,\r
+                           EFI_BROWSER_ACTION_CHANGING,\r
+                           MenuOption->ThisTag->QuestionId,\r
+                           MenuOption->ThisTag->HiiValue.Type,\r
+                           &IfrTypeValue,\r
+                           &ActionRequest\r
+                           );\r
+\r
+  //\r
+  // Remove password string from HII database\r
+  //\r
+  if (String != NULL) {\r
+    DeleteString (IfrTypeValue.string, Selection->FormSet->HiiHandle);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Display error message for invalid password.\r
+\r
+**/\r
+VOID\r
+PasswordInvalid (\r
+  VOID\r
+  )\r
+{\r
+  EFI_INPUT_KEY  Key;\r
+\r
+  //\r
+  // Invalid password, prompt error message\r
+  //\r
+  do {\r
+    CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString);\r
+  } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+}\r
+\r
+\r
+/**\r
+  Process a Question's Option (whether selected or un-selected).\r
+\r
+  @param  Selection              Pointer to UI_MENU_SELECTION.\r
+  @param  MenuOption             The MenuOption for this Question.\r
+  @param  Selected               TRUE: if Question is selected.\r
+  @param  OptionString           Pointer of the Option String to be displayed.\r
+\r
+  @retval EFI_SUCCESS            Question Option process success.\r
+  @retval Other                  Question Option process fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessOptions (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption,\r
+  IN  BOOLEAN                     Selected,\r
+  OUT CHAR16                      **OptionString\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  CHAR16                          *StringPtr;\r
+  CHAR16                          *TempString;\r
+  UINTN                           Index;\r
+  FORM_BROWSER_STATEMENT          *Question;\r
+  CHAR16                          FormattedNumber[21];\r
+  UINT16                          Number;\r
+  CHAR16                          Character[2];\r
+  EFI_INPUT_KEY                   Key;\r
+  UINTN                           BufferSize;\r
+  QUESTION_OPTION                 *OneOfOption;\r
+  LIST_ENTRY                      *Link;\r
+  EFI_HII_VALUE                   HiiValue;\r
+  EFI_HII_VALUE                   *QuestionValue;\r
+  UINT16                          Maximum;\r
+  QUESTION_OPTION                 *Option;\r
+  UINTN                           Index2;\r
+  UINT8                           *ValueArray;\r
+  UINT8                           ValueType;\r
+  EFI_STRING_ID                   StringId;\r
+\r
+  Status        = EFI_SUCCESS;\r
+\r
+  StringPtr     = NULL;\r
+  Character[1]  = L'\0';\r
+  *OptionString = NULL;\r
+  StringId      = 0;\r
+\r
+  ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));\r
+  BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow;\r
+\r
+  Question = MenuOption->ThisTag;\r
+  QuestionValue = &Question->HiiValue;\r
+  Maximum = (UINT16) Question->Maximum;\r
+\r
+  ValueArray = Question->BufferValue;\r
+  ValueType = Question->ValueType;\r
+\r
+  switch (Question->Operand) {\r
+  case EFI_IFR_ORDERED_LIST_OP:\r
+    //\r
+    // Check whether there are Options of this OrderedList\r
+    //\r
+    if (IsListEmpty (&Question->OptionListHead)) {\r
+      break;\r
+    }\r
+    //\r
+    // Initialize Option value array\r
+    //\r
+    if (GetArrayData (ValueArray, ValueType, 0) == 0) {\r
+      GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0);\r
+    }\r
+\r
+    if (Selected) {\r
+      //\r
+      // Go ask for input\r
+      //\r
+      Status = GetSelectionInputPopUp (Selection, MenuOption);\r
+    } else {\r
+      //\r
+      // We now know how many strings we will have, so we can allocate the\r
+      // space required for the array or strings.\r
+      //\r
+      *OptionString = AllocateZeroPool (Question->MaxContainers * BufferSize);\r
+      ASSERT (*OptionString);\r
+\r
+      HiiValue.Type = ValueType;\r
+      HiiValue.Value.u64 = 0;\r
+      for (Index = 0; Index < Question->MaxContainers; Index++) {\r
+        HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);\r
+        if (HiiValue.Value.u64 == 0) {\r
+          //\r
+          // Values for the options in ordered lists should never be a 0\r
+          //\r
+          break;\r
+        }\r
+\r
+        OneOfOption = ValueToOption (Question, &HiiValue);\r
+        if (OneOfOption == NULL) {\r
+          //\r
+          // Show error message\r
+          //\r
+          do {\r
+            CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);\r
+          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+          //\r
+          // The initial value of the orderedlist is invalid, force to be valid value\r
+          //\r
+          Link = GetFirstNode (&Question->OptionListHead);\r
+          Index2 = 0;\r
+          while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {\r
+            Option = QUESTION_OPTION_FROM_LINK (Link);\r
+            Link = GetNextNode (&Question->OptionListHead, Link);\r
+            if ((Option->SuppressExpression != NULL) &&\r
+                ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
+              continue;\r
+            }\r
+            SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);\r
+            Index2++;\r
+          }\r
+          SetArrayData (ValueArray, ValueType, Index2, 0);\r
+\r
+          Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+\r
+          FreePool (*OptionString);\r
+          *OptionString = NULL;\r
+          return EFI_NOT_FOUND;\r
+        }\r
+\r
+        Character[0] = LEFT_ONEOF_DELIMITER;\r
+        NewStrCat (OptionString[0], Character);\r
+        StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
+        ASSERT (StringPtr != NULL);\r
+        NewStrCat (OptionString[0], StringPtr);\r
+        Character[0] = RIGHT_ONEOF_DELIMITER;\r
+        NewStrCat (OptionString[0], Character);\r
+        Character[0] = CHAR_CARRIAGE_RETURN;\r
+        NewStrCat (OptionString[0], Character);\r
+        FreePool (StringPtr);\r
+      }\r
+\r
+      //\r
+      // Search the other options, try to find the one not in the container.\r
+      //\r
+      Link = GetFirstNode (&Question->OptionListHead);\r
+      while (!IsNull (&Question->OptionListHead, Link)) {\r
+        OneOfOption = QUESTION_OPTION_FROM_LINK (Link);\r
+        Link = GetNextNode (&Question->OptionListHead, Link);\r
+        if ((OneOfOption->SuppressExpression != NULL) &&\r
+            ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {\r
+          continue;\r
+        }\r
+\r
+        if (FindArrayData (ValueArray, ValueType, OneOfOption->Value.Value.u64, NULL)) {\r
+          continue;\r
+        }\r
+\r
+        SetArrayData (ValueArray, ValueType, Index++, OneOfOption->Value.Value.u64);\r
+\r
+        Character[0] = LEFT_ONEOF_DELIMITER;\r
+        NewStrCat (OptionString[0], Character);\r
+        StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
+        ASSERT (StringPtr != NULL);\r
+        NewStrCat (OptionString[0], StringPtr);\r
+        Character[0] = RIGHT_ONEOF_DELIMITER;\r
+        NewStrCat (OptionString[0], Character);\r
+        Character[0] = CHAR_CARRIAGE_RETURN;\r
+        NewStrCat (OptionString[0], Character);\r
+        FreePool (StringPtr);\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_ONE_OF_OP:\r
+    //\r
+    // Check whether there are Options of this OneOf\r
+    //\r
+    if (IsListEmpty (&Question->OptionListHead)) {\r
+      break;\r
+    }\r
+    if (Selected) {\r
+      //\r
+      // Go ask for input\r
+      //\r
+      Status = GetSelectionInputPopUp (Selection, MenuOption);\r
+    } else {\r
+      *OptionString = AllocateZeroPool (BufferSize);\r
+      ASSERT (*OptionString);\r
+\r
+      OneOfOption = ValueToOption (Question, QuestionValue);\r
+      if (OneOfOption == NULL) {\r
+        //\r
+        // Show error message\r
+        //\r
+        do {\r
+          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);\r
+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+        //\r
+        // Force the Question value to be valid\r
+        //\r
+        Link = GetFirstNode (&Question->OptionListHead);\r
+        while (!IsNull (&Question->OptionListHead, Link)) {\r
+          Option = QUESTION_OPTION_FROM_LINK (Link);\r
+\r
+          if ((Option->SuppressExpression == NULL) ||\r
+              (EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {\r
+            CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
+            SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
+            UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+            break;\r
+          }\r
+\r
+          Link = GetNextNode (&Question->OptionListHead, Link);\r
+        }\r
+\r
+        FreePool (*OptionString);\r
+        *OptionString = NULL;\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Character[0] = LEFT_ONEOF_DELIMITER;\r
+      NewStrCat (OptionString[0], Character);\r
+      StringPtr = GetToken (OneOfOption->Text, Selection->Handle);\r
+      ASSERT (StringPtr != NULL);\r
+      NewStrCat (OptionString[0], StringPtr);\r
+      Character[0] = RIGHT_ONEOF_DELIMITER;\r
+      NewStrCat (OptionString[0], Character);\r
+\r
+      FreePool (StringPtr);\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_CHECKBOX_OP:\r
+    *OptionString = AllocateZeroPool (BufferSize);\r
+    ASSERT (*OptionString);\r
+\r
+    *OptionString[0] = LEFT_CHECKBOX_DELIMITER;\r
+\r
+    if (Selected) {\r
+      //\r
+      // Since this is a BOOLEAN operation, flip it upon selection\r
+      //\r
+      QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);\r
+\r
+      //\r
+      // Perform inconsistent check\r
+      //\r
+      Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Inconsistent check fail, restore Question Value\r
+        //\r
+        QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);\r
+        FreePool (*OptionString);\r
+        *OptionString = NULL;\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Save Question value\r
+      //\r
+      Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
+      UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+    }\r
+\r
+    if (QuestionValue->Value.b) {\r
+      *(OptionString[0] + 1) = CHECK_ON;\r
+    } else {\r
+      *(OptionString[0] + 1) = CHECK_OFF;\r
+    }\r
+    *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_OP:\r
+    if (Selected) {\r
+      //\r
+      // Go ask for input\r
+      //\r
+      Status = GetNumericInput (Selection, MenuOption);\r
+    } else {\r
+      *OptionString = AllocateZeroPool (BufferSize);\r
+      ASSERT (*OptionString);\r
+\r
+      *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
+\r
+      //\r
+      // Formatted print\r
+      //\r
+      PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));\r
+      Number = (UINT16) GetStringWidth (FormattedNumber);\r
+      CopyMem (OptionString[0] + 1, FormattedNumber, Number);\r
+\r
+      *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_DATE_OP:\r
+    if (Selected) {\r
+      //\r
+      // This is similar to numerics\r
+      //\r
+      Status = GetNumericInput (Selection, MenuOption);\r
+    } else {\r
+      *OptionString = AllocateZeroPool (BufferSize);\r
+      ASSERT (*OptionString);\r
+\r
+      switch (MenuOption->Sequence) {\r
+      case 0:\r
+        *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
+        UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);\r
+        *(OptionString[0] + 3) = DATE_SEPARATOR;\r
+        break;\r
+\r
+      case 1:\r
+        SetUnicodeMem (OptionString[0], 4, L' ');\r
+        UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);\r
+        *(OptionString[0] + 6) = DATE_SEPARATOR;\r
+        break;\r
+\r
+      case 2:\r
+        SetUnicodeMem (OptionString[0], 7, L' ');\r
+        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);\r
+        *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;\r
+        break;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_TIME_OP:\r
+    if (Selected) {\r
+      //\r
+      // This is similar to numerics\r
+      //\r
+      Status = GetNumericInput (Selection, MenuOption);\r
+    } else {\r
+      *OptionString = AllocateZeroPool (BufferSize);\r
+      ASSERT (*OptionString);\r
+\r
+      switch (MenuOption->Sequence) {\r
+      case 0:\r
+        *OptionString[0] = LEFT_NUMERIC_DELIMITER;\r
+        UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);\r
+        *(OptionString[0] + 3) = TIME_SEPARATOR;\r
+        break;\r
+\r
+      case 1:\r
+        SetUnicodeMem (OptionString[0], 4, L' ');\r
+        UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);\r
+        *(OptionString[0] + 6) = TIME_SEPARATOR;\r
+        break;\r
+\r
+      case 2:\r
+        SetUnicodeMem (OptionString[0], 7, L' ');\r
+        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);\r
+        *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;\r
+        break;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_STRING_OP:\r
+    if (Selected) {\r
+      StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));\r
+      ASSERT (StringPtr);\r
+      CopyMem(StringPtr, Question->BufferValue, Maximum * sizeof (CHAR16));\r
+\r
+      Status = ReadString (MenuOption, gPromptForData, StringPtr);\r
+      if (!EFI_ERROR (Status)) {\r
+        HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);\r
+        Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+        if (EFI_ERROR (Status)) {\r
+          HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);\r
+        } else {\r
+          CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
+          SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);\r
+\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+        }\r
+      }\r
+\r
+      FreePool (StringPtr);\r
+    } else {\r
+      *OptionString = AllocateZeroPool (BufferSize);\r
+      ASSERT (*OptionString);\r
+\r
+      if (((CHAR16 *) Question->BufferValue)[0] == 0x0000) {\r
+        *(OptionString[0]) = '_';\r
+      } else {\r
+        if ((Maximum * sizeof (CHAR16)) < BufferSize) {\r
+          BufferSize = Maximum * sizeof (CHAR16);\r
+        }\r
+        CopyMem (OptionString[0], (CHAR16 *) Question->BufferValue, BufferSize);\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EFI_IFR_PASSWORD_OP:\r
+    if (Selected) {\r
+      StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));\r
+      ASSERT (StringPtr);\r
+\r
+      //\r
+      // For interactive passwords, old password is validated by callback\r
+      //\r
+      if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)  != 0) {\r
+        //\r
+        // Use a NULL password to test whether old password is required\r
+        //\r
+        *StringPtr = 0;\r
+        Status = PasswordCallback (Selection, MenuOption, StringPtr);\r
+        if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {\r
+          //\r
+          // Callback is not supported, or\r
+          // Callback request to terminate password input\r
+          //\r
+          FreePool (StringPtr);\r
+          return EFI_SUCCESS;\r
+        }\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          //\r
+          // Old password exist, ask user for the old password\r
+          //\r
+          Status = ReadString (MenuOption, gPromptForPassword, StringPtr);\r
+          if (EFI_ERROR (Status)) {\r
+            FreePool (StringPtr);\r
+            return Status;\r
+          }\r
+\r
+          //\r
+          // Check user input old password\r
+          //\r
+          Status = PasswordCallback (Selection, MenuOption, StringPtr);\r
+          if (EFI_ERROR (Status)) {\r
+            if (Status == EFI_NOT_READY) {\r
+              //\r
+              // Typed in old password incorrect\r
+              //\r
+              PasswordInvalid ();\r
+            } else {\r
+              Status = EFI_SUCCESS;\r
+            }\r
+\r
+            FreePool (StringPtr);\r
+            return Status;\r
+          }\r
+        }\r
+      } else {\r
+        //\r
+        // For non-interactive password, validate old password in local\r
+        //\r
+        if (*((CHAR16 *) Question->BufferValue) != 0) {\r
+          //\r
+          // There is something there!  Prompt for password\r
+          //\r
+          Status = ReadString (MenuOption, gPromptForPassword, StringPtr);\r
+          if (EFI_ERROR (Status)) {\r
+            FreePool (StringPtr);\r
+            return Status;\r
+          }\r
+\r
+          TempString = AllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);\r
+          ASSERT (TempString != NULL);\r
+\r
+          TempString[Maximum] = L'\0';\r
+\r
+          if (StrCmp (StringPtr, TempString) != 0) {\r
+            //\r
+            // Typed in old password incorrect\r
+            //\r
+            PasswordInvalid ();\r
+\r
+            FreePool (StringPtr);\r
+            FreePool (TempString);\r
+            return Status;\r
+          }\r
+\r
+          FreePool (TempString);\r
+        }\r
+      }\r
+\r
+      //\r
+      // Ask for new password\r
+      //\r
+      ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));\r
+      Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Reset state machine for interactive password\r
+        //\r
+        if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          PasswordCallback (Selection, MenuOption, NULL);\r
+        }\r
+\r
+        FreePool (StringPtr);\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Confirm new password\r
+      //\r
+      TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));\r
+      ASSERT (TempString);\r
+      Status = ReadString (MenuOption, gConfirmPassword, TempString);\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Reset state machine for interactive password\r
+        //\r
+        if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          PasswordCallback (Selection, MenuOption, NULL);\r
+        }\r
+\r
+        FreePool (StringPtr);\r
+        FreePool (TempString);\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Compare two typed-in new passwords\r
+      //\r
+      if (StrCmp (StringPtr, TempString) == 0) {\r
+        //\r
+        // Prepare the  Question->HiiValue.Value.string for ValidateQuestion use.\r
+        //\r
+        if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          StringId = Question->HiiValue.Value.string;\r
+          Question->HiiValue.Value.string = NewString (StringPtr, Selection->FormSet->HiiHandle);\r
+        } else {\r
+          HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);\r
+        }\r
+        \r
+        Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);\r
+\r
+        //\r
+        //  Researve the Question->HiiValue.Value.string.\r
+        //\r
+        if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          DeleteString(Question->HiiValue.Value.string, Selection->FormSet->HiiHandle);\r
+          Question->HiiValue.Value.string = StringId;\r
+        }   \r
+        \r
+        if (EFI_ERROR (Status)) {\r
+          //\r
+          // Reset state machine for interactive password\r
+          //\r
+          if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+            PasswordCallback (Selection, MenuOption, NULL);\r
+          } else {\r
+            //\r
+            // Researve the Question->HiiValue.Value.string.\r
+            //\r
+            HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);            \r
+          }\r
+        } else {\r
+          //\r
+          // Two password match, send it to Configuration Driver\r
+          //\r
+          if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+            PasswordCallback (Selection, MenuOption, StringPtr);\r
+          } else {\r
+            CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
+            SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);\r
+          }\r
+        }\r
+      } else {\r
+        //\r
+        // Reset state machine for interactive password\r
+        //\r
+        if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+          PasswordCallback (Selection, MenuOption, NULL);\r
+        }\r
+\r
+        //\r
+        // Two password mismatch, prompt error message\r
+        //\r
+        do {\r
+          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString);\r
+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+      }\r
+\r
+      FreePool (TempString);\r
+      FreePool (StringPtr);\r
+    }\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Process the help string: Split StringPtr to several lines of strings stored in\r
+  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.\r
+\r
+  @param  StringPtr              The entire help string.\r
+  @param  FormattedString        The oupput formatted string.\r
+  @param  EachLineWidth          The max string length of each line in the formatted string.\r
+  @param  RowCount               TRUE: if Question is selected.\r
+\r
+**/\r
+UINTN\r
+ProcessHelpString (\r
+  IN  CHAR16  *StringPtr,\r
+  OUT CHAR16  **FormattedString,\r
+  OUT UINT16  *EachLineWidth,\r
+  IN  UINTN   RowCount\r
+  )\r
+{\r
+  UINTN   Index;\r
+  CHAR16  *OutputString;\r
+  UINTN   TotalRowNum;\r
+  UINTN   CheckedNum;\r
+  UINT16  GlyphWidth;\r
+  UINT16  LineWidth;\r
+  UINT16  MaxStringLen;\r
+  UINT16  StringLen;\r
+\r
+  TotalRowNum    = 0;\r
+  CheckedNum     = 0;\r
+  GlyphWidth     = 1;\r
+  Index          = 0;\r
+  MaxStringLen   = 0;\r
+  StringLen      = 0;\r
+\r
+  //\r
+  // Set default help string width.\r
+  //\r
+  LineWidth      = (UINT16) (gHelpBlockWidth - 1);\r
+\r
+  //\r
+  // Get row number of the String.\r
+  //\r
+  while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {\r
+    if (StringLen > MaxStringLen) {\r
+      MaxStringLen = StringLen;\r
+    }\r
+\r
+    TotalRowNum ++;\r
+    FreePool (OutputString);\r
+  }\r
+  *EachLineWidth = MaxStringLen;\r
+\r
+  *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));\r
+  ASSERT (*FormattedString != NULL);\r
+\r
+  //\r
+  // Generate formatted help string array.\r
+  //\r
+  GlyphWidth  = 1;\r
+  Index       = 0;\r
+  while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {\r
+    CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));\r
+    CheckedNum ++;\r
+    FreePool (OutputString);\r
+  }\r
+\r
+  return TotalRowNum; \r
+}\r
index ba72d1220b594cb1857ed9bba97eee0ee1079a52..ed904161b619dd538b8ce296c83764791da2f225 100644 (file)
@@ -26,281 +26,167 @@ SETUP_DRIVER_PRIVATE_DATA  mPrivateData = {
     RegisterHotKey,\r
     RegiserExitHandler,\r
     SaveReminder\r
     RegisterHotKey,\r
     RegiserExitHandler,\r
     SaveReminder\r
-  },\r
-  {\r
-    BROWSER_EXTENSION2_VERSION_1,\r
-    SetScope,\r
-    RegisterHotKey,\r
-    RegiserExitHandler,\r
-    IsBrowserDataModified,\r
-    ExecuteAction,\r
   }\r
 };\r
 \r
 EFI_HII_DATABASE_PROTOCOL         *mHiiDatabase;\r
   }\r
 };\r
 \r
 EFI_HII_DATABASE_PROTOCOL         *mHiiDatabase;\r
+EFI_HII_STRING_PROTOCOL           *mHiiString;\r
 EFI_HII_CONFIG_ROUTING_PROTOCOL   *mHiiConfigRouting;\r
 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
 EFI_HII_CONFIG_ROUTING_PROTOCOL   *mHiiConfigRouting;\r
 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
-EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;\r
 \r
 UINTN           gBrowserContextCount = 0;\r
 LIST_ENTRY      gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);\r
 LIST_ENTRY      gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);\r
 LIST_ENTRY      gBrowserHotKeyList  = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);\r
 \r
 UINTN           gBrowserContextCount = 0;\r
 LIST_ENTRY      gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);\r
 LIST_ENTRY      gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);\r
 LIST_ENTRY      gBrowserHotKeyList  = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);\r
-LIST_ENTRY      gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
+LIST_ENTRY      gBrowserStorageList  = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);\r
 \r
 \r
+BANNER_DATA           *gBannerData;\r
+EFI_HII_HANDLE        gFrontPageHandle;\r
+UINTN                 gClassOfVfr;\r
+UINTN                 gFunctionKeySetting;\r
 BOOLEAN               gResetRequired;\r
 BOOLEAN               gResetRequired;\r
-BOOLEAN               gExitRequired;\r
+EFI_HII_HANDLE        gHiiHandle;\r
+UINT16                gDirection;\r
+EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
 BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;\r
 BOOLEAN               mBrowserScopeFirstSet = TRUE;\r
 EXIT_HANDLER          ExitHandlerFunction = NULL;\r
 BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;\r
 BOOLEAN               mBrowserScopeFirstSet = TRUE;\r
 EXIT_HANDLER          ExitHandlerFunction = NULL;\r
+UINTN                 gFooterHeight;\r
 \r
 //\r
 // Browser Global Strings\r
 //\r
 \r
 //\r
 // Browser Global Strings\r
 //\r
+CHAR16            *gSaveFailed;\r
+CHAR16            *gDiscardFailed;\r
+CHAR16            *gDefaultFailed;\r
+CHAR16            *gEnterString;\r
+CHAR16            *gEnterCommitString;\r
+CHAR16            *gEnterEscapeString;\r
+CHAR16            *gEscapeString;\r
+CHAR16            *gMoveHighlight;\r
+CHAR16            *gMakeSelection;\r
+CHAR16            *gDecNumericInput;\r
+CHAR16            *gHexNumericInput;\r
+CHAR16            *gToggleCheckBox;\r
+CHAR16            *gPromptForData;\r
+CHAR16            *gPromptForPassword;\r
+CHAR16            *gPromptForNewPassword;\r
+CHAR16            *gConfirmPassword;\r
+CHAR16            *gConfirmError;\r
+CHAR16            *gPassowordInvalid;\r
+CHAR16            *gPressEnter;\r
 CHAR16            *gEmptyString;\r
 CHAR16            *gEmptyString;\r
-CHAR16            *mUnknownString = L"!";\r
-\r
-EFI_GUID  gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
-\r
-extern UINT32          gBrowserStatus;\r
-extern CHAR16          *gErrorInfo;\r
-extern EFI_GUID        mCurrentFormSetGuid;\r
-extern EFI_HII_HANDLE  mCurrentHiiHandle;\r
-extern UINT16          mCurrentFormId;\r
-extern FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\r
-\r
-/**\r
-  Create a menu with specified formset GUID and form ID, and add it as a child\r
-  of the given parent menu.\r
-\r
-  @param  HiiHandle              Hii handle related to this formset.\r
-  @param  FormSetGuid            The Formset Guid of menu to be added.\r
-  @param  FormId                 The Form ID of menu to be added.\r
-  @param  QuestionId             The question id of this menu to be added.\r
-\r
-  @return A pointer to the newly added menu or NULL if memory is insufficient.\r
+CHAR16            *gAreYouSure;\r
+CHAR16            *gYesResponse;\r
+CHAR16            *gNoResponse;\r
+CHAR16            *gMiniString;\r
+CHAR16            *gPlusString;\r
+CHAR16            *gMinusString;\r
+CHAR16            *gAdjustNumber;\r
+CHAR16            *gSaveChanges;\r
+CHAR16            *gOptionMismatch;\r
+CHAR16            *gFormSuppress;\r
+CHAR16            *gProtocolNotFound;\r
 \r
 \r
-**/\r
-FORM_ENTRY_INFO *\r
-UiAddMenuList (\r
-  IN EFI_HII_HANDLE       HiiHandle,\r
-  IN EFI_GUID             *FormSetGuid,\r
-  IN UINT16               FormId,\r
-  IN UINT16               QuestionId\r
-  )\r
-{\r
-  FORM_ENTRY_INFO  *MenuList;\r
+CHAR16            *mUnknownString = L"!";\r
 \r
 \r
-  MenuList = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));\r
-  if (MenuList == NULL) {\r
-    return NULL;\r
-  }\r
+CHAR16            gPromptBlockWidth;\r
+CHAR16            gOptionBlockWidth;\r
+CHAR16            gHelpBlockWidth;\r
 \r
 \r
-  MenuList->Signature = FORM_ENTRY_INFO_SIGNATURE;\r
+EFI_GUID  gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+EFI_GUID  gSetupBrowserGuid = {\r
+  0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}\r
+};\r
 \r
 \r
-  MenuList->HiiHandle  = HiiHandle;\r
-  CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
-  MenuList->FormId     = FormId;\r
-  MenuList->QuestionId = QuestionId;\r
+FORM_BROWSER_FORMSET  *gOldFormSet = NULL;\r
 \r
 \r
+FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {\r
   //\r
   //\r
-  // If parent is not specified, it is the root Form of a Formset\r
+  // Boot Manager\r
   //\r
   //\r
-  InsertTailList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);\r
-\r
-  return MenuList;\r
-}\r
-\r
-/**\r
-  Return the form id for the input hiihandle and formset.\r
-\r
-  @param  HiiHandle              HiiHandle for FormSet.\r
-  @param  FormSetGuid            The Formset GUID of the menu to search.\r
-\r
-  @return First form's id for this form set.\r
-\r
-**/\r
-EFI_FORM_ID\r
-GetFirstFormId (\r
-  IN EFI_HII_HANDLE       HiiHandle,\r
-  IN EFI_GUID             *FormSetGuid\r
-  )\r
-{\r
-  LIST_ENTRY         *Link;\r
-  FORM_BROWSER_FORM  *Form;\r
-\r
-  Link = GetFirstNode (&gCurrentSelection->FormSet->FormListHead);\r
-  Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-\r
-  return Form->FormId;\r
-}\r
-\r
-/**\r
-  Search Menu with given FormSetGuid and FormId in all cached menu list.\r
-\r
-  @param  HiiHandle              HiiHandle for FormSet.\r
-  @param  FormSetGuid            The Formset GUID of the menu to search.\r
-  @param  FormId                 The Form ID of menu to search.\r
-\r
-  @return A pointer to menu found or NULL if not found.\r
-\r
-**/\r
-FORM_ENTRY_INFO *\r
-UiFindMenuList (\r
-  IN EFI_HII_HANDLE       HiiHandle, \r
-  IN EFI_GUID             *FormSetGuid,\r
-  IN UINT16               FormId\r
-  )\r
-{\r
-  LIST_ENTRY         *Link;\r
-  FORM_ENTRY_INFO    *MenuList;\r
-  FORM_ENTRY_INFO    *RetMenu;\r
-  EFI_FORM_ID        FirstFormId;\r
-\r
-  RetMenu = NULL;\r
-\r
-  Link = GetFirstNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
-  while (!IsNull (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link)) {\r
-    MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);\r
-    Link = GetNextNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link);\r
-    \r
-    //\r
-    // If already find the menu, free the menus behind it.\r
-    //\r
-    if (RetMenu != NULL) {\r
-      RemoveEntryList (&MenuList->Link);\r
-      FreePool (MenuList);\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Find the same FromSet.\r
-    //\r
-    if (MenuList->HiiHandle == HiiHandle) {\r
-      if (CompareGuid (&MenuList->FormSetGuid, &gZeroGuid)) {\r
-        //\r
-        // FormSetGuid is not specified.\r
-        //\r
-        RetMenu = MenuList;\r
-      } else if (CompareGuid (&MenuList->FormSetGuid, FormSetGuid)) {\r
-        if (MenuList->FormId == FormId) {\r
-          RetMenu = MenuList;\r
-        } else if (FormId == 0 || MenuList->FormId == 0 ) {\r
-          FirstFormId = GetFirstFormId (HiiHandle, FormSetGuid);\r
-          if ((FormId == 0 && FirstFormId == MenuList->FormId) || (MenuList->FormId ==0 && FirstFormId == FormId)) {\r
-            RetMenu = MenuList;\r
-          }\r
-        }\r
+  {\r
+    {\r
+      0x847bc3fe,\r
+      0xb974,\r
+      0x446d,\r
+      {\r
+        0x94,\r
+        0x49,\r
+        0x5a,\r
+        0xd5,\r
+        0x41,\r
+        0x2e,\r
+        0x99,\r
+        0x3b\r
       }\r
       }\r
-    }\r
-  }\r
-\r
-  return RetMenu;\r
-}\r
-\r
-/**\r
-  Find parent menu for current menu.\r
-\r
-  @param  CurrentMenu    Current Menu\r
-\r
-  @retval   The parent menu for current menu.\r
-**/\r
-FORM_ENTRY_INFO *\r
-UiFindParentMenu (\r
-  IN FORM_ENTRY_INFO  *CurrentMenu\r
-  )\r
-{\r
-  FORM_ENTRY_INFO    *ParentMenu;\r
-\r
-  ParentMenu = NULL;\r
-  if (CurrentMenu->Link.BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {\r
-    ParentMenu = FORM_ENTRY_INFO_FROM_LINK (CurrentMenu->Link.BackLink);\r
-  }\r
-\r
-  return ParentMenu;\r
-}\r
-\r
-/**\r
-  Free Menu list linked list.\r
-\r
-  @param  MenuListHead    One Menu list point in the menu list.\r
-\r
-**/\r
-VOID\r
-UiFreeMenuList (\r
-  LIST_ENTRY   *MenuListHead\r
-  )\r
-{\r
-  FORM_ENTRY_INFO    *MenuList;\r
-\r
-  while (!IsListEmpty (MenuListHead)) {\r
-    MenuList = FORM_ENTRY_INFO_FROM_LINK (MenuListHead->ForwardLink);\r
-    RemoveEntryList (&MenuList->Link);\r
-\r
-    FreePool (MenuList);\r
-  }\r
-}\r
-\r
-/**\r
-  Load all hii formset to the browser.\r
-\r
-**/\r
-VOID\r
-LoadAllHiiFormset (\r
-  VOID\r
-  )\r
-{\r
-  FORM_BROWSER_FORMSET    *LocalFormSet;\r
-  EFI_HII_HANDLE          *HiiHandles;\r
-  UINTN                   Index;\r
-  EFI_GUID                ZeroGuid;\r
-  EFI_STATUS              Status;\r
-\r
+    },\r
+    NONE_FUNCTION_KEY_SETTING\r
+  },\r
   //\r
   //\r
-  // Get all the Hii handles\r
+  // Device Manager\r
   //\r
   //\r
-  HiiHandles = HiiGetHiiHandles (NULL);\r
-  ASSERT (HiiHandles != NULL);\r
-\r
+  {\r
+    {\r
+      0x3ebfa8e6,\r
+      0x511d,\r
+      0x4b5b,\r
+      {\r
+        0xa9,\r
+        0x5f,\r
+        0xfb,\r
+        0x38,\r
+        0x26,\r
+        0xf,\r
+        0x1c,\r
+        0x27\r
+      }\r
+    },\r
+    NONE_FUNCTION_KEY_SETTING\r
+  },\r
   //\r
   //\r
-  // Search for formset of each class type\r
+  // BMM FormSet.\r
   //\r
   //\r
-  for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
-    //\r
-    // Check HiiHandles[Index] does exist in global maintain list.\r
-    //\r
-    if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Initilize FormSet Setting\r
-    //\r
-    LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
-    ASSERT (LocalFormSet != NULL);\r
-    ZeroMem (&ZeroGuid, sizeof (ZeroGuid));\r
-    Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);\r
-    if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {\r
-      DestroyFormSet (LocalFormSet);\r
-      continue;\r
-    }\r
-    InitializeCurrentSetting (LocalFormSet);\r
-\r
-    //\r
-    // Initilize Questions' Value\r
-    //\r
-    Status = LoadFormSetConfig (NULL, LocalFormSet);\r
-    if (EFI_ERROR (Status)) {\r
-      DestroyFormSet (LocalFormSet);\r
-      continue;\r
-    }\r
-  }\r
-\r
+  {\r
+    {\r
+      0x642237c7,\r
+      0x35d4,\r
+      0x472d,\r
+      {\r
+        0x83,\r
+        0x65,\r
+        0x12,\r
+        0xe0,\r
+        0xcc,\r
+        0xf2,\r
+        0x7a,\r
+        0x22\r
+      }\r
+    },\r
+    NONE_FUNCTION_KEY_SETTING\r
+  },\r
   //\r
   //\r
-  // Free resources, and restore gOldFormSet and gClassOfVfr\r
+  // BMM File Explorer FormSet.\r
   //\r
   //\r
-  FreePool (HiiHandles);\r
-}\r
+  {\r
+    {\r
+      0x1f2d63e1,\r
+      0xfebd,\r
+      0x4dc7,\r
+      {\r
+        0x9c,\r
+        0xc5,\r
+        0xba,\r
+        0x2b,\r
+        0x1c,\r
+        0xef,\r
+        0x9c,\r
+        0x5b\r
+      }\r
+    },\r
+    NONE_FUNCTION_KEY_SETTING\r
+  },\r
+};\r
 \r
 /**\r
   This is the routine which an external caller uses to direct the browser\r
 \r
 /**\r
   This is the routine which an external caller uses to direct the browser\r
@@ -343,14 +229,26 @@ SendForm (
   UI_MENU_SELECTION             *Selection;\r
   UINTN                         Index;\r
   FORM_BROWSER_FORMSET          *FormSet;\r
   UI_MENU_SELECTION             *Selection;\r
   UINTN                         Index;\r
   FORM_BROWSER_FORMSET          *FormSet;\r
-  FORM_ENTRY_INFO               *MenuList;\r
+  LIST_ENTRY                    *Link;\r
 \r
   //\r
 \r
   //\r
-  // If EDKII_FORM_DISPLAY_ENGINE_PROTOCOL not found, return EFI_UNSUPPORTED.\r
+  // Calculate total number of Register HotKeys. \r
   //\r
   //\r
-  if (mFormDisplay == NULL) {\r
-    return EFI_UNSUPPORTED;\r
+  Index = 0;\r
+  Link  = GetFirstNode (&gBrowserHotKeyList);\r
+  while (!IsNull (&gBrowserHotKeyList, Link)) {\r
+    Link = GetNextNode (&gBrowserHotKeyList, Link);\r
+    Index ++;\r
   }\r
   }\r
+  //\r
+  // Show three HotKeys help information on one ROW.\r
+  //\r
+  gFooterHeight = FOOTER_HEIGHT + (Index / 3);\r
+\r
+  //\r
+  // Clean the history menu list.\r
+  //\r
+  InitializeListHead (&gMenuList);\r
 \r
   //\r
   // Save globals used by SendForm()\r
 \r
   //\r
   // Save globals used by SendForm()\r
@@ -358,10 +256,65 @@ SendForm (
   SaveBrowserContext ();\r
 \r
   gResetRequired = FALSE;\r
   SaveBrowserContext ();\r
 \r
   gResetRequired = FALSE;\r
-  gExitRequired  = FALSE;\r
-  Status         = EFI_SUCCESS;\r
-  gEmptyString   = L"";\r
-  gDisplayFormData.ScreenDimensions = (EFI_SCREEN_DESCRIPTOR *) ScreenDimensions;\r
+  Status = EFI_SUCCESS;\r
+  ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
+  //\r
+  // Seed the dimensions in the global\r
+  //\r
+  gST->ConOut->QueryMode (\r
+                 gST->ConOut,\r
+                 gST->ConOut->Mode->Mode,\r
+                 &gScreenDimensions.RightColumn,\r
+                 &gScreenDimensions.BottomRow\r
+                 );\r
+\r
+  if (ScreenDimensions != NULL) {\r
+    //\r
+    // Check local dimension vs. global dimension.\r
+    //\r
+    if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||\r
+        (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)\r
+        ) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    } else {\r
+      //\r
+      // Local dimension validation.\r
+      //\r
+      if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&\r
+          (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&\r
+          ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&\r
+          (\r
+            (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +\r
+            SCROLL_ARROW_HEIGHT *\r
+            2 +\r
+            FRONT_PAGE_HEADER_HEIGHT +\r
+            gFooterHeight +\r
+            1\r
+          )\r
+        ) {\r
+        CopyMem (&gScreenDimensions, (VOID *) ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+      } else {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+    }\r
+  }\r
+\r
+  gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
+  gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS);\r
+  gHelpBlockWidth   = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS);\r
+\r
+  //\r
+  // Initialize the strings for the browser, upon exit of the browser, the strings will be freed\r
+  //\r
+  InitializeBrowserStrings ();\r
+\r
+  //\r
+  // Ensure we are in Text mode\r
+  //\r
+  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
 \r
   for (Index = 0; Index < HandleCount; Index++) {\r
     Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));\r
 \r
   for (Index = 0; Index < HandleCount; Index++) {\r
     Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));\r
@@ -382,13 +335,18 @@ SendForm (
       //\r
       // Initialize internal data structures of FormSet\r
       //\r
       //\r
       // Initialize internal data structures of FormSet\r
       //\r
-      Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet);\r
+      Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet, TRUE);\r
       if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {\r
         DestroyFormSet (FormSet);\r
         break;\r
       }\r
       Selection->FormSet = FormSet;\r
 \r
       if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {\r
         DestroyFormSet (FormSet);\r
         break;\r
       }\r
       Selection->FormSet = FormSet;\r
 \r
+      //\r
+      // Try to find pre FormSet in the maintain backup list.\r
+      //\r
+      gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle);\r
+\r
       //\r
       // Display this formset\r
       //\r
       //\r
       // Display this formset\r
       //\r
@@ -398,34 +356,25 @@ SendForm (
 \r
       gCurrentSelection = NULL;\r
 \r
 \r
       gCurrentSelection = NULL;\r
 \r
-      //\r
-      // If no data is changed, don't need to save current FormSet into the maintain list.\r
-      //\r
-      if (!IsNvUpdateRequiredForFormSet (FormSet) && !IsStorageDataChangedForFormSet(FormSet)) {\r
-        CleanBrowserStorage(FormSet);\r
-        RemoveEntryList (&FormSet->Link);\r
-        DestroyFormSet (FormSet);\r
-      }\r
-\r
       if (EFI_ERROR (Status)) {\r
         break;\r
       }\r
       if (EFI_ERROR (Status)) {\r
         break;\r
       }\r
-    } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);\r
-\r
-    FreePool (Selection);\r
-  }\r
 \r
 \r
-  //\r
-  // Still has error info, pop up a message.\r
-  //\r
-  if (gBrowserStatus != BROWSER_SUCCESS) {\r
-    gDisplayFormData.BrowserStatus = gBrowserStatus;\r
-    gDisplayFormData.ErrorString   = gErrorInfo;\r
+    } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);\r
 \r
 \r
-    gBrowserStatus = BROWSER_SUCCESS;\r
-    gErrorInfo     = NULL;\r
+    if (gOldFormSet != NULL) {\r
+      //\r
+      // If no data is changed, don't need to save current FormSet into the maintain list.\r
+      //\r
+      if (!IsNvUpdateRequired (gOldFormSet)) {\r
+        CleanBrowserStorage(gOldFormSet);\r
+        RemoveEntryList (&gOldFormSet->Link);\r
+        DestroyFormSet (gOldFormSet);\r
+      }\r
+      gOldFormSet = NULL;\r
+    }\r
 \r
 \r
-    mFormDisplay->FormDisplay (&gDisplayFormData, NULL);\r
+    FreePool (Selection);\r
   }\r
 \r
   if (ActionRequest != NULL) {\r
   }\r
 \r
   if (ActionRequest != NULL) {\r
@@ -435,17 +384,13 @@ SendForm (
     }\r
   }\r
 \r
     }\r
   }\r
 \r
-  mFormDisplay->ExitDisplay();\r
+  FreeBrowserStrings ();\r
+  UiFreeMenuList(&gMenuList);\r
 \r
 \r
-  //\r
-  // Clear the menu history data.\r
-  //\r
-  while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {\r
-    MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);\r
-    RemoveEntryList (&MenuList->Link);\r
-    FreePool (MenuList);\r
-  }\r
+  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+  gST->ConOut->ClearScreen (gST->ConOut);\r
 \r
 \r
+Done:\r
   //\r
   // Restore globals used by SendForm()\r
   //\r
   //\r
   // Restore globals used by SendForm()\r
   //\r
@@ -454,93 +399,10 @@ SendForm (
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
-/**\r
-  Get or set data to the storage.\r
-\r
-  @param  ResultsDataSize        The size of the buffer associatedwith ResultsData.\r
-  @param  ResultsData            A string returned from an IFR browser or\r
-                                 equivalent. The results string will have no\r
-                                 routing information in them.\r
-  @param  RetrieveData           A BOOLEAN field which allows an agent to retrieve\r
-                                 (if RetrieveData = TRUE) data from the uncommitted\r
-                                 browser state information or set (if RetrieveData\r
-                                 = FALSE) data in the uncommitted browser state\r
-                                 information.\r
-  @param  Storage                The pointer to the storage.\r
-\r
-  @retval EFI_SUCCESS            The results have been distributed or are awaiting\r
-                                 distribution.\r
-\r
-**/\r
-EFI_STATUS \r
-ProcessStorage (\r
-  IN OUT UINTN                         *ResultsDataSize,\r
-  IN OUT EFI_STRING                    *ResultsData,\r
-  IN BOOLEAN                           RetrieveData,\r
-  IN BROWSER_STORAGE                   *Storage\r
-  )\r
-{\r
-  CHAR16                *ConfigResp;\r
-  EFI_STATUS            Status;\r
-  CHAR16                *StrPtr;\r
-  UINTN                 BufferSize;\r
-  UINTN                 TmpSize;\r
-\r
-  if (RetrieveData) {\r
-    //\r
-    // Generate <ConfigResp>\r
-    //\r
-    Status = StorageToConfigResp (Storage, &ConfigResp, Storage->ConfigRequest, TRUE);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Skip <ConfigHdr> and '&' to point to <ConfigBody> when first copy the configbody.\r
-    // Also need to consider add "\0" at first time.\r
-    //\r
-    StrPtr     = ConfigResp + StrLen (Storage->ConfigHdr) + 1;\r
-    BufferSize = StrSize (StrPtr);\r
-\r
-\r
-    //\r
-    // Copy the data if the input buffer is bigger enough.\r
-    //\r
-    if (*ResultsDataSize >= BufferSize) {\r
-      StrCpy (*ResultsData, StrPtr);\r
-    }\r
-\r
-    *ResultsDataSize = BufferSize;\r
-    FreePool (ConfigResp);\r
-  } else {\r
-    //\r
-    // Prepare <ConfigResp>\r
-    //\r
-    TmpSize = StrLen (*ResultsData);\r
-    BufferSize = (TmpSize + StrLen (Storage->ConfigHdr) + 2) * sizeof (CHAR16);\r
-    ConfigResp = AllocateZeroPool (BufferSize);\r
-    ASSERT (ConfigResp != NULL);\r
-\r
-    StrCpy (ConfigResp, Storage->ConfigHdr);\r
-    StrCat (ConfigResp, L"&");\r
-    StrCat (ConfigResp, *ResultsData);\r
-\r
-    //\r
-    // Update Browser uncommited data\r
-    //\r
-    Status = ConfigRespToStorage (Storage, ConfigResp);\r
-    FreePool (ConfigResp);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
 \r
 /**\r
 \r
 /**\r
-  This routine called this service in the browser to retrieve or set certain uncommitted \r
-  state information that resides in the open formsets. \r
+  This function is called by a callback handler to retrieve uncommitted state\r
+  data from the browser.\r
 \r
   @param  This                   A pointer to the EFI_FORM_BROWSER2_PROTOCOL\r
                                  instance.\r
 \r
   @param  This                   A pointer to the EFI_FORM_BROWSER2_PROTOCOL\r
                                  instance.\r
@@ -578,69 +440,60 @@ BrowserCallback (
 {\r
   EFI_STATUS            Status;\r
   LIST_ENTRY            *Link;\r
 {\r
   EFI_STATUS            Status;\r
   LIST_ENTRY            *Link;\r
-  BROWSER_STORAGE       *Storage;\r
-  FORMSET_STORAGE       *FormsetStorage;\r
+  FORMSET_STORAGE       *Storage;\r
   FORM_BROWSER_FORMSET  *FormSet;\r
   FORM_BROWSER_FORMSET  *FormSet;\r
-  UINTN                 TotalSize;\r
   BOOLEAN               Found;\r
   BOOLEAN               Found;\r
+  CHAR16                *ConfigResp;\r
+  CHAR16                *StrPtr;\r
+  UINTN                 BufferSize;\r
+  UINTN                 TmpSize;\r
 \r
   if (ResultsDataSize == NULL || ResultsData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
 \r
   if (ResultsDataSize == NULL || ResultsData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  TotalSize = *ResultsDataSize;\r
-  Storage   = NULL;\r
-  Found     = FALSE;\r
-  Status    = EFI_SUCCESS;\r
+  if (gCurrentSelection == NULL) {\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  Storage = NULL;\r
+  ConfigResp = NULL;\r
+  FormSet = gCurrentSelection->FormSet;\r
 \r
   //\r
 \r
   //\r
-  // If set browser data, pre load all hii formset to avoid set the varstore which is not \r
-  // saved in browser.\r
+  // Find target storage\r
   //\r
   //\r
-  if (!RetrieveData && (gBrowserSettingScope == SystemLevel)) {\r
-    LoadAllHiiFormset();\r
+  Link = GetFirstNode (&FormSet->StorageListHead);\r
+  if (IsNull (&FormSet->StorageListHead, Link)) {\r
+    return EFI_UNSUPPORTED;\r
   }\r
 \r
   if (VariableGuid != NULL) {\r
     //\r
   }\r
 \r
   if (VariableGuid != NULL) {\r
     //\r
-    // Try to find target storage in the current formset.\r
+    // Try to find target storage\r
     //\r
     //\r
-    Link = GetFirstNode (&gBrowserStorageList);\r
-    while (!IsNull (&gBrowserStorageList, Link)) {\r
-      Storage = BROWSER_STORAGE_FROM_LINK (Link);\r
-      Link = GetNextNode (&gBrowserStorageList, Link);\r
-      //\r
-      // Check the current storage.\r
-      //\r
-      if (!CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {\r
-        continue;\r
-      }\r
+    Found = FALSE;\r
+    while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+      Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+      Link = GetNextNode (&FormSet->StorageListHead, Link);\r
 \r
 \r
-      if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||\r
-          Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
-        //\r
-        // Buffer storage require both GUID and Name\r
-        //\r
-        if (VariableName == NULL) {\r
-          return EFI_NOT_FOUND;\r
-        }\r
+      if (CompareGuid (&Storage->BrowserStorage->Guid, (EFI_GUID *) VariableGuid)) {\r
+        if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||\r
+            Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+          //\r
+          // Buffer storage require both GUID and Name\r
+          //\r
+          if (VariableName == NULL) {\r
+            return EFI_NOT_FOUND;\r
+          }\r
 \r
 \r
-        if (StrCmp (Storage->Name, (CHAR16 *) VariableName) != 0) {\r
-          continue;\r
+          if (StrCmp (Storage->BrowserStorage->Name, (CHAR16 *) VariableName) != 0) {\r
+            continue;\r
+          }\r
         }\r
         }\r
+        Found = TRUE;\r
+        break;\r
       }\r
       }\r
-\r
-      Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-\r
-      //\r
-      // Different formsets may have same varstore, so here just set the flag\r
-      // not exit the circle.\r
-      // \r
-      Found = TRUE;\r
-      break;\r
     }\r
 \r
     if (!Found) {\r
     }\r
 \r
     if (!Found) {\r
@@ -650,62 +503,65 @@ BrowserCallback (
     //\r
     // GUID/Name is not specified, take the first storage in FormSet\r
     //\r
     //\r
     // GUID/Name is not specified, take the first storage in FormSet\r
     //\r
-    if (gCurrentSelection == NULL) {\r
-      return EFI_NOT_READY;\r
-    }\r
+    Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+  }\r
 \r
 \r
+  if (RetrieveData) {\r
     //\r
     //\r
-    // Generate <ConfigResp>\r
+    // Skip if there is no RequestElement\r
     //\r
     //\r
-    FormSet = gCurrentSelection->FormSet;\r
-    Link = GetFirstNode (&FormSet->StorageListHead);\r
-    if (IsNull (&FormSet->StorageListHead, Link)) {\r
-      return EFI_UNSUPPORTED;\r
+    if (Storage->ElementCount == 0) {\r
+      return EFI_SUCCESS;\r
     }\r
 \r
     }\r
 \r
-    FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);\r
-    \r
-    Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, FormsetStorage->BrowserStorage);\r
+    //\r
+    // Generate <ConfigResp>\r
+    //\r
+    Status = StorageToConfigResp (Storage->BrowserStorage, &ConfigResp, Storage->ConfigRequest);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-  }\r
 \r
 \r
-  if (RetrieveData) {\r
-    Status = TotalSize <= *ResultsDataSize ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
-    *ResultsDataSize = TotalSize;\r
-  }\r
-   \r
-  return Status;\r
+    //\r
+    // Skip <ConfigHdr> and '&' to point to <ConfigBody>\r
+    //\r
+    StrPtr = ConfigResp + StrLen (Storage->BrowserStorage->ConfigHdr) + 1;\r
 \r
 \r
-}\r
+    BufferSize = StrSize (StrPtr);\r
+    if (*ResultsDataSize < BufferSize) {\r
+      *ResultsDataSize = BufferSize;\r
 \r
 \r
+      FreePool (ConfigResp);\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
 \r
 \r
-/**\r
-  Callback function for SimpleTextInEx protocol install events\r
+    *ResultsDataSize = BufferSize;\r
+    CopyMem (ResultsData, StrPtr, BufferSize);\r
 \r
 \r
-  @param Event           the event that is signaled.\r
-  @param Context         not used here.\r
+    FreePool (ConfigResp);\r
+  } else {\r
+    //\r
+    // Prepare <ConfigResp>\r
+    //\r
+    TmpSize = StrLen (ResultsData);\r
+    BufferSize = (TmpSize + StrLen (Storage->BrowserStorage->ConfigHdr) + 2) * sizeof (CHAR16);\r
+    ConfigResp = AllocateZeroPool (BufferSize);\r
+    ASSERT (ConfigResp != NULL);\r
 \r
 \r
-**/\r
-VOID\r
-EFIAPI\r
-FormDisplayCallback (\r
-  IN EFI_EVENT    Event,\r
-  IN VOID         *Context\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
+    StrCpy (ConfigResp, Storage->BrowserStorage->ConfigHdr);\r
+    StrCat (ConfigResp, L"&");\r
+    StrCat (ConfigResp, ResultsData);\r
 \r
 \r
-  if (mFormDisplay != NULL) {\r
-    return;\r
+    //\r
+    // Update Browser uncommited data\r
+    //\r
+    Status = ConfigRespToStorage (Storage->BrowserStorage, ConfigResp);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
   }\r
 \r
   }\r
 \r
-  Status = gBS->LocateProtocol (\r
-                  &gEdkiiFormDisplayEngineProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &mFormDisplay\r
-                  );\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -726,7 +582,8 @@ InitializeSetup (
   )\r
 {\r
   EFI_STATUS                  Status;\r
   )\r
 {\r
   EFI_STATUS                  Status;\r
-  VOID                        *Registration;\r
+  EFI_INPUT_KEY               DefaultHotKey;\r
+  EFI_STRING                  HelpString;\r
 \r
   //\r
   // Locate required Hii relative protocols\r
 \r
   //\r
   // Locate required Hii relative protocols\r
@@ -738,6 +595,13 @@ InitializeSetup (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiStringProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &mHiiString\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiConfigRoutingProtocolGuid,\r
                   NULL,\r
   Status = gBS->LocateProtocol (\r
                   &gEfiHiiConfigRoutingProtocolGuid,\r
                   NULL,\r
@@ -751,6 +615,30 @@ InitializeSetup (
                   (VOID **) &mPathFromText\r
                   );\r
 \r
                   (VOID **) &mPathFromText\r
                   );\r
 \r
+  //\r
+  // Publish our HII data\r
+  //\r
+  gHiiHandle = HiiAddPackages (\r
+                 &gSetupBrowserGuid,\r
+                 ImageHandle,\r
+                 SetupBrowserStrings,\r
+                 NULL\r
+                 );\r
+  ASSERT (gHiiHandle != NULL);\r
+\r
+  //\r
+  // Initialize Driver private data\r
+  //\r
+  gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));\r
+  ASSERT (gBannerData != NULL);\r
+  \r
+  //\r
+  // Initialize generic help strings.\r
+  //\r
+  gSaveFailed    = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);\r
+  gDiscardFailed = GetToken (STRING_TOKEN (DISCARD_FAILED), gHiiHandle);\r
+  gDefaultFailed = GetToken (STRING_TOKEN (DEFAULT_FAILED), gHiiHandle);\r
+\r
   //\r
   // Install FormBrowser2 protocol\r
   //\r
   //\r
   // Install FormBrowser2 protocol\r
   //\r
@@ -764,18 +652,25 @@ InitializeSetup (
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   //\r
-  // Install FormBrowserEx2 protocol\r
+  // Install default HotKey F10 for Save\r
+  //\r
+  DefaultHotKey.UnicodeChar = CHAR_NULL;\r
+  HelpString             = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);\r
+  DefaultHotKey.ScanCode = SCAN_F10;\r
+  RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_SUBMIT, 0, HelpString);\r
+  FreePool (HelpString);\r
+  //\r
+  // Install default HotKey F9 for Reset To Defaults\r
+  //\r
+  DefaultHotKey.ScanCode    = SCAN_F9;\r
+  HelpString                = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);\r
+  RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, HelpString);\r
+  FreePool (HelpString);\r
+\r
+  //\r
+  // Install FormBrowserEx protocol\r
   //\r
   //\r
-  InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);  \r
   mPrivateData.Handle = NULL;\r
   mPrivateData.Handle = NULL;\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &mPrivateData.Handle,\r
-                  &gEdkiiFormBrowserEx2ProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &mPrivateData.FormBrowserEx2\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-  \r
   Status = gBS->InstallProtocolInterface (\r
                   &mPrivateData.Handle,\r
                   &gEfiFormBrowserExProtocolGuid,\r
   Status = gBS->InstallProtocolInterface (\r
                   &mPrivateData.Handle,\r
                   &gEfiFormBrowserExProtocolGuid,\r
@@ -784,25 +679,7 @@ InitializeSetup (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  InitializeDisplayFormData ();\r
-\r
-  Status = gBS->LocateProtocol (\r
-                  &gEdkiiFormDisplayEngineProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &mFormDisplay\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    EfiCreateProtocolNotifyEvent (\r
-      &gEdkiiFormDisplayEngineProtocolGuid,\r
-      TPL_CALLBACK,\r
-      FormDisplayCallback,\r
-      NULL,\r
-      &Registration\r
-      );\r
-  }\r
-  \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -927,17 +804,69 @@ NewStringCat (
     return;\r
   }\r
 \r
     return;\r
   }\r
 \r
-  TmpSize = StrSize (*Dest);\r
-  NewString = AllocateZeroPool (TmpSize + StrSize (Src) - 1);\r
-  ASSERT (NewString != NULL);\r
+  TmpSize = StrSize (*Dest);\r
+  NewString = AllocateZeroPool (TmpSize + StrSize (Src) - 1);\r
+  ASSERT (NewString != NULL);\r
+\r
+  StrCpy (NewString, *Dest);\r
+  StrCat (NewString, Src);\r
+\r
+  FreePool (*Dest);\r
+  *Dest = NewString;\r
+}\r
+\r
+\r
+/**\r
+  Synchronize or restore Storage's Edit copy and Shadow copy.\r
+\r
+  @param  Storage          The Storage to be synchronized.\r
+  @param  SyncOrRestore    Sync the buffer to editbuffer or Restore  the \r
+                           editbuffer to buffer\r
+                           if TRUE, copy the editbuffer to the buffer.\r
+                           if FALSE, copy the buffer to the editbuffer.\r
+\r
+**/\r
+VOID\r
+SynchronizeStorage (\r
+  IN BROWSER_STORAGE         *Storage,\r
+  IN BOOLEAN                 SyncOrRestore\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  NAME_VALUE_NODE         *Node;\r
+\r
+  switch (Storage->Type) {\r
+  case EFI_HII_VARSTORE_BUFFER:\r
+  case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
+    if (SyncOrRestore) {\r
+      CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);\r
+    } else {\r
+      CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);\r
+    }\r
+    break;\r
+\r
+  case EFI_HII_VARSTORE_NAME_VALUE:\r
+    Link = GetFirstNode (&Storage->NameValueListHead);\r
+    while (!IsNull (&Storage->NameValueListHead, Link)) {\r
+      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
 \r
 \r
-  StrCpy (NewString, *Dest);\r
-  StrCat (NewString, Src);\r
+      if (SyncOrRestore) {\r
+        NewStringCpy (&Node->Value, Node->EditValue);\r
+      } else {\r
+        NewStringCpy (&Node->EditValue, Node->Value);\r
+      }\r
 \r
 \r
-  FreePool (*Dest);\r
-  *Dest = NewString;\r
+      Link = GetNextNode (&Storage->NameValueListHead, Link);\r
+    }\r
+    break;\r
+\r
+  case EFI_HII_VARSTORE_EFI_VARIABLE:\r
+  default:\r
+    break;\r
+  }\r
 }\r
 \r
 }\r
 \r
+\r
 /**\r
   Get Value for given Name from a NameValue Storage.\r
 \r
 /**\r
   Get Value for given Name from a NameValue Storage.\r
 \r
@@ -994,7 +923,6 @@ GetValueByName (
   @param  Name                   The Name.\r
   @param  Value                  The Value to set.\r
   @param  SetValueTo             Whether update editValue or Value.\r
   @param  Name                   The Name.\r
   @param  Value                  The Value to set.\r
   @param  SetValueTo             Whether update editValue or Value.\r
-  @param  ReturnNode             The node use the input name.\r
 \r
   @retval EFI_SUCCESS            Value found for given Name.\r
   @retval EFI_NOT_FOUND          No such Name found in NameValue storage.\r
 \r
   @retval EFI_SUCCESS            Value found for given Name.\r
   @retval EFI_NOT_FOUND          No such Name found in NameValue storage.\r
@@ -1002,11 +930,10 @@ GetValueByName (
 **/\r
 EFI_STATUS\r
 SetValueByName (\r
 **/\r
 EFI_STATUS\r
 SetValueByName (\r
-  IN  BROWSER_STORAGE             *Storage,\r
-  IN  CHAR16                      *Name,\r
-  IN  CHAR16                      *Value,\r
-  IN  GET_SET_QUESTION_VALUE_WITH SetValueTo,\r
-  OUT NAME_VALUE_NODE             **ReturnNode\r
+  IN BROWSER_STORAGE         *Storage,\r
+  IN CHAR16                  *Name,\r
+  IN CHAR16                  *Value,\r
+  IN GET_SET_QUESTION_VALUE_WITH SetValueTo\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
@@ -1037,11 +964,6 @@ SetValueByName (
       } else {\r
         Node->Value = Buffer;\r
       }\r
       } else {\r
         Node->Value = Buffer;\r
       }\r
-\r
-      if (ReturnNode != NULL) {\r
-        *ReturnNode = Node;\r
-      }\r
-\r
       return EFI_SUCCESS;\r
     }\r
 \r
       return EFI_SUCCESS;\r
     }\r
 \r
@@ -1058,7 +980,6 @@ SetValueByName (
   @param  Storage                The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
   @param  ConfigRequest          The ConfigRequest string.\r
   @param  Storage                The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
   @param  ConfigRequest          The ConfigRequest string.\r
-  @param  GetEditBuf             Get the data from editbuffer or buffer.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
@@ -1068,26 +989,23 @@ EFI_STATUS
 StorageToConfigResp (\r
   IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  **ConfigResp,\r
 StorageToConfigResp (\r
   IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  **ConfigResp,\r
-  IN CHAR16                  *ConfigRequest,\r
-  IN BOOLEAN                 GetEditBuf\r
+  IN CHAR16                  *ConfigRequest\r
   )\r
 {\r
   EFI_STATUS              Status;\r
   EFI_STRING              Progress;\r
   LIST_ENTRY              *Link;\r
   NAME_VALUE_NODE         *Node;\r
   )\r
 {\r
   EFI_STATUS              Status;\r
   EFI_STRING              Progress;\r
   LIST_ENTRY              *Link;\r
   NAME_VALUE_NODE         *Node;\r
-  UINT8                   *SourceBuf;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
   switch (Storage->Type) {\r
   case EFI_HII_VARSTORE_BUFFER:\r
   case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
 \r
   Status = EFI_SUCCESS;\r
 \r
   switch (Storage->Type) {\r
   case EFI_HII_VARSTORE_BUFFER:\r
   case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
-    SourceBuf = GetEditBuf ? Storage->EditBuffer : Storage->Buffer;\r
     Status = mHiiConfigRouting->BlockToConfig (\r
                                   mHiiConfigRouting,\r
                                   ConfigRequest,\r
     Status = mHiiConfigRouting->BlockToConfig (\r
                                   mHiiConfigRouting,\r
                                   ConfigRequest,\r
-                                  SourceBuf,\r
+                                  Storage->EditBuffer,\r
                                   Storage->Size,\r
                                   ConfigResp,\r
                                   &Progress\r
                                   Storage->Size,\r
                                   ConfigResp,\r
                                   &Progress\r
@@ -1106,11 +1024,7 @@ StorageToConfigResp (
         NewStringCat (ConfigResp, L"&");\r
         NewStringCat (ConfigResp, Node->Name);\r
         NewStringCat (ConfigResp, L"=");\r
         NewStringCat (ConfigResp, L"&");\r
         NewStringCat (ConfigResp, Node->Name);\r
         NewStringCat (ConfigResp, L"=");\r
-        if (GetEditBuf) {\r
-          NewStringCat (ConfigResp, Node->EditValue);\r
-        } else {\r
-          NewStringCat (ConfigResp, Node->Value);\r
-        }\r
+        NewStringCat (ConfigResp, Node->EditValue);\r
       }\r
       Link = GetNextNode (&Storage->NameValueListHead, Link);\r
     }\r
       }\r
       Link = GetNextNode (&Storage->NameValueListHead, Link);\r
     }\r
@@ -1191,7 +1105,7 @@ ConfigRespToStorage (
       if (StrPtr != NULL) {\r
         *StrPtr = 0;\r
       }\r
       if (StrPtr != NULL) {\r
         *StrPtr = 0;\r
       }\r
-      SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer, NULL);\r
+      SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer);\r
     }\r
     break;\r
 \r
     }\r
     break;\r
 \r
@@ -1617,7 +1531,7 @@ GetQuestionValue (
     if (IsBufferStorage) {\r
       CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
     } else {\r
     if (IsBufferStorage) {\r
       CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
     } else {\r
-      SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer, NULL);\r
+      SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer);\r
     }\r
 \r
     if (Result != NULL) {\r
     }\r
 \r
     if (Result != NULL) {\r
@@ -1667,10 +1581,8 @@ SetQuestionValue (
   CHAR16              *TemName;\r
   CHAR16              *TemString;\r
   UINTN               Index;\r
   CHAR16              *TemName;\r
   CHAR16              *TemString;\r
   UINTN               Index;\r
-  NAME_VALUE_NODE     *Node;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
   Status = EFI_SUCCESS;\r
-  Node   = NULL;\r
 \r
   if (SetValueTo >= GetSetValueWithMax) {\r
     return EFI_INVALID_PARAMETER;\r
 \r
   if (SetValueTo >= GetSetValueWithMax) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1805,14 +1717,6 @@ SetQuestionValue (
         //     \r
         CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
       }\r
         //     \r
         CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
       }\r
-      //\r
-      // Check whether question value has been changed.\r
-      //\r
-      if (CompareMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth) != 0) {\r
-        Question->ValueChanged = TRUE;\r
-      } else {\r
-        Question->ValueChanged = FALSE;\r
-      }\r
     } else {\r
       if (IsString) {\r
         //\r
     } else {\r
       if (IsString) {\r
         //\r
@@ -1844,19 +1748,8 @@ SetQuestionValue (
         }\r
       }\r
 \r
         }\r
       }\r
 \r
-      Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo, &Node);\r
+      Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo);\r
       FreePool (Value);\r
       FreePool (Value);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      //\r
-      // Check whether question value has been changed.\r
-      //\r
-      if (StrCmp (Node->Value, Node->EditValue) != 0) {\r
-        Question->ValueChanged = TRUE;\r
-      } else {\r
-        Question->ValueChanged = FALSE;\r
-      }\r
     }\r
   } else if (SetValueTo == GetSetValueWithHiiDriver) {\r
     if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
     }\r
   } else if (SetValueTo == GetSetValueWithHiiDriver) {\r
     if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
@@ -1975,12 +1868,12 @@ SetQuestionValue (
 \r
 \r
 /**\r
 \r
 \r
 /**\r
-  Perform nosubmitif check for a Form.\r
+  Perform inconsistent check for a Form.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Form                   Form data structure.\r
   @param  Question               The Question to be validated.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Form                   Form data structure.\r
   @param  Question               The Question to be validated.\r
-  @param  Type                   Validation type: NoSubmit\r
+  @param  Type                   Validation type: InConsistent or NoSubmit\r
 \r
   @retval EFI_SUCCESS            Form validation pass.\r
   @retval other                  Form validation failed.\r
 \r
   @retval EFI_SUCCESS            Form validation pass.\r
   @retval other                  Form validation failed.\r
@@ -1998,9 +1891,12 @@ ValidateQuestion (
   LIST_ENTRY              *Link;\r
   LIST_ENTRY              *ListHead;\r
   EFI_STRING              PopUp;\r
   LIST_ENTRY              *Link;\r
   LIST_ENTRY              *ListHead;\r
   EFI_STRING              PopUp;\r
+  EFI_INPUT_KEY           Key;\r
   FORM_EXPRESSION         *Expression;\r
 \r
   FORM_EXPRESSION         *Expression;\r
 \r
-  if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
+  if (Type == EFI_HII_EXPRESSION_INCONSISTENT_IF) {\r
+    ListHead = &Question->InconsistentListHead;\r
+  } else if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
     ListHead = &Question->NoSubmitListHead;\r
   } else {\r
     return EFI_UNSUPPORTED;\r
     ListHead = &Question->NoSubmitListHead;\r
   } else {\r
     return EFI_UNSUPPORTED;\r
@@ -2024,10 +1920,10 @@ ValidateQuestion (
       //\r
       if (Expression->Error != 0) {\r
         PopUp = GetToken (Expression->Error, FormSet->HiiHandle);\r
       //\r
       if (Expression->Error != 0) {\r
         PopUp = GetToken (Expression->Error, FormSet->HiiHandle);\r
-        if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
-          gBrowserStatus = BROWSER_NO_SUBMIT_IF;\r
-          gErrorInfo     = PopUp;\r
-        }\r
+        do {\r
+          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, PopUp, gPressEnter, gEmptyString);\r
+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+        FreePool (PopUp);\r
       }\r
 \r
       return EFI_NOT_READY;\r
       }\r
 \r
       return EFI_NOT_READY;\r
@@ -2091,8 +1987,7 @@ NoSubmitCheck (
   Fill storage's edit copy with settings requested from Configuration Driver.\r
 \r
   @param  FormSet                FormSet data structure.\r
   Fill storage's edit copy with settings requested from Configuration Driver.\r
 \r
   @param  FormSet                FormSet data structure.\r
-  @param  Storage                The storage which need to sync.\r
-  @param  ConfigRequest          The config request string which used to sync storage.\r
+  @param  ConfigInfo             The config info related to this form.\r
   @param  SyncOrRestore          Sync the buffer to editbuffer or Restore  the \r
                                  editbuffer to buffer\r
                                  if TRUE, copy the editbuffer to the buffer.\r
   @param  SyncOrRestore          Sync the buffer to editbuffer or Restore  the \r
                                  editbuffer to buffer\r
                                  if TRUE, copy the editbuffer to the buffer.\r
@@ -2102,11 +1997,10 @@ NoSubmitCheck (
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-SynchronizeStorage (\r
-  IN  FORM_BROWSER_FORMSET        *FormSet,\r
-  OUT BROWSER_STORAGE             *Storage,\r
-  IN  CHAR16                      *ConfigRequest,\r
-  IN  BOOLEAN                     SyncOrRestore\r
+SynchronizeStorageForForm (\r
+  IN FORM_BROWSER_FORMSET        *FormSet,\r
+  IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo,\r
+  IN BOOLEAN                     SyncOrRestore\r
   )\r
 {\r
   EFI_STATUS              Status;\r
   )\r
 {\r
   EFI_STATUS              Status;\r
@@ -2120,52 +2014,57 @@ SynchronizeStorage (
 \r
   Status = EFI_SUCCESS;\r
   Result = NULL;\r
 \r
   Status = EFI_SUCCESS;\r
   Result = NULL;\r
+  if (FormSet->ConfigAccess == NULL && ConfigInfo->Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
 \r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
-      (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
-    BufferSize = Storage->Size;\r
+  if (ConfigInfo->ElementCount == 0) {\r
+    //\r
+    // Skip if there is no RequestElement\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
+      (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+    BufferSize = ConfigInfo->Storage->Size;\r
 \r
     if (SyncOrRestore) {\r
 \r
     if (SyncOrRestore) {\r
-      Src = Storage->EditBuffer;\r
-      Dst = Storage->Buffer;\r
+      Src = ConfigInfo->Storage->EditBuffer;\r
+      Dst = ConfigInfo->Storage->Buffer;\r
     } else {\r
     } else {\r
-      Src = Storage->Buffer;\r
-      Dst = Storage->EditBuffer;\r
+      Src = ConfigInfo->Storage->Buffer;\r
+      Dst = ConfigInfo->Storage->EditBuffer;\r
     }\r
 \r
     }\r
 \r
-    if (ConfigRequest != NULL) {\r
-      Status = mHiiConfigRouting->BlockToConfig(\r
-                                    mHiiConfigRouting,\r
-                                    ConfigRequest,\r
-                                    Src,\r
-                                    BufferSize,\r
-                                    &Result,\r
-                                    &Progress\r
-                                    );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
+    Status = mHiiConfigRouting->BlockToConfig(\r
+                                  mHiiConfigRouting,\r
+                                  ConfigInfo->ConfigRequest,\r
+                                  Src,\r
+                                  BufferSize,\r
+                                  &Result,\r
+                                  &Progress\r
+                                  );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
 \r
-      Status = mHiiConfigRouting->ConfigToBlock (\r
-                                    mHiiConfigRouting,\r
-                                    Result,\r
-                                    Dst,\r
-                                    &BufferSize,\r
-                                    &Progress\r
-                                    );\r
-      if (Result != NULL) {\r
-        FreePool (Result);\r
-      }\r
-    } else {\r
-      CopyMem (Dst, Src, BufferSize);\r
+    Status = mHiiConfigRouting->ConfigToBlock (\r
+                                  mHiiConfigRouting,\r
+                                  Result,\r
+                                  Dst,\r
+                                  &BufferSize,\r
+                                  &Progress\r
+                                  );\r
+    if (Result != NULL) {\r
+      FreePool (Result);\r
     }\r
     }\r
-  } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-    Link = GetFirstNode (&Storage->NameValueListHead);\r
-    while (!IsNull (&Storage->NameValueListHead, Link)) {\r
+  } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);\r
+    while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {\r
       Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
 \r
       Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
 \r
-      if ((ConfigRequest != NULL && StrStr (ConfigRequest, Node->Name) != NULL) ||\r
-          (ConfigRequest == NULL)) {\r
+      if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {\r
         if (SyncOrRestore) {\r
           NewStringCpy (&Node->Value, Node->EditValue);\r
         } else {\r
         if (SyncOrRestore) {\r
           NewStringCpy (&Node->Value, Node->EditValue);\r
         } else {\r
@@ -2173,7 +2072,7 @@ SynchronizeStorage (
         }\r
       }\r
 \r
         }\r
       }\r
 \r
-      Link = GetNextNode (&Storage->NameValueListHead, Link);\r
+      Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);\r
     }\r
   }\r
 \r
     }\r
   }\r
 \r
@@ -2196,9 +2095,20 @@ SendDiscardInfoToDriver (
 {\r
   LIST_ENTRY                  *Link;\r
   FORM_BROWSER_STATEMENT      *Question;\r
 {\r
   LIST_ENTRY                  *Link;\r
   FORM_BROWSER_STATEMENT      *Question;\r
+  EFI_STATUS                  Status;\r
+  EFI_HII_VALUE               HiiValue;\r
+  UINT8                       *BufferValue;\r
+  BOOLEAN                     ValueChanged;\r
   EFI_IFR_TYPE_VALUE          *TypeValue;\r
   EFI_BROWSER_ACTION_REQUEST  ActionRequest;\r
 \r
   EFI_IFR_TYPE_VALUE          *TypeValue;\r
   EFI_BROWSER_ACTION_REQUEST  ActionRequest;\r
 \r
+  ValueChanged = FALSE;\r
+  BufferValue  = NULL;\r
+\r
+  if(!Form->NvUpdateRequired) {\r
+    return;\r
+  }\r
+\r
   Link = GetFirstNode (&Form->StatementListHead);\r
   while (!IsNull (&Form->StatementListHead, Link)) {\r
     Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
   Link = GetFirstNode (&Form->StatementListHead);\r
   while (!IsNull (&Form->StatementListHead, Link)) {\r
     Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
@@ -2212,10 +2122,45 @@ SendDiscardInfoToDriver (
       continue;\r
     }\r
 \r
       continue;\r
     }\r
 \r
-    if (!Question->ValueChanged) {\r
+    if (Question->BufferValue != NULL) {\r
+      BufferValue = AllocateZeroPool (Question->StorageWidth);\r
+      ASSERT (BufferValue != NULL);\r
+      CopyMem (BufferValue, Question->BufferValue, Question->StorageWidth);\r
+    } else {\r
+      HiiValue.Type = Question->HiiValue.Type;\r
+      CopyMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+    }\r
+\r
+    Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);\r
+    if (EFI_ERROR (Status)) {\r
+      if (BufferValue != NULL) {\r
+        FreePool (BufferValue);\r
+        BufferValue = NULL;\r
+      }\r
+      continue;\r
+    }\r
+\r
+    if (Question->BufferValue != NULL) {\r
+      if (CompareMem (BufferValue, Question->BufferValue, Question->StorageWidth)) {\r
+        ValueChanged = TRUE;\r
+      }\r
+    } else {\r
+      if (CompareMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE))) {\r
+        ValueChanged = TRUE;\r
+      }\r
+    }\r
+\r
+    if (BufferValue != NULL) {\r
+      FreePool (BufferValue);\r
+      BufferValue = NULL;\r
+    }\r
+\r
+    if (!ValueChanged) {\r
       continue;\r
     }\r
 \r
       continue;\r
     }\r
 \r
+    ValueChanged = FALSE;\r
+\r
     if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
       TypeValue = (EFI_IFR_TYPE_VALUE *) Question->BufferValue;\r
     } else {\r
     if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {\r
       TypeValue = (EFI_IFR_TYPE_VALUE *) Question->BufferValue;\r
     } else {\r
@@ -2280,78 +2225,6 @@ ValidateFormSet (
 \r
   return Find;\r
 }\r
 \r
   return Find;\r
 }\r
-/**\r
-  Check whether need to enable the reset flag in form level.\r
-  Also clean all ValueChanged flag in question.\r
-\r
-  @param  SetFlag                Whether need to set the Reset Flag.\r
-  @param  Form                   Form data structure.\r
-\r
-**/\r
-VOID\r
-UpdateFlagForForm (\r
-  IN BOOLEAN                          SetFlag,\r
-  IN FORM_BROWSER_FORM                *Form\r
-  )\r
-{\r
-  LIST_ENTRY              *Link;\r
-  FORM_BROWSER_STATEMENT  *Question;\r
-  BOOLEAN                 FindOne;\r
-\r
-  FindOne = FALSE;\r
-  Link = GetFirstNode (&Form->StatementListHead);\r
-  while (!IsNull (&Form->StatementListHead, Link)) {\r
-    Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-  \r
-    if (SetFlag && Question->ValueChanged && ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {\r
-      gResetRequired = TRUE;\r
-    } \r
-\r
-    if (Question->ValueChanged) {\r
-      Question->ValueChanged = FALSE;\r
-    }\r
-  \r
-    Link = GetNextNode (&Form->StatementListHead, Link);\r
-  }\r
-}\r
-\r
-/**\r
-  Check whether need to enable the reset flag.\r
-  Also clean ValueChanged flag for all statements.\r
-\r
-  Form level or formset level, only one.\r
-  \r
-  @param  SetFlag                Whether need to set the Reset Flag.\r
-  @param  FormSet                FormSet data structure.\r
-  @param  Form                   Form data structure.\r
-\r
-**/\r
-VOID\r
-ValueChangeResetFlagUpdate (\r
-  IN BOOLEAN                          SetFlag,\r
-  IN FORM_BROWSER_FORMSET             *FormSet,\r
-  IN FORM_BROWSER_FORM                *Form  \r
-  )\r
-{\r
-  FORM_BROWSER_FORM       *CurrentForm;\r
-  LIST_ENTRY              *Link;\r
-\r
-  //\r
-  // Form != NULL means only check form level.\r
-  //\r
-  if (Form != NULL) {\r
-    UpdateFlagForForm(SetFlag, Form);\r
-    return;\r
-  }\r
-\r
-  Link = GetFirstNode (&FormSet->FormListHead);\r
-  while (!IsNull (&FormSet->FormListHead, Link)) {\r
-    CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);\r
-    Link = GetNextNode (&FormSet->FormListHead, Link);\r
-\r
-    UpdateFlagForForm(SetFlag, CurrentForm);\r
-  }\r
-}\r
 \r
 /**\r
   Discard data based on the input setting scope (Form, FormSet or System).\r
 \r
 /**\r
   Discard data based on the input setting scope (Form, FormSet or System).\r
@@ -2383,7 +2256,7 @@ DiscardForm (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {\r
+  if (SettingScope == FormLevel && Form->NvUpdateRequired) {\r
     ConfigInfo = NULL;\r
     Link = GetFirstNode (&Form->ConfigRequestHead);\r
     while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
     ConfigInfo = NULL;\r
     Link = GetFirstNode (&Form->ConfigRequestHead);\r
     while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
@@ -2404,7 +2277,7 @@ DiscardForm (
       //\r
       // Prepare <ConfigResp>\r
       //\r
       //\r
       // Prepare <ConfigResp>\r
       //\r
-      SynchronizeStorage(FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);\r
+      SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);\r
 \r
       //\r
       // Call callback with Changed type to inform the driver.\r
 \r
       //\r
       // Call callback with Changed type to inform the driver.\r
@@ -2412,8 +2285,8 @@ DiscardForm (
       SendDiscardInfoToDriver (FormSet, Form);\r
     }\r
 \r
       SendDiscardInfoToDriver (FormSet, Form);\r
     }\r
 \r
-    ValueChangeResetFlagUpdate (FALSE, NULL, Form);\r
-  } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {\r
+    Form->NvUpdateRequired = FALSE;\r
+  } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
 \r
     //\r
     // Discard Buffer storage or Name/Value storage\r
 \r
     //\r
     // Discard Buffer storage or Name/Value storage\r
@@ -2434,7 +2307,7 @@ DiscardForm (
         continue;\r
       }\r
 \r
         continue;\r
       }\r
 \r
-      SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigRequest, FALSE);\r
+      SynchronizeStorage(Storage->BrowserStorage, FALSE);\r
     }\r
 \r
     Link = GetFirstNode (&FormSet->FormListHead);\r
     }\r
 \r
     Link = GetFirstNode (&FormSet->FormListHead);\r
@@ -2448,7 +2321,7 @@ DiscardForm (
       SendDiscardInfoToDriver (FormSet, Form);\r
     }\r
 \r
       SendDiscardInfoToDriver (FormSet, Form);\r
     }\r
 \r
-    ValueChangeResetFlagUpdate(FALSE, FormSet, NULL);\r
+    UpdateNvInfoInForm (FormSet, FALSE);   \r
   } else if (SettingScope == SystemLevel) {\r
     //\r
     // System Level Discard.\r
   } else if (SettingScope == SystemLevel) {\r
     //\r
     // System Level Discard.\r
@@ -2528,7 +2401,7 @@ SubmitForm (
     return Status;\r
   }\r
 \r
     return Status;\r
   }\r
 \r
-  if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {\r
+  if (SettingScope == FormLevel && Form->NvUpdateRequired) {\r
     ConfigInfo = NULL;\r
     Link = GetFirstNode (&Form->ConfigRequestHead);\r
     while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
     ConfigInfo = NULL;\r
     Link = GetFirstNode (&Form->ConfigRequestHead);\r
     while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
@@ -2550,7 +2423,7 @@ SubmitForm (
       //\r
       // 1. Prepare <ConfigResp>\r
       //\r
       //\r
       // 1. Prepare <ConfigResp>\r
       //\r
-      Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest, TRUE);\r
+      Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
@@ -2626,14 +2499,14 @@ SubmitForm (
       //\r
       // 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
       //\r
       //\r
       // 3. Config success, update storage shadow Buffer, only update the data belong to this form.\r
       //\r
-      SynchronizeStorage (FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);\r
+      SynchronizeStorageForForm(FormSet, ConfigInfo, TRUE);\r
     }\r
 \r
     //\r
     // 4. Update the NV flag.\r
     // \r
     }\r
 \r
     //\r
     // 4. Update the NV flag.\r
     // \r
-    ValueChangeResetFlagUpdate(TRUE, NULL, Form);\r
-  } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {\r
+    Form->NvUpdateRequired = FALSE;\r
+  } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {\r
     //\r
     // Submit Buffer storage or Name/Value storage\r
     //\r
     //\r
     // Submit Buffer storage or Name/Value storage\r
     //\r
@@ -2657,7 +2530,7 @@ SubmitForm (
       //\r
       // 1. Prepare <ConfigResp>\r
       //\r
       //\r
       // 1. Prepare <ConfigResp>\r
       //\r
-      Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest, TRUE);\r
+      Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest);\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
@@ -2729,13 +2602,13 @@ SubmitForm (
       //\r
       // 3. Config success, update storage shadow Buffer\r
       //\r
       //\r
       // 3. Config success, update storage shadow Buffer\r
       //\r
-      SynchronizeStorage (FormSet, Storage, FormSetStorage->ConfigRequest, TRUE);\r
+      SynchronizeStorage (Storage, TRUE);\r
     }\r
 \r
     //\r
     // 4. Update the NV flag.\r
     // \r
     }\r
 \r
     //\r
     // 4. Update the NV flag.\r
     // \r
-    ValueChangeResetFlagUpdate(TRUE, FormSet, NULL);\r
+    UpdateNvInfoInForm (FormSet, FALSE);\r
   } else if (SettingScope == SystemLevel) {\r
     //\r
     // System Level Save.\r
   } else if (SettingScope == SystemLevel) {\r
     //\r
     // System Level Save.\r
@@ -2931,198 +2804,66 @@ GetDefaultValueFromAltCfg (
     //\r
     // Add tailing L'\0' character\r
     //\r
     //\r
     // Add tailing L'\0' character\r
     //\r
-    StringPtr[Index/4] = L'\0';\r
-  } else {\r
-    ZeroMem (TemStr, sizeof (TemStr));\r
-    for (Index = 0; Index < LengthStr; Index ++) {\r
-      TemStr[0] = Value[LengthStr - Index - 1];\r
-      DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
-      if ((Index & 1) == 0) {\r
-        Dst [Index/2] = DigitUint8;\r
-      } else {\r
-        Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
-      }\r
-    }\r
-  }\r
-\r
-Done:\r
-  if (ConfigRequest != NULL){\r
-    FreePool (ConfigRequest);\r
-  }\r
-\r
-  if (ConfigResp != NULL) {\r
-    FreePool (ConfigResp);\r
-  }\r
-  \r
-  if (Result != NULL) {\r
-    FreePool (Result);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get default Id value used for browser.\r
-\r
-  @param  DefaultId              The default id value used by hii.\r
-\r
-  @retval Browser used default value.\r
-\r
-**/\r
-INTN\r
-GetDefaultIdForCallBack (\r
-  UINTN DefaultId\r
-  )\r
-{ \r
-  if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
-    return EFI_BROWSER_ACTION_DEFAULT_STANDARD;\r
-  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
-    return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;\r
-  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {\r
-    return EFI_BROWSER_ACTION_DEFAULT_SAFE;\r
-  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000) {\r
-    return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;\r
-  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000) {\r
-    return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;\r
-  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000) {\r
-    return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;\r
-  } else {\r
-    return -1;\r
-  }\r
-}\r
-\r
-\r
-\r
-/**\r
-  Return data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-\r
-  @retval Value                  The data to be returned\r
-\r
-**/\r
-UINT64\r
-GetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index\r
-  )\r
-{\r
-  UINT64 Data;\r
-\r
-  ASSERT (Array != NULL);\r
-\r
-  Data = 0;\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    Data = (UINT64) *(((UINT8 *) Array) + Index);\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    Data = (UINT64) *(((UINT16 *) Array) + Index);\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    Data = (UINT64) *(((UINT32 *) Array) + Index);\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    Data = (UINT64) *(((UINT64 *) Array) + Index);\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return Data;\r
-}\r
-\r
-\r
-/**\r
-  Set value of a data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-  @param  Value                  The value to be set.\r
-\r
-**/\r
-VOID\r
-SetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index,\r
-  IN UINT64                   Value\r
-  )\r
-{\r
-\r
-  ASSERT (Array != NULL);\r
-\r
-  switch (Type) {\r
-  case EFI_IFR_TYPE_NUM_SIZE_8:\r
-    *(((UINT8 *) Array) + Index) = (UINT8) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_16:\r
-    *(((UINT16 *) Array) + Index) = (UINT16) Value;\r
-    break;\r
-\r
-  case EFI_IFR_TYPE_NUM_SIZE_32:\r
-    *(((UINT32 *) Array) + Index) = (UINT32) Value;\r
-    break;\r
+    StringPtr[Index/4] = L'\0';\r
+  } else {\r
+    ZeroMem (TemStr, sizeof (TemStr));\r
+    for (Index = 0; Index < LengthStr; Index ++) {\r
+      TemStr[0] = Value[LengthStr - Index - 1];\r
+      DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+      if ((Index & 1) == 0) {\r
+        Dst [Index/2] = DigitUint8;\r
+      } else {\r
+        Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
+      }\r
+    }\r
+  }\r
 \r
 \r
-  case EFI_IFR_TYPE_NUM_SIZE_64:\r
-    *(((UINT64 *) Array) + Index) = (UINT64) Value;\r
-    break;\r
+Done:\r
+  if (ConfigRequest != NULL){\r
+    FreePool (ConfigRequest);\r
+  }\r
 \r
 \r
-  default:\r
-    break;\r
+  if (ConfigResp != NULL) {\r
+    FreePool (ConfigResp);\r
+  }\r
+  \r
+  if (Result != NULL) {\r
+    FreePool (Result);\r
   }\r
   }\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Search an Option of a Question by its value.\r
+  Get default Id value used for browser.\r
 \r
 \r
-  @param  Question               The Question\r
-  @param  OptionValue            Value for Option to be searched.\r
+  @param  DefaultId              The default id value used by hii.\r
 \r
 \r
-  @retval Pointer                Pointer to the found Option.\r
-  @retval NULL                   Option not found.\r
+  @retval Browser used default value.\r
 \r
 **/\r
 \r
 **/\r
-QUESTION_OPTION *\r
-ValueToOption (\r
-  IN FORM_BROWSER_STATEMENT   *Question,\r
-  IN EFI_HII_VALUE            *OptionValue\r
+INTN\r
+GetDefaultIdForCallBack (\r
+  UINTN DefaultId\r
   )\r
   )\r
-{\r
-  LIST_ENTRY       *Link;\r
-  QUESTION_OPTION  *Option;\r
-  INTN             Result;\r
-\r
-  Link = GetFirstNode (&Question->OptionListHead);\r
-  while (!IsNull (&Question->OptionListHead, Link)) {\r
-    Option = QUESTION_OPTION_FROM_LINK (Link);\r
-\r
-    if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {\r
-      //\r
-      // Check the suppressif condition, only a valid option can be return.\r
-      //\r
-      if ((Option->SuppressExpression == NULL) ||\r
-          ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {\r
-        return Option;\r
-      }\r
-    }\r
-\r
-    Link = GetNextNode (&Question->OptionListHead, Link);\r
+{ \r
+  if (DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_STANDARD;\r
+  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING;\r
+  } else if (DefaultId == EFI_HII_DEFAULT_CLASS_SAFE) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_SAFE;\r
+  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN + 0x1000) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_PLATFORM + DefaultId - EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN;\r
+  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN + 0x1000) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_HARDWARE + DefaultId - EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN;\r
+  } else if (DefaultId >= EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN && DefaultId < EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN + 0x1000) {\r
+    return EFI_BROWSER_ACTION_DEFAULT_FIRMWARE + DefaultId - EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN;\r
+  } else {\r
+    return -1;\r
   }\r
   }\r
-\r
-  return NULL;\r
 }\r
 \r
 }\r
 \r
-\r
 /**\r
   Reset Question to its default value.\r
 \r
 /**\r
   Reset Question to its default value.\r
 \r
@@ -3414,7 +3155,11 @@ ExtractDefault (
   LIST_ENTRY              *FormLink;\r
   LIST_ENTRY              *Link;\r
   FORM_BROWSER_STATEMENT  *Question;\r
   LIST_ENTRY              *FormLink;\r
   LIST_ENTRY              *Link;\r
   FORM_BROWSER_STATEMENT  *Question;\r
+  FORM_BROWSER_FORMSET    *BackUpFormSet;\r
   FORM_BROWSER_FORMSET    *LocalFormSet;\r
   FORM_BROWSER_FORMSET    *LocalFormSet;\r
+  EFI_HII_HANDLE          *HiiHandles;\r
+  UINTN                   Index;\r
+  EFI_GUID                ZeroGuid;\r
 \r
   Status = EFI_SUCCESS;\r
 \r
 \r
   Status = EFI_SUCCESS;\r
 \r
@@ -3484,6 +3229,10 @@ ExtractDefault (
       if ((Question->Storage != NULL) &&\r
           (Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
         SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
       if ((Question->Storage != NULL) &&\r
           (Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
         SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
+        //\r
+        // Update Form NV flag.\r
+        //\r
+        Form->NvUpdateRequired = TRUE;\r
       }\r
     }\r
   } else if (SettingScope == FormSetLevel) {\r
       }\r
     }\r
   } else if (SettingScope == FormSetLevel) {\r
@@ -3495,9 +3244,65 @@ ExtractDefault (
     }\r
   } else if (SettingScope == SystemLevel) {\r
     //\r
     }\r
   } else if (SettingScope == SystemLevel) {\r
     //\r
-    // Preload all Hii formset.\r
+    // Open all FormSet by locate HII packages.\r
+    // Initiliaze the maintain FormSet to store default data as back up data.\r
+    //\r
+    BackUpFormSet    = gOldFormSet;\r
+    gOldFormSet      = NULL;\r
+\r
+    //\r
+    // Get all the Hii handles\r
+    //\r
+    HiiHandles = HiiGetHiiHandles (NULL);\r
+    ASSERT (HiiHandles != NULL);\r
+\r
+    //\r
+    // Search for formset of each class type\r
+    //\r
+    for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+      //\r
+      // Check HiiHandles[Index] does exist in global maintain list. \r
+      //\r
+      if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {\r
+        continue;\r
+      }\r
+      \r
+      //\r
+      // Initilize FormSet Setting\r
+      //\r
+      LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
+      ASSERT (LocalFormSet != NULL);\r
+      ZeroMem (&ZeroGuid, sizeof (ZeroGuid));\r
+      Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet, FALSE);\r
+      if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {\r
+        DestroyFormSet (LocalFormSet);\r
+        continue;\r
+      }\r
+      Status = InitializeCurrentSetting (LocalFormSet);\r
+      if (EFI_ERROR (Status)) {\r
+        DestroyFormSet (LocalFormSet);\r
+        continue;\r
+      }\r
+      //\r
+      // Initilize Questions' Value\r
+      //\r
+      Status = LoadFormSetConfig (NULL, LocalFormSet);\r
+      if (EFI_ERROR (Status)) {\r
+        DestroyFormSet (LocalFormSet);\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Add FormSet into the maintain list.\r
+      //\r
+      InsertTailList (&gBrowserFormSetList, &LocalFormSet->Link);\r
+    }\r
+    \r
+    //\r
+    // Free resources, and restore gOldFormSet and gClassOfVfr\r
     //\r
     //\r
-    LoadAllHiiFormset();\r
+    FreePool (HiiHandles);\r
+    gOldFormSet = BackUpFormSet;\r
        \r
     //\r
     // Set Default Value for each FormSet in the maintain list.\r
        \r
     //\r
     // Set Default Value for each FormSet in the maintain list.\r
@@ -3516,81 +3321,6 @@ ExtractDefault (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-/**\r
-  Validate whether this question's value has changed.\r
-\r
-  @param  FormSet                FormSet data structure.\r
-  @param  Form                   Form data structure.\r
-  @param  Question               Question to be initialized.\r
-  @param  GetValueFrom           Where to get value, may from editbuffer, buffer or hii driver.\r
-\r
-  @retval TRUE                   Question's value has changed.\r
-  @retval FALSE                  Question's value has not changed\r
-\r
-**/\r
-BOOLEAN\r
-IsQuestionValueChanged (\r
-  IN FORM_BROWSER_FORMSET             *FormSet,\r
-  IN FORM_BROWSER_FORM                *Form,\r
-  IN OUT FORM_BROWSER_STATEMENT       *Question,\r
-  IN GET_SET_QUESTION_VALUE_WITH      GetValueFrom\r
-  )\r
-{\r
-  EFI_HII_VALUE    BackUpValue;\r
-  CHAR8            *BackUpBuffer;\r
-  EFI_STATUS       Status;\r
-  BOOLEAN          ValueChanged;\r
-  UINTN            BufferWidth;\r
-\r
-  //\r
-  // For quetion without storage, always mark it as data not changed.\r
-  //\r
-  if (Question->Storage == NULL && Question->Operand != EFI_IFR_TIME_OP && Question->Operand != EFI_IFR_DATE_OP) {\r
-    return FALSE;\r
-  }\r
-\r
-  BackUpBuffer = NULL;\r
-  ValueChanged = FALSE;\r
-\r
-  switch (Question->Operand) {\r
-    case EFI_IFR_ORDERED_LIST_OP:\r
-      BufferWidth  = Question->StorageWidth;\r
-      BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
-      ASSERT (BackUpBuffer != NULL);\r
-      break;\r
-\r
-    case EFI_IFR_STRING_OP:\r
-    case EFI_IFR_PASSWORD_OP:\r
-      BufferWidth  = (UINTN) Question->Maximum * sizeof (CHAR16);\r
-      BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);\r
-      ASSERT (BackUpBuffer != NULL);\r
-      break;\r
-\r
-    default:\r
-      BufferWidth = 0;\r
-      break;\r
-  }\r
-  CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
-\r
-  Status = GetQuestionValue (FormSet, Form, Question, GetValueFrom);\r
-  ASSERT_EFI_ERROR(Status);\r
-\r
-  if (CompareMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0 ||\r
-      CompareMem (BackUpBuffer, Question->BufferValue, BufferWidth) != 0) {\r
-    ValueChanged = TRUE;\r
-  }\r
-\r
-  CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
-  CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);\r
-\r
-  if (BackUpBuffer != NULL) {\r
-    FreePool (BackUpBuffer);\r
-  }\r
-\r
-  return ValueChanged;\r
-}\r
-\r
 /**\r
   Initialize Question's Edit copy from Storage.\r
 \r
 /**\r
   Initialize Question's Edit copy from Storage.\r
 \r
@@ -3624,11 +3354,7 @@ LoadFormConfig (
     //\r
     // Initialize local copy of Value for each Question\r
     //\r
     //\r
     // Initialize local copy of Value for each Question\r
     //\r
-    if (Question->Operand == EFI_IFR_PASSWORD_OP && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)== 0) {\r
-      Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);\r
-    } else {\r
-      Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
-    }\r
+    Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -3668,11 +3394,6 @@ LoadFormConfig (
       Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
     }\r
 \r
       Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
     }\r
 \r
-    //\r
-    // Update Question Value changed flag.\r
-    //\r
-    Question->ValueChanged = IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);\r
-\r
     Link = GetNextNode (&Form->StatementListHead, Link);\r
   }\r
 \r
     Link = GetNextNode (&Form->StatementListHead, Link);\r
   }\r
 \r
@@ -3716,11 +3437,6 @@ LoadFormSetConfig (
     Link = GetNextNode (&FormSet->FormListHead, Link);\r
   }\r
 \r
     Link = GetNextNode (&FormSet->FormListHead, Link);\r
   }\r
 \r
-  //\r
-  // Finished question initialization.\r
-  // \r
-  FormSet->QuestionInited = TRUE;\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -3775,13 +3491,6 @@ RemoveConfigRequest (
   CHAR16       *NextRequestElement;\r
   CHAR16       *SearchKey;\r
 \r
   CHAR16       *NextRequestElement;\r
   CHAR16       *SearchKey;\r
 \r
-  //\r
-  // No request element in it, just return.\r
-  //\r
-  if (ConfigRequest == NULL) {\r
-    return;\r
-  }\r
-\r
   if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
     //\r
     // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
   if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
     //\r
     // "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage\r
@@ -3856,7 +3565,6 @@ CleanBrowserStorage (
 {\r
   LIST_ENTRY            *Link;\r
   FORMSET_STORAGE       *Storage;\r
 {\r
   LIST_ENTRY            *Link;\r
   FORMSET_STORAGE       *Storage;\r
-  CHAR16                *ConfigRequest;\r
 \r
   Link = GetFirstNode (&FormSet->StorageListHead);\r
   while (!IsNull (&FormSet->StorageListHead, Link)) {\r
 \r
   Link = GetFirstNode (&FormSet->StorageListHead);\r
   while (!IsNull (&FormSet->StorageListHead, Link)) {\r
@@ -3864,8 +3572,7 @@ CleanBrowserStorage (
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
 \r
     if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) && \r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
 \r
     if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) && \r
-        (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) && \r
-        (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
+        (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE)) {\r
       continue;\r
     }\r
 \r
       continue;\r
     }\r
 \r
@@ -3873,8 +3580,7 @@ CleanBrowserStorage (
       continue;\r
     }\r
 \r
       continue;\r
     }\r
 \r
-    ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;\r
-    RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);\r
+    RemoveConfigRequest (Storage->BrowserStorage, Storage->ConfigRequest);\r
   }\r
 }\r
 \r
   }\r
 }\r
 \r
@@ -3945,6 +3651,7 @@ AppendConfigRequest (
   Adjust the config request info, remove the request elements which already in AllConfigRequest string.\r
 \r
   @param  Storage                Form set Storage.\r
   Adjust the config request info, remove the request elements which already in AllConfigRequest string.\r
 \r
   @param  Storage                Form set Storage.\r
+  @param  ConfigRequest          Return the ConfigRequest info.\r
 \r
   @retval TRUE                   Has element not covered by current used elements, need to continue to call ExtractConfig\r
   @retval FALSE                  All elements covered by current used elements.\r
 \r
   @retval TRUE                   Has element not covered by current used elements, need to continue to call ExtractConfig\r
   @retval FALSE                  All elements covered by current used elements.\r
@@ -3952,7 +3659,8 @@ AppendConfigRequest (
 **/\r
 BOOLEAN \r
 ConfigRequestAdjust (\r
 **/\r
 BOOLEAN \r
 ConfigRequestAdjust (\r
-  IN  FORMSET_STORAGE         *Storage\r
+  IN  FORMSET_STORAGE         *Storage,\r
+  OUT CHAR16                  **ConfigRequest\r
   )\r
 {\r
   CHAR16       *RequestElement;\r
   )\r
 {\r
   CHAR16       *RequestElement;\r
@@ -3968,10 +3676,7 @@ ConfigRequestAdjust (
 \r
   if (Storage->BrowserStorage->ConfigRequest == NULL) {\r
     Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
 \r
   if (Storage->BrowserStorage->ConfigRequest == NULL) {\r
     Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
-    if (Storage->ConfigElements != NULL) {\r
-      FreePool (Storage->ConfigElements);\r
-    }\r
-    Storage->ConfigElements = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
+    *ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
     return TRUE;\r
   }\r
 \r
     return TRUE;\r
   }\r
 \r
@@ -4040,10 +3745,7 @@ ConfigRequestAdjust (
   }\r
 \r
   if (RetVal) {\r
   }\r
 \r
   if (RetVal) {\r
-    if (Storage->ConfigElements != NULL) {\r
-      FreePool (Storage->ConfigElements);\r
-    }\r
-    Storage->ConfigElements = RetBuf;\r
+    *ConfigRequest = RetBuf;\r
   } else {\r
     FreePool (RetBuf);\r
   }\r
   } else {\r
     FreePool (RetBuf);\r
   }\r
@@ -4051,163 +3753,16 @@ ConfigRequestAdjust (
   return RetVal;\r
 }\r
 \r
   return RetVal;\r
 }\r
 \r
-/**\r
-\r
-  Base on ConfigRequest info to get default value for current formset. \r
-\r
-  ConfigRequest info include the info about which questions in current formset need to \r
-  get default value. This function only get these questions default value.\r
-  \r
-  @param  FormSet                FormSet data structure.\r
-  @param  Storage                Storage need to update value.\r
-  @param  ConfigRequest          The config request string.\r
-\r
-**/\r
-VOID\r
-GetDefaultForFormset (\r
-  IN FORM_BROWSER_FORMSET    *FormSet,\r
-  IN BROWSER_STORAGE         *Storage,\r
-  IN CHAR16                  *ConfigRequest\r
-  )\r
-{\r
-  UINT8             *BackUpBuf;\r
-  UINTN             BufferSize;\r
-  LIST_ENTRY        BackUpList;\r
-  NAME_VALUE_NODE   *Node;\r
-  LIST_ENTRY        *Link;\r
-  LIST_ENTRY        *NodeLink;\r
-  NAME_VALUE_NODE   *TmpNode;\r
-  EFI_STATUS        Status;\r
-  EFI_STRING        Progress;\r
-  EFI_STRING        Result;\r
-\r
-  BackUpBuf = NULL;\r
-  InitializeListHead(&BackUpList);\r
-\r
-  //\r
-  // Back update the edit buffer.\r
-  // \r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
-      (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
-    BackUpBuf = AllocateCopyPool (Storage->Size, Storage->EditBuffer);\r
-    ASSERT (BackUpBuf != NULL);\r
-  } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-    Link = GetFirstNode (&Storage->NameValueListHead);\r
-    while (!IsNull (&Storage->NameValueListHead, Link)) {\r
-      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
-      Link = GetNextNode (&Storage->NameValueListHead, Link);\r
-\r
-      //\r
-      // Only back Node belong to this formset.\r
-      //\r
-      if (StrStr (Storage->ConfigRequest, Node->Name) == NULL) {\r
-        continue;\r
-      }\r
-\r
-      TmpNode = AllocateCopyPool (sizeof (NAME_VALUE_NODE), Node);\r
-      TmpNode->Name = AllocateCopyPool (StrSize(Node->Name) * sizeof (CHAR16), Node->Name);\r
-      TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);\r
-\r
-      InsertTailList(&BackUpList, &TmpNode->Link);\r
-    }\r
-  }\r
-\r
-  //\r
-  // Get default value.\r
-  //\r
-  ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage, TRUE);\r
-\r
-  //\r
-  // Update the question value based on the input ConfigRequest.\r
-  //\r
-  if (Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
-      (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {\r
-    ASSERT (BackUpBuf != NULL);\r
-    BufferSize = Storage->Size;\r
-    Status = mHiiConfigRouting->BlockToConfig(\r
-                                  mHiiConfigRouting,\r
-                                  ConfigRequest,\r
-                                  Storage->EditBuffer,\r
-                                  BufferSize,\r
-                                  &Result,\r
-                                  &Progress\r
-                                  );\r
-    ASSERT_EFI_ERROR (Status);\r
-    \r
-    Status = mHiiConfigRouting->ConfigToBlock (\r
-                                  mHiiConfigRouting,\r
-                                  Result,\r
-                                  BackUpBuf,\r
-                                  &BufferSize,\r
-                                  &Progress\r
-                                  );\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    if (Result != NULL) {\r
-      FreePool (Result);\r
-    }\r
-    \r
-    CopyMem (Storage->EditBuffer, BackUpBuf, Storage->Size);\r
-    FreePool (BackUpBuf);\r
-  } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
-    //\r
-    // Update question value, only element in ConfigReqeust will be update.\r
-    //\r
-    Link = GetFirstNode (&BackUpList);\r
-    while (!IsNull (&BackUpList, Link)) {\r
-      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
-      Link = GetNextNode (&BackUpList, Link);\r
-\r
-      if (StrStr (ConfigRequest, Node->Name) != NULL) {\r
-        continue;\r
-      }\r
-\r
-      NodeLink = GetFirstNode (&Storage->NameValueListHead);\r
-      while (!IsNull (&Storage->NameValueListHead, NodeLink)) {\r
-        TmpNode  = NAME_VALUE_NODE_FROM_LINK (NodeLink);\r
-        NodeLink = GetNextNode (&Storage->NameValueListHead, NodeLink);\r
-      \r
-        if (StrCmp (Node->Name, TmpNode->Name) != 0) {\r
-          continue;\r
-        }\r
-\r
-        FreePool (TmpNode->EditValue);\r
-        TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);\r
-\r
-        RemoveEntryList (&Node->Link);\r
-        FreePool (Node->EditValue);\r
-        FreePool (Node->Name);\r
-        FreePool (Node);\r
-      }\r
-    }\r
-\r
-    //\r
-    // Restore the Name/Value node.\r
-    //  \r
-    Link = GetFirstNode (&BackUpList);\r
-    while (!IsNull (&BackUpList, Link)) {\r
-      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
-      Link = GetNextNode (&BackUpList, Link);\r
\r
-      //\r
-      // Free this node.\r
-      //\r
-      RemoveEntryList (&Node->Link);\r
-      FreePool (Node->EditValue);\r
-      FreePool (Node->Name);\r
-      FreePool (Node);\r
-    }\r
-  }\r
-}\r
-\r
 /**\r
   Fill storage's edit copy with settings requested from Configuration Driver.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Storage                Buffer Storage.\r
 \r
 /**\r
   Fill storage's edit copy with settings requested from Configuration Driver.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Storage                Buffer Storage.\r
 \r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 LoadStorage (\r
   IN FORM_BROWSER_FORMSET    *FormSet,\r
   IN FORMSET_STORAGE         *Storage\r
 LoadStorage (\r
   IN FORM_BROWSER_FORMSET    *FormSet,\r
   IN FORMSET_STORAGE         *Storage\r
@@ -4217,17 +3772,18 @@ LoadStorage (
   EFI_STRING  Progress;\r
   EFI_STRING  Result;\r
   CHAR16      *StrPtr;\r
   EFI_STRING  Progress;\r
   EFI_STRING  Result;\r
   CHAR16      *StrPtr;\r
+  CHAR16      *ConfigRequest;\r
 \r
 \r
-  switch (Storage->BrowserStorage->Type) {\r
-    case EFI_HII_VARSTORE_EFI_VARIABLE:\r
-      return;\r
-\r
-    case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
-      if (Storage->BrowserStorage->ReferenceCount > 1) {\r
-        ConfigRequestAdjust(Storage);\r
-        return;\r
-      }\r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
 \r
+  if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {\r
+    Status = EFI_SUCCESS;\r
+    //\r
+    // EFI varstore data all get from variable, so no need to get again.\r
+    //\r
+    if (Storage->BrowserStorage->ReferenceCount == 1) {\r
       Status = gRT->GetVariable (\r
                        Storage->BrowserStorage->Name,\r
                        &Storage->BrowserStorage->Guid,\r
       Status = gRT->GetVariable (\r
                        Storage->BrowserStorage->Name,\r
                        &Storage->BrowserStorage->Guid,\r
@@ -4235,78 +3791,55 @@ LoadStorage (
                        (UINTN*)&Storage->BrowserStorage->Size,\r
                        Storage->BrowserStorage->EditBuffer\r
                        );\r
                        (UINTN*)&Storage->BrowserStorage->Size,\r
                        Storage->BrowserStorage->EditBuffer\r
                        );\r
-      //\r
-      // If get variable fail, extract default from IFR binary\r
-      //\r
-      if (EFI_ERROR (Status)) {\r
-        ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
-      }\r
-\r
-      Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);\r
-      //\r
-      // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer. \r
-      //\r
-      SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);\r
-      break;\r
+    }\r
+    return Status;\r
+  }\r
 \r
 \r
-    case EFI_HII_VARSTORE_BUFFER:\r
-    case EFI_HII_VARSTORE_NAME_VALUE:\r
-      //\r
-      // Skip if there is no RequestElement\r
-      //\r
-      if (Storage->ElementCount == 0) {\r
-        return;\r
-      }\r
+  if (FormSet->ConfigAccess == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 \r
 \r
-      //\r
-      // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig\r
-      // will used to call ExtractConfig.\r
-      // If not elements need to udpate, return.\r
-      //\r
-      if (!ConfigRequestAdjust(Storage)) {\r
-        return;\r
-      }\r
-      ASSERT (Storage->ConfigElements != NULL);\r
+  if (Storage->ElementCount == 0) {\r
+    //\r
+    // Skip if there is no RequestElement\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
 \r
-      Status = EFI_NOT_FOUND;\r
-      if (FormSet->ConfigAccess != NULL) { \r
-        //\r
-        // Request current settings from Configuration Driver\r
-        //\r
-        Status = FormSet->ConfigAccess->ExtractConfig (\r
-                                          FormSet->ConfigAccess,\r
-                                          Storage->ConfigElements,\r
-                                          &Progress,\r
-                                          &Result\r
-                                          );\r
-        \r
-        if (!EFI_ERROR (Status)) {\r
-          //\r
-          // Convert Result from <ConfigAltResp> to <ConfigResp>\r
-          //\r
-          StrPtr = StrStr (Result, L"&GUID=");\r
-          if (StrPtr != NULL) {\r
-            *StrPtr = L'\0';\r
-          }\r
-          \r
-          Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
-          FreePool (Result);\r
-        }\r
-      }\r
+  //\r
+  // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig\r
+  // will used to call ExtractConfig.\r
+  //\r
+  if (!ConfigRequestAdjust(Storage, &ConfigRequest)) {\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
 \r
-      if (EFI_ERROR (Status)) {\r
-        //\r
-        // Base on the configRequest string to get default value.\r
-        //\r
-        GetDefaultForFormset (FormSet, Storage->BrowserStorage, Storage->ConfigElements);\r
-      }\r
+  //\r
+  // Request current settings from Configuration Driver\r
+  //\r
+  Status = FormSet->ConfigAccess->ExtractConfig (\r
+                                    FormSet->ConfigAccess,\r
+                                    ConfigRequest,\r
+                                    &Progress,\r
+                                    &Result\r
+                                    );\r
+  FreePool (ConfigRequest);\r
 \r
 \r
-      SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigElements, TRUE);\r
-      break;\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
 \r
-    default:\r
-      break;\r
+  //\r
+  // Convert Result from <ConfigAltResp> to <ConfigResp>\r
+  //\r
+  StrPtr = StrStr (Result, L"&GUID=");\r
+  if (StrPtr != NULL) {\r
+    *StrPtr = L'\0';\r
   }\r
   }\r
+\r
+  Status = ConfigRespToStorage (Storage->BrowserStorage, Result);\r
+  FreePool (Result);\r
+  return Status;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -4314,15 +3847,22 @@ LoadStorage (
 \r
   @param  FormSet                FormSet data structure.\r
 \r
 \r
   @param  FormSet                FormSet data structure.\r
 \r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 InitializeCurrentSetting (\r
   IN OUT FORM_BROWSER_FORMSET             *FormSet\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
 InitializeCurrentSetting (\r
   IN OUT FORM_BROWSER_FORMSET             *FormSet\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
+  LIST_ENTRY              *Link2;\r
   FORMSET_STORAGE         *Storage;\r
   FORMSET_STORAGE         *Storage;\r
-  FORM_BROWSER_FORMSET    *OldFormSet;\r
+  FORMSET_STORAGE         *StorageSrc;\r
+  FORMSET_STORAGE         *OldStorage;\r
+  FORM_BROWSER_FORM       *Form;\r
+  FORM_BROWSER_FORM       *Form2;\r
+  EFI_STATUS              Status;\r
 \r
   //\r
   // Extract default from IFR binary for no storage questions.\r
 \r
   //\r
   // Extract default from IFR binary for no storage questions.\r
@@ -4336,21 +3876,77 @@ InitializeCurrentSetting (
   while (!IsNull (&FormSet->StorageListHead, Link)) {\r
     Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
 \r
   while (!IsNull (&FormSet->StorageListHead, Link)) {\r
     Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
 \r
-    LoadStorage (FormSet, Storage);\r
+    OldStorage = NULL;\r
+    if (gOldFormSet != NULL) {\r
+      //\r
+      // Try to find the Storage in backup formset gOldFormSet\r
+      //\r
+      Link2 = GetFirstNode (&gOldFormSet->StorageListHead);\r
+      while (!IsNull (&gOldFormSet->StorageListHead, Link2)) {\r
+        StorageSrc = FORMSET_STORAGE_FROM_LINK (Link2);\r
+\r
+        if (StorageSrc->VarStoreId == Storage->VarStoreId) {\r
+          OldStorage = StorageSrc;\r
+          break;\r
+        }\r
+\r
+        Link2 = GetNextNode (&gOldFormSet->StorageListHead, Link2);\r
+      }\r
+    }\r
+\r
+    //\r
+    // Storage is not found in backup formset and current global storage not has other driver used,\r
+    // request it from ConfigDriver\r
+    //\r
+    if (OldStorage == NULL) {\r
+      Status = LoadStorage (FormSet, Storage);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // If get last time changed value failed, extract default from IFR binary\r
+        //\r
+        ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);\r
+        //\r
+        // ExtractDefault will set the NV flag to TRUE, so need this function to clean the flag\r
+        // in current situation.\r
+        //\r
+        UpdateNvInfoInForm (FormSet, FALSE);\r
+      }\r
+\r
+      //\r
+      // Now Edit Buffer is filled with default values(lower priority) or current\r
+      // settings(higher priority), sychronize it to shadow Buffer\r
+      //\r
+      SynchronizeStorage (Storage->BrowserStorage, TRUE);\r
+    }\r
 \r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
   }\r
 \r
   //\r
 \r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
   }\r
 \r
   //\r
-  // Try to find pre FormSet in the maintain backup list.\r
-  // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.\r
+  // If has old formset, get the old nv update status.\r
   //\r
   //\r
-  OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);\r
-  if (OldFormSet != NULL) {\r
-    RemoveEntryList (&OldFormSet->Link);\r
-    DestroyFormSet (OldFormSet);\r
+  if (gOldFormSet != NULL) {\r
+    Link = GetFirstNode (&FormSet->FormListHead);\r
+    while (!IsNull (&FormSet->FormListHead, Link)) {\r
+      Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+      Link2 = GetFirstNode (&gOldFormSet->FormListHead);\r
+      while (!IsNull (&gOldFormSet->FormListHead, Link2)) {\r
+        Form2 = FORM_BROWSER_FORM_FROM_LINK (Link2);\r
+\r
+        if (Form->FormId == Form2->FormId) {\r
+          Form->NvUpdateRequired = Form2->NvUpdateRequired;\r
+          break;\r
+        }\r
+\r
+        Link2 = GetNextNode (&gOldFormSet->FormListHead, Link2);\r
+      }\r
+      Link = GetNextNode (&FormSet->FormListHead, Link);\r
+    }\r
   }\r
   }\r
-  InsertTailList (&gBrowserFormSetList, &FormSet->Link);\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -4533,6 +4129,7 @@ GetIfrBinaryData (
                                  found in package list.\r
                                  On output, GUID of the formset found(if not NULL).\r
   @param  FormSet                FormSet data structure.\r
                                  found in package list.\r
                                  On output, GUID of the formset found(if not NULL).\r
   @param  FormSet                FormSet data structure.\r
+  @param  UpdateGlobalVar        Whether need to update the global variable.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
   @retval EFI_NOT_FOUND          The specified FormSet could not be found.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
   @retval EFI_NOT_FOUND          The specified FormSet could not be found.\r
@@ -4542,11 +4139,13 @@ EFI_STATUS
 InitializeFormSet (\r
   IN  EFI_HII_HANDLE                   Handle,\r
   IN OUT EFI_GUID                      *FormSetGuid,\r
 InitializeFormSet (\r
   IN  EFI_HII_HANDLE                   Handle,\r
   IN OUT EFI_GUID                      *FormSetGuid,\r
-  OUT FORM_BROWSER_FORMSET             *FormSet\r
+  OUT FORM_BROWSER_FORMSET             *FormSet,\r
+  IN  BOOLEAN                          UpdateGlobalVar                   \r
   )\r
 {\r
   EFI_STATUS                Status;\r
   EFI_HANDLE                DriverHandle;\r
   )\r
 {\r
   EFI_STATUS                Status;\r
   EFI_HANDLE                DriverHandle;\r
+  UINT16                    Index;\r
 \r
   Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
   if (EFI_ERROR (Status)) {\r
 \r
   Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
   if (EFI_ERROR (Status)) {\r
@@ -4556,7 +4155,6 @@ InitializeFormSet (
   FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;\r
   FormSet->HiiHandle = Handle;\r
   CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
   FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;\r
   FormSet->HiiHandle = Handle;\r
   CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
-  FormSet->QuestionInited = FALSE;\r
 \r
   //\r
   // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
 \r
   //\r
   // Retrieve ConfigAccess Protocol associated with this HiiPackageList\r
@@ -4583,8 +4181,55 @@ InitializeFormSet (
   // Parse the IFR binary OpCodes\r
   //\r
   Status = ParseOpCodes (FormSet);\r
   // Parse the IFR binary OpCodes\r
   //\r
   Status = ParseOpCodes (FormSet);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
 \r
-  return Status;\r
+  // \r
+  // If not need to update the global variable, just return.\r
+  //\r
+  if (!UpdateGlobalVar) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Set VFR type by FormSet SubClass field\r
+  //\r
+  gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
+  if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
+    gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;\r
+  }\r
+  \r
+  //\r
+  // Set VFR type by FormSet class guid\r
+  //\r
+  for (Index = 0; Index < 3; Index ++) {\r
+    if (CompareGuid (&FormSet->ClassGuid[Index], &gEfiHiiPlatformSetupFormsetGuid)) {\r
+      gClassOfVfr |= FORMSET_CLASS_PLATFORM_SETUP;\r
+      break;\r
+    }\r
+  }\r
+\r
+  gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;\r
+\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
+    gFrontPageHandle = FormSet->HiiHandle;\r
+    gFunctionKeySetting = NONE_FUNCTION_KEY_SETTING;\r
+  }\r
+\r
+  //\r
+  // Match GUID to find out the function key setting. If match fail, use the default setting.\r
+  //\r
+  for (Index = 0; Index < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index++) {\r
+    if (CompareGuid (&FormSet->Guid, &(gFunctionKeySettingTable[Index].FormSetGuid))) {\r
+      //\r
+      // Update the function key setting.\r
+      //\r
+      gFunctionKeySetting = gFunctionKeySettingTable[Index].KeySetting;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -4600,7 +4245,6 @@ SaveBrowserContext (
   )\r
 {\r
   BROWSER_CONTEXT  *Context;\r
   )\r
 {\r
   BROWSER_CONTEXT  *Context;\r
-  FORM_ENTRY_INFO     *MenuList;\r
 \r
   gBrowserContextCount++;\r
   if (gBrowserContextCount == 1) {\r
 \r
   gBrowserContextCount++;\r
   if (gBrowserContextCount == 1) {\r
@@ -4618,23 +4262,47 @@ SaveBrowserContext (
   //\r
   // Save FormBrowser context\r
   //\r
   //\r
   // Save FormBrowser context\r
   //\r
-  Context->Selection            = gCurrentSelection;\r
+  Context->BannerData           = gBannerData;\r
+  Context->ClassOfVfr           = gClassOfVfr;\r
+  Context->FunctionKeySetting   = gFunctionKeySetting;\r
   Context->ResetRequired        = gResetRequired;\r
   Context->ResetRequired        = gResetRequired;\r
-  Context->ExitRequired         = gExitRequired;\r
-  Context->HiiHandle            = mCurrentHiiHandle;\r
-  Context->FormId               = mCurrentFormId;\r
-  CopyGuid (&Context->FormSetGuid, &mCurrentFormSetGuid);\r
-\r
-  //\r
-  // Save the menu history data.\r
-  //\r
-  InitializeListHead(&Context->FormHistoryList);\r
-  while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {\r
-    MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);\r
-    RemoveEntryList (&MenuList->Link);\r
-\r
-    InsertTailList(&Context->FormHistoryList, &MenuList->Link);\r
-  }\r
+  Context->Direction            = gDirection;\r
+  Context->EnterString          = gEnterString;\r
+  Context->EnterCommitString    = gEnterCommitString;\r
+  Context->EnterEscapeString    = gEnterEscapeString;\r
+  Context->EscapeString         = gEscapeString;\r
+  Context->MoveHighlight        = gMoveHighlight;\r
+  Context->MakeSelection        = gMakeSelection;\r
+  Context->DecNumericInput      = gDecNumericInput;\r
+  Context->HexNumericInput      = gHexNumericInput;\r
+  Context->ToggleCheckBox       = gToggleCheckBox;\r
+  Context->PromptForData        = gPromptForData;\r
+  Context->PromptForPassword    = gPromptForPassword;\r
+  Context->PromptForNewPassword = gPromptForNewPassword;\r
+  Context->ConfirmPassword      = gConfirmPassword;\r
+  Context->ConfirmError         = gConfirmError;\r
+  Context->PassowordInvalid     = gPassowordInvalid;\r
+  Context->PressEnter           = gPressEnter;\r
+  Context->EmptyString          = gEmptyString;\r
+  Context->AreYouSure           = gAreYouSure;\r
+  Context->YesResponse          = gYesResponse;\r
+  Context->NoResponse           = gNoResponse;\r
+  Context->MiniString           = gMiniString;\r
+  Context->PlusString           = gPlusString;\r
+  Context->MinusString          = gMinusString;\r
+  Context->AdjustNumber         = gAdjustNumber;\r
+  Context->SaveChanges          = gSaveChanges;\r
+  Context->OptionMismatch       = gOptionMismatch;\r
+  Context->FormSuppress         = gFormSuppress;\r
+  Context->PromptBlockWidth     = gPromptBlockWidth;\r
+  Context->OptionBlockWidth     = gOptionBlockWidth;\r
+  Context->HelpBlockWidth       = gHelpBlockWidth;\r
+  Context->OldFormSet           = gOldFormSet;\r
+  Context->MenuRefreshHead      = gMenuRefreshHead;\r
+  Context->ProtocolNotFound     = gProtocolNotFound;\r
+\r
+  CopyMem (&Context->ScreenDimensions, &gScreenDimensions, sizeof (gScreenDimensions));\r
+  CopyMem (&Context->MenuOption, &gMenuOption, sizeof (gMenuOption));\r
 \r
   //\r
   // Insert to FormBrowser context list\r
 \r
   //\r
   // Insert to FormBrowser context list\r
@@ -4654,7 +4322,6 @@ RestoreBrowserContext (
 {\r
   LIST_ENTRY       *Link;\r
   BROWSER_CONTEXT  *Context;\r
 {\r
   LIST_ENTRY       *Link;\r
   BROWSER_CONTEXT  *Context;\r
-  FORM_ENTRY_INFO     *MenuList;\r
 \r
   ASSERT (gBrowserContextCount != 0);\r
   gBrowserContextCount--;\r
 \r
   ASSERT (gBrowserContextCount != 0);\r
   gBrowserContextCount--;\r
@@ -4673,22 +4340,47 @@ RestoreBrowserContext (
   //\r
   // Restore FormBrowser context\r
   //\r
   //\r
   // Restore FormBrowser context\r
   //\r
-  gCurrentSelection     = Context->Selection;\r
+  gBannerData           = Context->BannerData;\r
+  gClassOfVfr           = Context->ClassOfVfr;\r
+  gFunctionKeySetting   = Context->FunctionKeySetting;\r
   gResetRequired        = Context->ResetRequired;\r
   gResetRequired        = Context->ResetRequired;\r
-  gExitRequired         = Context->ExitRequired;\r
-  mCurrentHiiHandle     = Context->HiiHandle;\r
-  mCurrentFormId        = Context->FormId;\r
-  CopyGuid (&mCurrentFormSetGuid, &Context->FormSetGuid);\r
-\r
-  //\r
-  // Restore the menu history data.\r
-  //\r
-  while (!IsListEmpty (&Context->FormHistoryList)) {\r
-    MenuList = FORM_ENTRY_INFO_FROM_LINK (Context->FormHistoryList.ForwardLink);\r
-    RemoveEntryList (&MenuList->Link);\r
-\r
-    InsertTailList(&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);\r
-  }\r
+  gDirection            = Context->Direction;\r
+  gEnterString          = Context->EnterString;\r
+  gEnterCommitString    = Context->EnterCommitString;\r
+  gEnterEscapeString    = Context->EnterEscapeString;\r
+  gEscapeString         = Context->EscapeString;\r
+  gMoveHighlight        = Context->MoveHighlight;\r
+  gMakeSelection        = Context->MakeSelection;\r
+  gDecNumericInput      = Context->DecNumericInput;\r
+  gHexNumericInput      = Context->HexNumericInput;\r
+  gToggleCheckBox       = Context->ToggleCheckBox;\r
+  gPromptForData        = Context->PromptForData;\r
+  gPromptForPassword    = Context->PromptForPassword;\r
+  gPromptForNewPassword = Context->PromptForNewPassword;\r
+  gConfirmPassword      = Context->ConfirmPassword;\r
+  gConfirmError         = Context->ConfirmError;\r
+  gPassowordInvalid     = Context->PassowordInvalid;\r
+  gPressEnter           = Context->PressEnter;\r
+  gEmptyString          = Context->EmptyString;\r
+  gAreYouSure           = Context->AreYouSure;\r
+  gYesResponse          = Context->YesResponse;\r
+  gNoResponse           = Context->NoResponse;\r
+  gMiniString           = Context->MiniString;\r
+  gPlusString           = Context->PlusString;\r
+  gMinusString          = Context->MinusString;\r
+  gAdjustNumber         = Context->AdjustNumber;\r
+  gSaveChanges          = Context->SaveChanges;\r
+  gOptionMismatch       = Context->OptionMismatch;\r
+  gFormSuppress         = Context->FormSuppress;\r
+  gPromptBlockWidth     = Context->PromptBlockWidth;\r
+  gOptionBlockWidth     = Context->OptionBlockWidth;\r
+  gHelpBlockWidth       = Context->HelpBlockWidth;\r
+  gOldFormSet           = Context->OldFormSet;\r
+  gMenuRefreshHead      = Context->MenuRefreshHead;\r
+  gProtocolNotFound     = Context->ProtocolNotFound;\r
+\r
+  CopyMem (&gScreenDimensions, &Context->ScreenDimensions, sizeof (gScreenDimensions));\r
+  CopyMem (&gMenuOption, &Context->MenuOption, sizeof (gMenuOption));\r
 \r
   //\r
   // Remove from FormBrowser context list\r
 \r
   //\r
   // Remove from FormBrowser context list\r
@@ -4748,7 +4440,7 @@ IsHiiHandleInBrowserContext (
   //\r
   // HiiHandle is Current FormSet.\r
   //\r
   //\r
   // HiiHandle is Current FormSet.\r
   //\r
-  if (mCurrentHiiHandle == Handle) {\r
+  if ((gOldFormSet != NULL) && (gOldFormSet->HiiHandle == Handle)) {\r
     return TRUE;\r
   }\r
 \r
     return TRUE;\r
   }\r
 \r
@@ -4758,7 +4450,7 @@ IsHiiHandleInBrowserContext (
   Link = GetFirstNode (&gBrowserContextList);\r
   while (!IsNull (&gBrowserContextList, Link)) {\r
     Context = BROWSER_CONTEXT_FROM_LINK (Link);\r
   Link = GetFirstNode (&gBrowserContextList);\r
   while (!IsNull (&gBrowserContextList, Link)) {\r
     Context = BROWSER_CONTEXT_FROM_LINK (Link);\r
-    if (Context->HiiHandle == Handle) {\r
+    if (Context->OldFormSet->HiiHandle == Handle) {\r
       //\r
       // HiiHandle is in BrowserContext\r
       //\r
       //\r
       // HiiHandle is in BrowserContext\r
       //\r
@@ -4770,83 +4462,6 @@ IsHiiHandleInBrowserContext (
   return FALSE;\r
 }\r
 \r
   return FALSE;\r
 }\r
 \r
-/**\r
-  Perform Password check. \r
-  Passwork may be encrypted by driver that requires the specific check.\r
-  \r
-  @param  Form             Form where Password Statement is in.\r
-  @param  Statement        Password statement\r
-  @param  PasswordString   Password string to be checked. It may be NULL.\r
-                           NULL means to restore password.\r
-                           "" string can be used to checked whether old password does exist.\r
-  \r
-  @return Status     Status of Password check.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PasswordCheck (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *Form,\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
-  IN EFI_STRING                    PasswordString  OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS                      Status;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
-  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
-  EFI_IFR_TYPE_VALUE              IfrTypeValue;\r
-  FORM_BROWSER_STATEMENT          *Question;\r
-\r
-  ConfigAccess = gCurrentSelection->FormSet->ConfigAccess;\r
-  Question = GetBrowserStatement(Statement);\r
-  ASSERT (Question != NULL);\r
-\r
-  if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) {\r
-    if (ConfigAccess == NULL) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-  } else {\r
-    if (PasswordString == NULL) {\r
-      return EFI_SUCCESS;\r
-    } \r
-    \r
-    if (StrnCmp (PasswordString, (CHAR16 *) Question->BufferValue, Question->StorageWidth/sizeof (CHAR16)) == 0) {\r
-      return EFI_SUCCESS;\r
-    } else {\r
-      return EFI_NOT_READY;\r
-    }\r
-  }\r
-    \r
-  //\r
-  // Prepare password string in HII database\r
-  //\r
-  if (PasswordString != NULL) {\r
-    IfrTypeValue.string = NewString (PasswordString, gCurrentSelection->FormSet->HiiHandle);\r
-  } else {\r
-    IfrTypeValue.string = 0;\r
-  }\r
-\r
-  //\r
-  // Send password to Configuration Driver for validation\r
-  //\r
-  Status = ConfigAccess->Callback (\r
-                           ConfigAccess,\r
-                           EFI_BROWSER_ACTION_CHANGING,\r
-                           Question->QuestionId,\r
-                           Question->HiiValue.Type,\r
-                           &IfrTypeValue,\r
-                           &ActionRequest\r
-                           );\r
-\r
-  //\r
-  // Remove password string from HII database\r
-  //\r
-  if (PasswordString != NULL) {\r
-    DeleteString (IfrTypeValue.string, gCurrentSelection->FormSet->HiiHandle);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
   Find the registered HotKey based on KeyData.\r
   \r
 /**\r
   Find the registered HotKey based on KeyData.\r
   \r
@@ -4897,7 +4512,7 @@ SetScope (
   if (Scope >= MaxLevel) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (Scope >= MaxLevel) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-\r
+  \r
   //\r
   // When no hot key registered in system or on the first setting,\r
   // Scope can be set.\r
   //\r
   // When no hot key registered in system or on the first setting,\r
   // Scope can be set.\r
@@ -5021,128 +4636,6 @@ RegiserExitHandler (
   return;\r
 }\r
 \r
   return;\r
 }\r
 \r
-/**\r
-  Check whether the browser data has been modified.\r
-\r
-  @retval TRUE        Browser data is modified.\r
-  @retval FALSE       No browser data is modified.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsBrowserDataModified (\r
-  VOID\r
-  )\r
-{\r
-  LIST_ENTRY              *Link;\r
-  FORM_BROWSER_FORMSET    *FormSet;\r
-\r
-  if (gCurrentSelection == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  switch (gBrowserSettingScope) {\r
-    case FormLevel:\r
-      return IsNvUpdateRequiredForForm (gCurrentSelection->Form);\r
-\r
-    case FormSetLevel:\r
-      return IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet);\r
-\r
-    case SystemLevel:\r
-      Link = GetFirstNode (&gBrowserFormSetList);\r
-      while (!IsNull (&gBrowserFormSetList, Link)) {\r
-        FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
-        if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
-          return TRUE;\r
-        }\r
-        Link = GetNextNode (&gBrowserFormSetList, Link);\r
-      }\r
-      return FALSE;\r
-\r
-    default:\r
-      return FALSE;\r
-  }\r
-}\r
-\r
-/**\r
-  Execute the action requested by the Action parameter.\r
-\r
-  @param[in] Action     Execute the request action.\r
-  @param[in] DefaultId  The default Id info when need to load default value. Only used when Action is BROWSER_ACTION_DEFAULT.\r
-\r
-  @retval EFI_SUCCESS              Execute the request action succss.\r
-  @retval EFI_INVALID_PARAMETER    The input action value is invalid.\r
-\r
-**/\r
-EFI_STATUS \r
-EFIAPI\r
-ExecuteAction (\r
-  IN UINT32        Action,\r
-  IN UINT16        DefaultId\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  if (gCurrentSelection == NULL) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  // Executet the discard action.\r
-  //\r
-  if ((Action & BROWSER_ACTION_DISCARD) != 0) {\r
-    Status = DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Executet the difault action.\r
-  //\r
-  if ((Action & BROWSER_ACTION_DEFAULT) != 0) {\r
-    Status = ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Executet the submit action.\r
-  //\r
-  if ((Action & BROWSER_ACTION_SUBMIT) != 0) {\r
-    Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Executet the reset action.\r
-  //\r
-  if ((Action & BROWSER_ACTION_RESET) != 0) {\r
-    gResetRequired = TRUE;\r
-  }\r
-\r
-  //\r
-  // Executet the exit action.\r
-  //\r
-  if ((Action & BROWSER_ACTION_EXIT) != 0) {\r
-    DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
-    if (gBrowserSettingScope == SystemLevel) {\r
-      if (ExitHandlerFunction != NULL) {\r
-        ExitHandlerFunction ();\r
-      }\r
-    }\r
-\r
-    gExitRequired = TRUE;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
   Create reminder to let user to choose save or discard the changed browser data.\r
   Caller can use it to actively check the changed browser data.\r
 /**\r
   Create reminder to let user to choose save or discard the changed browser data.\r
   Caller can use it to actively check the changed browser data.\r
@@ -5162,6 +4655,12 @@ SaveReminder (
   FORM_BROWSER_FORMSET    *FormSet;\r
   BOOLEAN                 IsDataChanged;\r
   UINT32                  DataSavedAction;\r
   FORM_BROWSER_FORMSET    *FormSet;\r
   BOOLEAN                 IsDataChanged;\r
   UINT32                  DataSavedAction;\r
+  CHAR16                  *YesResponse;\r
+  CHAR16                  *NoResponse;\r
+  CHAR16                  *EmptyString;\r
+  CHAR16                  *ChangeReminderString;\r
+  CHAR16                  *SaveConfirmString;\r
+  EFI_INPUT_KEY           Key;\r
 \r
   DataSavedAction  = BROWSER_NO_CHANGES;\r
   IsDataChanged    = FALSE;\r
 \r
   DataSavedAction  = BROWSER_NO_CHANGES;\r
   IsDataChanged    = FALSE;\r
@@ -5172,7 +4671,7 @@ SaveReminder (
     if (!ValidateFormSet(FormSet)) {\r
       continue;\r
     }\r
     if (!ValidateFormSet(FormSet)) {\r
       continue;\r
     }\r
-    if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
+    if (IsNvUpdateRequired (FormSet)) {\r
       IsDataChanged = TRUE;\r
       break;\r
     }\r
       IsDataChanged = TRUE;\r
       break;\r
     }\r
@@ -5186,19 +4685,42 @@ SaveReminder (
   }\r
   \r
   //\r
   }\r
   \r
   //\r
-  // If data is changed, prompt user to save or discard it. \r
+  // If data is changed, prompt user\r
   //\r
   //\r
+  gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+\r
+  YesResponse          = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);\r
+  ASSERT (YesResponse != NULL);\r
+  NoResponse           = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);\r
+  ASSERT (NoResponse  != NULL);\r
+  EmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
+  ChangeReminderString = GetToken (STRING_TOKEN (CHANGE_REMINDER), gHiiHandle);\r
+  SaveConfirmString    = GetToken (STRING_TOKEN (SAVE_CONFIRM), gHiiHandle);\r
+\r
   do {\r
   do {\r
-    DataSavedAction = (UINT32) mFormDisplay->ConfirmDataChange();\r
+    CreateDialog (4, TRUE, 0, NULL, &Key, EmptyString, ChangeReminderString, SaveConfirmString, EmptyString);\r
+  } while\r
+  (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse[0] | UPPER_LOWER_CASE_OFFSET)) &&\r
+   ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse[0] | UPPER_LOWER_CASE_OFFSET))\r
+  );\r
 \r
 \r
-    if (DataSavedAction == BROWSER_SAVE_CHANGES) {\r
-      SubmitForm (NULL, NULL, SystemLevel);\r
-      break;\r
-    } else if (DataSavedAction == BROWSER_DISCARD_CHANGES) {\r
-      DiscardForm (NULL, NULL, SystemLevel);\r
-      break;\r
-    }\r
-  } while (1);\r
+  //\r
+  // If the user hits the YesResponse key\r
+  //\r
+  if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse[0] | UPPER_LOWER_CASE_OFFSET)) {\r
+    SubmitForm (NULL, NULL, SystemLevel);\r
+    DataSavedAction = BROWSER_SAVE_CHANGES;\r
+  } else {\r
+    DiscardForm (NULL, NULL, SystemLevel);\r
+    DataSavedAction = BROWSER_DISCARD_CHANGES;\r
+    gResetRequired  = FALSE;\r
+  }\r
+\r
+  FreePool (YesResponse);\r
+  FreePool (NoResponse);\r
+  FreePool (EmptyString);\r
+  FreePool (SaveConfirmString);\r
+  FreePool (ChangeReminderString);\r
 \r
   return DataSavedAction;\r
 }\r
 \r
   return DataSavedAction;\r
 }\r
index 030cf32eac72ba0e63d509394c66b2327b18d1c6..9a0c739094017a5ce74d42bb379bb604230d3b6c 100644 (file)
@@ -22,8 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SimpleTextOut.h>\r
 #include <Protocol/SimpleTextIn.h>\r
 #include <Protocol/FormBrowser2.h>\r
 #include <Protocol/SimpleTextOut.h>\r
 #include <Protocol/SimpleTextIn.h>\r
 #include <Protocol/FormBrowser2.h>\r
-#include <Protocol/FormBrowserEx2.h>\r
-#include <Protocol/DisplayProtocol.h>\r
+#include <Protocol/FormBrowserEx.h>\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/UnicodeCollation.h>\r
 #include <Protocol/HiiConfigAccess.h>\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/UnicodeCollation.h>\r
 #include <Protocol/HiiConfigAccess.h>\r
@@ -48,28 +47,105 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/HiiLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/DevicePathLib.h>\r
 #include <Library/HiiLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/DevicePathLib.h>\r
-#include <Library/UefiLib.h>\r
 \r
 \r
+#include "Colors.h"\r
 \r
 //\r
 // This is the generated header file which includes whatever needs to be exported (strings + IFR)\r
 //\r
 \r
 \r
 //\r
 // This is the generated header file which includes whatever needs to be exported (strings + IFR)\r
 //\r
 \r
-#define UI_ACTION_NONE               0\r
-#define UI_ACTION_REFRESH_FORM       1\r
-#define UI_ACTION_REFRESH_FORMSET    2\r
-#define UI_ACTION_EXIT               3\r
+extern UINT8  SetupBrowserStrings[];\r
 \r
 //\r
 \r
 //\r
+// Screen definitions\r
+//\r
+#define BANNER_HEIGHT                 6\r
+#define BANNER_COLUMNS                3\r
+#define BANNER_LEFT_COLUMN_INDENT     1\r
+\r
+#define FRONT_PAGE_HEADER_HEIGHT      6\r
+#define NONE_FRONT_PAGE_HEADER_HEIGHT 3\r
+#define LEFT_SKIPPED_COLUMNS          3\r
+#define FOOTER_HEIGHT                 4\r
+#define STATUS_BAR_HEIGHT             1\r
+#define SCROLL_ARROW_HEIGHT           1\r
+#define POPUP_PAD_SPACE_COUNT         5\r
+#define POPUP_FRAME_WIDTH             2\r
+\r
+//\r
+// Definition for function key setting\r
+//\r
+#define NONE_FUNCTION_KEY_SETTING     0\r
+#define ENABLE_FUNCTION_KEY_SETTING   1\r
+\r
+typedef struct {\r
+  EFI_GUID  FormSetGuid;\r
+  UINTN     KeySetting;\r
+} FUNCTIION_KEY_SETTING;\r
+\r
+//\r
+// Character definitions\r
+//\r
+#define CHAR_SPACE              0x0020\r
+#define UPPER_LOWER_CASE_OFFSET 0x20\r
+\r
 //\r
 // Time definitions\r
 //\r
 #define ONE_SECOND  10000000\r
 \r
 //\r
 // Time definitions\r
 //\r
 #define ONE_SECOND  10000000\r
 \r
+//\r
+// Display definitions\r
+//\r
+#define LEFT_HYPER_DELIMITER      L'<'\r
+#define RIGHT_HYPER_DELIMITER     L'>'\r
+\r
+#define LEFT_ONEOF_DELIMITER      L'<'\r
+#define RIGHT_ONEOF_DELIMITER     L'>'\r
+\r
+#define LEFT_NUMERIC_DELIMITER    L'['\r
+#define RIGHT_NUMERIC_DELIMITER   L']'\r
+\r
+#define LEFT_CHECKBOX_DELIMITER   L'['\r
+#define RIGHT_CHECKBOX_DELIMITER  L']'\r
+\r
+#define CHECK_ON                  L'X'\r
+#define CHECK_OFF                 L' '\r
+\r
+#define TIME_SEPARATOR            L':'\r
+#define DATE_SEPARATOR            L'/'\r
+\r
+#define YES_ANSWER                L'Y'\r
+#define NO_ANSWER                 L'N'\r
+\r
+//\r
+// This is the Input Error Message\r
+//\r
+#define INPUT_ERROR 1\r
+\r
+//\r
+// This is the NV RAM update required Message\r
+//\r
+#define NV_UPDATE_REQUIRED  2\r
+\r
+//\r
+// Refresh the Status Bar with flags\r
+//\r
+#define REFRESH_STATUS_BAR  0xff\r
+\r
+//\r
 // Incremental string lenght of ConfigRequest\r
 //\r
 #define CONFIG_REQUEST_STRING_INCREMENTAL  1024\r
 \r
 // Incremental string lenght of ConfigRequest\r
 //\r
 #define CONFIG_REQUEST_STRING_INCREMENTAL  1024\r
 \r
+//\r
+// HII value compare result\r
+//\r
+#define HII_VALUE_UNDEFINED     0\r
+#define HII_VALUE_EQUAL         1\r
+#define HII_VALUE_LESS_THAN     2\r
+#define HII_VALUE_GREATER_THAN  3\r
+\r
 //\r
 // Incremental size of stack for expression\r
 //\r
 //\r
 // Incremental size of stack for expression\r
 //\r
@@ -87,13 +163,16 @@ typedef struct {
   //\r
   // Produced protocol\r
   //\r
   //\r
   // Produced protocol\r
   //\r
-  EFI_FORM_BROWSER2_PROTOCOL            FormBrowser2;\r
-  EFI_FORM_BROWSER_EXTENSION_PROTOCOL   FormBrowserEx;\r
-\r
-  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL FormBrowserEx2;\r
+  EFI_FORM_BROWSER2_PROTOCOL          FormBrowser2;\r
+  \r
+  EFI_FORM_BROWSER_EXTENSION_PROTOCOL FormBrowserEx;\r
 \r
 } SETUP_DRIVER_PRIVATE_DATA;\r
 \r
 \r
 } SETUP_DRIVER_PRIVATE_DATA;\r
 \r
+typedef struct {\r
+  EFI_STRING_ID  Banner[BANNER_HEIGHT][BANNER_COLUMNS];\r
+} BANNER_DATA;\r
+\r
 //\r
 // IFR relative definition\r
 //\r
 //\r
 // IFR relative definition\r
 //\r
@@ -115,6 +194,16 @@ typedef struct {
 #define FORM_INCONSISTENT_VALIDATION         0\r
 #define FORM_NO_SUBMIT_VALIDATION            1\r
 \r
 #define FORM_INCONSISTENT_VALIDATION         0\r
 #define FORM_NO_SUBMIT_VALIDATION            1\r
 \r
+#define FORMSET_CLASS_PLATFORM_SETUP         0x0001\r
+#define FORMSET_CLASS_FRONT_PAGE             0x0002\r
+\r
+typedef struct {\r
+  UINT8               Type;\r
+  UINT8               *Buffer;\r
+  UINT16              BufferLen;\r
+  EFI_IFR_TYPE_VALUE  Value;\r
+} EFI_HII_VALUE;\r
+\r
 #define NAME_VALUE_NODE_SIGNATURE  SIGNATURE_32 ('N', 'V', 'S', 'T')\r
 \r
 typedef struct {\r
 #define NAME_VALUE_NODE_SIGNATURE  SIGNATURE_32 ('N', 'V', 'S', 'T')\r
 \r
 typedef struct {\r
@@ -166,7 +255,6 @@ typedef struct {
   BROWSER_STORAGE  *BrowserStorage;\r
 \r
   CHAR16           *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>\r
   BROWSER_STORAGE  *BrowserStorage;\r
 \r
   CHAR16           *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>\r
-  CHAR16           *ConfigElements;// Elements need to load initial data.\r
   UINTN            ElementCount;   // Number of <RequestElement> in the <ConfigRequest>\r
   UINTN            SpareStrLen;    // Spare length of ConfigRequest string buffer\r
 } FORMSET_STORAGE;\r
   UINTN            ElementCount;   // Number of <RequestElement> in the <ConfigRequest>\r
   UINTN            SpareStrLen;    // Spare length of ConfigRequest string buffer\r
 } FORMSET_STORAGE;\r
@@ -256,8 +344,6 @@ typedef struct {
 typedef struct {\r
   UINTN                Signature;\r
   LIST_ENTRY           Link;\r
 typedef struct {\r
   UINTN                Signature;\r
   LIST_ENTRY           Link;\r
-  \r
-  EFI_IFR_ONE_OF_OPTION  *OpCode;   // OneOfOption Data\r
 \r
   EFI_STRING_ID        Text;\r
   UINT8                Flags;\r
 \r
   EFI_STRING_ID        Text;\r
   UINT8                Flags;\r
@@ -290,7 +376,6 @@ typedef struct {
   LIST_ENTRY            Link;\r
 \r
   UINT8                 Operand;          // The operand (first byte) of this Statement or Question\r
   LIST_ENTRY            Link;\r
 \r
   UINT8                 Operand;          // The operand (first byte) of this Statement or Question\r
-  EFI_IFR_OP_HEADER     *OpCode;\r
 \r
   //\r
   // Statement Header\r
 \r
   //\r
   // Statement Header\r
@@ -299,11 +384,6 @@ typedef struct {
   EFI_STRING_ID         Help;\r
   EFI_STRING_ID         TextTwo;          // For EFI_IFR_TEXT\r
 \r
   EFI_STRING_ID         Help;\r
   EFI_STRING_ID         TextTwo;          // For EFI_IFR_TEXT\r
 \r
-  //\r
-  // Fake Question Id, used for statement not has true QuestionId.\r
-  //\r
-  EFI_QUESTION_ID       FakeQuestionId;\r
-\r
   //\r
   // Question Header\r
   //\r
   //\r
   // Question Header\r
   //\r
@@ -337,7 +417,6 @@ typedef struct {
   EFI_DEFAULT_ID        DefaultId;        // for EFI_IFR_RESET_BUTTON\r
   EFI_GUID              RefreshGuid;      // for EFI_IFR_REFRESH_ID\r
   BOOLEAN               Locked;           // Whether this statement is locked.\r
   EFI_DEFAULT_ID        DefaultId;        // for EFI_IFR_RESET_BUTTON\r
   EFI_GUID              RefreshGuid;      // for EFI_IFR_REFRESH_ID\r
   BOOLEAN               Locked;           // Whether this statement is locked.\r
-  BOOLEAN               ValueChanged;     // Whether this statement's value is changed.\r
   //\r
   // Get from IFR parsing\r
   //\r
   //\r
   // Get from IFR parsing\r
   //\r
@@ -388,6 +467,8 @@ typedef struct {
   BOOLEAN              ModalForm;            // Whether this is a modal form.\r
   BOOLEAN              Locked;               // Whether this form is locked.\r
 \r
   BOOLEAN              ModalForm;            // Whether this is a modal form.\r
   BOOLEAN              Locked;               // Whether this form is locked.\r
 \r
+  BOOLEAN              NvUpdateRequired;     // Whether this form has NV update request.\r
+\r
   LIST_ENTRY           ExpressionListHead;   // List of Expressions (FORM_EXPRESSION)\r
   LIST_ENTRY           StatementListHead;    // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
   LIST_ENTRY           ConfigRequestHead;    // List of configreques for all storage.\r
   LIST_ENTRY           ExpressionListHead;   // List of Expressions (FORM_EXPRESSION)\r
   LIST_ENTRY           StatementListHead;    // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
   LIST_ENTRY           ConfigRequestHead;    // List of configreques for all storage.\r
@@ -421,7 +502,6 @@ typedef struct {
   UINTN                           IfrBinaryLength;\r
   UINT8                           *IfrBinaryData;\r
 \r
   UINTN                           IfrBinaryLength;\r
   UINT8                           *IfrBinaryData;\r
 \r
-  BOOLEAN                         QuestionInited;   // Have finished question initilization?\r
   EFI_GUID                        Guid;\r
   EFI_STRING_ID                   FormSetTitle;\r
   EFI_STRING_ID                   Help;\r
   EFI_GUID                        Guid;\r
   EFI_STRING_ID                   FormSetTitle;\r
   EFI_STRING_ID                   Help;\r
@@ -434,82 +514,84 @@ typedef struct {
   FORM_BROWSER_STATEMENT          *StatementBuffer;     // Buffer for all Statements and Questions\r
   EXPRESSION_OPCODE               *ExpressionBuffer;    // Buffer for all Expression OpCode\r
 \r
   FORM_BROWSER_STATEMENT          *StatementBuffer;     // Buffer for all Statements and Questions\r
   EXPRESSION_OPCODE               *ExpressionBuffer;    // Buffer for all Expression OpCode\r
 \r
-  LIST_ENTRY                      StatementListOSF;     // Statement list out side of the form.\r
   LIST_ENTRY                      StorageListHead;      // Storage list (FORMSET_STORAGE)\r
   LIST_ENTRY                      DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)\r
   LIST_ENTRY                      FormListHead;         // Form list (FORM_BROWSER_FORM)\r
   LIST_ENTRY                      ExpressionListHead;   // List of Expressions (FORM_EXPRESSION)\r
 } FORM_BROWSER_FORMSET;\r
   LIST_ENTRY                      StorageListHead;      // Storage list (FORMSET_STORAGE)\r
   LIST_ENTRY                      DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)\r
   LIST_ENTRY                      FormListHead;         // Form list (FORM_BROWSER_FORM)\r
   LIST_ENTRY                      ExpressionListHead;   // List of Expressions (FORM_EXPRESSION)\r
 } FORM_BROWSER_FORMSET;\r
-#define FORM_BROWSER_FORMSET_FROM_LINK(a)  CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)\r
-\r
-typedef struct {\r
-  LIST_ENTRY   Link;\r
-  EFI_EVENT    RefreshEvent;\r
-} FORM_BROWSER_REFRESH_EVENT_NODE;\r
 \r
 \r
-#define FORM_BROWSER_REFRESH_EVENT_FROM_LINK(a) BASE_CR (a, FORM_BROWSER_REFRESH_EVENT_NODE, Link)\r
+#define FORM_BROWSER_FORMSET_FROM_LINK(a)  CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)\r
 \r
 \r
+#define BROWSER_CONTEXT_SIGNATURE  SIGNATURE_32 ('B', 'C', 'T', 'X')\r
 \r
 typedef struct {\r
 \r
 typedef struct {\r
-  EFI_HII_HANDLE  Handle;\r
-\r
-  //\r
-  // Target formset/form/Question information\r
-  //\r
-  EFI_GUID        FormSetGuid;\r
-  UINT16          FormId;\r
-  UINT16          QuestionId;\r
-  UINTN           Sequence;  // used for time/date only.\r
-\r
-  UINTN           TopRow;\r
-  UINTN           BottomRow;\r
-  UINTN           PromptCol;\r
-  UINTN           OptionCol;\r
-  UINTN           CurrentRow;\r
-\r
-  //\r
-  // Ation for Browser to taken:\r
-  //   UI_ACTION_NONE            - navigation inside a form\r
-  //   UI_ACTION_REFRESH_FORM    - re-evaluate expressions and repaint form\r
-  //   UI_ACTION_REFRESH_FORMSET - re-parse formset IFR binary\r
-  //\r
-  UINTN           Action;\r
+  UINTN                 Signature;\r
+  LIST_ENTRY            Link;\r
 \r
   //\r
 \r
   //\r
-  // Current selected fomset/form/Question\r
+  // Globals defined in Setup.c\r
   //\r
   //\r
-  FORM_BROWSER_FORMSET    *FormSet;\r
-  FORM_BROWSER_FORM       *Form;\r
-  FORM_BROWSER_STATEMENT  *Statement;\r
+  BANNER_DATA           *BannerData;\r
+  UINTN                 ClassOfVfr;\r
+  UINTN                 FunctionKeySetting;\r
+  BOOLEAN               ResetRequired;\r
+  UINT16                Direction;\r
+  EFI_SCREEN_DESCRIPTOR ScreenDimensions;\r
+  CHAR16                *EnterString;\r
+  CHAR16                *EnterCommitString;\r
+  CHAR16                *EnterEscapeString;\r
+  CHAR16                *EscapeString;\r
+  CHAR16                *MoveHighlight;\r
+  CHAR16                *MakeSelection;\r
+  CHAR16                *DecNumericInput;\r
+  CHAR16                *HexNumericInput;\r
+  CHAR16                *ToggleCheckBox;\r
+  CHAR16                *PromptForData;\r
+  CHAR16                *PromptForPassword;\r
+  CHAR16                *PromptForNewPassword;\r
+  CHAR16                *ConfirmPassword;\r
+  CHAR16                *ConfirmError;\r
+  CHAR16                *PassowordInvalid;\r
+  CHAR16                *PressEnter;\r
+  CHAR16                *EmptyString;\r
+  CHAR16                *AreYouSure;\r
+  CHAR16                *YesResponse;\r
+  CHAR16                *NoResponse;\r
+  CHAR16                *MiniString;\r
+  CHAR16                *PlusString;\r
+  CHAR16                *MinusString;\r
+  CHAR16                *AdjustNumber;\r
+  CHAR16                *SaveChanges;\r
+  CHAR16                *OptionMismatch;\r
+  CHAR16                *FormSuppress;\r
+  CHAR16                *ProtocolNotFound;\r
+  CHAR16                PromptBlockWidth;\r
+  CHAR16                OptionBlockWidth;\r
+  CHAR16                HelpBlockWidth;\r
+  FORM_BROWSER_FORMSET  *OldFormSet;\r
 \r
   //\r
 \r
   //\r
-  // Whether the Form is editable\r
+  // Globals defined in Ui.c\r
   //\r
   //\r
-  BOOLEAN                 FormEditable;\r
+  LIST_ENTRY           MenuOption;\r
+  VOID                 *MenuRefreshHead;\r
+} BROWSER_CONTEXT;\r
 \r
 \r
-  FORM_ENTRY_INFO            *CurrentMenu;\r
-} UI_MENU_SELECTION;\r
+#define BROWSER_CONTEXT_FROM_LINK(a)  CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)\r
 \r
 \r
-#define BROWSER_CONTEXT_SIGNATURE  SIGNATURE_32 ('B', 'C', 'T', 'X')\r
+#define BROWSER_HOT_KEY_SIGNATURE  SIGNATURE_32 ('B', 'H', 'K', 'S')\r
 \r
 typedef struct {\r
   UINTN                 Signature;\r
   LIST_ENTRY            Link;\r
 \r
 typedef struct {\r
   UINTN                 Signature;\r
   LIST_ENTRY            Link;\r
+  \r
+  EFI_INPUT_KEY         *KeyData;\r
+  IN UINT32             Action;\r
+  IN UINT16             DefaultId;\r
+  IN EFI_STRING         HelpString;\r
+} BROWSER_HOT_KEY;\r
 \r
 \r
-  //\r
-  // Globals defined in Setup.c\r
-  //\r
-  BOOLEAN                  ResetRequired;\r
-  BOOLEAN                  ExitRequired;\r
-  EFI_HII_HANDLE           HiiHandle;\r
-  EFI_GUID                 FormSetGuid;\r
-  EFI_FORM_ID              FormId;\r
-  UI_MENU_SELECTION        *Selection;\r
-\r
-  LIST_ENTRY           FormHistoryList;\r
-} BROWSER_CONTEXT;\r
-\r
-#define BROWSER_CONTEXT_FROM_LINK(a)  CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)\r
+#define BROWSER_HOT_KEY_FROM_LINK(a)  CR (a, BROWSER_HOT_KEY, Link, BROWSER_HOT_KEY_SIGNATURE)\r
 \r
 //\r
 // Scope for get defaut value. It may be GetDefaultForNoStorage, GetDefaultForStorage or GetDefaultForAll.\r
 \r
 //\r
 // Scope for get defaut value. It may be GetDefaultForNoStorage, GetDefaultForStorage or GetDefaultForAll.\r
@@ -532,31 +614,72 @@ typedef enum {
 } GET_SET_QUESTION_VALUE_WITH;\r
 \r
 extern EFI_HII_DATABASE_PROTOCOL         *mHiiDatabase;\r
 } GET_SET_QUESTION_VALUE_WITH;\r
 \r
 extern EFI_HII_DATABASE_PROTOCOL         *mHiiDatabase;\r
+extern EFI_HII_STRING_PROTOCOL           *mHiiString;\r
 extern EFI_HII_CONFIG_ROUTING_PROTOCOL   *mHiiConfigRouting;\r
 extern EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
 extern EFI_HII_CONFIG_ROUTING_PROTOCOL   *mHiiConfigRouting;\r
 extern EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;\r
-extern EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;\r
 \r
 \r
+extern BANNER_DATA           *gBannerData;\r
+extern EFI_HII_HANDLE        gFrontPageHandle;\r
+extern UINTN                 gClassOfVfr;\r
+extern UINTN                 gFunctionKeySetting;\r
 extern BOOLEAN               gResetRequired;\r
 extern BOOLEAN               gResetRequired;\r
-extern BOOLEAN               gExitRequired;\r
+extern EFI_HII_HANDLE        gHiiHandle;\r
+extern UINT16                gDirection;\r
+extern EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
 \r
 \r
+extern FORM_BROWSER_FORMSET  *gOldFormSet;\r
 extern LIST_ENTRY            gBrowserFormSetList;\r
 extern LIST_ENTRY            gBrowserHotKeyList;\r
 extern BROWSER_SETTING_SCOPE gBrowserSettingScope;\r
 extern EXIT_HANDLER          ExitHandlerFunction;\r
 extern LIST_ENTRY            gBrowserFormSetList;\r
 extern LIST_ENTRY            gBrowserHotKeyList;\r
 extern BROWSER_SETTING_SCOPE gBrowserSettingScope;\r
 extern EXIT_HANDLER          ExitHandlerFunction;\r
-extern EFI_HII_HANDLE        mCurrentHiiHandle;\r
+extern UINTN                 gFooterHeight;\r
+\r
 //\r
 // Browser Global Strings\r
 //\r
 //\r
 // Browser Global Strings\r
 //\r
+extern CHAR16            *gDiscardFailed;\r
+extern CHAR16            *gDefaultFailed;\r
+extern CHAR16            *gEnterString;\r
+extern CHAR16            *gEnterCommitString;\r
+extern CHAR16            *gEnterEscapeString;\r
+extern CHAR16            *gEscapeString;\r
+extern CHAR16            *gSaveFailed;\r
+extern CHAR16            *gMoveHighlight;\r
+extern CHAR16            *gMakeSelection;\r
+extern CHAR16            *gDecNumericInput;\r
+extern CHAR16            *gHexNumericInput;\r
+extern CHAR16            *gToggleCheckBox;\r
+extern CHAR16            *gPromptForData;\r
+extern CHAR16            *gPromptForPassword;\r
+extern CHAR16            *gPromptForNewPassword;\r
+extern CHAR16            *gConfirmPassword;\r
+extern CHAR16            *gConfirmError;\r
+extern CHAR16            *gPassowordInvalid;\r
+extern CHAR16            *gPressEnter;\r
 extern CHAR16            *gEmptyString;\r
 extern CHAR16            *gEmptyString;\r
+extern CHAR16            *gAreYouSure;\r
+extern CHAR16            *gYesResponse;\r
+extern CHAR16            *gNoResponse;\r
+extern CHAR16            *gMiniString;\r
+extern CHAR16            *gPlusString;\r
+extern CHAR16            *gMinusString;\r
+extern CHAR16            *gAdjustNumber;\r
+extern CHAR16            *gSaveChanges;\r
+extern CHAR16            *gOptionMismatch;\r
+extern CHAR16            *gFormSuppress;\r
+extern CHAR16            *gProtocolNotFound;\r
+\r
+extern CHAR16            gPromptBlockWidth;\r
+extern CHAR16            gOptionBlockWidth;\r
+extern CHAR16            gHelpBlockWidth;\r
 \r
 extern EFI_GUID          gZeroGuid;\r
 \r
 extern EFI_GUID          gZeroGuid;\r
+extern EFI_GUID          gTianoHiiIfrGuid;\r
 \r
 \r
-extern UI_MENU_SELECTION  *gCurrentSelection;\r
-\r
+#include "Ui.h"\r
 //\r
 // Global Procedure Defines\r
 //\r
 //\r
 // Global Procedure Defines\r
 //\r
-#include "Expression.h"\r
 \r
 /**\r
   Initialize the HII String Token to the correct values.\r
 \r
 /**\r
   Initialize the HII String Token to the correct values.\r
@@ -567,6 +690,91 @@ InitializeBrowserStrings (
   VOID\r
   );\r
 \r
   VOID\r
   );\r
 \r
+/**\r
+  Prints a unicode string to the default console,\r
+  using L"%s" format.\r
+\r
+  @param  String     String pointer.\r
+\r
+  @return Length of string printed to the console\r
+\r
+**/\r
+UINTN\r
+PrintString (\r
+  IN CHAR16       *String\r
+  );\r
+\r
+/**\r
+  Prints a chracter to the default console,\r
+  using L"%c" format.\r
+\r
+  @param  Character  Character to print.\r
+\r
+  @return Length of string printed to the console.\r
+\r
+**/\r
+UINTN\r
+PrintChar (\r
+  CHAR16       Character\r
+  );\r
+\r
+/**\r
+  Prints a formatted unicode string to the default console, at\r
+  the supplied cursor position.\r
+\r
+  @param  Column     The cursor position to print the string at.\r
+  @param  Row        The cursor position to print the string at\r
+  @param  Fmt        Format string\r
+  @param  ...        Variable argument list for formating string.\r
+\r
+  @return Length of string printed to the console\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PrintAt (\r
+  IN UINTN     Column,\r
+  IN UINTN     Row,\r
+  IN CHAR16    *Fmt,\r
+  ...\r
+  );\r
+\r
+/**\r
+  Prints a unicode string to the default console, at\r
+  the supplied cursor position, using L"%s" format.\r
+\r
+  @param  Column     The cursor position to print the string at.\r
+  @param  Row        The cursor position to print the string at\r
+  @param  String     String pointer.\r
+\r
+  @return Length of string printed to the console\r
+\r
+**/\r
+UINTN\r
+PrintStringAt (\r
+  IN UINTN     Column,\r
+  IN UINTN     Row,\r
+  IN CHAR16    *String\r
+  );\r
+\r
+/**\r
+  Prints a chracter to the default console, at\r
+  the supplied cursor position, using L"%c" format.\r
+\r
+  @param  Column     The cursor position to print the string at.\r
+  @param  Row        The cursor position to print the string at.\r
+  @param  Character  Character to print.\r
+\r
+  @return Length of string printed to the console.\r
+\r
+**/\r
+UINTN\r
+PrintCharAt (\r
+  IN UINTN     Column,\r
+  IN UINTN     Row,\r
+  CHAR16       Character\r
+  );\r
+\r
 /**\r
   Parse opcodes in the formset IFR binary.\r
 \r
 /**\r
   Parse opcodes in the formset IFR binary.\r
 \r
@@ -592,6 +800,17 @@ DestroyFormSet (
   IN OUT FORM_BROWSER_FORMSET  *FormSet\r
   );\r
 \r
   IN OUT FORM_BROWSER_FORMSET  *FormSet\r
   );\r
 \r
+/**\r
+  This function displays the page frame.\r
+\r
+  @param  Selection              Selection contains the information about \r
+                                 the Selection, form and formset to be displayed.\r
+                                 Selection action may be updated in retrieve callback.\r
+**/\r
+VOID\r
+DisplayPageFrame (\r
+  IN UI_MENU_SELECTION    *Selection\r
+  );\r
 \r
 /**\r
   Create a new string in HII Package List.\r
 \r
 /**\r
   Create a new string in HII Package List.\r
@@ -640,6 +859,59 @@ GetToken (
   IN  EFI_HII_HANDLE               HiiHandle\r
   );\r
 \r
   IN  EFI_HII_HANDLE               HiiHandle\r
   );\r
 \r
+/**\r
+  Draw a pop up windows based on the dimension, number of lines and\r
+  strings specified.\r
+\r
+  @param RequestedWidth  The width of the pop-up.\r
+  @param NumberOfLines   The number of lines.\r
+  @param Marker          The variable argument list for the list of string to be printed.\r
+\r
+**/\r
+VOID\r
+CreateSharedPopUp (\r
+  IN  UINTN                       RequestedWidth,\r
+  IN  UINTN                       NumberOfLines,\r
+  IN  VA_LIST                     Marker\r
+  );\r
+\r
+/**\r
+  Routine used to abstract a generic dialog interface and return the selected key or string\r
+\r
+  @param  NumberOfLines          The number of lines for the dialog box\r
+  @param  HotKey                 Defines whether a single character is parsed\r
+                                 (TRUE) and returned in KeyValue or a string is\r
+                                 returned in StringBuffer.  Two special characters\r
+                                 are considered when entering a string, a SCAN_ESC\r
+                                 and an CHAR_CARRIAGE_RETURN.  SCAN_ESC terminates\r
+                                 string input and returns\r
+  @param  MaximumStringSize      The maximum size in bytes of a typed in string\r
+                                 (each character is a CHAR16) and the minimum\r
+                                 string returned is two bytes\r
+  @param  StringBuffer           The passed in pointer to the buffer which will\r
+                                 hold the typed in string if HotKey is FALSE\r
+  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..\r
+  @param  ...                    A series of (quantity == NumberOfLines) text\r
+                                 strings which will be used to construct the dialog\r
+                                 box\r
+\r
+  @retval EFI_SUCCESS            Displayed dialog and received user interaction\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid (e.g.\r
+                                 (StringBuffer == NULL) && (HotKey == FALSE))\r
+  @retval EFI_DEVICE_ERROR       User typed in an ESC character to exit the routine\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateDialog (\r
+  IN  UINTN                       NumberOfLines,\r
+  IN  BOOLEAN                     HotKey,\r
+  IN  UINTN                       MaximumStringSize,\r
+  OUT CHAR16                      *StringBuffer,\r
+  OUT EFI_INPUT_KEY               *KeyValue,\r
+  ...\r
+  );\r
+\r
 /**\r
   Get Value for given Name from a NameValue Storage.\r
 \r
 /**\r
   Get Value for given Name from a NameValue Storage.\r
 \r
@@ -667,7 +939,6 @@ GetValueByName (
   @param  Name                   The Name.\r
   @param  Value                  The Value to set.\r
   @param  SetValueTo             Whether update editValue or Value.\r
   @param  Name                   The Name.\r
   @param  Value                  The Value to set.\r
   @param  SetValueTo             Whether update editValue or Value.\r
-  @param  ReturnNode             The node use the input name.\r
 \r
   @retval EFI_SUCCESS            Value found for given Name.\r
   @retval EFI_NOT_FOUND          No such Name found in NameValue storage.\r
 \r
   @retval EFI_SUCCESS            Value found for given Name.\r
   @retval EFI_NOT_FOUND          No such Name found in NameValue storage.\r
@@ -675,31 +946,10 @@ GetValueByName (
 **/\r
 EFI_STATUS\r
 SetValueByName (\r
 **/\r
 EFI_STATUS\r
 SetValueByName (\r
-  IN  BROWSER_STORAGE             *Storage,\r
-  IN  CHAR16                      *Name,\r
-  IN  CHAR16                      *Value,\r
-  IN  GET_SET_QUESTION_VALUE_WITH SetValueTo,\r
-  OUT NAME_VALUE_NODE             **ReturnNode\r
-  );\r
-\r
-/**\r
-  Validate whether this question's value has changed.\r
-\r
-  @param  FormSet                FormSet data structure.\r
-  @param  Form                   Form data structure.\r
-  @param  Question               Question to be initialized.\r
-  @param  GetValueFrom           Where to get value, may from editbuffer, buffer or hii driver.\r
-\r
-  @retval TRUE                   Question's value has changed.\r
-  @retval FALSE                  Question's value has not changed\r
-\r
-**/\r
-BOOLEAN\r
-IsQuestionValueChanged (\r
-  IN FORM_BROWSER_FORMSET             *FormSet,\r
-  IN FORM_BROWSER_FORM                *Form,\r
-  IN OUT FORM_BROWSER_STATEMENT       *Question,\r
-  IN GET_SET_QUESTION_VALUE_WITH      GetValueFrom\r
+  IN BROWSER_STORAGE             *Storage,\r
+  IN CHAR16                      *Name,\r
+  IN CHAR16                      *Value,\r
+  IN GET_SET_QUESTION_VALUE_WITH SetValueTo\r
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
@@ -821,8 +1071,10 @@ GetQuestionDefault (
 \r
   @param  FormSet                FormSet data structure.\r
 \r
 \r
   @param  FormSet                FormSet data structure.\r
 \r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 InitializeCurrentSetting (\r
   IN OUT FORM_BROWSER_FORMSET             *FormSet\r
   );\r
 InitializeCurrentSetting (\r
   IN OUT FORM_BROWSER_FORMSET             *FormSet\r
   );\r
@@ -835,6 +1087,7 @@ InitializeCurrentSetting (
                                  GUID), take the first FormSet found in package\r
                                  list.\r
   @param  FormSet                FormSet data structure.\r
                                  GUID), take the first FormSet found in package\r
                                  list.\r
   @param  FormSet                FormSet data structure.\r
+  @param  UpdateGlobalVar        Whether need to update the global variable.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
   @retval EFI_NOT_FOUND          The specified FormSet could not be found.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
   @retval EFI_NOT_FOUND          The specified FormSet could not be found.\r
@@ -844,7 +1097,8 @@ EFI_STATUS
 InitializeFormSet (\r
   IN  EFI_HII_HANDLE                   Handle,\r
   IN OUT EFI_GUID                      *FormSetGuid,\r
 InitializeFormSet (\r
   IN  EFI_HII_HANDLE                   Handle,\r
   IN OUT EFI_GUID                      *FormSetGuid,\r
-  OUT FORM_BROWSER_FORMSET             *FormSet                   \r
+  OUT FORM_BROWSER_FORMSET             *FormSet,\r
+  IN  BOOLEAN                          UpdateGlobalVar                   \r
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
@@ -922,7 +1176,6 @@ LoadFormSetConfig (
   @param  Storage                The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
   @param  ConfigRequest          The ConfigRequest string.\r
   @param  Storage                The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
   @param  ConfigRequest          The ConfigRequest string.\r
-  @param  GetEditBuf             Get the data from editbuffer or buffer.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
@@ -932,8 +1185,7 @@ EFI_STATUS
 StorageToConfigResp (\r
   IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  **ConfigResp,\r
 StorageToConfigResp (\r
   IN BROWSER_STORAGE         *Storage,\r
   IN CHAR16                  **ConfigResp,\r
-  IN CHAR16                  *ConfigRequest,\r
-  IN BOOLEAN                 GetEditBuf\r
+  IN CHAR16                  *ConfigRequest\r
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
@@ -958,8 +1210,10 @@ ConfigRespToStorage (
   @param  FormSet                FormSet data structure.\r
   @param  Storage                Buffer Storage.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Storage                Buffer Storage.\r
 \r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 LoadStorage (\r
   IN FORM_BROWSER_FORMSET    *FormSet,\r
   IN FORMSET_STORAGE         *Storage\r
 LoadStorage (\r
   IN FORM_BROWSER_FORMSET    *FormSet,\r
   IN FORMSET_STORAGE         *Storage\r
@@ -1095,29 +1349,30 @@ BrowserCallback (
                          about the Selection, form and formset to be displayed.\r
                          On output, Selection return the screen item that is selected\r
                          by user.\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
-  @param SettingLevel    Input Settting level, if it is FormLevel, just exit current form. \r
-                         else, we need to exit current formset.\r
+  @param Repaint         Whether need to repaint the menu.\r
+  @param NewLine         Whether need to show at new line.\r
   \r
   \r
-  @retval TRUE           Exit current form.\r
-  @retval FALSE          User press ESC and keep in current form.\r
+  @retval TRUE           Need return.\r
+  @retval FALSE          No need to return.\r
 **/\r
 BOOLEAN\r
 FindNextMenu (\r
 **/\r
 BOOLEAN\r
 FindNextMenu (\r
-  IN OUT UI_MENU_SELECTION        *Selection,\r
-  IN       BROWSER_SETTING_SCOPE  SettingLevel\r
+  IN OUT UI_MENU_SELECTION    *Selection,\r
+  IN     BOOLEAN              *Repaint, \r
+  IN     BOOLEAN              *NewLine  \r
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
-  check whether the form need to update the NV.\r
+  check whether the formset need to update the NV.\r
 \r
 \r
-  @param  Form                Form data structure.\r
+  @param  FormSet                FormSet data structure.\r
+  @param  SetValue               Whether set new value or clear old value.\r
 \r
 \r
-  @retval TRUE                   Need to update the NV.\r
-  @retval FALSE                  No need to update the NV.\r
 **/\r
 **/\r
-BOOLEAN\r
-IsNvUpdateRequiredForForm (\r
-  IN FORM_BROWSER_FORM    *Form\r
+VOID\r
+UpdateNvInfoInForm (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN BOOLEAN               SetValue\r
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
@@ -1128,22 +1383,9 @@ IsNvUpdateRequiredForForm (
   @retval TRUE                   Need to update the NV.\r
   @retval FALSE                  No need to update the NV.\r
 **/\r
   @retval TRUE                   Need to update the NV.\r
   @retval FALSE                  No need to update the NV.\r
 **/\r
-BOOLEAN\r
-IsNvUpdateRequiredForFormSet (\r
-  IN FORM_BROWSER_FORMSET  *FormSet\r
-  );\r
-\r
-/**\r
-  Check whether the storage data for current form set is changed.\r
-\r
-  @param  FormSet           FormSet data structure.\r
-\r
-  @retval TRUE              Data is changed.\r
-  @retval FALSE             Data is not changed.\r
-**/\r
 BOOLEAN \r
 BOOLEAN \r
-IsStorageDataChangedForFormSet (\r
-  IN FORM_BROWSER_FORMSET             *FormSet\r
+IsNvUpdateRequired (\r
+  IN FORM_BROWSER_FORMSET  *FormSet\r
   );\r
 \r
 /**\r
   );\r
 \r
 /**\r
@@ -1274,38 +1516,6 @@ RegiserExitHandler (
   IN EXIT_HANDLER Handler\r
   );\r
 \r
   IN EXIT_HANDLER Handler\r
   );\r
 \r
-/**\r
-  \r
-  Check whether the browser data has been modified. \r
-\r
-  @retval TRUE        Browser data is changed.\r
-  @retval FALSE       No browser data is changed.\r
-\r
-**/\r
-BOOLEAN \r
-EFIAPI\r
-IsBrowserDataModified (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  \r
-  Execute the action requested by the Action parameter. \r
-\r
-  @param[in] Action     Execute the request action.\r
-  @param[in] DefaultId  The default Id info when need to load default value.\r
-\r
-  @retval EFI_SUCCESS              Execute the request action succss.\r
-  @retval EFI_INVALID_PARAMETER    The input action value is invalid.\r
-\r
-**/\r
-EFI_STATUS \r
-EFIAPI\r
-ExecuteAction (\r
-  IN UINT32        Action,\r
-  IN UINT16        DefaultId\r
-  );\r
-\r
 /**\r
   Create reminder to let user to choose save or discard the changed browser data.\r
   Caller can use it to actively check the changed browser data.\r
 /**\r
   Create reminder to let user to choose save or discard the changed browser data.\r
   Caller can use it to actively check the changed browser data.\r
@@ -1334,267 +1544,6 @@ GetHotKeyFromRegisterList (
   IN EFI_INPUT_KEY *KeyData\r
   );\r
 \r
   IN EFI_INPUT_KEY *KeyData\r
   );\r
 \r
-/**\r
-\r
-  Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.\r
-\r
-  @param DisplayStatement        The input FORM_DISPLAY_ENGINE_STATEMENT.\r
-\r
-  @retval FORM_BROWSER_STATEMENT  The return FORM_BROWSER_STATEMENT info.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-GetBrowserStatement (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement\r
-  );\r
-  \r
-/**\r
-  Password may be stored as encrypted by Configuration Driver. When change a\r
-  password, user will be challenged with old password. To validate user input old\r
-  password, we will send the clear text to Configuration Driver via Callback().\r
-  Configuration driver is responsible to check the passed in password and return\r
-  the validation result. If validation pass, state machine in password Callback()\r
-  will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.\r
-  After user type in new password twice, Callback() will be invoked to send the\r
-  new password to Configuration Driver.\r
-\r
-  @param  Selection              Pointer to UI_MENU_SELECTION.\r
-  @param  MenuOption             The MenuOption for this password Question.\r
-  @param  String                 The clear text of password.\r
-\r
-  @retval EFI_NOT_AVAILABLE_YET  Callback() request to terminate password input.\r
-  @return In state of BROWSER_STATE_VALIDATE_PASSWORD:\r
-  @retval EFI_SUCCESS            Password correct, Browser will prompt for new\r
-                                 password.\r
-  @retval EFI_NOT_READY          Password incorrect, Browser will show error\r
-                                 message.\r
-  @retval Other                  Browser will do nothing.\r
-  @return In state of BROWSER_STATE_SET_PASSWORD:\r
-  @retval EFI_SUCCESS            Set password success.\r
-  @retval Other                  Set password failed.\r
-\r
-**/\r
-EFI_STATUS\r
-PasswordCallback (\r
-  IN  UI_MENU_SELECTION           *Selection,\r
-  IN  FORM_BROWSER_STATEMENT      *Question,\r
-  IN  CHAR16                      *String\r
-  );\r
-\r
-/**\r
-  Display error message for invalid password.\r
-\r
-**/\r
-VOID\r
-PasswordInvalid (\r
-  VOID\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
-/**\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
-/**\r
-  Create a menu with specified formset GUID and form ID, and add it as a child\r
-  of the given parent menu.\r
-\r
-  @param  HiiHandle              Hii handle related to this formset.\r
-  @param  FormSetGuid            The Formset Guid of menu to be added.\r
-  @param  FormId                 The Form ID of menu to be added.\r
-  @param  QuestionId             The question id of this menu to be added.\r
-\r
-  @return A pointer to the newly added menu or NULL if memory is insufficient.\r
-\r
-**/\r
-FORM_ENTRY_INFO *\r
-UiAddMenuList (\r
-  IN EFI_HII_HANDLE       HiiHandle,\r
-  IN EFI_GUID             *FormSetGuid,\r
-  IN UINT16               FormId,\r
-  IN UINT16               QuestionId\r
-  );\r
-\r
-/**\r
-  Search Menu with given FormSetGuid and FormId in all cached menu list.\r
-\r
-  @param  HiiHandle              HiiHandle for FormSet.\r
-  @param  FormSetGuid            The Formset GUID of the menu to search.\r
-  @param  FormId                 The Form ID of menu to search.\r
-\r
-  @return A pointer to menu found or NULL if not found.\r
-\r
-**/\r
-FORM_ENTRY_INFO *\r
-UiFindMenuList (\r
-  IN EFI_HII_HANDLE       HiiHandle, \r
-  IN EFI_GUID             *FormSetGuid,\r
-  IN UINT16               FormId\r
-  );\r
-\r
-/**\r
-  Free Menu list linked list.\r
-\r
-  @param  MenuListHead    One Menu list point in the menu list.\r
-\r
-**/\r
-VOID\r
-UiFreeMenuList (\r
-  LIST_ENTRY   *MenuListHead\r
-  );\r
-\r
-/**\r
-  Find parent menu for current menu.\r
-\r
-  @param  CurrentMenu    Current Menu\r
-\r
-  @retval   The parent menu for current menu.\r
-**/\r
-FORM_ENTRY_INFO *\r
-UiFindParentMenu (\r
-  IN FORM_ENTRY_INFO  *CurrentMenu\r
-  );\r
-\r
-/**\r
-  Search an Option of a Question by its value.\r
-\r
-  @param  Question               The Question\r
-  @param  OptionValue            Value for Option to be searched.\r
-\r
-  @retval Pointer                Pointer to the found Option.\r
-  @retval NULL                   Option not found.\r
-\r
-**/\r
-QUESTION_OPTION *\r
-ValueToOption (\r
-  IN FORM_BROWSER_STATEMENT   *Question,\r
-  IN EFI_HII_VALUE            *OptionValue\r
-  );\r
-/**\r
-  Return data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-\r
-  @retval Value                  The data to be returned\r
-\r
-**/\r
-UINT64\r
-GetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index\r
-  );\r
-\r
-/**\r
-  Set value of a data element in an Array by its Index.\r
-\r
-  @param  Array                  The data array.\r
-  @param  Type                   Type of the data in this array.\r
-  @param  Index                  Zero based index for data in this array.\r
-  @param  Value                  The value to be set.\r
-\r
-**/\r
-VOID\r
-SetArrayData (\r
-  IN VOID                     *Array,\r
-  IN UINT8                    Type,\r
-  IN UINTN                    Index,\r
-  IN UINT64                   Value\r
-  );\r
-\r
-/**\r
-   Compare two Hii value.\r
\r
-   @param  Value1                 Expression value to compare on left-hand.\r
-   @param  Value2                 Expression value to compare on right-hand.\r
-   @param  Result                 Return value after compare.\r
-                                  retval 0                      Two operators equal.\r
-                                  return Positive value if Value1 is greater than Value2.\r
-                                  retval Negative value if Value1 is less than Value2.\r
-   @param  HiiHandle              Only required for string compare.\r
\r
-   @retval other                  Could not perform compare on two values.\r
-   @retval EFI_SUCCESS            Compare the value success.\r
\r
-**/\r
-EFI_STATUS\r
-CompareHiiValue (\r
-  IN  EFI_HII_VALUE   *Value1,\r
-  IN  EFI_HII_VALUE   *Value2,\r
-  OUT INTN            *Result,\r
-  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL\r
-  );\r
-\r
-/**\r
-  Perform Password check. \r
-  Passwork may be encrypted by driver that requires the specific check.\r
-  \r
-  @param  Form             Form where Password Statement is in.\r
-  @param  Statement        Password statement\r
-  @param  PasswordString   Password string to be checked. It may be NULL.\r
-                           NULL means to restore password.\r
-                           "" string can be used to checked whether old password does exist.\r
-  \r
-  @return Status     Status of Password check.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PasswordCheck (\r
-  IN FORM_DISPLAY_ENGINE_FORM      *Form,\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
-  IN EFI_STRING                    PasswordString  OPTIONAL\r
-  );\r
-\r
-/**\r
-\r
-  Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.\r
-\r
-  @param DisplayStatement        The input FORM_DISPLAY_ENGINE_STATEMENT.\r
-\r
-  @retval FORM_BROWSER_STATEMENT  The return FORM_BROWSER_STATEMENT info.\r
-\r
-**/\r
-FORM_BROWSER_STATEMENT *\r
-GetBrowserStatement (\r
-  IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement\r
-  );\r
-  \r
-/**\r
-\r
-  Initialize the Display form structure data.\r
-\r
-**/\r
-VOID\r
-InitializeDisplayFormData (\r
-  VOID\r
-  );\r
-\r
-\r
 /**\r
   Base on the current formset info, clean the ConfigRequest string in browser storage.\r
 \r
 /**\r
   Base on the current formset info, clean the ConfigRequest string in browser storage.\r
 \r
@@ -1605,5 +1554,5 @@ VOID
 CleanBrowserStorage (\r
   IN OUT FORM_BROWSER_FORMSET  *FormSet\r
   );\r
 CleanBrowserStorage (\r
   IN OUT FORM_BROWSER_FORMSET  *FormSet\r
   );\r
-  \r
+\r
 #endif\r
 #endif\r
index a3f3a6fc2c8e078930528e842aee8434f540ec06..7e740bc0990548c0041afafa1c623dc5d8432587 100644 (file)
@@ -19,7 +19,7 @@
   BASE_NAME                      = SetupBrowser\r
   FILE_GUID                      = EBf342FE-B1D3-4EF8-957C-8048606FF671\r
   MODULE_TYPE                    = DXE_DRIVER\r
   BASE_NAME                      = SetupBrowser\r
   FILE_GUID                      = EBf342FE-B1D3-4EF8-957C-8048606FF671\r
   MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 2.0\r
+  VERSION_STRING                 = 1.0\r
   ENTRY_POINT                    = InitializeSetup\r
 \r
 #\r
   ENTRY_POINT                    = InitializeSetup\r
 \r
 #\r
 #\r
 \r
 [Sources]\r
 #\r
 \r
 [Sources]\r
+  SetupBrowserStr.uni\r
   Setup.c\r
   Setup.h\r
   IfrParse.c\r
   Expression.c\r
   Setup.c\r
   Setup.h\r
   IfrParse.c\r
   Expression.c\r
+  InputHandler.c\r
+  Print.c\r
   Presentation.c\r
   Presentation.c\r
-  Expression.h\r
+  ProcessOptions.c\r
+  Ui.c\r
+  Ui.h\r
+  Colors.h\r
+\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   HiiLib\r
   DevicePathLib\r
   PcdLib\r
   HiiLib\r
   DevicePathLib\r
   PcdLib\r
-  UefiLib\r
 \r
 [Guids]\r
 \r
 [Guids]\r
+  gEfiIfrTianoGuid                              ## CONSUMES  ## GUID\r
   gEfiIfrFrameworkGuid                          ## CONSUMES  ## GUID\r
   gEfiHiiPlatformSetupFormsetGuid\r
   gEfiHiiStandardFormGuid                       ## SOMETIMES_CONSUMES ## GUID\r
 \r
 [Protocols]\r
   gEfiHiiConfigAccessProtocolGuid               ## CONSUMES\r
   gEfiIfrFrameworkGuid                          ## CONSUMES  ## GUID\r
   gEfiHiiPlatformSetupFormsetGuid\r
   gEfiHiiStandardFormGuid                       ## SOMETIMES_CONSUMES ## GUID\r
 \r
 [Protocols]\r
   gEfiHiiConfigAccessProtocolGuid               ## CONSUMES\r
+  gEfiHiiStringProtocolGuid                     ## CONSUMES\r
   gEfiFormBrowser2ProtocolGuid                  ## PRODUCES\r
   gEfiFormBrowser2ProtocolGuid                  ## PRODUCES\r
-  gEdkiiFormBrowserEx2ProtocolGuid              ## PRODUCES\r
+  gEfiFormBrowserExProtocolGuid                 ## PRODUCES\r
   gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES\r
   gEfiHiiDatabaseProtocolGuid                   ## CONSUMES\r
   gEfiUnicodeCollation2ProtocolGuid             ## CONSUMES\r
   gEfiUserManagerProtocolGuid                   ## SOMETIMES_CONSUMES\r
   gEfiDevicePathFromTextProtocolGuid            ## SOMETIMES_CONSUMES\r
   gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES\r
   gEfiHiiDatabaseProtocolGuid                   ## CONSUMES\r
   gEfiUnicodeCollation2ProtocolGuid             ## CONSUMES\r
   gEfiUserManagerProtocolGuid                   ## SOMETIMES_CONSUMES\r
   gEfiDevicePathFromTextProtocolGuid            ## SOMETIMES_CONSUMES\r
-  gEdkiiFormDisplayEngineProtocolGuid           ## PRODUCE\r
-  gEfiFormBrowserExProtocolGuid                 ## PRODUCE\r
 \r
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport          ## CONSUMES\r
 \r
 [FeaturePcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport          ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement            ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu              ## CONSUMES\r
+\r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor               ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor                  ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextHighlightColor         ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldBackgroundHighlightColor   ## CONSUMES\r
 \r
 [Depex]\r
   gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid\r
 \r
 [Depex]\r
   gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni
new file mode 100644 (file)
index 0000000..bb6414d
Binary files /dev/null and b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni differ
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
new file mode 100644 (file)
index 0000000..7c246b6
--- /dev/null
@@ -0,0 +1,4027 @@
+/** @file\r
+Utility functions for User Interface functions.\r
+\r
+Copyright (c) 2004 - 2013, 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
+LIST_ENTRY          gMenuOption;\r
+LIST_ENTRY          gMenuList;\r
+MENU_REFRESH_ENTRY  *gMenuRefreshHead;                // Menu list used for refresh timer opcode.\r
+MENU_REFRESH_ENTRY  *gMenuEventGuidRefreshHead;       // Menu list used for refresh event guid opcode.\r
+\r
+//\r
+// Search table for UiDisplayMenu()\r
+//\r
+SCAN_CODE_TO_SCREEN_OPERATION     gScanCodeToOperation[] = {\r
+  {\r
+    SCAN_UP,\r
+    UiUp,\r
+  },\r
+  {\r
+    SCAN_DOWN,\r
+    UiDown,\r
+  },\r
+  {\r
+    SCAN_PAGE_UP,\r
+    UiPageUp,\r
+  },\r
+  {\r
+    SCAN_PAGE_DOWN,\r
+    UiPageDown,\r
+  },\r
+  {\r
+    SCAN_ESC,\r
+    UiReset,\r
+  },\r
+  {\r
+    SCAN_LEFT,\r
+    UiLeft,\r
+  },\r
+  {\r
+    SCAN_RIGHT,\r
+    UiRight,\r
+  }\r
+};\r
+\r
+UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);\r
+\r
+SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {\r
+  {\r
+    UiNoOperation,\r
+    CfUiNoOperation,\r
+  },\r
+  {\r
+    UiSelect,\r
+    CfUiSelect,\r
+  },\r
+  {\r
+    UiUp,\r
+    CfUiUp,\r
+  },\r
+  {\r
+    UiDown,\r
+    CfUiDown,\r
+  },\r
+  {\r
+    UiLeft,\r
+    CfUiLeft,\r
+  },\r
+  {\r
+    UiRight,\r
+    CfUiRight,\r
+  },\r
+  {\r
+    UiReset,\r
+    CfUiReset,\r
+  },\r
+  {\r
+    UiPageUp,\r
+    CfUiPageUp,\r
+  },\r
+  {\r
+    UiPageDown,\r
+    CfUiPageDown\r
+  }, \r
+  {\r
+    UiHotKey,\r
+    CfUiHotKey\r
+  }\r
+};\r
+\r
+BOOLEAN  mInputError;\r
+BOOLEAN GetLineByWidthFinished = FALSE;\r
+\r
+\r
+/**\r
+  Set Buffer to Value for Size bytes.\r
+\r
+  @param  Buffer                 Memory to set.\r
+  @param  Size                   Number of bytes to set\r
+  @param  Value                  Value of the set operation.\r
+\r
+**/\r
+VOID\r
+SetUnicodeMem (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Size,\r
+  IN CHAR16 Value\r
+  )\r
+{\r
+  CHAR16  *Ptr;\r
+\r
+  Ptr = Buffer;\r
+  while ((Size--)  != 0) {\r
+    *(Ptr++) = Value;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Initialize Menu option list.\r
+\r
+**/\r
+VOID\r
+UiInitMenu (\r
+  VOID\r
+  )\r
+{\r
+  InitializeListHead (&gMenuOption);\r
+}\r
+\r
+\r
+/**\r
+  Free Menu option linked list.\r
+\r
+**/\r
+VOID\r
+UiFreeMenu (\r
+  VOID\r
+  )\r
+{\r
+  UI_MENU_OPTION  *MenuOption;\r
+\r
+  while (!IsListEmpty (&gMenuOption)) {\r
+    MenuOption = MENU_OPTION_FROM_LINK (gMenuOption.ForwardLink);\r
+    RemoveEntryList (&MenuOption->Link);\r
+\r
+    //\r
+    // We allocated space for this description when we did a GetToken, free it here\r
+    //\r
+    if (MenuOption->Skip != 0) {\r
+      //\r
+      // For date/time, MenuOption->Description is shared by three Menu Options\r
+      // Data format :      [01/02/2004]      [11:22:33]\r
+      // Line number :        0  0    1         0  0  1\r
+      //\r
+      FreePool (MenuOption->Description);\r
+    }\r
+    FreePool (MenuOption);\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Create a menu with specified formset GUID and form ID, and add it as a child\r
+  of the given parent menu.\r
+\r
+  @param  Parent                 The parent of menu to be added.\r
+  @param  HiiHandle              Hii handle related to this formset.\r
+  @param  FormSetGuid            The Formset Guid of menu to be added.\r
+  @param  FormId                 The Form ID of menu to be added.\r
+\r
+  @return A pointer to the newly added menu or NULL if memory is insufficient.\r
+\r
+**/\r
+UI_MENU_LIST *\r
+UiAddMenuList (\r
+  IN OUT UI_MENU_LIST     *Parent,\r
+  IN EFI_HII_HANDLE       HiiHandle,\r
+  IN EFI_GUID             *FormSetGuid,\r
+  IN UINT16               FormId\r
+  )\r
+{\r
+  UI_MENU_LIST  *MenuList;\r
+\r
+  MenuList = AllocateZeroPool (sizeof (UI_MENU_LIST));\r
+  if (MenuList == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  MenuList->Signature = UI_MENU_LIST_SIGNATURE;\r
+  InitializeListHead (&MenuList->ChildListHead);\r
+\r
+  MenuList->HiiHandle = HiiHandle;\r
+  CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));\r
+  MenuList->FormId = FormId;\r
+  MenuList->Parent = Parent;\r
+\r
+  if (Parent == NULL) {\r
+    //\r
+    // If parent is not specified, it is the root Form of a Formset\r
+    //\r
+    InsertTailList (&gMenuList, &MenuList->Link);\r
+  } else {\r
+    InsertTailList (&Parent->ChildListHead, &MenuList->Link);\r
+  }\r
+\r
+  return MenuList;\r
+}\r
+\r
+\r
+/**\r
+  Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.\r
+\r
+  @param  Parent                 The parent of menu to search.\r
+  @param  Handle                 Hii handle related to this formset.\r
+  @param  FormSetGuid            The Formset GUID of the menu to search.  \r
+  @param  FormId                 The Form ID of menu to search.\r
+\r
+  @return A pointer to menu found or NULL if not found.\r
+\r
+**/\r
+UI_MENU_LIST *\r
+UiFindChildMenuList (\r
+  IN UI_MENU_LIST         *Parent,\r
+  IN EFI_HII_HANDLE       Handle,\r
+  IN EFI_GUID             *FormSetGuid, \r
+  IN UINT16               FormId\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  UI_MENU_LIST    *Child;\r
+  UI_MENU_LIST    *MenuList;\r
+\r
+  ASSERT (Parent != NULL);\r
+\r
+  if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid) && Parent->HiiHandle == Handle) {\r
+    return Parent;\r
+  }\r
+\r
+  Link = GetFirstNode (&Parent->ChildListHead);\r
+  while (!IsNull (&Parent->ChildListHead, Link)) {\r
+    Child = UI_MENU_LIST_FROM_LINK (Link);\r
+\r
+    MenuList = UiFindChildMenuList (Child, Handle, FormSetGuid, FormId);\r
+    if (MenuList != NULL) {\r
+      return MenuList;\r
+    }\r
+\r
+    Link = GetNextNode (&Parent->ChildListHead, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+\r
+/**\r
+  Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.\r
+\r
+  @param  Handle                 Hii handle related to this formset.\r
+  @param  FormSetGuid            The Formset GUID of the menu to search.\r
+  @param  FormId                 The Form ID of menu to search.\r
+\r
+  @return A pointer to menu found or NULL if not found.\r
+\r
+**/\r
+UI_MENU_LIST *\r
+UiFindMenuList (\r
+  IN EFI_HII_HANDLE       Handle,\r
+  IN EFI_GUID             *FormSetGuid,\r
+  IN UINT16               FormId\r
+  )\r
+{\r
+  LIST_ENTRY      *Link;\r
+  UI_MENU_LIST    *MenuList;\r
+  UI_MENU_LIST    *Child;\r
+\r
+  Link = GetFirstNode (&gMenuList);\r
+  while (!IsNull (&gMenuList, Link)) {\r
+    MenuList = UI_MENU_LIST_FROM_LINK (Link);\r
+\r
+    Child = UiFindChildMenuList(MenuList, Handle, FormSetGuid, FormId);\r
+    if (Child != NULL) {\r
+\r
+      //\r
+      // If this form already in the menu history list,\r
+      // just free the list between old this form.\r
+      //\r
+      UiFreeMenuList(&Child->ChildListHead);\r
+      return Child;\r
+    }\r
+\r
+    Link = GetNextNode (&gMenuList, Link);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Free Menu list linked list.\r
+\r
+  @param  MenuListHead    One Menu list point in the menu list.\r
+\r
+**/\r
+VOID\r
+UiFreeMenuList (\r
+  LIST_ENTRY   *MenuListHead\r
+  )\r
+{\r
+  UI_MENU_LIST    *MenuList;\r
+\r
+  while (!IsListEmpty (MenuListHead)) {\r
+    MenuList = UI_MENU_LIST_FROM_LINK (MenuListHead->ForwardLink);\r
+    RemoveEntryList (&MenuList->Link);\r
+    \r
+    UiFreeMenuList(&MenuList->ChildListHead);\r
+    FreePool (MenuList);\r
+  }\r
+\r
+}\r
+\r
+/**\r
+  Free Menu option linked list.\r
+\r
+**/\r
+VOID\r
+UiFreeRefreshList (\r
+  VOID\r
+  )\r
+{\r
+  MENU_REFRESH_ENTRY  *OldMenuRefreshEntry;\r
+\r
+  while (gMenuRefreshHead != NULL) {\r
+    OldMenuRefreshEntry = gMenuRefreshHead->Next;\r
+    FreePool (gMenuRefreshHead);\r
+    gMenuRefreshHead = OldMenuRefreshEntry;\r
+  }\r
+\r
+  while (gMenuEventGuidRefreshHead != NULL) {\r
+    OldMenuRefreshEntry = gMenuEventGuidRefreshHead->Next;\r
+    if (gMenuEventGuidRefreshHead != NULL) {\r
+      gBS->CloseEvent(gMenuEventGuidRefreshHead->Event);\r
+    }\r
+    FreePool (gMenuEventGuidRefreshHead);\r
+    gMenuEventGuidRefreshHead = OldMenuRefreshEntry;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Process option string for date/time opcode.\r
+\r
+  @param  MenuOption              Menu option point to date/time.\r
+  @param  OptionString            Option string input for process.\r
+  @param  AddOptCol               Whether need to update MenuOption->OptCol. \r
+\r
+**/\r
+VOID \r
+ProcessStringForDateTime (\r
+  UI_MENU_OPTION                  *MenuOption,\r
+  CHAR16                          *OptionString,\r
+  BOOLEAN                         AddOptCol\r
+  )\r
+{\r
+  UINTN Index;\r
+  UINTN Count;\r
+  FORM_BROWSER_STATEMENT          *Statement;\r
+\r
+  ASSERT (MenuOption != NULL && OptionString != NULL);\r
+  \r
+  Statement = MenuOption->ThisTag;\r
+  \r
+  //\r
+  // If leading spaces on OptionString - remove the spaces\r
+  //\r
+  for (Index = 0; OptionString[Index] == L' '; Index++) {\r
+    //\r
+    // Base on the blockspace to get the option column info.\r
+    //\r
+    if (AddOptCol) {\r
+      MenuOption->OptCol++;\r
+    }\r
+  }\r
+  \r
+  for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {\r
+    OptionString[Count] = OptionString[Index];\r
+    Count++;\r
+  }\r
+  OptionString[Count] = CHAR_NULL;\r
+  \r
+  //\r
+  // Enable to suppress field in the opcode base on the flag.\r
+  //\r
+  if (Statement->Operand == EFI_IFR_DATE_OP) {\r
+    //\r
+    // OptionString format is: <**:  **: ****>\r
+    //                        |month|day|year|\r
+    //                          4     3    5\r
+    //\r
+    if ((Statement->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {\r
+      //\r
+      // At this point, only "<**:" in the optionstring. \r
+      // Clean the day's ** field, after clean, the format is "<  :"\r
+      //\r
+      SetUnicodeMem (&OptionString[1], 2, L' ');\r
+    } else if ((Statement->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {\r
+      //\r
+      // At this point, only "**:" in the optionstring. \r
+      // Clean the month's "**" field, after clean, the format is "  :"\r
+      //                \r
+      SetUnicodeMem (&OptionString[0], 2, L' ');\r
+    } else if ((Statement->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {\r
+      //\r
+      // At this point, only "****>" in the optionstring. \r
+      // Clean the year's "****" field, after clean, the format is "  >"\r
+      //                \r
+      SetUnicodeMem (&OptionString[0], 4, L' ');\r
+    }\r
+  } else if (Statement->Operand == EFI_IFR_TIME_OP) {\r
+    //\r
+    // OptionString format is: <**:  **:    **>\r
+    //                        |hour|minute|second|\r
+    //                          4     3      3\r
+    //\r
+    if ((Statement->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {\r
+      //\r
+      // At this point, only "<**:" in the optionstring. \r
+      // Clean the hour's ** field, after clean, the format is "<  :"\r
+      //\r
+      SetUnicodeMem (&OptionString[1], 2, L' ');\r
+    } else if ((Statement->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {\r
+      //\r
+      // At this point, only "**:" in the optionstring. \r
+      // Clean the minute's "**" field, after clean, the format is "  :"\r
+      //                \r
+      SetUnicodeMem (&OptionString[0], 2, L' ');\r
+    } else if ((Statement->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {\r
+      //\r
+      // At this point, only "**>" in the optionstring. \r
+      // Clean the second's "**" field, after clean, the format is "  >"\r
+      //                \r
+      SetUnicodeMem (&OptionString[0], 2, L' ');\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Refresh question.\r
+\r
+  @param     MenuRefreshEntry    Menu refresh structure which has info about the refresh question.\r
+**/\r
+EFI_STATUS \r
+RefreshQuestion (\r
+  IN   MENU_REFRESH_ENTRY    *MenuRefreshEntry\r
+  )\r
+{\r
+  CHAR16                          *OptionString;\r
+  EFI_STATUS                      Status;\r
+  UI_MENU_SELECTION               *Selection;\r
+  FORM_BROWSER_STATEMENT          *Question;\r
+\r
+  Selection = MenuRefreshEntry->Selection;\r
+  Question = MenuRefreshEntry->MenuOption->ThisTag;\r
+\r
+  Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  OptionString = NULL;\r
+  ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);\r
+\r
+  if (OptionString != NULL) {\r
+    //\r
+    // If old Text is longer than new string, need to clean the old string before paint the newer.\r
+    // This option is no need for time/date opcode, because time/data opcode has fixed string length.\r
+    //\r
+    if ((MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_DATE_OP) &&\r
+      (MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_TIME_OP)) {\r
+      ClearLines (\r
+        MenuRefreshEntry->CurrentColumn, \r
+        MenuRefreshEntry->CurrentColumn + gOptionBlockWidth - 1,\r
+        MenuRefreshEntry->CurrentRow,\r
+        MenuRefreshEntry->CurrentRow,\r
+        PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND\r
+        );\r
+    }\r
+\r
+    gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);\r
+    ProcessStringForDateTime(MenuRefreshEntry->MenuOption, OptionString, FALSE);\r
+    PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);\r
+    FreePool (OptionString);\r
+  }\r
+\r
+  //\r
+  // Question value may be changed, need invoke its Callback()\r
+  //\r
+  Status = ProcessCallBackFunction (Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Refresh the question which has refresh guid event attribute.\r
+  \r
+  @param Event    The event which has this function related.     \r
+  @param Context  The input context info related to this event or the status code return to the caller.\r
+**/\r
+VOID\r
+EFIAPI\r
+RefreshQuestionNotify(\r
+  IN      EFI_EVENT Event,\r
+  IN      VOID      *Context\r
+  )\r
+{\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  UI_MENU_SELECTION               *Selection;\r
+\r
+  //\r
+  // Reset FormPackage update flag\r
+  //\r
+  mHiiPackageListUpdated = FALSE;\r
+\r
+  MenuRefreshEntry = (MENU_REFRESH_ENTRY *)Context;\r
+  ASSERT (MenuRefreshEntry != NULL);\r
+  Selection = MenuRefreshEntry->Selection;\r
+\r
+  RefreshQuestion (MenuRefreshEntry);\r
+  \r
+  if (mHiiPackageListUpdated) {\r
+    //\r
+    // Package list is updated, force to reparse IFR binary of target Formset\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+    Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+  } \r
+}\r
+\r
+\r
+/**\r
+  Refresh screen.\r
+\r
+**/\r
+EFI_STATUS\r
+RefreshForm (\r
+  VOID\r
+  )\r
+{\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  EFI_STATUS                      Status;\r
+  UI_MENU_SELECTION               *Selection;\r
+\r
+  if (gMenuRefreshHead != NULL) {\r
+    //\r
+    // call from refresh interval process.\r
+    //\r
+    MenuRefreshEntry = gMenuRefreshHead;\r
+    Selection = MenuRefreshEntry->Selection;\r
+    //\r
+    // Reset FormPackage update flag\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+\r
+    do {\r
+      Status = RefreshQuestion (MenuRefreshEntry);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      MenuRefreshEntry = MenuRefreshEntry->Next;\r
+\r
+    } while (MenuRefreshEntry != NULL);\r
+\r
+    if (mHiiPackageListUpdated) {\r
+      //\r
+      // Package list is updated, force to reparse IFR binary of target Formset\r
+      //\r
+      mHiiPackageListUpdated = FALSE;\r
+      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_TIMEOUT;\r
+}\r
+\r
+\r
+/**\r
+  Wait for a given event to fire, or for an optional timeout to expire.\r
+\r
+  @param  Event                  The event to wait for\r
+  @param  Timeout                An optional timeout value in 100 ns units.\r
+  @param  RefreshInterval        Menu refresh interval (in seconds).\r
+\r
+  @retval EFI_SUCCESS            Event fired before Timeout expired.\r
+  @retval EFI_TIME_OUT           Timout expired before Event fired.\r
+\r
+**/\r
+EFI_STATUS\r
+UiWaitForSingleEvent (\r
+  IN EFI_EVENT                Event,\r
+  IN UINT64                   Timeout, OPTIONAL\r
+  IN UINT8                    RefreshInterval OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Index;\r
+  EFI_EVENT   TimerEvent;\r
+  EFI_EVENT   WaitList[2];\r
+\r
+  if (Timeout != 0) {\r
+    //\r
+    // Create a timer event\r
+    //\r
+    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Set the timer event\r
+      //\r
+      gBS->SetTimer (\r
+            TimerEvent,\r
+            TimerRelative,\r
+            Timeout\r
+            );\r
+\r
+      //\r
+      // Wait for the original event or the timer\r
+      //\r
+      WaitList[0] = Event;\r
+      WaitList[1] = TimerEvent;\r
+      Status      = gBS->WaitForEvent (2, WaitList, &Index);\r
+      gBS->CloseEvent (TimerEvent);\r
+\r
+      //\r
+      // If the timer expired, change the return to timed out\r
+      //\r
+      if (!EFI_ERROR (Status) && Index == 1) {\r
+        Status = EFI_TIMEOUT;\r
+      }\r
+    }\r
+  } else {\r
+    //\r
+    // Update screen every second\r
+    //\r
+    if (RefreshInterval == 0) {\r
+      Timeout = ONE_SECOND;\r
+    } else {\r
+      Timeout = RefreshInterval * ONE_SECOND;\r
+    }\r
+\r
+    do {\r
+      Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
+\r
+      //\r
+      // Set the timer event\r
+      //\r
+      gBS->SetTimer (\r
+            TimerEvent,\r
+            TimerRelative,\r
+            Timeout\r
+            );\r
+\r
+      //\r
+      // Wait for the original event or the timer\r
+      //\r
+      WaitList[0] = Event;\r
+      WaitList[1] = TimerEvent;\r
+      Status      = gBS->WaitForEvent (2, WaitList, &Index);\r
+\r
+      //\r
+      // If the timer expired, update anything that needs a refresh and keep waiting\r
+      //\r
+      if (!EFI_ERROR (Status) && Index == 1) {\r
+        Status = EFI_TIMEOUT;\r
+        if (RefreshInterval != 0) {\r
+          Status = RefreshForm ();\r
+        }\r
+      }\r
+\r
+      gBS->CloseEvent (TimerEvent);\r
+    } while (Status == EFI_TIMEOUT);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Add one menu option by specified description and context.\r
+\r
+  @param  String                 String description for this option.\r
+  @param  Handle                 Hii handle for the package list.\r
+  @param  Form                   The form this statement belong to.\r
+  @param  Statement              Statement of this Menu Option.\r
+  @param  NumberOfLines          Display lines for this Menu Option.\r
+  @param  MenuItemCount          The index for this Option in the Menu.\r
+\r
+  @retval Pointer                Pointer to the added Menu Option.\r
+\r
+**/\r
+UI_MENU_OPTION *\r
+UiAddMenuOption (\r
+  IN CHAR16                  *String,\r
+  IN EFI_HII_HANDLE          Handle,\r
+  IN FORM_BROWSER_FORM       *Form,\r
+  IN FORM_BROWSER_STATEMENT  *Statement,\r
+  IN UINT16                  NumberOfLines,\r
+  IN UINT16                  MenuItemCount\r
+  )\r
+{\r
+  UI_MENU_OPTION  *MenuOption;\r
+  UINTN           Index;\r
+  UINTN           Count;\r
+\r
+  Count = 1;\r
+  MenuOption = NULL;\r
+\r
+  if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {\r
+    //\r
+    // Add three MenuOptions for Date/Time\r
+    // Data format :      [01/02/2004]      [11:22:33]\r
+    // Line number :        0  0    1         0  0  1\r
+    //\r
+    NumberOfLines = 0;\r
+    Count = 3;\r
+\r
+    if (Statement->Storage == NULL) {\r
+      //\r
+      // For RTC type of date/time, set default refresh interval to be 1 second\r
+      //\r
+      if (Statement->RefreshInterval == 0) {\r
+        Statement->RefreshInterval = 1;\r
+      }\r
+    }\r
+  }\r
+\r
+  for (Index = 0; Index < Count; Index++) {\r
+    MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));\r
+    ASSERT (MenuOption);\r
+\r
+    MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;\r
+    MenuOption->Description = String;\r
+    MenuOption->Handle      = Handle;\r
+    MenuOption->ThisTag     = Statement;\r
+    MenuOption->EntryNumber = MenuItemCount;\r
+\r
+    if (Index == 2) {\r
+      //\r
+      // Override LineNumber for the MenuOption in Date/Time sequence\r
+      //\r
+      MenuOption->Skip = 1;\r
+    } else {\r
+      MenuOption->Skip = NumberOfLines;\r
+    }\r
+    MenuOption->Sequence = Index;\r
+\r
+    if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut ) {\r
+      MenuOption->GrayOut = TRUE;\r
+    } else {\r
+      MenuOption->GrayOut = FALSE;\r
+    }\r
+\r
+    //\r
+    // If the form or the question has the lock attribute, deal same as grayout.\r
+    //\r
+    if (Form->Locked || Statement->Locked) {\r
+      MenuOption->GrayOut = TRUE;\r
+    }\r
+    \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
+    case EFI_IFR_CHECKBOX_OP:\r
+    case EFI_IFR_PASSWORD_OP:\r
+    case EFI_IFR_STRING_OP:\r
+      //\r
+      // User could change the value of these items\r
+      //\r
+      MenuOption->IsQuestion = TRUE;\r
+      break;\r
+\r
+    case EFI_IFR_TEXT_OP:\r
+      if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {\r
+        //\r
+        // Initializing GrayOut option as TRUE for Text setup options \r
+        // so that those options will be Gray in colour and un selectable.\r
+        //\r
+        MenuOption->GrayOut = TRUE;\r
+      }\r
+      //\r
+      // break skipped on purpose\r
+      //\r
+    default:\r
+      MenuOption->IsQuestion = FALSE;\r
+      break;\r
+    }\r
+\r
+    if ((Statement->ValueExpression != NULL) ||\r
+        ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {\r
+      MenuOption->ReadOnly = TRUE;\r
+      if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {\r
+        MenuOption->GrayOut = TRUE;\r
+      }\r
+    }\r
+\r
+    InsertTailList (&gMenuOption, &MenuOption->Link);\r
+  }\r
+\r
+  return MenuOption;\r
+}\r
+\r
+\r
+/**\r
+  Routine used to abstract a generic dialog interface and return the selected key or string\r
+\r
+  @param  NumberOfLines          The number of lines for the dialog box\r
+  @param  HotKey                 Defines whether a single character is parsed\r
+                                 (TRUE) and returned in KeyValue or a string is\r
+                                 returned in StringBuffer.  Two special characters\r
+                                 are considered when entering a string, a SCAN_ESC\r
+                                 and an CHAR_CARRIAGE_RETURN.  SCAN_ESC terminates\r
+                                 string input and returns\r
+  @param  MaximumStringSize      The maximum size in bytes of a typed in string\r
+                                 (each character is a CHAR16) and the minimum\r
+                                 string returned is two bytes\r
+  @param  StringBuffer           The passed in pointer to the buffer which will\r
+                                 hold the typed in string if HotKey is FALSE\r
+  @param  KeyValue               The EFI_KEY value returned if HotKey is TRUE..\r
+  @param  ...                    A series of (quantity == NumberOfLines) text\r
+                                 strings which will be used to construct the dialog\r
+                                 box\r
+\r
+  @retval EFI_SUCCESS            Displayed dialog and received user interaction\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters was invalid (e.g.\r
+                                 (StringBuffer == NULL) && (HotKey == FALSE))\r
+  @retval EFI_DEVICE_ERROR       User typed in an ESC character to exit the routine\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CreateDialog (\r
+  IN  UINTN                       NumberOfLines,\r
+  IN  BOOLEAN                     HotKey,\r
+  IN  UINTN                       MaximumStringSize,\r
+  OUT CHAR16                      *StringBuffer,\r
+  OUT EFI_INPUT_KEY               *KeyValue,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST       Marker;\r
+  UINTN         Count;\r
+  EFI_INPUT_KEY Key;\r
+  UINTN         LargestString;\r
+  CHAR16        *TempString;\r
+  CHAR16        *BufferedString;\r
+  CHAR16        *StackString;\r
+  CHAR16        KeyPad[2];\r
+  UINTN         Start;\r
+  UINTN         Top;\r
+  UINTN         Index;\r
+  EFI_STATUS    Status;\r
+  BOOLEAN       SelectionComplete;\r
+  UINTN         InputOffset;\r
+  UINTN         CurrentAttribute;\r
+  UINTN         DimensionsWidth;\r
+  UINTN         DimensionsHeight;\r
+\r
+  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
+  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;\r
+\r
+  SelectionComplete = FALSE;\r
+  InputOffset       = 0;\r
+  TempString        = AllocateZeroPool (MaximumStringSize * 2);\r
+  BufferedString    = AllocateZeroPool (MaximumStringSize * 2);\r
+  CurrentAttribute  = gST->ConOut->Mode->Attribute;\r
+\r
+  ASSERT (TempString);\r
+  ASSERT (BufferedString);\r
+\r
+  //\r
+  // Zero the outgoing buffer\r
+  //\r
+  ZeroMem (StringBuffer, MaximumStringSize);\r
+\r
+  if (HotKey) {\r
+    if (KeyValue == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  } else {\r
+    if (StringBuffer == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  //\r
+  // Disable cursor\r
+  //\r
+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
+\r
+  LargestString = 0;\r
+\r
+  VA_START (Marker, KeyValue);\r
+\r
+  //\r
+  // Determine the largest string in the dialog box\r
+  // Notice we are starting with 1 since String is the first string\r
+  //\r
+  for (Count = 0; Count < NumberOfLines; Count++) {\r
+    StackString = VA_ARG (Marker, CHAR16 *);\r
+\r
+    if (StackString[0] == L' ') {\r
+      InputOffset = Count + 1;\r
+    }\r
+\r
+    if ((GetStringWidth (StackString) / 2) > LargestString) {\r
+      //\r
+      // Size of the string visually and subtract the width by one for the null-terminator\r
+      //\r
+      LargestString = (GetStringWidth (StackString) / 2);\r
+    }\r
+  }\r
+  VA_END (Marker);\r
+\r
+  Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;\r
+  Top   = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;\r
+\r
+  Count = 0;\r
+\r
+  //\r
+  // Display the Popup\r
+  //\r
+  VA_START (Marker, KeyValue);\r
+  CreateSharedPopUp (LargestString, NumberOfLines, Marker);\r
+  VA_END (Marker);\r
+\r
+  //\r
+  // Take the first key typed and report it back?\r
+  //\r
+  if (HotKey) {\r
+    Status = WaitForKeyStroke (&Key);\r
+    ASSERT_EFI_ERROR (Status);\r
+    CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));\r
+\r
+  } else {\r
+    do {\r
+      Status = WaitForKeyStroke (&Key);\r
+\r
+      switch (Key.UnicodeChar) {\r
+      case CHAR_NULL:\r
+        switch (Key.ScanCode) {\r
+        case SCAN_ESC:\r
+          FreePool (TempString);\r
+          FreePool (BufferedString);\r
+          gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
+          gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
+          return EFI_DEVICE_ERROR;\r
+\r
+        default:\r
+          break;\r
+        }\r
+\r
+        break;\r
+\r
+      case CHAR_CARRIAGE_RETURN:\r
+        SelectionComplete = TRUE;\r
+        FreePool (TempString);\r
+        FreePool (BufferedString);\r
+        gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
+        gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
+        return EFI_SUCCESS;\r
+        break;\r
+\r
+      case CHAR_BACKSPACE:\r
+        if (StringBuffer[0] != CHAR_NULL) {\r
+          for (Index = 0; StringBuffer[Index] != CHAR_NULL; Index++) {\r
+            TempString[Index] = StringBuffer[Index];\r
+          }\r
+          //\r
+          // Effectively truncate string by 1 character\r
+          //\r
+          TempString[Index - 1] = CHAR_NULL;\r
+          StrCpy (StringBuffer, TempString);\r
+        }\r
+        //\r
+        // break skipped on purpose\r
+        //\r
+\r
+      default:\r
+        //\r
+        // If it is the beginning of the string, don't worry about checking maximum limits\r
+        //\r
+        if ((StringBuffer[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
+          StrnCpy (StringBuffer, &Key.UnicodeChar, 1);\r
+          StrnCpy (TempString, &Key.UnicodeChar, 1);\r
+        } else if ((GetStringWidth (StringBuffer) < MaximumStringSize) && (Key.UnicodeChar != CHAR_BACKSPACE)) {\r
+          KeyPad[0] = Key.UnicodeChar;\r
+          KeyPad[1] = CHAR_NULL;\r
+          StrCat (StringBuffer, KeyPad);\r
+          StrCat (TempString, KeyPad);\r
+        }\r
+        //\r
+        // If the width of the input string is now larger than the screen, we nee to\r
+        // adjust the index to start printing portions of the string\r
+        //\r
+        SetUnicodeMem (BufferedString, LargestString, L' ');\r
+\r
+        PrintStringAt (Start + 1, Top + InputOffset, BufferedString);\r
+\r
+        if ((GetStringWidth (StringBuffer) / 2) > (DimensionsWidth - 2)) {\r
+          Index = (GetStringWidth (StringBuffer) / 2) - DimensionsWidth + 2;\r
+        } else {\r
+          Index = 0;\r
+        }\r
+\r
+        for (Count = 0; Index + 1 < GetStringWidth (StringBuffer) / 2; Index++, Count++) {\r
+          BufferedString[Count] = StringBuffer[Index];\r
+        }\r
+\r
+        PrintStringAt (Start + 1, Top + InputOffset, BufferedString);\r
+        break;\r
+      }\r
+    } while (!SelectionComplete);\r
+  }\r
+\r
+  gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
+  gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Draw a pop up windows based on the dimension, number of lines and\r
+  strings specified.\r
+\r
+  @param RequestedWidth  The width of the pop-up.\r
+  @param NumberOfLines   The number of lines.\r
+  @param Marker          The variable argument list for the list of string to be printed.\r
+\r
+**/\r
+VOID\r
+CreateSharedPopUp (\r
+  IN  UINTN                       RequestedWidth,\r
+  IN  UINTN                       NumberOfLines,\r
+  IN  VA_LIST                     Marker\r
+  )\r
+{\r
+  UINTN   Index;\r
+  UINTN   Count;\r
+  CHAR16  Character;\r
+  UINTN   Start;\r
+  UINTN   End;\r
+  UINTN   Top;\r
+  UINTN   Bottom;\r
+  CHAR16  *String;\r
+  UINTN   DimensionsWidth;\r
+  UINTN   DimensionsHeight;\r
+\r
+  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
+  DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;\r
+\r
+  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);\r
+\r
+  if ((RequestedWidth + 2) > DimensionsWidth) {\r
+    RequestedWidth = DimensionsWidth - 2;\r
+  }\r
+\r
+  //\r
+  // Subtract the PopUp width from total Columns, allow for one space extra on\r
+  // each end plus a border.\r
+  //\r
+  Start     = (DimensionsWidth - RequestedWidth - 2) / 2 + gScreenDimensions.LeftColumn + 1;\r
+  End       = Start + RequestedWidth + 1;\r
+\r
+  Top       = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;\r
+  Bottom    = Top + NumberOfLines + 2;\r
+\r
+  Character = BOXDRAW_DOWN_RIGHT;\r
+  PrintCharAt (Start, Top, Character);\r
+  Character = BOXDRAW_HORIZONTAL;\r
+  for (Index = Start; Index + 2 < End; Index++) {\r
+    PrintChar (Character);\r
+  }\r
+\r
+  Character = BOXDRAW_DOWN_LEFT;\r
+  PrintChar (Character);\r
+  Character = BOXDRAW_VERTICAL;\r
+\r
+  Count = 0;\r
+  for (Index = Top; Index + 2 < Bottom; Index++, Count++) {\r
+    String = VA_ARG (Marker, CHAR16*);\r
+\r
+    //\r
+    // This will clear the background of the line - we never know who might have been\r
+    // here before us.  This differs from the next clear in that it used the non-reverse\r
+    // video for normal printing.\r
+    //\r
+    if (GetStringWidth (String) / 2 > 1) {\r
+      ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);\r
+    }\r
+\r
+    //\r
+    // Passing in a space results in the assumption that this is where typing will occur\r
+    //\r
+    if (String[0] == L' ') {\r
+      ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);\r
+    }\r
+\r
+    //\r
+    // Passing in a NULL results in a blank space\r
+    //\r
+    if (String[0] == CHAR_NULL) {\r
+      ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);\r
+    }\r
+\r
+    PrintStringAt (\r
+      ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,\r
+      Index + 1,\r
+      String\r
+      );\r
+    gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);\r
+    PrintCharAt (Start, Index + 1, Character);\r
+    PrintCharAt (End - 1, Index + 1, Character);\r
+  }\r
+\r
+  Character = BOXDRAW_UP_RIGHT;\r
+  PrintCharAt (Start, Bottom - 1, Character);\r
+  Character = BOXDRAW_HORIZONTAL;\r
+  for (Index = Start; Index + 2 < End; Index++) {\r
+    PrintChar (Character);\r
+  }\r
+\r
+  Character = BOXDRAW_UP_LEFT;\r
+  PrintChar (Character);\r
+}\r
+\r
+/**\r
+  Draw a pop up windows based on the dimension, number of lines and\r
+  strings specified.\r
+\r
+  @param RequestedWidth  The width of the pop-up.\r
+  @param NumberOfLines   The number of lines.\r
+  @param ...             A series of text strings that displayed in the pop-up.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CreateMultiStringPopUp (\r
+  IN  UINTN                       RequestedWidth,\r
+  IN  UINTN                       NumberOfLines,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Marker;\r
+\r
+  VA_START (Marker, NumberOfLines);\r
+\r
+  CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);\r
+\r
+  VA_END (Marker);\r
+}\r
+\r
+\r
+/**\r
+  Update status bar on the bottom of menu.\r
+\r
+  @param  Selection              Current Selction info.\r
+  @param  MessageType            The type of message to be shown.\r
+  @param  Flags                  The flags in Question header.\r
+  @param  State                  Set or clear.\r
+\r
+**/\r
+VOID\r
+UpdateStatusBar (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UINTN                       MessageType,\r
+  IN  UINT8                       Flags,\r
+  IN  BOOLEAN                     State\r
+  )\r
+{\r
+  UINTN           Index;\r
+  CHAR16          *NvUpdateMessage;\r
+  CHAR16          *InputErrorMessage;\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_FORMSET    *LocalFormSet;\r
+  FORM_BROWSER_STATEMENT  *Question;\r
+  \r
+  NvUpdateMessage   = GetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), gHiiHandle);\r
+  InputErrorMessage = GetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), gHiiHandle);\r
+\r
+  switch (MessageType) {\r
+  case INPUT_ERROR:\r
+    if (State) {\r
+      gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);\r
+      PrintStringAt (\r
+        gScreenDimensions.LeftColumn + gPromptBlockWidth,\r
+        gScreenDimensions.BottomRow - 1,\r
+        InputErrorMessage\r
+        );\r
+      mInputError = TRUE;\r
+    } else {\r
+      gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));\r
+      for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {\r
+        PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, L"  ");\r
+      }\r
+\r
+      mInputError = FALSE;\r
+    }\r
+    break;\r
+\r
+  case NV_UPDATE_REQUIRED:\r
+    //\r
+    // Global setting support. Show configuration change on every form.\r
+    //\r
+    if (State) {\r
+      gResetRequired    = (BOOLEAN) (gResetRequired | ((Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED));\r
+\r
+      if (Selection != NULL && Selection->Statement != NULL) {\r
+        Question = Selection->Statement;\r
+        if (Question->Storage != NULL || Question->Operand == EFI_IFR_DATE_OP || Question->Operand == EFI_IFR_TIME_OP) {\r
+          //\r
+          // Update only for Question value that need to be saved into Storage.\r
+          //\r
+          Selection->Form->NvUpdateRequired = TRUE;\r
+        }\r
+      }\r
+      \r
+      if (Selection == NULL || IsNvUpdateRequired (Selection->FormSet)) {\r
+        gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);\r
+        PrintStringAt (\r
+          gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth,\r
+          gScreenDimensions.BottomRow - 1,\r
+          NvUpdateMessage\r
+          );\r
+      }\r
+    } else {\r
+      gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));\r
+      for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) {\r
+        PrintAt (\r
+          (gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + Index),\r
+          gScreenDimensions.BottomRow - 1,\r
+          L"  "\r
+          );\r
+      }\r
+    }\r
+    break;\r
+\r
+  case REFRESH_STATUS_BAR:\r
+    if (mInputError) {\r
+      UpdateStatusBar (Selection, INPUT_ERROR, Flags, TRUE);\r
+    }\r
+\r
+    switch (gBrowserSettingScope) {\r
+    case SystemLevel:\r
+      //\r
+      // Check the maintain list to see whether there is any change.\r
+      //\r
+      Link = GetFirstNode (&gBrowserFormSetList);\r
+      while (!IsNull (&gBrowserFormSetList, Link)) {\r
+        LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+        if (IsNvUpdateRequired(LocalFormSet)) {\r
+          UpdateStatusBar (NULL, NV_UPDATE_REQUIRED, Flags, TRUE);\r
+          break;\r
+        }\r
+        Link = GetNextNode (&gBrowserFormSetList, Link);\r
+      }\r
+      break;\r
+    case FormSetLevel:\r
+    case FormLevel:\r
+      UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Flags, TRUE);\r
+    default:\r
+      break;\r
+    }\r
+\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  FreePool (InputErrorMessage);\r
+  FreePool (NvUpdateMessage);\r
+  return ;\r
+}\r
+\r
+\r
+/**\r
+  Get the supported width for a particular op-code\r
+\r
+  @param  Statement              The FORM_BROWSER_STATEMENT structure passed in.\r
+  @param  Handle                 The handle in the HII database being used\r
+\r
+  @return Returns the number of CHAR16 characters that is support.\r
+\r
+**/\r
+UINT16\r
+GetWidth (\r
+  IN FORM_BROWSER_STATEMENT        *Statement,\r
+  IN EFI_HII_HANDLE                 Handle\r
+  )\r
+{\r
+  CHAR16  *String;\r
+  UINTN   Size;\r
+  UINT16  Width;\r
+\r
+  Size = 0;\r
+\r
+  //\r
+  // See if the second text parameter is really NULL\r
+  //\r
+  if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {\r
+    String = GetToken (Statement->TextTwo, Handle);\r
+    Size   = StrLen (String);\r
+    FreePool (String);\r
+  }\r
+\r
+  if ((Statement->Operand == EFI_IFR_SUBTITLE_OP) ||\r
+      (Statement->Operand == EFI_IFR_REF_OP) ||\r
+      (Statement->Operand == EFI_IFR_PASSWORD_OP) ||\r
+      (Statement->Operand == EFI_IFR_ACTION_OP) ||\r
+      (Statement->Operand == EFI_IFR_RESET_BUTTON_OP) ||\r
+      //\r
+      // Allow a wide display if text op-code and no secondary text op-code\r
+      //\r
+      ((Statement->Operand == EFI_IFR_TEXT_OP) && (Size == 0))\r
+      ) {\r
+    Width = (UINT16) (gPromptBlockWidth + gOptionBlockWidth);\r
+  } else {\r
+    Width = (UINT16) gPromptBlockWidth;\r
+  }\r
+\r
+  if (Statement->InSubtitle) {\r
+    Width -= SUBTITLE_INDENT;\r
+  }\r
+\r
+  return (UINT16) (Width - LEFT_SKIPPED_COLUMNS);\r
+}\r
+\r
+/**\r
+  Will copy LineWidth amount of a string in the OutputString buffer and return the\r
+  number of CHAR16 characters that were copied into the OutputString buffer.\r
+  The output string format is:\r
+    Glyph Info + String info + '\0'.\r
+\r
+  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.\r
+\r
+  @param  InputString            String description for this option.\r
+  @param  LineWidth              Width of the desired string to extract in CHAR16\r
+                                 characters\r
+  @param  GlyphWidth             The glyph width of the begin of the char in the string.\r
+  @param  Index                  Where in InputString to start the copy process\r
+  @param  OutputString           Buffer to copy the string into\r
+\r
+  @return Returns the number of CHAR16 characters that were copied into the OutputString \r
+  buffer, include extra glyph info and '\0' info.\r
+\r
+**/\r
+UINT16\r
+GetLineByWidth (\r
+  IN      CHAR16                      *InputString,\r
+  IN      UINT16                      LineWidth,\r
+  IN OUT  UINT16                      *GlyphWidth,\r
+  IN OUT  UINTN                       *Index,\r
+  OUT     CHAR16                      **OutputString\r
+  )\r
+{\r
+  UINT16          StrOffset;\r
+  UINT16          GlyphOffset;\r
+  UINT16          OriginalGlyphWidth;\r
+  BOOLEAN         ReturnFlag;\r
+  UINT16          LastSpaceOffset;\r
+  UINT16          LastGlyphWidth;\r
+\r
+  if (InputString == NULL || Index == NULL || OutputString == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  if (LineWidth == 0 || *GlyphWidth == 0) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Save original glyph width.\r
+  //\r
+  OriginalGlyphWidth = *GlyphWidth;\r
+  LastGlyphWidth     = OriginalGlyphWidth;\r
+  ReturnFlag         = FALSE;\r
+  LastSpaceOffset    = 0;\r
+\r
+  //\r
+  // NARROW_CHAR can not be printed in screen, so if a line only contain  the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line  in Screen.\r
+  // To avoid displaying this  empty line in screen,  just skip  the two CHARs here.\r
+  //\r
+  if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {\r
+    *Index = *Index + 2;\r
+  }\r
+\r
+  //\r
+  // Fast-forward the string and see if there is a carriage-return in the string\r
+  //\r
+  for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {\r
+    switch (InputString[*Index + StrOffset]) {\r
+      case NARROW_CHAR:\r
+        *GlyphWidth = 1;\r
+        break;\r
+\r
+      case WIDE_CHAR:\r
+        *GlyphWidth = 2;\r
+        break;\r
+\r
+      case CHAR_CARRIAGE_RETURN:\r
+      case CHAR_LINEFEED:\r
+      case CHAR_NULL:\r
+        ReturnFlag = TRUE;\r
+        break;\r
+\r
+      default:\r
+        GlyphOffset = GlyphOffset + *GlyphWidth;\r
+\r
+        //\r
+        // Record the last space info in this line. Will be used in rewind.\r
+        //\r
+        if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {\r
+          LastSpaceOffset = StrOffset;\r
+          LastGlyphWidth  = *GlyphWidth;\r
+        }\r
+        break;\r
+    }\r
+\r
+    if (ReturnFlag) {\r
+      break;\r
+    }\r
+  } \r
+\r
+  //\r
+  // Rewind the string from the maximum size until we see a space to break the line\r
+  //\r
+  if (GlyphOffset > LineWidth) {\r
+    //\r
+    // Rewind the string to last space char in this line.\r
+    //\r
+    if (LastSpaceOffset != 0) {\r
+      StrOffset   = LastSpaceOffset;\r
+      *GlyphWidth = LastGlyphWidth;\r
+    } else {\r
+      //\r
+      // Roll back to last char in the line width.\r
+      //\r
+      StrOffset--;\r
+    }\r
+  }\r
+\r
+  //\r
+  // The CHAR_NULL has process last time, this time just return 0 to stand for the end.\r
+  //\r
+  if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Need extra glyph info and '\0' info, so +2.\r
+  //\r
+  *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));\r
+  if (*OutputString == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Save the glyph info at the begin of the string, will used by Print function.\r
+  //\r
+  if (OriginalGlyphWidth == 1) {\r
+    *(*OutputString) = NARROW_CHAR;\r
+  } else  {\r
+    *(*OutputString) = WIDE_CHAR;\r
+  }\r
+\r
+  CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));\r
+\r
+  if (InputString[*Index + StrOffset] == CHAR_SPACE) {\r
+    //\r
+    // Skip the space info at the begin of next line.\r
+    //  \r
+    *Index = (UINT16) (*Index + StrOffset + 1);\r
+  } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {\r
+    //\r
+    // Skip the /n or /n/r info.\r
+    //\r
+    if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {\r
+      *Index = (UINT16) (*Index + StrOffset + 2);\r
+    } else {\r
+      *Index = (UINT16) (*Index + StrOffset + 1);\r
+    }\r
+  } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {\r
+    //\r
+    // Skip the /r or /r/n info.\r
+    //  \r
+    if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {\r
+      *Index = (UINT16) (*Index + StrOffset + 2);\r
+    } else {\r
+      *Index = (UINT16) (*Index + StrOffset + 1);\r
+    }\r
+  } else {\r
+    *Index = (UINT16) (*Index + StrOffset);\r
+  }\r
+\r
+  //\r
+  // Include extra glyph info and '\0' info, so +2.\r
+  //\r
+  return StrOffset + 2;\r
+}\r
+\r
+\r
+/**\r
+  Update display lines for a Menu Option.\r
+\r
+  @param  Selection              The user's selection.\r
+  @param  MenuOption             The MenuOption to be checked.\r
+\r
+**/\r
+VOID\r
+UpdateOptionSkipLines (\r
+  IN UI_MENU_SELECTION            *Selection,\r
+  IN UI_MENU_OPTION               *MenuOption\r
+  )\r
+{\r
+  UINTN   Index;\r
+  UINT16  Width;\r
+  UINTN   Row;\r
+  UINTN   OriginalRow;\r
+  CHAR16  *OutputString;\r
+  CHAR16  *OptionString;\r
+  UINT16  GlyphWidth;\r
+\r
+  Row           = 0;\r
+  OptionString  = NULL;\r
+  Width         = (UINT16) gOptionBlockWidth;\r
+  OriginalRow   = 0;\r
+  GlyphWidth    = 1;\r
+  \r
+  ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
+  if (OptionString == NULL) {\r
+    return;\r
+  }\r
+\r
+  for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &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 (&OptionString[Index]) != 0) {\r
+      Row++;\r
+      //\r
+      // Since the Number of lines for this menu entry may or may not be reflected accurately\r
+      // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
+      // some testing to ensure we are keeping this in-sync.\r
+      //\r
+      // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
+      //\r
+      if ((Row - OriginalRow) >= MenuOption->Skip) {\r
+        MenuOption->Skip++;\r
+      }\r
+    }\r
+\r
+    FreePool (OutputString);\r
+  }\r
+\r
+  if (OptionString != NULL) {\r
+    FreePool (OptionString);\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Check whether this Menu Option could be highlighted.\r
+\r
+  This is an internal function.\r
+\r
+  @param  MenuOption             The MenuOption to be checked.\r
+\r
+  @retval TRUE                   This Menu Option is selectable.\r
+  @retval FALSE                  This Menu Option could not be selected.\r
+\r
+**/\r
+BOOLEAN\r
+IsSelectable (\r
+  UI_MENU_OPTION   *MenuOption\r
+  )\r
+{\r
+  if ((MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) ||\r
+      MenuOption->GrayOut || MenuOption->ReadOnly) {\r
+    return FALSE;\r
+  } else {\r
+    return TRUE;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Determine if the menu is the last menu that can be selected.\r
+\r
+  This is an internal function.\r
+\r
+  @param  Direction              The scroll direction. False is down. True is up.\r
+  @param  CurrentPos             The current focus.\r
+\r
+  @return FALSE -- the menu isn't the last menu that can be selected.\r
+  @return TRUE  -- the menu is the last menu that can be selected.\r
+\r
+**/\r
+BOOLEAN\r
+ValueIsScroll (\r
+  IN  BOOLEAN                     Direction,\r
+  IN  LIST_ENTRY                  *CurrentPos\r
+  )\r
+{\r
+  LIST_ENTRY      *Temp;\r
+\r
+  Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;\r
+\r
+  if (Temp == &gMenuOption) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
+/**\r
+  Move to next selectable statement.\r
+\r
+  This is an internal function.\r
+\r
+  @param  Selection              Menu selection.\r
+  @param  GoUp                   The navigation direction. TRUE: up, FALSE: down.\r
+  @param  CurrentPosition        Current position.\r
+  @param  GapToTop               Gap position to top or bottom.\r
+\r
+  @return The row distance from current MenuOption to next selectable MenuOption.\r
+\r
+  @retval -1       Reach the begin of the menu, still can't find the selectable menu.\r
+  @retval Value    Find the selectable menu, maybe the truly selectable, maybe the l\r
+                   last menu showing at current form.\r
+\r
+**/\r
+INTN\r
+MoveToNextStatement (\r
+  IN     UI_MENU_SELECTION         *Selection,\r
+  IN     BOOLEAN                   GoUp,\r
+  IN OUT LIST_ENTRY                **CurrentPosition,\r
+  IN     UINTN                     GapToTop\r
+  )\r
+{\r
+  INTN             Distance;\r
+  LIST_ENTRY       *Pos;\r
+  UI_MENU_OPTION   *NextMenuOption;\r
+  UI_MENU_OPTION   *PreMenuOption;\r
+\r
+  Distance      = 0;\r
+  Pos           = *CurrentPosition;\r
+  PreMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
+\r
+  while (TRUE) {\r
+    NextMenuOption = MENU_OPTION_FROM_LINK (Pos);\r
+    //\r
+    // NextMenuOption->Row == 0 means this menu has not calculate\r
+    // the NextMenuOption->Skip value yet, just calculate here.\r
+    //\r
+    if (NextMenuOption->Row == 0) {\r
+      UpdateOptionSkipLines (Selection, NextMenuOption);\r
+    }\r
+    \r
+    if (GoUp && (PreMenuOption != NextMenuOption)) {\r
+      //\r
+      // In this case, still can't find the selectable menu,\r
+      // return the last one in the showing form.\r
+      //\r
+      if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
+        NextMenuOption = PreMenuOption;\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Current Position doesn't need to be caculated when go up.\r
+      // Caculate distanct at first when go up\r
+      //      \r
+      Distance += NextMenuOption->Skip;\r
+    }\r
+\r
+    if (IsSelectable (NextMenuOption)) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Arrive at begin of the menu list.\r
+    //\r
+    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {\r
+      Distance = -1;\r
+      break;\r
+    }\r
+\r
+    if (!GoUp) {\r
+      //\r
+      // In this case, still can't find the selectable menu,\r
+      // return the last one in the showing form.\r
+      //\r
+      if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
+        NextMenuOption = PreMenuOption;\r
+        break;\r
+      }\r
+\r
+      Distance += NextMenuOption->Skip;\r
+    }\r
+\r
+    PreMenuOption = NextMenuOption;\r
+    Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);\r
+  }\r
+\r
+  *CurrentPosition = &NextMenuOption->Link;\r
+  return Distance;\r
+}\r
+\r
+\r
+/**\r
+  Adjust Data and Time position accordingly.\r
+  Data format :      [01/02/2004]      [11:22:33]\r
+  Line number :        0  0    1         0  0  1\r
+\r
+  This is an internal function.\r
+\r
+  @param  DirectionUp            the up or down direction. False is down. True is\r
+                                 up.\r
+  @param  CurrentPosition        Current position. On return: Point to the last\r
+                                 Option (Year or Second) if up; Point to the first\r
+                                 Option (Month or Hour) if down.\r
+\r
+  @return Return line number to pad. It is possible that we stand on a zero-advance\r
+  @return data or time opcode, so pad one line when we judge if we are going to scroll outside.\r
+\r
+**/\r
+UINTN\r
+AdjustDateAndTimePosition (\r
+  IN     BOOLEAN                     DirectionUp,\r
+  IN OUT LIST_ENTRY                  **CurrentPosition\r
+  )\r
+{\r
+  UINTN           Count;\r
+  LIST_ENTRY      *NewPosition;\r
+  UI_MENU_OPTION  *MenuOption;\r
+  UINTN           PadLineNumber;\r
+\r
+  PadLineNumber = 0;\r
+  NewPosition   = *CurrentPosition;\r
+  MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);\r
+\r
+  if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||\r
+      (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {\r
+    //\r
+    // Calculate the distance from current position to the last Date/Time MenuOption\r
+    //\r
+    Count = 0;\r
+    while (MenuOption->Skip == 0) {\r
+      Count++;\r
+      NewPosition   = NewPosition->ForwardLink;\r
+      MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);\r
+      PadLineNumber = 1;\r
+    }\r
+\r
+    NewPosition = *CurrentPosition;\r
+    if (DirectionUp) {\r
+      //\r
+      // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended\r
+      // to be one that back to the previous set of MenuOptions, we need to advance to the first\r
+      // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate\r
+      // checking can be done.\r
+      //\r
+      while (Count++ < 2) {\r
+        NewPosition = NewPosition->BackLink;\r
+      }\r
+    } else {\r
+      //\r
+      // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended\r
+      // to be one that progresses to the next set of MenuOptions, we need to advance to the last\r
+      // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate\r
+      // checking can be done.\r
+      //\r
+      while (Count-- > 0) {\r
+        NewPosition = NewPosition->ForwardLink;\r
+      }\r
+    }\r
+\r
+    *CurrentPosition = NewPosition;\r
+  }\r
+\r
+  return PadLineNumber;\r
+}\r
+\r
+/**\r
+  Find HII Handle in the HII database associated with given Device Path.\r
+\r
+  If DevicePath is NULL, then ASSERT.\r
+\r
+  @param  DevicePath             Device Path associated with the HII package list\r
+                                 handle.\r
+\r
+  @retval Handle                 HII package list Handle associated with the Device\r
+                                        Path.\r
+  @retval NULL                   Hii Package list handle is not found.\r
+\r
+**/\r
+EFI_HII_HANDLE\r
+EFIAPI\r
+DevicePathToHiiHandle (\r
+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_DEVICE_PATH_PROTOCOL    *TmpDevicePath;\r
+  UINTN                       BufferSize;\r
+  UINTN                       HandleCount;\r
+  UINTN                       Index;\r
+  EFI_HANDLE                  Handle;\r
+  EFI_HANDLE                  DriverHandle;\r
+  EFI_HII_HANDLE              *HiiHandles;\r
+  EFI_HII_HANDLE              HiiHandle;\r
+\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  TmpDevicePath = DevicePath;\r
+  //\r
+  // Locate Device Path Protocol handle buffer\r
+  //\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &TmpDevicePath,\r
+                  &DriverHandle\r
+                  );\r
+  if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Retrieve all HII Handles from HII database\r
+  //\r
+  BufferSize = 0x1000;\r
+  HiiHandles = AllocatePool (BufferSize);\r
+  ASSERT (HiiHandles != NULL);\r
+  Status = mHiiDatabase->ListPackageLists (\r
+                           mHiiDatabase,\r
+                           EFI_HII_PACKAGE_TYPE_ALL,\r
+                           NULL,\r
+                           &BufferSize,\r
+                           HiiHandles\r
+                           );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    FreePool (HiiHandles);\r
+    HiiHandles = AllocatePool (BufferSize);\r
+    ASSERT (HiiHandles != NULL);\r
+\r
+    Status = mHiiDatabase->ListPackageLists (\r
+                             mHiiDatabase,\r
+                             EFI_HII_PACKAGE_TYPE_ALL,\r
+                             NULL,\r
+                             &BufferSize,\r
+                             HiiHandles\r
+                             );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (HiiHandles);\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Search Hii Handle by Driver Handle\r
+  //\r
+  HiiHandle = NULL;\r
+  HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = mHiiDatabase->GetPackageListHandle (\r
+                             mHiiDatabase,\r
+                             HiiHandles[Index],\r
+                             &Handle\r
+                             );\r
+    if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
+      HiiHandle = HiiHandles[Index];\r
+      break;\r
+    }\r
+  }\r
+\r
+  FreePool (HiiHandles);\r
+  return HiiHandle;\r
+}\r
+\r
+/**\r
+  Find HII Handle in the HII database associated with given form set guid.\r
+\r
+  If FormSetGuid is NULL, then ASSERT.\r
+\r
+  @param  ComparingGuid          FormSet Guid associated with the HII package list\r
+                                 handle.\r
+\r
+  @retval Handle                 HII package list Handle associated with the Device\r
+                                        Path.\r
+  @retval NULL                   Hii Package list handle is not found.\r
+\r
+**/\r
+EFI_HII_HANDLE\r
+FormSetGuidToHiiHandle (\r
+  EFI_GUID     *ComparingGuid\r
+  )\r
+{\r
+  EFI_HII_HANDLE               *HiiHandles;\r
+  UINTN                        Index;\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINTN                        BufferSize;\r
+  UINT32                       Offset;\r
+  UINT32                       Offset2;\r
+  UINT32                       PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+  UINT8                        *Package;\r
+  UINT8                        *OpCodeData;\r
+  EFI_STATUS                   Status;\r
+  EFI_HII_HANDLE               HiiHandle;\r
+\r
+  ASSERT (ComparingGuid != NULL);\r
+\r
+  HiiHandle  = NULL;\r
+  //\r
+  // Get all the Hii handles\r
+  //\r
+  HiiHandles = HiiGetHiiHandles (NULL);\r
+  ASSERT (HiiHandles != NULL);\r
+\r
+  //\r
+  // Search for formset of each class type\r
+  //\r
+  for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+    BufferSize = 0;\r
+    HiiPackageList = NULL;\r
+    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      HiiPackageList = AllocatePool (BufferSize);\r
+      ASSERT (HiiPackageList != NULL);\r
+\r
+      Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
+    }\r
+    if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
+      return NULL;\r
+    }\r
+\r
+    //\r
+    // Get Form package from this HII package List\r
+    //\r
+    Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+    Offset2 = 0;\r
+    CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
+\r
+    while (Offset < PackageListLength) {\r
+      Package = ((UINT8 *) HiiPackageList) + Offset;\r
+      CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+      if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+        //\r
+        // Search FormSet in this Form Package\r
+        //\r
+        Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+        while (Offset2 < PackageHeader.Length) {\r
+          OpCodeData = Package + Offset2;\r
+\r
+          if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+            //\r
+            // Try to compare against formset GUID\r
+            //\r
+            if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+              HiiHandle = HiiHandles[Index];\r
+              break;\r
+            }\r
+          }\r
+\r
+          Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+        }\r
+      }\r
+      if (HiiHandle != NULL) {\r
+        break;\r
+      }\r
+      Offset += PackageHeader.Length;\r
+    }\r
+    \r
+    FreePool (HiiPackageList);\r
+       if (HiiHandle != NULL) {\r
+               break;\r
+       }\r
+  }\r
+\r
+  FreePool (HiiHandles);\r
+\r
+  return HiiHandle;\r
+}\r
+\r
+/**\r
+  Process the goto op code, update the info in the selection structure.\r
+\r
+  @param Statement    The statement belong to goto op code.\r
+  @param Selection    The selection info.\r
+  @param Repaint      Whether need to repaint the menu.\r
+  @param NewLine      Whether need to create new line.\r
+\r
+  @retval EFI_SUCCESS    The menu process successfully.\r
+  @return Other value if the process failed.\r
+**/\r
+EFI_STATUS\r
+ProcessGotoOpCode (\r
+  IN OUT   FORM_BROWSER_STATEMENT      *Statement,\r
+  IN OUT   UI_MENU_SELECTION           *Selection,\r
+  OUT      BOOLEAN                     *Repaint,\r
+  OUT      BOOLEAN                     *NewLine\r
+  )\r
+{\r
+  CHAR16                          *StringPtr;\r
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
+  FORM_BROWSER_FORM               *RefForm;\r
+  EFI_INPUT_KEY                   Key;\r
+  EFI_STATUS                      Status;\r
+\r
+  Status    = EFI_SUCCESS;\r
+  StringPtr = NULL;\r
+\r
+  //\r
+  // Prepare the device path check, get the device path info first.\r
+  //\r
+  if (Statement->HiiValue.Value.ref.DevicePath != 0) {\r
+    StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);\r
+  }\r
+\r
+  //\r
+  // Check whether the device path string is a valid string.\r
+  //\r
+  if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {\r
+    if (Selection->Form->ModalForm) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Goto another Hii Package list\r
+    //\r
+    if (mPathFromText != NULL) {\r
+      DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);\r
+      if (DevicePath != NULL) {\r
+        Selection->Handle = DevicePathToHiiHandle (DevicePath);\r
+        FreePool (DevicePath);\r
+      }\r
+      FreePool (StringPtr);\r
+    } else {\r
+      //\r
+      // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.\r
+      //\r
+      do {\r
+        CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gProtocolNotFound, gPressEnter, gEmptyString);\r
+      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+      if (Repaint != NULL) {\r
+        *Repaint = TRUE;\r
+      }\r
+      FreePool (StringPtr);\r
+      return Status;\r
+    }\r
+\r
+    Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+    if (Selection->Handle == NULL) {\r
+      //\r
+      // If target Hii Handle not found, exit\r
+      //\r
+      Selection->Action = UI_ACTION_EXIT;\r
+      Selection->Statement = NULL;\r
+      return Status;\r
+    }\r
+\r
+    CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
+    Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
+    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+  } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {\r
+    if (Selection->Form->ModalForm) {\r
+      return Status;\r
+    }  \r
+    //\r
+    // Goto another Formset, check for uncommitted data\r
+    //\r
+    Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+    \r
+    Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);\r
+    if (Selection->Handle == NULL) {\r
+      //\r
+      // If target Hii Handle not found, exit\r
+      //\r
+      Selection->Action = UI_ACTION_EXIT;\r
+      Selection->Statement = NULL;\r
+      return Status;\r
+    } \r
+\r
+    CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
+    Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
+    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+  } else if (Statement->HiiValue.Value.ref.FormId != 0) {\r
+    //\r
+    // Check whether target From is suppressed.\r
+    //\r
+    RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);\r
+\r
+    if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
+      if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\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
+        if (Repaint != NULL) {\r
+          *Repaint = TRUE;\r
+        }\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Goto another form inside this formset,\r
+    //\r
+    Selection->Action = UI_ACTION_REFRESH_FORM;\r
+\r
+    Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
+    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+  } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {\r
+    //\r
+    // Goto another Question\r
+    //\r
+    Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+\r
+    if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+      Selection->Action = UI_ACTION_REFRESH_FORM;\r
+    } else {\r
+      if (Repaint != NULL) {\r
+        *Repaint = TRUE;\r
+      }\r
+      if (NewLine != NULL) {\r
+        *NewLine = TRUE;\r
+      }\r
+    }\r
+  } else {\r
+    if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+      Selection->Action = UI_ACTION_REFRESH_FORM;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Display menu and wait for user to select one menu option, then return it.\r
+  If AutoBoot is enabled, then if user doesn't select any option,\r
+  after period of time, it will automatically return the first menu option.\r
+\r
+  @param  Selection              Menu selection.\r
+\r
+  @retval EFI_SUCESSS            This function always return successfully for now.\r
+\r
+**/\r
+EFI_STATUS\r
+UiDisplayMenu (\r
+  IN OUT UI_MENU_SELECTION           *Selection\r
+  )\r
+{\r
+  INTN                            SkipValue;\r
+  INTN                            Difference;\r
+  UINTN                           DistanceValue;\r
+  UINTN                           Row;\r
+  UINTN                           Col;\r
+  UINTN                           Temp;\r
+  UINTN                           Temp2;\r
+  UINTN                           TopRow;\r
+  UINTN                           BottomRow;\r
+  UINTN                           OriginalRow;\r
+  UINTN                           Index;\r
+  UINT16                          Width;\r
+  CHAR16                          *StringPtr;\r
+  CHAR16                          *OptionString;\r
+  CHAR16                          *OutputString;\r
+  CHAR16                          *HelpString;\r
+  CHAR16                          *HelpHeaderString;\r
+  CHAR16                          *HelpBottomString;\r
+  BOOLEAN                         NewLine;\r
+  BOOLEAN                         Repaint;\r
+  BOOLEAN                         SavedValue;\r
+  BOOLEAN                         UpArrow;\r
+  BOOLEAN                         DownArrow;\r
+  BOOLEAN                         InitializedFlag;\r
+  EFI_STATUS                      Status;\r
+  EFI_INPUT_KEY                   Key;\r
+  LIST_ENTRY                      *Link;\r
+  LIST_ENTRY                      *NewPos;\r
+  LIST_ENTRY                      *TopOfScreen;\r
+  LIST_ENTRY                      *SavedListEntry;\r
+  UI_MENU_OPTION                  *MenuOption;\r
+  UI_MENU_OPTION                  *NextMenuOption;\r
+  UI_MENU_OPTION                  *SavedMenuOption;\r
+  UI_MENU_OPTION                  *PreviousMenuOption;\r
+  UI_CONTROL_FLAG                 ControlFlag;\r
+  EFI_SCREEN_DESCRIPTOR           LocalScreen;\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  MENU_REFRESH_ENTRY              *MenuUpdateEntry;  \r
+  UI_SCREEN_OPERATION             ScreenOperation;\r
+  UINT8                           MinRefreshInterval;\r
+  UINT16                          DefaultId;\r
+  FORM_BROWSER_STATEMENT          *Statement;\r
+  UI_MENU_LIST                    *CurrentMenu;\r
+  UINTN                           ModalSkipColumn;\r
+  BROWSER_HOT_KEY                 *HotKey;\r
+  UINTN                           HelpPageIndex;\r
+  UINTN                           HelpPageCount;\r
+  UINTN                           RowCount;\r
+  UINTN                           HelpLine;\r
+  UINTN                           HelpHeaderLine;\r
+  UINTN                           HelpBottomLine;\r
+  BOOLEAN                         MultiHelpPage;\r
+  UINT16                          GlyphWidth;\r
+  UINT16                          EachLineWidth;\r
+  UINT16                          HeaderLineWidth;\r
+  UINT16                          BottomLineWidth;\r
+\r
+  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+\r
+  Status              = EFI_SUCCESS;\r
+  HelpString          = NULL;\r
+  HelpHeaderString    = NULL;\r
+  HelpBottomString    = NULL;\r
+  OptionString        = NULL;\r
+  ScreenOperation     = UiNoOperation;\r
+  NewLine             = TRUE;\r
+  MinRefreshInterval  = 0;\r
+  DefaultId           = 0;\r
+  HelpPageCount       = 0;\r
+  HelpLine            = 0;\r
+  RowCount            = 0;\r
+  HelpBottomLine      = 0;\r
+  HelpHeaderLine      = 0;\r
+  HelpPageIndex       = 0;\r
+  MultiHelpPage       = FALSE;\r
+  EachLineWidth       = 0;\r
+  HeaderLineWidth     = 0;\r
+  BottomLineWidth     = 0;\r
+  OutputString        = NULL;\r
+  UpArrow             = FALSE;\r
+  DownArrow           = FALSE;\r
+  SkipValue           = 0;\r
+  MenuRefreshEntry    = gMenuRefreshHead;\r
+\r
+  NextMenuOption      = NULL;\r
+  PreviousMenuOption  = NULL;\r
+  SavedMenuOption     = NULL;\r
+  HotKey              = NULL;\r
+  ModalSkipColumn     = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6;\r
+\r
+  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
+\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE){\r
+    TopRow  = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;\r
+    Row     = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;\r
+  } else {\r
+    TopRow  = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;\r
+    Row     = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;\r
+  }\r
+\r
+  if (Selection->Form->ModalForm) {\r
+    Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS + ModalSkipColumn;\r
+  } else {\r
+    Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS;\r
+  }\r
+\r
+  BottomRow = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - SCROLL_ARROW_HEIGHT - 1;\r
+\r
+  Selection->TopRow = TopRow;\r
+  Selection->BottomRow = BottomRow;\r
+  Selection->PromptCol = Col;\r
+  Selection->OptionCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;\r
+  Selection->Statement = NULL;\r
+\r
+  TopOfScreen = gMenuOption.ForwardLink;\r
+  Repaint     = TRUE;\r
+  MenuOption  = NULL;\r
+\r
+  //\r
+  // Find current Menu\r
+  //\r
+  CurrentMenu = UiFindMenuList (Selection->Handle, &Selection->FormSetGuid, Selection->FormId);\r
+  if (CurrentMenu == NULL) {\r
+    //\r
+    // Current menu not found, add it to the menu tree\r
+    //\r
+    CurrentMenu = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);\r
+  }\r
+  ASSERT (CurrentMenu != NULL);\r
+  Selection->CurrentMenu = CurrentMenu;\r
+\r
+  if (Selection->QuestionId == 0) {\r
+    //\r
+    // Highlight not specified, fetch it from cached menu\r
+    //\r
+    Selection->QuestionId = CurrentMenu->QuestionId;\r
+    Selection->Sequence   = CurrentMenu->Sequence;\r
+  }\r
+\r
+  //\r
+  // Init option as the current user's selection\r
+  //\r
+  InitializedFlag = TRUE;\r
+  NewPos = gMenuOption.ForwardLink;\r
+\r
+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
+  UpdateStatusBar (Selection, REFRESH_STATUS_BAR, (UINT8) 0, TRUE);\r
+\r
+  ControlFlag = CfInitialization;\r
+  Selection->Action = UI_ACTION_NONE;\r
+  while (TRUE) {\r
+    switch (ControlFlag) {\r
+    case CfInitialization:\r
+      if (IsListEmpty (&gMenuOption)) {\r
+        ControlFlag = CfReadKey;\r
+      } else {\r
+        ControlFlag = CfCheckSelection;\r
+      }\r
+      break;\r
+\r
+    case CfCheckSelection:\r
+      if (Selection->Action != UI_ACTION_NONE) {\r
+        ControlFlag = CfExit;\r
+      } else {\r
+        ControlFlag = CfRepaint;\r
+      }\r
+      break;\r
+\r
+    case CfRepaint:\r
+      ControlFlag = CfRefreshHighLight;\r
+\r
+      if (Repaint) {\r
+        //\r
+        // Display menu\r
+        //\r
+        DownArrow       = FALSE;\r
+        UpArrow         = FALSE;\r
+        Row             = TopRow;\r
+\r
+        Temp            = (UINTN) SkipValue;\r
+        Temp2           = (UINTN) SkipValue;\r
+\r
+        //\r
+        // 1. Clear the screen.\r
+        //\r
+        if (Selection->Form->ModalForm) {\r
+          ClearLines (\r
+            LocalScreen.LeftColumn + ModalSkipColumn,\r
+            LocalScreen.LeftColumn + ModalSkipColumn + gPromptBlockWidth + gOptionBlockWidth,\r
+            TopRow - SCROLL_ARROW_HEIGHT,\r
+            BottomRow + SCROLL_ARROW_HEIGHT,\r
+            PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND\r
+            );   \r
+        } else {\r
+          ClearLines (\r
+            LocalScreen.LeftColumn,\r
+            LocalScreen.RightColumn,\r
+            TopRow - SCROLL_ARROW_HEIGHT,\r
+            BottomRow + SCROLL_ARROW_HEIGHT,\r
+            PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND\r
+            );\r
+        }\r
+        UiFreeRefreshList ();\r
+        MinRefreshInterval = 0;\r
+\r
+        //\r
+        // 2.Paint the menu.\r
+        //\r
+        for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {\r
+          MenuOption          = MENU_OPTION_FROM_LINK (Link);\r
+          MenuOption->Row     = Row;\r
+          MenuOption->Col     = Col;\r
+          if (Selection->Form->ModalForm) {\r
+            MenuOption->OptCol  = gPromptBlockWidth + 1 + LocalScreen.LeftColumn + ModalSkipColumn;\r
+          } else {\r
+            MenuOption->OptCol  = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;\r
+          }\r
+\r
+          Statement = MenuOption->ThisTag;\r
+          if (Statement->InSubtitle) {\r
+            MenuOption->Col += SUBTITLE_INDENT;\r
+          }\r
+\r
+          if (MenuOption->GrayOut) {\r
+            gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);\r
+          } else {\r
+            if (Statement->Operand == EFI_IFR_SUBTITLE_OP) {\r
+              gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND);\r
+            }\r
+          }\r
+\r
+          Width       = GetWidth (Statement, MenuOption->Handle);\r
+          OriginalRow = Row;\r
+          GlyphWidth  = 1;\r
+\r
+          if (Statement->Operand == EFI_IFR_REF_OP && MenuOption->Col >= 2) {\r
+            //\r
+            // Print Arrow for Goto button.\r
+            //\r
+            PrintAt (\r
+              MenuOption->Col - 2,\r
+              Row,\r
+              L"%c",\r
+              GEOMETRICSHAPE_RIGHT_TRIANGLE\r
+              );\r
+          }\r
+\r
+          //\r
+          // 2.1. Paint the description.\r
+          //\r
+          for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+            //\r
+            // Temp means need to skip how many lines from the start.\r
+            //\r
+            if ((Temp == 0) && (Row <= BottomRow)) {\r
+              PrintStringAt (MenuOption->Col, Row, OutputString);\r
+            }\r
+            //\r
+            // If there is more string to process print on the next row and increment the Skip value\r
+            //\r
+            if (StrLen (&MenuOption->Description[Index]) != 0) {\r
+              if (Temp == 0) {\r
+                Row++;\r
+              }\r
+            }\r
+\r
+            FreePool (OutputString);\r
+            if (Temp != 0) {\r
+              Temp--;\r
+            }\r
+          }\r
+\r
+          Temp  = 0;\r
+          Row   = OriginalRow;\r
+\r
+          //\r
+          // 2.2. Paint the option string.\r
+          //\r
+          Status = ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // Repaint to clear possible error prompt pop-up\r
+            //\r
+            Repaint = TRUE;\r
+            NewLine = TRUE;\r
+            ControlFlag = CfRepaint;\r
+            break;\r
+          }\r
+\r
+          if (OptionString != NULL) {\r
+            if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {\r
+              ProcessStringForDateTime(MenuOption, OptionString, TRUE);\r
+            }\r
+\r
+            Width       = (UINT16) gOptionBlockWidth;\r
+            OriginalRow = Row;\r
+            GlyphWidth  = 1;\r
+\r
+            for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+              if ((Temp2 == 0) && (Row <= BottomRow)) {\r
+                PrintStringAt (MenuOption->OptCol, Row, OutputString);\r
+              }\r
+              //\r
+              // If there is more string to process print on the next row and increment the Skip value\r
+              //\r
+              if (StrLen (&OptionString[Index]) != 0) {\r
+                if (Temp2 == 0) {\r
+                  Row++;\r
+                  //\r
+                  // Since the Number of lines for this menu entry may or may not be reflected accurately\r
+                  // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
+                  // some testing to ensure we are keeping this in-sync.\r
+                  //\r
+                  // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
+                  //\r
+                  if ((Row - OriginalRow) >= MenuOption->Skip) {\r
+                    MenuOption->Skip++;\r
+                  }\r
+                }\r
+              }\r
+\r
+              FreePool (OutputString);\r
+              if (Temp2 != 0) {\r
+                Temp2--;\r
+              }\r
+            }\r
+\r
+            Temp2 = 0;\r
+            Row   = OriginalRow;\r
+\r
+            FreePool (OptionString);\r
+          }\r
+\r
+          //\r
+          // 2.4 Special process for Test opcode with test two.\r
+          //\r
+          if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {\r
+            if (gMenuEventGuidRefreshHead == NULL) {\r
+              MenuUpdateEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));\r
+              gMenuEventGuidRefreshHead = MenuUpdateEntry;\r
+            } else {\r
+              MenuUpdateEntry = gMenuEventGuidRefreshHead;\r
+              while (MenuUpdateEntry->Next != NULL) {\r
+                MenuUpdateEntry = MenuUpdateEntry->Next; \r
+              }\r
+              MenuUpdateEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));\r
+              MenuUpdateEntry = MenuUpdateEntry->Next; \r
+            }\r
+            ASSERT (MenuUpdateEntry != NULL);\r
+            Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, RefreshQuestionNotify, MenuUpdateEntry, &Statement->RefreshGuid, &MenuUpdateEntry->Event);\r
+            ASSERT (!EFI_ERROR (Status));\r
+            MenuUpdateEntry->MenuOption        = MenuOption;\r
+            MenuUpdateEntry->Selection         = Selection;\r
+            MenuUpdateEntry->CurrentColumn     = MenuOption->OptCol;\r
+            MenuUpdateEntry->CurrentRow        = MenuOption->Row;\r
+            if (MenuOption->GrayOut) {\r
+              MenuUpdateEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;\r
+            } else {\r
+              MenuUpdateEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;\r
+            }\r
+          }\r
+          \r
+          //\r
+          // If Question request refresh, register the op-code\r
+          //\r
+          if (Statement->RefreshInterval != 0) {\r
+            //\r
+            // Menu will be refreshed at minimal interval of all Questions\r
+            // which have refresh request\r
+            //\r
+            if (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval) {\r
+              MinRefreshInterval = Statement->RefreshInterval;\r
+            }\r
+            \r
+            if (gMenuRefreshHead == NULL) {\r
+              MenuRefreshEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));\r
+              gMenuRefreshHead = MenuRefreshEntry;\r
+            } else {\r
+              MenuRefreshEntry = gMenuRefreshHead;\r
+              while (MenuRefreshEntry->Next != NULL) {\r
+                MenuRefreshEntry = MenuRefreshEntry->Next; \r
+              }\r
+              MenuRefreshEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));\r
+              MenuRefreshEntry = MenuRefreshEntry->Next;\r
+            }\r
+            ASSERT (MenuRefreshEntry != NULL);            \r
+            MenuRefreshEntry->MenuOption        = MenuOption;\r
+            MenuRefreshEntry->Selection         = Selection;\r
+            MenuRefreshEntry->CurrentColumn     = MenuOption->OptCol;\r
+            MenuRefreshEntry->CurrentRow        = MenuOption->Row;\r
+            if (MenuOption->GrayOut) {\r
+              MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;\r
+            } else {               \r
+              MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;\r
+            }\r
+          }\r
+          \r
+          //\r
+          // If this is a text op with secondary text information\r
+          //\r
+          if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {\r
+            StringPtr   = GetToken (Statement->TextTwo, MenuOption->Handle);\r
+\r
+            Width       = (UINT16) gOptionBlockWidth;\r
+            OriginalRow = Row;\r
+            GlyphWidth = 1;\r
+\r
+            for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+              if ((Temp == 0) && (Row <= BottomRow)) {\r
+                PrintStringAt (MenuOption->OptCol, Row, OutputString);\r
+              }\r
+              //\r
+              // If there is more string to process print on the next row and increment the Skip value\r
+              //\r
+              if (StrLen (&StringPtr[Index]) != 0) {\r
+                if (Temp2 == 0) {\r
+                  Row++;\r
+                  //\r
+                  // Since the Number of lines for this menu entry may or may not be reflected accurately\r
+                  // since the prompt might be 1 lines and option might be many, and vice versa, we need to do\r
+                  // some testing to ensure we are keeping this in-sync.\r
+                  //\r
+                  // If the difference in rows is greater than or equal to the skip value, increase the skip value\r
+                  //\r
+                  if ((Row - OriginalRow) >= MenuOption->Skip) {\r
+                    MenuOption->Skip++;\r
+                  }\r
+                }\r
+              }\r
+\r
+              FreePool (OutputString);\r
+              if (Temp2 != 0) {\r
+                Temp2--;\r
+              }\r
+            }\r
+\r
+            Row = OriginalRow;\r
+            FreePool (StringPtr);\r
+          }\r
+          gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+\r
+          //\r
+          // 3. Update the row info which will be used by next menu.\r
+          //\r
+          if (Link == TopOfScreen) {\r
+            Row += MenuOption->Skip - SkipValue;\r
+          } else {\r
+            Row += MenuOption->Skip;\r
+          }\r
+\r
+          if (Row > BottomRow) {\r
+            if (!ValueIsScroll (FALSE, Link)) {\r
+              DownArrow = TRUE;\r
+            }\r
+\r
+            Row = BottomRow + 1;\r
+            break;\r
+          }\r
+        }\r
+\r
+        if (!ValueIsScroll (TRUE, TopOfScreen)) {\r
+          UpArrow = TRUE;\r
+        }\r
+\r
+        if (UpArrow) {\r
+          gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);\r
+          PrintAt (\r
+            LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,\r
+            TopRow - SCROLL_ARROW_HEIGHT,\r
+            L"%c",\r
+            ARROW_UP\r
+            );\r
+          gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+        }\r
+\r
+        if (DownArrow) {\r
+          gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);\r
+          PrintAt (\r
+            LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,\r
+            BottomRow + SCROLL_ARROW_HEIGHT,\r
+            L"%c",\r
+            ARROW_DOWN\r
+            );\r
+          gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+        }\r
+\r
+        MenuOption = NULL;\r
+      }\r
+      break;\r
+\r
+    case CfRefreshHighLight:\r
+      //\r
+      // MenuOption: Last menu option that need to remove hilight\r
+      //             MenuOption is set to NULL in Repaint\r
+      // NewPos:     Current menu option that need to hilight\r
+      //\r
+      ControlFlag = CfUpdateHelpString;\r
+      if (TopOfScreen == &MenuOption->Link) {\r
+        Temp = SkipValue;\r
+      } else {\r
+        Temp = 0;\r
+      }\r
+      if (NewPos == TopOfScreen) {\r
+        Temp2 = SkipValue;\r
+      } else {\r
+        Temp2 = 0;\r
+      }\r
+      if (InitializedFlag) {\r
+        InitializedFlag = FALSE;\r
+        MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
+      }\r
+\r
+      //\r
+      // Repaint flag is normally reset when finish processing CfUpdateHelpString. Temporarily\r
+      // reset Repaint flag because we may break halfway and skip CfUpdateHelpString processing.\r
+      //\r
+      SavedValue  = Repaint;\r
+      Repaint     = FALSE;\r
+\r
+      if (Selection->QuestionId != 0) {\r
+        NewPos = gMenuOption.ForwardLink;\r
+        SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+        while ((SavedMenuOption->ThisTag->QuestionId != Selection->QuestionId ||\r
+                SavedMenuOption->Sequence != Selection->Sequence) &&\r
+                NewPos->ForwardLink != &gMenuOption) {\r
+          NewPos     = NewPos->ForwardLink;\r
+          SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+        }\r
+        if (SavedMenuOption->ThisTag->QuestionId == Selection->QuestionId) {\r
+          //\r
+          // Target Question found, find its MenuOption\r
+          //\r
+          Link = TopOfScreen;\r
+\r
+          for (Index = TopRow; Index <= BottomRow && Link != NewPos;) {\r
+            SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+            Index += SavedMenuOption->Skip;\r
+            if (Link == TopOfScreen) {\r
+              Index -= SkipValue;\r
+            }\r
+            Link = Link->ForwardLink;\r
+          }\r
+          if (NewPos == Link) {\r
+            SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+          }\r
+\r
+          //\r
+          // Not find the selected menu in current show page.\r
+          // Have two case to enter this if:\r
+          // 1. Not find the menu at current page.\r
+          // 2. Find the menu in current page, but the menu shows at the bottom and not all info shows.\r
+          //    For case 2, has an exception: The menu can show more than one pages and now only this menu shows.\r
+          //\r
+          // Base on the selected menu will show at the bottom of the page,\r
+          // select the menu which will show at the top of the page.\r
+          //\r
+          if (Link != NewPos || Index > BottomRow || \r
+              (Link == NewPos && (SavedMenuOption->Row + SavedMenuOption->Skip - 1 > BottomRow) && (Link != TopOfScreen))) {\r
+            //\r
+            // Find the MenuOption which has the skip value for Date/Time opcode. \r
+            //\r
+            AdjustDateAndTimePosition(FALSE, &NewPos);\r
+            //\r
+            // NewPos is not in the current page, simply scroll page so that NewPos is in the end of the page\r
+            //\r
+            SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+            //\r
+            // SavedMenuOption->Row == 0 means the menu not show yet.\r
+            //\r
+            if (SavedMenuOption->Row == 0) {\r
+              UpdateOptionSkipLines (Selection, SavedMenuOption);\r
+            }\r
+\r
+            //\r
+            // Base on the selected menu will show at the bottome of next page, \r
+            // select the menu show at the top of the next page. \r
+            //\r
+            Link    = NewPos;\r
+            for (Index = TopRow + SavedMenuOption->Skip; Index <= BottomRow + 1; ) {            \r
+              Link = Link->BackLink;\r
+              SavedMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+              if (SavedMenuOption->Row == 0) {\r
+                UpdateOptionSkipLines (Selection, SavedMenuOption);\r
+              }\r
+              Index += SavedMenuOption->Skip;\r
+            }\r
+\r
+            //\r
+            // Found the menu which will show at the top of the page.\r
+            //\r
+            if (Link == NewPos) {\r
+              //\r
+              // The menu can show more than one pages, just show the menu at the top of the page.\r
+              //\r
+              SkipValue    = 0;\r
+              TopOfScreen  = Link;\r
+            } else {\r
+              //\r
+              // Check whether need to skip some line for menu shows at the top of the page.\r
+              //\r
+              SkipValue = Index - BottomRow - 1;\r
+              if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {\r
+                TopOfScreen     = Link;\r
+              } else {\r
+                SkipValue       = 0;\r
+                TopOfScreen     = Link->ForwardLink;\r
+              }\r
+            }\r
+\r
+            Repaint = TRUE;\r
+            NewLine = TRUE;\r
+            ControlFlag = CfRepaint;\r
+            break;\r
+          }\r
+        } else {\r
+          //\r
+          // Target Question not found, highlight the default menu option\r
+          //\r
+          NewPos = TopOfScreen;\r
+        }\r
+\r
+        Selection->QuestionId = 0;\r
+      }\r
+\r
+      if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {\r
+        if (MenuOption != NULL) {\r
+          //\r
+          // Remove highlight on last Menu Option\r
+          //\r
+          gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);\r
+          ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
+          gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+          if (OptionString != NULL) {\r
+            if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||\r
+                (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)\r
+               ) {\r
+              ProcessStringForDateTime(MenuOption, OptionString, FALSE);\r
+            }\r
+\r
+            Width               = (UINT16) gOptionBlockWidth;\r
+            OriginalRow         = MenuOption->Row;\r
+            GlyphWidth          = 1;\r
+\r
+            for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+              if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {\r
+                PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);\r
+              }\r
+              //\r
+              // If there is more string to process print on the next row and increment the Skip value\r
+              //\r
+              if (StrLen (&OptionString[Index]) != 0) {\r
+                if (Temp == 0) {\r
+                  MenuOption->Row++;\r
+                }\r
+              }\r
+\r
+              FreePool (OutputString);\r
+              if (Temp != 0) {\r
+                Temp--;\r
+              }\r
+            }\r
+\r
+            MenuOption->Row = OriginalRow;\r
+\r
+            FreePool (OptionString);\r
+          } else {\r
+            if (NewLine) {\r
+              if (MenuOption->GrayOut) {\r
+                gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);\r
+              } else if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) {\r
+                gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND);\r
+              }\r
+\r
+              OriginalRow = MenuOption->Row;\r
+              Width       = GetWidth (MenuOption->ThisTag, MenuOption->Handle);\r
+              GlyphWidth  = 1;\r
+\r
+              for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+                if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {\r
+                  PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);\r
+                }\r
+                //\r
+                // If there is more string to process print on the next row and increment the Skip value\r
+                //\r
+                if (StrLen (&MenuOption->Description[Index]) != 0) {\r
+                  if (Temp == 0) {\r
+                    MenuOption->Row++;\r
+                  }\r
+                }\r
+\r
+                FreePool (OutputString);\r
+                if (Temp != 0) {\r
+                  Temp--;\r
+                }\r
+              }\r
+\r
+              MenuOption->Row = OriginalRow;\r
+              gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+            }\r
+          }\r
+        }\r
+\r
+        //\r
+        // This is the current selected statement\r
+        //\r
+        MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+        Statement = MenuOption->ThisTag;\r
+        Selection->Statement = Statement;\r
+        if (!IsSelectable (MenuOption)) {\r
+          Repaint = SavedValue;\r
+          UpdateKeyHelp (Selection, MenuOption, FALSE);\r
+          break;\r
+        }\r
+\r
+        //\r
+        // Record highlight for current menu\r
+        //\r
+        CurrentMenu->QuestionId = Statement->QuestionId;\r
+        CurrentMenu->Sequence   = MenuOption->Sequence;\r
+\r
+        //\r
+        // Set reverse attribute\r
+        //\r
+        gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));\r
+        gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);\r
+\r
+        //\r
+        // Assuming that we have a refresh linked-list created, lets annotate the\r
+        // appropriate entry that we are highlighting with its new attribute.  Just prior to this\r
+        // lets reset all of the entries' attribute so we do not get multiple highlights in he refresh\r
+        //\r
+        if (gMenuRefreshHead != NULL) {\r
+          for (MenuRefreshEntry = gMenuRefreshHead; MenuRefreshEntry != NULL; MenuRefreshEntry = MenuRefreshEntry->Next) {\r
+            if (MenuRefreshEntry->MenuOption->GrayOut) {\r
+              MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;\r
+            } else {               \r
+              MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;\r
+            }\r
+            if (MenuRefreshEntry->MenuOption == MenuOption) {\r
+              MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor);\r
+            }\r
+          }\r
+        }\r
+\r
+        ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\r
+        if (OptionString != NULL) {\r
+          if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {\r
+            ProcessStringForDateTime(MenuOption, OptionString, FALSE);\r
+          }\r
+          Width               = (UINT16) gOptionBlockWidth;\r
+\r
+          OriginalRow         = MenuOption->Row;\r
+          GlyphWidth          = 1;\r
+\r
+          for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+            if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {\r
+              PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);\r
+            }\r
+            //\r
+            // If there is more string to process print on the next row and increment the Skip value\r
+            //\r
+            if (StrLen (&OptionString[Index]) != 0) {\r
+              if (Temp2 == 0) {\r
+              MenuOption->Row++;\r
+              }\r
+            }\r
+\r
+            FreePool (OutputString);\r
+            if (Temp2 != 0) {\r
+              Temp2--;\r
+            }\r
+          }\r
+\r
+          MenuOption->Row = OriginalRow;\r
+\r
+          FreePool (OptionString);\r
+        } else {\r
+          if (NewLine) {\r
+            OriginalRow = MenuOption->Row;\r
+\r
+            Width       = GetWidth (Statement, MenuOption->Handle);\r
+            GlyphWidth          = 1;\r
+\r
+            for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {\r
+              if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {\r
+                PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);\r
+              }\r
+              //\r
+              // If there is more string to process print on the next row and increment the Skip value\r
+              //\r
+              if (StrLen (&MenuOption->Description[Index]) != 0) {\r
+                if (Temp2 == 0) {\r
+                  MenuOption->Row++;\r
+                }\r
+              }\r
+\r
+              FreePool (OutputString);\r
+              if (Temp2 != 0) {\r
+                Temp2--;\r
+              }\r
+            }\r
+\r
+            MenuOption->Row = OriginalRow;\r
+\r
+          }\r
+        }\r
+\r
+        UpdateKeyHelp (Selection, MenuOption, FALSE);\r
+\r
+        //\r
+        // Clear reverse attribute\r
+        //\r
+        gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
+      }\r
+      //\r
+      // Repaint flag will be used when process CfUpdateHelpString, so restore its value\r
+      // if we didn't break halfway when process CfRefreshHighLight.\r
+      //\r
+      Repaint = SavedValue;\r
+      break;\r
+\r
+    case CfUpdateHelpString:\r
+      ControlFlag = CfPrepareToReadKey;\r
+      if (Selection->Form->ModalForm) {\r
+        break;\r
+      }\r
+\r
+      if (Repaint || NewLine) {\r
+        //\r
+        // Don't print anything if it is a NULL help token\r
+        //\r
+        ASSERT(MenuOption != NULL);\r
+        if (MenuOption->ThisTag->Help == 0 || !IsSelectable (MenuOption)) {\r
+          StringPtr = L"\0";\r
+        } else {\r
+          StringPtr = GetToken (MenuOption->ThisTag->Help, MenuOption->Handle);\r
+        }\r
+\r
+        RowCount      = BottomRow - TopRow;\r
+        HelpPageIndex = 0;\r
+        //\r
+        // 1.Calculate how many line the help string need to print.\r
+        //\r
+        if (HelpString != NULL) {\r
+          FreePool (HelpString);\r
+        }\r
+        HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);\r
+        if (HelpLine > RowCount) {\r
+          MultiHelpPage   = TRUE;\r
+          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);\r
+          if (HelpHeaderString != NULL) {\r
+            FreePool (HelpHeaderString);\r
+          }\r
+          HelpHeaderLine  = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, RowCount);\r
+          StringPtr       = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);\r
+          if (HelpBottomString != NULL) {\r
+            FreePool (HelpBottomString);\r
+          }\r
+          HelpBottomLine  = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, RowCount);\r
+          //\r
+          // Calculate the help page count.\r
+          //\r
+          if (HelpLine > 2 * RowCount - 2) {\r
+            HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;\r
+            if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {\r
+              HelpPageCount += 1;\r
+            }\r
+          } else {\r
+            HelpPageCount = 2;\r
+          }\r
+        } else {\r
+          MultiHelpPage = FALSE;\r
+        }\r
+      }\r
+\r
+      //\r
+      // Clean the help field first.\r
+      //\r
+      ClearLines (\r
+        LocalScreen.RightColumn - gHelpBlockWidth,\r
+        LocalScreen.RightColumn,\r
+        TopRow,\r
+        BottomRow,\r
+        PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND\r
+        );\r
+\r
+      //\r
+      // Check whether need to show the 'More(U/u)' at the begin.\r
+      // Base on current direct info, here shows aligned to the right side of the column.\r
+      // If the direction is multi line and aligned to right side may have problem, so \r
+      // add ASSERT code here.\r
+      //\r
+      if (HelpPageIndex > 0) {\r
+        gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);\r
+        for (Index = 0; Index < HelpHeaderLine; Index++) {\r
+          ASSERT (HelpHeaderLine == 1);\r
+          ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));\r
+          PrintStringAt (\r
+            LocalScreen.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,\r
+            Index + TopRow,\r
+            &HelpHeaderString[Index * HeaderLineWidth]\r
+            );\r
+        }\r
+      }\r
+\r
+      gST->ConOut->SetAttribute (gST->ConOut, HELP_TEXT | FIELD_BACKGROUND);\r
+      //\r
+      // Print the help string info.\r
+      //\r
+      if (!MultiHelpPage) {\r
+        for (Index = 0; Index < HelpLine; Index++) {\r
+          PrintStringAt (\r
+            LocalScreen.RightColumn - gHelpBlockWidth,\r
+            Index + TopRow,\r
+            &HelpString[Index * EachLineWidth]\r
+            );\r
+        }\r
+        gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);\r
+      } else  {\r
+        if (HelpPageIndex == 0) {\r
+          for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {\r
+            PrintStringAt (\r
+              LocalScreen.RightColumn - gHelpBlockWidth,\r
+              Index + TopRow,\r
+              &HelpString[Index * EachLineWidth]\r
+              );\r
+          }\r
+        } else {\r
+          for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) && \r
+              (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {\r
+            PrintStringAt (\r
+              LocalScreen.RightColumn - gHelpBlockWidth,\r
+              Index + TopRow + HelpHeaderLine,\r
+              &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth]\r
+              );\r
+          }\r
+          if (HelpPageIndex == HelpPageCount - 1) {\r
+            gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);\r
+          }\r
+        } \r
+      }\r
+\r
+      //\r
+      // Check whether need to print the 'More(D/d)' at the bottom.\r
+      // Base on current direct info, here shows aligned to the right side of the column.\r
+      // If the direction is multi line and aligned to right side may have problem, so \r
+      // add ASSERT code here.\r
+      //\r
+      if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {\r
+        gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);\r
+        for (Index = 0; Index < HelpBottomLine; Index++) {\r
+          ASSERT (HelpBottomLine == 1);\r
+          ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1)); \r
+          PrintStringAt (\r
+            LocalScreen.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,\r
+            Index + BottomRow - HelpBottomLine,\r
+            &HelpBottomString[Index * BottomLineWidth]\r
+            );\r
+        }\r
+      }\r
+      //\r
+      // Reset this flag every time we finish using it.\r
+      //\r
+      Repaint = FALSE;\r
+      NewLine = FALSE;\r
+      break;\r
+\r
+    case CfPrepareToReadKey:\r
+      ControlFlag = CfReadKey;\r
+      ScreenOperation = UiNoOperation;\r
+      break;\r
+\r
+    case CfReadKey:\r
+      ControlFlag = CfScreenOperation;\r
+\r
+      //\r
+      // Wait for user's selection\r
+      //\r
+      while (TRUE) {\r
+        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+        if (!EFI_ERROR (Status)) {\r
+          break;\r
+        }\r
+\r
+        //\r
+        // If we encounter error, continue to read another key in.\r
+        //\r
+        if (Status != EFI_NOT_READY) {\r
+          continue;\r
+        }\r
+\r
+        Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, MinRefreshInterval);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        if (Selection->Action == UI_ACTION_REFRESH_FORMSET) {\r
+          //\r
+          // IFR is updated in Callback of refresh opcode, re-parse it\r
+          //\r
+          ControlFlag = CfCheckSelection;\r
+          Selection->Statement = NULL;\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (ControlFlag == CfCheckSelection) {\r
+        break;\r
+      }\r
+\r
+      switch (Key.UnicodeChar) {\r
+      case CHAR_CARRIAGE_RETURN:\r
+        if(MenuOption->GrayOut || MenuOption->ReadOnly) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+\r
+        ScreenOperation = UiSelect;\r
+        gDirection      = 0;\r
+        break;\r
+\r
+      //\r
+      // We will push the adjustment of these numeric values directly to the input handler\r
+      //  NOTE: we won't handle manual input numeric\r
+      //\r
+      case '+':\r
+      case '-':\r
+        //\r
+        // If the screen has no menu items, and the user didn't select UiReset\r
+        // ignore the selection and go back to reading keys.\r
+        //\r
+        if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+\r
+        ASSERT(MenuOption != NULL);\r
+        Statement = MenuOption->ThisTag;\r
+        if ((Statement->Operand == EFI_IFR_DATE_OP)\r
+          || (Statement->Operand == EFI_IFR_TIME_OP)\r
+          || ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step != 0))\r
+        ){\r
+          if (Key.UnicodeChar == '+') {\r
+            gDirection = SCAN_RIGHT;\r
+          } else {\r
+            gDirection = SCAN_LEFT;\r
+          }\r
+          Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // Repaint to clear possible error prompt pop-up\r
+            //\r
+            Repaint = TRUE;\r
+            NewLine = TRUE;\r
+          } else {\r
+            Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          }\r
+          if (OptionString != NULL) {\r
+            FreePool (OptionString);\r
+          }\r
+        }\r
+        break;\r
+\r
+      case '^':\r
+        ScreenOperation = UiUp;\r
+        break;\r
+\r
+      case 'V':\r
+      case 'v':\r
+        ScreenOperation = UiDown;\r
+        break;\r
+\r
+      case ' ':\r
+        if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
+          //\r
+          // If the screen has no menu items, and the user didn't select UiReset\r
+          // ignore the selection and go back to reading keys.\r
+          //\r
+          if(IsListEmpty (&gMenuOption)) {\r
+            ControlFlag = CfReadKey;\r
+            break;\r
+          }\r
+          \r
+          ASSERT(MenuOption != NULL);\r
+          if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {\r
+            ScreenOperation = UiSelect;\r
+          }\r
+        }\r
+        break;\r
+\r
+      case 'D':\r
+      case 'd':\r
+        if (!MultiHelpPage) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+        ControlFlag    = CfUpdateHelpString;\r
+        HelpPageIndex  = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;\r
+        break;\r
+\r
+      case 'U':\r
+      case 'u':\r
+        if (!MultiHelpPage) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+        ControlFlag    = CfUpdateHelpString;\r
+        HelpPageIndex  = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;\r
+        break;\r
+\r
+      case CHAR_NULL:\r
+        for (Index = 0; Index < mScanCodeNumber; Index++) {\r
+          if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {\r
+            ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;\r
+            break;\r
+          }\r
+        }\r
+        \r
+        if (Selection->Form->ModalForm && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {\r
+          //\r
+          // ModalForm has no ESC key and Hot Key.\r
+          //\r
+          ControlFlag = CfReadKey;\r
+        } else if (Index == mScanCodeNumber) {\r
+          //\r
+          // Check whether Key matches the registered hot key.\r
+          //\r
+          HotKey = NULL;\r
+          if ((gBrowserSettingScope == SystemLevel) || \r
+              (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+            HotKey = GetHotKeyFromRegisterList (&Key);\r
+          }\r
+          if (HotKey != NULL) {\r
+            ScreenOperation = UiHotKey;\r
+          }\r
+        }\r
+        break;\r
+      }\r
+      break;\r
+\r
+    case CfScreenOperation:\r
+      if (ScreenOperation != UiReset) {\r
+        //\r
+        // If the screen has no menu items, and the user didn't select UiReset\r
+        // ignore the selection and go back to reading keys.\r
+        //\r
+        if (IsListEmpty (&gMenuOption)) {\r
+          ControlFlag = CfReadKey;\r
+          break;\r
+        }\r
+      }\r
+\r
+      for (Index = 0;\r
+           Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);\r
+           Index++\r
+          ) {\r
+        if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {\r
+          ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case CfUiSelect:\r
+      ControlFlag = CfCheckSelection;\r
+\r
+      ASSERT(MenuOption != NULL);\r
+      Statement = MenuOption->ThisTag;\r
+      if (Statement->Operand == EFI_IFR_TEXT_OP) {\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Keep highlight on current MenuOption\r
+      //\r
+      Selection->QuestionId = Statement->QuestionId;\r
+\r
+      switch (Statement->Operand) {\r
+      case EFI_IFR_REF_OP:\r
+        ProcessGotoOpCode(Statement, Selection, &Repaint, &NewLine);\r
+        break;\r
+\r
+      case EFI_IFR_ACTION_OP:\r
+        //\r
+        // Process the Config string <ConfigResp>\r
+        //\r
+        Status = ProcessQuestionConfig (Selection, Statement);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          break;\r
+        }\r
+\r
+        //\r
+        // The action button may change some Question value, so refresh the form\r
+        //\r
+        Selection->Action = UI_ACTION_REFRESH_FORM;\r
+        break;\r
+\r
+      case EFI_IFR_RESET_BUTTON_OP:\r
+        //\r
+        // Reset Question to default value specified by DefaultId\r
+        //\r
+        ControlFlag = CfUiDefault;\r
+        DefaultId = Statement->DefaultId;\r
+        break;\r
+\r
+      default:\r
+        //\r
+        // Editable Questions: oneof, ordered list, checkbox, numeric, string, password\r
+        //\r
+        UpdateKeyHelp (Selection, MenuOption, TRUE);\r
+        Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          Repaint = TRUE;\r
+          NewLine = TRUE;\r
+          UpdateKeyHelp (Selection, MenuOption, FALSE);\r
+        } else {\r
+          Selection->Action = UI_ACTION_REFRESH_FORM;\r
+        }\r
+\r
+        if (OptionString != NULL) {\r
+          FreePool (OptionString);\r
+        }\r
+        break;\r
+      }\r
+      break;\r
+\r
+    case CfUiReset:\r
+      //\r
+      // We come here when someone press ESC\r
+      //\r
+      ControlFlag = CfCheckSelection;\r
+      FindNextMenu (Selection, &Repaint, &NewLine);\r
+      break;\r
+\r
+    case CfUiLeft:\r
+      ControlFlag = CfCheckSelection;\r
+      ASSERT(MenuOption != NULL);\r
+      if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {\r
+        if (MenuOption->Sequence != 0) {\r
+          //\r
+          // In the middle or tail of the Date/Time op-code set, go left.\r
+          //\r
+          ASSERT(NewPos != NULL);\r
+          NewPos = NewPos->BackLink;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case CfUiRight:\r
+      ControlFlag = CfCheckSelection;\r
+      ASSERT(MenuOption != NULL);\r
+      if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {\r
+        if (MenuOption->Sequence != 2) {\r
+          //\r
+          // In the middle or tail of the Date/Time op-code set, go left.\r
+          //\r
+          ASSERT(NewPos != NULL);\r
+          NewPos = NewPos->ForwardLink;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case CfUiUp:\r
+      ControlFlag = CfCheckSelection;\r
+\r
+      SavedListEntry = NewPos;\r
+\r
+      ASSERT(NewPos != NULL);\r
+      //\r
+      // Adjust Date/Time position before we advance forward.\r
+      //\r
+      AdjustDateAndTimePosition (TRUE, &NewPos);\r
+      if (NewPos->BackLink != &gMenuOption) {\r
+        MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+        ASSERT (MenuOption != NULL);\r
+        NewLine    = TRUE;\r
+        NewPos     = NewPos->BackLink;\r
+\r
+        PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+        if (PreviousMenuOption->Row == 0) {\r
+          UpdateOptionSkipLines (Selection, PreviousMenuOption);\r
+        }\r
+        DistanceValue = PreviousMenuOption->Skip;\r
+        Difference    = 0;\r
+        if (MenuOption->Row >= DistanceValue + TopRow) {\r
+          Difference = MoveToNextStatement (Selection, TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);\r
+        }\r
+        NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+       \r
+        if (Difference < 0) {\r
+          //\r
+          // We hit the begining MenuOption that can be focused\r
+          // so we simply scroll to the top.\r
+          //\r
+          if (TopOfScreen != gMenuOption.ForwardLink) {\r
+            TopOfScreen = gMenuOption.ForwardLink;\r
+            Repaint     = TRUE;\r
+          } else {\r
+            //\r
+            // Scroll up to the last page when we have arrived at top page.\r
+            //\r
+            NewPos          = &gMenuOption;\r
+            TopOfScreen     = &gMenuOption;\r
+            MenuOption      = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+            ScreenOperation = UiPageUp;\r
+            ControlFlag     = CfScreenOperation;\r
+            break;\r
+          }\r
+        } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {\r
+          //\r
+          // Previous focus MenuOption is above the TopOfScreen, so we need to scroll\r
+          //\r
+          TopOfScreen = NewPos;\r
+          Repaint     = TRUE;\r
+          SkipValue = 0;\r
+        } else if (!IsSelectable (NextMenuOption)) {\r
+          //\r
+          // Continue to go up until scroll to next page or the selectable option is found.\r
+          //\r
+          ScreenOperation = UiUp;\r
+          ControlFlag     = CfScreenOperation;\r
+        }\r
+\r
+        //\r
+        // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
+        //\r
+        AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+        AdjustDateAndTimePosition (TRUE, &NewPos);\r
+        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+        UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+      } else {\r
+        //\r
+        // Scroll up to the last page.\r
+        //\r
+        NewPos          = &gMenuOption;\r
+        TopOfScreen     = &gMenuOption;\r
+        MenuOption      = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+        ScreenOperation = UiPageUp;\r
+        ControlFlag     = CfScreenOperation;\r
+      }\r
+      break;\r
+\r
+    case CfUiPageUp:\r
+      //\r
+      // SkipValue means lines is skipped when show the top menu option.\r
+      //\r
+      ControlFlag     = CfCheckSelection;\r
+\r
+      ASSERT(NewPos != NULL);\r
+      //\r
+      // Already at the first menu option, so do nothing.\r
+      //\r
+      if (NewPos->BackLink == &gMenuOption) {\r
+        NewLine = FALSE;\r
+        Repaint = FALSE;\r
+        break;\r
+      }\r
+\r
+      NewLine   = TRUE;\r
+      Repaint   = TRUE;\r
+\r
+      //\r
+      // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one\r
+      // form of options to be show, so just update the SkipValue to show the next\r
+      // parts of options.\r
+      //\r
+      if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {\r
+        SkipValue -= BottomRow - TopRow + 1;\r
+        break;\r
+      }\r
+\r
+      Link      = TopOfScreen;\r
+      //\r
+      // First minus the menu of the top screen, it's value is SkipValue.\r
+      //\r
+      Index     = (BottomRow + 1) - SkipValue;\r
+      while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {\r
+        Link = Link->BackLink;\r
+        PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+        if (PreviousMenuOption->Row == 0) {\r
+          UpdateOptionSkipLines (Selection, PreviousMenuOption);\r
+        }        \r
+        if (Index < PreviousMenuOption->Skip) {\r
+          break;\r
+        }\r
+        Index = Index - PreviousMenuOption->Skip;\r
+      }\r
+      \r
+      if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {\r
+        SkipValue = 0;\r
+        if (TopOfScreen == &gMenuOption) {\r
+          TopOfScreen = gMenuOption.ForwardLink;\r
+          NewPos      = gMenuOption.BackLink;\r
+          MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);\r
+          Repaint = FALSE;\r
+        } else if (TopOfScreen != Link) {\r
+          TopOfScreen = Link;\r
+          NewPos      = Link;\r
+          MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
+        } else {\r
+          //\r
+          // Finally we know that NewPos is the last MenuOption can be focused.\r
+          //\r
+          Repaint = FALSE;\r
+          NewPos  = Link;\r
+          MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
+        }\r
+      } else {\r
+        if (Index >= TopRow) {\r
+          //\r
+          // At here, only case "Index < PreviousMenuOption->Skip" can reach here.\r
+          //\r
+          SkipValue = PreviousMenuOption->Skip - (Index - TopRow);\r
+        } else {\r
+          SkipValue = PreviousMenuOption->Skip - (TopRow - Index);\r
+          Link = Link->ForwardLink;\r
+        }\r
+\r
+        //\r
+        // Move to the option in Next page.\r
+        //\r
+        if (TopOfScreen == &gMenuOption) {\r
+          NewPos = gMenuOption.BackLink;\r
+          MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);\r
+        } else {\r
+          NewPos = Link;\r
+          MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
+        }\r
+\r
+        //\r
+        // There are more MenuOption needing scrolling up.\r
+        //\r
+        TopOfScreen = Link;\r
+        MenuOption  = NULL;\r
+      }\r
+\r
+      //\r
+      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
+      // Don't do this when we are already in the first page.\r
+      //\r
+      AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+      AdjustDateAndTimePosition (TRUE, &NewPos);\r
+      break;\r
+\r
+    case CfUiPageDown:\r
+      //\r
+      // SkipValue means lines is skipped when show the top menu option.\r
+      //\r
+      ControlFlag     = CfCheckSelection;\r
+\r
+      ASSERT (NewPos != NULL);\r
+      if (NewPos->ForwardLink == &gMenuOption) {\r
+        NewLine = FALSE;\r
+        Repaint = FALSE;\r
+        break;\r
+      }\r
+\r
+      NewLine = TRUE;\r
+      Repaint = TRUE;\r
+      Link    = TopOfScreen;\r
+      NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+      Index = TopRow + NextMenuOption->Skip - SkipValue;\r
+      //\r
+      // Count to the menu option which will show at the top of the next form.\r
+      //\r
+      while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {\r
+        Link           = Link->ForwardLink;\r
+        NextMenuOption = MENU_OPTION_FROM_LINK (Link);\r
+        Index = Index + NextMenuOption->Skip;\r
+      }\r
+\r
+      if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {\r
+        //\r
+        // Finally we know that NewPos is the last MenuOption can be focused.\r
+        //\r
+        Repaint = FALSE;\r
+        MoveToNextStatement (Selection, TRUE, &Link, Index - TopRow);\r
+        SkipValue = 0;\r
+      } else {\r
+        //\r
+        // Calculate the skip line for top of screen menu.\r
+        //\r
+        if (Link == TopOfScreen) {\r
+          //\r
+          // The top of screen menu option occupies the entire form.\r
+          //\r
+          SkipValue += BottomRow - TopRow + 1;\r
+        } else {\r
+          SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));\r
+        }\r
+\r
+        TopOfScreen = Link;\r
+        MenuOption = NULL;\r
+        //\r
+        // Move to the Next selectable menu.\r
+        //\r
+        MoveToNextStatement (Selection, FALSE, &Link, BottomRow - TopRow);\r
+      }\r
+\r
+      //\r
+      // Save the menu as the next highlight menu.\r
+      //\r
+      NewPos  = Link;\r
+\r
+      //\r
+      // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.\r
+      // Don't do this when we are already in the last page.\r
+      //\r
+      AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+      AdjustDateAndTimePosition (TRUE, &NewPos);\r
+      break;\r
+\r
+    case CfUiDown:\r
+      //\r
+      // SkipValue means lines is skipped when show the top menu option.\r
+      // NewPos  points to the menu which is highlighted now.\r
+      //\r
+      ControlFlag = CfCheckSelection;\r
+      //\r
+      // Since the behavior of hitting the down arrow on a Date/Time op-code is intended\r
+      // to be one that progresses to the next set of op-codes, we need to advance to the last\r
+      // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate\r
+      // checking can be done.  The only other logic we need to introduce is that if a Date/Time\r
+      // op-code is the last entry in the menu, we need to rewind back to the first op-code of\r
+      // the Date/Time op-code.\r
+      //\r
+      SavedListEntry = NewPos;\r
+      AdjustDateAndTimePosition (FALSE, &NewPos);\r
+\r
+      if (NewPos->ForwardLink != &gMenuOption) {\r
+        MenuOption      = MENU_OPTION_FROM_LINK (NewPos);\r
+        NewLine         = TRUE;\r
+        NewPos          = NewPos->ForwardLink;\r
+\r
+        Difference      = 0;\r
+        //\r
+        // Current menu not at the bottom of the form.\r
+        //\r
+        if (BottomRow >= MenuOption->Row + MenuOption->Skip) {\r
+          //\r
+          // Find the next selectable menu.\r
+          //\r
+          Difference = MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);\r
+          //\r
+          // We hit the end of MenuOption that can be focused\r
+          // so we simply scroll to the first page.\r
+          //\r
+          if (Difference < 0) {\r
+            //\r
+            // Scroll to the first page.\r
+            //\r
+            if (TopOfScreen != gMenuOption.ForwardLink) {\r
+              TopOfScreen = gMenuOption.ForwardLink;\r
+              Repaint     = TRUE;\r
+              MenuOption  = NULL;\r
+            } else {\r
+              MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+            }\r
+            NewPos        = gMenuOption.ForwardLink;\r
+            MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
+\r
+            SkipValue = 0;\r
+            //\r
+            // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
+            //\r
+            AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+            AdjustDateAndTimePosition (TRUE, &NewPos);\r
+            break;\r
+          }\r
+        }\r
+        NextMenuOption  = MENU_OPTION_FROM_LINK (NewPos);\r
+        if (NextMenuOption->Row == 0) {\r
+          UpdateOptionSkipLines (Selection, NextMenuOption);\r
+        }\r
+        DistanceValue  = Difference + NextMenuOption->Skip;\r
+\r
+        Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;\r
+        if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&\r
+            (NextMenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||\r
+             NextMenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)\r
+            ) {\r
+          Temp ++;\r
+        }\r
+\r
+        //\r
+        // If we are going to scroll, update TopOfScreen\r
+        //\r
+        if (Temp > BottomRow) {\r
+          do {\r
+            //\r
+            // Is the current top of screen a zero-advance op-code?\r
+            // If so, keep moving forward till we hit a >0 advance op-code\r
+            //\r
+            SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+\r
+            //\r
+            // If bottom op-code is more than one line or top op-code is more than one line\r
+            //\r
+            if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {\r
+              //\r
+              // Is the bottom op-code greater than or equal in size to the top op-code?\r
+              //\r
+              if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {\r
+                //\r
+                // Skip the top op-code\r
+                //\r
+                TopOfScreen     = TopOfScreen->ForwardLink;\r
+                Difference      = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);\r
+\r
+                SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+\r
+                //\r
+                // If we have a remainder, skip that many more op-codes until we drain the remainder\r
+                //\r
+                while (Difference >= (INTN) SavedMenuOption->Skip) {\r
+                  //\r
+                  // Since the Difference is greater than or equal to this op-code's skip value, skip it\r
+                  //\r
+                  Difference      = Difference - (INTN) SavedMenuOption->Skip;\r
+                  TopOfScreen     = TopOfScreen->ForwardLink;\r
+                  SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+                }\r
+                //\r
+                // Since we will act on this op-code in the next routine, and increment the\r
+                // SkipValue, set the skips to one less than what is required.\r
+                //\r
+                SkipValue = Difference - 1;\r
+              } else {\r
+                //\r
+                // Since we will act on this op-code in the next routine, and increment the\r
+                // SkipValue, set the skips to one less than what is required.\r
+                //\r
+                SkipValue += (Temp - BottomRow) - 1;\r
+              }\r
+            } else {\r
+              if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {\r
+                TopOfScreen = TopOfScreen->ForwardLink;\r
+                break;\r
+              }\r
+            }\r
+            //\r
+            // If the op-code at the top of the screen is more than one line, let's not skip it yet\r
+            // Let's set a skip flag to smoothly scroll the top of the screen.\r
+            //\r
+            if (SavedMenuOption->Skip > 1) {\r
+              if (SavedMenuOption == NextMenuOption) {\r
+                SkipValue = 0;\r
+              } else {\r
+                SkipValue++;\r
+              }\r
+            } else if (SavedMenuOption->Skip == 1) {\r
+              SkipValue   = 0;\r
+            } else {\r
+              SkipValue   = 0;\r
+              TopOfScreen = TopOfScreen->ForwardLink;\r
+            }\r
+          } while (SavedMenuOption->Skip == 0);\r
+\r
+          Repaint       = TRUE;\r
+        } else if (!IsSelectable (NextMenuOption)) {\r
+          //\r
+          // Continue to go down until scroll to next page or the selectable option is found.\r
+          //\r
+          ScreenOperation = UiDown;\r
+          ControlFlag     = CfScreenOperation;\r
+        }\r
+\r
+        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+\r
+        UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+\r
+      } else {\r
+        //\r
+        // Scroll to the first page.\r
+        //\r
+        if (TopOfScreen != gMenuOption.ForwardLink) {\r
+          TopOfScreen = gMenuOption.ForwardLink;\r
+          Repaint     = TRUE;\r
+          MenuOption  = NULL;\r
+        } else {\r
+          //\r
+          // Need to remove the current highlight menu.\r
+          // MenuOption saved the last highlight menu info.\r
+          //\r
+          MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
+        }\r
+\r
+        SkipValue     = 0;\r
+        NewLine       = TRUE;\r
+        //\r
+        // Get the next highlight menu.\r
+        //\r
+        NewPos        = gMenuOption.ForwardLink;\r
+        MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);\r
+      }\r
+\r
+      //\r
+      // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.\r
+      //\r
+      AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
+      AdjustDateAndTimePosition (TRUE, &NewPos);\r
+      break;\r
+\r
+    case CfUiHotKey:\r
+      ControlFlag = CfCheckSelection;\r
+      \r
+      Status = EFI_SUCCESS;\r
+      //\r
+      // Discard changes. After it, no NV flag is showed.\r
+      //\r
+      if ((HotKey->Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
+        Status = DiscardForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);\r
+        if (!EFI_ERROR (Status)) {\r
+          Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          Selection->Statement = NULL;\r
+          gResetRequired = FALSE;\r
+        } else {\r
+          do {\r
+            CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gDiscardFailed, gPressEnter, gEmptyString);\r
+          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+          //\r
+          // Still show current page.\r
+          //\r
+          Selection->Action = UI_ACTION_NONE;\r
+          Repaint = TRUE;\r
+          NewLine = TRUE;\r
+          break;\r
+        }\r
+      }\r
+\r
+      //\r
+      // Reterieve default setting. After it. NV flag will be showed.\r
+      //\r
+      if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+        Status = ExtractDefault (Selection->FormSet, Selection->Form, HotKey->DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);\r
+        if (!EFI_ERROR (Status)) {\r
+          Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          Selection->Statement = NULL;\r
+          gResetRequired = TRUE;\r
+        } else {\r
+          do {\r
+            CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gDefaultFailed, gPressEnter, gEmptyString);\r
+          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+          //\r
+          // Still show current page.\r
+          //\r
+          Selection->Action = UI_ACTION_NONE;\r
+          Repaint = TRUE;\r
+          NewLine = TRUE;\r
+          break;\r
+        }\r
+      }\r
+\r
+      //\r
+      // Save changes. After it, no NV flag is showed.\r
+      //\r
+      if ((HotKey->Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
+        Status = SubmitForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);\r
+        if (!EFI_ERROR (Status)) {\r
+          ASSERT(MenuOption != NULL);\r
+          UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+        } else {\r
+          do {\r
+            CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gSaveFailed, gPressEnter, gEmptyString);\r
+          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+          //\r
+          // Still show current page.\r
+          //\r
+          Selection->Action = UI_ACTION_NONE;\r
+          Repaint = TRUE;\r
+          NewLine = TRUE;\r
+          break;\r
+        }\r
+      }\r
+      \r
+      //\r
+      // Set Reset required Flag\r
+      //\r
+      if ((HotKey->Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
+        gResetRequired = TRUE;\r
+      }\r
+      \r
+      //\r
+      // Exit Action\r
+      //\r
+      if ((HotKey->Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
+        //\r
+        // Form Exit without saving, Similar to ESC Key.\r
+        // FormSet Exit without saving, Exit SendForm.\r
+        // System Exit without saving, CallExitHandler and Exit SendForm.\r
+        //\r
+        DiscardForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);\r
+        if (gBrowserSettingScope == FormLevel) {\r
+          ControlFlag = CfUiReset;\r
+        } else if (gBrowserSettingScope == FormSetLevel) {\r
+          Selection->Action = UI_ACTION_EXIT;\r
+        } else if (gBrowserSettingScope == SystemLevel) {\r
+          if (ExitHandlerFunction != NULL) {\r
+            ExitHandlerFunction ();\r
+          }\r
+          Selection->Action = UI_ACTION_EXIT;\r
+        }\r
+        Selection->Statement = NULL;\r
+      }\r
+      break;\r
+\r
+    case CfUiDefault:\r
+      ControlFlag = CfCheckSelection;\r
+      //\r
+      // Reset to default value for all forms in the whole system.\r
+      //\r
+      Status = ExtractDefault (Selection->FormSet, NULL, DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        Selection->Action = UI_ACTION_REFRESH_FORM;\r
+        Selection->Statement = NULL;\r
+        gResetRequired = TRUE;\r
+      }\r
+      break;\r
+\r
+    case CfUiNoOperation:\r
+      ControlFlag = CfCheckSelection;\r
+      break;\r
+\r
+    case CfExit:\r
+      UiFreeRefreshList ();\r
+\r
+      gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
+      gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row + 4);\r
+      gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
+      gST->ConOut->OutputString (gST->ConOut, L"\n");\r
+      if (HelpString != NULL) {\r
+        FreePool (HelpString);\r
+      }\r
+      if (HelpHeaderString != NULL) {\r
+        FreePool (HelpHeaderString);\r
+      }\r
+      if (HelpBottomString != NULL) {\r
+        FreePool (HelpBottomString);\r
+      }\r
+\r
+      return EFI_SUCCESS;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  }\r
+}\r
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
new file mode 100644 (file)
index 0000000..03cb0cd
--- /dev/null
@@ -0,0 +1,1067 @@
+/** @file\r
+Private structure, MACRO and function definitions for User Interface related functionalities.\r
+\r
+Copyright (c) 2004 - 2013, 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
+#ifndef _UI_H_\r
+#define _UI_H_\r
+\r
+//\r
+// Globals\r
+//\r
+#define REGULAR_NUMERIC 0\r
+#define TIME_NUMERIC    1\r
+#define DATE_NUMERIC    2\r
+\r
+#define SUBTITLE_INDENT  2\r
+\r
+\r
+//\r
+// It take 23 characters including the NULL to print a 64 bits number with "[" and "]".\r
+// pow(2, 64) = [18446744073709551616]\r
+//\r
+#define MAX_NUMERIC_INPUT_WIDTH 23\r
+\r
+typedef enum {\r
+  UiNoOperation,\r
+  UiSelect,\r
+  UiUp,\r
+  UiDown,\r
+  UiLeft,\r
+  UiRight,\r
+  UiReset,\r
+  UiPrevious,\r
+  UiPageUp,\r
+  UiPageDown,\r
+  UiHotKey,\r
+  UiMaxOperation\r
+} UI_SCREEN_OPERATION;\r
+\r
+typedef enum {\r
+  CfInitialization,\r
+  CfCheckSelection,\r
+  CfRepaint,\r
+  CfRefreshHighLight,\r
+  CfUpdateHelpString,\r
+  CfPrepareToReadKey,\r
+  CfReadKey,\r
+  CfScreenOperation,\r
+  CfUiSelect,\r
+  CfUiReset,\r
+  CfUiLeft,\r
+  CfUiRight,\r
+  CfUiUp,\r
+  CfUiPageUp,\r
+  CfUiPageDown,\r
+  CfUiDown,\r
+  CfUiDefault,\r
+  CfUiNoOperation,\r
+  CfExit,\r
+  CfUiHotKey,\r
+  CfMaxControlFlag\r
+} UI_CONTROL_FLAG;\r
+\r
+#define UI_ACTION_NONE               0\r
+#define UI_ACTION_REFRESH_FORM       1\r
+#define UI_ACTION_REFRESH_FORMSET    2\r
+#define UI_ACTION_EXIT               3\r
+\r
+typedef struct _UI_MENU_LIST UI_MENU_LIST;\r
+\r
+typedef struct {\r
+  EFI_HII_HANDLE  Handle;\r
+\r
+  //\r
+  // Target formset/form/Question information\r
+  //\r
+  EFI_GUID        FormSetGuid;\r
+  UINT16          FormId;\r
+  UINT16          QuestionId;\r
+  UINTN           Sequence;  // used for time/date only.\r
+\r
+  UINTN           TopRow;\r
+  UINTN           BottomRow;\r
+  UINTN           PromptCol;\r
+  UINTN           OptionCol;\r
+  UINTN           CurrentRow;\r
+\r
+  //\r
+  // Ation for Browser to taken:\r
+  //   UI_ACTION_NONE            - navigation inside a form\r
+  //   UI_ACTION_REFRESH_FORM    - re-evaluate expressions and repaint form\r
+  //   UI_ACTION_REFRESH_FORMSET - re-parse formset IFR binary\r
+  //\r
+  UINTN           Action;\r
+\r
+  //\r
+  // Current selected fomset/form/Question\r
+  //\r
+  FORM_BROWSER_FORMSET    *FormSet;\r
+  FORM_BROWSER_FORM       *Form;\r
+  FORM_BROWSER_STATEMENT  *Statement;\r
+\r
+  //\r
+  // Whether the Form is editable\r
+  //\r
+  BOOLEAN                 FormEditable;\r
+\r
+  UI_MENU_LIST            *CurrentMenu;\r
+} UI_MENU_SELECTION;\r
+\r
+#define UI_MENU_OPTION_SIGNATURE  SIGNATURE_32 ('u', 'i', 'm', 'm')\r
+#define UI_MENU_LIST_SIGNATURE    SIGNATURE_32 ('u', 'i', 'm', 'l')\r
+\r
+typedef struct {\r
+  UINTN                   Signature;\r
+  LIST_ENTRY              Link;\r
+\r
+  EFI_HII_HANDLE          Handle;\r
+  FORM_BROWSER_STATEMENT  *ThisTag;\r
+  UINT16                  EntryNumber;\r
+\r
+  UINTN                   Row;\r
+  UINTN                   Col;\r
+  UINTN                   OptCol;\r
+  CHAR16                  *Description;\r
+  UINTN                   Skip;           // Number of lines\r
+\r
+  //\r
+  // Display item sequence for date/time\r
+  //  Date:      Month/Day/Year\r
+  //  Sequence:  0     1   2\r
+  //\r
+  //  Time:      Hour : Minute : Second\r
+  //  Sequence:  0      1        2\r
+  //\r
+  //\r
+  UINTN                   Sequence;\r
+\r
+  BOOLEAN                 GrayOut;\r
+  BOOLEAN                 ReadOnly;\r
+\r
+  //\r
+  // Whether user could change value of this item\r
+  //\r
+  BOOLEAN                 IsQuestion;\r
+} UI_MENU_OPTION;\r
+\r
+#define MENU_OPTION_FROM_LINK(a)  CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)\r
+\r
+struct _UI_MENU_LIST {\r
+  UINTN           Signature;\r
+  LIST_ENTRY      Link;\r
+\r
+  EFI_HII_HANDLE  HiiHandle;\r
+  EFI_GUID        FormSetGuid;\r
+  UINT16          FormId;\r
+  UINT16          QuestionId;\r
+  UINTN           Sequence;    // used for time/date only.\r
+\r
+  UI_MENU_LIST    *Parent;\r
+  LIST_ENTRY      ChildListHead;\r
+};\r
+\r
+#define UI_MENU_LIST_FROM_LINK(a)  CR (a, UI_MENU_LIST, Link, UI_MENU_LIST_SIGNATURE)\r
+\r
+typedef struct _MENU_REFRESH_ENTRY MENU_REFRESH_ENTRY;\r
+struct _MENU_REFRESH_ENTRY {\r
+  MENU_REFRESH_ENTRY          *Next;\r
+  UI_MENU_OPTION              *MenuOption;  // Describes the entry needing an update\r
+  UI_MENU_SELECTION           *Selection;\r
+  UINTN                       CurrentColumn;\r
+  UINTN                       CurrentRow;\r
+  UINTN                       CurrentAttribute;\r
+  EFI_EVENT                   Event;\r
+};\r
+\r
+typedef struct {\r
+  UINT16              ScanCode;\r
+  UI_SCREEN_OPERATION ScreenOperation;\r
+} SCAN_CODE_TO_SCREEN_OPERATION;\r
+\r
+typedef struct {\r
+  UI_SCREEN_OPERATION ScreenOperation;\r
+  UI_CONTROL_FLAG     ControlFlag;\r
+} SCREEN_OPERATION_T0_CONTROL_FLAG;\r
+\r
+\r
+extern LIST_ENTRY          gMenuOption;\r
+extern LIST_ENTRY          gMenuList;\r
+extern MENU_REFRESH_ENTRY  *gMenuRefreshHead;\r
+extern UI_MENU_SELECTION   *gCurrentSelection;\r
+extern BOOLEAN             mHiiPackageListUpdated;\r
+\r
+//\r
+// Global Functions\r
+//\r
+/**\r
+  Initialize Menu option list.\r
+\r
+**/\r
+VOID\r
+UiInitMenu (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initialize Menu option list.\r
+\r
+**/\r
+VOID\r
+UiInitMenuList (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Free Menu option linked list.\r
+\r
+**/\r
+VOID\r
+UiFreeMenu (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Create a menu with specified formset GUID and form ID, and add it as a child\r
+  of the given parent menu.\r
+\r
+  @param  Parent                 The parent of menu to be added.\r
+  @param  HiiHandle              Hii handle related to this formset.\r
+  @param  FormSetGuid            The Formset Guid of menu to be added.\r
+  @param  FormId                 The Form ID of menu to be added.\r
+\r
+  @return A pointer to the newly added menu or NULL if memory is insufficient.\r
+\r
+**/\r
+UI_MENU_LIST *\r
+UiAddMenuList (\r
+  IN OUT UI_MENU_LIST     *Parent,\r
+  IN EFI_HII_HANDLE       HiiHandle,\r
+  IN EFI_GUID             *FormSetGuid,\r
+  IN UINT16               FormId\r
+  );\r
+\r
+/**\r
+  Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.\r
+\r
+  @param  Parent                 The parent of menu to search.\r
+  @param  Handle                 Hii handle related to this formset.\r
+  @param  FormSetGuid            The Formset GUID of the menu to search.  \r
+  @param  FormId                 The Form ID of menu to search.\r
+\r
+  @return A pointer to menu found or NULL if not found.\r
+\r
+**/\r
+UI_MENU_LIST *\r
+UiFindChildMenuList (\r
+  IN UI_MENU_LIST         *Parent,\r
+  IN EFI_HII_HANDLE       Handle,\r
+  IN EFI_GUID             *FormSetGuid, \r
+  IN UINT16               FormId\r
+  );\r
+\r
+/**\r
+  Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.\r
+\r
+  @param  Handle                 Hii handle related to this formset.\r
+  @param  FormSetGuid            The Formset GUID of the menu to search.\r
+  @param  FormId                 The Form ID of menu to search.\r
+\r
+  @return A pointer to menu found or NULL if not found.\r
+\r
+**/\r
+UI_MENU_LIST *\r
+UiFindMenuList (\r
+  IN EFI_HII_HANDLE       Handle,\r
+  IN EFI_GUID             *FormSetGuid,\r
+  IN UINT16               FormId\r
+  );\r
+\r
+/**\r
+  Free Menu list linked list.\r
+\r
+  @param  MenuListHead    One Menu list point in the menu list.\r
+\r
+**/\r
+VOID\r
+UiFreeMenuList (\r
+  LIST_ENTRY   *MenuListHead\r
+  );\r
+\r
+/**\r
+  Free Menu option linked list.\r
+\r
+**/\r
+VOID\r
+UiFreeRefreshList (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Add one menu option by specified description and context.\r
+\r
+  @param  String                 String description for this option.\r
+  @param  Handle                 Hii handle for the package list.\r
+  @param  Form                   The form this statement belong to.\r
+  @param  Statement              Statement of this Menu Option.\r
+  @param  NumberOfLines          Display lines for this Menu Option.\r
+  @param  MenuItemCount          The index for this Option in the Menu.\r
+\r
+  @retval Pointer                Pointer to the added Menu Option.\r
+\r
+**/\r
+UI_MENU_OPTION *\r
+UiAddMenuOption (\r
+  IN CHAR16                  *String,\r
+  IN EFI_HII_HANDLE          Handle,\r
+  IN FORM_BROWSER_FORM       *Form,\r
+  IN FORM_BROWSER_STATEMENT  *Statement,\r
+  IN UINT16                  NumberOfLines,\r
+  IN UINT16                  MenuItemCount\r
+  );\r
+\r
+/**\r
+  Display menu and wait for user to select one menu option, then return it.\r
+  If AutoBoot is enabled, then if user doesn't select any option,\r
+  after period of time, it will automatically return the first menu option.\r
+\r
+  @param  Selection              Menu selection.\r
+\r
+  @return Return the pointer of the menu which selected,\r
+  @return otherwise return NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+UiDisplayMenu (\r
+  IN OUT UI_MENU_SELECTION           *Selection\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
+/**\r
+  Process the goto op code, update the info in the selection structure.\r
+\r
+  @param Statement    The statement belong to goto op code.\r
+  @param Selection    The selection info.\r
+  @param Repaint      Whether need to repaint the menu.\r
+  @param NewLine      Whether need to create new line.\r
+\r
+  @retval EFI_SUCCESS    The menu process successfully.\r
+  @return Other value if the process failed.\r
+**/\r
+EFI_STATUS\r
+ProcessGotoOpCode (\r
+  IN OUT   FORM_BROWSER_STATEMENT      *Statement,\r
+  IN OUT   UI_MENU_SELECTION           *Selection,\r
+  OUT      BOOLEAN                     *Repaint,\r
+  OUT      BOOLEAN                     *NewLine\r
+  );\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
+/**\r
+  Set Buffer to Value for Size bytes.\r
+\r
+  @param  Buffer                 Memory to set.\r
+  @param  Size                   Number of bytes to set\r
+  @param  Value                  Value of the set operation.\r
+\r
+**/\r
+VOID\r
+SetUnicodeMem (\r
+  IN VOID   *Buffer,\r
+  IN UINTN  Size,\r
+  IN CHAR16 Value\r
+  );\r
+\r
+/**\r
+  Wait for a given event to fire, or for an optional timeout to expire.\r
+\r
+  @param  Event                  The event to wait for\r
+  @param  Timeout                An optional timeout value in 100 ns units.\r
+  @param  RefreshInterval        Menu refresh interval (in seconds).\r
+\r
+  @retval EFI_SUCCESS            Event fired before Timeout expired.\r
+  @retval EFI_TIME_OUT           Timout expired before Event fired.\r
+\r
+**/\r
+EFI_STATUS\r
+UiWaitForSingleEvent (\r
+  IN EFI_EVENT                Event,\r
+  IN UINT64                   Timeout, OPTIONAL\r
+  IN UINT8                    RefreshInterval OPTIONAL\r
+  );\r
+\r
+/**\r
+  Draw a pop up windows based on the dimension, number of lines and\r
+  strings specified.\r
+\r
+  @param ScreenWidth     The width of the pop-up.\r
+  @param NumberOfLines   The number of lines.\r
+  @param ...             A series of text strings that displayed in the pop-up.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CreateMultiStringPopUp (\r
+  IN  UINTN                       ScreenWidth,\r
+  IN  UINTN                       NumberOfLines,\r
+  ...\r
+  );\r
+\r
+/**\r
+  Get string or password input from user.\r
+\r
+  @param  MenuOption        Pointer to the current input menu.\r
+  @param  Prompt            The prompt string shown on popup window.\r
+  @param  StringPtr         Old user input and destination for use input string.\r
+\r
+  @retval EFI_SUCCESS       If string input is read successfully\r
+  @retval EFI_DEVICE_ERROR  If operation fails\r
+\r
+**/\r
+EFI_STATUS\r
+ReadString (\r
+  IN     UI_MENU_OPTION              *MenuOption,\r
+  IN     CHAR16                      *Prompt,\r
+  IN OUT CHAR16                      *StringPtr\r
+  );\r
+\r
+/**\r
+  Get selection for OneOf and OrderedList (Left/Right will be ignored).\r
+\r
+  @param  Selection         Pointer to current selection.\r
+  @param  MenuOption        Pointer to the current input menu.\r
+\r
+  @retval EFI_SUCCESS       If Option input is processed successfully\r
+  @retval EFI_DEVICE_ERROR  If operation fails\r
+\r
+**/\r
+EFI_STATUS\r
+GetSelectionInputPopUp (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption\r
+  );\r
+\r
+/**\r
+  This routine reads a numeric value from the user input.\r
+\r
+  @param  Selection         Pointer to current selection.\r
+  @param  MenuOption        Pointer to the current input menu.\r
+\r
+  @retval EFI_SUCCESS       If numerical input is read successfully\r
+  @retval EFI_DEVICE_ERROR  If operation fails\r
+\r
+**/\r
+EFI_STATUS\r
+GetNumericInput (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption\r
+  );\r
+\r
+/**\r
+  Update status bar on the bottom of menu.\r
+\r
+  @param  Selection              Current selection info.\r
+  @param  MessageType            The type of message to be shown.\r
+  @param  Flags                  The flags in Question header.\r
+  @param  State                  Set or clear.\r
+\r
+**/\r
+VOID\r
+UpdateStatusBar (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UINTN                       MessageType,\r
+  IN  UINT8                       Flags,\r
+  IN  BOOLEAN                     State\r
+  );\r
+\r
+/**\r
+  Process Question Config.\r
+\r
+  @param  Selection              The UI menu selection.\r
+  @param  Question               The Question to be peocessed.\r
+\r
+  @retval EFI_SUCCESS            Question Config process success.\r
+  @retval Other                  Question Config process fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessQuestionConfig (\r
+  IN  UI_MENU_SELECTION       *Selection,\r
+  IN  FORM_BROWSER_STATEMENT  *Question\r
+  );\r
+\r
+/**\r
+  Print Question Value according to it's storage width and display attributes.\r
+\r
+  @param  Question               The Question to be printed.\r
+  @param  FormattedNumber        Buffer for output string.\r
+  @param  BufferSize             The FormattedNumber buffer size in bytes.\r
+\r
+  @retval EFI_SUCCESS            Print success.\r
+  @retval EFI_BUFFER_TOO_SMALL   Buffer size is not enough for formatted number.\r
+\r
+**/\r
+EFI_STATUS\r
+PrintFormattedNumber (\r
+  IN FORM_BROWSER_STATEMENT   *Question,\r
+  IN OUT CHAR16               *FormattedNumber,\r
+  IN UINTN                    BufferSize\r
+  );\r
+\r
+/**\r
+  Search an Option of a Question by its value.\r
+\r
+  @param  Question               The Question\r
+  @param  OptionValue            Value for Option to be searched.\r
+\r
+  @retval Pointer                Pointer to the found Option.\r
+  @retval NULL                   Option not found.\r
+\r
+**/\r
+QUESTION_OPTION *\r
+ValueToOption (\r
+  IN FORM_BROWSER_STATEMENT   *Question,\r
+  IN EFI_HII_VALUE            *OptionValue\r
+  );\r
+\r
+/**\r
+  Return data element in an Array by its Index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Index                  Zero based index for data in this array.\r
+\r
+  @retval Value                  The data to be returned\r
+\r
+**/\r
+UINT64\r
+GetArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINTN                    Index\r
+  );\r
+\r
+/**\r
+  Set value of a data element in an Array by its Index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Index                  Zero based index for data in this array.\r
+  @param  Value                  The value to be set.\r
+\r
+**/\r
+VOID\r
+SetArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINTN                    Index,\r
+  IN UINT64                   Value\r
+  );\r
+\r
+/**\r
+  Check whether this value already in the array, if yes, return the index.\r
+\r
+  @param  Array                  The data array.\r
+  @param  Type                   Type of the data in this array.\r
+  @param  Value                  The value to be find.\r
+  @param  Index                  The index in the array which has same value with Value.\r
+  \r
+  @retval   TRUE Found the value in the array.\r
+  @retval   FALSE Not found the value.\r
+\r
+**/\r
+BOOLEAN \r
+FindArrayData (\r
+  IN VOID                     *Array,\r
+  IN UINT8                    Type,\r
+  IN UINT64                   Value,\r
+  OUT UINTN                   *Index OPTIONAL\r
+  );\r
+\r
+/**\r
+  Process a Question's Option (whether selected or un-selected).\r
+\r
+  @param  Selection              Pointer to UI_MENU_SELECTION.\r
+  @param  MenuOption             The MenuOption for this Question.\r
+  @param  Selected               TRUE: if Question is selected.\r
+  @param  OptionString           Pointer of the Option String to be displayed.\r
+\r
+  @retval EFI_SUCCESS            Question Option process success.\r
+  @retval Other                  Question Option process fail.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessOptions (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
+  IN  UI_MENU_OPTION              *MenuOption,\r
+  IN  BOOLEAN                     Selected,\r
+  OUT CHAR16                      **OptionString\r
+  );\r
+\r
+/**\r
+  Process the help string: Split StringPtr to several lines of strings stored in\r
+  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.\r
+\r
+  @param  StringPtr              The entire help string.\r
+  @param  FormattedString        The oupput formatted string.\r
+  @param  EachLineWidth          The string length of each line in the formatted string.\r
+  @param  RowCount               TRUE: if Question is selected.\r
+\r
+**/\r
+UINTN\r
+ProcessHelpString (\r
+  IN  CHAR16  *StringPtr,\r
+  OUT CHAR16  **FormattedString,\r
+  OUT UINT16  *EachLineWidth,\r
+  IN  UINTN   RowCount\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
+/**\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
+/**\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
+/**\r
+  Will copy LineWidth amount of a string in the OutputString buffer and return the\r
+  number of CHAR16 characters that were copied into the OutputString buffer.\r
+  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.\r
+\r
+  @param  InputString            String description for this option.\r
+  @param  LineWidth              Width of the desired string to extract in CHAR16\r
+                                 characters\r
+  @param  GlyphWidth             The glyph width of the beging char in the string.\r
+  @param  Index                  Where in InputString to start the copy process\r
+  @param  OutputString           Buffer to copy the string into\r
+\r
+  @return Returns the number of CHAR16 characters that were copied into the OutputString buffer.\r
+\r
+**/\r
+UINT16\r
+GetLineByWidth (\r
+  IN      CHAR16                      *InputString,\r
+  IN      UINT16                      LineWidth,\r
+  IN OUT  UINT16                      *GlyphWidth,\r
+  IN OUT  UINTN                       *Index,\r
+  OUT     CHAR16                      **OutputString\r
+  );\r
+\r
+/**\r
+  Get the supported width for a particular op-code\r
+\r
+  @param  Statement              The FORM_BROWSER_STATEMENT structure passed in.\r
+  @param  Handle                 The handle in the HII database being used\r
+\r
+  @return Returns the number of CHAR16 characters that is support.\r
+\r
+**/\r
+UINT16\r
+GetWidth (\r
+  IN FORM_BROWSER_STATEMENT        *Statement,\r
+  IN EFI_HII_HANDLE                 Handle\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
+/**\r
+  Wait for a key to be pressed by user.\r
+\r
+  @param Key         The key which is pressed by user.\r
+\r
+  @retval EFI_SUCCESS The function always completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+WaitForKeyStroke (\r
+  OUT  EFI_INPUT_KEY           *Key\r
+  );\r
+\r
+/**\r
+  Reset stack pointer to begin of the stack.\r
+\r
+**/\r
+VOID\r
+ResetScopeStack (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Push the expression options onto the Stack.\r
+\r
+  @param  Pointer                Pointer to the current expression.\r
+  @param  Level                  Which type this expression belong to. Form, \r
+                                 statement or option?\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushConditionalExpression (\r
+  IN FORM_EXPRESSION     *Pointer,\r
+  IN EXPRESS_LEVEL               Level\r
+  );\r
+\r
+/**\r
+  Pop the expression options from the Stack\r
+\r
+  @param  Level                  Which type this expression belong to. Form, \r
+                                 statement or option?\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopConditionalExpression (\r
+  IN  EXPRESS_LEVEL      Level\r
+  );\r
+  \r
+/**\r
+  Get the expression Buffer pointer.\r
+  \r
+  @param  Level                  Which type this expression belong to. Form, \r
+                                 statement or option?\r
+\r
+  @retval  The start pointer of the expression buffer or NULL.\r
+\r
+**/\r
+FORM_EXPRESSION **\r
+GetConditionalExpressionList (\r
+  IN EXPRESS_LEVEL       Level\r
+  );\r
+\r
+/**\r
+  Get the expression list count.\r
+  \r
+  @param  Level                  Which type this expression belong to. Form, \r
+                                 statement or option?\r
+\r
+  @retval >=0                    The expression count\r
+  @retval -1                     Input parameter error.\r
+\r
+**/\r
+INTN \r
+GetConditionalExpressionCount (\r
+  IN EXPRESS_LEVEL       Level\r
+  );\r
+\r
+/**\r
+  Push an Operand onto the Stack\r
+\r
+  @param  Operand                Operand to push.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushScope (\r
+  IN UINT8   Operand\r
+  );\r
+\r
+/**\r
+  Pop an Operand from the Stack\r
+\r
+  @param  Operand                Operand to pop.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopScope (\r
+  OUT UINT8     *Operand\r
+  );\r
+\r
+/**\r
+  Reset stack pointer to begin of the stack.\r
+\r
+**/\r
+VOID\r
+ResetCurrentExpressionStack (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Push current expression onto the Stack\r
+\r
+  @param  Pointer                Pointer to current expression.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushCurrentExpression (\r
+  IN VOID  *Pointer\r
+  );\r
+\r
+/**\r
+  Pop current expression from the Stack\r
+\r
+  @param  Pointer                Pointer to current expression to be pop.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopCurrentExpression (\r
+  OUT VOID    **Pointer\r
+  );\r
+\r
+/**\r
+  Reset stack pointer to begin of the stack.\r
+\r
+**/\r
+VOID\r
+ResetMapExpressionListStack (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Push the list of map expression onto the Stack\r
+\r
+  @param  Pointer                Pointer to the list of map expression to be pushed.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PushMapExpressionList (\r
+  IN VOID  *Pointer\r
+  );\r
+\r
+/**\r
+  Pop the list of map expression from the Stack\r
+\r
+  @param  Pointer                Pointer to the list of map expression to be pop.\r
+\r
+  @retval EFI_SUCCESS            The value was pushed onto the stack.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+PopMapExpressionList (\r
+  OUT VOID    **Pointer\r
+  );\r
+\r
+/**\r
+  Get Form given its FormId.\r
+\r
+  @param  FormSet                The formset which contains this form.\r
+  @param  FormId                 Id of this form.\r
+\r
+  @retval Pointer                The form.\r
+  @retval NULL                   Specified Form is not found in the formset.\r
+\r
+**/\r
+FORM_BROWSER_FORM *\r
+IdToForm (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN UINT16                FormId\r
+  );\r
+\r
+/**\r
+  Search a Question in Formset scope using its QuestionId.\r
+\r
+  @param  FormSet                The formset which contains this form.\r
+  @param  Form                   The form which contains this Question.\r
+  @param  QuestionId             Id of this Question.\r
+\r
+  @retval Pointer                The Question.\r
+  @retval NULL                   Specified Question not found in the form.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+IdToQuestion (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form,\r
+  IN UINT16                QuestionId\r
+  );\r
+\r
+/**\r
+  Zero extend integer/boolean/date/time to UINT64 for comparing.\r
+\r
+  @param  Value                  HII Value to be converted.\r
+\r
+**/\r
+VOID\r
+ExtendValueToU64 (\r
+  IN  EFI_HII_VALUE   *Value\r
+  );\r
+\r
+/**\r
+  Compare two Hii value.\r
+\r
+  @param  Value1                 Expression value to compare on left-hand.\r
+  @param  Value2                 Expression value to compare on right-hand.\r
+  @param  Result                 Return value after compare.\r
+                                 retval 0                      Two operators equal.\r
+                                 return Positive value if Value1 is greater than Value2.\r
+                                 retval Negative value if Value1 is less than Value2.\r
+  @param  HiiHandle              Only required for string compare.\r
+\r
+  @retval other                  Could not perform compare on two values.\r
+  @retval EFI_SUCCESS            Compare the value success.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareHiiValue (\r
+  IN  EFI_HII_VALUE   *Value1,\r
+  IN  EFI_HII_VALUE   *Value2,\r
+  OUT INTN            *Result,\r
+  IN  EFI_HII_HANDLE  HiiHandle OPTIONAL\r
+  );\r
+\r
+/**\r
+  Evaluate the result of a HII expression\r
+\r
+  If Expression is NULL, then ASSERT.\r
+\r
+  @param  FormSet                FormSet associated with this expression.\r
+  @param  Form                   Form associated with this expression.\r
+  @param  Expression             Expression to be evaluated.\r
+\r
+  @retval EFI_SUCCESS            The expression evaluated successfuly\r
+  @retval EFI_NOT_FOUND          The Question which referenced by a QuestionId\r
+                                 could not be found.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough system memory to grow the\r
+                                 stack.\r
+  @retval EFI_ACCESS_DENIED      The pop operation underflowed the stack\r
+  @retval EFI_INVALID_PARAMETER  Syntax error with the Expression\r
+\r
+**/\r
+EFI_STATUS\r
+EvaluateExpression (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN FORM_BROWSER_FORM     *Form,\r
+  IN OUT FORM_EXPRESSION   *Expression\r
+  );\r
+\r
+/**\r
+  Return the result of the expression list. Check the expression list and \r
+  return the highest priority express result.  \r
+  Priority: DisableIf > SuppressIf > GrayOutIf > FALSE\r
+\r
+  @param  ExpList             The input expression list.\r
+  @param  Evaluate            Whether need to evaluate the expression first.\r
+  @param  FormSet             FormSet associated with this expression. Only \r
+                              needed when Evaluate is TRUE\r
+  @param  Form                Form associated with this expression. Only \r
+                              needed when Evaluate is TRUE \r
+\r
+  @retval EXPRESS_RESULT      Return the higher priority express result. \r
+                              DisableIf > SuppressIf > GrayOutIf > FALSE\r
+\r
+**/\r
+EXPRESS_RESULT \r
+EvaluateExpressionList (\r
+  IN FORM_EXPRESSION_LIST *ExpList,\r
+  IN BOOLEAN              Evaluate,\r
+  IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL\r
+  IN FORM_BROWSER_FORM    *Form OPTIONAL\r
+  );\r
+\r
+#endif // _UI_H\r
index 507e7ed0e1da803619dda3140f23d06a43ac971b..cfcfc4234d804fcfe3102508d257ff8a4f354cc8 100644 (file)
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf\r
   GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf\r
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf\r
   GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
   TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
   SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf\r
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
   TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
   SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf\r
 \r
   IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 \r
   IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   MdeModulePkg/Universal/PrintDxe/PrintDxe.inf\r
   MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf {\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   MdeModulePkg/Universal/PrintDxe/PrintDxe.inf\r
   MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf {\r
index 7315d432fa5558bc8108c0485f07a4252f4744b2..2b8a8e76d3c9295b4586093676734dde5825a50c 100644 (file)
@@ -233,7 +233,6 @@ INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
 INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf\r
 INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf\r
 INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf\r
 INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf\r
 INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf\r
 INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf\r
-INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf\r
 INF  RuleOverride = TIANOCOMPRESSED MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf\r
 INF  RuleOverride = TIANOCOMPRESSED MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf\r
index 28b1815c70ed389548599b727afd49ab2cede081..f732703fdb3c06c07d5e166c4ae1d4266c15701e 100644 (file)
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
   PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
   OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf {\r
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
   OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf {\r
index 7acd16717e8465906d1387c3a2efad9fa9b1f7e4..be6ca885b947c4e1a302a7ec2121364f631ab43e 100644 (file)
@@ -211,7 +211,6 @@ INF  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
 INF  PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 INF  PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
 INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf\r
 INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
 INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf\r
index 2b35027b6a91d1586736af20292b43f45ece80a1..dcfb95aa3217fe4c9e8479a385347dbae0a7f864 100644 (file)
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
   PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
   OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf {\r
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
   OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf {\r
index 2bd31f6b8219528cf8b4c55c3f7dd23357cb782c..fe77a3a3de65ffb627161f91267569a61e8ccfd4 100644 (file)
@@ -212,7 +212,6 @@ INF  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
 INF  PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 INF  PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
 INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf\r
 INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
 INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf\r
index cd09beb3b458ce36a8afe74643b897db0cd95762..89ce44e6d28ae05d1777e794a82d6ff5c6467e27 100644 (file)
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf\r
   LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf\r
-  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
 \r
 !ifdef $(SOURCE_DEBUG_ENABLE)\r
   PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
   PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
   PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
   MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
   OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf {\r
   MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
   OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf {\r
index 7db09cad55d786176436bba2f81c498a84690706..abeedefd85552b65ace57cd077c5411bb18fbc6e 100644 (file)
@@ -211,7 +211,6 @@ INF  IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf
 INF  PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
 INF  PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf\r
 INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
 INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
-INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
 INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
 INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf\r
 INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
 \r
 INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf\r