]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
MdeModulePkg: Enable reconnect request from action request or question flag.
[mirror_edk2.git] / MdeModulePkg / Universal / DisplayEngineDxe / FormDisplay.c
index 0db450e078d1f7a750730bcd4969c59a87715691..e198a5e9570f34c5f9974f1b454fcfdfac3f4a3b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Entry and initialization module for the browser.\r
 \r
-Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -98,8 +98,7 @@ EFI_GUID  gDisplayEngineGuid = {
   0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}\r
 };\r
 \r
-FORM_ENTRY_INFO               gFormEntryInfo;\r
-UINTN                         gSequence;\r
+BOOLEAN                       gMisMatch;\r
 EFI_SCREEN_DESCRIPTOR         gStatementDimensions;\r
 BOOLEAN                       mStatementLayoutIsChanged = TRUE;\r
 USER_INPUT                    *gUserInput;\r
@@ -114,9 +113,13 @@ FORM_ENTRY_INFO               gOldFormEntry = {0};
 //\r
 // Browser Global Strings\r
 //\r
+CHAR16            *gReconnectConfirmChanges;\r
+CHAR16            *gReconnectFail;\r
+CHAR16            *gReconnectRequired;\r
+CHAR16            *gChangesOpt;\r
 CHAR16            *gFormNotFound;\r
 CHAR16            *gNoSubmitIf;\r
-CHAR16            *gBrwoserError;\r
+CHAR16            *gBrowserError;\r
 CHAR16            *gSaveFailed;\r
 CHAR16            *gNoSubmitIfFailed;\r
 CHAR16            *gSaveProcess;\r
@@ -136,7 +139,20 @@ CHAR16            *gMiniString;
 CHAR16            *gOptionMismatch;\r
 CHAR16            *gFormSuppress;\r
 CHAR16            *gProtocolNotFound;\r
-\r
+CHAR16            *gConfirmDefaultMsg;\r
+CHAR16            *gConfirmSubmitMsg;\r
+CHAR16            *gConfirmDiscardMsg;\r
+CHAR16            *gConfirmResetMsg;\r
+CHAR16            *gConfirmExitMsg;\r
+CHAR16            *gConfirmSubmitMsg2nd;\r
+CHAR16            *gConfirmDefaultMsg2nd;\r
+CHAR16            *gConfirmResetMsg2nd;\r
+CHAR16            *gConfirmExitMsg2nd;\r
+CHAR16            *gConfirmOpt;\r
+CHAR16            *gConfirmOptYes;\r
+CHAR16            *gConfirmOptNo;\r
+CHAR16            *gConfirmMsgConnect;\r
+CHAR16            *gConfirmMsgEnd;\r
 CHAR16            gModalSkipColumn;\r
 CHAR16            gPromptBlockWidth;\r
 CHAR16            gOptionBlockWidth;\r
@@ -191,9 +207,13 @@ InitializeDisplayStrings (
   VOID\r
   )\r
 {\r
+  gReconnectConfirmChanges = GetToken (STRING_TOKEN (RECONNECT_CONFIRM_CHANGES), gHiiHandle);\r
   mUnknownString        = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);\r
   gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);\r
   gNoSubmitIfFailed     = GetToken (STRING_TOKEN (NO_SUBMIT_IF_CHECK_FAILED), gHiiHandle);\r
+  gReconnectFail        = GetToken (STRING_TOKEN (RECONNECT_FAILED), gHiiHandle);\r
+  gReconnectRequired    = GetToken (STRING_TOKEN (RECONNECT_REQUIRED), gHiiHandle);\r
+  gChangesOpt           = GetToken (STRING_TOKEN (RECONNECT_CHANGES_OPTIONS), gHiiHandle);\r
   gSaveProcess          = GetToken (STRING_TOKEN (DISCARD_OR_JUMP), gHiiHandle);\r
   gSaveNoSubmitProcess  = GetToken (STRING_TOKEN (DISCARD_OR_CHECK), gHiiHandle);\r
   gDiscardChange        = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_DISCARD), gHiiHandle);\r
