]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
Update the logic in browser core, use config routine protocol instead of config acces...
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
index a5caf4426cc50289d03b576e4083f8c4a4bf8aae..fb3ff7b266f45cb0082659d474b7fb28b226baeb 100644 (file)
@@ -160,7 +160,7 @@ UpdateStatement (
   //\r
   // Question value may be changed, need invoke its Callback()\r
   //\r
-  ProcessCallBackFunction (gCurrentSelection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+  ProcessCallBackFunction (gCurrentSelection, gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
   \r
   if (mHiiPackageListUpdated) {\r
     //\r
@@ -569,6 +569,47 @@ UpdateHotkeyList (
   }\r
 }\r
 \r
+/**\r
+\r
+  Get the extra question attribute from override question list.\r
+\r
+  @param    QuestionId    The question id for this request question.\r
+\r
+  @retval   The attribute for this question or NULL if not found this \r
+            question in the list.\r
+\r
+**/\r
+UINT32 \r
+ProcessQuestionExtraAttr (\r
+  IN   EFI_QUESTION_ID  QuestionId\r
+  )\r
+{\r
+  LIST_ENTRY                   *Link;\r
+  QUESTION_ATTRIBUTE_OVERRIDE  *QuestionDesc;\r
+\r
+  //\r
+  // Return HII_DISPLAY_NONE if input a invalid question id.\r
+  //\r
+  if (QuestionId == 0) {\r
+    return HII_DISPLAY_NONE;\r
+  }\r
+\r
+  Link = GetFirstNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
+  while (!IsNull (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link)) {\r
+    QuestionDesc = FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link);\r
+    Link = GetNextNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link);\r
+\r
+    if ((QuestionDesc->QuestionId == QuestionId) &&\r
+        (QuestionDesc->FormId     == gCurrentSelection->FormId) &&\r
+        (QuestionDesc->HiiHandle  == gCurrentSelection->Handle) &&\r
+        CompareGuid (&QuestionDesc->FormSetGuid, &gCurrentSelection->FormSetGuid)) {\r
+      return QuestionDesc->Attribute;\r
+    }\r
+  }\r
+\r
+  return HII_DISPLAY_NONE;\r
+}\r
+\r
 /**\r
 \r
   Enum all statement in current form, find all the statement can be display and\r
@@ -589,6 +630,7 @@ AddStatementToDisplayForm (
   EFI_EVENT                     RefreshIntervalEvent;\r
   FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
   BOOLEAN                       FormEditable;\r
+  UINT32                        ExtraAttribute;\r
 \r
   HostDisplayStatement = NULL;\r
   MinRefreshInterval   = 0;\r
@@ -630,6 +672,14 @@ AddStatementToDisplayForm (
       continue;\r
     }\r
 \r
+    //\r
+    // Check the extra attribute.\r
+    //\r
+    ExtraAttribute = ProcessQuestionExtraAttr (Statement->QuestionId);\r
+    if ((ExtraAttribute & HII_DISPLAY_SUPPRESS) != 0) {\r
+      continue;\r
+    }\r
+\r
     DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
     ASSERT (DisplayStatement != NULL);\r
 \r
@@ -638,6 +688,11 @@ AddStatementToDisplayForm (
     //\r
     InitializeDisplayStatement(DisplayStatement, Statement, HostDisplayStatement);\r
 \r
+    //\r
+    // Set the extra attribute.\r
+    //\r
+    DisplayStatement->Attribute |= ExtraAttribute;\r
+\r
     //\r
     // Save the Host statement info.\r
     // Host statement may has nest statement follow it.\r
@@ -985,6 +1040,87 @@ ProcessAction (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Check whether the formset guid is in this Hii package list.\r
+\r
+  @param  HiiHandle              The HiiHandle for this HII package list.\r
+  @param  FormSetGuid            The formset guid for the request formset.\r
+\r
+  @retval TRUE                   Find the formset guid.\r
+  @retval FALSE                  Not found the formset guid.\r
+\r
+**/\r
+BOOLEAN\r
+GetFormsetGuidFromHiiHandle (\r
+  IN EFI_HII_HANDLE       HiiHandle,\r
+  IN EFI_GUID             *FormSetGuid\r
+  )\r
+{\r
+  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
+  UINTN                        BufferSize;\r
+  UINT32                       Offset;\r
+  UINT32                       Offset2;\r
+  UINT32                       PackageListLength;\r
+  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
+  UINT8                        *Package;\r
+  UINT8                        *OpCodeData;\r
+  EFI_STATUS                   Status;\r
+  BOOLEAN                      FindGuid;\r
+\r
+  BufferSize     = 0;\r
+  HiiPackageList = NULL;\r
+  FindGuid       = FALSE;\r
+  \r
+  Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HiiPackageList = AllocatePool (BufferSize);\r
+    ASSERT (HiiPackageList != NULL);\r
+\r
+    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+  }\r
+  if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Get Form package from this HII package List\r
+  //\r
+  Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+  Offset2 = 0;\r
+  CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
+\r
+  while (Offset < PackageListLength) {\r
+    Package = ((UINT8 *) HiiPackageList) + Offset;\r
+    CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+    Offset += PackageHeader.Length;\r
+\r
+    if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+      //\r
+      // Search FormSet in this Form Package\r
+      //\r
+      Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+      while (Offset2 < PackageHeader.Length) {\r
+        OpCodeData = Package + Offset2;\r
+\r
+        if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+          if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))){\r
+            FindGuid = TRUE;\r
+            break;\r
+          }\r
+        }\r
+\r
+        Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+      }\r
+    }\r
+    if (FindGuid) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  FreePool (HiiPackageList);\r
+\r
+  return FindGuid;\r
+}\r
 \r
 /**\r
   Find HII Handle in the HII database associated with given Device Path.\r
@@ -993,6 +1129,7 @@ ProcessAction (
 \r
   @param  DevicePath             Device Path associated with the HII package list\r
                                  handle.\r
+  @param  FormsetGuid            The formset guid for this formset.\r
 \r
   @retval Handle                 HII package list Handle associated with the Device\r
                                         Path.\r
@@ -1000,15 +1137,13 @@ ProcessAction (
 \r
 **/\r
 EFI_HII_HANDLE\r
