]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
index 4b00b54ce8f3222747a9f22557fcb2120ee56d38..ded1c7ad1159011d893e51eeeb61e9902e36ded2 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
 Utility functions for UI presentation.\r
 \r
-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -69,27 +70,11 @@ EvaluateFormExpressions (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  Add empty function for event process function.\r
-\r
-  @param Event    The Event need to be process\r
-  @param Context  The context of the event.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-SetupBrowserEmptyFunction (\r
-  IN  EFI_EVENT    Event,\r
-  IN  VOID         *Context\r
-  )\r
-{\r
-}\r
-\r
 /**\r
   Base on the opcode buffer info to get the display statement.\r
 \r
   @param OpCode    The input opcode buffer for this statement.\r
-  \r
+\r
   @retval Statement  The statement use this opcode buffer.\r
 \r
 **/\r
@@ -118,7 +103,7 @@ GetDisplayStatement (
   Free the refresh event list.\r
 \r
 **/\r
-VOID \r
+VOID\r
 FreeRefreshEvent (\r
   VOID\r
   )\r
@@ -138,7 +123,7 @@ FreeRefreshEvent (
 }\r
 \r
 /**\r
-  Check whether this statement value is changed. If yes, update the statement value and return TRUE; \r
+  Check whether this statement value is changed. If yes, update the statement value and return TRUE;\r
   else return FALSE.\r
 \r
   @param Statement           The statement need to check.\r
@@ -160,7 +145,7 @@ UpdateStatement (
   // Question value may be changed, need invoke its Callback()\r
   //\r
   ProcessCallBackFunction (gCurrentSelection, gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
-  \r
+\r
   if (mHiiPackageListUpdated) {\r
     //\r
     // Package list is updated, force to reparse IFR binary of target Formset\r
@@ -172,13 +157,13 @@ UpdateStatement (
 \r
 /**\r
   Refresh the question which has refresh guid event attribute.\r
-  \r
-  @param Event    The event which has this function related.     \r
+\r
+  @param Event    The event which has this function related.\r
   @param Context  The input context info related to this event or the status code return to the caller.\r
 **/\r
 VOID\r
 EFIAPI\r
-RefreshEventNotify(\r
+RefreshEventNotifyForStatement(\r
   IN      EFI_EVENT Event,\r
   IN      VOID      *Context\r
   )\r
@@ -190,6 +175,23 @@ RefreshEventNotify(
   gBS->SignalEvent (mValueChangedEvent);\r
 }\r
 \r
+/**\r
+  Refresh the questions within this form.\r
+\r
+  @param Event    The event which has this function related.\r
+  @param Context  The input context info related to this event or the status code return to the caller.\r
+**/\r
+VOID\r
+EFIAPI\r
+RefreshEventNotifyForForm(\r
+  IN      EFI_EVENT Event,\r
+  IN      VOID      *Context\r
+  )\r
+{\r
+  gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
+\r
+  gBS->SignalEvent (mValueChangedEvent);\r
+}\r
 \r
 /**\r
   Create refresh hook event for statement which has refresh event or interval.\r
@@ -198,7 +200,7 @@ RefreshEventNotify(
 \r
 **/\r
 VOID\r
-CreateRefreshEvent (\r
+CreateRefreshEventForStatement (\r
   IN     FORM_BROWSER_STATEMENT        *Statement\r
   )\r
 {\r
@@ -212,7 +214,7 @@ CreateRefreshEvent (
   Status = gBS->CreateEventEx (\r
                     EVT_NOTIFY_SIGNAL,\r
                     TPL_CALLBACK,\r
-                    RefreshEventNotify,\r
+                    RefreshEventNotifyForStatement,\r
                     Statement,\r
                     &Statement->RefreshGuid,\r
                     &RefreshEvent);\r
@@ -224,6 +226,39 @@ CreateRefreshEvent (
   InsertTailList(&mRefreshEventList, &EventNode->Link);\r
 }\r
 \r
+/**\r
+  Create refresh hook event for form which has refresh event or interval.\r
+\r
+  @param Form           The form need to check.\r
+\r
+**/\r
+VOID\r
+CreateRefreshEventForForm (\r
+  IN     FORM_BROWSER_FORM        *Form\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_EVENT                       RefreshEvent;\r
+  FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
+\r
+  //\r
+  // If question has refresh guid, create the notify function.\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_CALLBACK,\r
+                    RefreshEventNotifyForForm,\r
+                    Form,\r
+                    &Form->RefreshGuid,\r
+                    &RefreshEvent);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
+  ASSERT (EventNode != NULL);\r
+  EventNode->RefreshEvent = RefreshEvent;\r
+  InsertTailList(&mRefreshEventList, &EventNode->Link);\r
+}\r
+\r
 /**\r
 \r
   Initialize the Display statement structure data.\r
@@ -307,8 +342,8 @@ InitializeDisplayStatement (
   //\r
   // Create the refresh event process function.\r
   //\r
-  if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {\r
-    CreateRefreshEvent (Statement);\r
+  if (!IsZeroGuid (&Statement->RefreshGuid)) {\r
+    CreateRefreshEventForStatement (Statement);\r
   }\r
 \r
   //\r
@@ -322,7 +357,7 @@ InitializeDisplayStatement (
   // Create the refresh guid hook event.\r
   // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.\r
   //\r
-  if ((!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) || (Statement->RefreshInterval != 0)) {\r
+  if ((!IsZeroGuid (&Statement->RefreshGuid)) || (Statement->RefreshInterval != 0)) {\r
     gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
   }\r
 \r
@@ -415,11 +450,11 @@ UpdateHotkeyList (
 \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
+  @retval   The attribute for this question or NULL if not found this\r
             question in the list.\r
 \r
 **/\r
-UINT32 \r
+UINT32\r
 ProcessQuestionExtraAttr (\r
   IN   EFI_QUESTION_ID  QuestionId\r
   )\r
@@ -495,6 +530,21 @@ AddStatementToDisplayForm (
     InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
   }\r
 \r
+  //\r
+  // treat formset as statement outside the form,get its opcode.\r
+  //\r
+  DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
+  ASSERT (DisplayStatement != NULL);\r
+\r
+  DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
+  DisplayStatement->Version   = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
+  DisplayStatement->OpCode = gCurrentSelection->FormSet->OpCode;\r
+\r
+  InitializeListHead (&DisplayStatement->NestStatementList);\r
+  InitializeListHead (&DisplayStatement->OptionListHead);\r
+\r
+  InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
+\r
   //\r
   // Process the statement in this form.\r
   //\r
@@ -538,7 +588,7 @@ AddStatementToDisplayForm (
     //\r
     // Get the minimal refresh interval value for later use.\r
     //\r
-    if ((Statement->RefreshInterval != 0) && \r
+    if ((Statement->RefreshInterval != 0) &&\r
       (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval)) {\r
       MinRefreshInterval = Statement->RefreshInterval;\r
     }\r
@@ -559,6 +609,16 @@ AddStatementToDisplayForm (
     InsertTailList(&mRefreshEventList, &EventNode->Link);\r
   }\r
 \r
+  //\r
+  // Create the refresh event process function for Form.\r
+  //\r
+  if (!IsZeroGuid (&gCurrentSelection->Form->RefreshGuid)) {\r
+    CreateRefreshEventForForm (gCurrentSelection->Form);\r
+    if (gDisplayFormData.FormRefreshEvent == NULL) {\r
+      gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
+    }\r
+  }\r
+\r
   //\r
   // Update hotkey list field.\r
   //\r
@@ -589,7 +649,7 @@ UpdateDataChangedFlag (
 \r
   //\r
   // Base on the system level to check whether need to show the NV flag.\r
-  // \r
+  //\r
   switch (gBrowserSettingScope) {\r
   case SystemLevel:\r
     //\r
@@ -640,13 +700,13 @@ InitializeDisplayFormData (
   InitializeListHead (&gDisplayFormData.HotKeyListHead);\r
 \r
   Status = gBS->CreateEvent (\r
-        EVT_NOTIFY_WAIT, \r
+        EVT_NOTIFY_WAIT,\r
         TPL_CALLBACK,\r
-        SetupBrowserEmptyFunction,\r
+        EfiEventEmptyFunction,\r
         NULL,\r
         &mValueChangedEvent\r
         );\r
-  ASSERT_EFI_ERROR (Status); \r
+  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 /**\r
@@ -803,7 +863,7 @@ GetBrowserStatement (
   @param  Form                   Form data structure.\r
 \r
 **/\r
-VOID \r
+VOID\r
 UpdateStatementStatusForForm (\r
   IN FORM_BROWSER_FORMSET             *FormSet,\r
   IN FORM_BROWSER_FORM                *Form\r
@@ -834,7 +894,7 @@ UpdateStatementStatusForForm (
   @param  FormSet                FormSet data structure.\r
 \r
 **/\r
-VOID \r
+VOID\r
 UpdateStatementStatusForFormSet (\r
   IN FORM_BROWSER_FORMSET                *FormSet\r
   )\r
@@ -859,10 +919,10 @@ UpdateStatementStatusForFormSet (
   @param  SettingScope           Setting Scope for Default action.\r
 \r
 **/\r
-VOID \r
+VOID\r
 UpdateStatementStatus (\r
   IN FORM_BROWSER_FORMSET             *FormSet,\r
-  IN FORM_BROWSER_FORM                *Form, \r
+  IN FORM_BROWSER_FORM                *Form,\r
   IN BROWSER_SETTING_SCOPE            SettingScope\r
   )\r
 {\r
@@ -906,7 +966,7 @@ UpdateStatementStatus (
   @retval EFI_SUCESSS            This function always return successfully for now.\r
 \r
 **/\r
-EFI_STATUS \r
+EFI_STATUS\r
 ProcessAction (\r
   IN UINT32        Action,\r
   IN UINT16        DefaultId\r
@@ -937,7 +997,8 @@ ProcessAction (
   }\r
 \r
   if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
-    gResetRequired = TRUE;\r
+    gResetRequiredFormLevel = TRUE;\r
+    gResetRequiredSystemLevel = TRUE;\r
   }\r
 \r
   if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
@@ -990,7 +1051,7 @@ GetFormsetGuidFromHiiHandle (
   BufferSize     = 0;\r
   HiiPackageList = NULL;\r
   FindGuid       = FALSE;\r
-  \r
+\r
   Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     HiiPackageList = AllocatePool (BufferSize);\r
@@ -1007,7 +1068,7 @@ GetFormsetGuidFromHiiHandle (
   //\r
   Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
   Offset2 = 0;\r
-  CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
+  CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
 \r
   while (Offset < PackageListLength) {\r
     Package = ((UINT8 *) HiiPackageList) + Offset;\r
@@ -1196,7 +1257,7 @@ ProcessChangedData (
     case BROWSER_ACTION_DISCARD:\r
       DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
       break;\r
-  \r
+\r
     case BROWSER_ACTION_SUBMIT:\r
       Status = SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
       if (EFI_ERROR (Status)) {\r
@@ -1270,7 +1331,7 @@ ProcessGotoOpCode (
   FORM_BROWSER_FORM               *RefForm;\r
   EFI_STATUS                      Status;\r
   EFI_HII_HANDLE                  HiiHandle;\r
-  \r
+\r
   Status    = EFI_SUCCESS;\r
   StringPtr = NULL;\r
   HiiHandle = NULL;\r
@@ -1334,7 +1395,7 @@ ProcessGotoOpCode (
     CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
     Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
     Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
-  } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {\r
+  } else if (!IsZeroGuid (&Statement->HiiValue.Value.ref.FormSetGuid)) {\r
     if (Selection->Form->ModalForm) {\r
       return Status;\r
     }\r
@@ -1379,7 +1440,7 @@ ProcessGotoOpCode (
     if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
       if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\r
         //\r
-        // Form is suppressed. \r
+        // Form is suppressed.\r
         //\r
         PopupErrorMessage(BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
         return EFI_SUCCESS;\r
@@ -1426,6 +1487,8 @@ ProcessQuestionConfig (
   ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);\r
   if (ConfigResp == NULL) {\r
     return EFI_NOT_FOUND;\r
+  } else if (ConfigResp[0] == L'\0') {\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -1502,14 +1565,14 @@ ProcessUserInput (
     case EFI_IFR_REF_OP:\r
       Status = ProcessGotoOpCode(Statement, gCurrentSelection);\r
       break;\r
-    \r
+\r
     case EFI_IFR_ACTION_OP:\r
       //\r
       // Process the Config string <ConfigResp>\r
       //\r
       Status = ProcessQuestionConfig (gCurrentSelection, Statement);\r
       break;\r
-    \r
+\r
     case EFI_IFR_RESET_BUTTON_OP:\r
       //\r
       // Reset Question to default value specified by DefaultId\r
@@ -1538,6 +1601,7 @@ ProcessUserInput (
         DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
         Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
         CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
+        ZeroMem (UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);\r
         FreePool (UserInput->InputValue.Buffer);\r
         //\r
         // Two password match, send it to Configuration Driver\r
@@ -1748,9 +1812,9 @@ IsNvUpdateRequiredForForm (
                          about the Selection, form and formset to be displayed.\r
                          On output, Selection return the screen item that is selected\r
                          by user.\r
-  @param SettingLevel    Input Settting level, if it is FormLevel, just exit current form. \r
+  @param SettingLevel    Input Settting level, if it is FormLevel, just exit current form.\r
                          else, we need to exit current formset.\r
-  \r
+\r
   @retval TRUE           Exit current form.\r
   @retval FALSE          User press ESC and keep in current form.\r
 **/\r
@@ -1763,7 +1827,7 @@ FindNextMenu (
   FORM_ENTRY_INFO            *CurrentMenu;\r
   FORM_ENTRY_INFO            *ParentMenu;\r
   BROWSER_SETTING_SCOPE      Scope;\r
-  \r
+\r
   CurrentMenu = Selection->CurrentMenu;\r
   Scope       = FormSetLevel;\r
 \r
@@ -1822,6 +1886,30 @@ FindNextMenu (
   return TRUE;\r
 }\r
 \r
+/**\r
+  Reconnect the controller.\r
+\r
+  @param DriverHandle          The controller handle which need to be reconnect.\r
+\r
+  @retval   TRUE     do the reconnect behavior success.\r
+  @retval   FALSE    do the reconnect behavior failed.\r
+\r
+**/\r
+BOOLEAN\r
+ReconnectController (\r
+  IN EFI_HANDLE   DriverHandle\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+\r
+  Status = gBS->DisconnectController(DriverHandle, NULL, NULL);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->ConnectController(DriverHandle, NULL, NULL, TRUE);\r
+  }\r
+\r
+  return Status == EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Call the call back function for the question and process the return action.\r
 \r
@@ -1835,10 +1923,10 @@ FindNextMenu (
   @param Action                The action request.\r
   @param SkipSaveOrDiscard     Whether skip save or discard action.\r
 \r
-  @retval EFI_SUCCESS          The call back function excutes successfully.\r
-  @return Other value if the call back function failed to excute.  \r
+  @retval EFI_SUCCESS          The call back function executes successfully.\r
+  @return Other value if the call back function failed to execute.\r
 **/\r
-EFI_STATUS \r
+EFI_STATUS\r
 ProcessCallBackFunction (\r
   IN OUT UI_MENU_SELECTION               *Selection,\r
   IN     FORM_BROWSER_FORMSET            *FormSet,\r
@@ -1888,7 +1976,7 @@ ProcessCallBackFunction (
     if ((Question != NULL) && (Statement != Question)) {\r
       continue;\r
     }\r
-    \r
+\r
     if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
       continue;\r
     }\r
@@ -1942,6 +2030,7 @@ ProcessCallBackFunction (
 \r
         ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
         if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
+          ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
           CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
         } else {\r
           CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
@@ -1957,7 +2046,8 @@ ProcessCallBackFunction (
         switch (ActionRequest) {\r
         case EFI_BROWSER_ACTION_REQUEST_RESET:\r
           DiscardFormIsRequired = TRUE;\r
-          gResetRequired = TRUE;\r
+          gResetRequiredFormLevel = TRUE;\r
+          gResetRequiredSystemLevel = TRUE;\r
           NeedExit              = TRUE;\r
           break;\r
 \r
@@ -1993,6 +2083,10 @@ ProcessCallBackFunction (
           SettingLevel          = FormLevel;\r
           break;\r
 \r
+        case EFI_BROWSER_ACTION_REQUEST_RECONNECT:\r
+          gCallbackReconnect    = TRUE;\r
+          break;\r
+\r
         default:\r
           break;\r
         }\r
@@ -2005,7 +2099,12 @@ ProcessCallBackFunction (
         Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
         if (!EFI_ERROR (Status)) {\r
           //\r
-          // According the spec, return value from call back of "changing" and \r
+          //check whether the question value  changed compared with edit buffer before updating edit buffer\r
+          // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
+          //\r
+          IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
+          //\r
+          // According the spec, return value from call back of "changing" and\r
           // "retrieve" should update to the question's temp buffer.\r
           //\r
           SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
@@ -2014,7 +2113,7 @@ ProcessCallBackFunction (
 \r
       case EFI_BROWSER_ACTION_RETRIEVE:\r
         //\r
-        // According the spec, return value from call back of "changing" and \r
+        // According the spec, return value from call back of "changing" and\r
         // "retrieve" should update to the question's temp buffer.\r
         //\r
         SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
@@ -2025,9 +2124,9 @@ ProcessCallBackFunction (
       }\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
+      // 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
@@ -2035,18 +2134,23 @@ ProcessCallBackFunction (
         } else {\r
           CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));\r
         }\r
-        \r
+\r
         //\r
         // Do the question validation.\r
         //\r
         InternalStatus = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
         if (!EFI_ERROR (InternalStatus)) {\r
+          //\r
+          //check whether the question value  changed compared with edit buffer before updating edit buffer\r
+          // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
+          //\r
+          IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
           SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
         }\r
       }\r
 \r
       //\r
-      // According the spec, return fail from call back of "changing" and \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 && Status != EFI_UNSUPPORTED) {\r
@@ -2083,6 +2187,28 @@ ProcessCallBackFunction (
     }\r
   }\r
 \r
+  if (gCallbackReconnect && (EFI_BROWSER_ACTION_CHANGED == Action)) {\r
+    //\r
+    // Confirm changes with user first.\r
+    //\r
+    if (IsNvUpdateRequiredForFormSet(FormSet)) {\r
+      if (BROWSER_ACTION_DISCARD == PopupErrorMessage(BROWSER_RECONNECT_SAVE_CHANGES, NULL, NULL, NULL)) {\r
+        gCallbackReconnect = FALSE;\r
+        DiscardFormIsRequired = TRUE;\r
+      } else {\r
+        SubmitFormIsRequired = TRUE;\r
+      }\r
+    } else {\r
+      PopupErrorMessage(BROWSER_RECONNECT_REQUIRED, NULL, NULL, NULL);\r
+    }\r
+\r
+    //\r
+    // Exit current formset before do the reconnect.\r
+    //\r
+    NeedExit = TRUE;\r
+    SettingLevel = FormSetLevel;\r
+  }\r
+\r
   if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
     SubmitForm (FormSet, Form, SettingLevel);\r
   }\r
@@ -2100,18 +2226,18 @@ ProcessCallBackFunction (
 \r
 /**\r
   Call the retrieve type call back function for one question to get the initialize data.\r
-  \r
-  This function only used when in the initialize stage, because in this stage, the \r
+\r
+  This function only used when in the initialize stage, because in this stage, the\r
   Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.\r
 \r
   @param ConfigAccess          The config access protocol produced by the hii driver.\r
   @param Statement             The Question which need to call.\r
   @param FormSet               The formset this question belong to.\r
 \r
-  @retval EFI_SUCCESS          The call back function excutes successfully.\r
-  @return Other value if the call back function failed to excute.  \r
+  @retval EFI_SUCCESS          The call back function executes successfully.\r
+  @return Other value if the call back function failed to execute.\r
 **/\r
-EFI_STATUS \r
+EFI_STATUS\r
 ProcessRetrieveForQuestion (\r
   IN     EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess,\r
   IN     FORM_BROWSER_STATEMENT          *Statement,\r
@@ -2139,7 +2265,7 @@ ProcessRetrieveForQuestion (
     //\r
     TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
   }\r
-    \r
+\r
   ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
   Status = ConfigAccess->Callback (\r
                            ConfigAccess,\r
@@ -2155,6 +2281,7 @@ ProcessRetrieveForQuestion (
 \r
     ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
     if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
+      ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
       CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
     } else {\r
       CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
@@ -2222,9 +2349,15 @@ SetupBrowser (
   mCurFakeQestId = 0;\r
 \r
   do {\r
+\r
+    //\r
+    // Reset Status to prevent the next break from returning incorrect error status.\r
+    //\r
+    Status = EFI_SUCCESS;\r
+\r
     //\r
     // IFR is updated, force to reparse the IFR binary\r
-    // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and \r
+    // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and\r
     // EFI_BROWSER_ACTION_RETRIEVE, so code place here.\r
     //\r
     if (mHiiPackageListUpdated) {\r
@@ -2262,7 +2395,7 @@ SetupBrowser (
     if (Selection->Form->SuppressExpression != NULL) {\r
       if (EvaluateExpressionList(Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {\r
         //\r
-        // Form is suppressed. \r
+        // Form is suppressed.\r
         //\r
         PopupErrorMessage(BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
         Status = EFI_NOT_FOUND;\r
@@ -2351,8 +2484,8 @@ SetupBrowser (
     //\r
     Statement = Selection->Statement;\r
     if (Statement != NULL) {\r
-      if ((ConfigAccess != NULL) && \r
-          ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
+      if ((ConfigAccess != NULL) &&\r
+          ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&\r
           (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
         Status = ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
         if (Statement->Operand == EFI_IFR_REF_OP) {\r
@@ -2362,31 +2495,35 @@ SetupBrowser (
           if (!EFI_ERROR (Status)) {\r
             Status = ProcessGotoOpCode(Statement, Selection);\r
           }\r
-          \r
+\r
           //\r
           // Callback return error status or status return from process goto opcode.\r
           //\r
           if (EFI_ERROR (Status)) {\r
             //\r
-            // Cross reference will not be taken\r
+            // Cross reference will not be taken, restore all essential field\r
             //\r
-            Selection->FormId = Selection->Form->FormId;\r
+            Selection->Handle = mCurrentHiiHandle;\r
+            CopyMem (&Selection->FormSetGuid, &mCurrentFormSetGuid, sizeof (EFI_GUID));\r
+            Selection->FormId = mCurrentFormId;\r
             Selection->QuestionId = 0;\r
+            Selection->Action = UI_ACTION_REFRESH_FORM;\r
           }\r
         }\r
 \r
-        //\r
-        // Verify whether question value has checked, update the ValueChanged flag in Question.\r
-        //\r
-        IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
 \r
-        if (!EFI_ERROR (Status) && \r
-            (Statement->Operand != EFI_IFR_REF_OP) && \r
+        if (!EFI_ERROR (Status) &&\r
+            (Statement->Operand != EFI_IFR_REF_OP) &&\r
             ((Statement->Storage == NULL) || (Statement->Storage != NULL && Statement->ValueChanged))) {\r
           //\r
           // Only question value has been changed, browser will trig CHANGED callback.\r
           //\r
           ProcessCallBackFunction(Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+          //\r
+          //check whether the question value changed compared with buffer value\r
+          //if doesn't change ,set the ValueChanged flag to FALSE ,in order not to display the "configuration changed "information on the screen\r
+          //\r
+          IsQuestionValueChanged(gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
         }\r
       } else {\r
         //\r
@@ -2403,13 +2540,19 @@ SetupBrowser (
       }\r
 \r
       //\r
-      // If question has EFI_IFR_FLAG_RESET_REQUIRED flag and without storage and process question success till here, \r
-      // trig the gResetFlag.\r
+      // If question has EFI_IFR_FLAG_RESET_REQUIRED/EFI_IFR_FLAG_RECONNECT_REQUIRED flag and without storage\r
+      // and process question success till here, trig the gResetFlag/gFlagReconnect.\r
       //\r
-      if ((Status == EFI_SUCCESS) && \r
-          (Statement->Storage == NULL) && \r
-          ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {\r
-        gResetRequired = TRUE;\r
+      if ((Status == EFI_SUCCESS) &&\r
+          (Statement->Storage == NULL)) {\r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {\r
+          gResetRequiredFormLevel = TRUE;\r
+          gResetRequiredSystemLevel = TRUE;\r
+        }\r
+\r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {\r
+          gFlagReconnect = TRUE;\r
+        }\r
       }\r
     }\r
 \r
@@ -2438,8 +2581,8 @@ SetupBrowser (
     // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
     // for each question with callback flag.\r
     //\r
-    if ((ConfigAccess != NULL) && \r
-        ((Selection->Action == UI_ACTION_EXIT) || \r
+    if ((ConfigAccess != NULL) &&\r
+        ((Selection->Action == UI_ACTION_EXIT) ||\r
          (Selection->Handle != mCurrentHiiHandle) ||\r
          (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
          (Selection->FormId != mCurrentFormId))) {\r