]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg HiiDataBase: Fix the potential NULL pointer reference
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Database.c
index b5a5c43b43c568286eb6152efd6769fba78e2083..4a2dc8d0304399810344f05b5d246a57f5f3d66b 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
+Implementation for EFI_HII_DATABASE_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\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
 http://opensource.org/licenses/bsd-license.php\r
@@ -9,33 +10,28 @@ http://opensource.org/licenses/bsd-license.php
 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
 \r
-Module Name:\r
-\r
-    Database.c\r
-\r
-Abstract:\r
-\r
-    Implementation for EFI_HII_DATABASE_PROTOCOL.\r
-\r
-Revision History\r
-\r
-\r
 **/\r
 \r
 \r
 #include "HiiDatabase.h"\r
 \r
-//\r
-// Global variables\r
-//\r
-STATIC EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID;\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 = TRUE;\r
+UINTN                          gNvDefaultStoreSize = 0;\r
+SKU_ID                         gSkuId              = 0xFFFFFFFFFFFFFFFF;\r
+LIST_ENTRY                     gVarStorageList     = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);\r
 \r
 /**\r
   This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
+  This is a internal function.\r
 \r
   @param  Private                hii database private structure\r
-  @param  DatabaseRecord         HII_DATABASE_RECORD node which is used to store a\r
+  @param  DatabaseNode           HII_DATABASE_RECORD node which is used to store a\r
                                  package list\r
 \r
   @retval EFI_SUCCESS            A database record is generated successfully.\r
@@ -44,7 +40,6 @@ STATIC EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID;
   @retval EFI_INVALID_PARAMETER  Private is NULL or DatabaseRecord is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GenerateHiiDatabaseRecord (\r
   IN  HII_DATABASE_PRIVATE_DATA *Private,\r
@@ -67,7 +62,7 @@ GenerateHiiDatabaseRecord (
 \r
   DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));\r
   if (DatabaseRecord->PackageList == NULL) {\r
-    SafeFreePool (DatabaseRecord);\r
+    FreePool (DatabaseRecord);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -87,8 +82,8 @@ GenerateHiiDatabaseRecord (
   //\r
   HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE));\r
   if (HiiHandle == NULL) {\r
-    SafeFreePool (DatabaseRecord->PackageList);\r
-    SafeFreePool (DatabaseRecord);\r
+    FreePool (DatabaseRecord->PackageList);\r
+    FreePool (DatabaseRecord);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   HiiHandle->Signature = HII_HANDLE_SIGNATURE;\r
@@ -96,7 +91,7 @@ GenerateHiiDatabaseRecord (
   // Backup the number of Hii handles\r
   //\r
   Private->HiiHandleCount++;\r
-  HiiHandle->Key = Private->HiiHandleCount;\r
+  HiiHandle->Key = (UINTN) Private->HiiHandleCount;\r
   //\r
   // Insert the handle to hii handle list of the whole database.\r
   //\r
@@ -118,6 +113,7 @@ GenerateHiiDatabaseRecord (
 \r
 /**\r
   This function checks whether a handle is a valid EFI_HII_HANDLE\r
+  This is a internal function.\r
 \r
   @param  Handle                 Pointer to a EFI_HII_HANDLE\r
 \r
@@ -148,6 +144,7 @@ IsHiiHandleValid (
 \r
 /**\r
   This function invokes the matching registered function.\r
+  This is a internal function.\r
 \r
   @param  Private                HII Database driver private structure.\r
   @param  NotifyType             The type of change concerning the database.\r
@@ -162,7 +159,6 @@ IsHiiHandleValid (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InvokeRegisteredFunction (\r
   IN HII_DATABASE_PRIVATE_DATA    *Private,\r
@@ -203,7 +199,7 @@ InvokeRegisteredFunction (
     Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg);\r
     break;\r
 \r
-  case EFI_HII_PACKAGE_FORM:\r
+  case EFI_HII_PACKAGE_FORMS:\r
     BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length;\r
     Buffer = (UINT8 *) AllocateZeroPool (BufferSize);\r
     ASSERT (Buffer != NULL);\r
@@ -348,8 +344,9 @@ InvokeRegisteredFunction (
     }\r
   }\r
 \r
-  SafeFreePool (Buffer);\r
-  Buffer = NULL;\r
+  if (Buffer != NULL) {\r
+    FreePool (Buffer);\r
+  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -357,13 +354,14 @@ InvokeRegisteredFunction (
 \r
 /**\r
   This function insert a GUID package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  PackageHdr             Pointer to a buffer stored with GUID package\r
                                  information.\r
   @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
@@ -371,7 +369,6 @@ InvokeRegisteredFunction (
   @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertGuidPackage (\r
   IN     VOID                               *PackageHdr,\r
@@ -398,7 +395,7 @@ InsertGuidPackage (
   }\r
   GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);\r
   if (GuidPackage->GuidPkg == NULL) {\r
-    SafeFreePool (GuidPackage);\r
+    FreePool (GuidPackage);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -417,6 +414,7 @@ InsertGuidPackage (
 \r
 /**\r
   This function exports GUID packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -431,7 +429,6 @@ InsertGuidPackage (
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportGuidPackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -485,6 +482,7 @@ ExportGuidPackages (
 \r
 /**\r
   This function deletes all GUID packages from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -496,7 +494,6 @@ ExportGuidPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveGuidPackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -532,16 +529,534 @@ RemoveGuidPackages (
     RemoveEntryList (&Package->GuidEntry);\r
     CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
     PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
-    SafeFreePool (Package->GuidPkg);\r
-    SafeFreePool (Package);\r
+    FreePool (Package->GuidPkg);\r
+    FreePool (Package);\r
   }\r
 \r
   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
+    Entry->DefaultId = DefaultId;\r
+    Entry->VariableStorage = VariableStorage;\r
+    InsertTailList (&gVarStorageList, &Entry->Entry);\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 + 1);\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
+  This is a internal function.\r
 \r
   @param  PackageHdr             Pointer to a buffer stored with Form package\r
                                  information.\r
@@ -556,7 +1071,6 @@ RemoveGuidPackages (
   @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertFormPackage (\r
   IN     VOID                               *PackageHdr,\r
@@ -587,7 +1101,7 @@ InsertFormPackage (
 \r
   FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));\r
   if (FormPackage->IfrData == NULL) {\r
-    SafeFreePool (FormPackage);\r
+    FreePool (FormPackage);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -609,6 +1123,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
@@ -618,6 +1137,7 @@ InsertFormPackage (
 \r
 /**\r
   This function exports Form packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -632,7 +1152,6 @@ InsertFormPackage (
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportFormPackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -666,7 +1185,7 @@ ExportFormPackages (
   for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {\r
     FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);\r
     PackageLength += FormPackage->FormPkgHdr.Length;\r
-    if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
+    if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {\r
       //\r
       // Invoke registered notification if exists\r
       //\r
@@ -674,7 +1193,7 @@ ExportFormPackages (
                  Private,\r
                  EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,\r
                  (VOID *) FormPackage,\r
-                 EFI_HII_PACKAGE_FORM,\r
+                 EFI_HII_PACKAGE_FORMS,\r
                  Handle\r
                  );\r
       ASSERT_EFI_ERROR (Status);\r
@@ -701,6 +1220,7 @@ ExportFormPackages (
 \r
 /**\r
   This function deletes all Form packages from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -712,7 +1232,6 @@ ExportFormPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveFormPackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -737,7 +1256,7 @@ RemoveFormPackages (
                Private,\r
                EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
                (VOID *) Package,\r
-               EFI_HII_PACKAGE_FORM,\r
+               EFI_HII_PACKAGE_FORMS,\r
                Handle\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -746,9 +1265,18 @@ RemoveFormPackages (
 \r
     RemoveEntryList (&Package->IfrEntry);\r
     PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;\r
-    SafeFreePool (Package->IfrData);\r
-    SafeFreePool (Package);\r
-\r
+    FreePool (Package->IfrData);\r
+    FreePool (Package);\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
@@ -758,6 +1286,7 @@ RemoveFormPackages (
 \r
 /**\r
   This function insert a String package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  PackageHdr             Pointer to a buffer stored with String package\r
@@ -775,7 +1304,6 @@ RemoveFormPackages (
                                  exists in current package list.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertStringPackage (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -783,7 +1311,6 @@ InsertStringPackage (
   IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,\r
   IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
   OUT    HII_STRING_PACKAGE_INSTANCE        **Package\r
-\r
   )\r
 {\r
   HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
@@ -813,15 +1340,15 @@ 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 (R8_EfiLibCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {\r
-      SafeFreePool (Language);\r
+    if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {\r
+      FreePool (Language);\r
       return EFI_UNSUPPORTED;\r
     }\r
   }\r
-  SafeFreePool (Language);\r
+  FreePool (Language);\r
 \r
   //\r
   // Create a String package node\r
@@ -865,7 +1392,7 @@ InsertStringPackage (
   //\r
   // Collect all font block info\r
   //\r
-  Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL);\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
@@ -884,16 +1411,100 @@ InsertStringPackage (
 \r
 Error:\r
 \r
-  SafeFreePool (StringPackage->StringBlock);\r
-  SafeFreePool (StringPackage->StringPkgHdr);\r
-  SafeFreePool (StringPackage);\r
+  if (StringPackage != NULL) {\r
+    if (StringPackage->StringBlock != NULL) {\r
+      FreePool (StringPackage->StringBlock);\r
+    }\r
+    if (StringPackage->StringPkgHdr != NULL) {\r
+      FreePool (StringPackage->StringPkgHdr);\r
+    }\r
+    FreePool (StringPackage);\r
+  }\r
   return Status;\r
 \r
 }\r
 \r
+/**\r
+ Adjust all string packages in a single package list to have the same max string ID.\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 packages.\r
+\r
+**/\r
+EFI_STATUS\r
+AdjustStringPackage (\r
+  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
+)\r
+{\r
+  LIST_ENTRY                  *Link;\r
+  HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
+  UINT32                      Skip2BlockSize;\r
+  UINT32                      OldBlockSize;\r
+  UINT8                       *StringBlock;\r
+  UINT8                       *BlockPtr;\r
+  EFI_STRING_ID               MaxStringId;\r
+  UINT16                      SkipCount;\r
+\r
+  MaxStringId = 0;\r
+  for (Link = PackageList->StringPkgHdr.ForwardLink;\r
+       Link != &PackageList->StringPkgHdr;\r
+       Link = Link->ForwardLink\r
+      ) {\r
+    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
+    if (MaxStringId < StringPackage->MaxStringId) {\r
+      MaxStringId = StringPackage->MaxStringId;\r
+    }\r
+  }\r
+\r
+  for (Link = PackageList->StringPkgHdr.ForwardLink;\r
+       Link != &PackageList->StringPkgHdr;\r
+       Link = Link->ForwardLink\r
+      ) {\r
+    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
+    if (StringPackage->MaxStringId < MaxStringId) {\r
+      OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
+      //\r
+      // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.\r
+      //\r
+      SkipCount      = (UINT16) (MaxStringId - StringPackage->MaxStringId);\r
+      Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+\r
+      StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize);\r
+      if (StringBlock == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+      //\r
+      // Copy original string blocks, except the EFI_HII_SIBT_END.\r
+      //\r
+      CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
+      //\r
+      // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks\r
+      //\r
+      BlockPtr  = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
+      *BlockPtr = EFI_HII_SIBT_SKIP2;\r
+      CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));\r
+      BlockPtr  += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+\r
+      //\r
+      // Append a EFI_HII_SIBT_END block to the end.\r
+      //\r
+      *BlockPtr = EFI_HII_SIBT_END;\r
+      FreePool (StringPackage->StringBlock);\r
+      StringPackage->StringBlock = StringBlock;\r
+      StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;\r
+      PackageList->PackageListHdr.PackageLength += Skip2BlockSize;\r
+      StringPackage->MaxStringId = MaxStringId;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   This function exports String packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -908,7 +1519,6 @@ Error:
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportStringPackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -976,6 +1586,7 @@ ExportStringPackages (
 \r
 /**\r
   This function deletes all String packages from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -987,7 +1598,6 @@ ExportStringPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveStringPackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1022,8 +1632,8 @@ RemoveStringPackages (
 \r
     RemoveEntryList (&Package->StringEntry);\r
     PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;\r
-    SafeFreePool (Package->StringBlock);\r
-    SafeFreePool (Package->StringPkgHdr);\r
+    FreePool (Package->StringBlock);\r
+    FreePool (Package->StringPkgHdr);\r
     //\r
     // Delete font information\r
     //\r
@@ -1035,10 +1645,10 @@ RemoveStringPackages (
                    HII_FONT_INFO_SIGNATURE\r
                    );\r
       RemoveEntryList (&FontInfo->Entry);\r
-      SafeFreePool (FontInfo);\r
+      FreePool (FontInfo);\r
     }\r
 \r
-    SafeFreePool (Package);\r
+    FreePool (Package);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1047,6 +1657,7 @@ RemoveStringPackages (
 \r
 /**\r
   This function insert a Font package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  PackageHdr             Pointer to a buffer stored with Font package\r
@@ -1064,7 +1675,6 @@ RemoveStringPackages (
                                  exists in current hii database.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertFontPackage (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1114,7 +1724,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
@@ -1177,11 +1787,21 @@ InsertFontPackage (
 \r
 Error:\r
 \r
-  SafeFreePool (FontPkgHdr);\r
-  SafeFreePool (FontInfo);\r
-  SafeFreePool (FontPackage->GlyphBlock);\r
-  SafeFreePool (FontPackage);\r
-  SafeFreePool (GlobalFont);\r
+  if (FontPkgHdr != NULL) {\r
+    FreePool (FontPkgHdr);\r
+  }\r
+  if (FontInfo != NULL) {\r
+    FreePool (FontInfo);\r
+  }\r
+  if (FontPackage != NULL) {\r
+    if (FontPackage->GlyphBlock != NULL) {\r
+      FreePool (FontPackage->GlyphBlock);\r
+    }\r
+    FreePool (FontPackage);\r
+  }\r
+  if (GlobalFont != NULL) {\r
+    FreePool (GlobalFont);\r
+  }\r
 \r
   return Status;\r
 \r
@@ -1190,6 +1810,7 @@ Error:
 \r
 /**\r
   This function exports Font packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -1204,7 +1825,6 @@ Error:
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportFontPackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1273,6 +1893,7 @@ ExportFontPackages (
 \r
 /**\r
   This function deletes all Font packages from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -1284,7 +1905,6 @@ ExportFontPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveFontPackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1321,8 +1941,11 @@ RemoveFontPackages (
 \r
     RemoveEntryList (&Package->FontEntry);\r
     PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;\r
-    SafeFreePool (Package->GlyphBlock);\r
-    SafeFreePool (Package->FontPkgHdr);\r
+\r
+    if (Package->GlyphBlock != NULL) {\r
+      FreePool (Package->GlyphBlock);\r
+    }\r
+    FreePool (Package->FontPkgHdr);\r
     //\r
     // Delete default character cell information\r
     //\r
@@ -1334,7 +1957,7 @@ RemoveFontPackages (
                     HII_GLYPH_INFO_SIGNATURE\r
                     );\r
       RemoveEntryList (&GlyphInfo->Entry);\r
-      SafeFreePool (GlyphInfo);\r
+      FreePool (GlyphInfo);\r
     }\r
 \r
     //\r
@@ -1344,13 +1967,13 @@ RemoveFontPackages (
       GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
       if (GlobalFont->FontPackage == Package) {\r
         RemoveEntryList (&GlobalFont->Entry);\r
-        SafeFreePool (GlobalFont->FontInfo);\r
-        SafeFreePool (GlobalFont);\r
+        FreePool (GlobalFont->FontInfo);\r
+        FreePool (GlobalFont);\r
         break;\r
       }\r
     }\r
 \r
-    SafeFreePool (Package);\r
+    FreePool (Package);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1359,6 +1982,7 @@ RemoveFontPackages (
 \r
 /**\r
   This function insert a Image package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  PackageHdr             Pointer to a buffer stored with Image package\r
                                  information.\r
@@ -1373,7 +1997,6 @@ RemoveFontPackages (
   @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertImagePackage (\r
   IN     VOID                               *PackageHdr,\r
@@ -1438,7 +2061,7 @@ InsertImagePackage (
 \r
     ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);\r
     if (ImagePackage->PaletteBlock == NULL) {\r
-      SafeFreePool (ImagePackage);\r
+      FreePool (ImagePackage);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     CopyMem (\r
@@ -1456,10 +2079,10 @@ 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
-      SafeFreePool (ImagePackage->PaletteBlock);\r
-      SafeFreePool (ImagePackage);\r
+      FreePool (ImagePackage->PaletteBlock);\r
+      FreePool (ImagePackage);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     CopyMem (\r
@@ -1484,6 +2107,7 @@ InsertImagePackage (
 \r
 /**\r
   This function exports Image packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -1498,7 +2122,6 @@ InsertImagePackage (
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportImagePackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1575,6 +2198,7 @@ ExportImagePackages (
 \r
 /**\r
   This function deletes Image package from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -1586,7 +2210,6 @@ ExportImagePackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveImagePackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1619,9 +2242,11 @@ RemoveImagePackages (
 \r
   PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;\r
 \r
-  SafeFreePool (Package->ImageBlock);\r
-  SafeFreePool (Package->PaletteBlock);\r
-  SafeFreePool (Package);\r
+  FreePool (Package->ImageBlock);\r
+  if (Package->PaletteBlock != NULL) {\r
+    FreePool (Package->PaletteBlock);\r
+  }\r
+  FreePool (Package);\r
 \r
   PackageList->ImagePkg = NULL;\r
 \r
@@ -1631,6 +2256,7 @@ RemoveImagePackages (
 \r
 /**\r
   This function insert a Simple Font package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  PackageHdr             Pointer to a buffer stored with Simple Font\r
                                  package information.\r
@@ -1645,7 +2271,6 @@ RemoveImagePackages (
   @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertSimpleFontPackage (\r
   IN     VOID                               *PackageHdr,\r
@@ -1699,14 +2324,19 @@ InsertSimpleFontPackage (
 \r
 Error:\r
 \r
-  SafeFreePool (SimpleFontPackage->SimpleFontPkgHdr);\r
-  SafeFreePool (SimpleFontPackage);\r
+  if (SimpleFontPackage != NULL) {\r
+    if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {\r
+      FreePool (SimpleFontPackage->SimpleFontPkgHdr);\r
+    }\r
+    FreePool (SimpleFontPackage);\r
+  }\r
   return Status;\r
 }\r
 \r
 \r
 /**\r
   This function exports SimpleFont packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -1721,7 +2351,6 @@ Error:
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportSimpleFontPackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1780,6 +2409,7 @@ ExportSimpleFontPackages (
 \r
 /**\r
   This function deletes all Simple Font packages from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -1791,7 +2421,6 @@ ExportSimpleFontPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveSimpleFontPackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1825,8 +2454,8 @@ RemoveSimpleFontPackages (
 \r
     RemoveEntryList (&Package->SimpleFontEntry);\r
     PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;\r
-    SafeFreePool (Package->SimpleFontPkgHdr);\r
-    SafeFreePool (Package);\r
+    FreePool (Package->SimpleFontPkgHdr);\r
+    FreePool (Package);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -1835,6 +2464,7 @@ RemoveSimpleFontPackages (
 \r
 /**\r
   This function insert a Device path package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  DevicePath             Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol\r
                                  instance\r
@@ -1848,7 +2478,6 @@ RemoveSimpleFontPackages (
   @retval EFI_INVALID_PARAMETER  DevicePath is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertDevicePathPackage (\r
   IN     EFI_DEVICE_PATH_PROTOCOL           *DevicePath,\r
@@ -1895,6 +2524,7 @@ InsertDevicePathPackage (
 \r
 /**\r
   This function exports device path package to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -1909,7 +2539,6 @@ InsertDevicePathPackage (
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportDevicePathPackage (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -1966,6 +2595,7 @@ ExportDevicePathPackage (
 \r
 /**\r
   This function deletes Device Path package from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list.\r
@@ -1976,7 +2606,6 @@ ExportDevicePathPackage (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveDevicePathPackage (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -2011,7 +2640,7 @@ RemoveDevicePathPackage (
   CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
   PackageList->PackageListHdr.PackageLength -= Header.Length;\r
 \r
-  SafeFreePool (Package);\r
+  FreePool (Package);\r
 \r
   PackageList->DevicePathPkg = NULL;\r
 \r
@@ -2022,6 +2651,7 @@ RemoveDevicePathPackage (
 /**\r
   This function will insert a device path package to package list firstly then\r
   invoke notification functions if any.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  NotifyType             The type of change concerning the database.\r
@@ -2036,7 +2666,6 @@ RemoveDevicePathPackage (
   @retval EFI_INVALID_PARAMETER  DevicePath is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 AddDevicePathPackage (\r
   IN HII_DATABASE_PRIVATE_DATA        *Private,\r
@@ -2078,6 +2707,7 @@ AddDevicePathPackage (
 \r
 /**\r
   This function insert a Keyboard Layout package to a package list node.\r
+  This is a internal function.\r
 \r
   @param  PackageHdr             Pointer to a buffer stored with Keyboard Layout\r
                                  package information.\r
@@ -2092,7 +2722,6 @@ AddDevicePathPackage (
   @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InsertKeyboardLayoutPackage (\r
   IN     VOID                               *PackageHdr,\r
@@ -2140,8 +2769,13 @@ InsertKeyboardLayoutPackage (
 \r
 Error:\r
 \r
-  SafeFreePool (KeyboardLayoutPackage->KeyboardPkg);\r
-  SafeFreePool (KeyboardLayoutPackage);\r
+\r
+  if (KeyboardLayoutPackage != NULL) {\r
+    if (KeyboardLayoutPackage->KeyboardPkg != NULL) {\r
+      FreePool (KeyboardLayoutPackage->KeyboardPkg);\r
+    }\r
+    FreePool (KeyboardLayoutPackage);\r
+  }\r
 \r
   return Status;\r
 }\r
@@ -2149,6 +2783,7 @@ Error:
 \r
 /**\r
   This function exports Keyboard Layout packages to a buffer.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
@@ -2164,7 +2799,6 @@ Error:
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportKeyboardLayoutPackages (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -2225,6 +2859,7 @@ ExportKeyboardLayoutPackages (
 \r
 /**\r
   This function deletes all Keyboard Layout packages from a package list node.\r
+  This is a internal function.\r
 \r
   @param  Private                Hii database private data.\r
   @param  Handle                 Handle of the package list which contains the to\r
@@ -2237,7 +2872,6 @@ ExportKeyboardLayoutPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RemoveKeyboardLayoutPackages (\r
   IN     HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -2273,8 +2907,8 @@ RemoveKeyboardLayoutPackages (
     RemoveEntryList (&Package->KeyboardEntry);\r
     CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));\r
     PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;\r
-    SafeFreePool (Package->KeyboardPkg);\r
-    SafeFreePool (Package);\r
+    FreePool (Package->KeyboardPkg);\r
+    FreePool (Package);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -2286,6 +2920,8 @@ RemoveKeyboardLayoutPackages (
   invoke notification functions if any. It is the worker function of\r
   HiiNewPackageList and HiiUpdatePackageList.\r
 \r
+  This is a internal function.\r
+\r
   @param  Private                Hii database private structure.\r
   @param  NotifyType             The type of change concerning the database.\r
   @param  PackageList            Pointer to a package list.\r
@@ -2299,7 +2935,6 @@ RemoveKeyboardLayoutPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 AddPackages (\r
   IN HII_DATABASE_PRIVATE_DATA         *Private,\r
@@ -2319,11 +2954,19 @@ AddPackages (
   EFI_HII_PACKAGE_HEADER               *PackageHdrPtr;\r
   EFI_HII_PACKAGE_HEADER               PackageHeader;\r
   UINT32                               OldPackageListLen;\r
+  BOOLEAN                              StringPkgIsAdd;\r
 \r
   //\r
   // Initialize Variables\r
   //\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
@@ -2363,7 +3006,7 @@ AddPackages (
                  DatabaseRecord->Handle\r
                  );\r
       break;\r
-    case EFI_HII_PACKAGE_FORM:\r
+    case EFI_HII_PACKAGE_FORMS:\r
       Status = InsertFormPackage (\r
                  PackageHdrPtr,\r
                  NotifyType,\r
@@ -2380,6 +3023,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
@@ -2410,6 +3063,7 @@ AddPackages (
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
+      ASSERT (StringPackage != NULL);\r
       Status = InvokeRegisteredFunction (\r
                  Private,\r
                  NotifyType,\r
@@ -2417,6 +3071,7 @@ AddPackages (
                  (UINT8) (PackageHeader.Type),\r
                  DatabaseRecord->Handle\r
                  );\r
+      StringPkgIsAdd = TRUE;\r
       break;\r
     case EFI_HII_PACKAGE_FONTS:\r
       Status = InsertFontPackage (\r
@@ -2494,6 +3149,13 @@ AddPackages (
     PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
     CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
   }\r
+  \r
+  //\r
+  // Adjust String Package to make sure all string packages have the same max string ID.\r
+  //\r
+  if (!EFI_ERROR (Status) && StringPkgIsAdd) {\r
+    Status = AdjustStringPackage (DatabaseRecord->PackageList);\r
+  }\r
 \r
   return Status;\r
 }\r
@@ -2503,6 +3165,8 @@ AddPackages (
   This function exports a package list to a buffer. It is the worker function\r
   of HiiExportPackageList.\r
 \r
+  This is a internal function.\r
+\r
   @param  Private                Hii database private structure.\r
   @param  Handle                 Identification of a package list.\r
   @param  PackageList            Pointer to a package list which will be exported.\r
@@ -2516,7 +3180,6 @@ AddPackages (
   @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ExportPackageList (\r
   IN HII_DATABASE_PRIVATE_DATA          *Private,\r
@@ -2531,7 +3194,7 @@ ExportPackageList (
   UINTN                               ResultSize;\r
   EFI_HII_PACKAGE_HEADER              EndofPackageList;\r
 \r
-  ASSERT (Private != NULL || PackageList != NULL || UsedSize != NULL);\r
+  ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);\r
   ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
   ASSERT (IsHiiHandleValid (Handle));\r
 \r
@@ -2664,6 +3327,141 @@ 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 mainly use to get and update configuration settings 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 Configuration Setting data.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiGetConfigurationSetting(\r
+  IN CONST EFI_HII_DATABASE_PROTOCOL        *This\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+\r
+  //\r
+  // Get the HiiDatabase info.\r
+  //\r
+  Status = HiiGetDatabaseInfo(This);\r
+\r
+  //\r
+  // Get ConfigResp string\r
+  //\r
+  if (gExportConfigResp) {\r
+    Status = HiiGetConfigRespInfo (This);\r
+    gExportConfigResp = FALSE;\r
+  }\r
+  return Status;\r
+\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
@@ -2675,6 +3473,8 @@ ExportPackageList (
   @param  PackageList            A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
                                  structure.\r
   @param  DriverHandle           Associate the package list with this EFI handle.\r
+                                 If a NULL is specified, this data will not be associate\r
+                                 with any drivers and cannot have a callback induced.\r
   @param  Handle                 A pointer to the EFI_HII_HANDLE instance.\r
 \r
   @retval EFI_SUCCESS            The package list associated with the Handle was\r
@@ -2690,7 +3490,7 @@ EFIAPI
 HiiNewPackageList (\r
   IN CONST EFI_HII_DATABASE_PROTOCOL    *This,\r
   IN CONST EFI_HII_PACKAGE_LIST_HEADER  *PackageList,\r
-  IN CONST EFI_HANDLE                   DriverHandle,\r
+  IN CONST EFI_HANDLE                   DriverHandle, OPTIONAL\r
   OUT EFI_HII_HANDLE                    *Handle\r
   )\r
 {\r
@@ -2715,9 +3515,8 @@ HiiNewPackageList (
     DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
     if (CompareGuid (\r
           &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
-          &PackageListGuid\r
-          )\r
-        ) {\r
+          &PackageListGuid) && \r
+        DatabaseRecord->DriverHandle == DriverHandle) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
@@ -2755,12 +3554,21 @@ HiiNewPackageList (
   }\r
 \r
   *Handle = DatabaseRecord->Handle;\r
+\r
+  //\r
+  // Check whether need to get the Database and configuration setting info.\r
+  // Only after ReadyToBoot, need to do the export.\r
+  //\r
+  if (gExportAfterReadyToBoot) {\r
+    HiiGetConfigurationSetting(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
@@ -2771,7 +3579,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
@@ -2856,10 +3664,17 @@ HiiRemovePackageList (
       ASSERT (Private->HiiHandleCount >= 0);\r
 \r
       HiiHandle->Signature = 0;\r
-      SafeFreePool (HiiHandle);\r
-      SafeFreePool (Node->PackageList);\r
-      SafeFreePool (Node);\r
+      FreePool (HiiHandle);\r
+      FreePool (Node->PackageList);\r
+      FreePool (Node);\r
 \r
+      //\r
+      // Check whether need to get the Database and configuration setting info.\r
+      // Only after ReadyToBoot, need to do the export.\r
+      //\r
+      if (gExportAfterReadyToBoot) {\r
+        HiiGetConfigurationSetting(This);\r
+      }\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -2933,7 +3748,7 @@ HiiUpdatePackageList (
         case EFI_HII_PACKAGE_TYPE_GUID:\r
           Status = RemoveGuidPackages (Private, Handle, OldPackageList);\r
           break;\r
-        case EFI_HII_PACKAGE_FORM:\r
+        case EFI_HII_PACKAGE_FORMS:\r
           Status = RemoveFormPackages (Private, Handle, OldPackageList);\r
           break;\r
         case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
@@ -2967,7 +3782,19 @@ 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 and configuration setting info.\r
+      // Only after ReadyToBoot, need to do the export.\r
+      //\r
+      if (gExportAfterReadyToBoot) {\r
+        if (Status == EFI_SUCCESS){\r
+          HiiGetConfigurationSetting(This);\r
+        }\r
+      }\r
+\r
+      return Status;\r
     }\r
   }\r
 \r
@@ -2994,18 +3821,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
@@ -3063,7 +3891,7 @@ HiiListPackageLists (
           }\r
         }\r
         break;\r
-      case EFI_HII_PACKAGE_FORM:\r
+      case EFI_HII_PACKAGE_FORMS:\r
         if (!IsListEmpty (&PackageList->FormPkgHdr)) {\r
           Matched = TRUE;\r
         }\r
@@ -3099,7 +3927,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
@@ -3156,9 +3984,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
@@ -3176,13 +4006,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
@@ -3204,8 +4034,7 @@ HiiExportPackageLists (
                  (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)\r
                  );\r
       ASSERT_EFI_ERROR (Status);\r
-    }\r
-    else if (Handle != NULL && Node->Handle == Handle) {\r
+    } else if (Handle != NULL && Node->Handle == Handle) {\r
       Status = ExportPackageList (\r
                  Private,\r
                  Handle,\r
@@ -3309,7 +4138,7 @@ HiiRegisterPackageNotify (
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Notify->NotifyHandle,\r
-                  &mHiiDatabaseNotifyGuid,\r
+                  &gEfiCallerIdGuid,\r
                   NULL,\r
                   NULL\r
                   );\r
@@ -3336,7 +4165,7 @@ HiiRegisterPackageNotify (
 \r
   @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL\r
                                  instance.\r
-  @param  NotifyHandle           The handle of the notification function being\r
+  @param  NotificationHandle     The handle of the notification function being\r
                                  unregistered.\r
 \r
   @retval EFI_SUCCESS            Notification is unregistered successfully.\r
@@ -3367,7 +4196,7 @@ HiiUnregisterPackageNotify (
 \r
   Status = gBS->OpenProtocol (\r
                   NotificationHandle,\r
-                  &mHiiDatabaseNotifyGuid,\r
+                  &gEfiCallerIdGuid,\r
                   NULL,\r
                   NULL,\r
                   NULL,\r
@@ -3388,13 +4217,12 @@ HiiUnregisterPackageNotify (
       RemoveEntryList (&Notify->DatabaseNotifyEntry);\r
       Status = gBS->UninstallMultipleProtocolInterfaces (\r
                       Notify->NotifyHandle,\r
-                      &mHiiDatabaseNotifyGuid,\r
+                      &gEfiCallerIdGuid,\r
                       NULL,\r
                       NULL\r
                       );\r
       ASSERT_EFI_ERROR (Status);\r
-      SafeFreePool (Notify);\r
-      Notify = NULL;\r
+      FreePool (Notify);\r
 \r
       return EFI_SUCCESS;\r
     }\r
@@ -3422,7 +4250,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
@@ -3676,7 +4506,9 @@ HiiSetKeyboardLayout (
   // Backup current keyboard layout.\r
   //\r
   CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));\r
-  SafeFreePool(Private->CurrentLayout);\r
+  if (Private->CurrentLayout != NULL) {\r
+    FreePool(Private->CurrentLayout);\r
+  }\r
   Private->CurrentLayout = KeyboardLayout;\r
 \r
   //\r