+ if (VarStoreId != 0) {\r
+ break;\r
+ }\r
+\r
+ IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;\r
+\r
+ if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {\r
+ //\r
+ // Find the matched VarStore\r
+ //\r
+ CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrNameValueVarStore->Guid);\r
+ VarStorageData->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+ VarStoreId = IfrNameValueVarStore->VarStoreId;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_DEFAULTSTORE_OP:\r
+ //\r
+ // Add new the map between default id and default name.\r
+ //\r
+ DefaultDataPtr = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+ if (DefaultDataPtr == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ DefaultDataPtr->DefaultId = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;\r
+ InsertTailList (&DefaultIdArray->Entry, &DefaultDataPtr->Entry);\r
+ DefaultDataPtr = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ case EFI_IFR_FORM_MAP_OP:\r
+ //\r
+ // No matched varstore is found and directly return.\r
+ //\r
+ if ( VarStoreId == 0) {\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_REF_OP:\r
+ //\r
+ // Ref question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if ( VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrRef = (EFI_IFR_REF4 *)IfrOpHdr;\r
+ if (IfrRef->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ VarWidth = (UINT16)(sizeof (EFI_HII_REF));\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_NUMERIC_OP:\r
+ //\r
+ // Numeric and OneOf has the same opcode structure.\r
+ //\r
+\r
+ //\r
+ // Numeric and OneOf question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpHdr;\r
+ if (IfrOneOf->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ if (QuestionReferBitField) {\r
+ VarWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;\r
+ } else {\r
+ VarWidth = (UINT16)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+ }\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // when go to there,BlockData can't be NULLL.\r
+ //\r
+ ASSERT (BlockData != NULL);\r
+\r
+ if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {\r
+ //\r
+ // Set this flag to TRUE for the first oneof option.\r
+ //\r
+ FirstOneOfOption = TRUE;\r
+ } else if (IfrOpHdr->OpCode == EFI_IFR_NUMERIC_OP) {\r
+ //\r
+ // Numeric minimum value will be used as default value when no default is specified.\r
+ //\r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ if (QuestionReferBitField) {\r
+ //\r
+ // Since default value in bit field was stored as UINT32 type.\r
+ //\r
+ CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+ } else {\r
+ switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set default value base on the DefaultId list get from IFR data.\r
+ //\r
+ NvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ if (NvDefaultStoreSize > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {\r
+ FindQuestionDefaultSetting (DefaultData.DefaultId, IfrEfiVarStoreTmp, &(IfrOneOf->Question), &DefaultData.Value, VarWidth, QuestionReferBitField);\r
+ }\r
+\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ //\r
+ // offset by question header\r
+ // width by EFI_IFR_ORDERED_LIST MaxContainers * OneofOption Type\r
+ //\r
+\r
+ FirstOrderedList = TRUE;\r
+ //\r
+ // OrderedList question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpHdr;\r
+ if (IfrOrderedList->Question.VarStoreId != VarStoreId) {\r
+ BlockData = NULL;\r
+ break;\r
+ }\r
+\r
+ VarWidth = IfrOrderedList->MaxContainers;\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ //\r
+ // EFI_IFR_DEFAULT_OP\r
+ // offset by question header\r
+ // width is 1 sizeof (BOOLEAN)\r
+ // default id by CheckBox Flags if CheckBox flags (Default or Mau) is set, the default value is 1 to be set.\r
+ // value by DefaultOption\r
+ // default id by DeaultOption DefaultId can override CheckBox Flags and Default value.\r
+ //\r
+\r
+ //\r
+ // CheckBox question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr;\r
+ if (IfrCheckBox->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ VarWidth = (UINT16)sizeof (BOOLEAN);\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ if (QuestionReferBitField) {\r
+ VarWidth = 1;\r
+ }\r
+\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // when go to there,BlockData can't be NULLL.\r
+ //\r
+ ASSERT (BlockData != NULL);\r
+\r
+ SmallestIdFromFlag = FALSE;\r
+\r
+ //\r
+ // Add default value for standard ID by CheckBox Flag\r
+ //\r
+ VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.DefaultId = VarDefaultId;\r
+ if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {\r
+ //\r
+ // When flag is set, default value is TRUE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromFlag;\r
+ if (QuestionReferBitField) {\r
+ DefaultData.Value.u32 = TRUE;\r
+ } else {\r
+ DefaultData.Value.b = TRUE;\r
+ }\r
+\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ //\r
+ // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+ //\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ SmallestIdFromFlag = TRUE;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Add default value for Manufacture ID by CheckBox Flag\r
+ //\r
+ VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.DefaultId = VarDefaultId;\r
+ if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {\r
+ //\r
+ // When flag is set, default value is TRUE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromFlag;\r
+ if (QuestionReferBitField) {\r
+ DefaultData.Value.u32 = TRUE;\r
+ } else {\r
+ DefaultData.Value.b = TRUE;\r
+ }\r
+\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ //\r
+ // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+ //\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ SmallestIdFromFlag = TRUE;\r
+ }\r
+ }\r
+\r
+ if (SmallestIdFromFlag) {\r
+ //\r
+ // When smallest default Id is given by the flag of CheckBox, set default value with TRUE for other default Id in the DefaultId list.\r
+ //\r
+ DefaultData.Type = DefaultValueFromOtherDefault;\r
+ if (QuestionReferBitField) {\r
+ DefaultData.Value.u32 = TRUE;\r
+ } else {\r
+ DefaultData.Value.b = TRUE;\r
+ }\r
+\r
+ //\r
+ // Set default value for all the default id in the DefaultId list.\r
+ //\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ } else {\r
+ //\r
+ // When flag is not set, default value is FASLE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ if (QuestionReferBitField) {\r
+ DefaultData.Value.u32 = FALSE;\r
+ } else {\r
+ DefaultData.Value.b = FALSE;\r
+ }\r
+\r
+ //\r
+ // Set default value for all the default id in the DefaultId list.\r
+ //\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_DATE_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // Date question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrDate = (EFI_IFR_DATE *)IfrOpHdr;\r
+ if (IfrDate->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ VarWidth = (UINT16)sizeof (EFI_HII_DATE);\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_TIME_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // Time question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrTime = (EFI_IFR_TIME *)IfrOpHdr;\r
+ if (IfrTime->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ VarWidth = (UINT16)sizeof (EFI_HII_TIME);\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_STRING_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // String question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrString = (EFI_IFR_STRING *)IfrOpHdr;\r
+ if (IfrString->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ VarWidth = (UINT16)(IfrString->MaxSize * sizeof (UINT16));\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_PASSWORD_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // Password question is not in IFR Form. This IFR form is not valid.\r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrPassword = (EFI_IFR_PASSWORD *)IfrOpHdr;\r
+ if (IfrPassword->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // The BlockData may allocate by other opcode,need to clean.\r
+ //\r
+ if (BlockData != NULL) {\r
+ BlockData = NULL;\r
+ }\r
+\r
+ VarWidth = (UINT16)(IfrPassword->MaxSize * sizeof (UINT16));\r
+ Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ //\r
+ // The opcode is not required,exit and parse other opcode.\r
+ //\r
+ break;\r
+ }\r
+\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // No default value for string.\r
+ //\r
+ BlockData = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ //\r
+ // No matched block data is ignored.\r
+ //\r
+ if ((BlockData == NULL) || (BlockData->Scope == 0)) {\r
+ break;\r
+ }\r
+\r
+ IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;\r
+ if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+ if (!FirstOrderedList) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get ordered list option data type.\r
+ //\r
+ if ((IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrOneOfOption->Type == EFI_IFR_TYPE_BOOLEAN)) {\r
+ VarWidth = 1;\r
+ } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_16) {\r
+ VarWidth = 2;\r
+ } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_32) {\r
+ VarWidth = 4;\r
+ } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ VarWidth = 8;\r
+ } else {\r
+ //\r
+ // Invalid ordered list option data type.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
+\r
+ FreePool (BlockData);\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Calculate Ordered list QuestionId width.\r
+ //\r
+ BlockData->Width = (UINT16)(BlockData->Width * VarWidth);\r
+ //\r
+ // Check whether this question is in requested block array.\r
+ //\r
+ if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, (BOOLEAN)(BlockData->Name != NULL), HiiHandle)) {\r
+ //\r
+ // This question is not in the requested string. Skip it.\r
+ //\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
+\r
+ FreePool (BlockData);\r
+ BlockData = NULL;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Check this var question is in the var storage\r
+ //\r
+ if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ FreePool (BlockData);\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Add Block Data into VarStorageData BlockEntry\r
+ //\r
+ InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+\r
+ FirstOrderedList = FALSE;\r
+\r
+ break;\r
+ }\r
+\r
+ //\r
+ // 1. Set default value for OneOf option when flag field has default attribute.\r
+ // And set the default value with the smallest default id for other default id in the DefaultId list.\r
+ //\r
+ if (((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) ||\r
+ ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG))\r
+ {\r
+ //\r
+ // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.\r
+ // The first oneof option value will be used as default value when no default value is specified.\r
+ //\r
+ FirstOneOfOption = FALSE;\r
+\r
+ SmallestIdFromFlag = FALSE;\r
+\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.Type = DefaultValueFromFlag;\r
+ CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+ if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {\r
+ DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+ //\r
+ // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+ //\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ SmallestIdFromFlag = TRUE;\r
+ }\r
+ }\r
+\r
+ if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {\r
+ DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+ //\r
+ // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+ //\r
+ SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ SmallestIdFromFlag = TRUE;\r
+ }\r
+ }\r
+\r
+ if (SmallestIdFromFlag) {\r
+ //\r
+ // When smallest default Id is given by the flag of oneofOption, set this option value for other default Id in the DefaultId list.\r
+ //\r
+ DefaultData.Type = DefaultValueFromOtherDefault;\r
+ //\r
+ // Set default value for other default id in the DefaultId list.\r
+ //\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // 2. Set as the default value when this is the first option.\r
+ // The first oneof option value will be used as default value when no default value is specified.\r
+ //\r
+ if (FirstOneOfOption) {\r
+ // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.\r
+ FirstOneOfOption = FALSE;\r
+\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_DEFAULT_OP:\r
+ //\r
+ // Update Current BlockData to the default value.\r
+ //\r
+ if ((BlockData == NULL) || (BlockData->Scope == 0)) {\r
+ //\r
+ // No matched block data is ignored.\r
+ //\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Get the DefaultId\r
+ //\r
+ IfrDefault = (EFI_IFR_DEFAULT *)IfrOpHdr;\r
+ VarDefaultId = IfrDefault->DefaultId;\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.Type = DefaultValueFromOpcode;\r
+ DefaultData.DefaultId = VarDefaultId;\r
+ if (QuestionReferBitField) {\r
+ CopyMem (&DefaultData.Value.u32, &IfrDefault->Value.u32, sizeof (UINT32));\r
+ } else {\r
+ CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+ }\r
+\r
+ // If the value field is expression, set the cleaned flag.\r
+ if (IfrDefault->Type == EFI_IFR_TYPE_OTHER) {\r
+ DefaultData.Cleaned = TRUE;\r
+ }\r
+\r
+ //\r
+ // Add DefaultValue into current BlockData\r
+ //\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+ //\r
+ // Set default value for other default id in the DefaultId list.\r
+ // when SmallestDefaultId == VarDefaultId means there are two defaults with same default Id.\r
+ // If the two defaults are both from default opcode, use the first default as the default value of other default Id.\r
+ // If one from flag and the other form default opcode, use the default opcode value as the default value of other default Id.\r
+ //\r
+ if ((SmallestDefaultId > VarDefaultId) || ((SmallestDefaultId == VarDefaultId) && !FromOtherDefaultOpcode)) {\r
+ FromOtherDefaultOpcode = TRUE;\r
+ SmallestDefaultId = VarDefaultId;\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+ if (DefaultDataPtr->DefaultId != DefaultData.DefaultId) {\r
+ DefaultData.Type = DefaultValueFromOtherDefault;\r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // After insert the default value, reset the cleaned value for next\r
+ // time used. If not set here, need to set the value before every time.\r
+ // use it.\r
+ //\r
+ DefaultData.Cleaned = FALSE;\r
+ break;\r
+\r
+ case EFI_IFR_END_OP:\r
+ //\r
+ // End Opcode is for Var question.\r
+ //\r
+ QuestionReferBitField = FALSE;\r
+ if (BlockData != NULL) {\r
+ if (BlockData->Scope > 0) {\r
+ BlockData->Scope--;\r
+ }\r
+\r
+ if (BlockData->Scope == 0) {\r
+ BlockData = NULL;\r
+ //\r
+ // when finishing parsing a question, clean the SmallestDefaultId and GetDefaultFromDefaultOpcode.\r
+ //\r
+ SmallestDefaultId = 0xFFFF;\r
+ FromOtherDefaultOpcode = FALSE;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_GUID_OP:\r
+ if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {\r
+ QuestionReferBitField = TRUE;\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ if (BlockData != NULL) {\r
+ if (BlockData->Scope > 0) {\r
+ BlockData->Scope = (UINT8)(BlockData->Scope + IfrOpHdr->Scope);\r
+ }\r
+\r
+ if (BlockData->Scope == 0) {\r
+ BlockData = NULL;\r
+ }\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ IfrOffset += IfrOpHdr->Length;\r
+ PackageOffset += IfrOpHdr->Length;\r
+ }\r
+\r
+ //\r
+ // if Status == EFI_NOT_FOUND, just means the opcode is not required,not contain any error,\r
+ // so set the Status to EFI_SUCCESS.\r
+ //\r
+ if (Status == EFI_NOT_FOUND) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+Done:\r
+ for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+ BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+ for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; ) {\r
+ DefaultDataPtr = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+ LinkDefault = LinkDefault->ForwardLink;\r
+ if (DefaultDataPtr->Cleaned == TRUE) {\r
+ RemoveEntryList (&DefaultDataPtr->Entry);\r
+ FreePool (DefaultDataPtr);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (IfrEfiVarStoreTmp != NULL) {\r
+ FreePool (IfrEfiVarStoreTmp);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ parse the configrequest string, get the elements.\r
+\r
+ @param ConfigRequest The input configrequest string.\r
+ @param Progress Return the progress data.\r
+\r
+ @retval Block data pointer.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetBlockElement (\r
+ IN EFI_STRING ConfigRequest,\r
+ OUT EFI_STRING *Progress\r
+ )\r
+{\r
+ EFI_STRING StringPtr;\r
+ IFR_BLOCK_DATA *BlockData;\r
+ IFR_BLOCK_DATA *RequestBlockArray;\r
+ EFI_STATUS Status;\r
+ UINT8 *TmpBuffer;\r
+ UINT16 Offset;\r
+ UINT16 Width;\r
+ LIST_ENTRY *Link;\r
+ IFR_BLOCK_DATA *NextBlockData;\r
+ UINTN Length;\r
+\r
+ TmpBuffer = NULL;\r
+\r
+ //\r
+ // Init RequestBlockArray\r
+ //\r
+ RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+ if (RequestBlockArray == NULL) {\r
+ goto Done;\r
+ }\r
+\r
+ InitializeListHead (&RequestBlockArray->Entry);\r
+\r
+ //\r
+ // Get the request Block array from the request string\r
+ // Offset and Width\r
+ //\r
+\r
+ //\r
+ // Parse each <RequestElement> if exists\r
+ // Only <BlockName> format is supported by this help function.\r
+ // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
+ //\r
+ StringPtr = ConfigRequest;\r
+ while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
+ //\r
+ // Skip the OFFSET string\r
+ //\r
+ *Progress = StringPtr;\r
+ StringPtr += StrLen (L"&OFFSET=");\r
+ //\r
+ // Get Offset\r
+ //\r
+ Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Offset = 0;\r
+ CopyMem (\r
+ &Offset,\r
+ TmpBuffer,\r
+ (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+ );\r
+ FreePool (TmpBuffer);\r
+\r
+ StringPtr += Length;\r
+ if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+ goto Done;\r
+ }\r
+\r
+ StringPtr += StrLen (L"&WIDTH=");\r
+\r
+ //\r
+ // Get Width\r
+ //\r
+ Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Width = 0;\r
+ CopyMem (\r
+ &Width,\r
+ TmpBuffer,\r
+ (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+ );\r
+ FreePool (TmpBuffer);\r
+\r
+ StringPtr += Length;\r
+ if ((*StringPtr != 0) && (*StringPtr != L'&')) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Set Block Data\r
+ //\r
+ BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+ if (BlockData == NULL) {\r
+ goto Done;\r
+ }\r
+\r
+ BlockData->Offset = Offset;\r
+ BlockData->Width = Width;\r
+ InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
+\r
+ //\r
+ // Skip &VALUE string if &VALUE does exists.\r
+ //\r
+ if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) == 0) {\r
+ StringPtr += StrLen (L"&VALUE=");\r
+\r
+ //\r
+ // Get Value\r
+ //\r
+ Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ FreePool (TmpBuffer);\r
+ StringPtr += Length;\r
+ if ((*StringPtr != 0) && (*StringPtr != L'&')) {\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If '\0', parsing is finished.\r
+ //\r
+ if (*StringPtr == 0) {\r