]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add new call back return value; also add some sample code to use it.
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 31 May 2011 00:59:15 +0000 (00:59 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 31 May 2011 00:59:15 +0000 (00:59 +0000)
Signed-off-by: ydong10
Reviewed-by: lgao4
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11713 6f19259b-4bc3-4df7-8a09-765794883524

12 files changed:
MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr
MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni
MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
MdeModulePkg/Universal/SetupBrowserDxe/Ui.h

index 9751242fd2a29c68b52a542fc748c4bf671fd706..9f78db28542c9533884db5a2c043118936feadfa 100644 (file)
@@ -2,7 +2,7 @@
 This is an example of how a driver might export data to the HII protocol to be\r
 later utilized by the Setup Protocol\r
 \r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2011, 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
@@ -587,7 +587,7 @@ AppendAltCfgString (
     StringPtr += StrLen (L"&VALUE=");\r
 \r
     //\r
-    // Get Width\r
+    // Get Value\r
     //\r
     Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
     if (EFI_ERROR (Status)) {\r
@@ -1501,6 +1501,34 @@ DriverCallback (
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
       break;\r
 \r
+    case 0x1241:\r
+      //\r
+      // User press "Submit current form and Exit now", request Browser to submit current form and exit\r
+      //\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
+      break;\r
+\r
+    case 0x1242:\r
+      //\r
+      // User press "Discard current form now", request Browser to discard the uncommitted data.\r
+      //\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;\r
+      break;\r
+\r
+    case 0x1243:\r
+      //\r
+      // User press "Submit current form now", request Browser to save the uncommitted data.\r
+      //\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+      break;\r
+\r
+    case 0x1244:\r
+      //\r
+      // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.\r
+      //\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+      break;\r
+\r
     case 0x2000:\r
       //\r
       // Only used to update the state.\r
index fce22fef2fcfdc8234664aed79992b2fd0eb213a..26d29e381375ff71051dc0933c89c10f74e7312a 100644 (file)
@@ -2,7 +2,7 @@
 //\r
 //    Sample Setup formset.\r
 //\r
-//  Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+//  Copyright (c) 2004 - 2011, 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
@@ -141,6 +141,19 @@ formset
       flags  = INTERACTIVE,\r
       key    = 0x1238;\r
 \r
+    text\r
+      help   = STRING_TOKEN(STR_SAVE_CURRENT),\r
+      text   = STRING_TOKEN(STR_SAVE_CURRENT),\r
+        text   = STRING_TOKEN(STR_SAVE_CURRENT),\r
+      flags  = INTERACTIVE,\r
+      key    = 0x1243;\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT),\r
+      text   = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT),\r
+        text   = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT),\r
+      flags  = INTERACTIVE,\r
+      key    = 0x1244;\r
     //\r
     // Define oneof (EFI_IFR_ONE_OF)\r
     //\r
@@ -530,6 +543,20 @@ formset
 \r
       enddate;\r
 \r
+      text\r
+        help   = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT),\r
+        text   = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT),\r
+          text   = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT),\r
+        flags  = INTERACTIVE,\r
+        key    = 0x1241;\r
+\r
+      text\r
+        help   = STRING_TOKEN(STR_DISCARD_CURRENT),\r
+        text   = STRING_TOKEN(STR_DISCARD_CURRENT),\r
+          text   = STRING_TOKEN(STR_DISCARD_CURRENT),\r
+        flags  = INTERACTIVE,\r
+        key    = 0x1242;\r
+\r
       time    hour varid  = Time.Hours,         // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from\r
               prompt      = STRING_TOKEN(STR_TIME_PROMPT),\r
               help        = STRING_TOKEN(STR_TIME_HELP),\r
index 1901fd8d2e010d9d43e4c7a31b59b9f261503551..8bd34469a204012b5510150d72d7cfb6facff7f4 100644 (file)
Binary files a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni and b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni differ
index a50ef5ca7361f03d04164e08c7181aeed2d93efc..5d0339a0402487cc9931b324589fc747481473c0 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Utility functions for expression evaluation.\r
 \r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2011, 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
@@ -2138,7 +2138,7 @@ EvaluateExpression (
             for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
               StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
             }\r
-            Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue);\r
+            Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, TRUE);\r
             FreePool (NameValue);\r
             if (!EFI_ERROR (Status)) {\r
               Data1.Value.b = TRUE;\r
index ef862e4e985531dcbe107720e65d1dc88f7cda75..564a246a1b1c5e4b3ca2b60c635fb668964b532c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Parser for IFR binary encoding.\r
 \r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2011, 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
@@ -357,6 +357,7 @@ InitializeConfigHdr (
 \r
   @param  FormSet                Pointer of the current FormSet.\r
   @param  Question               The Question to be initialized.\r
+  @param  Form                   Pointer of the current form.\r
 \r
   @retval EFI_SUCCESS            Function success.\r
   @retval EFI_INVALID_PARAMETER  No storage associated with the Question.\r
@@ -365,7 +366,8 @@ InitializeConfigHdr (
 EFI_STATUS\r
 InitializeRequestElement (\r
   IN OUT FORM_BROWSER_FORMSET     *FormSet,\r
-  IN OUT FORM_BROWSER_STATEMENT   *Question\r
+  IN OUT FORM_BROWSER_STATEMENT   *Question,\r
+  IN OUT FORM_BROWSER_FORM        *Form\r
   )\r
 {\r
   FORMSET_STORAGE  *Storage;\r
@@ -373,6 +375,9 @@ InitializeRequestElement (
   UINTN            StringSize;\r
   CHAR16           *NewStr;\r
   CHAR16           RequestElement[30];\r
+  LIST_ENTRY       *Link;\r
+  BOOLEAN          Find;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   Storage = Question->Storage;\r
   if (Storage == NULL) {\r
@@ -433,6 +438,53 @@ InitializeRequestElement (
   Storage->ElementCount++;\r
   Storage->SpareStrLen -= StrLen;\r
 \r
+  //\r
+  // Update the Config Request info saved in the form.\r
+  //\r
+  ConfigInfo = NULL;\r
+  Find       = FALSE;\r
+  Link = GetFirstNode (&Form->ConfigRequestHead);\r
+  while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+\r
+    if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) {\r
+      Find = TRUE;\r
+      break;\r
+    }\r
+\r
+    Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+  }\r
+\r
+  if (!Find) {\r
+    ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));\r
+    ConfigInfo->Signature     = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;\r
+    ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);\r
+    ConfigInfo->SpareStrLen   = 0;\r
+    ConfigInfo->Storage       = Storage;\r
+    InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);\r
+  }\r
+\r
+  //\r
+  // Append <RequestElement> to <ConfigRequest>\r
+  //\r
+  if (StrLen > ConfigInfo->SpareStrLen) {\r
+    //\r
+    // Old String buffer is not sufficient for RequestElement, allocate a new one\r
+    //\r
+    StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);\r
+    NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
+    ASSERT (NewStr != NULL);\r
+    if (ConfigInfo->ConfigRequest != NULL) {\r
+      CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);\r
+      FreePool (ConfigInfo->ConfigRequest);\r
+    }\r
+    ConfigInfo->ConfigRequest = NewStr;\r
+    ConfigInfo->SpareStrLen   = CONFIG_REQUEST_STRING_INCREMENTAL;\r
+  }\r
+\r
+  StrCat (ConfigInfo->ConfigRequest, RequestElement);\r
+  ConfigInfo->ElementCount++;\r
+  ConfigInfo->SpareStrLen -= StrLen;\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -632,6 +684,7 @@ DestroyForm (
   LIST_ENTRY              *Link;\r
   FORM_EXPRESSION         *Expression;\r
   FORM_BROWSER_STATEMENT  *Statement;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   //\r
   // Free Form Expressions\r
@@ -655,6 +708,18 @@ DestroyForm (
     DestroyStatement (FormSet, Statement);\r
   }\r
 \r
+  //\r
+  // Free ConfigRequest string.\r
+  //\r
+  while (!IsListEmpty (&Form->ConfigRequestHead)) {\r
+    Link = GetFirstNode (&Form->ConfigRequestHead);\r
+    ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+    RemoveEntryList (&ConfigInfo->Link);\r
+\r
+    FreePool (ConfigInfo->ConfigRequest);\r
+    FreePool (ConfigInfo);\r
+  }\r
+\r
   //\r
   // Free this Form\r
   //\r
@@ -1273,8 +1338,10 @@ ParseOpCodes (
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
+      InitializeListHead (&CurrentForm->ConfigRequestHead);\r
 \r
       CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
+      CurrentForm->NvUpdateRequired = FALSE;\r
       CopyMem (&CurrentForm->FormId,    &((EFI_IFR_FORM *) OpCodeData)->FormId,    sizeof (UINT16));\r
       CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
 \r
@@ -1305,8 +1372,10 @@ ParseOpCodes (
       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
       ASSERT (CurrentForm != NULL);\r
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+      CurrentForm->NvUpdateRequired = FALSE;\r
       InitializeListHead (&CurrentForm->ExpressionListHead);\r
       InitializeListHead (&CurrentForm->StatementListHead);\r
+      InitializeListHead (&CurrentForm->ConfigRequestHead);\r
       CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
 \r
       MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
@@ -1538,7 +1607,7 @@ ParseOpCodes (
         break;\r
       }\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
 \r
       if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
         SuppressForOption = TRUE;\r
@@ -1568,7 +1637,7 @@ ParseOpCodes (
       CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
 \r
       break;\r
 \r
@@ -1589,7 +1658,7 @@ ParseOpCodes (
       CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       break;\r
 \r
     case EFI_IFR_PASSWORD_OP:\r
@@ -1608,7 +1677,7 @@ ParseOpCodes (
       CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
       CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
 \r
-      InitializeRequestElement (FormSet, CurrentStatement);\r
+      InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       break;\r
 \r
     case EFI_IFR_DATE_OP:\r
@@ -1621,7 +1690,7 @@ ParseOpCodes (
       if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r
 \r
-        InitializeRequestElement (FormSet, CurrentStatement);\r
+        InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       } else {\r
         //\r
         // Don't assign storage for RTC type of date/time\r
@@ -1641,7 +1710,7 @@ ParseOpCodes (
       if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
         CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r
 \r
-        InitializeRequestElement (FormSet, CurrentStatement);\r
+        InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       } else {\r
         //\r
         // Don't assign storage for RTC type of date/time\r
@@ -1740,7 +1809,7 @@ ParseOpCodes (
         CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
         CurrentStatement->ValueType = CurrentOption->Value.Type;\r
 \r
-        InitializeRequestElement (FormSet, CurrentStatement);\r
+        InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
       }\r
       break;\r
 \r
index 360a6d75ecff552d852d05298d4f1558488aa121..eee8eed24489a2913887657ddab79eb623bbb950 100644 (file)
@@ -637,7 +637,7 @@ EnterCarriageReturn:
           //\r
           // NV flag is unnecessary for RTC type of Date/Time\r
           //\r
-          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
         }\r
       }\r
 \r
@@ -653,7 +653,7 @@ EnterCarriageReturn:
         // Remove a character\r
         //\r
         EditValue = PreviousNumber[Count - 1];\r
-        UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE);\r
+        UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);\r
         Count--;\r
         Column--;\r
         PrintAt (Column, Row, L" ");\r
@@ -670,12 +670,12 @@ EnterCarriageReturn:
           } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {\r
             Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A);\r
           } else {\r
-            UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+            UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
             break;\r
           }\r
         } else {\r
           if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {\r
-            UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+            UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
             break;\r
           }\r
         }\r
@@ -704,12 +704,12 @@ EnterCarriageReturn:
         }\r
 \r
         if (EditValue > Maximum) {\r
-          UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE);\r
+          UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);\r
           ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0]));\r
           EditValue = PreviousNumber[Count];\r
           break;\r
         } else {\r
-          UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE);\r
+          UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);\r
         }\r
 \r
         Count++;\r
