]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
index 534c5647a42f1e7de754ea84a9f2e0a16e254a86..6da0e30c989fbc6c882900984ed298f9db293a35 100644 (file)
@@ -1,25 +1,29 @@
 /** @file\r
 Implementation for EFI_HII_DATABASE_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 #include "HiiDatabase.h"\r
 \r
+#define BASE_NUMBER        10\r
+\r
+EFI_HII_PACKAGE_LIST_HEADER    *gRTDatabaseInfoBuffer = NULL;\r
+EFI_STRING                     gRTConfigRespBuffer    = NULL;\r
+UINTN                          gDatabaseInfoSize = 0;\r
+UINTN                          gConfigRespSize = 0;\r
+BOOLEAN                        gExportConfigResp = FALSE;\r
+UINTN                          gNvDefaultStoreSize = 0;\r
+SKU_ID                         gSkuId              = 0xFFFFFFFFFFFFFFFF;\r
+LIST_ENTRY                     gVarStorageList     = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);\r
+\r
 //\r
-// Global variables\r
+// HII database lock.\r
 //\r
-EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID;\r
-\r
+EFI_LOCK mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
 \r
 /**\r
   This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
@@ -356,7 +360,7 @@ InvokeRegisteredFunction (
   @param  NotifyType             The type of change concerning the database.\r
   @param  PackageList            Pointer to a package list which will be inserted\r
                                  to.\r
-  @param  Package                Created GUID pacakge\r
+  @param  Package                Created GUID package\r
 \r
   @retval EFI_SUCCESS            Guid Package is inserted successfully.\r
   @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new\r
@@ -531,6 +535,528 @@ RemoveGuidPackages (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Check the input question related to EFI variable\r
+\r
+  @param IfrQuestionHdr     Point to Question header\r
+  @param EfiVarStoreList    Point to EFI VarStore List\r
+  @param EfiVarStoreNumber  The number of EFI VarStore\r
+\r
+  @retval Index             The index of the found EFI varstore in EFI varstore list\r
+                            EfiVarStoreNumber will return if no EFI varstore is found.\r
+**/\r
+UINTN\r
+IsEfiVarStoreQuestion (\r
+  EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,\r
+  EFI_IFR_VARSTORE_EFI    **EfiVarStoreList,\r
+  UINTN                   EfiVarStoreNumber\r
+  )\r
+{\r
+  UINTN Index;\r
+  for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
+    if (IfrQuestionHdr->VarStoreId == EfiVarStoreList[Index]->VarStoreId) {\r
+      return Index;\r
+    }\r
+  }\r
+\r
+  return EfiVarStoreNumber;\r
+}\r
+\r
+/**\r
+  Find the matched variable from the input variable storage.\r
+\r
+  @param[in] VariableStorage Point to the variable storage header.\r
+  @param[in] VarGuid         A unique identifier for the variable.\r
+  @param[in] VarAttribute    The attributes bitmask for the variable.\r
+  @param[in] VarName         A Null-terminated ascii string that is the name of the variable.\r
+\r
+  @return Pointer to the matched variable header or NULL if not found.\r
+**/\r
+VARIABLE_HEADER *\r
+FindVariableData (\r
+  IN  VARIABLE_STORE_HEADER  *VariableStorage,\r
+  IN  EFI_GUID               *VarGuid,\r
+  IN  UINT32                 VarAttribute,\r
+  IN  CHAR16                 *VarName\r
+  )\r
+{\r
+  VARIABLE_HEADER *VariableHeader;\r
+  VARIABLE_HEADER *VariableEnd;\r
+\r
+  VariableEnd    = (VARIABLE_HEADER *) ((UINT8 *) VariableStorage + VariableStorage->Size);\r
+  VariableHeader = (VARIABLE_HEADER *) (VariableStorage + 1);\r
+  VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableHeader);\r
+  while (VariableHeader < VariableEnd) {\r
+    if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&\r
+        VariableHeader->Attributes == VarAttribute &&\r
+        StrCmp (VarName, (CHAR16 *) (VariableHeader + 1)) == 0) {\r
+      return VariableHeader;\r
+    }\r
+    VariableHeader = (VARIABLE_HEADER *) ((UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);\r
+    VariableHeader = (VARIABLE_HEADER *) HEADER_ALIGN (VariableHeader);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Find question default value from PcdNvStoreDefaultValueBuffer\r
+\r
+  @param DefaultId          Default store ID\r
+  @param EfiVarStore        Point to EFI VarStore header\r
+  @param IfrQuestionHdr     Point to Question header\r
+  @param ValueBuffer        Point to Buffer includes the found default setting\r
+  @param Width              Width of the default value\r
+  @param BitFieldQuestion   Whether the Question is stored in Bit field.\r
+\r
+  @retval EFI_SUCCESS       Question default value is found.\r
+  @retval EFI_NOT_FOUND     Question default value is not found.\r
+**/\r
+EFI_STATUS\r
+FindQuestionDefaultSetting (\r
+  IN  UINT16                  DefaultId,\r
+  IN  EFI_IFR_VARSTORE_EFI    *EfiVarStore,\r
+  IN  EFI_IFR_QUESTION_HEADER *IfrQuestionHdr,\r
+  OUT VOID                    *ValueBuffer,\r
+  IN  UINTN                   Width,\r
+  IN  BOOLEAN                 BitFieldQuestion\r
+  )\r
+{\r
+  VARIABLE_HEADER            *VariableHeader;\r
+  VARIABLE_STORE_HEADER      *VariableStorage;\r
+  LIST_ENTRY                 *Link;\r
+  VARSTORAGE_DEFAULT_DATA    *Entry;\r
+  VARIABLE_STORE_HEADER      *NvStoreBuffer;\r
+  UINT8        *DataBuffer;\r
+  UINT8        *BufferEnd;\r
+  BOOLEAN      IsFound;\r
+  UINTN        Index;\r
+  UINT32       BufferValue;\r
+  UINT32       BitFieldVal;\r
+  UINTN        BitOffset;\r
+  UINTN        ByteOffset;\r
+  UINTN        BitWidth;\r
+  UINTN        StartBit;\r
+  UINTN        EndBit;\r
+  PCD_DEFAULT_DATA *DataHeader;\r
+  PCD_DEFAULT_INFO *DefaultInfo;\r
+  PCD_DATA_DELTA   *DeltaData;\r
+\r
+  if (gSkuId == 0xFFFFFFFFFFFFFFFF) {\r
+    gSkuId = LibPcdGetSku ();\r
+  }\r
+\r
+  //\r
+  // Find the DefaultId setting from the full DefaultSetting\r
+  //\r
+  VariableStorage = NULL;\r
+  Link = gVarStorageList.ForwardLink;\r
+  while (Link != &gVarStorageList) {\r
+    Entry = BASE_CR (Link, VARSTORAGE_DEFAULT_DATA, Entry);\r
+    if (Entry->DefaultId == DefaultId) {\r
+      VariableStorage = Entry->VariableStorage;\r
+      break;\r
+    }\r
+    Link = Link->ForwardLink;\r
+  }\r
+\r
+  if (Link == &gVarStorageList) {\r
+    DataBuffer = (UINT8 *) PcdGetPtr (PcdNvStoreDefaultValueBuffer);\r
+    gNvDefaultStoreSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;\r
+    //\r
+    // The first section data includes NV storage default setting.\r
+    //\r
+    DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));\r
+    NvStoreBuffer  = (VARIABLE_STORE_HEADER *) ((UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);\r
+    VariableStorage   = AllocatePool (NvStoreBuffer->Size);\r
+    ASSERT (VariableStorage != NULL);\r
+    CopyMem (VariableStorage, NvStoreBuffer, NvStoreBuffer->Size);\r
+\r
+    //\r
+    // Find the matched SkuId and DefaultId in the first section\r
+    //\r
+    IsFound = FALSE;\r
+    DefaultInfo    = &(DataHeader->DefaultInfo[0]);\r
+    BufferEnd      = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
+    while ((UINT8 *) DefaultInfo < BufferEnd) {\r
+      if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == gSkuId) {\r
+        IsFound = TRUE;\r
+        break;\r
+      }\r
+      DefaultInfo ++;\r
+    }\r
+    //\r
+    // Find the matched SkuId and DefaultId in the remaining section\r
+    //\r
+    Index = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));\r
+    DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
+    while (!IsFound && Index < gNvDefaultStoreSize && DataHeader->DataSize != 0xFFFF) {\r
+      DefaultInfo = &(DataHeader->DefaultInfo[0]);\r
+      BufferEnd   = (UINT8 *) DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;\r
+      while ((UINT8 *) DefaultInfo < BufferEnd) {\r
+        if (DefaultInfo->DefaultId == DefaultId && DefaultInfo->SkuId == gSkuId) {\r
+          IsFound = TRUE;\r
+          break;\r
+        }\r
+        DefaultInfo ++;\r
+      }\r
+      if (IsFound) {\r
+        DeltaData = (PCD_DATA_DELTA *) BufferEnd;\r
+        BufferEnd = (UINT8 *) DataHeader + DataHeader->DataSize;\r
+        while ((UINT8 *) DeltaData < BufferEnd) {\r
+          *((UINT8 *) VariableStorage + DeltaData->Offset) = (UINT8) DeltaData->Value;\r
+          DeltaData ++;\r
+        }\r
+        break;\r
+      }\r
+      Index      = (Index + DataHeader->DataSize + 7) & (~7);\r
+      DataHeader = (PCD_DEFAULT_DATA *) (DataBuffer + Index);\r
+    }\r
+    //\r
+    // Cache the found result in VarStorageList\r
+    //\r
+    if (!IsFound) {\r
+      FreePool (VariableStorage);\r
+      VariableStorage = NULL;\r
+    }\r
+    Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));\r
+    if (Entry != NULL) {\r
+      Entry->DefaultId = DefaultId;\r
+      Entry->VariableStorage = VariableStorage;\r
+      InsertTailList (&gVarStorageList, &Entry->Entry);\r
+    } else if (VariableStorage != NULL) {\r
+      FreePool (VariableStorage);\r
+      VariableStorage = NULL;\r
+    }\r
+  }\r
+  //\r
+  // The matched variable storage is not found.\r
+  //\r
+  if (VariableStorage == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Find the question default value from the variable storage\r
+  //\r
+  VariableHeader = FindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *) EfiVarStore->Name);\r
+  if (VariableHeader == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  StartBit   = 0;\r
+  EndBit     = 0;\r
+  ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+  if (BitFieldQuestion) {\r
+    BitOffset  = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+    ByteOffset = BitOffset / 8;\r
+    BitWidth   = Width;\r
+    StartBit   = BitOffset % 8;\r
+    EndBit     = StartBit + BitWidth - 1;\r
+    Width      = EndBit / 8 + 1;\r
+  }\r
+  if (VariableHeader->DataSize < ByteOffset + Width) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Copy the question value\r
+  //\r
+  if (ValueBuffer != NULL) {\r
+    if (BitFieldQuestion) {\r
+      CopyMem (&BufferValue, (UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + ByteOffset, Width);\r
+      BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);\r
+      CopyMem (ValueBuffer, &BitFieldVal, Width);\r
+    } else {\r
+      CopyMem (ValueBuffer, (UINT8 *) VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update IFR default setting in Form Package.\r
+\r
+  @param  FormPackage              Form Package to be updated\r
+\r
+**/\r
+VOID\r
+UpdateDefaultSettingInFormPackage (\r
+  HII_IFR_PACKAGE_INSTANCE *FormPackage\r
+  )\r
+{\r
+  UINTN                    IfrOffset;\r
+  UINTN                    PackageLength;\r
+  EFI_IFR_VARSTORE_EFI     *IfrEfiVarStore;\r
+  EFI_IFR_OP_HEADER        *IfrOpHdr;\r
+  EFI_IFR_ONE_OF_OPTION    *IfrOneOfOption;\r
+  UINT8                    IfrQuestionType;\r
+  UINT8                    IfrScope;\r
+  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;\r
+  EFI_IFR_VARSTORE_EFI     **EfiVarStoreList;\r
+  UINTN                    EfiVarStoreMaxNum;\r
+  UINTN                    EfiVarStoreNumber;\r
+  UINT16                   *DefaultIdList;\r
+  UINTN                    DefaultIdNumber;\r
+  UINTN                    DefaultIdMaxNum;\r
+  UINTN                    Index;\r
+  UINTN                    EfiVarStoreIndex;\r
+  EFI_IFR_TYPE_VALUE       IfrValue;\r
+  EFI_IFR_TYPE_VALUE       IfrManufactValue;\r
+  BOOLEAN                  StandardDefaultIsSet;\r
+  BOOLEAN                  ManufactDefaultIsSet;\r
+  EFI_IFR_CHECKBOX         *IfrCheckBox;\r
+  EFI_STATUS               Status;\r
+  EFI_IFR_DEFAULT          *IfrDefault;\r
+  UINTN                    Width;\r
+  EFI_IFR_QUESTION_HEADER  VarStoreQuestionHeader;\r
+  BOOLEAN                  QuestionReferBitField;\r
+\r
+  //\r
+  // If no default setting, do nothing\r
+  //\r
+  if (gNvDefaultStoreSize == 0) {\r
+    gNvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);\r
+  }\r
+  if (gNvDefaultStoreSize < sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
+    return;\r
+  }\r
+\r
+  ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));\r
+  PackageLength = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);\r
+  Width         = 0;\r
+  IfrOffset     = 0;\r
+  IfrScope      = 0;\r
+  IfrOpHdr      = (EFI_IFR_OP_HEADER *) FormPackage->IfrData;\r
+  IfrQuestionHdr    = NULL;\r
+  IfrQuestionType   = 0;\r
+  EfiVarStoreMaxNum = 0;\r
+  EfiVarStoreNumber = 0;\r
+  DefaultIdMaxNum   = 0;\r
+  DefaultIdNumber   = 0;\r
+  EfiVarStoreList   = NULL;\r
+  DefaultIdList     = NULL;\r
+  StandardDefaultIsSet = FALSE;\r
+  ManufactDefaultIsSet = FALSE;\r
+  QuestionReferBitField = FALSE;\r
+\r
+  while (IfrOffset < PackageLength) {\r
+    switch (IfrOpHdr->OpCode) {\r
+    case EFI_IFR_VARSTORE_EFI_OP:\r
+      if (EfiVarStoreNumber >= EfiVarStoreMaxNum) {\r
+        //\r
+        // Reallocate EFI VarStore Buffer\r
+        //\r
+        EfiVarStoreList   = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);\r
+        if (EfiVarStoreList == NULL) {\r
+          goto Done;\r
+        }\r
+        EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;\r
+      }\r
+      IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+      //\r
+      // Convert VarStore Name from ASCII string to Unicode string.\r
+      //\r
+      EfiVarStoreList [EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));\r
+      if (EfiVarStoreList [EfiVarStoreNumber] == NULL) {\r
+        break;\r
+      }\r
+      CopyMem (EfiVarStoreList [EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *) &(EfiVarStoreList [EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+      Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);\r
+      if (!EFI_ERROR (Status)) {\r
+        EfiVarStoreNumber ++;\r
+      } else {\r
+        FreePool (EfiVarStoreList [EfiVarStoreNumber]);\r
+        EfiVarStoreList [EfiVarStoreNumber] = NULL;\r
+      }\r
+      break;\r
+    case EFI_IFR_DEFAULTSTORE_OP:\r
+      if (DefaultIdNumber >= DefaultIdMaxNum) {\r
+        //\r
+        // Reallocate DefaultIdNumber\r
+        //\r
+        DefaultIdList   = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);\r
+        if (DefaultIdList == NULL) {\r
+          goto Done;\r
+        }\r
+        DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;\r
+      }\r
+      DefaultIdList[DefaultIdNumber ++] = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId;\r
+      break;\r
+    case EFI_IFR_FORM_OP:\r
+    case EFI_IFR_FORM_MAP_OP:\r
+      //\r
+      // No EFI varstore is found and directly return.\r
+      //\r
+      if (EfiVarStoreNumber == 0 || DefaultIdNumber == 0) {\r
+        goto Done;\r
+      }\r
+      break;\r
+    case EFI_IFR_CHECKBOX_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      IfrCheckBox      = (EFI_IFR_CHECKBOX *) IfrOpHdr;\r
+      EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
+      Width            = sizeof (BOOLEAN);\r
+      if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
+        for (Index = 0; Index < DefaultIdNumber; Index ++) {\r
+          if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+            Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              if (IfrValue.b) {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT;\r
+              } else {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT);\r
+              }\r
+            }\r
+          } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+            Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              if (IfrValue.b) {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT_MFG;\r
+              } else {\r
+                IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT_MFG);\r
+              }\r
+            }\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_NUMERIC_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      if (QuestionReferBitField) {\r
+        Width          = (UINTN) (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);\r
+      } else {\r
+        Width          = (UINTN) ((UINT32) 1 << (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));\r
+      }\r
+      break;\r
+    case EFI_IFR_ONE_OF_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      if (QuestionReferBitField) {\r
+        Width          = (UINTN) (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);\r
+      } else {\r
+        Width          = (UINTN) ((UINT32) 1 << (((EFI_IFR_ONE_OF *) IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));\r
+      }\r
+      EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
+      StandardDefaultIsSet = FALSE;\r
+      ManufactDefaultIsSet = FALSE;\r
+      //\r
+      // Find Default and Manufacturing default for OneOf question\r
+      //\r
+      if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
+        for (Index = 0; Index < DefaultIdNumber; Index ++) {\r
+          if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+            Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, Width, QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              StandardDefaultIsSet = TRUE;\r
+            }\r
+          } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+            Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrManufactValue, Width, QuestionReferBitField);\r
+            if (!EFI_ERROR (Status)) {\r
+              ManufactDefaultIsSet = TRUE;\r
+            }\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_ORDERED_LIST_OP:\r
+      IfrScope         = IfrOpHdr->Scope;\r
+      IfrQuestionType  = IfrOpHdr->OpCode;\r
+      IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *) (IfrOpHdr + 1);\r
+      break;\r
+    case EFI_IFR_ONE_OF_OPTION_OP:\r
+      if (IfrQuestionHdr != NULL && IfrScope > 0) {\r
+        IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpHdr;\r
+        if (IfrQuestionType == EFI_IFR_ONE_OF_OP) {\r
+          Width = (UINTN) ((UINT32) 1 << (IfrOneOfOption->Flags & EFI_IFR_NUMERIC_SIZE));\r
+          if (StandardDefaultIsSet) {\r
+            if (CompareMem (&IfrOneOfOption->Value, &IfrValue, Width) == 0) {\r
+              IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;\r
+            } else {\r
+              IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT;\r
+            }\r
+          }\r
+          if (ManufactDefaultIsSet) {\r
+            if (CompareMem (&IfrOneOfOption->Value, &IfrManufactValue, Width) == 0) {\r
+              IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;\r
+            } else {\r
+              IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT_MFG;\r
+            }\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_DEFAULT_OP:\r
+      if (IfrQuestionHdr != NULL && IfrScope > 0) {\r
+        IfrDefault = (EFI_IFR_DEFAULT *) IfrOpHdr;\r
+        //\r
+        // Collect default value width\r
+        //\r
+        if (!QuestionReferBitField) {\r
+          Width = 0;\r
+          if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_8 || IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN) {\r
+            Width = 1;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_16) {\r
+            Width = 2;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_32) {\r
+            Width = 4;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_64) {\r
+            Width = 8;\r
+          } else if (IfrDefault->Type == EFI_IFR_TYPE_BUFFER) {\r
+            Width = IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value);\r
+          }\r
+        }\r
+        //\r
+        // Update the default value\r
+        //\r
+        if (Width > 0) {\r
+          EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);\r
+          if (EfiVarStoreIndex < EfiVarStoreNumber) {\r
+            Status = FindQuestionDefaultSetting (IfrDefault->DefaultId, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrDefault->Value, Width, QuestionReferBitField);\r
+          }\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_END_OP:\r
+      if (IfrQuestionHdr != NULL) {\r
+        if (IfrScope > 0) {\r
+          IfrScope --;\r
+        }\r
+        if (IfrScope == 0) {\r
+          IfrQuestionHdr = NULL;\r
+          QuestionReferBitField = FALSE;\r
+        }\r
+      }\r
+      break;\r
+    case EFI_IFR_GUID_OP:\r
+      if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+        QuestionReferBitField = TRUE;\r
+      }\r
+      break;\r
+    default:\r
+      break;\r
+    }\r
+    IfrOffset = IfrOffset + IfrOpHdr->Length;\r
+    IfrOpHdr  = (EFI_IFR_OP_HEADER *) ((UINT8 *) IfrOpHdr + IfrOpHdr->Length);\r
+    if (IfrScope > 0) {\r
+      IfrScope += IfrOpHdr->Scope;\r
+    }\r
+  }\r
+\r
+Done:\r
+  if (EfiVarStoreList != NULL) {\r
+    for (Index = 0; Index < EfiVarStoreNumber; Index ++) {\r
+      FreePool (EfiVarStoreList [Index]);\r
+    }\r
+  }\r
+  return;\r
+}\r
 \r
 /**\r
   This function insert a Form package to a package list node.\r
@@ -601,6 +1127,11 @@ InsertFormPackage (
   InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);\r
   *Package = FormPackage;\r
 \r
+  //\r
+  // Update FormPackage with the default setting\r
+  //\r
+  UpdateDefaultSettingInFormPackage (FormPackage);\r
+\r
   if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {\r
     PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;\r
   }\r
@@ -740,7 +1271,16 @@ RemoveFormPackages (
     PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;\r
     FreePool (Package->IfrData);\r
     FreePool (Package);\r
-\r
+    //\r
+    // If Hii runtime support feature is enabled,\r
+    // will export Hii info for runtime use after ReadyToBoot event triggered.\r
+    // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,\r
+    // will need to export the content of HiiDatabase.\r
+    // But if form packages removed, also need to export the ConfigResp string\r
+    //\r
+    if (gExportAfterReadyToBoot) {\r
+      gExportConfigResp = TRUE;\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -804,7 +1344,7 @@ InsertStringPackage (
   if (Language == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);\r
+  AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);\r
   for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {\r
     StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
     if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {\r
@@ -856,7 +1396,7 @@ InsertStringPackage (
   //\r
   // Collect all font block info\r
   //\r
-  Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId);\r
+  Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId, NULL);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -890,11 +1430,11 @@ Error:
 \r
 /**\r
  Adjust all string packages in a single package list to have the same max string ID.\r
\r
+\r
  @param  PackageList        Pointer to a package list which will be adjusted.\r
 \r
  @retval EFI_SUCCESS  Adjust all string packages successfully.\r
- @retval others       Can't adjust string packges.\r
+ @retval others       Can't adjust string packages.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1188,7 +1728,7 @@ InsertFontPackage (
   }\r
   FontInfo->FontStyle = FontPkgHdr->FontStyle;\r
   FontInfo->FontSize  = FontPkgHdr->Cell.Height;\r
-  StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily);\r
+  StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF(EFI_FONT_INFO,FontName)) / sizeof (CHAR16), FontPkgHdr->FontFamily);\r
 \r
   if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {\r
     Status = EFI_UNSUPPORTED;\r
@@ -1543,7 +2083,7 @@ InsertImagePackage (
   if (ImageInfoOffset != 0) {\r
     ImageSize = ImagePackage->ImagePkgHdr.Header.Length -\r
                 sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;\r
-    ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize);\r
+    ImagePackage->ImageBlock = AllocateZeroPool (ImageSize);\r
     if (ImagePackage->ImageBlock == NULL) {\r
       FreePool (ImagePackage->PaletteBlock);\r
       FreePool (ImagePackage);\r
@@ -2423,8 +2963,14 @@ AddPackages (
   //\r
   // Initialize Variables\r
   //\r
-  StringPkgIsAdd = FALSE;\r
-  FontPackage = NULL;\r
+  StringPkgIsAdd        = FALSE;\r
+  FontPackage           = NULL;\r
+  StringPackage         = NULL;\r
+  GuidPackage           = NULL;\r
+  FormPackage           = NULL;\r
+  ImagePackage          = NULL;\r
+  SimpleFontPackage     = NULL;\r
+  KeyboardLayoutPackage = NULL;\r
 \r
   //\r
   // Process the package list header\r
@@ -2481,6 +3027,16 @@ AddPackages (
                  (UINT8) (PackageHeader.Type),\r
                  DatabaseRecord->Handle\r
                  );\r
+      //\r
+      // If Hii runtime support feature is enabled,\r
+      // will export Hii info for runtime use after ReadyToBoot event triggered.\r
+      // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,\r
+      // will need to export the content of HiiDatabase.\r
+      // But if form packages added/updated, also need to export the ConfigResp string.\r
+      //\r
+      if (gExportAfterReadyToBoot) {\r
+        gExportConfigResp = TRUE;\r
+      }\r
       break;\r
     case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
       Status = InsertKeyboardLayoutPackage (\r
@@ -2511,6 +3067,7 @@ AddPackages (
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
+      ASSERT (StringPackage != NULL);\r
       Status = InvokeRegisteredFunction (\r
                  Private,\r
                  NotifyType,\r
@@ -2596,7 +3153,7 @@ AddPackages (
     PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
     CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
   }\r
-  \r
+\r
   //\r
   // Adjust String Package to make sure all string packages have the same max string ID.\r
   //\r
@@ -2774,6 +3331,108 @@ ExportPackageList (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+This function mainly use to get and update ConfigResp string.\r
+\r
+@param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.\r
+\r
+@retval EFI_SUCCESS            Get the information successfully.\r
+@retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Configuration Setting data.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiGetConfigRespInfo(\r
+  IN CONST EFI_HII_DATABASE_PROTOCOL        *This\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  HII_DATABASE_PRIVATE_DATA           *Private;\r
+  EFI_STRING                          ConfigAltResp;\r
+  UINTN                               ConfigSize;\r
+\r
+  ConfigAltResp        = NULL;\r
+  ConfigSize           = 0;\r
+\r
+  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // Get ConfigResp string\r
+  //\r
+  Status = HiiConfigRoutingExportConfig(&Private->ConfigRouting,&ConfigAltResp);\r
+\r
+  if (!EFI_ERROR (Status)){\r
+    ConfigSize = StrSize(ConfigAltResp);\r
+    if (ConfigSize > gConfigRespSize){\r
+      gConfigRespSize = ConfigSize;\r
+      if (gRTConfigRespBuffer != NULL){\r
+        FreePool(gRTConfigRespBuffer);\r
+      }\r
+      gRTConfigRespBuffer = (EFI_STRING)AllocateRuntimeZeroPool(ConfigSize);\r
+      if (gRTConfigRespBuffer == NULL){\r
+        FreePool(ConfigAltResp);\r
+        DEBUG ((DEBUG_ERROR, "Not enough memory resource to get the ConfigResp string.\n"));\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+    } else {\r
+      ZeroMem(gRTConfigRespBuffer,gConfigRespSize);\r
+    }\r
+    CopyMem(gRTConfigRespBuffer,ConfigAltResp,ConfigSize);\r
+    gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, gRTConfigRespBuffer);\r
+    FreePool(ConfigAltResp);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+This is an internal function,mainly use to get HiiDatabase information.\r
+\r
+@param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.\r
+\r
+@retval EFI_SUCCESS            Get the information successfully.\r
+@retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Hiidatabase data.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiGetDatabaseInfo(\r
+  IN CONST EFI_HII_DATABASE_PROTOCOL        *This\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_HII_PACKAGE_LIST_HEADER         *DatabaseInfo;\r
+  UINTN                               DatabaseInfoSize;\r
+\r
+  DatabaseInfo         = NULL;\r
+  DatabaseInfoSize     = 0;\r
+\r
+  //\r
+  // Get HiiDatabase information.\r
+  //\r
+  Status = HiiExportPackageLists(This, NULL, &DatabaseInfoSize, DatabaseInfo);\r
+\r
+  ASSERT(Status == EFI_BUFFER_TOO_SMALL);\r
+\r
+  if(DatabaseInfoSize > gDatabaseInfoSize ) {\r
+    gDatabaseInfoSize = DatabaseInfoSize;\r
+    if (gRTDatabaseInfoBuffer != NULL){\r
+      FreePool(gRTDatabaseInfoBuffer);\r
+    }\r
+    gRTDatabaseInfoBuffer = AllocateRuntimeZeroPool(DatabaseInfoSize);\r
+    if (gRTDatabaseInfoBuffer == NULL){\r
+      DEBUG ((DEBUG_ERROR, "Not enough memory resource to get the HiiDatabase info.\n"));\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  } else {\r
+    ZeroMem(gRTDatabaseInfoBuffer,gDatabaseInfoSize);\r
+  }\r
+  Status = HiiExportPackageLists(This, NULL, &DatabaseInfoSize, gRTDatabaseInfoBuffer);\r
+  ASSERT_EFI_ERROR (Status);\r
+  gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, gRTDatabaseInfoBuffer);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
 \r
 /**\r
   This function adds the packages in the package list to the database and returns a handle. If there is a\r
@@ -2827,17 +3486,20 @@ HiiNewPackageList (
     DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
     if (CompareGuid (\r
           &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
-          &PackageListGuid) && \r
+          &PackageListGuid) &&\r
         DatabaseRecord->DriverHandle == DriverHandle) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   //\r
   // Build a PackageList node\r
   //\r
   Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -2847,6 +3509,7 @@ HiiNewPackageList (
   //\r
   Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -2866,12 +3529,38 @@ HiiNewPackageList (
   }\r
 \r
   *Handle = DatabaseRecord->Handle;\r
+\r
+  //\r
+  // Check whether need to get the Database info.\r
+  // Only after ReadyToBoot, need to do the export.\r
+  //\r
+  if (gExportAfterReadyToBoot) {\r
+    HiiGetDatabaseInfo (This);\r
+  }\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+  //\r
+  // Notes:\r
+  // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+  // belong to the atomic behavior of Hii Database update.\r
+  // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+  // we can not think it belong to the atomic behavior of Hii Database update.\r
+  // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+  //\r
+\r
+  // Check whether need to get the configuration setting info from HII drivers.\r
+  // When after ReadyToBoot and need to do the export for form package add.\r
+  //\r
+  if (gExportAfterReadyToBoot && gExportConfigResp) {\r
+    HiiGetConfigRespInfo (This);\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  This function removes the package list that is associated with a handle Handle\r
+  This function removes the package list that is associated with Handle\r
   from the HII database. Before removing the package, any registered functions\r
   with the notification type REMOVE_PACK and the same package type will be called.\r
 \r
@@ -2882,7 +3571,7 @@ HiiNewPackageList (
 \r
   @retval EFI_SUCCESS            The data associated with the Handle was removed\r
                                  from  the HII database.\r
-  @retval EFI_NOT_FOUND          The specified andle is not in database.\r
+  @retval EFI_NOT_FOUND          The specified handle is not in database.\r
   @retval EFI_INVALID_PARAMETER  The Handle was not valid.\r
 \r
 **/\r
