]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
MdeModulePkg/ResetSystemRuntimeDxe: Add platform filter and handler
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Setup.c
index f649e0497927ebd3aca7016362c28ea39c625a0a..c2cfa5c5c829c582f0bbc804d30e8f0f838f89ed 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Entry and initialization module for the browser.\r
 \r
-Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, 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
@@ -53,7 +53,8 @@ LIST_ENTRY      gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserSto
 LIST_ENTRY      gBrowserSaveFailFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserSaveFailFormSetList);\r
 \r
 BOOLEAN               mSystemSubmit = FALSE;\r
-BOOLEAN               gResetRequired;\r
+BOOLEAN               gResetRequiredFormLevel;\r
+BOOLEAN               gResetRequiredSystemLevel = FALSE;\r
 BOOLEAN               gExitRequired;\r
 BOOLEAN               gFlagReconnect;\r
 BOOLEAN               gCallbackReconnect;\r
@@ -181,7 +182,7 @@ UiFindMenuList (
     // Find the same FromSet.\r
     //\r
     if (MenuList->HiiHandle == HiiHandle) {\r
-      if (CompareGuid (&MenuList->FormSetGuid, &gZeroGuid)) {\r
+      if (IsZeroGuid (&MenuList->FormSetGuid)) {\r
         //\r
         // FormSetGuid is not specified.\r
         //\r
@@ -499,7 +500,7 @@ SendForm (
   SaveBrowserContext ();\r
 \r
   gFlagReconnect = FALSE;\r
-  gResetRequired = FALSE;\r
+  gResetRequiredFormLevel = FALSE;\r
   gExitRequired  = FALSE;\r
   gCallbackReconnect = FALSE;\r
   Status         = EFI_SUCCESS;\r
@@ -579,7 +580,7 @@ SendForm (
 \r
   if (ActionRequest != NULL) {\r
     *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
-    if (gResetRequired) {\r
+    if (gResetRequiredFormLevel) {\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;\r
     }\r
   }\r
@@ -938,7 +939,7 @@ InitializeSetup (
   \r
   Status = gBS->InstallProtocolInterface (\r
                   &mPrivateData.Handle,\r
-                  &gEfiFormBrowserExProtocolGuid,\r
+                  &gEdkiiFormBrowserExProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
                   &mPrivateData.FormBrowserEx\r
                   );\r
@@ -1367,6 +1368,71 @@ ConfigRespToStorage (
   return Status;\r
 }\r
 \r
+/**\r
+  Get bit field value from the buffer and then set the value for the question.\r
+  Note: Data type UINT32 can cover all the bit field value.\r
+\r
+  @param  Question        The question refer to bit field.\r
+  @param  Buffer          Point to the buffer which the question value get from.\r
+\r
+**/\r
+VOID\r
+GetBitsQuestionValue (\r
+  IN  FORM_BROWSER_STATEMENT *Question,\r
+  IN  UINT8                  *Buffer\r
+  )\r
+{\r
+  UINTN    StartBit;\r
+  UINTN    EndBit;\r
+  UINT32   RetVal;\r
+  UINT32   BufferValue;\r
+\r
+  StartBit = Question->BitVarOffset % 8;\r
+  EndBit = StartBit + Question->BitStorageWidth - 1;\r
+\r
+  CopyMem ((UINT8 *) &BufferValue, Buffer, Question->StorageWidth);\r
+\r
+  RetVal = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+\r
+  //\r
+  // Set question value.\r
+  // Note: Since Question with BufferValue (orderedlist, password, string)are not supported to refer bit field.\r
+  // Only oneof/checkbox/oneof can support bit field.So we can copy the value to the Hiivalue of Question directly.\r
+  //\r
+  CopyMem ((UINT8 *) &Question->HiiValue.Value, (UINT8 *) &RetVal, Question->StorageWidth);\r
+}\r
+\r
+/**\r
+  Set bit field value to the buffer.\r
+  Note: Data type UINT32 can cover all the bit field value.\r
+\r
+  @param  Question        The question refer to bit field.\r
+  @param  Buffer          Point to the buffer which the question value set to.\r
+  @param  Value           The bit field value need to set.\r
+\r
+**/\r
+VOID\r
+SetBitsQuestionValue (\r
+  IN     FORM_BROWSER_STATEMENT *Question,\r
+  IN OUT UINT8                  *Buffer,\r
+  IN     UINT32                 Value\r
+  )\r
+{\r
+  UINT32   Operand;\r
+  UINTN    StartBit;\r
+  UINTN    EndBit;\r
+  UINT32   RetVal;\r
+\r
+  StartBit = Question->BitVarOffset % 8;\r
+  EndBit = StartBit + Question->BitStorageWidth - 1;\r
+\r
+  CopyMem ((UINT8*) &Operand, Buffer, Question->StorageWidth);\r
+\r
+  RetVal = BitFieldWrite32 (Operand, StartBit, EndBit, Value);\r
+\r
+  CopyMem (Buffer, (UINT8*) &RetVal, Question->StorageWidth);\r
+}\r
+\r
 /**\r
   Convert the buffer value to HiiValue.\r
 \r
@@ -1394,6 +1460,9 @@ BufferToValue (
   BOOLEAN                      IsString;\r
   UINTN                        Length;\r
   EFI_STATUS                   Status;\r
+  UINT8                        *Buffer;\r
+\r
+  Buffer = NULL;\r
 \r
   IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ?  TRUE : FALSE);\r
   if (Question->Storage->Type == EFI_HII_VARSTORE_BUFFER || \r
@@ -1415,7 +1484,15 @@ BufferToValue (
     //\r
     // Other type of Questions\r
     //\r
-    Dst = (UINT8 *) &Question->HiiValue.Value;\r
+    if (Question->QuestionReferToBitField) {\r
+      Buffer = (UINT8 *)AllocateZeroPool (Question->StorageWidth);\r
+      if (Buffer == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+      Dst = Buffer;\r
+    } else {\r
+      Dst = (UINT8 *) &Question->HiiValue.Value;\r
+    }\r
   }\r
 \r
   //\r
@@ -1429,46 +1506,55 @@ BufferToValue (
   *StringPtr = L'\0';\r
 \r
   LengthStr = StrLen (Value);\r
+\r
+  //\r
+  // Value points to a Unicode hexadecimal string, we need to convert the string to the value with CHAR16/UINT8...type.\r
+  // When generating the Value string, we follow this rule: 1 byte -> 2 Unicode characters (for string: 2 byte(CHAR16) ->4 Unicode characters).\r
+  // So the maximum value string length of a question is : Question->StorageWidth * 2.\r
+  // If the value string length > Question->StorageWidth * 2, only set the string length as Question->StorageWidth * 2, then convert.\r
+  //\r
+  if (LengthStr > (UINTN) Question->StorageWidth * 2) {\r
+    Length = (UINTN) Question->StorageWidth * 2;\r
+  } else {\r
+    Length = LengthStr;\r
+  }\r
+\r
   Status    = EFI_SUCCESS;\r
   if (!IsBufferStorage && IsString) {\r
     //\r
     // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
     // Add string tail char L'\0' into Length\r
     //\r
-    Length    = Question->StorageWidth + sizeof (CHAR16);\r
-    if (Length < ((LengthStr / 4 + 1) * 2)) {\r
-      Status = EFI_BUFFER_TOO_SMALL;\r
-    } else {\r
-      DstBuf = (CHAR16 *) Dst;\r
-      ZeroMem (TemStr, sizeof (TemStr));\r
-      for (Index = 0; Index < LengthStr; Index += 4) {\r
-        StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value + Index, 4);\r
-        DstBuf[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
-      }\r
-      //\r
-      // Add tailing L'\0' character\r
-      //\r
-      DstBuf[Index/4] = L'\0';\r
+    DstBuf = (CHAR16 *) Dst;\r
+    ZeroMem (TemStr, sizeof (TemStr));\r
+    for (Index = 0; Index < Length; Index += 4) {\r
+      StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value + Index, 4);\r
+      DstBuf[Index/4] = (CHAR16) StrHexToUint64 (TemStr);\r
     }\r
+    //\r
+    // Add tailing L'\0' character\r
+    //\r
+    DstBuf[Index/4] = L'\0';\r
   } else {\r
-    if (Question->StorageWidth < ((LengthStr + 1) / 2)) {\r
-      Status = EFI_BUFFER_TOO_SMALL;\r
-    } else {\r
-      ZeroMem (TemStr, sizeof (TemStr));\r
-      for (Index = 0; Index < LengthStr; Index ++) {\r
-        TemStr[0] = Value[LengthStr - Index - 1];\r
-        DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
-        if ((Index & 1) == 0) {\r
-          Dst [Index/2] = DigitUint8;\r
-        } else {\r
-          Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
-        }\r
+    ZeroMem (TemStr, sizeof (TemStr));\r
+    for (Index = 0; Index < Length; Index ++) {\r
+      TemStr[0] = Value[LengthStr - Index - 1];\r
+      DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+      if ((Index & 1) == 0) {\r
+        Dst [Index/2] = DigitUint8;\r
+      } else {\r
+        Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);\r
       }\r
     }\r
   }\r
 \r
   *StringPtr = TempChar;\r
 \r
+  if (Buffer != NULL && Question->QuestionReferToBitField) {\r
+    GetBitsQuestionValue (Question, Buffer);\r
+    FreePool (Buffer);\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -1673,13 +1759,23 @@ GetQuestionValue (
       if (GetValueFrom == GetSetValueWithEditBuffer) {\r
         //\r
         // Copy from storage Edit buffer\r
+        // If the Question refer to bit filed, get the value in the related bit filed.\r
         //\r
-        CopyMem (Dst, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
+        if (Question->QuestionReferToBitField) {\r
+          GetBitsQuestionValue (Question, Storage->EditBuffer + Question->VarStoreInfo.VarOffset);\r
+        } else {\r
+          CopyMem (Dst, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
+        }\r
       } else {\r
         //\r
         // Copy from storage Edit buffer\r
+        // If the Question refer to bit filed, get the value in the related bit filed.\r
         //\r
-        CopyMem (Dst, Storage->Buffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
+        if (Question->QuestionReferToBitField) {\r
+          GetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset);\r
+        } else {\r
+          CopyMem (Dst, Storage->Buffer + Question->VarStoreInfo.VarOffset, StorageWidth);\r
+        }\r
       }\r
     } else {\r
       Value = NULL;\r
@@ -1945,13 +2041,23 @@ SetQuestionValue (
       if (SetValueTo == GetSetValueWithEditBuffer) {\r
         //\r
         // Copy to storage edit buffer\r
-        //      \r
-        CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
+        // If the Question refer to bit filed, copy the value in related bit filed to storage edit buffer.\r
+        //\r
+        if (Question->QuestionReferToBitField) {\r
+          SetBitsQuestionValue (Question, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));\r
+        } else {\r
+          CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
+        }\r
       } else if (SetValueTo == GetSetValueWithBuffer) {\r
         //\r
-        // Copy to storage edit buffer\r
-        //     \r
-        CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
+        // Copy to storage buffer\r
+        // If the Question refer to bit filed, copy the value in related bit filed to storage buffer.\r
+        //\r
+        if (Question->QuestionReferToBitField) {\r
+          SetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));\r
+        } else {\r
+          CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);\r
+        }\r
       }\r
     } else {\r
       if (IsString) {\r
@@ -1968,7 +2074,14 @@ SetQuestionValue (
         TemName = (CHAR16 *) Src;\r
         TemString = Value;\r
         for (; *TemName != L'\0'; TemName++) {\r
-          TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
+          UnicodeValueToStringS (\r
+            TemString,\r
+            BufferLen - ((UINTN)TemString - (UINTN)Value),\r
+            PREFIX_ZERO | RADIX_HEX,\r
+            *TemName,\r
+            4\r
+            );\r
+          TemString += StrnLenS (TemString, (BufferLen - ((UINTN)TemString - (UINTN)Value)) / sizeof (CHAR16));\r
         }\r
       } else {\r
         BufferLen = StorageWidth * 2 + 1;\r
@@ -1980,7 +2093,14 @@ SetQuestionValue (
         TemBuffer = Src + StorageWidth - 1;\r
         TemString = Value;\r
         for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
-          TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+          UnicodeValueToStringS (\r
+            TemString,\r
+            BufferLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)Value),\r
+            PREFIX_ZERO | RADIX_HEX,\r
+            *TemBuffer,\r
+            2\r
+            );\r
+          TemString += StrnLenS (TemString, BufferLen - ((UINTN)TemString - (UINTN)Value) / sizeof (CHAR16));\r
         }\r
       }\r
 \r
@@ -2030,7 +2150,14 @@ SetQuestionValue (
       TemName = (CHAR16 *) Src;\r
       TemString = Value;\r
       for (; *TemName != L'\0'; TemName++) {\r
-        TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
+        UnicodeValueToStringS (\r
+          TemString,\r
+          MaxLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ConfigResp),\r
+          PREFIX_ZERO | RADIX_HEX,\r
+          *TemName,\r
+          4\r
+          );\r
+        TemString += StrnLenS (TemString, MaxLen - ((UINTN)TemString - (UINTN)ConfigResp) / sizeof (CHAR16));\r
       }\r
     } else {\r
       //\r
@@ -2039,7 +2166,14 @@ SetQuestionValue (
       TemBuffer = Src + StorageWidth - 1;\r
       TemString = Value;\r
       for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {\r
-        TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+        UnicodeValueToStringS (\r
+          TemString,\r
+          MaxLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ConfigResp),\r
+          PREFIX_ZERO | RADIX_HEX,\r
+          *TemBuffer,\r
+          2\r
+          );\r
+        TemString += StrnLenS (TemString, MaxLen - ((UINTN)TemString - (UINTN)ConfigResp) / sizeof (CHAR16));\r
       }\r
     }\r
 \r
@@ -2646,7 +2780,8 @@ UpdateFlagForForm (
     //\r
     if (SetFlag && OldValue && !Question->ValueChanged) {\r
       if ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {\r
-        gResetRequired = TRUE;\r
+        gResetRequiredFormLevel = TRUE;\r
+        gResetRequiredSystemLevel = TRUE;\r
       }\r
 \r
       if ((Question->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {\r
@@ -3271,6 +3406,7 @@ SubmitForForm (
 \r
         Status = EFI_SUCCESS;\r
       }\r
+      SendDiscardInfoToDriver (FormSet,Form);\r
     } else {\r
       Status = EFI_UNSUPPORTED;\r
     }\r
@@ -3332,9 +3468,11 @@ SubmitForFormSet (
   BOOLEAN                 HasInserted;\r
   FORM_BROWSER_STATEMENT  *Question;\r
   BOOLEAN                 SubmitFormSetFail;\r
+  BOOLEAN                 DiscardChange;\r
 \r
   HasInserted = FALSE;\r
   SubmitFormSetFail = FALSE;\r
+  DiscardChange     = FALSE;\r
 \r
   if (!IsNvUpdateRequiredForFormSet (FormSet)) {\r
     return EFI_SUCCESS;\r
@@ -3435,6 +3573,7 @@ SubmitForFormSet (
       // If not in system level, just handl the save failed storage here.\r
       //\r
       if (ConfirmSaveFail (Form->FormTitle, FormSet->HiiHandle) == BROWSER_ACTION_DISCARD) {\r
+        DiscardChange = TRUE;\r
         Link = GetFirstNode (&FormSet->SaveFailStorageListHead);\r
         while (!IsNull (&FormSet->SaveFailStorageListHead, Link)) {\r
           FormSetStorage = FORMSET_STORAGE_FROM_SAVE_FAIL_LINK (Link);\r
@@ -3483,6 +3622,21 @@ SubmitForFormSet (
     }\r
   }\r
 \r
+  //\r
+  // If user discard the change, send the discard info to driver.\r
+  //\r
+  if (DiscardChange) {\r
+    Link = GetFirstNode (&FormSet->FormListHead);\r
+    while (!IsNull (&FormSet->FormListHead, Link)) {\r
+      Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+      Link = GetNextNode (&FormSet->FormListHead, Link);\r
+      //\r
+      // Call callback with Changed type to inform the driver.\r
+      //\r
+      SendDiscardInfoToDriver (FormSet, Form);\r
+    }\r
+  }\r
+\r
   //\r
   // 5. Update the NV flag.\r
   // \r
@@ -3512,6 +3666,7 @@ SubmitForSystem (
 {\r
   EFI_STATUS              Status;\r
   LIST_ENTRY              *Link;\r
+  LIST_ENTRY              *FormLink;\r
   LIST_ENTRY              *StorageLink;\r
   FORMSET_STORAGE         *FormSetStorage;\r
   FORM_BROWSER_FORM       *Form;\r
@@ -3602,6 +3757,16 @@ SubmitForSystem (
         }\r
       }\r
 \r
+      FormLink = GetFirstNode (&LocalFormSet->FormListHead);\r
+      while (!IsNull (&LocalFormSet->FormListHead, FormLink)) {\r
+        Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);\r
+        FormLink = GetNextNode (&LocalFormSet->FormListHead, FormLink);\r
+        //\r
+        // Call callback with Changed type to inform the driver.\r
+        //\r
+        SendDiscardInfoToDriver (LocalFormSet, Form);\r
+      }\r
+\r
       if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {\r
         CleanBrowserStorage(LocalFormSet);\r
         RemoveEntryList (&LocalFormSet->Link);\r
@@ -3756,6 +3921,11 @@ GetOffsetFromConfigResp (
   // Type is EFI_HII_VARSTORE_EFI_VARIABLE or EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER\r
   //\r
 \r
+  //\r
+  // Convert all hex digits in ConfigResp to lower case before searching.\r
+  //\r
+  HiiToLower (ConfigResp);\r
+\r
   //\r
   // 1. Directly use Question->BlockName to find.\r
   //\r
@@ -4050,9 +4220,14 @@ GetQuestionDefault (
   INTN                            Action;\r
   CHAR16                          *NewString;\r
   EFI_IFR_TYPE_VALUE              *TypeValue;\r
+  UINT16                          OriginalDefaultId;\r
+  FORMSET_DEFAULTSTORE            *DefaultStore;\r
+  LIST_ENTRY                      *DefaultLink;\r
 \r
   Status   = EFI_NOT_FOUND;\r
   StrValue = NULL;\r
+  OriginalDefaultId  = DefaultId;\r
+  DefaultLink        = GetFirstNode (&FormSet->DefaultStoreListHead);\r
 \r
   //\r
   // Statement don't have storage, skip them\r
@@ -4069,6 +4244,7 @@ GetQuestionDefault (
   //  4, set flags of EFI_ONE_OF_OPTION (provide Standard and Manufacturing default)\r
   //  5, set flags of EFI_IFR_CHECKBOX (provide Standard and Manufacturing default) (lowest priority)\r
   //\r
+ReGetDefault:\r
   HiiValue = &Question->HiiValue;\r
   TypeValue = &HiiValue->Value;\r
   if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
@@ -4100,6 +4276,7 @@ GetQuestionDefault (
 \r
         ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth);\r
         if (StrLen (NewString) * sizeof (CHAR16) <= Question->StorageWidth) {\r
+          ZeroMem (Question->BufferValue, Question->StorageWidth);\r
           CopyMem (Question->BufferValue, NewString, StrSize (NewString));\r
         } else {\r
           CopyMem (Question->BufferValue, NewString, Question->StorageWidth);\r
@@ -4170,6 +4347,7 @@ GetQuestionDefault (
             return EFI_NOT_FOUND;\r
           }\r
           if (Question->StorageWidth > StrSize (StrValue)) {\r
+            ZeroMem (Question->BufferValue, Question->StorageWidth);\r
             CopyMem (Question->BufferValue, StrValue, StrSize (StrValue));\r
           } else {\r
             CopyMem (Question->BufferValue, StrValue, Question->StorageWidth);\r
@@ -4224,8 +4402,6 @@ GetQuestionDefault (
           ((DefaultId == EFI_HII_DEFAULT_CLASS_MANUFACTURING) && ((Question->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0))\r
          ) {\r
         HiiValue->Value.b = TRUE;\r
-      } else {\r
-        HiiValue->Value.b = FALSE;\r
       }\r
 \r
       return EFI_SUCCESS;\r
@@ -4233,10 +4409,30 @@ GetQuestionDefault (
   }\r
 \r
   //\r
-  // For Questions without default\r
+  // For question without default value for current default Id, we try to re-get the default value form other default id in the DefaultStoreList.\r
+  // If get, will exit the function, if not, will choose next default id in the DefaultStoreList.\r
+  // The default id in DefaultStoreList are in ascending order to make sure choose the smallest default id every time.\r
+  //\r
+  while (!IsNull(&FormSet->DefaultStoreListHead, DefaultLink)) {\r
+    DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK(DefaultLink);\r
+    DefaultLink = GetNextNode (&FormSet->DefaultStoreListHead,DefaultLink);\r
+    DefaultId = DefaultStore->DefaultId;\r
+    if (DefaultId == OriginalDefaultId) {\r
+      continue;\r
+    }\r
+    goto ReGetDefault;\r
+  }\r
+\r
+  //\r
+  // For Questions without default value for all the default id in the DefaultStoreList.\r
   //\r
   Status = EFI_NOT_FOUND;\r
   switch (Question->Operand) {\r
+  case EFI_IFR_CHECKBOX_OP:\r
+    HiiValue->Value.b = FALSE;\r
+    Status = EFI_SUCCESS;\r
+    break;\r
+\r
   case EFI_IFR_NUMERIC_OP:\r
     //\r
     // Take minimum value as numeric default value\r
@@ -5654,7 +5850,7 @@ GetIfrBinaryData (
           //\r
           // Try to compare against formset GUID\r
           //\r
-          if (CompareGuid (FormSetGuid, &gZeroGuid) || \r
+          if (IsZeroGuid (FormSetGuid) ||\r
               CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
             break;\r
           }\r
@@ -5824,7 +6020,7 @@ SaveBrowserContext (
   // Save FormBrowser context\r
   //\r
   Context->Selection            = gCurrentSelection;\r
-  Context->ResetRequired        = gResetRequired;\r
+  Context->ResetRequired        = gResetRequiredFormLevel;\r
   Context->FlagReconnect        = gFlagReconnect;\r
   Context->CallbackReconnect    = gCallbackReconnect;\r
   Context->ExitRequired         = gExitRequired;\r
@@ -5897,7 +6093,7 @@ RestoreBrowserContext (
   // Restore FormBrowser context\r
   //\r
   gCurrentSelection     = Context->Selection;\r
-  gResetRequired        = Context->ResetRequired;\r
+  gResetRequiredFormLevel = Context->ResetRequired;\r
   gFlagReconnect        = Context->FlagReconnect;\r
   gCallbackReconnect    = Context->CallbackReconnect;\r
   gExitRequired         = Context->ExitRequired;\r
@@ -6044,29 +6240,10 @@ PasswordCheck (
       return EFI_UNSUPPORTED;\r
     }\r
   } else {\r
-    if (PasswordString == NULL) {\r
-      return EFI_SUCCESS;\r
-    } \r
-\r
     //\r
-    // Check whether has preexisted password.\r
+    // If a password doesn't have the CALLBACK flag, browser will not handle it.\r
     //\r
-    if (PasswordString[0] == 0) {\r
-      if (*((CHAR16 *) Question->BufferValue) == 0) {\r
-        return EFI_SUCCESS;\r
-      } else {\r
-        return EFI_NOT_READY;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Check whether the input password is same as preexisted password.\r
-    //\r
-    if (StrnCmp (PasswordString, (CHAR16 *) Question->BufferValue, Question->StorageWidth/sizeof (CHAR16)) == 0) {\r
-      return EFI_SUCCESS;\r
-    } else {\r
-      return EFI_NOT_READY;\r
-    }\r
+    return EFI_UNSUPPORTED;\r
   }\r
     \r
   //\r
@@ -6391,7 +6568,8 @@ ExecuteAction (
   // Executet the reset action.\r
   //\r
   if ((Action & BROWSER_ACTION_RESET) != 0) {\r
-    gResetRequired = TRUE;\r
+    gResetRequiredFormLevel = TRUE;\r
+    gResetRequiredSystemLevel = TRUE;\r
   }\r
 \r
   //\r
@@ -6491,6 +6669,6 @@ IsResetRequired (
   VOID\r
   )\r
 {\r
-  return gResetRequired;\r
+  return gResetRequiredSystemLevel;\r
 }\r
 \r