]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
HII Library Class interface refine.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Ui.c
index a66e94647503d9abae3e2b00c677d4eefbba163e..4d2fc8871aaf7dd3f6831cea115ebac5971889bd 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Utility functions for User Interface functions.\r
 \r
-Copyright (c) 2004 - 2007, Intel Corporation\r
+Copyright (c) 2004 - 2008, Intel Corporation\r
 All rights reserved. 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
@@ -116,6 +116,9 @@ SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {
   }\r
 };\r
 \r
+BOOLEAN  mInputError;\r
+BOOLEAN GetLineByWidthFinished = FALSE;\r
+\r
 \r
 /**\r
   Set Buffer to Value for Size bytes.\r
@@ -124,6 +127,8 @@ SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {
   @param  Size                   Number of bytes to set\r
   @param  Value                  Value of the set operation.\r
 \r
+  @return Value.\r
+\r
 **/\r
 VOID\r
 SetUnicodeMem (\r
@@ -186,7 +191,7 @@ UiRemoveMenuListEntry (
     Selection->FormId = UiMenuList->FormId;\r
     Selection->QuestionId = UiMenuList->QuestionId;\r
     RemoveEntryList (&UiMenuList->MenuLink);\r
-    gBS->FreePool (UiMenuList);\r
+    FreePool (UiMenuList);\r
   }\r
 }\r
 \r
@@ -205,7 +210,7 @@ UiFreeMenuList (
   while (!IsListEmpty (&gMenuList)) {\r
     UiMenuList = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);\r
     RemoveEntryList (&UiMenuList->MenuLink);\r
-    gBS->FreePool (UiMenuList);\r
+    FreePool (UiMenuList);\r
   }\r
 }\r
 \r
@@ -258,9 +263,9 @@ UiFreeMenu (
       // Data format :      [01/02/2004]      [11:22:33]\r
       // Line number :        0  0    1         0  0  1\r
       //\r
-      gBS->FreePool (MenuOption->Description);\r
+      FreePool (MenuOption->Description);\r
     }\r
-    gBS->FreePool (MenuOption);\r
+    FreePool (MenuOption);\r
   }\r
 }\r
 \r
@@ -278,7 +283,7 @@ UiFreeRefreshList (
 \r
   while (gMenuRefreshHead != NULL) {\r
     OldMenuRefreshEntry = gMenuRefreshHead->Next;\r
-    gBS->FreePool (gMenuRefreshHead);\r
+    FreePool (gMenuRefreshHead);\r
     gMenuRefreshHead = OldMenuRefreshEntry;\r
   }\r
 \r
@@ -291,66 +296,122 @@ UiFreeRefreshList (
   Refresh screen.\r
 \r
 **/\r
-VOID\r
+EFI_STATUS\r
 RefreshForm (\r
   VOID\r
   )\r
 {\r
-  CHAR16                  *OptionString;\r
-  MENU_REFRESH_ENTRY      *MenuRefreshEntry;\r
-  UINTN                   Index;\r
-  UINTN                   Loop;\r
-  EFI_STATUS              Status;\r
-  UI_MENU_SELECTION       *Selection;\r
-  FORM_BROWSER_STATEMENT  *Question;\r
-\r
-  OptionString = NULL;\r
+  CHAR16                          *OptionString;\r
+  MENU_REFRESH_ENTRY              *MenuRefreshEntry;\r
+  UINTN                           Index;\r
+  EFI_STATUS                      Status;\r
+  UI_MENU_SELECTION               *Selection;\r
+  FORM_BROWSER_STATEMENT          *Question;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_HII_VALUE                   *HiiValue;\r
+  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
 \r
   if (gMenuRefreshHead != NULL) {\r
 \r
     MenuRefreshEntry = gMenuRefreshHead;\r
 \r
+    //\r
+    // Reset FormPackage update flag\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+\r
     do {\r
       gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);\r
 \r
       Selection = MenuRefreshEntry->Selection;\r
       Question = MenuRefreshEntry->MenuOption->ThisTag;\r
 \r
+      Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\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 leading spaces on OptionString - remove the spaces\r
+        //\r
+        for (Index = 0; OptionString[Index] == L' '; Index++)\r
+          ;\r
+\r
+        PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, &OptionString[Index]);\r
+        FreePool (OptionString);\r
+      }\r
+\r
       //\r
-      // Don't update Question being edited\r
+      // Question value may be changed, need invoke its Callback()\r
       //\r
-      if (Question != MenuRefreshEntry->Selection->Statement) {\r
+      ConfigAccess = Selection->FormSet->ConfigAccess;\r
+      if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
 \r
-        Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);\r
-        if (EFI_ERROR (Status)) {\r
-          return;\r
+        HiiValue = &Question->HiiValue;\r
+        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+          //\r
+          // Create String in HII database for Configuration Driver to retrieve\r
+          //\r
+          HiiValue->Value.string = NewString ((CHAR16 *) Question->BufferValue, Selection->FormSet->HiiHandle);\r
         }\r
 \r
-        ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_CHANGING,\r
+                                 Question->QuestionId,\r
+                                 HiiValue->Type,\r
+                                 &HiiValue->Value,\r
+                                 &ActionRequest\r
+                                 );\r
 \r
-        if (OptionString != NULL) {\r
+        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
           //\r
-          // If leading spaces on OptionString - remove the spaces\r
+          // Clean the String in HII Database\r
           //\r
-          for (Index = 0; OptionString[Index] == L' '; Index++)\r
-            ;\r
+          DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);\r
+        }\r
 \r