@@ -2908,6 +3597,8 @@ HiiRemovePackageList (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   //\r
@@ -2925,34 +3616,42 @@ HiiRemovePackageList (
       //\r
       Status = RemoveGuidPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFormPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveStringPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveImagePackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
 \r
@@ -2971,10 +3670,36 @@ HiiRemovePackageList (
       FreePool (Node->PackageList);\r
       FreePool (Node);\r
 \r
+      //\r
+      // Check whether need to get the Database info.\r
+      // Only after ReadyToBoot, need to do the export.\r
+      //\r
+      if (gExportAfterReadyToBoot) {\r
+        HiiGetDatabaseInfo (This);\r
+      }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
+\r
+      //\r
+      // Check whether need to get the configuration setting info from HII drivers.\r
+      // When after ReadyToBoot and need to do the export for form package remove.\r
+      //\r
+      if (gExportAfterReadyToBoot && gExportConfigResp) {\r
+        HiiGetConfigRespInfo (This);\r
+      }\r
       return EFI_SUCCESS;\r
     }\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3027,6 +3752,7 @@ HiiUpdatePackageList (
 \r
   Status = EFI_SUCCESS;\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
   //\r
   // Get original packagelist to be updated\r
   //\r
@@ -3068,6 +3794,7 @@ HiiUpdatePackageList (
         }\r
 \r
         if (EFI_ERROR (Status)) {\r
+          EfiReleaseLock (&mHiiDatabaseLock);\r
           return Status;\r
         }\r
 \r
@@ -3078,10 +3805,38 @@ HiiUpdatePackageList (
       //\r
       // Add all of the packages within the new package list\r
       //\r
-      return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
+      Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);\r
+\r
+      //\r
+      // Check whether need to get the Database info.\r
+      // Only after ReadyToBoot, need to do the export.\r
+      //\r
+      if (gExportAfterReadyToBoot && Status == EFI_SUCCESS) {\r
+        HiiGetDatabaseInfo (This);\r
+      }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
+\r
+      //\r
+      // Check whether need to get the configuration setting info from HII drivers.\r
+      // When after ReadyToBoot and need to do the export for form package update.\r
+      //\r
+      if (gExportAfterReadyToBoot && gExportConfigResp && Status == EFI_SUCCESS) {\r
+        HiiGetConfigRespInfo (This);\r
+      }\r
+\r
+      return Status;\r
     }\r
   }\r
-\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3105,18 +3860,19 @@ HiiUpdatePackageList (
                                  buffer that is required for the handles found.\r
   @param  Handle                 An array of EFI_HII_HANDLE instances returned.\r
 \r
-  @retval EFI_SUCCESS            The matching handles are outputed successfully.\r
-                                               HandleBufferLength is updated with the actual length.\r
+  @retval EFI_SUCCESS            The matching handles are outputted successfully.\r
+                                 HandleBufferLength is updated with the actual length.\r
   @retval EFI_BUFFER_TO_SMALL    The HandleBufferLength parameter indicates that\r
                                  Handle is too small to support the number of\r
                                  handles. HandleBufferLength is updated with a\r
                                  value that will  enable the data to fit.\r
   @retval EFI_NOT_FOUND          No matching handle could not be found in database.\r
-  @retval EFI_INVALID_PARAMETER  Handle or HandleBufferLength was NULL.\r
-  \r
+  @retval EFI_INVALID_PARAMETER  HandleBufferLength was NULL.\r
+  @retval EFI_INVALID_PARAMETER  The value referenced by HandleBufferLength was not\r
+                                 zero and Handle was NULL.\r
   @retval EFI_INVALID_PARAMETER  PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but\r
-                                                     PackageGuid is not NULL, PackageType is a EFI_HII_\r
-                                                     PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
+                                 PackageGuid is not NULL, PackageType is a EFI_HII_\r
+                                 PACKAGE_TYPE_GUID but PackageGuid is NULL.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -3210,7 +3966,7 @@ HiiListPackageLists (
         }\r
         break;\r
         //\r
-        // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
+        // Pseudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles\r
         // to be listed.\r
         //\r
       case EFI_HII_PACKAGE_TYPE_ALL:\r
@@ -3267,9 +4023,11 @@ HiiListPackageLists (
                                  Handle is too small to support the number of\r
                                  handles.      HandleBufferLength is updated with a\r
                                  value that will enable the data to fit.\r
-  @retval EFI_NOT_FOUND          The specifiecd Handle could not be found in the\r
+  @retval EFI_NOT_FOUND          The specified Handle could not be found in the\r
                                  current database.\r
-  @retval EFI_INVALID_PARAMETER  Handle or Buffer or BufferSize was NULL.\r
+  @retval EFI_INVALID_PARAMETER  BufferSize was NULL.\r
+  @retval EFI_INVALID_PARAMETER  The value referenced by BufferSize was not zero\r
+                                 and Buffer was NULL.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -3287,13 +4045,13 @@ HiiExportPackageLists (
   HII_DATABASE_RECORD                 *Node;\r
   UINTN                               UsedSize;\r
 \r
-  if (This == NULL || BufferSize == NULL || Handle == NULL) {\r
+  if (This == NULL || BufferSize == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (*BufferSize > 0 && Buffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (!IsHiiHandleValid (Handle)) {\r
+  if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -3419,7 +4177,7 @@ HiiRegisterPackageNotify (
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Notify->NotifyHandle,\r
-                  &mHiiDatabaseNotifyGuid,\r
+                  &gEfiCallerIdGuid,\r
                   NULL,\r
                   NULL\r
                   );\r
@@ -3477,7 +4235,7 @@ HiiUnregisterPackageNotify (
 \r
   Status = gBS->OpenProtocol (\r
                   NotificationHandle,\r
-                  &mHiiDatabaseNotifyGuid,\r
+                  &gEfiCallerIdGuid,\r
                   NULL,\r
                   NULL,\r
                   NULL,\r
@@ -3498,7 +4256,7 @@ HiiUnregisterPackageNotify (
       RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
       Status = gBS->UninstallMultipleProtocolInterfaces (\r
                       Notify->NotifyHandle,\r
-                      &mHiiDatabaseNotifyGuid,\r
+                      &gEfiCallerIdGuid,\r
                       NULL,\r
                       NULL\r
                       );\r
@@ -3531,7 +4289,9 @@ HiiUnregisterPackageNotify (
                                  number of GUIDs. KeyGuidBufferLength is\r
                                  updated with a value that will enable the data to\r
                                  fit.\r
-  @retval EFI_INVALID_PARAMETER  The KeyGuidBuffer or KeyGuidBufferLength was NULL.\r
+  @retval EFI_INVALID_PARAMETER  The KeyGuidBufferLength is NULL.\r
+  @retval EFI_INVALID_PARAMETER  The value referenced by KeyGuidBufferLength is not\r
+                                 zero and KeyGuidBuffer is NULL.\r
   @retval EFI_NOT_FOUND          There was no keyboard layout.\r
 \r
 **/\r