-EFIAPI\r
 DevicePathToHiiHandle (\r
-  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath\r
+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath,\r
+  IN EFI_GUID                   *FormsetGuid\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
@@ -1033,32 +1168,8 @@ DevicePathToHiiHandle (
   //\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
+  HiiHandles = HiiGetHiiHandles (NULL);\r
+  if (HiiHandles == NULL) {\r
     return NULL;\r
   }\r
 \r
@@ -1066,16 +1177,21 @@ DevicePathToHiiHandle (
   // 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
+  for (Index = 0; HiiHandles[Index] != NULL; 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
+      if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], FormsetGuid)) {\r
+        HiiHandle = HiiHandles[Index];\r
+        break;\r
+      }\r
+\r
+      if (HiiHandle != NULL) {\r
+        break;\r
+      }\r
     }\r
   }\r
 \r
@@ -1102,17 +1218,8 @@ FormSetGuidToHiiHandle (
   )\r
 {\r
   EFI_HII_HANDLE               *HiiHandles;\r
-  UINTN                        Index;\r
-  EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;\r
-  UINTN                        BufferSize;\r
-  UINT32                       Offset;\r
-  UINT32                       Offset2;\r
-  UINT32                       PackageListLength;\r
-  EFI_HII_PACKAGE_HEADER       PackageHeader;\r
-  UINT8                        *Package;\r
-  UINT8                        *OpCodeData;\r
-  EFI_STATUS                   Status;\r
   EFI_HII_HANDLE               HiiHandle;\r
+  UINTN                        Index;\r
 \r
   ASSERT (ComparingGuid != NULL);\r
 \r
@@ -1127,61 +1234,14 @@ FormSetGuidToHiiHandle (
   // Search for formset of each class type\r
   //\r
   for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
-    BufferSize = 0;\r
-    HiiPackageList = NULL;\r
-    Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
-    if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      HiiPackageList = AllocatePool (BufferSize);\r
-      ASSERT (HiiPackageList != NULL);\r
-\r
-      Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);\r
-    }\r
-    if (EFI_ERROR (Status) || HiiPackageList == NULL) {\r
-      return NULL;\r
+    if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], ComparingGuid)) {\r
+      HiiHandle = HiiHandles[Index];\r
+      break;\r
     }\r
 \r
-    //\r
-    // Get Form package from this HII package List\r
-    //\r
-    Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-    Offset2 = 0;\r
-    CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
-\r
-    while (Offset < PackageListLength) {\r
-      Package = ((UINT8 *) HiiPackageList) + Offset;\r
-      CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
-\r
-      if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
-        //\r
-        // Search FormSet in this Form Package\r
-        //\r
-        Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
-        while (Offset2 < PackageHeader.Length) {\r
-          OpCodeData = Package + Offset2;\r
-\r
-          if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
-            //\r
-            // Try to compare against formset GUID\r
-            //\r
-            if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
-              HiiHandle = HiiHandles[Index];\r
-              break;\r
-            }\r
-          }\r
-\r
-          Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
-        }\r
-      }\r
-      if (HiiHandle != NULL) {\r
-        break;\r
-      }\r
-      Offset += PackageHeader.Length;\r
+    if (HiiHandle != NULL) {\r
+      break;\r
     }\r