@@ -1183,7 +1183,7 @@ TheKey:
         GetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
       } else {\r
         SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
-        UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+        UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
       }\r
 \r
       return Status;\r
index 8dc1651950745245d6a7cd2aee8828fd4975f07d..94ba2399507c9f3df520f4e46d98fc5474be6082 100644 (file)
@@ -847,6 +847,327 @@ FormUpdateNotify (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  check whether the formset need to update the NV.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+\r
+  @retval TRUE                   Need to update the NV.\r
+  @retval FALSE                  No need to update the NV.\r
+**/\r
+BOOLEAN \r
+IsNvUpdateRequired (\r
+  IN FORM_BROWSER_FORMSET  *FormSet\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_FORM       *Form;\r
+\r
+  Link = GetFirstNode (&FormSet->FormListHead);\r
+  while (!IsNull (&FormSet->FormListHead, Link)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+    if (Form->NvUpdateRequired ) {\r
+      return TRUE;\r
+    }\r
+\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  check whether the formset need to update the NV.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  SetValue               Whether set new value or clear old value.\r
+\r
+**/\r
+VOID\r
+UpdateNvInfoInForm (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN BOOLEAN               SetValue\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORM_BROWSER_FORM       *Form;\r
+  \r
+  Link = GetFirstNode (&FormSet->FormListHead);\r
+  while (!IsNull (&FormSet->FormListHead, Link)) {\r
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+    Form->NvUpdateRequired = SetValue;\r
+\r
+    Link = GetNextNode (&FormSet->FormListHead, Link);\r
+  }\r
+}\r
+/**\r
+  Find menu which will show next time.\r
+\r
+  @param Selection       On input, Selection tell setup browser the information\r
+                         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 Repaint         Whether need to repaint the menu.\r
+  @param NewLine         Whether need to show at new line.\r
+  \r
+  @retval TRUE           Need return.\r
+  @retval FALSE          No need to return.\r
+**/\r
+BOOLEAN\r
+FindNextMenu (\r
+  IN OUT UI_MENU_SELECTION    *Selection,\r
+  IN     BOOLEAN              *Repaint, \r
+  IN     BOOLEAN              *NewLine  \r
+  )\r
+{\r
+  UI_MENU_LIST            *CurrentMenu;\r
+  CHAR16                  YesResponse;\r
+  CHAR16                  NoResponse;\r
+  EFI_INPUT_KEY           Key;\r
+  EFI_STATUS              Status;\r
+  \r
+  CurrentMenu = Selection->CurrentMenu;\r
+\r
+  if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {\r
+    //\r
+    // we have a parent, so go to the parent menu\r
+    //\r
+    if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {\r
+      //\r
+      // The parent menu and current menu are in the same formset\r
+      //\r
+      Selection->Action = UI_ACTION_REFRESH_FORM;\r
+    } else {\r
+      Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+    }\r
+    Selection->Statement = NULL;\r
+\r
+    Selection->FormId = CurrentMenu->Parent->FormId;\r
+    Selection->QuestionId = CurrentMenu->Parent->QuestionId;\r
+\r
+    //\r
+    // Clear highlight record for this menu\r
+    //\r
+    CurrentMenu->QuestionId = 0;\r
+    return FALSE;\r
+  }\r
+\r
+  if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
+    //\r
+    // We never exit FrontPage, so skip the ESC\r
+    //\r
+    Selection->Action = UI_ACTION_NONE;\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // We are going to leave current FormSet, so check uncommited data in this FormSet\r
+  //\r
+  if (IsNvUpdateRequired(Selection->FormSet)) {\r
+    Status      = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+\r
+    YesResponse = gYesResponse[0];\r
+    NoResponse  = gNoResponse[0];\r
+\r
+    //\r
+    // If NV flag is up, prompt user\r
+    //\r
+    do {\r
+      CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);\r
+    } while\r
+    (\r
+      (Key.ScanCode != SCAN_ESC) &&\r
+      ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
+      ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
+    );\r
+\r
+    if (Key.ScanCode == SCAN_ESC) {\r
+      //\r
+      // User hits the ESC key\r
+      //\r
+      if (Repaint != NULL) {\r
+        *Repaint = TRUE;\r
+      }\r
+\r
+      if (NewLine != NULL) {\r
+        *NewLine = TRUE;\r
+      }\r
+\r
+      Selection->Action = UI_ACTION_NONE;\r
+      return FALSE;\r
+    }\r
+\r
+    //\r
+    // If the user hits the YesResponse key\r
+    //\r
+    if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
+      Status = SubmitForm (Selection->FormSet, Selection->Form, FALSE);\r
+    }\r
+  }\r
+\r
+  Selection->Statement = NULL;\r
+  CurrentMenu->QuestionId = 0;  \r
+\r
+  Selection->Action = UI_ACTION_EXIT;\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Call the call back function for the question and process the return action.\r
+\r
+  @param Selection             On input, Selection tell setup browser the information\r
+                               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 Question              The Question which need to call.\r
+  @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
+**/\r
+EFI_STATUS \r
+ProcessCallBackFunction (\r
+  IN OUT UI_MENU_SELECTION               *Selection,\r
+  IN     FORM_BROWSER_STATEMENT          *Question,\r
+  IN     EFI_BROWSER_ACTION              Action,\r
+  IN     BOOLEAN                         SkipSaveOrDiscard\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_HII_VALUE                   *HiiValue;\r
+  EFI_IFR_TYPE_VALUE              *TypeValue;\r
+  FORM_BROWSER_STATEMENT          *Statement;\r
+  BOOLEAN                         SubmitFormIsRequired;\r
+  BOOLEAN                         SingleForm;\r
+  BOOLEAN                         DiscardFormIsRequired;\r
+  BOOLEAN                         NeedExit;\r
+  LIST_ENTRY                      *Link;\r
+\r
+  ConfigAccess = Selection->FormSet->ConfigAccess;\r
+  SubmitFormIsRequired  = FALSE;\r
+  SingleForm            = FALSE;\r
+  DiscardFormIsRequired = FALSE;\r
+  NeedExit              = FALSE;\r
+  Status                = EFI_SUCCESS;\r
+  ActionRequest         = EFI_BROWSER_ACTION_REQUEST_NONE;\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
+    Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+    Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+\r
+    //\r
+    // if Question != NULL, only process the question. Else, process all question in this form.\r
+    //\r
+    if ((Question != NULL) && (Statement != Question)) {\r
+      continue;\r
+    }\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
+    HiiValue = &Statement->HiiValue;\r
+    TypeValue = &HiiValue->Value;\r
+    if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+      //\r
+      // For OrderedList, passing in the value buffer to Callback()\r
+      //\r
+      TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
+    }\r
+      \r
+    ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+    Status = ConfigAccess->Callback (\r
+                             ConfigAccess,\r
+                             Action,\r
+                             Statement->QuestionId,\r
+                             HiiValue->Type,\r
+                             TypeValue,\r
+                             &ActionRequest\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
+        break;\r
+\r
+      case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:\r
+        SubmitFormIsRequired  = TRUE;\r
+        SingleForm            = TRUE;\r
+        NeedExit              = TRUE;\r
+        break;\r
+\r
+      case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:\r
+        DiscardFormIsRequired = TRUE;\r
+        SingleForm            = TRUE;      \r
+        NeedExit              = TRUE;\r
+        break;\r
+\r
+      case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY:\r
+        SubmitFormIsRequired  = TRUE;\r
+        SingleForm            = TRUE;\r
+        break;\r
+\r
+      case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD:\r
+        DiscardFormIsRequired = TRUE;\r
+        SingleForm            = TRUE;\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+    } else if (Status == EFI_UNSUPPORTED) {\r
+      //\r
+      // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
+      //\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
+    SubmitForm (Selection->FormSet, Selection->Form, SingleForm);\r
+  }\r
+\r
+  if (DiscardFormIsRequired && !SkipSaveOrDiscard) {\r
+    DiscardForm (Selection->FormSet, Selection->Form, SingleForm);\r
+  }\r
+\r
+  if (NeedExit) {\r
+    FindNextMenu (Selection, NULL, NULL);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   The worker function that send the displays to the screen. On output,\r
   the selection made by user is returned.\r
@@ -867,15 +1188,11 @@ SetupBrowser (
 {\r
   EFI_STATUS                      Status;\r
   LIST_ENTRY                      *Link;\r
-  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
@@ -974,69 +1291,11 @@ SetupBrowser (
       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
-        } else if (Status == EFI_UNSUPPORTED) {\r
-          //\r
-          // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
-          //\r
-          Status = EFI_SUCCESS;\r
-        }\r
-      }\r
-      if (SubmitFormIsRequired) {\r
-        SubmitForm (Selection->FormSet, Selection->Form);\r
+      Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
       }\r
+\r
       //\r
       // EXIT requests to close form.\r
       //\r
@@ -1107,45 +1366,8 @@ SetupBrowser (
           ((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
-        TypeValue = &HiiValue->Value;\r
-        if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
-          //\r
-          // For OrderedList, passing in the value buffer to Callback()\r
-          //\r
-          TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
-        }\r
-\r
-        Status = ConfigAccess->Callback (\r
-                                 ConfigAccess,\r
-                                 EFI_BROWSER_ACTION_CHANGING,\r
-                                 Statement->QuestionId,\r
-                                 HiiValue->Type,\r
-                                 TypeValue,\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
-            SubmitForm (Selection->FormSet, Selection->Form);\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
-        } else if (Status != EFI_UNSUPPORTED) {\r
+        Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);         \r
+        if ((EFI_ERROR (Status)) && (Status != EFI_UNSUPPORTED)) {\r
           //\r
           // Callback return error status other than EFI_UNSUPPORTED\r
           //\r
@@ -1156,11 +1378,6 @@ SetupBrowser (
             Selection->FormId = Selection->Form->FormId;\r
             Selection->QuestionId = 0;\r
           }\r
-        } else {\r
-          //\r
-          // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
-          //\r
-          Status = EFI_SUCCESS;\r
         }\r
       }\r
 \r
@@ -1185,56 +1402,10 @@ SetupBrowser (
          (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
-        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
-            Selection->Action = UI_ACTION_EXIT;\r
-            gNvUpdateRequired = FALSE;\r
-            break;\r
-\r
-          default:\r
-            break;\r
-          }\r
-        } else if (Status == EFI_UNSUPPORTED) {\r
-          //\r
-          // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
-          //\r
-          Status = EFI_SUCCESS;\r
-        }\r
-      }\r
-      if (SubmitFormIsRequired) {\r
-        SubmitForm (Selection->FormSet, Selection->Form);\r
+      Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
       }\r
     }\r
   } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
index 2e77522ca17f0efe2c6c1fe6e26e0dafc92b7ed6..aa57fe437c729d77e83baed67c6e0ba67648cbd1 100644 (file)
@@ -482,7 +482,7 @@ ProcessOptions (
           SetArrayData (ValueArray, ValueType, Index2, 0);\r
 \r
           Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
-          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
 \r
           FreePool (*OptionString);\r
           *OptionString = NULL;\r
@@ -550,7 +550,7 @@ ProcessOptions (
               !Option->SuppressExpression->Result.Value.b) {\r
             CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));\r
             SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
-            UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+            UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
             break;\r
           }\r
 \r
@@ -586,7 +586,7 @@ ProcessOptions (
             Suppress = FALSE;\r
             CopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));\r
             SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
