]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
1. Support inconsistent if opcode used in string/password opcode.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
index 93267f0fdeecfce49ad10287fa1769be543eea80..6d9a555b4920c1e33b88f6102a0215d47f835485 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
 Utility functions for UI presentation.\r
 \r
-Copyright (c) 2004 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<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
 http://opensource.org/licenses/bsd-license.php\r
@@ -13,11 +13,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "Setup.h"\r
-#include "Ui.h"\r
 \r
 BOOLEAN            mHiiPackageListUpdated;\r
 UI_MENU_SELECTION  *gCurrentSelection;\r
-\r
+EFI_HII_HANDLE     mCurrentHiiHandle = NULL;\r
+EFI_GUID           mCurrentFormSetGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+UINT16             mCurrentFormId = 0;\r
 \r
 /**\r
   Clear retangle with specified text attribute.\r
@@ -110,6 +111,8 @@ NewStrCat (
   hit, then 2 Unicode character will consume an output storage\r
   space with size of CHAR16 till a NARROW_CHAR is hit.\r
 \r
+  If String is NULL, then ASSERT ().\r
+\r
   @param String          The input string to be counted.\r
 \r
   @return Storage space for the input string.\r
@@ -124,6 +127,11 @@ GetStringWidth (
   UINTN Count;\r
   UINTN IncrementValue;\r
 \r
+  ASSERT (String != NULL);\r
+  if (String == NULL) {\r
+    return 0;\r
+  }\r
+\r
   Index           = 0;\r
   Count           = 0;\r
   IncrementValue  = 1;\r
@@ -209,7 +217,7 @@ DisplayPageFrame (
     Buffer[Index] = Character;\r
   }\r
 \r
-  if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
     //\r
     //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);\r
     //\r
@@ -290,7 +298,7 @@ DisplayPageFrame (
     KEYHELP_TEXT | KEYHELP_BACKGROUND\r
     );\r
 \r
-  if (gClassOfVfr != FORMSET_CLASS_FRONT_PAGE) {\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
     ClearLines (\r
       LocalScreen.LeftColumn,\r
       LocalScreen.RightColumn,\r
@@ -325,7 +333,7 @@ DisplayPageFrame (
     Character = BOXDRAW_UP_LEFT;\r
     PrintChar (Character);\r
 \r
-    if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
+    if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
       //\r
       // Print Bottom border line\r
       // +------------------------------------------------------------------------------+\r
@@ -388,9 +396,11 @@ EvaluateFormExpressions (
     Link = GetNextNode (&Form->ExpressionListHead, Link);\r
 \r
     if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||\r
-        Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
+        Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||\r
+        Expression->Type == EFI_HII_EXPRESSION_WRITE ||\r
+        (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {\r
       //\r
-      // Postpone Form validation to Question editing or Form submiting\r
+      // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.\r
       //\r
       continue;\r
     }\r
@@ -473,7 +483,7 @@ DisplayForm (
 \r
   StringPtr = GetToken (Selection->Form->FormTitle, Handle);\r
 \r
-  if (gClassOfVfr != FORMSET_CLASS_FRONT_PAGE) {\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
     gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
     PrintStringAt (\r
       (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,\r
@@ -591,6 +601,7 @@ InitializeBrowserStrings (
   gAdjustNumber         = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);\r
   gSaveChanges          = GetToken (STRING_TOKEN (SAVE_CHANGES), gHiiHandle);\r
   gOptionMismatch       = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);\r
+  gFormSuppress         = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);\r
   return ;\r
 }\r
 \r
@@ -632,6 +643,7 @@ FreeBrowserStrings (
   FreePool (gAdjustNumber);\r
   FreePool (gSaveChanges);\r
   FreePool (gOptionMismatch);\r
+  FreePool (gFormSuppress);\r
   return ;\r
 }\r
 \r
@@ -684,7 +696,7 @@ UpdateKeyHelp (
     ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
 \r
     if (!Selected) {\r
-      if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
+      if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
         if (Selection->FormEditable) {\r
           PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
           PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
@@ -741,7 +753,7 @@ UpdateKeyHelp (
   case EFI_IFR_CHECKBOX_OP:\r
     ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
 \r
-    if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
+    if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
       if (Selection->FormEditable) {\r
         PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
         PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
@@ -762,7 +774,7 @@ UpdateKeyHelp (
     ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
 \r
     if (!Selected) {\r
-      if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
+      if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
         if (Selection->FormEditable) {\r
           PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
           PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
@@ -855,13 +867,17 @@ SetupBrowser (
   EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
   EFI_HANDLE                      NotifyHandle;\r
   EFI_HII_VALUE                   *HiiValue;\r
+  EFI_IFR_TYPE_VALUE              *TypeValue;\r
   FORM_BROWSER_STATEMENT          *Statement;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
   FORM_BROWSER_FORMSET            *FormSet;\r
+  EFI_INPUT_KEY                   Key;\r
+  BOOLEAN                         SubmitFormIsRequired;\r
 \r
   gMenuRefreshHead = NULL;\r
   gResetRequired = FALSE;\r
   FormSet = Selection->FormSet;\r
+  ConfigAccess = Selection->FormSet->ConfigAccess;\r
 \r
   //\r
   // Register notify for Form package update\r
@@ -878,58 +894,11 @@ SetupBrowser (
     return Status;\r
   }\r
 \r
-  //\r
-  // Before display the formset, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
-  //\r
-  ConfigAccess = Selection->FormSet->ConfigAccess;\r
-  if ((ConfigAccess != NULL) && (Selection->Action != UI_ACTION_REFRESH_FORMSET)) {\r
-    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
-    mHiiPackageListUpdated = FALSE;\r
-    Status = ConfigAccess->Callback (\r
-                             ConfigAccess,\r
-                             EFI_BROWSER_ACTION_FORM_OPEN,\r
-                             0,\r
-                             EFI_IFR_TYPE_UNDEFINED,\r
-                             NULL,\r
-                             &ActionRequest\r
-                             );\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
-        //\r
-        // Till now there is no uncommitted data, so ignore this request\r
-        //\r
-        break;\r
-\r
-      case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
-        Selection->Action = UI_ACTION_EXIT;\r
-        break;\r
-\r
-      default:\r
-        break;\r
-      }\r
-    }\r
-\r
-    if (mHiiPackageListUpdated) {\r
-      //\r
-      // IFR is updated during callback, force to reparse the IFR binary\r
-      //\r
-      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
-      goto Done;\r
-    }\r
-  }\r
-\r
   //\r
   // Initialize current settings of Questions in this FormSet\r
   //\r
   Status = InitializeCurrentSetting (Selection->FormSet);\r
   if (EFI_ERROR (Status)) {\r
-    Selection->Action = UI_ACTION_EXIT;\r
     goto Done;\r
   }\r
 \r
@@ -953,15 +922,150 @@ SetupBrowser (
       //\r
       // No Form to display\r
       //\r
-      return EFI_NOT_FOUND;\r
+      Status = EFI_NOT_FOUND;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Check Form is suppressed.\r
+    //\r
+    if (Selection->Form->SuppressExpression != NULL) {\r
+      Status = EvaluateExpression (Selection->FormSet, Selection->Form, Selection->Form->SuppressExpression);\r
+      if (EFI_ERROR (Status) || (Selection->Form->SuppressExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN)) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        goto Done;\r
+      }\r
+\r
+      if (Selection->Form->SuppressExpression->Result.Value.b) {\r
+        //\r
+        // Form is suppressed. \r
+        //\r
+        do {\r
+          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);\r
+        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+        Status = EFI_NOT_FOUND;\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Reset FormPackage update flag\r
+    //\r
+    mHiiPackageListUpdated = FALSE;\r
+\r
+    //\r
+    // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
+    // for each question with callback flag.\r
+    // New form may be the first form, or the different form after another form close.\r
+    //\r
+    if ((ConfigAccess != NULL) &&\r
+        ((Selection->Handle != mCurrentHiiHandle) ||\r
+        (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+        (Selection->FormId != mCurrentFormId))) {\r
+\r
+      //\r
+      // Keep current form information\r
+      //\r
+      mCurrentHiiHandle   = Selection->Handle;\r
+      CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
+      mCurrentFormId      = Selection->FormId;\r
+\r
+      //\r
+      // Go through each statement in this form\r
+      //\r
+      SubmitFormIsRequired = FALSE;\r
+      Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+      while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+        Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+        Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+        \r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Check whether Statement is disabled.\r
+        //\r
+        if (Statement->DisableExpression != NULL) {\r
+          Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression);\r
+          if (!EFI_ERROR (Status) && \r
+              (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && \r
+              (Statement->DisableExpression->Result.Value.b)) {\r
+            continue;\r
+          }\r
+        }\r
+\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_FORM_OPEN,\r
+                                 Statement->QuestionId,\r
+                                 EFI_IFR_TYPE_UNDEFINED,\r
+                                 NULL,\r
+                                 &ActionRequest\r
+                                 );\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
+            SubmitFormIsRequired = TRUE;\r
+            break;\r
+\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
+\r
+          default:\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (SubmitFormIsRequired) {\r
+        SubmitForm (Selection->FormSet, Selection->Form);\r
+      }\r
+      //\r
+      // EXIT requests to close form.\r
+      //\r
+      if (Selection->Action == UI_ACTION_EXIT) {\r
+        goto Done;\r
+      }\r
+      //\r
+      // IFR is updated during callback of open form, force to reparse the IFR binary\r
+      //\r
+      if (mHiiPackageListUpdated) {\r
+        Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+        mHiiPackageListUpdated = FALSE;\r
+        goto Done;\r
+      }\r
     }\r
 \r
     //\r
     // Load Questions' Value for display\r
     //\r
-    Status = LoadFormSetConfig (Selection->FormSet);\r
+    Status = LoadFormSetConfig (Selection, Selection->FormSet);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // EXIT requests to close form.\r
+    //\r
+    if (Selection->Action == UI_ACTION_EXIT) {\r
+      goto Done;\r
+    }\r
+    //\r
+    // IFR is updated during callback of read value, force to reparse the IFR binary\r
+    //\r
+    if (mHiiPackageListUpdated) {\r
+      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+      mHiiPackageListUpdated = FALSE;\r
+      goto Done;\r
     }\r
 \r
     //\r
@@ -974,7 +1078,7 @@ SetupBrowser (
     //\r
     Status = DisplayForm (Selection);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
 \r
     //\r
@@ -991,36 +1095,30 @@ SetupBrowser (
       //\r
       mHiiPackageListUpdated = FALSE;\r
 \r
-      if (((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
+      if ((ConfigAccess != NULL) && \r
+          ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
+          (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
+\r
         ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
 \r
         HiiValue = &Statement->HiiValue;\r
-        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+        TypeValue = &HiiValue->Value;\r
+        if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
           //\r
-          // Create String in HII database for Configuration Driver to retrieve\r
+          // For OrderedList, passing in the value buffer to Callback()\r
           //\r
-          HiiValue->Value.string = NewString ((CHAR16 *) Statement->BufferValue, Selection->FormSet->HiiHandle);\r
+          TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
         }\r
 \r
-        if (ConfigAccess == NULL) {\r
-          return EFI_UNSUPPORTED;\r
-        }\r
         Status = ConfigAccess->Callback (\r
                                  ConfigAccess,\r
                                  EFI_BROWSER_ACTION_CHANGING,\r
                                  Statement->QuestionId,\r
                                  HiiValue->Type,\r
-                                 &HiiValue->Value,\r
+                                 TypeValue,\r
                                  &ActionRequest\r
                                  );\r
 \r
-        if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
-          //\r
-          // Clean the String in HII Database\r
-          //\r
-          DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);\r
-        }\r
-\r
         if (!EFI_ERROR (Status)) {\r
           switch (ActionRequest) {\r
           case EFI_BROWSER_ACTION_REQUEST_RESET:\r
@@ -1060,44 +1158,68 @@ SetupBrowser (
         //\r
         // Force to reparse IFR binary of target Formset\r
         //\r
+        mHiiPackageListUpdated = FALSE;\r
         Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
       }\r
     }\r
-  } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
 \r
-  //\r
-  // Before exit the formset, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
-  //\r
-  if ((ConfigAccess != NULL) && (Selection->Action == UI_ACTION_EXIT)) {\r
-    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
-    Status = ConfigAccess->Callback (\r
-                             ConfigAccess,\r
-                             EFI_BROWSER_ACTION_FORM_CLOSE,\r
-                             0,\r
-                             EFI_IFR_TYPE_UNDEFINED,\r
-                             NULL,\r
-                             &ActionRequest\r
-                             );\r
-\r
-    if (!EFI_ERROR (Status)) {\r
-      switch (ActionRequest) {\r
-      case EFI_BROWSER_ACTION_REQUEST_RESET:\r
-        gResetRequired = TRUE;\r
-        break;\r
+    //\r
+    // 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
+         (Selection->Handle != mCurrentHiiHandle) ||\r
+         (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+         (Selection->FormId != mCurrentFormId))) {\r
+      //\r
+      // Go through each statement in this form\r
+      //\r
+      SubmitFormIsRequired = FALSE;\r
+      Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+      while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+        Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+        Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+        \r
+        if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+          continue;\r
+        }\r
 \r
-      case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
-        SubmitForm (Selection->FormSet, Selection->Form);\r
-        break;\r
+        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+        Status = ConfigAccess->Callback (\r
+                                 ConfigAccess,\r
+                                 EFI_BROWSER_ACTION_FORM_CLOSE,\r
+                                 Statement->QuestionId,\r
+                                 EFI_IFR_TYPE_UNDEFINED,\r
+                                 NULL,\r
+                                 &ActionRequest\r
+                                 );\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
+            SubmitFormIsRequired = TRUE;\r
+            break;\r
 \r
-      case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
-        gNvUpdateRequired = FALSE;\r
-        break;\r
+          case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+            Selection->Action = UI_ACTION_EXIT;\r
+            gNvUpdateRequired = FALSE;\r
+            break;\r
 \r
-      default:\r
-        break;\r
+          default:\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      if (SubmitFormIsRequired) {\r
+        SubmitForm (Selection->FormSet, Selection->Form);\r
       }\r
     }\r
-  }\r
+  } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
 \r
   //\r
   // Record the old formset\r
@@ -1108,12 +1230,21 @@ SetupBrowser (
   gOldFormSet = FormSet;\r
 \r
 Done:\r
+  //\r
+  // Reset current form information to the initial setting when error happens or form exit.\r
+  //\r
+  if (EFI_ERROR (Status) || Selection->Action == UI_ACTION_EXIT) {\r
+    mCurrentHiiHandle = NULL;\r
+    CopyGuid (&mCurrentFormSetGuid, &gZeroGuid);\r
+    mCurrentFormId = 0;\r
+  }\r
+\r
   //\r
   // Unregister notify for Form package update\r
   //\r
-  Status = mHiiDatabase->UnregisterPackageNotify (\r
-                           mHiiDatabase,\r
-                           NotifyHandle\r
-                           );\r
+  mHiiDatabase->UnregisterPackageNotify (\r
+                   mHiiDatabase,\r
+                   NotifyHandle\r
+                   );\r
   return Status;\r
 }\r