-          for (Loop = 0; OptionString[Index] != CHAR_NULL; Index++) {\r
-            OptionString[Loop] = OptionString[Index];\r
-            Loop++;\r
-          }\r
+        if (!EFI_ERROR (Status)) {\r
+          switch (ActionRequest) {\r
+          case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+            gResetRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+            SubmitForm (Selection->FormSet, Selection->Form);\r
+            break;\r
 \r
-          OptionString[Loop] = CHAR_NULL;\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
 \r
-          PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);\r
-          gBS->FreePool (OptionString);\r
+          default:\r
+            break;\r
+          }\r
         }\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
@@ -442,7 +503,7 @@ UiWaitForSingleEvent (
       if (!EFI_ERROR (Status) && Index == 1) {\r
         Status = EFI_TIMEOUT;\r
         if (RefreshInterval != 0) {\r
-          RefreshForm ();\r
+          Status = RefreshForm ();\r
         }\r
       }\r
 \r
@@ -548,7 +609,6 @@ UiAddMenuOption (
   @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  String                 Pointer to the first string in the list\r
   @param  ...                    A series of (quantity == NumberOfLines) text\r
                                  strings which will be used to construct the dialog\r
                                  box\r
@@ -566,11 +626,11 @@ CreateDialog (
   IN  UINTN                       MaximumStringSize,\r
   OUT CHAR16                      *StringBuffer,\r
   OUT EFI_INPUT_KEY               *KeyValue,\r
-  IN  CHAR16                      *String,\r
   ...\r
   )\r
 {\r
   VA_LIST       Marker;\r
+  VA_LIST       MarkerBackup;\r
   UINTN         Count;\r
   EFI_INPUT_KEY Key;\r
   UINTN         LargestString;\r
@@ -600,7 +660,8 @@ CreateDialog (
   ASSERT (TempString);\r
   ASSERT (BufferedString);\r
 \r
-  VA_START (Marker, String);\r
+  VA_START (Marker, KeyValue);\r
+  MarkerBackup = Marker;\r
 \r
   //\r
   // Zero the outgoing buffer\r
@@ -621,16 +682,13 @@ CreateDialog (
   //\r
   gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
 \r
-  LargestString = (GetStringWidth (String) / 2);\r
+  LargestString = 0;\r
 \r
-  if (*String == L' ') {\r
-    InputOffset = 1;\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 = 1; Count < NumberOfLines; Count++) {\r
+  for (Count = 0; Count < NumberOfLines; Count++) {\r
     StackString = VA_ARG (Marker, CHAR16 *);\r
 \r
     if (StackString[0] == L' ') {\r
@@ -653,7 +711,7 @@ CreateDialog (
   //\r
   // Display the Popup\r
   //\r
-  CreateSharedPopUp (LargestString, NumberOfLines, &String);\r
+  CreateSharedPopUp (LargestString, NumberOfLines, MarkerBackup);\r
 \r
   //\r
   // Take the first key typed and report it back?\r
@@ -671,8 +729,8 @@ CreateDialog (
       case CHAR_NULL:\r
         switch (Key.ScanCode) {\r
         case SCAN_ESC:\r
-          gBS->FreePool (TempString);\r
-          gBS->FreePool (BufferedString);\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
@@ -685,8 +743,8 @@ CreateDialog (
 \r
       case CHAR_CARRIAGE_RETURN:\r
         SelectionComplete = TRUE;\r
-        gBS->FreePool (TempString);\r
-        gBS->FreePool (BufferedString);\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
@@ -752,14 +810,14 @@ CreateDialog (
 \r
   @param RequestedWidth  The width of the pop-up.\r
   @param NumberOfLines   The number of lines.\r
-  @param ArrayOfStrings  The array of string to be printed.\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  CHAR16                      **ArrayOfStrings\r
+  IN  VA_LIST                     Marker\r
   )\r
 {\r
   UINTN   Index;\r
@@ -776,8 +834,6 @@ CreateSharedPopUp (
   DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
   DimensionsHeight  = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;\r
 \r
-  Count = 0;\r
-\r
   gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);\r
 \r
   if ((RequestedWidth + 2) > DimensionsWidth) {\r
@@ -804,9 +860,10 @@ CreateSharedPopUp (
   Character = BOXDRAW_DOWN_LEFT;\r
   PrintChar (Character);\r
   Character = BOXDRAW_VERTICAL;\r
-  for (Index = Top; Index + 2 < Bottom; Index++) {\r
-    String = ArrayOfStrings[Count];\r
-    Count++;\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
@@ -858,7 +915,6 @@ CreateSharedPopUp (
 \r
   @param RequestedWidth  The width of the pop-up.\r
   @param NumberOfLines   The number of lines.\r
-  @param ArrayOfStrings  The array of string to be printed.\r
   @param ...             A series of text strings that displayed in the pop-up.\r
 \r
 **/\r
@@ -866,11 +922,16 @@ VOID
 CreatePopUp (\r
   IN  UINTN                       RequestedWidth,\r
   IN  UINTN                       NumberOfLines,\r
-  IN  CHAR16                      *ArrayOfStrings,\r
   ...\r
   )\r
 {\r
-  CreateSharedPopUp (RequestedWidth, NumberOfLines, &ArrayOfStrings);\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
@@ -890,7 +951,6 @@ UpdateStatusBar (
   )\r
 {\r
   UINTN           Index;\r
-  STATIC BOOLEAN  InputError;\r
   CHAR16          *NvUpdateMessage;\r
   CHAR16          *InputErrorMessage;\r
 \r
@@ -906,14 +966,14 @@ UpdateStatusBar (
         gScreenDimensions.BottomRow - 1,\r
         InputErrorMessage\r
         );\r
-      InputError = TRUE;\r
+      mInputError = TRUE;\r
     } else {\r
       gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT);\r
       for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {\r
         PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, L"  ");\r
       }\r
 \r
-      InputError = FALSE;\r
+      mInputError = FALSE;\r
     }\r
     break;\r
 \r
@@ -945,7 +1005,7 @@ UpdateStatusBar (
     break;\r
 \r
   case REFRESH_STATUS_BAR:\r
-    if (InputError) {\r
+    if (mInputError) {\r
       UpdateStatusBar (INPUT_ERROR, Flags, TRUE);\r
     }\r
 \r
@@ -958,8 +1018,8 @@ UpdateStatusBar (
     break;\r
   }\r
 \r
-  gBS->FreePool (InputErrorMessage);\r
-  gBS->FreePool (NvUpdateMessage);\r
+  FreePool (InputErrorMessage);\r
+  FreePool (NvUpdateMessage);\r
   return ;\r
 }\r
 \r
@@ -991,7 +1051,7 @@ GetWidth (
   if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {\r
     String = GetToken (Statement->TextTwo, Handle);\r
     Size   = StrLen (String);\r
-    gBS->FreePool (String);\r
+    FreePool (String);\r
   }\r
 \r
   if ((Statement->Operand == EFI_IFR_SUBTITLE_OP) ||\r
@@ -1016,9 +1076,6 @@ GetWidth (
   return Width;\r
 }\r
 \r
-\r
-STATIC BOOLEAN GetLineByWidthFinished = FALSE;\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
@@ -1128,9 +1185,6 @@ GetLineByWidth (
   @param  OptionalString         The option string.\r
   @param  SkipValue              The number of lins to skip.\r
 \r
-  @retval TRUE                   This Menu Option is selectable.\r
-  @retval FALSE                  This Menu Option could not be selected.\r
-\r
 **/\r
 VOID\r
 UpdateOptionSkipLines (\r
@@ -1162,7 +1216,7 @@ UpdateOptionSkipLines (
       //\r
       // If there is more string to process print on the next row and increment the Skip value\r
       //\r
-      if (StrLen (&OptionString[Index])) {\r
+      if (StrLen (&OptionString[Index]) != 0) {\r
         if (SkipValue == 0) {\r
           Row++;\r
           //\r
@@ -1178,7 +1232,7 @@ UpdateOptionSkipLines (
         }\r
       }\r
 \r
-      gBS->FreePool (OutputString);\r
+      FreePool (OutputString);\r
       if (SkipValue != 0) {\r
         SkipValue--;\r
       }\r
@@ -1394,6 +1448,102 @@ AdjustDateAndTimePosition (
   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
   Display menu and wait for user to select one menu option, then return it.\r
@@ -1452,6 +1602,9 @@ UiDisplayMenu (
   UINT16                          DefaultId;\r
   EFI_DEVICE_PATH_PROTOCOL        *DevicePath;\r
   FORM_BROWSER_STATEMENT          *Statement;\r
+  CHAR16                          TemStr[2];\r
+  UINT8                           *DevicePathBuffer;\r
+  UINT8                           DigitUint8;\r
 \r
   CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
 \r
@@ -1579,13 +1732,13 @@ UiDisplayMenu (
             //\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])) {\r
+            if (StrLen (&MenuOption->Description[Index]) != 0) {\r
               if (Temp == 0) {\r
                 Row++;\r
               }\r
             }\r
 \r
-            gBS->FreePool (OutputString);\r
+            FreePool (OutputString);\r
             if (Temp != 0) {\r
               Temp--;\r
             }\r
@@ -1595,7 +1748,16 @@ UiDisplayMenu (
           Row   = OriginalRow;\r
 \r
           gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);\r
-          ProcessOptions (Selection, MenuOption, FALSE, &OptionString);\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
@@ -1665,7 +1827,7 @@ UiDisplayMenu (
               //\r
               // If there is more string to process print on the next row and increment the Skip value\r
               //\r
-              if (StrLen (&OptionString[Index])) {\r
+              if (StrLen (&OptionString[Index]) != 0) {\r
                 if (Temp2 == 0) {\r
                   Row++;\r
                   //\r
@@ -1681,7 +1843,7 @@ UiDisplayMenu (
                 }\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
               if (Temp2 != 0) {\r
                 Temp2--;\r
               }\r
@@ -1690,7 +1852,7 @@ UiDisplayMenu (
             Temp2 = 0;\r
             Row   = OriginalRow;\r
 \r
-            gBS->FreePool (OptionString);\r
+            FreePool (OptionString);\r
           }\r
           //\r
           // If this is a text op with secondary text information\r
@@ -1708,7 +1870,7 @@ UiDisplayMenu (
               //\r
               // If there is more string to process print on the next row and increment the Skip value\r
               //\r
-              if (StrLen (&StringPtr[Index])) {\r
+              if (StrLen (&StringPtr[Index]) != 0) {\r
                 if (Temp2 == 0) {\r
                   Row++;\r
                   //\r
@@ -1724,14 +1886,14 @@ UiDisplayMenu (
                 }\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
               if (Temp2 != 0) {\r
                 Temp2--;\r
               }\r
             }\r
 \r
             Row = OriginalRow;\r
-            gBS->FreePool (StringPtr);\r
+            FreePool (StringPtr);\r
           }\r
 \r
           //\r
@@ -1882,16 +2044,16 @@ UiDisplayMenu (
               //\r
               // If there is more string to process print on the next row and increment the Skip value\r
               //\r
-              if (StrLen (&OptionString[Index])) {\r
+              if (StrLen (&OptionString[Index]) != 0) {\r
                 MenuOption->Row++;\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
             }\r
 \r
             MenuOption->Row = OriginalRow;\r
 \r
-            gBS->FreePool (OptionString);\r
+            FreePool (OptionString);\r
           } else {\r
             if (NewLine) {\r
               if (MenuOption->GrayOut) {\r
@@ -1910,11 +2072,11 @@ UiDisplayMenu (
                 //\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])) {\r
+                if (StrLen (&MenuOption->Description[Index]) != 0) {\r
                   MenuOption->Row++;\r
                 }\r
 \r
-                gBS->FreePool (OutputString);\r
+                FreePool (OutputString);\r
               }\r
 \r
               MenuOption->Row = OriginalRow;\r
@@ -1988,16 +2150,16 @@ UiDisplayMenu (
             //\r
             // If there is more string to process print on the next row and increment the Skip value\r
             //\r
-            if (StrLen (&OptionString[Index])) {\r
+            if (StrLen (&OptionString[Index]) != 0) {\r
               MenuOption->Row++;\r
             }\r
 \r
-            gBS->FreePool (OutputString);\r
+            FreePool (OutputString);\r
           }\r
 \r
           MenuOption->Row = OriginalRow;\r
 \r
-          gBS->FreePool (OptionString);\r
+          FreePool (OptionString);\r
         } else {\r
           if (NewLine) {\r
             OriginalRow = MenuOption->Row;\r
@@ -2011,11 +2173,11 @@ UiDisplayMenu (
               //\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])) {\r
+              if (StrLen (&MenuOption->Description[Index]) != 0) {\r
                 MenuOption->Row++;\r
               }\r
 \r
-              gBS->FreePool (OutputString);\r
+              FreePool (OutputString);\r
             }\r
 \r
             MenuOption->Row = OriginalRow;\r
@@ -2023,12 +2185,8 @@ UiDisplayMenu (
           }\r
         }\r
 \r
-        if (((NewPos->ForwardLink != &Menu) && (ScreenOperation == UiDown)) ||\r
-            ((NewPos->BackLink != &Menu) && (ScreenOperation == UiUp)) ||\r
-            (ScreenOperation == UiNoOperation)\r
-            ) {\r
-          UpdateKeyHelp (MenuOption, FALSE);\r
-        }\r
+        UpdateKeyHelp (MenuOption, FALSE);\r
+\r
         //\r
         // Clear reverse attribute\r
         //\r
@@ -2095,17 +2253,22 @@ UiDisplayMenu (
         Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, MinRefreshInterval);\r
       } while (Status == EFI_TIMEOUT);\r
 \r
-      if (Status == EFI_TIMEOUT) {\r
-        Key.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
-      } else {\r
-        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+      if (Selection->Action == UI_ACTION_REFRESH_FORMSET) {\r
         //\r
-        // if we encounter error, continue to read another key in.\r
+        // IFR is updated in Callback of refresh opcode, re-parse it\r
         //\r
-        if (EFI_ERROR (Status)) {\r
-          ControlFlag = CfReadKey;\r
-          continue;\r
-        }\r
+        ControlFlag = CfUiReset;\r
+        Selection->Statement = NULL;\r
+        break;\r
+      }\r
+\r
+      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+      //\r
+      // if we encounter error, continue to read another key in.\r
+      //\r
+      if (EFI_ERROR (Status)) {\r
+        ControlFlag = CfReadKey;\r
+        break;\r
       }\r
 \r
       if (IsListEmpty (&Menu) && Key.UnicodeChar != CHAR_NULL) {\r
@@ -2138,7 +2301,16 @@ UiDisplayMenu (
             gDirection = SCAN_LEFT;\r
           }\r
           Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);\r
-          SafeFreePool (OptionString);\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // Repaint to clear possible error prompt pop-up\r
+            //\r
+            Repaint = TRUE;\r
+            NewLine = TRUE;\r
+          }\r
+          if (OptionString != NULL) {\r
+            FreePool (OptionString);\r
+          }\r
         }\r
         break;\r
 \r
@@ -2285,9 +2457,28 @@ UiDisplayMenu (
           }\r
           BufferSize = StrLen (StringPtr) / 2;\r
           DevicePath = AllocatePool (BufferSize);\r
+          \r
+          //\r
+          // Convert from Device Path String to DevicePath Buffer in the reverse order.\r
+          //\r
+          DevicePathBuffer = (UINT8 *) DevicePath;\r
+          for (Index = 0; StringPtr[Index] != L'\0'; Index ++) {\r
+            TemStr[0] = StringPtr[Index];\r
+            DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+            if (DigitUint8 == 0 && TemStr[0] != L'0') {\r
+              //\r
+              // Invalid Hex Char as the tail.\r
+              //\r
+              break;\r
+            }\r
+            if ((Index & 1) == 0) {\r
+              DevicePathBuffer [Index/2] = DigitUint8;\r
+            } else {\r
+              DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);\r
+            }\r
+          }\r
 \r
-          HexStringToBuffer ((UINT8 *) DevicePath, &BufferSize, StringPtr);\r
-          Selection->Handle = HiiLibDevicePathToHiiHandle (DevicePath);\r
+          Selection->Handle = DevicePathToHiiHandle (DevicePath);\r
           if (Selection->Handle == NULL) {\r
             //\r
             // If target Hii Handle not found, exit\r
@@ -2297,8 +2488,8 @@ UiDisplayMenu (
             break;\r
           }\r
 \r
-          gBS->FreePool (StringPtr);\r
-          gBS->FreePool (DevicePath);\r
+          FreePool (StringPtr);\r
+          FreePool (DevicePath);\r
 \r
           CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));\r
           Selection->FormId = Statement->RefFormId;\r
@@ -2376,15 +2567,14 @@ UiDisplayMenu (
         if (EFI_ERROR (Status)) {\r
           Repaint = TRUE;\r
           NewLine = TRUE;\r
-          break;\r
-        }\r
-\r
-        if (OptionString != NULL) {\r
-          PrintStringAt (LocalScreen.LeftColumn + gPromptBlockWidth + 1, MenuOption->Row, OptionString);\r
-          gBS->FreePool (OptionString);\r
-        }\r
+            UpdateKeyHelp (MenuOption, FALSE);\r
+          } else {\r
+            Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          }\r
 \r
-        Selection->Action = UI_ACTION_REFRESH_FORM;\r
+          if (OptionString != NULL) {\r
+            FreePool (OptionString);\r
+          }\r
         break;\r
       }\r
       break;\r
@@ -2829,6 +3019,7 @@ UiDisplayMenu (
 \r
       if (!EFI_ERROR (Status)) {\r
         Selection->Action = UI_ACTION_REFRESH_FORM;\r
+        Selection->Statement = NULL;\r
 \r
         //\r
         // Show NV update flag on status bar\r