]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
MdeModulePkg/Ip4Dxe: Clean up IP4 interface if failed to open ARP protocol.
[mirror_edk2.git] / MdeModulePkg / Universal / DisplayEngineDxe / FormDisplay.c
index b9090d370265474a844c0c3b3a50fd61a2a859cd..d2867d2921ccbf861b1002af6661a9f771ce1605 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Entry and initialization module for the browser.\r
 \r
-Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, 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
@@ -49,7 +49,7 @@ SCAN_CODE_TO_SCREEN_OPERATION     gScanCodeToOperation[] = {
   }\r
 };\r
 \r
-UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);\r
+UINTN mScanCodeNumber = ARRAY_SIZE (gScanCodeToOperation);\r
 \r
 SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {\r
   {\r
@@ -113,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
@@ -147,8 +151,18 @@ CHAR16            *gConfirmExitMsg2nd;
 CHAR16            *gConfirmOpt;\r
 CHAR16            *gConfirmOptYes;\r
 CHAR16            *gConfirmOptNo;\r
+CHAR16            *gConfirmOptOk;\r
+CHAR16            *gConfirmOptCancel;\r
+CHAR16            *gYesOption;\r
+CHAR16            *gNoOption;\r
+CHAR16            *gOkOption;\r
+CHAR16            *gCancelOption;\r
+CHAR16            *gErrorPopup;\r
+CHAR16            *gWarningPopup;\r
+CHAR16            *gInfoPopup;\r
 CHAR16            *gConfirmMsgConnect;\r
 CHAR16            *gConfirmMsgEnd;\r
+CHAR16            *gPasswordUnsupported;\r
 CHAR16            gModalSkipColumn;\r
 CHAR16            gPromptBlockWidth;\r
 CHAR16            gOptionBlockWidth;\r
@@ -162,6 +176,10 @@ FORM_DISPLAY_DRIVER_PRIVATE_DATA  mPrivateData = {
     FormDisplay,\r
     DriverClearDisplayPage,\r
     ConfirmDataChange\r
+  },\r
+  {\r
+    EFI_HII_POPUP_PROTOCOL_REVISION,\r
+    CreatePopup\r
   }\r
 };\r
 \r
@@ -203,9 +221,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
@@ -225,7 +247,7 @@ 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
@@ -238,8 +260,18 @@ InitializeDisplayStrings (
   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
+  gConfirmOptOk         = GetToken (STRING_TOKEN (CONFIRM_OPTION_OK), gHiiHandle);\r
+  gConfirmOptCancel     = GetToken (STRING_TOKEN (CONFIRM_OPTION_CANCEL), gHiiHandle);\r
+  gYesOption            = GetToken (STRING_TOKEN (YES_SELECTABLE_OPTION), gHiiHandle);\r
+  gNoOption             = GetToken (STRING_TOKEN (NO_SELECTABLE_OPTION), gHiiHandle);\r
+  gOkOption             = GetToken (STRING_TOKEN (OK_SELECTABLE_OPTION), gHiiHandle);\r
+  gCancelOption         = GetToken (STRING_TOKEN (CANCEL_SELECTABLE_OPTION), gHiiHandle);\r
+  gErrorPopup           = GetToken (STRING_TOKEN (ERROR_POPUP_STRING), gHiiHandle);\r
+  gWarningPopup         = GetToken (STRING_TOKEN (WARNING_POPUP_STRING), gHiiHandle);\r
+  gInfoPopup            = GetToken (STRING_TOKEN (INFO_POPUP_STRING), gHiiHandle);\r
   gConfirmMsgConnect    = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);\r
   gConfirmMsgEnd        = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);\r
