UINT8 Scope;\r
} IFR_BLOCK_DATA;\r
\r
+typedef struct {\r
+ EFI_VARSTORE_ID VarStoreId;\r
+ UINT16 Size;\r
+} IFR_VARSTORAGE_DATA;\r
+\r
//\r
// <ConfigHdr> Template\r
//\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Get value from config request resp string.\r
+\r
+ @param ConfigElement ConfigResp string contains the current setting.\r
+ @param VarName The variable name which need to get value.\r
+ @param VarValue The return value.\r
+ \r
+ @retval EFI_SUCCESS Get the value for the VarName\r
+ @retval EFI_OUT_OF_RESOURCES The memory is not enough.\r
+**/\r
+EFI_STATUS\r
+GetValueFromRequest (\r
+ IN CHAR16 *ConfigElement,\r
+ IN CHAR16 *VarName,\r
+ OUT UINT64 *VarValue\r
+ )\r
+{\r
+ UINT8 *TmpBuffer;\r
+ CHAR16 *StringPtr;\r
+ UINTN Length;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Find VarName related string.\r
+ //\r
+ StringPtr = StrStr (ConfigElement, VarName);\r
+ ASSERT (StringPtr != NULL);\r
+\r
+ //\r
+ // Skip the "VarName=" string\r
+ //\r
+ StringPtr += StrLen (VarName) + 1;\r
+\r
+ //\r
+ // Get Offset\r
+ //\r
+ Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ *VarValue = 0;\r
+ CopyMem (VarValue, TmpBuffer, (((Length + 1) / 2) < sizeof (UINT64)) ? ((Length + 1) / 2) : sizeof (UINT64));\r
+\r
+ FreePool (TmpBuffer);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
This internal function parses IFR data to validate current setting.\r
\r
- @param ConfigResp ConfigResp string contains the current setting.\r
+ Base on the NameValueType, if it is TRUE, RequestElement and HiiHandle is valid;\r
+ else the VarBuffer and CurrentBlockArray is valid.\r
+\r
@param HiiPackageList Point to Hii package list.\r
@param PackageListLength The length of the pacakge.\r
@param VarGuid Guid of the buffer storage.\r
@param VarName Name of the buffer storage.\r
+ @param VarBuffer The data buffer for the storage.\r
+ @param CurrentBlockArray The block array from the config Requst string.\r
+ @param RequestElement The config string for this storage.\r
+ @param HiiHandle The HiiHandle for this formset.\r
+ @param NameValueType Whether current storage is name/value varstore or not.\r
\r
@retval EFI_SUCCESS The current setting is valid.\r
@retval EFI_OUT_OF_RESOURCES The memory is not enough.\r
@retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
-InternalHiiValidateCurrentSetting (\r
- IN EFI_STRING ConfigResp,\r
+ValidateQuestionFromVfr (\r
IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
IN UINTN PackageListLength,\r
IN EFI_GUID *VarGuid,\r
- IN CHAR16 *VarName\r
+ IN CHAR16 *VarName,\r
+ IN UINT8 *VarBuffer,\r
+ IN IFR_BLOCK_DATA *CurrentBlockArray,\r
+ IN CHAR16 *RequestElement,\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN BOOLEAN NameValueType\r
)\r
-{ \r
- IFR_BLOCK_DATA *CurrentBlockArray;\r
- IFR_BLOCK_DATA *BlockData;\r
- IFR_BLOCK_DATA *NewBlockData;\r
+{\r
IFR_BLOCK_DATA VarBlockData;\r
- EFI_STRING StringPtr;\r
- UINTN Length;\r
UINT8 *TmpBuffer;\r
UINT16 Offset;\r
UINT16 Width;\r
UINT64 VarValue;\r
EFI_IFR_TYPE_VALUE TmpValue;\r
- LIST_ENTRY *Link;\r
- UINT8 *VarBuffer;\r
- UINTN MaxBufferSize;\r
EFI_STATUS Status;\r
EFI_HII_PACKAGE_HEADER PacakgeHeader;\r
UINT32 PackageOffset;\r
UINTN IfrOffset;\r
EFI_IFR_OP_HEADER *IfrOpHdr;\r
EFI_IFR_VARSTORE *IfrVarStore;\r
+ EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueStore;\r
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;\r
+ IFR_VARSTORAGE_DATA VarStoreData;\r
EFI_IFR_ONE_OF *IfrOneOf;\r
EFI_IFR_NUMERIC *IfrNumeric;\r
EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;\r
EFI_IFR_STRING *IfrString;\r
CHAR8 *VarStoreName;\r
UINTN Index;\r
- \r
- //\r
- // 1. Get the current setting to current block data array and Convert them into VarBuffer\r
- //\r
+ CHAR16 *QuestionName;\r
+ CHAR16 *StringPtr;\r
\r
- //\r
- // Skip ConfigHdr string\r
- //\r
- StringPtr = ConfigResp;\r
- StringPtr = StrStr (ConfigResp, L"&OFFSET");\r
- if (StringPtr == NULL) {\r
- //\r
- // No ConfigBlock value is required to be validated.\r
- // EFI_SUCCESS directly return.\r
- //\r
- return EFI_SUCCESS;\r
- }\r
- \r
//\r
// Initialize the local variables.\r
//\r
- Index = 0;\r
- VarStoreName = NULL;\r
- Status = EFI_SUCCESS;\r
- BlockData = NULL;\r
- NewBlockData = NULL;\r
- TmpBuffer = NULL;\r
- MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE;\r
- VarBuffer = AllocateZeroPool (MaxBufferSize);\r
- if (VarBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Init CurrentBlockArray\r
- //\r
- CurrentBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
- if (CurrentBlockArray == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- InitializeListHead (&CurrentBlockArray->Entry);\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
- while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
- //\r
- // Skip the &OFFSET= string\r
- // \r
- StringPtr += StrLen (L"&OFFSET=");\r
-\r
- //\r
- // Get Offset\r
- //\r
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\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
- TmpBuffer = NULL;\r
-\r
- StringPtr += Length;\r
- if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- StringPtr += StrLen (L"&WIDTH=");\r
-\r
- //\r
- // Get Width\r
- //\r
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\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
- TmpBuffer = NULL;\r
-\r
- StringPtr += Length;\r
- if (*StringPtr != 0 && *StringPtr != L'&') {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- StringPtr += StrLen (L"&VALUE=");\r
-\r
- //\r
- // Get Value\r
- //\r
- Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- StringPtr += Length;\r
- if (*StringPtr != 0 && *StringPtr != L'&') {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Check whether VarBuffer is enough\r
- //\r
- if ((UINTN) (Offset + Width) > MaxBufferSize) {\r
- VarBuffer = ReallocatePool (\r
- MaxBufferSize,\r
- Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE,\r
- VarBuffer\r
- );\r
- if (VarBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE;\r
- }\r
-\r
- //\r
- // Update the Block with configuration info\r
- //\r
- CopyMem (VarBuffer + Offset, TmpBuffer, Width);\r
- FreePool (TmpBuffer);\r
- TmpBuffer = NULL;\r
-\r
- //\r
- // Set new Block Data\r
- //\r
- NewBlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
- if (NewBlockData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- NewBlockData->Offset = Offset;\r
- NewBlockData->Width = Width;\r
-\r
- //\r
- // Insert the new block data into the block data array.\r
- //\r
- for (Link = CurrentBlockArray->Entry.ForwardLink; Link != &CurrentBlockArray->Entry; Link = Link->ForwardLink) {\r
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
- if (NewBlockData->Offset == BlockData->Offset) {\r
- if (NewBlockData->Width > BlockData->Width) {\r
- BlockData->Width = NewBlockData->Width;\r
- }\r
- FreePool (NewBlockData);\r
- break;\r
- } else if (NewBlockData->Offset < BlockData->Offset) {\r
- //\r
- // Insert new block data as the previous one of this link.\r
- //\r
- InsertTailList (Link, &NewBlockData->Entry);\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Insert new block data into the array tail.\r
- //\r
- if (Link == &CurrentBlockArray->Entry) {\r
- InsertTailList (Link, &NewBlockData->Entry);\r
- }\r
-\r
- //\r
- // If '\0', parsing is finished. \r
- //\r
- if (*StringPtr == 0) {\r
- break;\r
- }\r
- //\r
- // Go to next ConfigBlock \r
- //\r
- }\r
-\r
- //\r
- // Merge the aligned block data into the single block data.\r
- //\r
- Link = CurrentBlockArray->Entry.ForwardLink;\r
- while ((Link != &CurrentBlockArray->Entry) && (Link->ForwardLink != &CurrentBlockArray->Entry)) {\r
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
- NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
- if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
- if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
- BlockData->Width = (UINT16) (NewBlockData->Offset + NewBlockData->Width - BlockData->Offset);\r
- }\r
- RemoveEntryList (Link->ForwardLink);\r
- FreePool (NewBlockData);\r
- continue;\r
- }\r
- Link = Link->ForwardLink; \r
- }\r
- \r
- if (IsListEmpty (&CurrentBlockArray->Entry)) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
+ Index = 0;\r
+ VarStoreName = NULL;\r
+ Status = EFI_SUCCESS;\r
+ TmpBuffer = NULL;\r
+ VarValue = 0;\r
+ IfrVarStore = NULL;\r
+ IfrNameValueStore = NULL;\r
+ IfrEfiVarStore = NULL;\r
+ ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));\r
+ ZeroMem (&VarBlockData, sizeof (VarBlockData));\r
\r
//\r
- // 2. Check IFR value is in block data, then Validate Value\r
+ // Check IFR value is in block data, then Validate Value\r
//\r
- ZeroMem (&VarBlockData, sizeof (VarBlockData));\r
- VarValue = 0;\r
- IfrVarStore = NULL;\r
PackageOffset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
while (PackageOffset < PackageListLength) {\r
CopyMem (&PacakgeHeader, (UINT8 *) HiiPackageList + PackageOffset, sizeof (PacakgeHeader));\r
- \r
+\r
//\r
// Parse IFR opcode from the form package.\r
//\r
// Validate current setting to the value built in IFR opcode\r
//\r
switch (IfrOpHdr->OpCode) {\r
- case EFI_IFR_VARSTORE_OP: \r
+ case EFI_IFR_VARSTORE_OP:\r
//\r
// VarStoreId has been found. No further found.\r
//\r
- if (IfrVarStore != NULL) {\r
+ if (VarStoreData.VarStoreId != 0) {\r
break;\r
}\r
//\r
} else {\r
IfrVarStore = NULL;\r
}\r
+\r
+ if (IfrVarStore != NULL) {\r
+ VarStoreData.VarStoreId = IfrVarStore->VarStoreId;\r
+ VarStoreData.Size = IfrVarStore->Size;\r
+ }\r
break;\r
- case EFI_IFR_FORM_OP:\r
- case EFI_IFR_FORM_MAP_OP:\r
+ case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
//\r
- // Check the matched VarStoreId is found.\r
+ // VarStoreId has been found. No further found.\r
//\r
- if (IfrVarStore == NULL) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
+ if (VarStoreData.VarStoreId != 0) {\r
+ break;\r
}\r
- break;\r
- case EFI_IFR_ONE_OF_OP:\r
//\r
- // Check whether current value is the one of option.\r
+ // Find the matched VarStoreId to the input VarGuid\r
//\r
+ IfrNameValueStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;\r
+ if (!CompareGuid ((EFI_GUID *) (VOID *) &IfrNameValueStore->Guid, VarGuid)) {\r
+ IfrNameValueStore = NULL;\r
+ }\r
\r
- //\r
- // OneOf question is not in IFR Form. This IFR form is not valid. \r
- //\r
- if (IfrVarStore == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ if (IfrNameValueStore != NULL) {\r
+ VarStoreData.VarStoreId = IfrNameValueStore->VarStoreId;\r
}\r
- // \r
- // Check whether this question is for the requested varstore.\r
+ break;\r
+ case EFI_IFR_VARSTORE_EFI_OP:\r
//\r
- IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpHdr;\r
- if (IfrOneOf->Question.VarStoreId != IfrVarStore->VarStoreId) {\r
+ // VarStore is found. Don't need to search any more.\r
+ //\r
+ if (VarStoreData.VarStoreId != 0) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset by Question header and Width by DataType Flags\r
- //\r
- Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
- Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+\r
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+\r
//\r
- // Check whether this question is in current block array.\r
+ // If the length is small than the structure, this is from old efi \r
+ // varstore definition. Old efi varstore get config directly from \r
+ // GetVariable function.\r
//\r
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+ if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+ break;\r
+ }\r
+\r
+ if (CompareGuid ((EFI_GUID *) (VOID *) &IfrEfiVarStore->Guid, VarGuid)) {\r
+ VarStoreName = (CHAR8 *) IfrEfiVarStore->Name;\r
+ for (Index = 0; VarStoreName[Index] != 0; Index ++) {\r
+ if ((CHAR16) VarStoreName[Index] != VarName[Index]) {\r
+ break;\r
+ }\r
+ }\r
//\r
- // This question is not in the current configuration string. Skip it.\r
+ // The matched VarStore is found.\r
//\r
- break;\r
+ if ((VarStoreName[Index] != 0) || (VarName[Index] != 0)) {\r
+ IfrEfiVarStore = NULL;\r
+ }\r
+ } else {\r
+ IfrEfiVarStore = NULL;\r
}\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((Offset + Width) > IfrVarStore->Size) {\r
+\r
+ if (IfrEfiVarStore != NULL) {\r
//\r
- // This question exceeds the var store size. \r
+ // Find the matched VarStore\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ VarStoreData.VarStoreId = IfrEfiVarStore->VarStoreId;\r
+ VarStoreData.Size = IfrEfiVarStore->Size;\r
+ }\r
+ break;\r
+ case EFI_IFR_FORM_OP:\r
+ case EFI_IFR_FORM_MAP_OP:\r
+ //\r
+ // Check the matched VarStoreId is found.\r
+ //\r
+ if (VarStoreData.VarStoreId == 0) {\r
+ return EFI_SUCCESS;\r
}\r
+ break;\r
+ case EFI_IFR_ONE_OF_OP:\r
+ //\r
+ // Check whether current value is the one of option.\r
+ //\r
\r
//\r
- // Get the current value for oneof opcode\r
+ // OneOf question is not in IFR Form. This IFR form is not valid. \r
//\r
- VarValue = 0;\r
- CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ if (VarStoreData.VarStoreId == 0) {\r
+ return EFI_INVALID_PARAMETER;\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 != VarStoreData.VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ if (NameValueType) {\r
+ QuestionName = HiiGetString (HiiHandle, IfrOneOf->Question.VarStoreInfo.VarName, NULL);\r
+ ASSERT (QuestionName != NULL);\r
+\r
+ if (StrStr (RequestElement, QuestionName) == NULL) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+\r
+ Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ } else {\r
+ //\r
+ // Get Offset by Question header and Width by DataType Flags\r
+ //\r
+ Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+ Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+ //\r
+ // Check whether this question is in current block array.\r
+ //\r
+ if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+ //\r
+ // Check this var question is in the var storage \r
+ //\r
+ if ((Offset + Width) > VarStoreData.Size) {\r
+ //\r
+ // This question exceeds the var store size. \r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Get the current value for oneof opcode\r
+ //\r
+ VarValue = 0;\r
+ CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ }\r
//\r
// Set Block Data, to be checked in the following Oneof option opcode.\r
//\r
- VarBlockData.Offset = Offset;\r
- VarBlockData.Width = Width;\r
VarBlockData.OpCode = IfrOpHdr->OpCode;\r
VarBlockData.Scope = IfrOpHdr->Scope;\r
break;\r
//\r
// Numeric question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (IfrVarStore == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ if (VarStoreData.VarStoreId == 0) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
//\r
// Check whether this question is for the requested varstore.\r
//\r
IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpHdr;\r
- if (IfrNumeric->Question.VarStoreId != IfrVarStore->VarStoreId) {\r
+ if (IfrNumeric->Question.VarStoreId != VarStoreData.VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset by Question header and Width by DataType Flags\r
- //\r
- Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
- Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
- //\r
- // Check whether this question is in current block array.\r
- //\r
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+\r
+ if (NameValueType) {\r
+ QuestionName = HiiGetString (HiiHandle, IfrNumeric->Question.VarStoreInfo.VarName, NULL);\r
+ ASSERT (QuestionName != NULL);\r
+\r
+ if (StrStr (RequestElement, QuestionName) == NULL) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+ \r
+ Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ } else {\r
//\r
- // This question is not in the current configuration string. Skip it.\r
+ // Get Offset by Question header and Width by DataType Flags\r
//\r
- break;\r
- }\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((Offset + Width) > IfrVarStore->Size) {\r
+ Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
+ Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
//\r
- // This question exceeds the var store size. \r
+ // Check whether this question is in current block array.\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
+ if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+ //\r
+ // Check this var question is in the var storage \r
+ //\r
+ if ((Offset + Width) > VarStoreData.Size) {\r
+ //\r
+ // This question exceeds the var store size. \r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
- //\r
- // Check the current value is in the numeric range.\r
- //\r
- VarValue = 0;\r
- CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ //\r
+ // Check the current value is in the numeric range.\r
+ //\r
+ VarValue = 0;\r
+ CopyMem (&VarValue, VarBuffer + Offset, Width);\r
+ }\r
switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
case EFI_IFR_NUMERIC_SIZE_1:\r
if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {\r
//\r
// Not in the valid range.\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
break;\r
case EFI_IFR_NUMERIC_SIZE_2:\r
//\r
// Not in the valid range.\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
break;\r
case EFI_IFR_NUMERIC_SIZE_4:\r
//\r
// Not in the valid range.\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
break;\r
case EFI_IFR_NUMERIC_SIZE_8:\r
//\r
// Not in the valid range.\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
break;\r
}\r
//\r
// CheckBox question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (IfrVarStore == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ if (VarStoreData.VarStoreId == 0) {\r
+ return EFI_INVALID_PARAMETER;\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 != IfrVarStore->VarStoreId) {\r
+ if (IfrCheckBox->Question.VarStoreId != VarStoreData.VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset by Question header\r
- //\r
- Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
- Width = (UINT16) sizeof (BOOLEAN);\r
- //\r
- // Check whether this question is in current block array.\r
- //\r
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+\r
+ if (NameValueType) {\r
+ QuestionName = HiiGetString (HiiHandle, IfrCheckBox->Question.VarStoreInfo.VarName, NULL);\r
+ ASSERT (QuestionName != NULL);\r
+\r
+ if (StrStr (RequestElement, QuestionName) == NULL) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+ \r
+ Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ } else {\r
//\r
- // This question is not in the current configuration string. Skip it.\r
+ // Get Offset by Question header\r
//\r
- break;\r
- }\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((Offset + Width) > IfrVarStore->Size) {\r
+ Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+ Width = (UINT16) sizeof (BOOLEAN);\r
+ //\r
+ // Check whether this question is in current block array.\r
+ //\r
+ if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
//\r
- // This question exceeds the var store size. \r
+ // Check this var question is in the var storage \r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ if ((Offset + Width) > VarStoreData.Size) {\r
+ //\r
+ // This question exceeds the var store size. \r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Check the current value is in the numeric range.\r
+ //\r
+ VarValue = 0;\r
+ CopyMem (&VarValue, VarBuffer + Offset, Width);\r
}\r
-\r
//\r
// Boolean type, only 1 and 0 is valid.\r
//\r
- if (*(VarBuffer + Offset) > 1) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done; \r
+ if (VarValue > 1) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
- \r
break;\r
case EFI_IFR_STRING_OP:\r
//\r
//\r
// CheckBox question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (IfrVarStore == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ if (VarStoreData.VarStoreId == 0) {\r
+ return EFI_INVALID_PARAMETER;\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 != IfrVarStore->VarStoreId) {\r
+ if (IfrString->Question.VarStoreId != VarStoreData.VarStoreId) {\r
break;\r
}\r
- \r
//\r
- // Get Offset/Width by Question header and OneOf Flags\r
+ // Get Width by OneOf Flags\r
//\r
- Offset = IfrString->Question.VarStoreInfo.VarOffset;\r
Width = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
- //\r
- // Check whether this question is in current block array.\r
- //\r
- if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+ if (NameValueType) {\r
+ QuestionName = HiiGetString (HiiHandle, IfrString->Question.VarStoreInfo.VarName, NULL);\r
+ ASSERT (QuestionName != NULL);\r
+\r
+ StringPtr = StrStr (RequestElement, QuestionName);\r
+ if (StringPtr == NULL) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+\r
//\r
- // This question is not in the current configuration string. Skip it.\r
+ // Skip the "=".\r
+ // \r
+ StringPtr += 1;\r
+ \r
//\r
- break;\r
- }\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((Offset + Width) > IfrVarStore->Size) {\r
+ // Check current string length is less than maxsize\r
//\r
- // This question exceeds the var store size. \r
+ if (StrSize (StringPtr) > Width) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ } else {\r
//\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- \r
- //\r
- // Check current string length is less than maxsize\r
- //\r
- if (StrSize ((CHAR16 *) (VarBuffer + Offset)) > Width) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done; \r
+ // Get Offset/Width by Question header and OneOf Flags\r
+ //\r
+ Offset = IfrString->Question.VarStoreInfo.VarOffset;\r
+ //\r
+ // Check whether this question is in current block array.\r
+ //\r
+ if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+ //\r
+ // This question is not in the current configuration string. Skip it.\r
+ //\r
+ break;\r
+ }\r
+ //\r
+ // Check this var question is in the var storage \r
+ //\r
+ if ((Offset + Width) > VarStoreData.Size) {\r
+ //\r
+ // This question exceeds the var store size. \r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check current string length is less than maxsize\r
+ //\r
+ if (StrSize ((CHAR16 *) (VarBuffer + Offset)) > Width) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
}\r
break;\r
case EFI_IFR_ONE_OF_OPTION_OP:\r
VarBlockData.OpCode = 0;\r
}\r
}\r
-\r
break;\r
case EFI_IFR_END_OP:\r
//\r
// OneOf value doesn't belong to one of option value. \r
//\r
if ((VarBlockData.Scope == 0) && (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
+ return EFI_INVALID_PARAMETER;\r
}\r
break;\r
default:\r
//\r
break;\r
}\r
- \r
+\r
//\r
// Go to next package.\r
//\r
- PackageOffset += PacakgeHeader.Length; \r
+ PackageOffset += PacakgeHeader.Length;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This internal function parses IFR data to validate current setting.\r
+\r
+ @param ConfigElement ConfigResp element string contains the current setting.\r
+ @param CurrentBlockArray Current block array.\r
+ @param VarBuffer Data buffer for this varstore.\r
+ \r
+ @retval EFI_SUCCESS The current setting is valid.\r
+ @retval EFI_OUT_OF_RESOURCES The memory is not enough.\r
+ @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid.\r
+**/\r
+EFI_STATUS\r
+GetBlockDataInfo (\r
+ IN CHAR16 *ConfigElement,\r
+ OUT IFR_BLOCK_DATA **CurrentBlockArray,\r
+ OUT UINT8 **VarBuffer\r
+ )\r
+{\r
+ IFR_BLOCK_DATA *BlockData;\r
+ IFR_BLOCK_DATA *NewBlockData;\r
+ EFI_STRING StringPtr;\r
+ UINTN Length;\r
+ UINT8 *TmpBuffer;\r
+ UINT16 Offset;\r
+ UINT16 Width;\r
+ LIST_ENTRY *Link;\r
+ UINTN MaxBufferSize;\r
+ EFI_STATUS Status;\r
+ CHAR8 *VarStoreName;\r
+ UINTN Index;\r
+ IFR_BLOCK_DATA *BlockArray;\r
+ UINT8 *DataBuffer;\r
+ \r
+ //\r
+ // Initialize the local variables.\r
+ //\r
+ Index = 0;\r
+ VarStoreName = NULL;\r
+ Status = EFI_SUCCESS;\r
+ BlockData = NULL;\r
+ NewBlockData = NULL;\r
+ TmpBuffer = NULL;\r
+ BlockArray = NULL;\r
+ MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE;\r
+ DataBuffer = AllocateZeroPool (MaxBufferSize);\r
+ if (DataBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ //\r
+ // Init BlockArray\r
+ //\r
+ BlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+ if (BlockArray == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ InitializeListHead (&BlockArray->Entry);\r
+\r
+ StringPtr = StrStr (ConfigElement, L"&OFFSET=");\r
+ ASSERT (StringPtr != NULL);\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
+ while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
+ //\r
+ // Skip the &OFFSET= string\r
+ // \r
+ StringPtr += StrLen (L"&OFFSET=");\r
+\r
+ //\r
+ // Get Offset\r
+ //\r
+ Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\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
+ TmpBuffer = NULL;\r
+\r
+ StringPtr += Length;\r
+ if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ StringPtr += StrLen (L"&WIDTH=");\r
+\r
+ //\r
+ // Get Width\r
+ //\r
+ Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\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
+ TmpBuffer = NULL;\r
+\r
+ StringPtr += Length;\r
+ if (*StringPtr != 0 && *StringPtr != L'&') {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ StringPtr += StrLen (L"&VALUE=");\r
+\r
+ //\r
+ // Get Value\r
+ //\r
+ Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ StringPtr += Length;\r
+ if (*StringPtr != 0 && *StringPtr != L'&') {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check whether VarBuffer is enough\r
+ //\r
+ if ((UINTN) (Offset + Width) > MaxBufferSize) {\r
+ DataBuffer = ReallocatePool (\r
+ MaxBufferSize,\r
+ Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE,\r
+ DataBuffer\r
+ );\r
+ if (DataBuffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE;\r
+ }\r
+\r
+ //\r
+ // Update the Block with configuration info\r
+ //\r
+ CopyMem (DataBuffer + Offset, TmpBuffer, Width);\r
+ FreePool (TmpBuffer);\r
+ TmpBuffer = NULL;\r
+\r
+ //\r
+ // Set new Block Data\r
+ //\r
+ NewBlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+ if (NewBlockData == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ NewBlockData->Offset = Offset;\r
+ NewBlockData->Width = Width;\r
+\r
+ //\r
+ // Insert the new block data into the block data array.\r
+ //\r
+ for (Link = BlockArray->Entry.ForwardLink; Link != &BlockArray->Entry; Link = Link->ForwardLink) {\r
+ BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ if (NewBlockData->Offset == BlockData->Offset) {\r
+ if (NewBlockData->Width > BlockData->Width) {\r
+ BlockData->Width = NewBlockData->Width;\r
+ }\r
+ FreePool (NewBlockData);\r
+ break;\r
+ } else if (NewBlockData->Offset < BlockData->Offset) {\r
+ //\r
+ // Insert new block data as the previous one of this link.\r
+ //\r
+ InsertTailList (Link, &NewBlockData->Entry);\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Insert new block data into the array tail.\r
+ //\r
+ if (Link == &BlockArray->Entry) {\r
+ InsertTailList (Link, &NewBlockData->Entry);\r
+ }\r
+\r
+ //\r
+ // If '\0', parsing is finished. \r
+ //\r
+ if (*StringPtr == 0) {\r
+ break;\r
+ }\r
+ //\r
+ // Go to next ConfigBlock \r
+ //\r
+ }\r
+\r
+ //\r
+ // Merge the aligned block data into the single block data.\r
+ //\r
+ Link = BlockArray->Entry.ForwardLink;\r
+ while ((Link != &BlockArray->Entry) && (Link->ForwardLink != &BlockArray->Entry)) {\r
+ BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
+ if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
+ if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
+ BlockData->Width = (UINT16) (NewBlockData->Offset + NewBlockData->Width - BlockData->Offset);\r
+ }\r
+ RemoveEntryList (Link->ForwardLink);\r
+ FreePool (NewBlockData);\r
+ continue;\r
+ }\r
+ Link = Link->ForwardLink;\r
+ }\r
+\r
+ *VarBuffer = DataBuffer;\r
+ *CurrentBlockArray = BlockArray;\r
+ return EFI_SUCCESS;\r
+\r
Done:\r
+ if (DataBuffer != NULL) {\r
+ FreePool (DataBuffer);\r
+ }\r
+ \r
+ if (BlockArray != NULL) {\r
+ //\r
+ // Free Link Array CurrentBlockArray\r
+ //\r
+ while (!IsListEmpty (&BlockArray->Entry)) {\r
+ BlockData = BASE_CR (BlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+ RemoveEntryList (&BlockData->Entry);\r
+ FreePool (BlockData);\r
+ }\r
+ FreePool (BlockArray);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This internal function parses IFR data to validate current setting.\r
+\r
+ @param ConfigResp ConfigResp string contains the current setting.\r
+ @param HiiPackageList Point to Hii package list.\r
+ @param PackageListLength The length of the pacakge.\r
+ @param VarGuid Guid of the buffer storage.\r
+ @param VarName Name of the buffer storage.\r
+ @param HiiHandle The HiiHandle for this package.\r
+ \r
+ @retval EFI_SUCCESS The current setting is valid.\r
+ @retval EFI_OUT_OF_RESOURCES The memory is not enough.\r
+ @retval EFI_INVALID_PARAMETER The config string or the Hii package is invalid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalHiiValidateCurrentSetting (\r
+ IN EFI_STRING ConfigResp,\r
+ IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
+ IN UINTN PackageListLength,\r
+ IN EFI_GUID *VarGuid,\r
+ IN CHAR16 *VarName,\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ CHAR16 *StringPtr;\r
+ EFI_STATUS Status;\r
+ IFR_BLOCK_DATA *CurrentBlockArray;\r
+ IFR_BLOCK_DATA *BlockData;\r
+ UINT8 *VarBuffer;\r
+ BOOLEAN NameValueType;\r
+\r
+ CurrentBlockArray = NULL;\r
+ VarBuffer = NULL;\r
+ StringPtr = NULL;\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // If StringPtr != NULL, get the request elements.\r
+ //\r
+ if (StrStr (ConfigResp, L"&OFFSET=") != NULL) {\r
+ Status = GetBlockDataInfo(ConfigResp, &CurrentBlockArray, &VarBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ NameValueType = FALSE;\r
+ } else {\r
+ //\r
+ // Skip header part.\r
+ //\r
+ StringPtr = StrStr (ConfigResp, L"PATH=");\r
+ ASSERT (StringPtr != NULL);\r
+\r
+ if (StrStr (StringPtr, L"&") != NULL) {\r
+ NameValueType = TRUE;\r
+ } else {\r
+ //\r
+ // Not found Request element, return success.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ Status = ValidateQuestionFromVfr(\r
+ HiiPackageList,\r
+ PackageListLength,\r
+ VarGuid,\r
+ VarName,\r
+ VarBuffer,\r
+ CurrentBlockArray,\r
+ ConfigResp,\r
+ HiiHandle,\r
+ NameValueType\r
+ );\r
+\r
if (VarBuffer != NULL) {\r
FreePool (VarBuffer);\r
}\r
RemoveEntryList (&BlockData->Entry);\r
FreePool (BlockData);\r
}\r
- FreePool (CurrentBlockArray); \r
+ FreePool (CurrentBlockArray);\r
}\r
\r
return Status;\r
}\r
\r
+/**\r
+ Check whether the ConfigRequest string has the request elements.\r
+ For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.\r
+ For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.\r
+\r
+ @param ConfigRequest The input config request string.\r
+\r
+ @retval TRUE The input include config request elements.\r
+ @retval FALSE The input string not includes.\r
+ \r
+**/\r
+BOOLEAN\r
+GetElementsFromRequest (\r
+ IN EFI_STRING ConfigRequest\r
+ )\r
+{\r
+ EFI_STRING TmpRequest;\r
+\r
+ TmpRequest = StrStr (ConfigRequest, L"PATH=");\r
+ ASSERT (TmpRequest != NULL);\r
+\r
+ if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
This function parses the input ConfigRequest string and its matched IFR code\r
string for setting default value and validating current setting.\r
// Its default value and validating can't execute by parsing IFR data.\r
// Directly jump into the next ConfigAltResp string for another pair Guid, Name, and Path. \r
//\r
- Status = EFI_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
goto NextConfigAltResp;\r
}\r
\r
//\r
// Only the ConfigHdr is found. Not any block data is found. No data is required to be validated and set.\r
//\r
- if (StrStr (ConfigResp, L"&OFFSET=") == NULL) {\r
+ if (!GetElementsFromRequest (ConfigResp)) {\r
goto NextConfigAltResp;\r
}\r
\r
//\r
// Current Setting is in ConfigResp, will be set into buffer, then check it again.\r
//\r
- Status = InternalHiiValidateCurrentSetting (ConfigResp, HiiPackageList, PackageListLength, VarGuid, VarName);\r
+ Status = InternalHiiValidateCurrentSetting (ConfigResp, HiiPackageList, PackageListLength, VarGuid, VarName, HiiHandle);\r
}\r
\r
if (EFI_ERROR (Status)) {\r
HiiPackageList = NULL;\r
}\r
\r
- if (ConfigResp != NULL) {\r
- FreePool (ConfigResp);\r
- ConfigResp = NULL;\r
- }\r
+ if (ConfigResp != NULL) {\r
+ FreePool (ConfigResp);\r
+ ConfigResp = NULL;\r
+ }\r
\r
//\r
// Free the allocated buffer.\r
if (Buffer == NULL) {\r
*SubStr = AllocateCopyPool (StrSize (String), String);\r
ASSERT (*SubStr != NULL);\r
- return ;\r
+ return;\r
}\r
\r
//\r
// Find next AltCfg String\r
//\r
*(AltConfigHdr + HeaderLength) = L'\0';\r
- StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr); \r
+ StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);\r
}\r
\r
FreePool (AltConfigHdr);\r
)\r
{\r
LIST_ENTRY *Link;\r
- IFR_DEFAULT_DATA *DefaultValueArray;\r
+ IFR_DEFAULT_DATA *DefaultValueArray; \r
+ LIST_ENTRY *DefaultLink;\r
+ \r
+ DefaultLink = &BlockData->DefaultValueEntry;\r
\r
- for (Link = BlockData->DefaultValueEntry.ForwardLink; Link != &BlockData->DefaultValueEntry; Link = Link->ForwardLink) {\r
+ for (Link = DefaultLink->ForwardLink; Link != DefaultLink; Link = Link->ForwardLink) {\r
DefaultValueArray = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {\r
//\r
/**\r
This function inserts new BlockData into the block link\r
\r
- @param BlockLink The list entry points to block array.\r
- @param BlockData The point to BlockData is added.\r
+ @param BlockLink The list entry points to block array.\r
+ @param BlockData The point to BlockData is added.\r
\r
**/\r
VOID\r
IN IFR_BLOCK_DATA **BlockData\r
)\r
{\r
- LIST_ENTRY *Link;\r
- IFR_BLOCK_DATA *BlockArray;\r
- IFR_BLOCK_DATA *BlockSingleData;\r
+ LIST_ENTRY *Link;\r
+ IFR_BLOCK_DATA *BlockArray;\r
+ IFR_BLOCK_DATA *BlockSingleData;\r
\r
BlockSingleData = *BlockData;\r
- \r
+\r
+ if (BlockSingleData->Name != NULL) {\r
+ InsertTailList (BlockLink, &BlockSingleData->Entry);\r
+ return;\r
+ }\r
+\r
//\r
// Insert block data in its Offset and Width order.\r
//\r
//\r
// The same block array has been added.\r
//\r
- FreePool (BlockSingleData);\r
- *BlockData = BlockArray;\r
+ if (BlockSingleData != BlockArray) {\r
+ FreePool (BlockSingleData);\r
+ *BlockData = BlockArray;\r
+ }\r
return;\r
}\r
} else if (BlockArray->Offset > BlockSingleData->Offset) {\r
//\r
// Add new block data into the tail.\r
//\r
- InsertTailList (Link, &BlockSingleData->Entry);\r
- return; \r
+ InsertTailList (Link, &BlockSingleData->Entry); \r
+}\r
+\r
+/**\r
+ Retrieves a pointer to the a Null-terminated ASCII string containing the list \r
+ of languages that an HII handle in the HII Database supports. The returned \r
+ string is allocated using AllocatePool(). The caller is responsible for freeing\r
+ the returned string using FreePool(). The format of the returned string follows\r
+ the language format assumed the HII Database.\r
+ \r
+ If HiiHandle is NULL, then ASSERT().\r
+\r
+ @param[in] HiiHandle A handle that was previously registered in the HII Database.\r
+\r
+ @retval NULL HiiHandle is not registered in the HII database\r
+ @retval NULL There are not enough resources available to retrieve the suported \r
+ languages.\r
+ @retval NULL The list of suported languages could not be retrieved.\r
+ @retval Other A pointer to the Null-terminated ASCII string of supported languages.\r
+\r
+**/\r
+CHAR8 *\r
+GetSupportedLanguages (\r
+ IN EFI_HII_HANDLE HiiHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN LanguageSize;\r
+ CHAR8 TempSupportedLanguages;\r
+ CHAR8 *SupportedLanguages;\r
+\r
+ ASSERT (HiiHandle != NULL);\r
+\r
+ //\r
+ // Retrieve the size required for the supported languages buffer.\r
+ //\r
+ LanguageSize = 0;\r
+ Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize);\r
+\r
+ //\r
+ // If GetLanguages() returns EFI_SUCCESS for a zero size, \r
+ // then there are no supported languages registered for HiiHandle. If GetLanguages() \r
+ // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+ // in the HII Database\r
+ //\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ //\r
+ // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Allocate the supported languages buffer.\r
+ //\r
+ SupportedLanguages = AllocateZeroPool (LanguageSize);\r
+ if (SupportedLanguages == NULL) {\r
+ //\r
+ // Return NULL if allocation fails.\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Retrieve the supported languages string\r
+ //\r
+ Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, SupportedLanguages, &LanguageSize);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+ //\r
+ FreePool (SupportedLanguages);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Return the Null-terminated ASCII string of supported languages\r
+ //\r
+ return SupportedLanguages;\r
+}\r
+\r
+/**\r
+ Retrieves a string from a string package.\r
+ \r
+ If HiiHandle is NULL, then ASSERT().\r
+ If StringId is 0, then ASSET.\r
+\r
+ @param[in] HiiHandle A handle that was previously registered in the HII Database.\r
+ @param[in] StringId The identifier of the string to retrieved from the string \r
+ package associated with HiiHandle.\r
+\r
+ @retval NULL The string specified by StringId is not present in the string package.\r
+ @retval Other The string was returned.\r
+\r
+**/\r
+EFI_STRING\r
+InternalGetString (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_STRING_ID StringId\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN StringSize;\r
+ CHAR16 TempString;\r
+ EFI_STRING String;\r
+ CHAR8 *SupportedLanguages;\r
+ CHAR8 *PlatformLanguage;\r
+ CHAR8 *BestLanguage;\r
+ CHAR8 *Language;\r
+\r
+ ASSERT (HiiHandle != NULL);\r
+ ASSERT (StringId != 0);\r
+\r
+ //\r
+ // Initialize all allocated buffers to NULL\r
+ // \r
+ SupportedLanguages = NULL;\r
+ PlatformLanguage = NULL;\r
+ BestLanguage = NULL;\r
+ String = NULL;\r
+ Language = "";\r
+\r
+ //\r
+ // Get the languages that the package specified by HiiHandle supports\r
+ //\r
+ SupportedLanguages = GetSupportedLanguages (HiiHandle);\r
+ if (SupportedLanguages == NULL) {\r
+ goto Error;\r
+ }\r
+\r
+ //\r
+ // Get the current platform language setting\r
+ //\r
+ GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatformLanguage, NULL);\r
+\r
+ //\r
+ // Get the best matching language from SupportedLanguages\r
+ //\r
+ BestLanguage = GetBestLanguage (\r
+ SupportedLanguages, \r
+ FALSE, // RFC 4646 mode\r
+ Language, // Highest priority \r
+ PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority\r
+ SupportedLanguages, // Lowest priority \r
+ NULL\r
+ );\r
+ if (BestLanguage == NULL) {\r
+ goto Error;\r
+ }\r
+\r
+ //\r
+ // Retrieve the size of the string in the string package for the BestLanguage\r
+ //\r
+ StringSize = 0;\r
+ Status = mPrivate.HiiString.GetString (\r
+ &mPrivate.HiiString,\r
+ BestLanguage,\r
+ HiiHandle,\r
+ StringId,\r
+ &TempString,\r
+ &StringSize,\r
+ NULL\r
+ );\r
+ //\r
+ // If GetString() returns EFI_SUCCESS for a zero size, \r
+ // then there are no supported languages registered for HiiHandle. If GetString() \r
+ // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+ // in the HII Database\r
+ //\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ goto Error;\r
+ }\r
+\r
+ //\r
+ // Allocate a buffer for the return string\r
+ //\r
+ String = AllocateZeroPool (StringSize);\r
+ if (String == NULL) {\r
+ goto Error;\r
+ }\r
+\r
+ //\r
+ // Retrieve the string from the string package\r
+ //\r
+ Status = mPrivate.HiiString.GetString (\r
+ &mPrivate.HiiString,\r
+ BestLanguage,\r
+ HiiHandle,\r
+ StringId,\r
+ String,\r
+ &StringSize,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+ //\r
+ FreePool (String);\r
+ String = NULL;\r
+ }\r
+\r
+Error:\r
+ //\r
+ // Free allocated buffers\r
+ //\r
+ if (SupportedLanguages != NULL) {\r
+ FreePool (SupportedLanguages);\r
+ }\r
+ if (PlatformLanguage != NULL) {\r
+ FreePool (PlatformLanguage);\r
+ }\r
+ if (BestLanguage != NULL) {\r
+ FreePool (BestLanguage);\r
+ }\r
+\r
+ //\r
+ // Return the Null-terminated Unicode string\r
+ //\r
+ return String;\r
}\r
\r
/**\r
@param RequestBlockArray The block array is to be checked. \r
@param VarOffset Offset of var to the structure\r
@param VarWidth Width of var.\r
+ @param IsNameValueType Whether this varstore is name/value varstore or not.\r
+ @param HiiHandle Hii handle for this hii package.\r
\r
@retval TRUE This Var is in the block range.\r
@retval FALSE This Var is not in the block range.\r
BlockArrayCheck (\r
IN IFR_BLOCK_DATA *RequestBlockArray,\r
IN UINT16 VarOffset,\r
- IN UINT16 VarWidth\r
+ IN UINT16 VarWidth,\r
+ IN BOOLEAN IsNameValueType,\r
+ IN EFI_HII_HANDLE HiiHandle\r
)\r
{\r
LIST_ENTRY *Link;\r
IFR_BLOCK_DATA *BlockData;\r
- \r
+ EFI_STRING Name;\r
+\r
//\r
// No Request Block array, all vars are got.\r
//\r
if (RequestBlockArray == NULL) {\r
return TRUE;\r
}\r
- \r
+\r
//\r
// Check the input var is in the request block range.\r
//\r
for (Link = RequestBlockArray->Entry.ForwardLink; Link != &RequestBlockArray->Entry; Link = Link->ForwardLink) {\r
BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
- if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {\r
- return TRUE;\r
+\r
+ if (IsNameValueType) {\r
+ Name = InternalGetString (HiiHandle, VarOffset);\r
+ ASSERT (Name != NULL);\r
+\r
+ if (StrnCmp (BlockData->Name, Name, StrLen (Name)) == 0) {\r
+ FreePool (Name);\r
+ return TRUE;\r
+ }\r
+ FreePool (Name);\r
+ } else {\r
+ if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {\r
+ return TRUE;\r
+ }\r
}\r
}\r
\r
IN EFI_STRING ConfigHdr,\r
OUT BOOLEAN *IsEfiVarstore,\r
OUT EFI_IFR_VARSTORE_EFI **EfiVarStore\r
- \r
)\r
{\r
EFI_STATUS Status;\r
return Status;\r
}\r
\r
+/**\r
+ Check whether the ConfigRequest string has the request elements.\r
+ For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.\r
+ For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.\r
+\r
+ @param ConfigRequest The input config request string.\r
+\r
+ @retval TRUE The input include config request elements.\r
+ @retval FALSE The input string not includes.\r
+\r
+**/\r
+BOOLEAN\r
+GetElementsFromRequest (\r
+ IN EFI_STRING ConfigRequest\r
+ )\r
+{\r
+ EFI_STRING TmpRequest;\r
+\r
+ TmpRequest = StrStr (ConfigRequest, L"PATH=");\r
+ ASSERT (TmpRequest != NULL);\r
+\r
+ if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Check whether the this varstore is the request varstore.\r
+\r
+ @param VarstoreGuid Varstore guid.\r
+ @param Name Varstore name.\r
+ @param ConfigHdr Current configRequest info.\r
+\r
+ @retval TRUE This varstore is the requst one.\r
+ @retval FALSE This varstore is not the requst one.\r
+ \r
+**/\r
+BOOLEAN\r
+IsThisVarstore (\r
+ IN EFI_GUID *VarstoreGuid,\r
+ IN CHAR16 *Name,\r
+ IN CHAR16 *ConfigHdr\r
+ )\r
+{\r
+ EFI_STRING GuidStr;\r
+ EFI_STRING NameStr;\r
+ EFI_STRING TempStr;\r
+ UINTN LengthString;\r
+ BOOLEAN RetVal;\r
+\r
+ RetVal = FALSE;\r
+ GuidStr = NULL;\r
+ TempStr = NULL;\r
+\r
+ GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);\r
+ if (Name != NULL) {\r
+ GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *) Name, 2, &NameStr);\r
+ } else {\r
+ GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
+ }\r
+ LengthString = StrLen (GuidStr);\r
+ LengthString = LengthString + StrLen (NameStr) + 1;\r
+ TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
+ if (TempStr == NULL) {\r
+ goto Done;\r
+ }\r
+\r
+ StrCpy (TempStr, GuidStr);\r
+ StrCat (TempStr, NameStr);\r
+\r
+ if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+ RetVal = TRUE;\r
+ }\r
+\r
+Done:\r
+ if (GuidStr != NULL) {\r
+ FreePool (GuidStr); \r
+ }\r
+\r
+ if (NameStr != NULL) {\r
+ FreePool (NameStr);\r
+ }\r
+\r
+ if (TempStr != NULL) {\r
+ FreePool (TempStr);\r
+ }\r
+\r
+ return RetVal;\r
+}\r
+\r
+/**\r
+ Check whether the this op code is required.\r
+\r
+ @param RequestBlockArray The array includes all the request info or NULL.\r
+ @param HiiHandle The hii handle for this form package.\r
+ @param VarStorageData The varstore data strucure.\r
+ @param IfrOpHdr Ifr opcode header for this opcode.\r
+ @param VarWidth The buffer width for this opcode.\r
+ @param ReturnData The data block added for this opcode.\r
+\r
+ @retval EFI_SUCCESS This opcode is required.\r
+ @retval Others This opcode is not required or error occur.\r
+ \r
+**/\r
+EFI_STATUS\r
+IsThisOpcodeRequired (\r
+ IN IFR_BLOCK_DATA *RequestBlockArray,\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN OUT IFR_VARSTORAGE_DATA *VarStorageData,\r
+ IN EFI_IFR_OP_HEADER *IfrOpHdr,\r
+ IN UINT16 VarWidth,\r
+ OUT IFR_BLOCK_DATA **ReturnData\r
+ )\r
+{\r
+ IFR_BLOCK_DATA *BlockData;\r
+ UINT16 VarOffset;\r
+ EFI_STRING_ID NameId;\r
+ EFI_IFR_QUESTION_HEADER *IfrQuestionHdr;\r
+\r
+ NameId = 0;\r
+ VarOffset = 0;\r
+ IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER *)((CHAR8 *) IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));\r
+\r
+ if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ NameId = IfrQuestionHdr->VarStoreInfo.VarName;\r
+\r
+ //\r
+ // Check whether this question is in requested block array.\r
+ //\r
+ if (!BlockArrayCheck (RequestBlockArray, NameId, 0, TRUE, HiiHandle)) {\r
+ //\r
+ // This question is not in the requested string. Skip it.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ } else {\r
+ VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+ \r
+ //\r
+ // Check whether this question is in requested block array.\r
+ //\r
+ if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth, FALSE, HiiHandle)) {\r
+ //\r
+ // This question is not in the requested string. Skip it.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Check this var question is in the var storage \r
+ //\r
+ if (((VarOffset + VarWidth) > VarStorageData->Size)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
+ BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+ if (BlockData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ BlockData->Name = InternalGetString(HiiHandle, NameId);\r
+ } else {\r
+ BlockData->Offset = VarOffset;\r
+ }\r
+\r
+ BlockData->Width = VarWidth;\r
+ BlockData->QuestionId = IfrQuestionHdr->QuestionId;\r
+ BlockData->OpCode = IfrOpHdr->OpCode;\r
+ BlockData->Scope = IfrOpHdr->Scope;\r
+ InitializeListHead (&BlockData->DefaultValueEntry);\r
+ //\r
+ // Add Block Data into VarStorageData BlockEntry\r
+ //\r
+ InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+ *ReturnData = BlockData;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
This function parses Form Package to get the block array and the default\r
value array according to the request ConfigHdr.\r
\r
+ @param HiiHandle Hii Handle for this hii package.\r
@param Package Pointer to the form package data.\r
@param PackageLength Length of the pacakge.\r
@param ConfigHdr Request string ConfigHdr. If it is NULL,\r
the first found varstore will be as ConfigHdr.\r
@param RequestBlockArray The block array is retrieved from the request string.\r
@param VarStorageData VarStorage structure contains the got block and default value.\r
- @param PIfrDefaultIdArray Point to the got default id and default name array.\r
+ @param DefaultIdArray Point to the got default id and default name array.\r
\r
@retval EFI_SUCCESS The block array and the default value array are got.\r
@retval EFI_INVALID_PARAMETER The varstore defintion in the differnt form pacakges\r
EFI_STATUS\r
EFIAPI\r
ParseIfrData (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
IN UINT8 *Package,\r
IN UINT32 PackageLength,\r
IN EFI_STRING ConfigHdr,\r
IFR_DEFAULT_DATA *DefaultDataPtr;\r
IFR_BLOCK_DATA *BlockData;\r
CHAR16 *VarStoreName;\r
- UINT16 VarOffset;\r
UINT16 VarWidth;\r
UINT16 VarDefaultId;\r
EFI_STRING GuidStr;\r
BOOLEAN FirstOneOfOption;\r
LIST_ENTRY *LinkData;\r
LIST_ENTRY *LinkDefault;\r
+ EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;\r
\r
LengthString = 0;\r
Status = EFI_SUCCESS;\r
IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
while (IfrOffset < PackageLength) {\r
IfrOpHdr = (EFI_IFR_OP_HEADER *) (Package + IfrOffset);\r
-\r
switch (IfrOpHdr->OpCode) {\r
case EFI_IFR_VARSTORE_OP:\r
//\r
// VarStore is found. Don't need to search any more.\r
//\r
- if (VarStorageData->Size != 0) {\r
+ if (VarStorageData->VarStoreId != 0) {\r
break;\r
}\r
\r
- //\r
- // Get the requied varstore information\r
- // Add varstore by Guid and Name in ConfigHdr\r
- // Make sure Offset is in varstore size and varstoreid\r
- //\r
IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
- VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));\r
+\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize (IfrVarStore->Name) * sizeof (CHAR16));\r
if (VarStoreName == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
- AsciiStrToUnicodeStr ((CHAR8 *) IfrVarStore->Name, VarStoreName);\r
+ AsciiStrToUnicodeStr (IfrVarStore->Name, VarStoreName);\r
\r
- GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrVarStore->Guid, 1, &GuidStr);\r
- GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *) VarStoreName, 2, &NameStr);\r
- LengthString = StrLen (GuidStr);\r
- LengthString = LengthString + StrLen (NameStr) + 1;\r
- TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
- if (TempStr == NULL) {\r
- FreePool (GuidStr);\r
- FreePool (NameStr);\r
- FreePool (VarStoreName);\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- StrCpy (TempStr, GuidStr);\r
- StrCat (TempStr, NameStr);\r
- if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+ if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
//\r
// Find the matched VarStore\r
//\r
VarStorageData->VarStoreId = IfrVarStore->VarStoreId;\r
VarStorageData->Size = IfrVarStore->Size;\r
VarStorageData->Name = VarStoreName;\r
- } else {\r
- //\r
- // No found, free the allocated memory \r
- //\r
- FreePool (VarStoreName);\r
+ VarStorageData->Type = EFI_HII_VARSTORE_BUFFER;\r
}\r
- //\r
- // Free alllocated temp string.\r
- //\r
- FreePool (GuidStr);\r
- FreePool (NameStr);\r
- FreePool (TempStr);\r
break;\r
\r
case EFI_IFR_VARSTORE_EFI_OP:\r
//\r
// VarStore is found. Don't need to search any more.\r
//\r
- if (VarStorageData->Size != 0) {\r
+ if (VarStorageData->VarStoreId != 0) {\r
break;\r
}\r
\r
- //\r
- // Get the requied varstore information\r
- // Add varstore by Guid and Name in ConfigHdr\r
- // Make sure Offset is in varstore size and varstoreid\r
- //\r
IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
\r
//\r
break;\r
}\r
\r
- VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize (IfrEfiVarStore->Name) * sizeof (CHAR16));\r
if (VarStoreName == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
- AsciiStrToUnicodeStr ((CHAR8 *) IfrEfiVarStore->Name, VarStoreName);\r
+ AsciiStrToUnicodeStr (IfrEfiVarStore->Name, VarStoreName);\r
\r
- GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrEfiVarStore->Guid, 1, &GuidStr);\r
- GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *) VarStoreName, 2, &NameStr);\r
- LengthString = StrLen (GuidStr);\r
- LengthString = LengthString + StrLen (NameStr) + 1;\r
- TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
- if (TempStr == NULL) {\r
- FreePool (GuidStr);\r
- FreePool (NameStr);\r
- FreePool (VarStoreName);\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- StrCpy (TempStr, GuidStr);\r
- StrCat (TempStr, NameStr);\r
- if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+ if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
//\r
// Find the matched VarStore\r
//\r
VarStorageData->VarStoreId = IfrEfiVarStore->VarStoreId;\r
VarStorageData->Size = IfrEfiVarStore->Size;\r
VarStorageData->Name = VarStoreName;\r
- } else {\r
- //\r
- // No found, free the allocated memory \r
- //\r
- FreePool (VarStoreName);\r
+ VarStorageData->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;\r
}\r
+ break;\r
+\r
+ case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
//\r
- // Free alllocated temp string.\r
+ // VarStore is found. Don't need to search any more.\r
//\r
- FreePool (GuidStr);\r
- FreePool (NameStr);\r
- FreePool (TempStr);\r
+ if (VarStorageData->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->VarStoreId = IfrNameValueVarStore->VarStoreId;\r
+ VarStorageData->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+ }\r
break;\r
\r
case EFI_IFR_DEFAULTSTORE_OP:\r
//\r
// No matched varstore is found and directly return.\r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_SUCCESS;\r
goto Done;\r
}\r
//\r
// Ref question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
if (IfrRef->Question.VarStoreId != VarStorageData->VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset/Width by Question header.\r
- //\r
- VarOffset = IfrRef->Question.VarStoreInfo.VarOffset;\r
VarWidth = (UINT16) (sizeof (EFI_HII_REF));\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
- //\r
- // This question is not in the requested string. Skip it.\r
- //\r
- break;\r
- }\r
\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrRef->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- BlockData->Scope = IfrOpHdr->Scope;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
break;\r
\r
case EFI_IFR_ONE_OF_OP:\r
//\r
// Numeric and OneOf question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
if (IfrOneOf->Question.VarStoreId != VarStorageData->VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
VarWidth = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
- //\r
- // This question is not in the requested string. Skip it.\r
- //\r
- break;\r
- }\r
\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- \r
- //\r
- // Set Block Data\r
- //\r
- BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+\r
if (BlockData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
+ //\r
+ // BlockData == NULL means this opcode is not in the requst array.\r
+ //\r
+ break;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrOneOf->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- BlockData->Scope = IfrOpHdr->Scope;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
- \r
+\r
if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {\r
//\r
// Set this flag to TRUE for the first oneof option.\r
case EFI_IFR_NUMERIC_SIZE_1:\r
DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
break;\r
- \r
+\r
case EFI_IFR_NUMERIC_SIZE_2:\r
CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
break;\r
- \r
+\r
case EFI_IFR_NUMERIC_SIZE_4:\r
CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
break;\r
- \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
// Set default value base on the DefaultId list get from IFR data.\r
// \r
for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
- DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry); \r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
InsertDefaultValue (BlockData, &DefaultData);\r
}\r
//\r
// OrderedList question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
BlockData = NULL;\r
break;\r
}\r
-\r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrOrderedList->Question.VarStoreInfo.VarOffset;\r
VarWidth = IfrOrderedList->MaxContainers;\r
- \r
- //\r
- // Set Block Data\r
- //\r
- BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
- if (BlockData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrOrderedList->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- BlockData->Scope = IfrOpHdr->Scope;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
break;\r
\r
case EFI_IFR_CHECKBOX_OP:\r
//\r
// CheckBox question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
if (IfrCheckBox->Question.VarStoreId != VarStorageData->VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
VarWidth = (UINT16) sizeof (BOOLEAN);\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+ if (BlockData == NULL) {\r
//\r
- // This question is not in the requested string. Skip it.\r
+ // BlockData == NULL means this opcode is not in the requst array.\r
//\r
break;\r
}\r
\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrCheckBox->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- BlockData->Scope = IfrOpHdr->Scope;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
- \r
//\r
// Add default value for standard ID by CheckBox Flag\r
//\r
//\r
// When flag is not set, defautl value is FASLE.\r
//\r
- DefaultData.Type = DefaultValueFromDefault; \r
+ DefaultData.Type = DefaultValueFromDefault;\r
DefaultData.Value.b = FALSE;\r
}\r
//\r
//\r
// Date question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
break;\r
}\r
\r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrDate->Question.VarStoreInfo.VarOffset;\r
VarWidth = (UINT16) sizeof (EFI_HII_DATE);\r
-\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
- //\r
- // This question is not in the requested array. Skip it.\r
- //\r
- break;\r
- }\r
-\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrDate->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- BlockData->Scope = IfrOpHdr->Scope;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
-\r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
break;\r
\r
case EFI_IFR_TIME_OP:\r
//\r
// Time question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
break;\r
}\r
\r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrTime->Question.VarStoreInfo.VarOffset;\r
VarWidth = (UINT16) sizeof (EFI_HII_TIME);\r
-\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
- //\r
- // This question is not in the requested array. Skip it.\r
- //\r
- break;\r
- }\r
-\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrTime->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- BlockData->Scope = IfrOpHdr->Scope;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
-\r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
break;\r
\r
case EFI_IFR_STRING_OP:\r
//\r
// String question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
if (IfrString->Question.VarStoreId != VarStorageData->VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrString->Question.VarStoreInfo.VarOffset;\r
- VarWidth = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
-\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
- //\r
- // This question is not in the requested string. Skip it.\r
- //\r
- break;\r
- }\r
\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
+ VarWidth = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrString->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
- \r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
- \r
+\r
//\r
// No default value for string.\r
//\r
//\r
// Password question is not in IFR Form. This IFR form is not valid. \r
//\r
- if (VarStorageData->Size == 0) {\r
+ if (VarStorageData->VarStoreId == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
if (IfrPassword->Question.VarStoreId != VarStorageData->VarStoreId) {\r
break;\r
}\r
- \r
- //\r
- // Get Offset/Width by Question header and OneOf Flags\r
- //\r
- VarOffset = IfrPassword->Question.VarStoreInfo.VarOffset;\r
- VarWidth = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));\r
-\r
- //\r
- // Check whether this question is in requested block array.\r
- //\r
- if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
- //\r
- // This question is not in the requested string. Skip it.\r
- //\r
- break;\r
- }\r
\r
- //\r
- // Check this var question is in the var storage \r
- //\r
- if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
+ VarWidth = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- BlockData->Offset = VarOffset;\r
- BlockData->Width = VarWidth;\r
- BlockData->QuestionId = IfrPassword->Question.QuestionId;\r
- BlockData->OpCode = IfrOpHdr->OpCode;\r
- InitializeListHead (&BlockData->DefaultValueEntry);\r
- \r
- //\r
- // Add Block Data into VarStorageData BlockEntry\r
- //\r
- InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
- \r
+\r
//\r
// No default value for string.\r
//\r
if (BlockData == NULL || BlockData->Scope == 0) {\r
break;\r
}\r
- \r
+\r
IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpHdr;\r
if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\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
FreePool (BlockData);\r
goto Done;\r
}\r
//\r
// Check whether this question is in requested block array.\r
//\r
- if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width)) {\r
+ if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, 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
FreePool (BlockData);\r
BlockData = NULL;\r
break;\r
//\r
// Check this var question is in the var storage \r
//\r
- if ((BlockData->Offset + BlockData->Width) > VarStorageData->Size) {\r
+ if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {\r
Status = EFI_INVALID_PARAMETER;\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
FreePool (BlockData);\r
goto Done;\r
}\r
\r
// Prepare new DefaultValue\r
//\r
- DefaultData.Type = DefaultValueFromFlag;\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
DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
InsertDefaultValue (BlockData, &DefaultData);\r
}\r
-\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
// Prepare new DefaultValue\r
// \r
- DefaultData.Type = DefaultValueFromDefault;\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
//\r
if (BlockData == NULL || BlockData->Scope == 0) {\r
//\r
- // No matched block data is ignored. \r
+ // No matched block data is ignored.\r
//\r
break;\r
}\r
DefaultData.Type = DefaultValueFromOpcode;\r
DefaultData.DefaultId = VarDefaultId;\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
// Add DefaultValue into current BlockData\r
//\r
InsertDefaultValue (BlockData, &DefaultData);\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 everytime \r
//\r
DefaultData.Cleaned = FALSE;\r
break;\r
+\r
case EFI_IFR_END_OP:\r
//\r
// End Opcode is for Var question.\r
BlockData->Scope--;\r
}\r
break;\r
+\r
default:\r
if (BlockData != NULL && BlockData->Scope > 0) {\r
BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);\r
}\r
}\r
\r
- return Status; \r
+ return Status;\r
}\r
\r
/**\r
- This function gets the full request string and full default value string by \r
- parsing IFR data in HII form packages. \r
- \r
- When Request points to NULL string, the request string and default value string \r
- for each varstore in form package will return. \r
+ parse the configrequest string, get the elements.\r
\r
- @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.\r
- @param DevicePath Device Path which Hii Config Access Protocol is registered.\r
- @param Request Pointer to a null-terminated Unicode string in\r
- <ConfigRequest> format. When it doesn't contain\r
- any RequestElement, it will be updated to return \r
- the full RequestElement retrieved from IFR data.\r
- If it points to NULL, the request string for the first\r
- varstore in form package will be merged into a\r
- <MultiConfigRequest> format string and return. \r
- @param AltCfgResp Pointer to a null-terminated Unicode string in\r
- <ConfigAltResp> format. When the pointer is to NULL,\r
- the full default value string retrieved from IFR data\r
- will return. When the pinter is to a string, the\r
- full default value string retrieved from IFR data\r
- will be merged into the input string and return.\r
- When Request points to NULL, the default value string \r
- for each varstore in form package will be merged into \r
- a <MultiConfigAltResp> format string and return.\r
- @param PointerProgress Optional parameter, it can be be NULL. \r
- When it is not NULL, if Request is NULL, it returns NULL. \r
- On return, points to a character in the Request\r
- string. Points to the string's null terminator if\r
- request was successful. Points to the most recent\r
- & before the first failing name / value pair (or\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
+ //\r
+ // Init RequestBlockArray\r
+ //\r
+ RequestBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+ if (RequestBlockArray == NULL) {\r
+ goto Done;\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
+ 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
+ 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
+ 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
+ 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
+ StringPtr += Length;\r
+ if (*StringPtr != 0 && *StringPtr != L'&') {\r
+ goto Done;\r
+ }\r
+ }\r
+ //\r
+ // If '\0', parsing is finished. \r
+ //\r
+ if (*StringPtr == 0) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Merge the requested block data.\r
+ //\r
+ Link = RequestBlockArray->Entry.ForwardLink;\r
+ while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {\r
+ BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
+ if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
+ if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
+ BlockData->Width = (UINT16) (NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);\r
+ }\r
+ RemoveEntryList (Link->ForwardLink);\r
+ FreePool (NextBlockData);\r
+ continue;\r
+ }\r
+ Link = Link->ForwardLink;\r
+ }\r
+\r
+ return RequestBlockArray;\r
+\r
+Done:\r
+ if (RequestBlockArray != NULL) {\r
+ //\r
+ // Free Link Array RequestBlockArray\r
+ //\r
+ while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+ BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+ RemoveEntryList (&BlockData->Entry);\r
+ FreePool (BlockData);\r
+ }\r
+\r
+ FreePool (RequestBlockArray);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ parse the configrequest string, get the elements.\r
+\r
+ @param ConfigRequest The input config request string.\r
+ @param Progress Return the progress data.\r
+\r
+ @retval return data block array.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetNameElement (\r
+ IN EFI_STRING ConfigRequest,\r
+ OUT EFI_STRING *Progress\r
+ )\r
+{\r
+ EFI_STRING StringPtr;\r
+ EFI_STRING NextTag;\r
+ IFR_BLOCK_DATA *BlockData;\r
+ IFR_BLOCK_DATA *RequestBlockArray;\r
+ BOOLEAN HasValue;\r
+\r
+ StringPtr = ConfigRequest;\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
+ InitializeListHead (&RequestBlockArray->Entry);\r
+\r
+ //\r
+ // Get the request Block array from the request string\r
+ //\r
+\r
+ //\r
+ // Parse each <RequestElement> if exists\r
+ // Only <BlockName> format is supported by this help function.\r
+ // <BlockName> ::= &'Name***=***\r
+ //\r
+ while (StringPtr != NULL && *StringPtr == L'&') {\r
+\r
+ *Progress = StringPtr;\r
+ //\r
+ // Skip the L"&" string\r
+ //\r
+ StringPtr += 1;\r
+\r
+ HasValue = FALSE;\r
+ if ((NextTag = StrStr (StringPtr, L"=")) != NULL) {\r
+ *NextTag = L'\0';\r
+ HasValue = TRUE;\r
+ } else if ((NextTag = StrStr (StringPtr, L"&")) != NULL) {\r
+ *NextTag = L'\0';\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
+ //\r
+ // Get Name\r
+ //\r
+ BlockData->Name = AllocateCopyPool(StrSize (StringPtr), StringPtr);\r
+ InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
+\r
+ if (HasValue) {\r
+ //\r
+ // If has value, skip the value.\r
+ // \r
+ StringPtr = NextTag + 1;\r
+ *NextTag = L'=';\r
+ StringPtr = StrStr (StringPtr, L"&");\r
+ } else if (NextTag != NULL) {\r
+ //\r
+ // restore the '&' text.\r
+ //\r
+ StringPtr = NextTag;\r
+ *NextTag = L'&';\r
+ }\r
+ }\r
+\r
+ return RequestBlockArray;\r
+\r
+Done:\r
+ if (RequestBlockArray != NULL) {\r
+ //\r
+ // Free Link Array RequestBlockArray\r
+ //\r
+ while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+ BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+ RemoveEntryList (&BlockData->Entry);\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
+ FreePool (BlockData);\r
+ }\r
+\r
+ FreePool (RequestBlockArray);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Generate ConfigRequest string base on the varstore info.\r
+\r
+ @param ConfigHdr The config header for this varstore.\r
+ @param VarStorageData The varstore info.\r
+ @param Status Return Status.\r
+ @param ConfigRequest The ConfigRequest info may be return.\r
+\r
+ @retval TRUE Need to continue\r
+ @retval Others NO need to continue or error occur.\r
+**/\r
+BOOLEAN\r
+GenerateConfigRequest (\r
+ IN CHAR16 *ConfigHdr,\r
+ IN IFR_VARSTORAGE_DATA *VarStorageData,\r
+ OUT EFI_STATUS *Status,\r
+ IN OUT EFI_STRING *ConfigRequest\r
+ )\r
+{\r
+ BOOLEAN DataExist;\r
+ UINTN Length;\r
+ LIST_ENTRY *Link;\r
+ CHAR16 *FullConfigRequest;\r
+ CHAR16 *StringPtr;\r
+ IFR_BLOCK_DATA *BlockData;\r
+\r
+ //\r
+ // Append VarStorageData BlockEntry into *Request string\r
+ // Now support only one varstore in a form package.\r
+ //\r
+ \r
+ //\r
+ // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package\r
+ // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig\r
+ //\r
+ \r
+ //\r
+ // Compute the length of the entire request starting with <ConfigHdr> and a \r
+ // Null-terminator\r
+ //\r
+ DataExist = FALSE;\r
+ Length = StrLen (ConfigHdr) + 1;\r
+\r
+ for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
+ DataExist = TRUE;\r
+ BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // Add <BlockName> length for each Name\r
+ //\r
+ // <BlockName> ::= &Name1&Name2&... \r
+ // |1| StrLen(Name1)\r
+ //\r
+ Length = Length + (1 + StrLen (BlockData->Name));\r
+ } else {\r
+ //\r
+ // Add <BlockName> length for each Offset/Width pair\r
+ //\r
+ // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
+ // | 8 | 4 | 7 | 4 |\r
+ //\r
+ Length = Length + (8 + 4 + 7 + 4);\r
+ }\r
+ }\r
+ //\r
+ // No any request block data is found. The request string can't be constructed.\r
+ //\r
+ if (!DataExist) {\r
+ *Status = EFI_SUCCESS;\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Allocate buffer for the entire <ConfigRequest>\r
+ //\r
+ FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));\r
+ if (FullConfigRequest == NULL) {\r
+ *Status = EFI_OUT_OF_RESOURCES;\r
+ return FALSE;\r
+ }\r
+ StringPtr = FullConfigRequest;\r
+\r
+ //\r
+ // Start with <ConfigHdr>\r
+ //\r
+ StrCpy (StringPtr, ConfigHdr);\r
+ StringPtr += StrLen (StringPtr);\r
+\r
+ //\r
+ // Loop through all the Offset/Width pairs and append them to ConfigRequest\r
+ //\r
+ for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
+ BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // Append &Name1\0\r
+ //\r
+ UnicodeSPrint (\r
+ StringPtr,\r
+ (1 + StrLen (BlockData->Name) + 1) * sizeof (CHAR16),\r
+ L"&%s",\r
+ BlockData->Name\r
+ );\r
+ } else {\r
+ //\r
+ // Append &OFFSET=XXXX&WIDTH=YYYY\0\r
+ //\r
+ UnicodeSPrint (\r
+ StringPtr, \r
+ (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16), \r
+ L"&OFFSET=%04X&WIDTH=%04X", \r
+ BlockData->Offset, \r
+ BlockData->Width\r
+ );\r
+ }\r
+ StringPtr += StrLen (StringPtr);\r
+ }\r
+ //\r
+ // Set to the got full request string.\r
+ //\r
+ HiiToLower (FullConfigRequest);\r
+\r
+ if (*ConfigRequest != NULL) {\r
+ FreePool (*ConfigRequest);\r
+ }\r
+ *ConfigRequest = FullConfigRequest;\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Generate ConfigRequest Header base on the varstore info.\r
+\r
+ @param VarStorageData The varstore info.\r
+ @param DevicePath Device path for this varstore.\r
+ @param ConfigHdr The config header for this varstore.\r
+\r
+ @retval EFI_SUCCESS Generate the header success.\r
+ @retval EFI_OUT_OF_RESOURCES Allocate buffer fail.\r
+**/\r
+EFI_STATUS\r
+GenerateHdr (\r
+ IN IFR_VARSTORAGE_DATA *VarStorageData,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ OUT EFI_STRING *ConfigHdr\r
+ )\r
+{\r
+ EFI_STRING GuidStr;\r
+ EFI_STRING NameStr;\r
+ EFI_STRING PathStr;\r
+ UINTN Length;\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+ NameStr = NULL;\r
+ GuidStr = NULL;\r
+ PathStr = NULL;\r
+\r
+ //\r
+ // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle\r
+ //\r
+ GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &VarStorageData->Guid, 1, &GuidStr);\r
+ if (VarStorageData->Name != NULL) {\r
+ GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *) VarStorageData->Name, 2, &NameStr);\r
+ } else {\r
+ GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
+ }\r
+ GenerateSubStr (\r
+ L"PATH=",\r
+ GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath),\r
+ (VOID *) DevicePath,\r
+ 1,\r
+ &PathStr\r
+ );\r
+ Length = StrLen (GuidStr) + StrLen (NameStr) + StrLen (PathStr) + 1;\r
+ if (VarStorageData->Name == NULL) {\r
+ Length += 1;\r
+ }\r
+\r
+ *ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));\r
+ if (*ConfigHdr == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ StrCpy (*ConfigHdr, GuidStr);\r
+ StrCat (*ConfigHdr, NameStr);\r
+ if (VarStorageData->Name == NULL) {\r
+ StrCat (*ConfigHdr, L"&");\r
+ }\r
+ StrCat (*ConfigHdr, PathStr);\r
+\r
+ //\r
+ // Remove the last character L'&'\r
+ //\r
+ *(*ConfigHdr + StrLen (*ConfigHdr) - 1) = L'\0';\r
+\r
+Done:\r
+ if (GuidStr != NULL) {\r
+ FreePool (GuidStr);\r
+ }\r
+\r
+ if (NameStr != NULL) {\r
+ FreePool (NameStr);\r
+ }\r
+\r
+ if (PathStr != NULL) {\r
+ FreePool (PathStr);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Get Data buffer size based on data type.\r
+\r
+ @param ValueType The input data type.\r
+\r
+ @retval The data buffer size for the input type.\r
+**/\r
+UINT16\r
+GetStorageWidth (\r
+ IN UINT8 ValueType\r
+ )\r
+{\r
+ UINT16 StorageWidth;\r
+\r
+ switch (ValueType) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ case EFI_IFR_TYPE_BOOLEAN:\r
+ StorageWidth = (UINT16) sizeof (UINT8);\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ StorageWidth = (UINT16) sizeof (UINT16);\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ StorageWidth = (UINT16) sizeof (UINT32);\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ StorageWidth = (UINT16) sizeof (UINT64);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_TIME:\r
+ StorageWidth = (UINT16) sizeof (EFI_IFR_TIME);\r
+ break;\r
+\r
+ case EFI_IFR_TYPE_DATE:\r
+ StorageWidth = (UINT16) sizeof (EFI_IFR_DATE);\r
+ break;\r
+\r
+ default:\r
+ StorageWidth = 0;\r
+ break;\r
+ }\r
+\r
+ return StorageWidth;\r
+}\r
+\r
+/**\r
+ Generate ConfigAltResp string base on the varstore info.\r
+\r
+ @param ConfigHdr The config header for this varstore.\r
+ @param VarStorageData The varstore info.\r
+ @param DefaultIdArray The Default id array.\r
+ @param DefaultAltCfgResp The DefaultAltCfgResp info may be return.\r
+\r
+ @retval TRUE Need to continue\r
+ @retval Others NO need to continue or error occur.\r
+**/\r
+EFI_STATUS\r
+GenerateAltConfigResp (\r
+ IN CHAR16 *ConfigHdr,\r
+ IN IFR_VARSTORAGE_DATA *VarStorageData,\r
+ IN IFR_DEFAULT_DATA *DefaultIdArray,\r
+ IN OUT EFI_STRING *DefaultAltCfgResp\r
+ )\r
+{\r
+ BOOLEAN DataExist;\r
+ UINTN Length;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *LinkData;\r
+ LIST_ENTRY *LinkDefault;\r
+ LIST_ENTRY *ListEntry;\r
+ CHAR16 *StringPtr;\r
+ IFR_BLOCK_DATA *BlockData;\r
+ IFR_DEFAULT_DATA *DefaultId;\r
+ IFR_DEFAULT_DATA *DefaultValueData;\r
+ UINTN Width;\r
+ UINT8 *TmpBuffer;\r
+\r
+ BlockData = NULL;\r
+ DataExist = FALSE;\r
+\r
+ //\r
+ // Add length for <ConfigHdr> + '\0'\r
+ //\r
+ Length = StrLen (ConfigHdr) + 1;\r
+\r
+ for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+ DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+ //\r
+ // Add length for "&<ConfigHdr>&ALTCFG=XXXX"\r
+ // |1| StrLen (ConfigHdr) | 8 | 4 |\r
+ //\r
+ Length += (1 + StrLen (ConfigHdr) + 8 + 4);\r
+ \r
+ for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+ BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+ ListEntry = &BlockData->DefaultValueEntry;\r
+ for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+ DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+ if (DefaultValueData->DefaultId != DefaultId->DefaultId) {\r
+ continue;\r
+ }\r
+ if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ //\r
+ // Add length for "&Name1=zzzzzzzzzzzz"\r
+ // |1|Name|1|Value|\r
+ //\r
+ Length += (1 + StrLen (BlockData->Name) + 1 + BlockData->Width * 2);\r
+ } else {\r
+ //\r
+ // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"\r
+ // | 8 | 4 | 7 | 4 | 7 | Width * 2 |\r
+ //\r
+ Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);\r
+ }\r
+ DataExist = TRUE;\r
+ }\r
+ }\r
+ }\r
+ \r
+ //\r
+ // No default value is found. The default string doesn't exist.\r
+ //\r
+ if (!DataExist) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Allocate buffer for the entire <DefaultAltCfgResp>\r
+ //\r
+ *DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
+ if (*DefaultAltCfgResp == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ StringPtr = *DefaultAltCfgResp;\r
+\r
+ //\r
+ // Start with <ConfigHdr>\r
+ //\r
+ StrCpy (StringPtr, ConfigHdr);\r
+ StringPtr += StrLen (StringPtr);\r
+\r
+ for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+ DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+ //\r
+ // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"\r
+ // |1| StrLen (ConfigHdr) | 8 | 4 |\r
+ //\r
+ UnicodeSPrint (\r
+ StringPtr, \r
+ (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
+ L"&%s&ALTCFG=%04X", \r
+ ConfigHdr, \r
+ DefaultId->DefaultId\r
+ );\r
+ StringPtr += StrLen (StringPtr);\r
+\r
+ for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+ BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+ ListEntry = &BlockData->DefaultValueEntry;\r
+ for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+ DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+ if (DefaultValueData->DefaultId != DefaultId->DefaultId) {\r
+ continue;\r
+ }\r
+ if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+ UnicodeSPrint (\r
+ StringPtr, \r
+ (1 + StrLen (ConfigHdr) + 1) * sizeof (CHAR16), \r
+ L"&%s=", \r
+ BlockData->Name\r
+ );\r
+ StringPtr += StrLen (StringPtr);\r
+ } else {\r
+ //\r
+ // Add <BlockConfig>\r
+ // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
+ //\r
+ UnicodeSPrint (\r
+ StringPtr, \r
+ (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),\r
+ L"&OFFSET=%04X&WIDTH=%04X&VALUE=", \r
+ BlockData->Offset, \r
+ BlockData->Width\r
+ );\r
+ StringPtr += StrLen (StringPtr);\r
+ }\r
+ Width = BlockData->Width;\r
+ //\r
+ // Convert Value to a hex string in "%x" format\r
+ // NOTE: This is in the opposite byte that GUID and PATH use\r
+ //\r
+ TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
+ for (; Width > 0; Width--) {\r
+ StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ HiiToLower (*DefaultAltCfgResp);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function gets the full request string and full default value string by \r
+ parsing IFR data in HII form packages. \r
+ \r
+ When Request points to NULL string, the request string and default value string \r
+ for each varstore in form package will return. \r
+\r
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.\r
+ @param DevicePath Device Path which Hii Config Access Protocol is registered.\r
+ @param Request Pointer to a null-terminated Unicode string in\r
+ <ConfigRequest> format. When it doesn't contain\r
+ any RequestElement, it will be updated to return \r
+ the full RequestElement retrieved from IFR data.\r
+ If it points to NULL, the request string for the first\r
+ varstore in form package will be merged into a\r
+ <MultiConfigRequest> format string and return. \r
+ @param AltCfgResp Pointer to a null-terminated Unicode string in\r
+ <ConfigAltResp> format. When the pointer is to NULL,\r
+ the full default value string retrieved from IFR data\r
+ will return. When the pinter is to a string, the\r
+ full default value string retrieved from IFR data\r
+ will be merged into the input string and return.\r
+ When Request points to NULL, the default value string \r
+ for each varstore in form package will be merged into \r
+ a <MultiConfigAltResp> format string and return.\r
+ @param PointerProgress Optional parameter, it can be be NULL. \r
+ When it is not NULL, if Request is NULL, it returns NULL. \r
+ On return, points to a character in the Request\r
+ string. Points to the string's null terminator if\r
+ request was successful. Points to the most recent\r
+ & before the first failing name / value pair (or\r
the beginning of the string if the failure is in\r
the first name / value pair) if the request was\r
not successful.\r
UINTN PackageSize;\r
IFR_BLOCK_DATA *RequestBlockArray;\r
IFR_BLOCK_DATA *BlockData;\r
- IFR_BLOCK_DATA *NextBlockData;\r
IFR_DEFAULT_DATA *DefaultValueData;\r
IFR_DEFAULT_DATA *DefaultId;\r
IFR_DEFAULT_DATA *DefaultIdArray;\r
IFR_VARSTORAGE_DATA *VarStorageData;\r
EFI_STRING DefaultAltCfgResp;\r
- EFI_STRING FullConfigRequest;\r
EFI_STRING ConfigHdr;\r
- EFI_STRING GuidStr;\r
- EFI_STRING NameStr;\r
- EFI_STRING PathStr;\r
EFI_STRING StringPtr;\r
EFI_STRING Progress;\r
- UINTN Length;\r
- UINT8 *TmpBuffer;\r
- UINT16 Offset;\r
- UINT16 Width;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *LinkData;\r
- LIST_ENTRY *LinkDefault;\r
BOOLEAN DataExist;\r
\r
if (DataBaseRecord == NULL || DevicePath == NULL || Request == NULL || AltCfgResp == NULL) {\r
DefaultIdArray = NULL;\r
VarStorageData = NULL;\r
DefaultAltCfgResp = NULL;\r
- FullConfigRequest = NULL;\r
ConfigHdr = NULL;\r
- GuidStr = NULL;\r
- NameStr = NULL;\r
- PathStr = NULL;\r
HiiFormPackage = NULL;\r
PackageSize = 0;\r
DataExist = FALSE;\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
- StringPtr += StrLen (L"&PATH=");\r
- while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
- StringPtr ++;\r
- }\r
- //\r
- // Check the following string &OFFSET=\r
- //\r
- if (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
- Progress = StringPtr;\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- } else if (*StringPtr == L'\0') {\r
- //\r
- // No request block is found.\r
- //\r
- StringPtr = NULL;\r
- }\r
- }\r
- if (StringPtr != NULL) {\r
- //\r
- // Init RequestBlockArray\r
- //\r
- RequestBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
- if (RequestBlockArray == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\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
- 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
- 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
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\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
- 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
- Status = EFI_INVALID_PARAMETER;\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
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\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
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- StringPtr += Length;\r
- if (*StringPtr != 0 && *StringPtr != L'&') {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
- }\r
- //\r
- // If '\0', parsing is finished. \r
- //\r
- if (*StringPtr == 0) {\r
- break;\r
- }\r
- }\r
- \r
- //\r
- // Merge the requested block data.\r
- //\r
- Link = RequestBlockArray->Entry.ForwardLink;\r
- while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {\r
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
- NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
- if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
- if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
- BlockData->Width = (UINT16) (NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);\r
- }\r
- RemoveEntryList (Link->ForwardLink);\r
- FreePool (NextBlockData);\r
- continue;\r
- }\r
- Link = Link->ForwardLink; \r
- }\r
- }\r
- \r
- //\r
- // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
- //\r
-\r
- //\r
- // Initialize DefaultIdArray to store the map between DeaultId and DefaultName\r
- //\r
- DefaultIdArray = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
- if (DefaultIdArray == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- InitializeListHead (&DefaultIdArray->Entry);\r
-\r
- //\r
- // Initialize VarStorageData to store the var store Block and Default value information.\r
- //\r
- VarStorageData = (IFR_VARSTORAGE_DATA *) AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));\r
- if (VarStorageData == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
- InitializeListHead (&VarStorageData->Entry);\r
- InitializeListHead (&VarStorageData->BlockEntry);\r
-\r
- //\r
- // Parse the opcode in form pacakge to get the default setting.\r
- //\r
- Status = ParseIfrData (HiiFormPackage, (UINT32) PackageSize, *Request, RequestBlockArray, VarStorageData, DefaultIdArray);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- \r
- //\r
- // No requested varstore in IFR data and directly return\r
- //\r
- if (VarStorageData->Size == 0) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
-\r
- //\r
- // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.\r
- //\r
-\r
- //\r
- // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle\r
- //\r
- GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &VarStorageData->Guid, 1, &GuidStr);\r
- GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *) VarStorageData->Name, 2, &NameStr);\r
- GenerateSubStr (\r
- L"PATH=",\r
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath),\r
- (VOID *) DevicePath,\r
- 1,\r
- &PathStr\r
- );\r
- Length = StrLen (GuidStr);\r
- Length = Length + StrLen (NameStr);\r
- Length = Length + StrLen (PathStr) + 1;\r
- ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));\r
- if (ConfigHdr == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done; \r
- }\r
- StrCpy (ConfigHdr, GuidStr);\r
- StrCat (ConfigHdr, NameStr);\r
- StrCat (ConfigHdr, PathStr);\r
-\r
- //\r
- // Remove the last character L'&'\r
- //\r
- *(ConfigHdr + StrLen (ConfigHdr) - 1) = L'\0';\r
-\r
- if (RequestBlockArray == NULL) {\r
- //\r
- // Append VarStorageData BlockEntry into *Request string\r
- // Now support only one varstore in a form package.\r
- //\r
-\r
- //\r
- // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package\r
- // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig\r
- //\r
-\r
- //\r
- // Compute the length of the entire request starting with <ConfigHdr> and a \r
- // Null-terminator\r
- //\r
- DataExist = FALSE;\r
- Length = StrLen (ConfigHdr) + 1;\r
-\r
- for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
- //\r
- // Add <BlockName> length for each Offset/Width pair\r
- //\r
- // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
- // | 8 | 4 | 7 | 4 |\r
- //\r
- DataExist = TRUE;\r
- Length = Length + (8 + 4 + 7 + 4);\r
- }\r
- \r
- //\r
- // No any request block data is found. The request string can't be constructed.\r
- //\r
- if (!DataExist) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Allocate buffer for the entire <ConfigRequest>\r
- //\r
- FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));\r
- if (FullConfigRequest == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
+ StringPtr += StrLen (L"&PATH=");\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr ++;\r
}\r
- StringPtr = FullConfigRequest;\r
- \r
- //\r
- // Start with <ConfigHdr>\r
- //\r
- StrCpy (StringPtr, ConfigHdr);\r
- StringPtr += StrLen (StringPtr);\r
\r
- //\r
- // Loop through all the Offset/Width pairs and append them to ConfigRequest\r
- //\r
- for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
- BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ if (*StringPtr == L'\0') {\r
//\r
- // Append &OFFSET=XXXX&WIDTH=YYYY\0\r
+ // No request block is found.\r
//\r
- UnicodeSPrint (\r
- StringPtr, \r
- (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16), \r
- L"&OFFSET=%04X&WIDTH=%04X", \r
- BlockData->Offset, \r
- BlockData->Width\r
- );\r
- StringPtr += StrLen (StringPtr);\r
- }\r
- //\r
- // Set to the got full request string.\r
- //\r
- HiiToLower (FullConfigRequest);\r
- if (*Request != NULL) {\r
- FreePool (*Request);\r
+ StringPtr = NULL;\r
}\r
- *Request = FullConfigRequest;\r
}\r
- \r
- //\r
- // 4. Construct Default Value string in AltResp according to request element.\r
- // Go through all VarStorageData Entry and get the DefaultId array for each one\r
- // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody\r
- //\r
- DataExist = FALSE;\r
+\r
//\r
- // Add length for <ConfigHdr> + '\0'\r
+ // If StringPtr != NULL, get the request elements.\r
//\r
- Length = StrLen (ConfigHdr) + 1;\r
- \r
- for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
- DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
- //\r
- // Add length for "&<ConfigHdr>&ALTCFG=XXXX"\r
- // |1| StrLen (ConfigHdr) | 8 | 4 |\r
- //\r
- Length += (1 + StrLen (ConfigHdr) + 8 + 4);\r
- \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; LinkDefault = LinkDefault->ForwardLink) {\r
- DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
- if (DefaultValueData->DefaultId == DefaultId->DefaultId) {\r
- //\r
- // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"\r
- // | 8 | 4 | 7 | 4 | 7 | Width * 2 |\r
- //\r
- Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);\r
- DataExist = TRUE;\r
- }\r
- }\r
+ if (StringPtr != NULL) {\r
+ if (StrStr (StringPtr, L"&OFFSET=") != NULL) {\r
+ RequestBlockArray = GetBlockElement(StringPtr, &Progress);\r
+ } else {\r
+ RequestBlockArray = GetNameElement(StringPtr, &Progress);\r
+ }\r
+\r
+ if (RequestBlockArray == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
}\r
}\r
- \r
+\r
//\r
- // No default value is found. The default string doesn't exist.\r
+ // Initialize DefaultIdArray to store the map between DeaultId and DefaultName\r
//\r
- if (!DataExist) {\r
- Status = EFI_SUCCESS;\r
+ DefaultIdArray = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+ if (DefaultIdArray == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
+ InitializeListHead (&DefaultIdArray->Entry);\r
\r
//\r
- // Allocate buffer for the entire <DefaultAltCfgResp>\r
+ // Initialize VarStorageData to store the var store Block and Default value information.\r
//\r
- DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
- if (DefaultAltCfgResp == NULL) {\r
+ VarStorageData = (IFR_VARSTORAGE_DATA *) AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));\r
+ if (VarStorageData == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
- StringPtr = DefaultAltCfgResp;\r
+ InitializeListHead (&VarStorageData->Entry);\r
+ InitializeListHead (&VarStorageData->BlockEntry);\r
\r
//\r
- // Start with <ConfigHdr>\r
+ // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
//\r
- StrCpy (StringPtr, ConfigHdr);\r
- StringPtr += StrLen (StringPtr);\r
\r
- for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
- DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
- //\r
- // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"\r
- // |1| StrLen (ConfigHdr) | 8 | 4 |\r
- //\r
- UnicodeSPrint (\r
- StringPtr, \r
- (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
- L"&%s&ALTCFG=%04X", \r
- ConfigHdr, \r
- DefaultId->DefaultId\r
- );\r
- StringPtr += StrLen (StringPtr);\r
- \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; LinkDefault = LinkDefault->ForwardLink) {\r
- DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
- if (DefaultValueData->DefaultId == DefaultId->DefaultId) {\r
- //\r
- // Add <BlockConfig>\r
- // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
- //\r
- UnicodeSPrint (\r
- StringPtr, \r
- (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),\r
- L"&OFFSET=%04X&WIDTH=%04X&VALUE=", \r
- BlockData->Offset, \r
- BlockData->Width\r
- );\r
- StringPtr += StrLen (StringPtr);\r
+ //\r
+ // Parse the opcode in form pacakge to get the default setting.\r
+ //\r
+ Status = ParseIfrData (DataBaseRecord->Handle,\r
+ HiiFormPackage,\r
+ (UINT32) PackageSize,\r
+ *Request,\r
+ RequestBlockArray,\r
+ VarStorageData,\r
+ DefaultIdArray);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
- //\r
- // Convert Value to a hex string in "%x" format\r
- // NOTE: This is in the opposite byte that GUID and PATH use\r
- //\r
- Width = BlockData->Width;\r
- TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
- for (; Width > 0; Width--) {\r
- StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
- }\r
- }\r
- }\r
+ //\r
+ // No requested varstore in IFR data and directly return\r
+ //\r
+ if (VarStorageData->VarStoreId == 0) {\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.\r
+ //\r
+ Status = GenerateHdr (VarStorageData, DevicePath, &ConfigHdr);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ if (RequestBlockArray == NULL) {\r
+ if (!GenerateConfigRequest(ConfigHdr, VarStorageData, &Status, Request)) {\r
+ goto Done;\r
}\r
}\r
- HiiToLower (DefaultAltCfgResp);\r
+\r
+ //\r
+ // 4. Construct Default Value string in AltResp according to request element.\r
+ // Go through all VarStorageData Entry and get the DefaultId array for each one\r
+ // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody\r
+ //\r
+ Status = GenerateAltConfigResp (ConfigHdr, VarStorageData, DefaultIdArray, &DefaultAltCfgResp);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
//\r
// 5. Merge string into the input AltCfgResp if the iput *AltCfgResp is not NULL.\r
while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
RemoveEntryList (&BlockData->Entry);\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
FreePool (BlockData);\r
}\r
\r
FreePool (RequestBlockArray);\r
}\r
- \r
+\r
if (VarStorageData != NULL) {\r
//\r
// Free link array VarStorageData\r
while (!IsListEmpty (&VarStorageData->BlockEntry)) {\r
BlockData = BASE_CR (VarStorageData->BlockEntry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
RemoveEntryList (&BlockData->Entry);\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
//\r
// Free default value link array\r
//\r
}\r
FreePool (DefaultIdArray);\r
}\r
- \r
+\r
//\r
// Free the allocated string \r
//\r
- if (GuidStr != NULL) {\r
- FreePool (GuidStr);\r
- }\r
- if (NameStr != NULL) {\r
- FreePool (NameStr);\r
- }\r
- if (PathStr != NULL) {\r
- FreePool (PathStr);\r
- }\r
if (ConfigHdr != NULL) {\r
FreePool (ConfigHdr);\r
}\r
if (*Request == NULL) {\r
*PointerProgress = NULL;\r
} else if (EFI_ERROR (Status)) {\r
- *PointerProgress = Progress;\r
+ *PointerProgress = *Request;\r
} else {\r
*PointerProgress = *Request + StrLen (*Request);\r
}\r
return Status;\r
}\r
\r
+/**\r
+ Validate the config request elements.\r
+\r
+ @param ConfigElements A null-terminated Unicode string in <ConfigRequest> format, \r
+ without configHdr field.\r
+\r
+ @retval CHAR16 * THE first Name/value pair not correct.\r
+ @retval NULL Success parse the name/value pair\r
+**/\r
+CHAR16 *\r
+OffsetWidthValidate (\r
+ CHAR16 *ConfigElements\r
+ )\r
+{\r
+ CHAR16 *StringPtr;\r
+ CHAR16 *RetVal;\r
+\r
+ StringPtr = ConfigElements;\r
+\r
+ while (1) {\r
+ RetVal = StringPtr;\r
+ if (StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+ return RetVal;\r
+ }\r
+\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\r
+ return RetVal;\r
+ }\r
+\r
+ StringPtr += StrLen (L"&WIDTH=");\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+ StringPtr ++;\r
+ }\r
+\r
+ if (*StringPtr == L'\0') {\r
+ return NULL;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Validate the config request elements.\r
+\r
+ @param ConfigElements A null-terminated Unicode string in <ConfigRequest> format, \r
+ without configHdr field.\r
+\r
+ @retval CHAR16 * THE first Name/value pair not correct.\r
+ @retval NULL Success parse the name/value pair\r
+\r
+**/\r
+CHAR16 *\r
+NameValueValidate (\r
+ CHAR16 *ConfigElements\r
+ )\r
+{\r
+ CHAR16 *StringPtr;\r
+ CHAR16 *RetVal;\r
+\r
+ StringPtr = ConfigElements;\r
+\r
+ while (1) {\r
+ RetVal = StringPtr;\r
+ if (*StringPtr != L'&') {\r
+ return RetVal;\r
+ }\r
+ StringPtr += 1;\r
+\r
+ StringPtr = StrStr (StringPtr, L"&");\r
+ \r
+ if (StringPtr == NULL) {\r
+ return NULL;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Validate the config request string.\r
+\r
+ @param ConfigRequest A null-terminated Unicode string in <ConfigRequest> format.\r
+\r
+ @retval CHAR16 * THE first element not correct.\r
+ @retval NULL Success parse the name/value pair\r
+\r
+**/\r
+CHAR16 *\r
+ConfigRequestValidate (\r
+ CHAR16 *ConfigRequest\r
+ )\r
+{\r
+ BOOLEAN HasNameField;\r
+ CHAR16 *StringPtr;\r
+\r
+ HasNameField = TRUE;\r
+ StringPtr = ConfigRequest;\r
+\r
+ //\r
+ // Check <ConfigHdr>\r
+ //\r
+ if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+ return ConfigRequest;\r
+ }\r
+ StringPtr += StrLen (L"GUID=");\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\r
+ return ConfigRequest;\r
+ }\r
+ StringPtr += StrLen (L"&NAME=");\r
+ if (*StringPtr == L'&') {\r
+ HasNameField = FALSE;\r
+ }\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\r
+ return ConfigRequest;\r
+ }\r
+ StringPtr += StrLen (L"&PATH=");\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr ++;\r
+ }\r
+\r
+ if (*StringPtr == L'\0') {\r
+ return NULL;\r
+ }\r
+\r
+ if (HasNameField) {\r
+ //\r
+ // Should be Buffer varstore, config request should be "OFFSET/Width" pairs.\r
+ //\r
+ return OffsetWidthValidate(StringPtr);\r
+ } else {\r
+ //\r
+ // Should be Name/Value varstore, config request should be "&name1&name2..." pairs.\r
+ //\r
+ return NameValueValidate(StringPtr);\r
+ }\r
+}\r
+\r
/**\r
This function allows a caller to extract the current configuration\r
for one or more named elements from one or more drivers.\r
BOOLEAN FirstElement;\r
BOOLEAN IfrDataParsedFlag;\r
BOOLEAN IsEfiVarStore;\r
- EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo; \r
+ EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;\r
+ EFI_STRING ErrorPtr;\r
\r
if (This == NULL || Progress == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
}\r
- \r
+\r
+ //\r
+ // Validate ConfigRequest String.\r
+ //\r
+ ErrorPtr = ConfigRequestValidate(ConfigRequest);\r
+ if (ErrorPtr != NULL) {\r
+ *Progress = StrStr (StringPtr, ErrorPtr);\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
//\r
- // Check whether ConfigRequest contains request string OFFSET/WIDTH\r
+ // Check whether ConfigRequest contains request string.\r
//\r
IfrDataParsedFlag = FALSE;\r
- if ((HiiHandle != NULL) && (StrStr (ConfigRequest, L"&OFFSET=") == NULL)) {\r
+ if ((HiiHandle != NULL) && !GetElementsFromRequest(ConfigRequest)) {\r
//\r
// Get the full request string from IFR when HiiPackage is registered to HiiHandle \r
//\r
// AccessProgress indicates the parsing progress on <ConfigRequest>.\r
// Map it to the progress on <MultiConfigRequest> then return it.\r
//\r
+ ASSERT (AccessProgress != NULL);\r
*Progress = StrStr (StringPtr, AccessProgress);\r
goto Done;\r
}\r
//\r
// Not any request block is found.\r
//\r
- if (StrStr (ConfigRequest, L"&OFFSET=") == NULL) {\r
+ if (!GetElementsFromRequest(ConfigRequest)) {\r
AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
goto NextConfigString;\r
}\r
// Call the GetVariable function to extract settings.\r
//\r
Status = GetConfigRespFromEfiVarStore(This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);\r
- FreePool (EfiVarStoreInfo); \r
+ FreePool (EfiVarStoreInfo);\r
} else {\r
//\r
// Call corresponding ConfigAccess protocol to extract settings\r
DefaultResults = NULL;\r
}\r
\r
-NextConfigString: \r
+NextConfigString:\r
if (!FirstElement) {\r
Status = AppendToMultiString (Results, L"&");\r
ASSERT_EFI_ERROR (Status);\r
if (StringPtr != NULL) {\r
*StringPtr = 0;\r
}\r
- if (StrStr (AccessResults, L"&OFFSET=") != NULL) {\r
+ if (GetElementsFromRequest (AccessResults)) {\r
Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);\r
ASSERT_EFI_ERROR (Status);\r
}\r