]> 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 4fd83f807281f9b7c70ae590aea85b04b38f97fc..4a2dc8d0304399810344f05b5d246a57f5f3d66b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Implementation for EFI_HII_DATABASE_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -15,11 +15,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \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 = 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
@@ -531,6 +536,523 @@ 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
+    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
@@ -601,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