@@ -213,7 +233,21 @@ InitializeDisplayStrings (
   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
+  gBrowserError         = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);\r
+  gConfirmDefaultMsg    = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE), gHiiHandle);\r
+  gConfirmDiscardMsg    = GetToken (STRING_TOKEN (CONFIRM_DISCARD_MESSAGE), gHiiHandle);\r
+  gConfirmSubmitMsg     = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE), gHiiHandle);\r
+  gConfirmResetMsg      = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE), gHiiHandle);\r
+  gConfirmExitMsg       = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE), gHiiHandle);\r
+  gConfirmDefaultMsg2nd = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE_2ND), gHiiHandle);\r
+  gConfirmSubmitMsg2nd  = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE_2ND), gHiiHandle);\r
+  gConfirmResetMsg2nd   = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_2ND), gHiiHandle);\r
+  gConfirmExitMsg2nd    = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2ND), gHiiHandle);\r
+  gConfirmOpt           = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);\r
+  gConfirmOptYes        = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);\r
+  gConfirmOptNo         = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);\r
+  gConfirmMsgConnect    = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);\r
+  gConfirmMsgEnd        = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);\r
 }\r
 \r
 /**\r
@@ -230,6 +264,10 @@ FreeDisplayStrings (
   FreePool (gEmptyString);\r
   FreePool (gSaveFailed);\r
   FreePool (gNoSubmitIfFailed);\r
+  FreePool (gReconnectFail);\r
+  FreePool (gReconnectRequired);\r
+  FreePool (gChangesOpt);\r
+  FreePool (gReconnectConfirmChanges);\r
   FreePool (gSaveProcess);\r
   FreePool (gSaveNoSubmitProcess);\r
   FreePool (gDiscardChange);\r
@@ -246,9 +284,23 @@ FreeDisplayStrings (
   FreePool (gOptionMismatch);\r
   FreePool (gFormSuppress);\r
   FreePool (gProtocolNotFound);\r
-  FreePool (gBrwoserError);\r
+  FreePool (gBrowserError);\r
   FreePool (gNoSubmitIf);\r
   FreePool (gFormNotFound);\r
+  FreePool (gConfirmDefaultMsg);\r
+  FreePool (gConfirmSubmitMsg);\r
+  FreePool (gConfirmDiscardMsg);\r
+  FreePool (gConfirmResetMsg);\r
+  FreePool (gConfirmExitMsg);\r
+  FreePool (gConfirmDefaultMsg2nd);\r
+  FreePool (gConfirmSubmitMsg2nd);\r
+  FreePool (gConfirmResetMsg2nd);\r
+  FreePool (gConfirmExitMsg2nd);\r
+  FreePool (gConfirmOpt);\r
+  FreePool (gConfirmOptYes);\r
+  FreePool (gConfirmOptNo);\r
+  FreePool (gConfirmMsgConnect);\r
+  FreePool (gConfirmMsgEnd);\r
 }\r
 \r
 /**\r
@@ -1474,6 +1526,238 @@ FindTopOfScreenMenu (
   return TopOfScreen;\r
 }\r
 \r
+/**\r
+  Get the index info for this opcode.\r
+\r
+  @param  OpCode      The input opcode for the statement.\r
+\r
+  @retval  The index of this statement.\r
+\r
+**/\r
+UINTN\r
+GetIndexInfoForOpcode (\r
+  IN EFI_IFR_OP_HEADER  *OpCode\r
+  )\r
+{\r
+  LIST_ENTRY                      *NewPos;\r
+  UI_MENU_OPTION                  *MenuOption;\r
+  UINTN                           Index;\r
+\r
+  NewPos = gMenuOption.ForwardLink;\r
+  Index  = 0;\r
+\r
+  for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink){\r
+    MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+    if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) {\r
+      if (MenuOption->ThisTag->OpCode == OpCode) {\r
+        return Index;\r
+      }\r
+\r
+      Index ++;\r
+    }\r
+  }\r
+\r
+  return Index;\r
+}\r
+\r
+/**\r
+  Is this the saved highlight statement.\r
+\r
+  @param  HighLightedStatement      The input highlight statement.\r
+\r
+  @retval  TRUE   This is the highlight statement.\r
+  @retval  FALSE  This is not the highlight statement.\r
+\r
+**/\r
+BOOLEAN \r
+IsSavedHighlightStatement (\r
+  IN FORM_DISPLAY_ENGINE_STATEMENT  *HighLightedStatement\r
+  )\r
+{\r
+  if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) &&\r
+      (gFormData->FormId == gHighligthMenuInfo.FormId)) {\r
+    if (gHighligthMenuInfo.HLTQuestionId != 0) {\r
+      return (BOOLEAN) (gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode));\r
+    } else {\r
+      if (CompareMem (gHighligthMenuInfo.HLTOpCode, HighLightedStatement->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {\r
+        if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(HighLightedStatement->OpCode)) {\r
+          return TRUE;\r
+        } else {\r
+          return FALSE;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Is this the highlight menu.\r
+\r
+  @param  MenuOption      The input Menu option.\r
+\r
+  @retval  TRUE   This is the highlight menu option.\r
+  @retval  FALSE  This is not the highlight menu option.\r
+\r
+**/\r
+BOOLEAN\r
+IsHighLightMenuOption (\r
+  IN UI_MENU_OPTION     *MenuOption\r
+  )\r
+{\r
+  if (gHighligthMenuInfo.HLTQuestionId != 0) {\r
+    if (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.HLTQuestionId) {\r
+      return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);\r
+    }\r
+  } else {\r
+    if(CompareMem (gHighligthMenuInfo.HLTOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {\r
+      if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) {\r
+        return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);\r
+      } else {\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Find the highlight menu.\r
+\r
+  If the input is NULL, base on the record highlight info in\r
+  gHighligthMenuInfo to find the last highlight menu.\r
+\r
+  @param  HighLightedStatement      The input highlight statement.\r
+\r
+  @retval  The highlight menu index.\r
+\r
+**/\r
+LIST_ENTRY *\r
+FindHighLightMenuOption (\r
+ IN FORM_DISPLAY_ENGINE_STATEMENT  *HighLightedStatement\r
+ )\r
+{\r
+  LIST_ENTRY                      *NewPos;\r
+  UI_MENU_OPTION                  *MenuOption;\r
+\r
+  NewPos = gMenuOption.ForwardLink;\r
+  MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+  if (HighLightedStatement != NULL) {\r
+    while (MenuOption->ThisTag != HighLightedStatement) {\r
+      NewPos     = NewPos->ForwardLink;\r
+      if (NewPos == &gMenuOption) {\r
+        //\r
+        // Not Found it, break\r
+        //\r
+        break;\r
+      }\r
+      MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+    }\r
+\r
+    //\r
+    // Must find the highlight statement.\r
+    //\r
+    ASSERT (NewPos != &gMenuOption);\r
+\r
+  } else {\r
+    while (!IsHighLightMenuOption (MenuOption)) {\r
+      NewPos     = NewPos->ForwardLink;\r
+      if (NewPos == &gMenuOption) {\r
+        //\r
+        // Not Found it, break\r
+        //\r
+        break;\r
+      }\r
+      MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+    }\r
+\r
+    //\r
+    // Highlight statement has disappear (suppressed/disableed)\r
+    //\r
+    if (NewPos == &gMenuOption) {\r
+      NewPos = NULL;\r
+    }\r
+  }\r
+\r
+  return NewPos;\r
+}\r
+\r
+/**\r
+  Is this the Top of screen menu.\r
+\r
+  @param  MenuOption      The input Menu option.\r
+\r
+  @retval  TRUE   This is the Top of screen menu option.\r
+  @retval  FALSE  This is not the Top of screen menu option.\r
+\r
+**/\r
+BOOLEAN\r
+IsTopOfScreeMenuOption (\r
+  IN UI_MENU_OPTION     *MenuOption\r
+  )\r
+{\r
+  if (gHighligthMenuInfo.TOSQuestionId != 0) {\r
+    return (BOOLEAN) (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.TOSQuestionId);\r
+  } \r
+\r
+  if(CompareMem (gHighligthMenuInfo.TOSOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.TOSOpCode->Length) == 0) {\r
+    if (gHighligthMenuInfo.TOSIndex == 0 || gHighligthMenuInfo.TOSIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) {\r
+      return TRUE;\r
+    } else {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Find the Top of screen menu.\r
+\r
+  If the input is NULL, base on the record highlight info in\r
+  gHighligthMenuInfo to find the last highlight menu.\r
+\r
+  @param  HighLightedStatement      The input highlight statement.\r
+\r
+  @retval  The highlight menu index.\r
+\r
+**/\r
+LIST_ENTRY *\r
+FindTopOfScreenMenuOption (\r
+ VOID\r
+ )\r
+{\r
+  LIST_ENTRY                      *NewPos;\r
+  UI_MENU_OPTION                  *MenuOption;\r
+\r
+  NewPos = gMenuOption.ForwardLink;\r
+  MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+\r
+  while (!IsTopOfScreeMenuOption(MenuOption)) {\r
+    NewPos     = NewPos->ForwardLink;\r
+    if (NewPos == &gMenuOption) {\r
+      //\r
+      // Not Found it, break\r
+      //\r
+      break;\r
+    }\r
+    MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+  }\r
+\r
+  //\r
+  // Last time top of screen menu has disappeared.\r
+  //\r
+  if (NewPos == &gMenuOption) {\r
+    NewPos = NULL;\r
+  }\r
+\r
+  return NewPos;\r
+}\r
+\r
 /**\r
   Find the first menu which will be show at the top.\r
 \r
@@ -1491,160 +1775,228 @@ FindTopMenu (
   OUT UINTN                     *SkipValue\r
   )\r
 {\r
-  LIST_ENTRY                      *NewPos;\r
   UINTN                           TopRow;\r
   UINTN                           BottomRow;\r
-  UI_MENU_OPTION                  *SavedMenuOption;\r
+  UI_MENU_OPTION                  *MenuOption;\r
   UINTN                           TmpValue;\r
 \r
-  TmpValue  = 0;\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, TRUE);\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
+  if (gMisMatch) {\r
+    //\r
+    // Reenter caused by option mismatch or auto exit caused by refresh form(refresh interval/guid), \r
+    // base on the record highlight info to find the highlight menu.\r
+    //\r
+    ASSERT (gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle &&\r
+            gFormData->FormId == gHighligthMenuInfo.FormId);\r
 \r
-  while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||\r
-         (SavedMenuOption->Sequence != gSequence)) {\r
-    NewPos     = NewPos->ForwardLink;\r
-    if (NewPos == &gMenuOption) {\r
+    *HighlightMenu = FindHighLightMenuOption(NULL);\r
+    if (*HighlightMenu != NULL) {\r
       //\r
-      // Not Found it, break\r
+      // Update skip info for this highlight menu.\r
       //\r
-      break;\r
-    }\r
-    SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-  }\r
-  ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);\r
-\r
-  *HighlightMenu = NewPos;\r
+      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
+      UpdateOptionSkipLines (MenuOption);\r
 \r
-  AdjustDateAndTimePosition(FALSE, &NewPos);\r
-  SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-  UpdateOptionSkipLines (SavedMenuOption);\r
+      //\r
+      // Found the last time highlight menu.\r
+      //\r
+      *TopOfScreen = FindTopOfScreenMenuOption();\r
+      if (*TopOfScreen != NULL) {\r
+        //\r
+        // Found the last time selectable top of screen menu.\r
+        //\r
+        AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+        MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);\r
+        UpdateOptionSkipLines (MenuOption);\r
 \r
-  //\r
-  // FormRefreshEvent != NULL means this form will auto exit at an interval, display engine \r
-  // will try to keep highlight on the current position after this form exit and re-enter.\r
-  //\r
-  // HiiHandle + QuestionId can find the only one question in the system.\r
-  //\r
-  // If this question has question id, save the question id info to find the question.\r
-  // else save the opcode buffer to find it.\r
-  //\r
-  if (gFormData->FormRefreshEvent != NULL && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) {\r
-    if (gHighligthMenuInfo.QuestionId != 0) { \r
-      if (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode)) {\r
-        BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
+        *SkipValue = gHighligthMenuInfo.SkipValue;\r
+      } else {\r
         //\r
-        // SkipValue only used for menu at the top of the form.\r
-        // If Highlight menu is not at the top, this value will be update later.\r
+        // Not found last time top of screen menu, so base on current highlight menu\r
+        // to find the new top of screen menu.\r
+        // Make the current highlight menu at the bottom of the form to calculate the\r
+        // top of screen menu.\r
         //\r
-        TmpValue = gHighligthMenuInfo.SkipValue;\r
+        if (MenuOption->Skip >= BottomRow - TopRow) {\r
+          *TopOfScreen = *HighlightMenu;\r
+          TmpValue     = 0;\r
+        } else {\r
+          *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);\r
+        }\r
+\r
+        *SkipValue   = TmpValue;\r
+      }\r
+    } else {\r
+      //\r
+      // Last time highlight menu has disappear, find the first highlightable menu as the defalut one.\r
+      //\r
+      *HighlightMenu = gMenuOption.ForwardLink;\r
+      if (!IsListEmpty (&gMenuOption)) {\r
+        MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);\r
       }\r
-    } else if (gHighligthMenuInfo.OpCode != NULL){\r
-      if (!CompareMem (gHighligthMenuInfo.OpCode, SavedMenuOption->ThisTag->OpCode, gHighligthMenuInfo.OpCode->Length)) {\r
-        BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;\r
+      *TopOfScreen   = gMenuOption.ForwardLink;\r
+      *SkipValue = 0;\r
+    }\r
+\r
+    gMisMatch = FALSE;\r
+  } else if (FormData->HighLightedStatement != NULL) {\r
+    if (IsSavedHighlightStatement (FormData->HighLightedStatement)) {\r
+      //\r
+      // Input highlight menu is same as last time highlight menu.\r
+      // Base on last time highlight menu to set the top of screen menu and highlight menu.\r
+      //\r
+      *HighlightMenu = FindHighLightMenuOption(NULL);\r
+      ASSERT (*HighlightMenu != NULL);\r
+\r
+      //\r
+      // Update skip info for this highlight menu.\r
+      //\r
+      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
+      UpdateOptionSkipLines (MenuOption);\r
+      \r
+      *TopOfScreen = FindTopOfScreenMenuOption();\r
+      if (*TopOfScreen == NULL) {\r
         //\r
-        // SkipValue only used for menu at the top of the form.\r
-        // If Highlight menu is not at the top, this value will be update later.\r
+        // Not found last time top of screen menu, so base on current highlight menu\r
+        // to find the new top of screen menu.\r
+        // Make the current highlight menu at the bottom of the form to calculate the\r
+        // top of screen menu.\r
         //\r
-        TmpValue = gHighligthMenuInfo.SkipValue;\r
+        if (MenuOption->Skip >= BottomRow - TopRow) {\r
+          *TopOfScreen = *HighlightMenu;\r
+          TmpValue     = 0;\r
+        } else {\r
+          *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);\r
+        }\r
+\r
+        *SkipValue   = TmpValue;\r
+      } else {\r
+        AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+        MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);\r
+        UpdateOptionSkipLines (MenuOption);\r
+\r
+        *SkipValue = gHighligthMenuInfo.SkipValue;\r
       }\r
-    }\r
-  }\r
+      AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
+    } else {\r
+      //\r
+      // Input highlight menu is not save as last time highlight menu.\r
+      //\r
+      *HighlightMenu = FindHighLightMenuOption(FormData->HighLightedStatement);\r
+      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
+      UpdateOptionSkipLines (MenuOption);\r
 \r
-  if (SavedMenuOption->Skip >= BottomRow - TopRow) {\r
-    *TopOfScreen = NewPos;\r
+      //\r
+      // Make the current highlight menu at the bottom of the form to calculate the\r
+      // top of screen menu.\r
+      //\r
+      if (MenuOption->Skip >= BottomRow - TopRow) {\r
+        *TopOfScreen = *HighlightMenu;\r
+        TmpValue     = 0;\r
+      } else {\r
+        *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);\r
+      }\r
+\r
+      *SkipValue   = TmpValue;\r
+    }\r
+    AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
   } else {\r
-    *TopOfScreen = FindTopOfScreenMenu(NewPos, BottomRow - TopRow - SavedMenuOption->Skip, &TmpValue);\r
+    //\r
+    // If not has input highlight statement, just return the first one in this form.\r
+    //\r
+    *TopOfScreen   = gMenuOption.ForwardLink;\r
+    *HighlightMenu = gMenuOption.ForwardLink;\r
+    if (!IsListEmpty (&gMenuOption)) {\r
+      MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);\r
+    }\r
+    *SkipValue     = 0;\r
   }\r
-  AdjustDateAndTimePosition(TRUE, TopOfScreen);\r
 \r
-  *SkipValue   = TmpValue;\r
+  //\r
+  // First enter to show the menu, update highlight info.\r
+  //\r
+  UpdateHighlightMenuInfo (*HighlightMenu, *TopOfScreen, *SkipValue);\r
 }\r
 \r
 /**\r
-  Update highlight menu info.\r
+  Record the highlight menu and top of screen menu info.\r
 \r
-  @param  MenuOption               The menu opton which is highlight.\r
-  @param  SkipValue                The skipvalue info for this menu.\r
-                                   SkipValue only used for the menu at the top of the form.\r
+  @param  Highlight               The menu opton which is highlight.\r
+  @param  TopOfScreen             The menu opton which is at the top of the form.\r
+  @param  SkipValue               The skip line info for the top of screen menu.\r
 \r
 **/\r
 VOID\r
 UpdateHighlightMenuInfo (\r
-  IN UI_MENU_OPTION            *MenuOption,\r
-  IN UINTN                     SkipValue\r
+  IN  LIST_ENTRY                      *Highlight,\r
+  IN  LIST_ENTRY                      *TopOfScreen,\r
+  IN  UINTN                           SkipValue\r
   )\r
 {\r
+  UI_MENU_OPTION                  *MenuOption;\r
   FORM_DISPLAY_ENGINE_STATEMENT   *Statement;\r
 \r
-  //\r
-  // This is the current selected statement\r
-  //\r
-  Statement = MenuOption->ThisTag;\r
+  gHighligthMenuInfo.HiiHandle  = gFormData->HiiHandle;\r
+  gHighligthMenuInfo.FormId     = gFormData->FormId;\r
+  gHighligthMenuInfo.SkipValue  = (UINT16)SkipValue;\r
 \r
-  //\r
-  // Get the highlight statement.\r
-  //\r
-  gUserInput->SelectedStatement = Statement;\r
-  gSequence = (UINT16) MenuOption->Sequence;\r
+  if (!IsListEmpty (&gMenuOption)) {\r
+    MenuOption = MENU_OPTION_FROM_LINK (Highlight);\r
+    Statement  = MenuOption->ThisTag;\r
 \r
-  //\r
-  // FormRefreshEvent != NULL means this form will auto exit at an interval, display engine \r
-  // will try to keep highlight on the current position after this form exit and re-enter.\r
-  //\r
-  // HiiHandle + QuestionId can find the only one question in the system.\r
-  //\r
-  // If this question has question id, base on the question id info to find the question.\r
-  // else base on the opcode buffer to find it.\r
-  //\r
-  if (gFormData->FormRefreshEvent != NULL) {\r
-    gHighligthMenuInfo.HiiHandle  = gFormData->HiiHandle;\r
-    gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);\r
+    gUserInput->SelectedStatement = Statement;\r
 \r
-    //\r
-    // if question id == 0, save the opcode buffer for later use.\r
-    //\r
-    if (gHighligthMenuInfo.QuestionId == 0) {\r
-      if (gHighligthMenuInfo.OpCode != NULL) {\r
-        FreePool (gHighligthMenuInfo.OpCode);\r
+    gHighligthMenuInfo.HLTSequence   = MenuOption->Sequence;\r
+    gHighligthMenuInfo.HLTQuestionId = GetQuestionIdInfo(Statement->OpCode);\r
+    if (gHighligthMenuInfo.HLTQuestionId == 0) {\r
+      //\r
+      // if question id == 0, save the opcode buffer..\r
+      //\r
+      if (gHighligthMenuInfo.HLTOpCode != NULL) {\r
+        FreePool (gHighligthMenuInfo.HLTOpCode);\r
       }\r
-      gHighligthMenuInfo.OpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);\r
-      ASSERT (gHighligthMenuInfo.OpCode != NULL);\r
+      gHighligthMenuInfo.HLTOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);\r
+      ASSERT (gHighligthMenuInfo.HLTOpCode != NULL);\r
+\r
+      gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode(Statement->OpCode);\r
+    }\r
+\r
+    MenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);\r
+    Statement  = MenuOption->ThisTag;\r
+\r
+    gHighligthMenuInfo.TOSQuestionId = GetQuestionIdInfo(Statement->OpCode);\r
+    if (gHighligthMenuInfo.TOSQuestionId == 0) {\r
+      //\r
+      // if question id == 0, save the opcode buffer..\r
+      //\r
+      if (gHighligthMenuInfo.TOSOpCode != NULL) {\r
+        FreePool (gHighligthMenuInfo.TOSOpCode);\r
+      }\r
+      gHighligthMenuInfo.TOSOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);\r
+      ASSERT (gHighligthMenuInfo.TOSOpCode != NULL);\r
+\r
+      gHighligthMenuInfo.TOSIndex = GetIndexInfoForOpcode(Statement->OpCode);\r
     }\r
-    gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;\r
-    gHighligthMenuInfo.SkipValue  = (UINT16) SkipValue;\r
   } else {\r
-    gHighligthMenuInfo.HiiHandle  = NULL;\r
-    gHighligthMenuInfo.QuestionId = 0;\r
-    if (gHighligthMenuInfo.OpCode != NULL) {\r
-      FreePool (gHighligthMenuInfo.OpCode);\r
-      gHighligthMenuInfo.OpCode = NULL;\r
+    gUserInput->SelectedStatement    = NULL;\r
+\r
+    gHighligthMenuInfo.HLTSequence   = 0;\r
+    gHighligthMenuInfo.HLTQuestionId = 0;\r
+    if (gHighligthMenuInfo.HLTOpCode != NULL) {\r
+      FreePool (gHighligthMenuInfo.HLTOpCode);\r
     }\r
-    gHighligthMenuInfo.DisplayRow = 0;\r
-    gHighligthMenuInfo.SkipValue  = 0;\r
-  }\r
+    gHighligthMenuInfo.HLTOpCode     = NULL;\r
+    gHighligthMenuInfo.HLTIndex      = 0;\r
 \r
-  RefreshKeyHelp(gFormData, Statement, FALSE);\r
+    gHighligthMenuInfo.TOSQuestionId = 0;\r
+    if (gHighligthMenuInfo.TOSOpCode != NULL) {\r
+      FreePool (gHighligthMenuInfo.TOSOpCode);\r
+    }\r
+    gHighligthMenuInfo.TOSOpCode     = NULL;\r
+    gHighligthMenuInfo.TOSIndex      = 0;\r
+  }\r
 }\r
 \r
 /**\r
@@ -1777,6 +2129,146 @@ HasOptionString (
   return TRUE;\r
 }\r
 \r
+/**\r
+  Double confirm with user about the action.\r
+\r
+  @param  Action               The user input action.\r
+\r
+  @retval TRUE                 User confirm with the input or not need user confirm.\r
+  @retval FALSE                User want ignore this input.\r
+\r
+**/\r
+BOOLEAN\r
+FxConfirmPopup (\r
+  IN UINT32   Action\r
+  )\r
+{\r
+  EFI_INPUT_KEY                   Key;\r
+  CHAR16                          *CfmStr;\r
+  UINTN                           CfmStrLen;\r
+  UINT32                          CheckFlags;\r
+  BOOLEAN                         RetVal;\r
+  UINTN                           CatLen;\r
+\r
+  CfmStrLen = 0;\r
+  CatLen    = StrLen (gConfirmMsgConnect);\r
+\r
+  //\r
+  // Below action need extra popup dialog to confirm.\r
+  // \r
+  CheckFlags = BROWSER_ACTION_DISCARD | \r
+               BROWSER_ACTION_DEFAULT |\r
+               BROWSER_ACTION_SUBMIT |\r
+               BROWSER_ACTION_RESET |\r
+               BROWSER_ACTION_EXIT;\r
+\r
+  //\r
+  // Not need to confirm with user, just return TRUE.\r
+  //\r
+  if ((Action & CheckFlags) == 0) {\r
+    return TRUE;\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
+    CfmStrLen += StrLen (gConfirmDiscardMsg);\r
+  } \r
+\r
+  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+    if (CfmStrLen != 0) {\r
+      CfmStrLen += CatLen;\r
+    } \r
+\r
+    CfmStrLen += StrLen (gConfirmDefaultMsg);\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_SUBMIT)  == BROWSER_ACTION_SUBMIT) {\r
+    if (CfmStrLen != 0) {\r
+      CfmStrLen += CatLen;\r
+    } \r
+\r
+    CfmStrLen += StrLen (gConfirmSubmitMsg);\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_RESET)  == BROWSER_ACTION_RESET) {\r
+    if (CfmStrLen != 0) {\r
+      CfmStrLen += CatLen;\r
+    } \r
+\r
+    CfmStrLen += StrLen (gConfirmResetMsg);\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_EXIT)  == BROWSER_ACTION_EXIT) {\r
+    if (CfmStrLen != 0) {\r
+      CfmStrLen += CatLen;\r
+    } \r
+\r
+    CfmStrLen += StrLen (gConfirmExitMsg);\r
+  }\r
+\r
+  //\r
+  // Allocate buffer to save the string.\r
+  // String + "?" + "\0"\r
+  //\r
+  CfmStr = AllocateZeroPool ((CfmStrLen + 1 + 1) * sizeof (CHAR16));\r
+  ASSERT (CfmStr != NULL);\r
+\r
+  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
+    StrCpy (CfmStr, gConfirmDiscardMsg);\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+    if (CfmStr[0] != 0) {\r
+      StrCat (CfmStr, gConfirmMsgConnect);\r
+      StrCat (CfmStr, gConfirmDefaultMsg2nd);\r
+    } else {\r
+      StrCpy (CfmStr, gConfirmDefaultMsg);\r
+    }\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_SUBMIT)  == BROWSER_ACTION_SUBMIT) {\r
+    if (CfmStr[0] != 0) {\r
+      StrCat (CfmStr, gConfirmMsgConnect);\r
+      StrCat (CfmStr, gConfirmSubmitMsg2nd);\r
+    } else {\r
+      StrCpy (CfmStr, gConfirmSubmitMsg);\r
+    }\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_RESET)  == BROWSER_ACTION_RESET) {\r
+    if (CfmStr[0] != 0) {\r
+      StrCat (CfmStr, gConfirmMsgConnect);\r
+      StrCat (CfmStr, gConfirmResetMsg2nd);\r
+    } else {\r
+      StrCpy (CfmStr, gConfirmResetMsg);\r
+    }\r
+  }\r
+\r
+  if ((Action & BROWSER_ACTION_EXIT)  == BROWSER_ACTION_EXIT) {\r
+    if (CfmStr[0] != 0) {\r
+      StrCat (CfmStr, gConfirmMsgConnect);\r
+      StrCat (CfmStr, gConfirmExitMsg2nd);\r
+    } else {\r
+      StrCpy (CfmStr, gConfirmExitMsg);\r
+    }\r
+  }\r
+\r
+  StrCat (CfmStr, gConfirmMsgEnd);\r
+\r
+  do {\r
+    CreateDialog (&Key, gEmptyString, CfmStr, gConfirmOpt, gEmptyString, NULL);\r
+  } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) &&\r
+           ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptNo[0] | UPPER_LOWER_CASE_OFFSET)));\r
+\r
+  if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) {\r
+    RetVal = TRUE;\r
+  } else {\r
+    RetVal = FALSE;\r
+  }\r
+\r
+  FreePool (CfmStr);\r
+\r
+  return RetVal;\r
+}\r
 \r
 /**\r
   Print string for this menu option.\r
@@ -1816,6 +2308,7 @@ DisplayOneMenu (
   UINTN                           Temp3;\r
   EFI_STATUS                      Status;\r
   UINTN                           Row;\r
+  BOOLEAN                         IsProcessingFirstRow;\r
   UINTN                           Col;\r
   UINTN                           PromptLineNum;\r
   UINTN                           OptionLineNum;\r
@@ -1830,6 +2323,7 @@ DisplayOneMenu (
   PromptLineNum = 0;\r
   OptionLineNum = 0;\r
   MaxRow        = 0;\r
+  IsProcessingFirstRow = TRUE;\r
 \r
   //\r
   // Set default color.\r
@@ -1933,7 +2427,7 @@ DisplayOneMenu (
         //\r
         PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth);\r
         \r
-        if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) {\r
+        if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2 && IsProcessingFirstRow) {\r
           //\r
           // Print Arrow for Goto button.\r
           //\r
@@ -1942,6 +2436,7 @@ DisplayOneMenu (
             Row,\r
             GEOMETRICSHAPE_RIGHT_TRIANGLE\r
             );\r
+          IsProcessingFirstRow = FALSE;\r
         }\r
         DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight);\r
         PromptLineNum ++;\r
@@ -2049,10 +2544,8 @@ UiDisplayMenu (
   UINTN                           TopRow;\r
   UINTN                           BottomRow;\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
@@ -2069,10 +2562,8 @@ UiDisplayMenu (
   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
   BROWSER_HOT_KEY                 *HotKey;\r
   UINTN                           HelpPageIndex;\r
@@ -2087,7 +2578,6 @@ UiDisplayMenu (
   UINT16                          BottomLineWidth;\r
   EFI_STRING_ID                   HelpInfo;\r
   UI_EVENT_TYPE                   EventType;\r
-  FORM_DISPLAY_ENGINE_STATEMENT   *InitialHighlight;\r
   BOOLEAN                         SkipHighLight;\r
 \r
   EventType           = UIEventNone;\r
@@ -2098,7 +2588,6 @@ UiDisplayMenu (
   OptionString        = NULL;\r
   ScreenOperation     = UiNoOperation;\r
   NewLine             = TRUE;\r
-  DefaultId           = 0;\r
   HelpPageCount       = 0;\r
   HelpLine            = 0;\r
   RowCount            = 0;\r
@@ -2109,24 +2598,20 @@ UiDisplayMenu (
   EachLineWidth       = 0;\r
   HeaderLineWidth     = 0;\r
   BottomLineWidth     = 0;\r
-  OutputString        = NULL;\r
   UpArrow             = FALSE;\r
   DownArrow           = FALSE;\r
   SkipValue           = 0;\r
   SkipHighLight       = FALSE;\r
 \r
   NextMenuOption      = NULL;\r
-  PreviousMenuOption  = NULL;\r
   SavedMenuOption     = NULL;\r
   HotKey              = NULL;\r
   Repaint             = TRUE;\r
   MenuOption          = NULL;\r
   gModalSkipColumn    = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;\r
-  InitialHighlight    = gFormData->HighLightedStatement;\r
 \r
   ZeroMem (&Key, sizeof (EFI_INPUT_KEY));\r
 \r
-  Width     = (UINT16)gOptionBlockWidth - 1;\r
   TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;\r
   BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;\r
 \r
@@ -2138,6 +2623,10 @@ UiDisplayMenu (
   }\r
 \r
   FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);\r
+  if (!IsListEmpty (&gMenuOption)) {\r
+    NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
+    gUserInput->SelectedStatement = NextMenuOption->ThisTag;\r
+  }\r
 \r
   gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
 \r
@@ -2243,7 +2732,11 @@ UiDisplayMenu (
           }\r
 \r
           if (EFI_ERROR (Status)) {\r
-            return Status;\r
+            if (gMisMatch) {\r
+              return EFI_SUCCESS;\r
+            } else {\r
+              return Status;\r
+            }\r
           }\r
           //\r
           // 3. Update the row info which will be used by next menu.\r
@@ -2306,10 +2799,12 @@ UiDisplayMenu (
       //\r
       ControlFlag = CfUpdateHelpString;\r
 \r
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
+\r
       if (SkipHighLight) {\r
-        MenuOption    = SavedMenuOption;\r
         SkipHighLight = FALSE;\r
-        UpdateHighlightMenuInfo (MenuOption, TopOfScreen == &MenuOption->Link ? SkipValue : 0);\r
+        MenuOption    = SavedMenuOption;\r
+        RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE);\r
         break;\r
       }\r
 \r
@@ -2351,9 +2846,7 @@ UiDisplayMenu (
         // This is the current selected statement\r
         //\r
         MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
-        Statement = MenuOption->ThisTag;\r
-\r
-        UpdateHighlightMenuInfo (MenuOption, Temp2);\r
+        RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);\r
 \r
         if (!IsSelectable (MenuOption)) {\r
           break;\r
@@ -2588,6 +3081,7 @@ UiDisplayMenu (
       }\r
 \r
       if (EventType == UIEventDriver) {\r
+        gMisMatch = TRUE;\r
         gUserInput->Action = BROWSER_ACTION_NONE;\r
         ControlFlag = CfExit;\r
         break;\r
@@ -2795,13 +3289,6 @@ UiDisplayMenu (
         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
@@ -2810,8 +3297,19 @@ UiDisplayMenu (
       ControlFlag = CfRepaint;\r
 \r
       ASSERT (HotKey != NULL);\r
-      gUserInput->Action = HotKey->Action;\r
-      ControlFlag = CfExit;\r
+\r
+      if (FxConfirmPopup(HotKey->Action)) {\r
+        gUserInput->Action = HotKey->Action;\r
+        if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+          gUserInput->DefaultId = HotKey->DefaultId;\r
+        }\r
+        ControlFlag = CfExit;\r
+      } else {\r
+        Repaint     = TRUE;\r
+        NewLine     = TRUE;\r
+        ControlFlag = CfRepaint;\r
+      }\r
+\r
       break;\r
 \r
     case CfUiLeft:\r
@@ -2914,6 +3412,8 @@ UiDisplayMenu (
       //\r
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
       AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
       break;\r
 \r
     case CfUiPageUp:\r
@@ -2953,6 +3453,8 @@ UiDisplayMenu (
       //\r
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
       AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
       break;\r
 \r
     case CfUiPageDown:\r
@@ -3014,6 +3516,8 @@ UiDisplayMenu (
       //\r
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
       AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
       break;\r
 \r
     case CfUiDown:\r
@@ -3075,6 +3579,8 @@ UiDisplayMenu (
         //\r
         AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
         AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+        UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
         break;\r
       }        \r
 \r
@@ -3172,6 +3678,8 @@ UiDisplayMenu (
       //\r
       AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
       AdjustDateAndTimePosition (TRUE, &NewPos);\r
+\r
+      UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);\r
       break;\r
 \r
     case CfUiNoOperation:\r
@@ -3280,8 +3788,20 @@ BrowserStatusProcess (
       ErrorInfo = gNoSubmitIfFailed;\r
       break;\r
 \r
+    case BROWSER_RECONNECT_FAIL:\r
+      ErrorInfo = gReconnectFail;\r
+      break;\r
+\r
+    case BROWSER_RECONNECT_SAVE_CHANGES:\r
+      ErrorInfo = gReconnectConfirmChanges;\r
+      break;\r
+\r
+    case BROWSER_RECONNECT_REQUIRED:\r
+      ErrorInfo = gReconnectRequired;\r
+      break;\r
+\r
     default:\r
-      ErrorInfo = gBrwoserError;\r
+      ErrorInfo = gBrowserError;\r
       break;\r
     }\r
   }\r
@@ -3289,15 +3809,21 @@ BrowserStatusProcess (
   switch (gFormData->BrowserStatus) {\r
   case BROWSER_SUBMIT_FAIL:\r
   case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:\r
+  case BROWSER_RECONNECT_SAVE_CHANGES:\r
     ASSERT (gUserInput != NULL);\r
     if (gFormData->BrowserStatus == (BROWSER_SUBMIT_FAIL)) {\r
       PrintString = gSaveProcess;\r
       JumpToFormSet = gJumpToFormSet[0];\r
+      DiscardChange = gDiscardChange[0];\r
+    } else if (gFormData->BrowserStatus == (BROWSER_RECONNECT_SAVE_CHANGES)){\r
+      PrintString = gChangesOpt;\r
+      JumpToFormSet = gConfirmOptYes[0];\r
+      DiscardChange = gConfirmOptNo[0];\r
     } else {\r
       PrintString = gSaveNoSubmitProcess;\r
       JumpToFormSet = gCheckError[0];\r
+      DiscardChange = gDiscardChange[0];\r
     }\r
-    DiscardChange = gDiscardChange[0];\r
 \r
     do {\r
       CreateDialog (&Key, gEmptyString, ErrorInfo, PrintString, gEmptyString, NULL);\r
@@ -3581,8 +4107,12 @@ UnloadDisplayEngine (
 \r
   FreeDisplayStrings ();\r
 \r
-  if (gHighligthMenuInfo.OpCode != NULL) {\r
-    FreePool (gHighligthMenuInfo.OpCode);\r
+  if (gHighligthMenuInfo.HLTOpCode != NULL) {\r
+    FreePool (gHighligthMenuInfo.HLTOpCode);\r
+  }\r
+\r
+  if (gHighligthMenuInfo.TOSOpCode != NULL) {\r
+    FreePool (gHighligthMenuInfo.TOSOpCode);\r
   }\r
 \r
   return EFI_SUCCESS;\r