+  gPasswordUnsupported  = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED ), gHiiHandle);\r
 }\r
 \r
 /**\r
@@ -256,6 +288,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
@@ -272,7 +308,7 @@ 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
@@ -287,8 +323,18 @@ FreeDisplayStrings (
   FreePool (gConfirmOpt);\r
   FreePool (gConfirmOptYes);\r
   FreePool (gConfirmOptNo);\r
+  FreePool (gConfirmOptOk);\r
+  FreePool (gConfirmOptCancel);\r
+  FreePool (gYesOption);\r
+  FreePool (gNoOption);\r
+  FreePool (gOkOption);\r
+  FreePool (gCancelOption);\r
+  FreePool (gErrorPopup);\r
+  FreePool (gWarningPopup);\r
+  FreePool (gInfoPopup);\r
   FreePool (gConfirmMsgConnect);\r
   FreePool (gConfirmMsgEnd);\r
+  FreePool (gPasswordUnsupported);\r
 }\r
 \r
 /**\r
@@ -525,7 +571,7 @@ GetLineByWidth (
   //\r
   // Need extra glyph info and '\0' info, so +2.\r
   //\r
-  *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));\r
+  *OutputString = AllocateZeroPool ((StrOffset + 2) * sizeof(CHAR16));\r
   if (*OutputString == NULL) {\r
     return 0;\r
   }\r
@@ -592,7 +638,6 @@ UiAddMenuOption (
   UI_MENU_OPTION   *MenuOption;\r
   UINTN            Index;\r
   UINTN            Count;\r
-  CHAR16           *String;\r
   UINT16           NumberOfLines;\r
   UINT16           GlyphWidth;\r
   UINT16           Width;\r
@@ -609,9 +654,6 @@ UiAddMenuOption (
   PromptId = GetPrompt (Statement->OpCode);\r
   ASSERT (PromptId != 0);\r
 \r
-  String = GetToken (PromptId, gFormData->HiiHandle);\r
-  ASSERT (String != NULL);\r
-\r
   if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
     Count = 3;\r
   }\r
@@ -621,7 +663,7 @@ UiAddMenuOption (
     ASSERT (MenuOption);\r
 \r
     MenuOption->Signature   = UI_MENU_OPTION_SIGNATURE;\r
-    MenuOption->Description = String;\r
+    MenuOption->Description = GetToken (PromptId, gFormData->HiiHandle);\r
     MenuOption->Handle      = gFormData->HiiHandle;\r
     MenuOption->ThisTag     = Statement;\r
     MenuOption->NestInStatement = NestIn;\r
@@ -685,11 +727,11 @@ UiAddMenuOption (
       (Statement->OpCode->OpCode != EFI_IFR_DATE_OP) && \r
       (Statement->OpCode->OpCode != EFI_IFR_TIME_OP)) {\r
       Width  = GetWidth (MenuOption, NULL);\r
-      for (; GetLineByWidth (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {\r
+      for (; GetLineByWidth (MenuOption->Description, 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
+        if (StrLen (&MenuOption->Description[ArrayEntry]) != 0) {\r
           NumberOfLines++;\r
         }\r
         FreePool (OutputString);\r
@@ -866,7 +908,7 @@ UpdateSkipInfoForMenu (
   CHAR16  *OutputString;\r
   UINT16  GlyphWidth;\r
 \r
-  Width         = (UINT16) gOptionBlockWidth;\r
+  Width         = (UINT16) gOptionBlockWidth - 1;\r
   GlyphWidth    = 1;\r
   Row           = 1;\r
 \r
@@ -1042,12 +1084,8 @@ MoveToNextStatement (
       UpdateOptionSkipLines (NextMenuOption);\r
     }\r
 \r
-    if (IsSelectable (NextMenuOption)) {\r
-      break;\r
-    }\r
-\r
     //\r
-    // In this case, still can't find the selectable menu,\r
+    // Check whether the menu is beyond current showing form,\r
     // return the first one beyond the showing form.\r
     //\r
     if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {\r
@@ -1057,6 +1095,13 @@ MoveToNextStatement (
       break;\r
     }\r
 \r
+    //\r
+    // return the selectable menu in the showing form.\r
+    //\r
+    if (IsSelectable (NextMenuOption)) {\r
+      break;\r
+    }\r
+\r
     Distance += NextMenuOption->Skip;\r
 \r
     //\r
@@ -1704,23 +1749,56 @@ IsTopOfScreeMenuOption (
 }\r
 \r
 /**\r
-  Find the Top of screen menu.\r
+  Calculate the distance between two menus and include the skip value of StartMenu.\r
 \r
-  If the input is NULL, base on the record highlight info in\r
-  gHighligthMenuInfo to find the last highlight menu.\r
+  @param  StartMenu             The link_entry pointer to start menu.\r
+  @param  EndMenu               The link_entry pointer to end menu.\r
 \r
-  @param  HighLightedStatement      The input highlight statement.\r
+**/\r
+UINTN\r
+GetDistanceBetweenMenus(\r
+  IN LIST_ENTRY  *StartMenu,\r
+  IN LIST_ENTRY  *EndMenu\r
+)\r
+{\r
+  LIST_ENTRY                 *Link;\r
+  UI_MENU_OPTION             *MenuOption;\r
+  UINTN                      Distance;\r
 \r
-  @retval  The highlight menu index.\r
+  Distance = 0;\r
+\r
+  Link = StartMenu;\r
+  while (Link != EndMenu) {\r
+    MenuOption = MENU_OPTION_FROM_LINK (Link);\r
+    if (MenuOption->Row == 0) {\r
+      UpdateOptionSkipLines (MenuOption);\r
+    }\r
+    Distance += MenuOption->Skip;\r
+    Link = Link->BackLink;\r
+  }\r
+  return Distance;\r
+}\r
+\r
+/**\r
+  Find the top of screen menu base on the previous record menu info.\r
+\r
+  @param  HighLightMenu      The link_entry pointer to highlight menu.\r
+\r
+  @retval  Return the the link_entry pointer top of screen menu.\r
 \r
 **/\r
 LIST_ENTRY *\r
 FindTopOfScreenMenuOption (\r
- VOID\r
- )\r
+  IN LIST_ENTRY                   *HighLightMenu\r
 )\r
 {\r
   LIST_ENTRY                      *NewPos;\r
   UI_MENU_OPTION                  *MenuOption;\r
+  UINTN                           TopRow;\r
+  UINTN                           BottomRow;\r
+\r
+  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;\r
+  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
 \r
   NewPos = gMenuOption.ForwardLink;\r
   MenuOption = MENU_OPTION_FROM_LINK (NewPos);\r
@@ -1740,7 +1818,16 @@ FindTopOfScreenMenuOption (
   // Last time top of screen menu has disappeared.\r
   //\r
   if (NewPos == &gMenuOption) {\r
-    NewPos = NULL;\r
+    return NULL;\r
+  }\r
+  //\r
+  // Check whether highlight menu and top of screen menu can be shown within one page,\r
+  // if can't, return NULL to re-calcaulate the top of scrren menu. Because some new menus\r
+  // may be dynamically inserted between highlightmenu and previous top of screen menu,\r
+  // So previous record top of screen menu is not appropriate for current display.\r
+  //\r
+  if (GetDistanceBetweenMenus (HighLightMenu, NewPos) + 1 > BottomRow - TopRow) {\r
+    return NULL;\r
   }\r
 \r
   return NewPos;\r
@@ -1770,14 +1857,15 @@ FindTopMenu (
 \r
   TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;\r
   BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;\r
-\r
-  if (gMisMatch) {\r
+  //\r
+  // When option mismatch happens,there exist two cases,one is reenter the form, just like the if case below,\r
+  // and the other is exit current form and enter last form, it can be covered by the else case.\r
+  //\r
+  if (gMisMatch && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle && gFormData->FormId == gHighligthMenuInfo.FormId) {\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
     *HighlightMenu = FindHighLightMenuOption(NULL);\r
     if (*HighlightMenu != NULL) {\r
@@ -1790,7 +1878,7 @@ FindTopMenu (
       //\r
       // Found the last time highlight menu.\r
       //\r
-      *TopOfScreen = FindTopOfScreenMenuOption();\r
+      *TopOfScreen = FindTopOfScreenMenuOption(*HighlightMenu);\r
       if (*TopOfScreen != NULL) {\r
         //\r
         // Found the last time selectable top of screen menu.\r
@@ -1818,7 +1906,7 @@ FindTopMenu (
       }\r
     } else {\r
       //\r
-      // Last time highlight menu has disappear, find the first highlightable menu as the defalut one.\r
+      // Last time highlight menu has disappear, find the first highlightable menu as the default one.\r
       //\r
       *HighlightMenu = gMenuOption.ForwardLink;\r
       if (!IsListEmpty (&gMenuOption)) {\r
@@ -1828,7 +1916,6 @@ FindTopMenu (
       *SkipValue = 0;\r
     }\r
 \r
-    gMisMatch = FALSE;\r
   } else if (FormData->HighLightedStatement != NULL) {\r
     if (IsSavedHighlightStatement (FormData->HighLightedStatement)) {\r
       //\r
@@ -1844,7 +1931,7 @@ FindTopMenu (
       MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);\r
       UpdateOptionSkipLines (MenuOption);\r
       \r
-      *TopOfScreen = FindTopOfScreenMenuOption();\r
+      *TopOfScreen = FindTopOfScreenMenuOption(*HighlightMenu);\r
       if (*TopOfScreen == NULL) {\r
         //\r
         // Not found last time top of screen menu, so base on current highlight menu\r
@@ -1901,6 +1988,13 @@ FindTopMenu (
     }\r
     *SkipValue     = 0;\r
   }\r
+\r
+  gMisMatch = FALSE;\r
+\r
+  //\r
+  // First enter to show the menu, update highlight info.\r
+  //\r
+  UpdateHighlightMenuInfo (*HighlightMenu, *TopOfScreen, *SkipValue);\r
 }\r
 \r
 /**\r
@@ -2132,6 +2226,7 @@ FxConfirmPopup (
   UINT32                          CheckFlags;\r
   BOOLEAN                         RetVal;\r
   UINTN                           CatLen;\r
+  UINTN                           MaxLen;\r
 \r
   CfmStrLen = 0;\r
   CatLen    = StrLen (gConfirmMsgConnect);\r
@@ -2192,55 +2287,57 @@ FxConfirmPopup (
   // Allocate buffer to save the string.\r
   // String + "?" + "\0"\r
   //\r
-  CfmStr = AllocateZeroPool ((CfmStrLen + 1 + 1) * sizeof (CHAR16));\r
+  MaxLen = CfmStrLen + 1 + 1;\r
+  CfmStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
   ASSERT (CfmStr != NULL);\r
 \r
   if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
-    StrCpy (CfmStr, gConfirmDiscardMsg);\r
+    StrCpyS (CfmStr, MaxLen, 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
+      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+      StrCatS (CfmStr, MaxLen, gConfirmDefaultMsg2nd);\r
     } else {\r
-      StrCpy (CfmStr, gConfirmDefaultMsg);\r
+      StrCpyS (CfmStr, MaxLen, 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
+      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+      StrCatS (CfmStr, MaxLen, gConfirmSubmitMsg2nd);\r
     } else {\r
-      StrCpy (CfmStr, gConfirmSubmitMsg);\r
+      StrCpyS (CfmStr, MaxLen, 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
+      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+      StrCatS (CfmStr, MaxLen, gConfirmResetMsg2nd);\r
     } else {\r
-      StrCpy (CfmStr, gConfirmResetMsg);\r
+      StrCpyS (CfmStr, MaxLen, 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
+      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);\r
+      StrCatS (CfmStr, MaxLen, gConfirmExitMsg2nd);\r
     } else {\r
-      StrCpy (CfmStr, gConfirmExitMsg);\r
+      StrCpyS (CfmStr, MaxLen, gConfirmExitMsg);\r
     }\r
   }\r
 \r
-  StrCat (CfmStr, gConfirmMsgEnd);\r
+  StrCatS (CfmStr, MaxLen, 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
+           ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptNo[0] | UPPER_LOWER_CASE_OFFSET)) &&\r
+           (Key.ScanCode != SCAN_ESC));\r
 \r
   if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) {\r
     RetVal = TRUE;\r
@@ -2291,6 +2388,7 @@ DisplayOneMenu (
   UINTN                           Temp3;\r
   EFI_STATUS                      Status;\r
   UINTN                           Row;\r
+  BOOLEAN                         IsProcessingFirstRow;\r
   UINTN                           Col;\r
   UINTN                           PromptLineNum;\r
   UINTN                           OptionLineNum;\r
@@ -2305,6 +2403,7 @@ DisplayOneMenu (
   PromptLineNum = 0;\r
   OptionLineNum = 0;\r
   MaxRow        = 0;\r
+  IsProcessingFirstRow = TRUE;\r
 \r
   //\r
   // Set default color.\r
@@ -2408,7 +2507,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
@@ -2417,6 +2516,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
@@ -2525,6 +2625,8 @@ UiDisplayMenu (
   UINTN                           BottomRow;\r
   UINTN                           Index;\r
   CHAR16                          *StringPtr;\r
+  CHAR16                          *StringRightPtr;\r
+  CHAR16                          *StringErrorPtr;\r
   CHAR16                          *OptionString;\r
   CHAR16                          *HelpString;\r
   CHAR16                          *HelpHeaderString;\r
@@ -2559,6 +2661,7 @@ UiDisplayMenu (
   EFI_STRING_ID                   HelpInfo;\r
   UI_EVENT_TYPE                   EventType;\r
   BOOLEAN                         SkipHighLight;\r
+  EFI_HII_VALUE                   *StatementValue;\r
 \r
   EventType           = UIEventNone;\r
   Status              = EFI_SUCCESS;\r
@@ -2865,10 +2968,26 @@ UiDisplayMenu (
           //\r
           ASSERT(MenuOption != NULL);\r
           HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;\r
+          Statement = MenuOption->ThisTag;\r
+          StatementValue = &Statement->CurrentValue;\r
           if (HelpInfo == 0 || !IsSelectable (MenuOption)) {\r
-            StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
+            if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){\r
+              StringPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);\r
+            } else {\r
+              StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
+            }\r
           } else {\r
-            StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
+            if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){\r
+              StringRightPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
+              StringErrorPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);\r
+              StringPtr = AllocateZeroPool ((StrLen (StringRightPtr) + StrLen (StringErrorPtr)+ 1 ) * sizeof (CHAR16));\r
+              StrCpyS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringRightPtr);\r
+              StrCatS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringErrorPtr);\r
+              FreePool (StringRightPtr);\r
+              FreePool (StringErrorPtr);\r
+            } else {\r
+              StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);\r
+            }\r
           }\r
         }\r
 \r
@@ -2905,7 +3024,7 @@ UiDisplayMenu (
           //\r
           if (HelpLine > 2 * RowCount - 2) {\r
             HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;\r
-            if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {\r
+            if ((HelpLine - RowCount + 1) % (RowCount - 2) != 0) {\r
               HelpPageCount += 1;\r
             }\r
           } else {\r
@@ -2926,7 +3045,7 @@ UiDisplayMenu (
         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
+          ASSERT (GetStringWidth (HelpHeaderString) / 2 < ((UINT32) gHelpBlockWidth - 1));\r
           PrintStringAtWithWidth (\r
             gStatementDimensions.RightColumn - gHelpBlockWidth,\r
             Index + TopRow,\r
@@ -3007,7 +3126,7 @@ UiDisplayMenu (
         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
+          ASSERT (GetStringWidth (HelpBottomString) / 2 < ((UINT32) gHelpBlockWidth - 1));\r
           PrintStringAtWithWidth (\r
             gStatementDimensions.RightColumn - gHelpBlockWidth,\r
             BottomRow + Index - HelpBottomLine + 1,\r
@@ -3208,7 +3327,7 @@ UiDisplayMenu (
       }\r
 \r
       for (Index = 0;\r
-           Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);\r
+           Index < ARRAY_SIZE (gScreenOperationToControlFlag);\r
            Index++\r
           ) {\r
         if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {\r
@@ -3280,6 +3399,9 @@ UiDisplayMenu (
 \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
@@ -3682,6 +3804,34 @@ UiDisplayMenu (
   }\r
 }\r
 \r
+/**\r
+  Free the UI Menu Option structure data.\r
+\r
+  @param   MenuOptionList         Point to the menu option list which need to be free.\r
+\r
+**/\r
+VOID\r
+FreeMenuOptionData(\r
+  LIST_ENTRY           *MenuOptionList\r
+  )\r
+{\r
+  LIST_ENTRY           *Link;\r
+  UI_MENU_OPTION       *Option;\r
+\r
+  //\r
+  // Free menu option list\r
+  //\r
+  while (!IsListEmpty (MenuOptionList)) {\r
+    Link = GetFirstNode (MenuOptionList);\r
+    Option = MENU_OPTION_FROM_LINK (Link);\r
+    if (Option->Description != NULL){\r
+      FreePool(Option->Description);\r
+    }\r
+    RemoveEntryList (&Option->Link);\r
+    FreePool (Option);\r
+  }\r
+}\r
+\r
 /**\r
 \r
   Base on the browser status info to show an pop up message.\r
@@ -3765,8 +3915,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
@@ -3774,15 +3936,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
@@ -3936,6 +4104,11 @@ FormDisplay (
   CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);\r
   gOldFormEntry.FormId    = FormData->FormId;\r
 \r
+  //\r
+  //Free the Ui menu option list.\r
+  //\r
+  FreeMenuOptionData(&gMenuOption);\r
+\r
   return Status;\r
 }\r
 \r
@@ -4019,6 +4192,17 @@ InitializeDisplayEngine (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Install HII Popup Protocol.\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                 &mPrivateData.Handle,\r
+                 &gEfiHiiPopupProtocolGuid,\r
+                 EFI_NATIVE_INTERFACE,\r
+                 &mPrivateData.HiiPopup\r
+                );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   InitializeDisplayStrings();\r
   \r
   ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));\r