-    \r
-    FreePool (HiiPackageList);\r
-       if (HiiHandle != NULL) {\r
-               break;\r
-       }\r
   }\r
 \r
   FreePool (HiiHandles);\r
@@ -1309,7 +1369,7 @@ ProcessGotoOpCode (
   //\r
   // Check whether the device path string is a valid string.\r
   //\r
-  if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {\r
+  if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL && StringPtr[0] != L'\0') {\r
     if (Selection->Form->ModalForm) {\r
       return Status;\r
     }\r
@@ -1320,7 +1380,7 @@ ProcessGotoOpCode (
     if (mPathFromText != NULL) {\r
       DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);\r
       if (DevicePath != NULL) {\r
-        HiiHandle = DevicePathToHiiHandle (DevicePath);\r
+        HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);\r
         FreePool (DevicePath);\r
       }\r
       FreePool (StringPtr);\r
@@ -1439,7 +1499,6 @@ ProcessQuestionConfig (
   EFI_STATUS                      Status;\r
   CHAR16                          *ConfigResp;\r
   CHAR16                          *Progress;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
 \r
   if (Question->QuestionConfig == 0) {\r
     return EFI_SUCCESS;\r
@@ -1456,12 +1515,8 @@ ProcessQuestionConfig (
   //\r
   // Send config to Configuration Driver\r
   //\r
-  ConfigAccess = Selection->FormSet->ConfigAccess;\r
-  if (ConfigAccess == NULL) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  Status = ConfigAccess->RouteConfig (\r
-                           ConfigAccess,\r
+  Status = mHiiConfigRouting->RouteConfig (\r
+                           mHiiConfigRouting,\r
                            ConfigResp,\r
                            &Progress\r
                            );\r
@@ -1618,9 +1673,6 @@ ProcessUserInput (
         CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));\r
         break;\r
       }\r
-      if (Statement->Operand != EFI_IFR_PASSWORD_OP) {\r
-        SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
-      }\r
       break;\r
     }\r
   }\r
@@ -1986,6 +2038,8 @@ FindNextMenu (
                                about the Selection, form and formset to be displayed.\r
                                On output, Selection return the screen item that is selected\r
                                by user.\r
+  @param FormSet               The formset this question belong to.\r
+  @param Form                  The form this question belong to.\r
   @param Question              The Question which need to call.\r
   @param Action                The action request.\r
   @param SkipSaveOrDiscard     Whether skip save or discard action.\r
@@ -1996,6 +2050,8 @@ FindNextMenu (
 EFI_STATUS \r
 ProcessCallBackFunction (\r
   IN OUT UI_MENU_SELECTION               *Selection,\r
+  IN     FORM_BROWSER_FORMSET            *FormSet,\r
+  IN     FORM_BROWSER_FORM               *Form,\r
   IN     FORM_BROWSER_STATEMENT          *Question,\r
   IN     EFI_BROWSER_ACTION              Action,\r
   IN     BOOLEAN                         SkipSaveOrDiscard\r
@@ -2012,23 +2068,26 @@ ProcessCallBackFunction (
   BOOLEAN                         NeedExit;\r
   LIST_ENTRY                      *Link;\r
   BROWSER_SETTING_SCOPE           SettingLevel;\r
+  EFI_IFR_TYPE_VALUE              BackUpValue;\r
+  UINT8                           *BackUpBuffer;\r
 \r
-  ConfigAccess = Selection->FormSet->ConfigAccess;\r
+  ConfigAccess = FormSet->ConfigAccess;\r
   SubmitFormIsRequired  = FALSE;\r
   SettingLevel          = FormSetLevel;\r
   DiscardFormIsRequired = FALSE;\r
   NeedExit              = FALSE;\r
   Status                = EFI_SUCCESS;\r
   ActionRequest         = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+  BackUpBuffer          = NULL;\r
 \r
   if (ConfigAccess == NULL) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  Link = GetFirstNode (&Selection->Form->StatementListHead);\r
-  while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+  Link = GetFirstNode (&Form->StatementListHead);\r
+  while (!IsNull (&Form->StatementListHead, Link)) {\r
     Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
-    Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+    Link = GetNextNode (&Form->StatementListHead, Link);\r
 \r
     //\r
     // if Question != NULL, only process the question. Else, process all question in this form.\r
@@ -2045,7 +2104,7 @@ ProcessCallBackFunction (
     // Check whether Statement is disabled.\r
     //\r
     if (Statement->Expression != NULL) {\r
-      if (EvaluateExpressionList(Statement->Expression, TRUE, Selection->FormSet, Selection->Form) == ExpressDisable) {\r
+      if (EvaluateExpressionList(Statement->Expression, TRUE, FormSet, Form) == ExpressDisable) {\r
         continue;\r
       }\r
     }\r
@@ -2058,7 +2117,18 @@ ProcessCallBackFunction (
       //\r
       TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
     }\r
-      \r
+\r
+    //\r
+    // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.\r
+    //\r
+    if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+      if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+        BackUpBuffer = AllocateCopyPool(Statement->StorageWidth + sizeof(CHAR16), Statement->BufferValue);\r
+      } else {\r
+        CopyMem (&BackUpValue, &HiiValue->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+      }\r
+    }\r
+\r
     ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
     Status = ConfigAccess->Callback (\r
                              ConfigAccess,\r
@@ -2122,15 +2192,31 @@ ProcessCallBackFunction (
       // "retrieve" should update to the question's temp buffer.\r
       //\r
       if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
-        SetQuestionValue(Selection->FormSet, Selection->Form, Statement, GetSetValueWithEditBuffer);\r
+        SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
       }\r
     } else {\r
+      //\r
+      // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING, \r
+      // then the browser will use the value passed to Callback() and ignore the \r
+      // value returned by Callback(). \r
+      //\r
+      if (Action  == EFI_BROWSER_ACTION_CHANGING && Status == EFI_UNSUPPORTED) {\r
+        if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+          CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth + sizeof(CHAR16));\r
+        } else {\r
+          CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));\r
+        }\r
+\r
+        SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
+      }\r
+\r
       //\r
       // According the spec, return fail from call back of "changing" and \r
       // "retrieve", should restore the question's value.\r
       //\r
-      if (Action  == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
-        GetQuestionValue(Selection->FormSet, Selection->Form, Statement, GetSetValueWithEditBuffer);\r
+      if ((Action == EFI_BROWSER_ACTION_CHANGING && Status != EFI_UNSUPPORTED) || \r
+           Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+        GetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
       }\r
 \r
       if (Status == EFI_UNSUPPORTED) {\r
@@ -2140,14 +2226,18 @@ ProcessCallBackFunction (
         Status = EFI_SUCCESS;\r
       }\r
     }\r
+\r
+    if (BackUpBuffer != NULL) {\r
+      FreePool (BackUpBuffer);\r
+    }\r
   }\r
 \r
   if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
-    SubmitForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+    SubmitForm (FormSet, Form, SettingLevel);\r
   }\r
 \r
   if (DiscardFormIsRequired && !SkipSaveOrDiscard) {\r
-    DiscardForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+    DiscardForm (FormSet, Form, SettingLevel);\r
   }\r
 \r
   if (NeedExit) {\r
@@ -2249,6 +2339,11 @@ SetupBrowser (
     return Status;\r
   }\r
 \r
+  if ((Selection->Handle != mCurrentHiiHandle) ||\r
+      (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid))) {\r
+    gFinishRetrieveCall = FALSE;\r
+  }\r
+\r
   //\r
   // Initialize current settings of Questions in this FormSet\r
   //\r
@@ -2327,7 +2422,7 @@ SetupBrowser (
       CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
       mCurrentFormId      = Selection->FormId;\r
 \r
-      Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
+      Status = ProcessCallBackFunction (Selection, gCurrentSelection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
@@ -2350,6 +2445,11 @@ SetupBrowser (
       goto Done;\r
     }\r
 \r
+    //\r
+    // Finish call RETRIEVE callback for this formset.\r
+    //\r
+    gFinishRetrieveCall = TRUE;\r
+\r
     //\r
     // IFR is updated during callback of read value, force to reparse the IFR binary\r
     //\r
@@ -2375,7 +2475,7 @@ SetupBrowser (
       if ((ConfigAccess != NULL) && \r
           ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
           (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
-        Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+        Status = ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
         if (Statement->Operand == EFI_IFR_REF_OP) {\r
           //\r
           // Process dynamic update ref opcode.\r
@@ -2397,8 +2497,10 @@ SetupBrowser (
         }\r
 \r
         if (!EFI_ERROR (Status) && Statement->Operand != EFI_IFR_REF_OP) {\r
-          ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+          ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
         }\r
+      } else if (Statement->Operand != EFI_IFR_PASSWORD_OP) {\r
+        SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
       }\r
     }\r
 \r
@@ -2433,7 +2535,7 @@ SetupBrowser (
          (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
          (Selection->FormId != mCurrentFormId))) {\r
 \r
-      Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
+      Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r