+/**\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