-            UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+            UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
             gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);\r
             break;\r
           }\r
@@ -638,7 +638,7 @@ ProcessOptions (
       // Save Question value\r
       //\r
       Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
-      UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+      UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
     }\r
 \r
     if (QuestionValue->Value.b) {\r
@@ -751,7 +751,7 @@ ProcessOptions (
           CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));\r
           SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);\r
 \r
-          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
+          UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);\r
         }\r
       }\r
 \r
index 67a4aeb7ecc7097fc5bb382fb9b2df88390f0e80..0eaa78321fae30a32c02f6404fe4ae62b1e882ea 100644 (file)
@@ -35,7 +35,6 @@ EFI_HII_HANDLE        gFrontPageHandle;
 UINTN                 gClassOfVfr;\r
 UINTN                 gFunctionKeySetting;\r
 BOOLEAN               gResetRequired;\r
-BOOLEAN               gNvUpdateRequired;\r
 EFI_HII_HANDLE        gHiiHandle;\r
 UINT16                gDirection;\r
 EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
@@ -294,7 +293,6 @@ SendForm (
     }\r
 \r
     gOldFormSet = NULL;\r
-    gNvUpdateRequired = FALSE;\r
 \r
     do {\r
       FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));\r
@@ -471,7 +469,7 @@ BrowserCallback (
     //\r
     // Generate <ConfigResp>\r
     //\r
-    Status = StorageToConfigResp (Storage, &ConfigResp);\r
+    Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -810,6 +808,7 @@ GetValueByName (
   @param  Storage                The NameValue Storage.\r
   @param  Name                   The Name.\r
   @param  Value                  The Value to set.\r
+  @param  Edit                   Whether update editValue or Value.\r
 \r
   @retval EFI_SUCCESS            Value found for given Name.\r
   @retval EFI_NOT_FOUND          No such Name found in NameValue storage.\r
@@ -819,22 +818,34 @@ EFI_STATUS
 SetValueByName (\r
   IN FORMSET_STORAGE         *Storage,\r
   IN CHAR16                  *Name,\r
-  IN CHAR16                  *Value\r
+  IN CHAR16                  *Value,\r
+  IN BOOLEAN                 Edit\r
   )\r
 {\r
   LIST_ENTRY              *Link;\r
   NAME_VALUE_NODE         *Node;\r
+  CHAR16                  *Buffer;\r
 \r
   Link = GetFirstNode (&Storage->NameValueListHead);\r
   while (!IsNull (&Storage->NameValueListHead, Link)) {\r
     Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
 \r
     if (StrCmp (Name, Node->Name) == 0) {\r
-      if (Node->EditValue != NULL) {\r
-        FreePool (Node->EditValue);\r
+      if (Edit) {\r
+        Buffer = Node->EditValue;\r
+      } else {\r
+        Buffer = Node->Value;\r
+      }\r
+      if (Buffer != NULL) {\r
+        FreePool (Buffer);\r
+      }\r
+      Buffer = AllocateCopyPool (StrSize (Value), Value);\r
+      ASSERT (Buffer != NULL);\r
+      if (Edit) {\r
+        Node->EditValue = Buffer;\r
+      } else {\r
+        Node->Value = Buffer;\r
       }\r
-      Node->EditValue = AllocateCopyPool (StrSize (Value), Value);\r
-      ASSERT (Node->EditValue != NULL);\r
       return EFI_SUCCESS;\r
     }\r
 \r
@@ -848,8 +859,9 @@ SetValueByName (
 /**\r
   Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.\r
 \r
-  @param  Storage                The Storage to be conveted.\r
+  @param  Buffer                 The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
+  @param  SingleForm             Whether update data for single form or formset level.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
@@ -857,22 +869,34 @@ SetValueByName (
 **/\r
 EFI_STATUS\r
 StorageToConfigResp (\r
-  IN FORMSET_STORAGE         *Storage,\r
-  IN CHAR16                  **ConfigResp\r
+  IN VOID                    *Buffer,\r
+  IN CHAR16                  **ConfigResp,\r
+  IN BOOLEAN                 SingleForm\r
   )\r
 {\r
   EFI_STATUS  Status;\r
   EFI_STRING  Progress;\r
   LIST_ENTRY              *Link;\r
   NAME_VALUE_NODE         *Node;\r
+  CHAR16                  *ConfigRequest;\r
+  FORMSET_STORAGE         *Storage;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   Status = EFI_SUCCESS;\r
+  if (SingleForm) {\r
+    ConfigInfo    = (FORM_BROWSER_CONFIG_REQUEST *) Buffer;\r
+    Storage       = ConfigInfo->Storage;\r
+    ConfigRequest = ConfigInfo->ConfigRequest;\r
+  } else {\r
+    Storage       = (FORMSET_STORAGE *) Buffer;\r
+    ConfigRequest = Storage->ConfigRequest;\r
+  }\r
 \r
   switch (Storage->Type) {\r
   case EFI_HII_VARSTORE_BUFFER:\r
     Status = mHiiConfigRouting->BlockToConfig (\r
                                   mHiiConfigRouting,\r
-                                  Storage->ConfigRequest,\r
+                                  ConfigRequest,\r
                                   Storage->EditBuffer,\r
                                   Storage->Size,\r
                                   ConfigResp,\r
@@ -888,11 +912,12 @@ StorageToConfigResp (
     while (!IsNull (&Storage->NameValueListHead, Link)) {\r
       Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
 \r
-      NewStringCat (ConfigResp, L"&");\r
-      NewStringCat (ConfigResp, Node->Name);\r
-      NewStringCat (ConfigResp, L"=");\r
-      NewStringCat (ConfigResp, Node->EditValue);\r
-\r
+      if (StrStr (ConfigRequest, Node->Name) != NULL) {\r
+        NewStringCat (ConfigResp, L"&");\r
+        NewStringCat (ConfigResp, Node->Name);\r
+        NewStringCat (ConfigResp, L"=");\r
+        NewStringCat (ConfigResp, Node->EditValue);\r
+      }\r
       Link = GetNextNode (&Storage->NameValueListHead, Link);\r
     }\r
     break;\r
@@ -971,7 +996,7 @@ ConfigRespToStorage (
       if (StrPtr != NULL) {\r
         *StrPtr = 0;\r
       }\r
-      SetValueByName (Storage, Name, Value);\r
+      SetValueByName (Storage, Name, Value, TRUE);\r
     }\r
     break;\r
 \r
@@ -1322,7 +1347,7 @@ GetQuestionValue (
     if (IsBufferStorage) {\r
       CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);\r
     } else {\r
-      SetValueByName (Storage, Question->VariableName, Value);\r
+      SetValueByName (Storage, Question->VariableName, Value, TRUE);\r
     }\r
 \r
     FreePool (Result);\r
@@ -1520,7 +1545,7 @@ SetQuestionValue (
       }\r
     }\r
 \r
-    Status = SetValueByName (Storage, Question->VariableName, Value);\r
+    Status = SetValueByName (Storage, Question->VariableName, Value, TRUE);\r
     FreePool (Value);\r
   }\r
 \r
@@ -1682,6 +1707,7 @@ ValidateQuestion (
   Perform NoSubmit check for each Form in FormSet.\r
 \r
   @param  FormSet                FormSet data structure.\r
+  @param  CurrentForm            Current input form data structure.\r
 \r
   @retval EFI_SUCCESS            Form validation pass.\r
   @retval other                  Form validation failed.\r
@@ -1689,7 +1715,8 @@ ValidateQuestion (
 **/\r
 EFI_STATUS\r
 NoSubmitCheck (\r
-  IN  FORM_BROWSER_FORMSET            *FormSet\r
+  IN  FORM_BROWSER_FORMSET            *FormSet,\r
+  IN  FORM_BROWSER_FORM               *CurrentForm\r
   )\r
 {\r
   EFI_STATUS              Status;\r
@@ -1701,6 +1728,11 @@ NoSubmitCheck (
   LinkForm = GetFirstNode (&FormSet->FormListHead);\r
   while (!IsNull (&FormSet->FormListHead, LinkForm)) {\r
     Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);\r
+    LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);\r
+\r
+    if (CurrentForm != NULL && CurrentForm != Form) {\r
+      continue;\r
+    }\r
 \r
     Link = GetFirstNode (&Form->StatementListHead);\r
     while (!IsNull (&Form->StatementListHead, Link)) {\r
@@ -1713,19 +1745,219 @@ NoSubmitCheck (
 \r
       Link = GetNextNode (&Form->StatementListHead, Link);\r
     }\r
-\r
-    LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Restore Storage's Edit copy to Shadow copy.\r
+\r
+  @param  Storage                The Storage to be synchronized.\r
+\r
+**/\r
+VOID\r
+RestoreStorage (\r
+  IN FORMSET_STORAGE         *Storage\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  NAME_VALUE_NODE         *Node;\r
+\r
+  switch (Storage->Type) {\r
+  case EFI_HII_VARSTORE_BUFFER:\r
+    CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);\r
+    break;\r
+\r
+  case EFI_HII_VARSTORE_NAME_VALUE:\r
+    Link = GetFirstNode (&Storage->NameValueListHead);\r
+    while (!IsNull (&Storage->NameValueListHead, Link)) {\r
+      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
+\r
+      if (Node->EditValue != NULL) {\r
+        FreePool (Node->EditValue);\r
+      }\r
+      Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value);\r
+      ASSERT (Node->EditValue != NULL);\r
+      Link = GetNextNode (&Storage->NameValueListHead, Link);\r
+    }\r
+    break;\r
+\r
+  case EFI_HII_VARSTORE_EFI_VARIABLE:\r
+  default:\r
+    break;\r
+  }\r
+}\r
 \r
 /**\r
-  Submit a Form.\r
+  Fill storage's edit copy with settings requested from Configuration Driver.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  ConfigInfo             The config info related to this form.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+FormRestoreStorage (\r
+  IN FORM_BROWSER_FORMSET        *FormSet,\r
+  IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_STRING              Progress;\r
+  EFI_STRING              Result;\r
+  UINTN                   BufferSize;\r
+  LIST_ENTRY              *Link;\r
+  NAME_VALUE_NODE         *Node;\r
+\r
+  Status = EFI_SUCCESS;\r
+  Result = NULL;\r
+  if (FormSet->ConfigAccess == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (ConfigInfo->ElementCount == 0) {\r
+    //\r
+    // Skip if there is no RequestElement\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
+    BufferSize = ConfigInfo->Storage->Size;\r
+    Status = mHiiConfigRouting->BlockToConfig(\r
+                                  mHiiConfigRouting,\r
+                                  ConfigInfo->ConfigRequest,\r
+                                  ConfigInfo->Storage->Buffer,\r
+                                  BufferSize,\r
+                                  &Result,\r
+                                  &Progress\r
+                                  );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    Status = mHiiConfigRouting->ConfigToBlock (\r
+                                  mHiiConfigRouting,\r
+                                  Result,\r
+                                  ConfigInfo->Storage->EditBuffer,\r
+                                  &BufferSize,\r
+                                  &Progress\r
+                                  );\r
+    if (Result != NULL) {\r
+      FreePool (Result);\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);\r
+    while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {\r
+      Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
+\r
+      if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {\r
+        if (Node->EditValue != NULL) {\r
+          FreePool (Node->EditValue);\r
+        }\r
+        Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value);\r
+        ASSERT (Node->EditValue != NULL);\r
+      }\r
+\r
+      Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Discard data for form level or formset level.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Form                   Form data structure.\r
+  @param  SingleForm             Only discard single form or formset.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+DiscardForm (\r
+  IN FORM_BROWSER_FORMSET             *FormSet,\r
+  IN FORM_BROWSER_FORM                *Form,\r
+  IN BOOLEAN                          SingleForm\r
+  )\r
+{\r
+  LIST_ENTRY              *Link;\r
+  FORMSET_STORAGE         *Storage;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
+\r
+  if (SingleForm) {\r
+    if (Form->NvUpdateRequired) {\r
+      ConfigInfo = NULL;\r
+      Link = GetFirstNode (&Form->ConfigRequestHead);\r
+      while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+        ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+        Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
+\r
+        if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Skip if there is no RequestElement\r
+        //\r
+        if (ConfigInfo->ElementCount == 0) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Prepare <ConfigResp>\r
+        //\r
+        FormRestoreStorage(FormSet, ConfigInfo);\r
+      }\r
+\r
+      Form->NvUpdateRequired = FALSE;\r
+    }\r
+  } else {\r
+    if (IsNvUpdateRequired(FormSet)) {\r
+      //\r
+      // Discard Buffer storage or Name/Value storage\r
+      //\r
+      Link = GetFirstNode (&FormSet->StorageListHead);\r
+      while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+        Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+        Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+        if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Skip if there is no RequestElement\r
+        //\r
+        if (Storage->ElementCount == 0) {\r
+          continue;\r
+        }\r
+\r
+        RestoreStorage(Storage);\r
+      }\r
+\r
+      UpdateNvInfoInForm(FormSet, FALSE);   \r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;  \r
+}\r
+\r
+/**\r
+  Submit data for form level or formset level.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  Form                   Form data structure.\r
+  @param  SingleForm             whether submit for the single form or all form set.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
 \r
@@ -1733,7 +1965,8 @@ NoSubmitCheck (
 EFI_STATUS\r
 SubmitForm (\r
   IN FORM_BROWSER_FORMSET             *FormSet,\r
-  IN FORM_BROWSER_FORM                *Form\r
+  IN FORM_BROWSER_FORM                *Form,\r
+  IN BOOLEAN                          SingleForm\r
   )\r
 {\r
   EFI_STATUS              Status;\r
@@ -1741,66 +1974,122 @@ SubmitForm (
   EFI_STRING              ConfigResp;\r
   EFI_STRING              Progress;\r
   FORMSET_STORAGE         *Storage;\r
+  FORM_BROWSER_CONFIG_REQUEST  *ConfigInfo;\r
 \r
   //\r
   // Validate the Form by NoSubmit check\r
   //\r
-  Status = NoSubmitCheck (FormSet);\r
+  if (SingleForm) {\r
+    Status = NoSubmitCheck (FormSet, Form);\r
+  } else {\r
+    Status = NoSubmitCheck (FormSet, NULL);\r
+  }\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  //\r
-  // Submit Buffer storage or Name/Value storage\r
-  //\r
-  Link = GetFirstNode (&FormSet->StorageListHead);\r
-  while (!IsNull (&FormSet->StorageListHead, Link)) {\r
-    Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
-    Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+  if (SingleForm) {\r
+    ConfigInfo = NULL;\r
+    Link = GetFirstNode (&Form->ConfigRequestHead);\r
+    while (!IsNull (&Form->ConfigRequestHead, Link)) {\r
+      ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);\r
+      Link = GetNextNode (&Form->ConfigRequestHead, Link);\r
 \r
-    if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
-      continue;\r
-    }\r
+      if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+        continue;\r
+      }\r
 \r
-    //\r
-    // Skip if there is no RequestElement\r
-    //\r
-    if (Storage->ElementCount == 0) {\r
-      continue;\r
-    }\r
+      //\r
+      // Skip if there is no RequestElement\r
+      //\r
+      if (ConfigInfo->ElementCount == 0) {\r
+        continue;\r
+      }\r
 \r
-    //\r
-    // Prepare <ConfigResp>\r
-    //\r
-    Status = StorageToConfigResp (Storage, &ConfigResp);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      //\r
+      // Prepare <ConfigResp>\r
+      //\r
+      Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Send <ConfigResp> to Configuration Driver\r
+      //\r
+      if (FormSet->ConfigAccess != NULL) {\r
+        Status = FormSet->ConfigAccess->RouteConfig (\r
+                                          FormSet->ConfigAccess,\r
+                                          ConfigResp,\r
+                                          &Progress\r
+                                          );\r
+        if (EFI_ERROR (Status)) {\r
+          FreePool (ConfigResp);\r
+          return Status;\r
+        }\r
+      }\r
+      FreePool (ConfigResp);\r
+\r
+      //\r
+      // Config success, update storage shadow Buffer\r
+      //\r
+      SynchronizeStorage (ConfigInfo->Storage);\r
     }\r
 \r
+    Form->NvUpdateRequired = FALSE;\r
+  } else {\r
     //\r
-    // Send <ConfigResp> to Configuration Driver\r
+    // Submit Buffer storage or Name/Value storage\r
     //\r
-    if (FormSet->ConfigAccess != NULL) {\r
-      Status = FormSet->ConfigAccess->RouteConfig (\r
-                                        FormSet->ConfigAccess,\r
-                                        ConfigResp,\r
-                                        &Progress\r
-                                        );\r
+    Link = GetFirstNode (&FormSet->StorageListHead);\r
+    while (!IsNull (&FormSet->StorageListHead, Link)) {\r
+      Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
+      Link = GetNextNode (&FormSet->StorageListHead, Link);\r
+\r
+      if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Skip if there is no RequestElement\r
+      //\r
+      if (Storage->ElementCount == 0) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Prepare <ConfigResp>\r
+      //\r
+      Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);\r
       if (EFI_ERROR (Status)) {\r
-        FreePool (ConfigResp);\r
         return Status;\r
       }\r
+\r
+      //\r
+      // Send <ConfigResp> to Configuration Driver\r
+      //\r
+      if (FormSet->ConfigAccess != NULL) {\r
+        Status = FormSet->ConfigAccess->RouteConfig (\r
+                                          FormSet->ConfigAccess,\r
+                                          ConfigResp,\r
+                                          &Progress\r
+                                          );\r
+        if (EFI_ERROR (Status)) {\r
+          FreePool (ConfigResp);\r
+          return Status;\r
+        }\r
+      }\r
+      FreePool (ConfigResp);\r
+\r
+      //\r
+      // Config success, update storage shadow Buffer\r
+      //\r
+      SynchronizeStorage (Storage);\r
     }\r
-    FreePool (ConfigResp);\r
 \r
-    //\r
-    // Config success, update storage shadow Buffer\r
-    //\r
-    SynchronizeStorage (Storage);\r
+    UpdateNvInfoInForm(FormSet, FALSE);\r
   }\r
 \r
-  gNvUpdateRequired = FALSE;\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -2321,8 +2610,6 @@ LoadFormConfig (
   FORM_BROWSER_STATEMENT      *Question;\r
   UINT8                       *BufferValue;\r
   UINTN                       StorageWidth;\r
-  EFI_HII_VALUE               *HiiValue;\r
-  EFI_BROWSER_ACTION_REQUEST  ActionRequest;\r
   \r
   Link = GetFirstNode (&Form->StatementListHead);\r
   while (!IsNull (&Form->StatementListHead, Link)) {\r
@@ -2368,41 +2655,7 @@ LoadFormConfig (
                        );\r
 \r
       if (!EFI_ERROR (Status)) {\r
-        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
-        HiiValue = &Question->HiiValue;\r
-        BufferValue = (UINT8 *) &Question->HiiValue.Value;\r
-        if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
-          BufferValue = Question->BufferValue;\r
-        }\r
-\r
-        Status = FormSet->ConfigAccess->Callback (\r
-                                 FormSet->ConfigAccess,\r
-                                 EFI_BROWSER_ACTION_RETRIEVE,\r
-                                 Question->QuestionId,\r
-                                 HiiValue->Type,\r
-                                 (EFI_IFR_TYPE_VALUE *) BufferValue,\r
-                                 &ActionRequest\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
+        Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);\r
       }\r
     }\r
 \r
@@ -2539,6 +2792,7 @@ CopyStorage (
   switch (Src->Type) {\r
   case EFI_HII_VARSTORE_BUFFER:\r
     CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size);\r
+    CopyMem (Dst->Buffer, Src->Buffer, Src->Size);\r
     break;\r
 \r
   case EFI_HII_VARSTORE_NAME_VALUE:\r
@@ -2546,7 +2800,8 @@ CopyStorage (
     while (!IsNull (&Src->NameValueListHead, Link)) {\r
       Node = NAME_VALUE_NODE_FROM_LINK (Link);\r
 \r
-      SetValueByName (Dst, Node->Name, Node->EditValue);\r
+      SetValueByName (Dst, Node->Name, Node->EditValue, TRUE);\r
+      SetValueByName (Dst, Node->Name, Node->Value, FALSE);\r
 \r
       Link = GetNextNode (&Src->NameValueListHead, Link);\r
     }\r
@@ -2624,6 +2879,13 @@ InitializeCurrentSetting (
       // Storage is not found in backup formset, request it from ConfigDriver\r
       //\r
       Status = LoadStorage (FormSet, Storage);\r
+      //\r
+      // Now Edit Buffer is filled with default values(lower priority) and current\r
+      // settings(higher priority), sychronize it to shadow Buffer\r
+      //\r
+      if (!EFI_ERROR (Status)) {\r
+        SynchronizeStorage (Storage);\r
+      }\r
     } else {\r
       //\r
       // Storage found in backup formset, use it\r
@@ -2631,14 +2893,6 @@ InitializeCurrentSetting (
       Status = CopyStorage (Storage, OldStorage);\r
     }\r
 \r
-    //\r
-    // Now Edit Buffer is filled with default values(lower priority) and current\r
-    // settings(higher priority), sychronize it to shadow Buffer\r
-    //\r
-    if (!EFI_ERROR (Status)) {\r
-      SynchronizeStorage (Storage);\r
-    }\r
-\r
     Link = GetNextNode (&FormSet->StorageListHead, Link);\r
   }\r
 \r
@@ -2958,7 +3212,6 @@ SaveBrowserContext (
   Context->ClassOfVfr           = gClassOfVfr;\r
   Context->FunctionKeySetting   = gFunctionKeySetting;\r
   Context->ResetRequired        = gResetRequired;\r
-  Context->NvUpdateRequired     = gNvUpdateRequired;\r
   Context->Direction            = gDirection;\r
   Context->FunctionNineString   = gFunctionNineString;\r
   Context->FunctionTenString    = gFunctionTenString;\r
@@ -3039,7 +3292,6 @@ RestoreBrowserContext (
   gClassOfVfr           = Context->ClassOfVfr;\r
   gFunctionKeySetting   = Context->FunctionKeySetting;\r
   gResetRequired        = Context->ResetRequired;\r
-  gNvUpdateRequired     = Context->NvUpdateRequired;\r
   gDirection            = Context->Direction;\r
   gFunctionNineString   = Context->FunctionNineString;\r
   gFunctionTenString    = Context->FunctionTenString;\r
index f000c7b7674c130ff6f52a6c664961c6418a8146..d76569e8ec4fcb69c29e831f9c9ea338f2af9daa 100644 (file)
@@ -400,6 +400,19 @@ typedef struct {
 \r
 #define FORM_BROWSER_STATEMENT_FROM_LINK(a)  CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE)\r
 \r
+#define FORM_BROWSER_CONFIG_REQUEST_SIGNATURE  SIGNATURE_32 ('F', 'C', 'R', 'S')\r
+typedef struct {\r
+  UINTN                 Signature;\r
+  LIST_ENTRY            Link;\r
+\r
+  CHAR16                *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>\r
+  UINTN                 ElementCount;   // Number of <RequestElement> in the <ConfigRequest>  \r
+  UINTN                 SpareStrLen;\r
+\r
+  FORMSET_STORAGE       *Storage;\r
+} FORM_BROWSER_CONFIG_REQUEST;\r
+#define FORM_BROWSER_CONFIG_REQUEST_FROM_LINK(a)  CR (a, FORM_BROWSER_CONFIG_REQUEST, Link, FORM_BROWSER_CONFIG_REQUEST_SIGNATURE)\r
+\r
 #define FORM_BROWSER_FORM_SIGNATURE  SIGNATURE_32 ('F', 'F', 'R', 'M')\r
 #define STANDARD_MAP_FORM_TYPE 0x01\r
 \r
@@ -413,8 +426,11 @@ typedef struct {
 \r
   EFI_IMAGE_ID      ImageId;\r
 \r
+  BOOLEAN           NvUpdateRequired;     // Whether this form has NV update request.\r
+\r
   LIST_ENTRY        ExpressionListHead;   // List of Expressions (FORM_EXPRESSION)\r
   LIST_ENTRY        StatementListHead;    // List of Statements and Questions (FORM_BROWSER_STATEMENT)\r
+  LIST_ENTRY        ConfigRequestHead;    // List of configreques for all storage.\r
   FORM_EXPRESSION   *SuppressExpression;  // nesting inside of SuppressIf\r
 } FORM_BROWSER_FORM;\r
 \r
@@ -472,7 +488,6 @@ typedef struct {
   UINTN                 ClassOfVfr;\r
   UINTN                 FunctionKeySetting;\r
   BOOLEAN               ResetRequired;\r
-  BOOLEAN               NvUpdateRequired;\r
   UINT16                Direction;\r
   EFI_SCREEN_DESCRIPTOR ScreenDimensions;\r
   CHAR16                *FunctionNineString;\r
@@ -528,7 +543,6 @@ extern EFI_HII_HANDLE        gFrontPageHandle;
 extern UINTN                 gClassOfVfr;\r
 extern UINTN                 gFunctionKeySetting;\r
 extern BOOLEAN               gResetRequired;\r
-extern BOOLEAN               gNvUpdateRequired;\r
 extern EFI_HII_HANDLE        gHiiHandle;\r
 extern UINT16                gDirection;\r
 extern EFI_SCREEN_DESCRIPTOR gScreenDimensions;\r
@@ -833,6 +847,7 @@ GetValueByName (
   @param  Storage                The NameValue Storage.\r
   @param  Name                   The Name.\r
   @param  Value                  The Value to set.\r
+  @param  Edit                   Whether update editValue or Value.\r
 \r
   @retval EFI_SUCCESS            Value found for given Name.\r
   @retval EFI_NOT_FOUND          No such Name found in NameValue storage.\r
@@ -842,7 +857,8 @@ EFI_STATUS
 SetValueByName (\r
   IN FORMSET_STORAGE         *Storage,\r
   IN CHAR16                  *Name,\r
-  IN CHAR16                  *Value\r
+  IN CHAR16                  *Value,\r
+  IN BOOLEAN                 Edit\r
   );\r
 \r
 /**\r
@@ -906,10 +922,28 @@ ValidateQuestion (
   );\r
 \r
 /**\r
-  Submit a Form.\r
+  Discard data for form level or formset level.\r
 \r
   @param  FormSet                FormSet data structure.\r
   @param  Form                   Form data structure.\r
+  @param  SingleForm             whether submit single form or formset.\r
+\r
+  @retval EFI_SUCCESS            The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+DiscardForm (\r
+  IN FORM_BROWSER_FORMSET             *FormSet,\r
+  IN FORM_BROWSER_FORM                *Form,\r
+  IN BOOLEAN                          SingleForm\r
+  );\r
+\r
+/**\r
+  Submit data for form level or formset level.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  Form                   Form data structure.\r
+  @param  SingleForm             whether submit single form or formset.\r
 \r
   @retval EFI_SUCCESS            The function completed successfully.\r
 \r
@@ -917,7 +951,8 @@ ValidateQuestion (
 EFI_STATUS\r
 SubmitForm (\r
   IN FORM_BROWSER_FORMSET             *FormSet,\r
-  IN FORM_BROWSER_FORM                *Form\r
+  IN FORM_BROWSER_FORM                *Form,\r
+  IN BOOLEAN                          SingleForm\r
   );\r
 \r
 /**\r
@@ -1028,8 +1063,9 @@ LoadFormSetConfig (
 /**\r
   Convert setting of Buffer Storage or NameValue Storage to <ConfigResp>.\r
 \r
-  @param  Storage                The Storage to be conveted.\r
+  @param  Buffer                 The Storage to be conveted.\r
   @param  ConfigResp             The returned <ConfigResp>.\r
+  @param  SingleForm             Whether update data for single form or formset level.\r
 \r
   @retval EFI_SUCCESS            Convert success.\r
   @retval EFI_INVALID_PARAMETER  Incorrect storage type.\r
@@ -1037,8 +1073,9 @@ LoadFormSetConfig (
 **/\r
 EFI_STATUS\r
 StorageToConfigResp (\r
-  IN FORMSET_STORAGE         *Storage,\r
-  IN CHAR16                  **ConfigResp\r
+  IN VOID                    *Buffer,\r
+  IN CHAR16                  **ConfigResp,\r
+  IN BOOLEAN                 SingleForm\r
   );\r
 \r
 /**\r
@@ -1195,4 +1232,71 @@ BrowserCallback (
   IN CONST CHAR16                      *VariableName  OPTIONAL\r
   );\r
 \r
+/**\r
+  Find menu which will show next time.\r
+\r
+  @param Selection       On input, Selection tell setup browser the information\r
+                         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 Repaint         Whether need to repaint the menu.\r
+  @param NewLine         Whether need to show at new line.\r
+  \r
+  @retval TRUE           Need return.\r
+  @retval FALSE          No need to return.\r
+**/\r
+BOOLEAN\r
+FindNextMenu (\r
+  IN OUT UI_MENU_SELECTION    *Selection,\r
+  IN     BOOLEAN              *Repaint, \r
+  IN     BOOLEAN              *NewLine  \r
+  );\r
+\r
+/**\r
+  check whether the formset need to update the NV.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+  @param  SetValue               Whether set new value or clear old value.\r
+\r
+**/\r
+VOID\r
+UpdateNvInfoInForm (\r
+  IN FORM_BROWSER_FORMSET  *FormSet,\r
+  IN BOOLEAN               SetValue\r
+  );\r
+\r
+/**\r
+  check whether the formset need to update the NV.\r
+\r
+  @param  FormSet                FormSet data structure.\r
+\r
+  @retval TRUE                   Need to update the NV.\r
+  @retval FALSE                  No need to update the NV.\r
+**/\r
+BOOLEAN \r
+IsNvUpdateRequired (\r
+  IN FORM_BROWSER_FORMSET  *FormSet\r
+  );\r
+\r
+/**\r
+  Call the call back function for the question and process the return action.\r
+\r
+  @param Selection             On input, Selection tell setup browser the information\r
+                               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 Statement             The Question which need to call.\r
+  @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
+**/\r
+EFI_STATUS \r
+ProcessCallBackFunction (\r
+  IN OUT UI_MENU_SELECTION               *Selection,\r
+  IN     FORM_BROWSER_STATEMENT          *Question,\r
+  IN     EFI_BROWSER_ACTION              Action,\r
+  IN     BOOLEAN                         SkipSaveOrDiscard\r
+  );\r
 #endif\r
index 3ab63be2d61749f593c4ed8cf4e1acfc119f80f4..d5f726b0cefec550c26612fa2e09618b9c58565c 100644 (file)
@@ -340,8 +340,6 @@ RefreshForm (
   EFI_STATUS                      Status;\r
   UI_MENU_SELECTION               *Selection;\r
   FORM_BROWSER_STATEMENT          *Question;\r
-  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
-  EFI_BROWSER_ACTION_REQUEST      ActionRequest;\r
 \r
   if (gMenuRefreshHead != NULL) {\r
 \r
@@ -394,36 +392,9 @@ RefreshForm (
       //\r
       // Question value may be changed, need invoke its Callback()\r
       //\r
-      ConfigAccess = Selection->FormSet->ConfigAccess;\r
-      if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) {\r
-        ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
-        Status = ConfigAccess->Callback (\r
-                                 ConfigAccess,\r
-                                 EFI_BROWSER_ACTION_CHANGING,\r
-                                 Question->QuestionId,\r
-                                 Question->HiiValue.Type,\r
-                                 &Question->HiiValue.Value,\r
-                                 &ActionRequest\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
-          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
+      Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
       }\r
 \r
       MenuRefreshEntry = MenuRefreshEntry->Next;\r
@@ -1004,6 +975,7 @@ CreateMultiStringPopUp (
 /**\r
   Update status bar on the bottom of menu.\r
 \r
+  @param  Selection              Current Selction info.\r
   @param  MessageType            The type of message to be shown.\r
   @param  Flags                  The flags in Question header.\r
   @param  State                  Set or clear.\r
@@ -1011,6 +983,7 @@ CreateMultiStringPopUp (
 **/\r
 VOID\r
 UpdateStatusBar (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
   IN  UINTN                       MessageType,\r
   IN  UINT8                       Flags,\r
   IN  BOOLEAN                     State\r
@@ -1054,7 +1027,9 @@ UpdateStatusBar (
           );\r
         gResetRequired    = (BOOLEAN) (gResetRequired | ((Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED));\r
 \r
-        gNvUpdateRequired = TRUE;\r
+        if (Selection != NULL) {\r
+          Selection->Form->NvUpdateRequired = TRUE;\r
+        }\r
       } else {\r
         gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));\r
         for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) {\r
@@ -1065,18 +1040,20 @@ UpdateStatusBar (
             );\r
         }\r
 \r
-        gNvUpdateRequired = FALSE;\r
+        if (Selection != NULL) {\r
+          Selection->Form->NvUpdateRequired = FALSE;\r
+        }\r
       }\r
     }\r
     break;\r
 \r
   case REFRESH_STATUS_BAR:\r
     if (mInputError) {\r
-      UpdateStatusBar (INPUT_ERROR, Flags, TRUE);\r
+      UpdateStatusBar (Selection, INPUT_ERROR, Flags, TRUE);\r
     }\r
 \r
-    if (gNvUpdateRequired) {\r
-      UpdateStatusBar (NV_UPDATE_REQUIRED, Flags, TRUE);\r
+    if (IsNvUpdateRequired(Selection->FormSet)) {\r
+      UpdateStatusBar (NULL, NV_UPDATE_REQUIRED, Flags, TRUE);\r
     }\r
     break;\r
 \r
@@ -1640,8 +1617,6 @@ UiDisplayMenu (
   CHAR16                          *OptionString;\r
   CHAR16                          *OutputString;\r
   CHAR16                          *FormattedString;\r
-  CHAR16                          YesResponse;\r
-  CHAR16                          NoResponse;\r
   BOOLEAN                         NewLine;\r
   BOOLEAN                         Repaint;\r
   BOOLEAN                         SavedValue;\r
@@ -1730,6 +1705,7 @@ UiDisplayMenu (
     CurrentMenu = UiAddMenuList (NULL, &Selection->FormSetGuid, Selection->FormId);\r
   }\r
   ASSERT (CurrentMenu != NULL);\r
+  Selection->CurrentMenu = CurrentMenu;\r
 \r
   if (Selection->QuestionId == 0) {\r
     //\r
@@ -1745,7 +1721,7 @@ UiDisplayMenu (
   NewPos = gMenuOption.ForwardLink;\r
 \r
   gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
-  UpdateStatusBar (REFRESH_STATUS_BAR, (UINT8) 0, TRUE);\r
+  UpdateStatusBar (Selection, REFRESH_STATUS_BAR, (UINT8) 0, TRUE);\r
 \r
   ControlFlag = CfInitialization;\r
   Selection->Action = UI_ACTION_NONE;\r
@@ -2697,84 +2673,10 @@ UiDisplayMenu (
       // We come here when someone press ESC\r
       //\r
       ControlFlag = CfCheckSelection;\r
-\r
-      if (CurrentMenu->Parent != NULL) {\r
-        //\r
-        // we have a parent, so go to the parent menu\r
-        //\r
-        if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {\r
-          //\r
-          // The parent menu and current menu are in the same formset\r
-          //\r
-          Selection->Action = UI_ACTION_REFRESH_FORM;\r
-        } else {\r
-          Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
-        }\r
-        Selection->Statement = NULL;\r
-\r
-        Selection->FormId = CurrentMenu->Parent->FormId;\r
-        Selection->QuestionId = CurrentMenu->Parent->QuestionId;\r
-\r
-        //\r
-        // Clear highlight record for this menu\r
-        //\r
-        CurrentMenu->QuestionId = 0;\r
-        break;\r
-      }\r
-\r
-      if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
-        //\r
-        // We never exit FrontPage, so skip the ESC\r
-        //\r
-        Selection->Action = UI_ACTION_NONE;\r
-        break;\r
-      }\r
-\r
-      //\r
-      // We are going to leave current FormSet, so check uncommited data in this FormSet\r
-      //\r
-      if (gNvUpdateRequired) {\r
-        Status      = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-\r
-        YesResponse = gYesResponse[0];\r
-        NoResponse  = gNoResponse[0];\r
-\r
-        //\r
-        // If NV flag is up, prompt user\r
-        //\r
-        do {\r
-          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);\r
-        } while\r
-        (\r
-          (Key.ScanCode != SCAN_ESC) &&\r
-          ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
-          ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
-        );\r
-\r
-        if (Key.ScanCode == SCAN_ESC) {\r
-          //\r
-          // User hits the ESC key\r
-          //\r
-          Repaint = TRUE;\r
-          NewLine = TRUE;\r
-\r
-          Selection->Action = UI_ACTION_NONE;\r
-          break;\r
-        }\r
-\r
-        //\r
-        // If the user hits the YesResponse key\r
-        //\r
-        if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
-          Status = SubmitForm (Selection->FormSet, Selection->Form);\r
-        }\r
-      }\r
-\r
-      Selection->Action = UI_ACTION_EXIT;\r
-      Selection->Statement = NULL;\r
-      CurrentMenu->QuestionId = 0;\r
-\r
-      return EFI_SUCCESS;\r
+      if (FindNextMenu (Selection, &Repaint, &NewLine)) {\r
+        return EFI_SUCCESS;\r
+      } \r
+      break;\r
 \r
     case CfUiLeft:\r
       ControlFlag = CfCheckSelection;\r
@@ -2869,7 +2771,7 @@ UiDisplayMenu (
         AdjustDateAndTimePosition (TRUE, &TopOfScreen);\r
         AdjustDateAndTimePosition (TRUE, &NewPos);\r
         MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
-        UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+        UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
       } else {\r
         //\r
         // Scroll up to the last page.\r
@@ -3166,7 +3068,7 @@ UiDisplayMenu (
 \r
         MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);\r
 \r
-        UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+        UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
 \r
       } else {\r
         //\r
@@ -3197,12 +3099,12 @@ UiDisplayMenu (
       //\r
       // Submit the form\r
       //\r
-      Status = SubmitForm (Selection->FormSet, Selection->Form);\r
+      Status = SubmitForm (Selection->FormSet, Selection->Form, FALSE);\r
 \r
       if (!EFI_ERROR (Status)) {\r
         ASSERT(MenuOption != NULL);\r
-        UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
-        UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+        UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);\r
+        UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE);\r
       } else {\r
         do {\r
           CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveFailed, gPressEnter, gEmptyString);\r
@@ -3231,7 +3133,7 @@ UiDisplayMenu (
         //\r
         // Show NV update flag on status bar\r
         //\r
-        gNvUpdateRequired = TRUE;\r
+        UpdateNvInfoInForm(Selection->FormSet, TRUE);\r
         gResetRequired = TRUE;\r
       }\r
       break;\r
index 362f8e7d6001e4c19c63988ea4bf031a54a238f0..a9f679b3d2a7986d5cb5ac3ba28b779e36be4d6c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Private structure, MACRO and function definitions for User Interface related functionalities.\r
 \r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2011, 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
@@ -76,6 +76,8 @@ typedef enum {
 #define UI_ACTION_REFRESH_FORMSET    2\r
 #define UI_ACTION_EXIT               3\r
 \r
+typedef struct _UI_MENU_LIST UI_MENU_LIST;\r
+\r
 typedef struct {\r
   EFI_HII_HANDLE  Handle;\r
 \r
@@ -111,6 +113,8 @@ typedef struct {
   // Whether the Form is editable\r
   //\r
   BOOLEAN                 FormEditable;\r
+\r
+  UI_MENU_LIST            *CurrentMenu;\r
 } UI_MENU_SELECTION;\r
 \r
 #define UI_MENU_OPTION_SIGNATURE  SIGNATURE_32 ('u', 'i', 'm', 'm')\r
@@ -152,8 +156,6 @@ typedef struct {
 \r
 #define MENU_OPTION_FROM_LINK(a)  CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)\r
 \r
-typedef struct _UI_MENU_LIST UI_MENU_LIST;\r
-\r
 struct _UI_MENU_LIST {\r
   UINTN           Signature;\r
   LIST_ENTRY      Link;\r
@@ -449,6 +451,7 @@ GetNumericInput (
 /**\r
   Update status bar on the bottom of menu.\r
 \r
+  @param  Selection              Current selection info.\r
   @param  MessageType            The type of message to be shown.\r
   @param  Flags                  The flags in Question header.\r
   @param  State                  Set or clear.\r
@@ -456,6 +459,7 @@ GetNumericInput (
 **/\r
 VOID\r
 UpdateStatusBar (\r
+  IN  UI_MENU_SELECTION           *Selection,\r
   IN  UINTN                       MessageType,\r
   IN  UINT8                       Flags,\r
   IN  BOOLEAN                     State\r