+ EFI_STRING TmpPtr;\r
+ UINTN Length;\r
+ EFI_STRING Str;\r
+ UINT8 *Buf;\r
+ EFI_STATUS Status;\r
+ UINT8 DigitUint8;\r
+ UINTN Index;\r
+ CHAR16 TemStr[2];\r
+\r
+ if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Buf = NULL;\r
+\r
+ TmpPtr = StringPtr;\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr++;\r
+ }\r
+ *Len = StringPtr - TmpPtr;\r
+ Length = *Len + 1;\r
+\r
+ Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));\r
+ if (Str == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));\r
+ *(Str + *Len) = L'\0';\r
+\r
+ Length = (Length + 1) / 2;\r
+ Buf = (UINT8 *) AllocateZeroPool (Length);\r
+ if (Buf == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ \r
+ Length = *Len;\r
+ ZeroMem (TemStr, sizeof (TemStr));\r
+ for (Index = 0; Index < Length; Index ++) {\r
+ TemStr[0] = Str[Length - Index - 1];\r
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
+ if ((Index & 1) == 0) {\r
+ Buf [Index/2] = DigitUint8;\r
+ } else {\r
+ Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]);\r
+ }\r
+ }\r
+\r
+ *Number = Buf;\r
+ Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+ if (Str != NULL) {\r
+ FreePool (Str);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function merges DefaultAltCfgResp string into AltCfgResp string for\r
+ the missing AltCfgId in AltCfgResq.\r
+\r
+ @param AltCfgResp Pointer to a null-terminated Unicode string in\r
+ <ConfigAltResp> format. The default value string \r
+ will be merged into it. \r
+ @param DefaultAltCfgResp Pointer to a null-terminated Unicode string in\r
+ <MultiConfigAltResp> format. The default value \r
+ string may contain more than one ConfigAltResp\r
+ string for the different varstore buffer.\r
+\r
+ @retval EFI_SUCCESS The merged string returns.\r
+ @retval EFI_INVALID_PARAMETER *AltCfgResp is to NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MergeDefaultString (\r
+ IN OUT EFI_STRING *AltCfgResp,\r
+ IN EFI_STRING DefaultAltCfgResp\r
+ )\r
+{\r
+ EFI_STRING StringPtrDefault;\r
+ EFI_STRING StringPtrEnd;\r
+ CHAR16 TempChar;\r
+ EFI_STRING StringPtr;\r
+ EFI_STRING AltConfigHdr;\r
+ UINTN HeaderLength;\r
+ UINTN SizeAltCfgResp;\r
+ \r
+ if (*AltCfgResp == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ //\r
+ // Get the requestr ConfigHdr\r
+ //\r
+ SizeAltCfgResp = 0;\r
+ StringPtr = *AltCfgResp;\r
+ \r
+ //\r
+ // Find <ConfigHdr> GUID=...&NAME=...&PATH=...\r
+ //\r
+ if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ StringPtr += StrLen (L"&PATH=");\r
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+ StringPtr ++;\r
+ }\r
+ HeaderLength = StringPtr - *AltCfgResp;\r
+\r
+ //\r
+ // Construct AltConfigHdr string "&<ConfigHdr>&ALTCFG=XXXX\0"\r
+ // |1| StrLen (ConfigHdr) | 8 | 4 | 1 |\r
+ //\r
+ AltConfigHdr = AllocateZeroPool ((1 + HeaderLength + 8 + 4 + 1) * sizeof (CHAR16));\r
+ if (AltConfigHdr == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ StrCpy (AltConfigHdr, L"&");\r
+ StrnCat (AltConfigHdr, *AltCfgResp, HeaderLength);\r
+ StrCat (AltConfigHdr, L"&ALTCFG=");\r
+ HeaderLength = StrLen (AltConfigHdr);\r
+ \r
+ StringPtrDefault = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+ while (StringPtrDefault != NULL) {\r
+ //\r
+ // Get AltCfg Name\r
+ //\r
+ StrnCat (AltConfigHdr, StringPtrDefault + HeaderLength, 4);\r
+ StringPtr = StrStr (*AltCfgResp, AltConfigHdr); \r
+ \r
+ //\r
+ // Append the found default value string to the input AltCfgResp\r
+ // \r
+ if (StringPtr == NULL) {\r
+ StringPtrEnd = StrStr (StringPtrDefault + 1, L"&GUID");\r
+ SizeAltCfgResp = StrSize (*AltCfgResp);\r
+ if (StringPtrEnd == NULL) {\r
+ //\r
+ // No more default string is found.\r
+ //\r
+ *AltCfgResp = (EFI_STRING) ReallocatePool (\r
+ SizeAltCfgResp,\r
+ SizeAltCfgResp + StrSize (StringPtrDefault),\r
+ (VOID *) (*AltCfgResp)\r
+ );\r
+ if (*AltCfgResp == NULL) {\r
+ FreePool (AltConfigHdr);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ StrCat (*AltCfgResp, StringPtrDefault);\r
+ break;\r
+ } else {\r
+ TempChar = *StringPtrEnd;\r
+ *StringPtrEnd = L'\0';\r
+ *AltCfgResp = (EFI_STRING) ReallocatePool (\r
+ SizeAltCfgResp,\r
+ SizeAltCfgResp + StrSize (StringPtrDefault),\r
+ (VOID *) (*AltCfgResp)\r
+ );\r
+ if (*AltCfgResp == NULL) {\r
+ FreePool (AltConfigHdr);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ StrCat (*AltCfgResp, StringPtrDefault);\r
+ *StringPtrEnd = TempChar;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Find next AltCfg String\r
+ //\r
+ *(AltConfigHdr + HeaderLength) = L'\0';\r
+ StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);\r
+ }\r
+ \r
+ FreePool (AltConfigHdr);\r
+ return EFI_SUCCESS; \r
+}\r
+\r
+/**\r
+ This function inserts new DefaultValueData into the BlockData DefaultValue array.\r
+\r
+ @param BlockData The BlockData is updated to add new default value.\r
+ @param DefaultValueData The DefaultValue is added.\r
+\r
+**/\r
+VOID\r
+InsertDefaultValue (\r
+ IN IFR_BLOCK_DATA *BlockData,\r
+ IN IFR_DEFAULT_DATA *DefaultValueData\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ IFR_DEFAULT_DATA *DefaultValueArray; \r
+ LIST_ENTRY *DefaultLink;\r
+ \r
+ DefaultLink = &BlockData->DefaultValueEntry;\r
+\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
+ // DEFAULT_VALUE_FROM_OPCODE has high priority, DEFAULT_VALUE_FROM_DEFAULT has low priority.\r
+ //\r
+ if (DefaultValueData->Type > DefaultValueArray->Type) {\r
+ //\r
+ // Update the default value array in BlockData.\r
+ //\r
+ CopyMem (&DefaultValueArray->Value, &DefaultValueData->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+ DefaultValueArray->Type = DefaultValueData->Type;\r
+ DefaultValueArray->Cleaned = DefaultValueData->Cleaned;\r
+ }\r
+ return;\r
+ } \r
+ }\r
+\r
+ //\r
+ // Insert new default value data in tail.\r
+ //\r
+ DefaultValueArray = AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+ ASSERT (DefaultValueArray != NULL);\r
+ CopyMem (DefaultValueArray, DefaultValueData, sizeof (IFR_DEFAULT_DATA));\r
+ InsertTailList (Link, &DefaultValueArray->Entry);\r
+}\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
+ \r
+**/\r
+VOID\r
+InsertBlockData (\r
+ IN LIST_ENTRY *BlockLink,\r
+ IN IFR_BLOCK_DATA **BlockData\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ IFR_BLOCK_DATA *BlockArray;\r
+ IFR_BLOCK_DATA *BlockSingleData;\r
+\r
+ BlockSingleData = *BlockData;\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
+ for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {\r
+ BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+ if (BlockArray->Offset == BlockSingleData->Offset) {\r
+ if (BlockArray->Width > BlockSingleData->Width) {\r
+ //\r
+ // Insert this block data in the front of block array\r
+ //\r
+ InsertTailList (Link, &BlockSingleData->Entry);\r
+ return;\r
+ }\r
+\r
+ if (BlockArray->Width == BlockSingleData->Width) {\r
+ //\r
+ // The same block array has been added.\r
+ //\r
+ if (BlockSingleData != BlockArray) {\r
+ FreePool (BlockSingleData);\r
+ *BlockData = BlockArray;\r
+ }\r
+ return;\r
+ }\r
+ } else if (BlockArray->Offset > BlockSingleData->Offset) {\r
+ //\r
+ // Insert new block data in the front of block array \r
+ //\r
+ InsertTailList (Link, &BlockSingleData->Entry);\r
+ return;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Add new block data into the tail.\r
+ //\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
+ This function checks VarOffset and VarWidth is in the block range.\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
+**/\r
+BOOLEAN\r
+BlockArrayCheck (\r
+ IN IFR_BLOCK_DATA *RequestBlockArray,\r
+ IN UINT16 VarOffset,\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
+ 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
+ // 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
+\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
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Get form package data from data base.\r
+\r
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.\r
+ @param HiiFormPackage The buffer saves the package data.\r
+ @param PackageSize The buffer size of the package data.\r
+\r
+**/\r
+EFI_STATUS\r
+GetFormPackageData (\r
+ IN HII_DATABASE_RECORD *DataBaseRecord,\r
+ IN OUT UINT8 **HiiFormPackage,\r
+ OUT UINTN *PackageSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+ UINTN ResultSize;\r
+\r
+ if (DataBaseRecord == NULL || HiiFormPackage == NULL || PackageSize == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Size = 0;\r
+ ResultSize = 0;\r
+ //\r
+ // 0. Get Hii Form Package by HiiHandle\r
+ //\r
+ Status = ExportFormPackages (\r
+ &mPrivate, \r
+ DataBaseRecord->Handle, \r
+ DataBaseRecord->PackageList, \r
+ 0, \r
+ Size, \r
+ HiiFormPackage,\r
+ &ResultSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ (*HiiFormPackage) = AllocatePool (ResultSize);\r
+ if (*HiiFormPackage == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get HiiFormPackage by HiiHandle\r
+ //\r
+ Size = ResultSize;\r
+ ResultSize = 0;\r
+ Status = ExportFormPackages (\r
+ &mPrivate, \r
+ DataBaseRecord->Handle, \r
+ DataBaseRecord->PackageList, \r
+ 0,\r
+ Size, \r
+ *HiiFormPackage,\r
+ &ResultSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (*HiiFormPackage);\r
+ }\r
+ \r
+ *PackageSize = Size;\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ This function parses Form Package to get the efi varstore info according to the request ConfigHdr.\r
+\r
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.\r
+ @param ConfigHdr Request string ConfigHdr. If it is NULL,\r
+ the first found varstore will be as ConfigHdr.\r
+ @param IsEfiVarstore Whether the request storage type is efi varstore type.\r
+ @param EfiVarStore The efi varstore info which will return.\r
+**/ \r
+EFI_STATUS\r
+GetVarStoreType (\r
+ IN HII_DATABASE_RECORD *DataBaseRecord,\r
+ IN EFI_STRING ConfigHdr,\r
+ OUT BOOLEAN *IsEfiVarstore,\r
+ OUT EFI_IFR_VARSTORE_EFI **EfiVarStore\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN IfrOffset;\r
+ UINTN PackageOffset;\r
+ EFI_IFR_OP_HEADER *IfrOpHdr;\r
+ CHAR16 *VarStoreName;\r
+ EFI_STRING GuidStr;\r
+ EFI_STRING NameStr;\r
+ EFI_STRING TempStr;\r
+ UINTN LengthString; \r
+ UINT8 *HiiFormPackage;\r
+ UINTN PackageSize;\r
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;\r
+ EFI_HII_PACKAGE_HEADER *PackageHeader;\r
+ \r
+ HiiFormPackage = NULL;\r
+ LengthString = 0;\r
+ Status = EFI_SUCCESS;\r
+ GuidStr = NULL;\r
+ NameStr = NULL;\r
+ TempStr = NULL;\r
+ *IsEfiVarstore = FALSE;\r
+\r
+ Status = GetFormPackageData(DataBaseRecord, &HiiFormPackage, &PackageSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ PackageOffset = IfrOffset;\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiFormPackage;\r
+\r
+ while (IfrOffset < PackageSize) {\r
+ //\r
+ // More than one form packages exist.\r
+ //\r
+ if (PackageOffset >= PackageHeader->Length) {\r
+ //\r
+ // Process the new form package.\r
+ //\r
+ PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ IfrOffset += PackageOffset;\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiFormPackage + IfrOffset);\r
+ }\r
+\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (HiiFormPackage + IfrOffset);\r
+ IfrOffset += IfrOpHdr->Length;\r
+ PackageOffset += IfrOpHdr->Length;\r
+\r
+ if (IfrOpHdr->OpCode == EFI_IFR_VARSTORE_EFI_OP ) {\r
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+ //\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 (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+ continue;\r
+ }\r
+\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)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
+\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
+ *EfiVarStore = (EFI_IFR_VARSTORE_EFI *) AllocateZeroPool (IfrOpHdr->Length);\r
+ if (*EfiVarStore == NULL) {\r
+ FreePool (VarStoreName);\r
+ FreePool (GuidStr);\r
+ FreePool (NameStr);\r
+ FreePool (TempStr);\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ *IsEfiVarstore = TRUE;\r
+ CopyMem (*EfiVarStore, IfrEfiVarStore, IfrOpHdr->Length);\r
+ } \r
+ \r
+ //\r
+ // Free alllocated temp string.\r
+ //\r
+ FreePool (VarStoreName);\r
+ FreePool (GuidStr);\r
+ FreePool (NameStr);\r
+ FreePool (TempStr);\r
+\r
+ //\r
+ // Already found the varstore, break;\r
+ //\r
+ if (*IsEfiVarstore) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+Done:\r
+ if (HiiFormPackage != NULL) {\r
+ FreePool (HiiFormPackage);\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
+ 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
+ //\r
+ // If ConfigHdr has name field and varstore not has name, return FALSE.\r
+ //\r
+ if (Name == NULL && StrStr (ConfigHdr, L"NAME=&") == NULL) {\r
+ return FALSE;\r
+ }\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
+ This function parses Form Package to get the efi varstore info according to the request ConfigHdr.\r
+\r
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.\r
+ @param ConfigHdr Request string ConfigHdr. If it is NULL,\r
+ the first found varstore will be as ConfigHdr.\r
+ @retval TRUE This hii package is the reqeust one.\r
+ @retval FALSE This hii package is not the reqeust one.\r
+**/ \r
+BOOLEAN\r
+IsThisPackageList (\r
+ IN HII_DATABASE_RECORD *DataBaseRecord,\r
+ IN EFI_STRING ConfigHdr\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN IfrOffset;\r
+ UINTN PackageOffset;\r
+ EFI_IFR_OP_HEADER *IfrOpHdr;\r
+ CHAR16 *VarStoreName;\r
+ UINT8 *HiiFormPackage;\r
+ UINTN PackageSize;\r
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;\r
+ EFI_HII_PACKAGE_HEADER *PackageHeader;\r
+ EFI_IFR_VARSTORE *IfrVarStore;\r
+ EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;\r
+ BOOLEAN FindVarstore;\r
+\r
+ HiiFormPackage = NULL;\r
+ VarStoreName = NULL;\r
+ Status = EFI_SUCCESS;\r
+ FindVarstore = FALSE;\r
+\r
+ Status = GetFormPackageData(DataBaseRecord, &HiiFormPackage, &PackageSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ PackageOffset = IfrOffset;\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiFormPackage;\r
+\r
+ while (IfrOffset < PackageSize) {\r
+ //\r
+ // More than one form packages exist.\r
+ //\r
+ if (PackageOffset >= PackageHeader->Length) {\r
+ //\r
+ // Process the new form package.\r
+ //\r
+ PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ IfrOffset += PackageOffset;\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiFormPackage + IfrOffset);\r
+ }\r
+\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (HiiFormPackage + IfrOffset);\r
+ IfrOffset += IfrOpHdr->Length;\r
+ PackageOffset += IfrOpHdr->Length;\r
+\r
+ switch (IfrOpHdr->OpCode) {\r
+ \r
+ case EFI_IFR_VARSTORE_OP:\r
+ IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
+\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));\r
+ if (VarStoreName == NULL) {\r
+ goto Done;\r
+ }\r
+ AsciiStrToUnicodeStr ((CHAR8 *)IfrVarStore->Name, VarStoreName);\r
+\r
+ if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+ FindVarstore = TRUE;\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_VARSTORE_EFI_OP:\r
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+ if (VarStoreName == NULL) {\r
+ goto Done;\r
+ }\r
+ AsciiStrToUnicodeStr ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName);\r
+\r
+ if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+ FindVarstore = TRUE;\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
+ IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;\r
+\r
+ if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {\r
+ FindVarstore = TRUE;\r
+ goto Done;\r
+ }\r
+ break;\r
+ \r
+ case EFI_IFR_FORM_OP:\r
+ case EFI_IFR_FORM_MAP_OP:\r
+ //\r
+ // No matched varstore is found and directly return.\r
+ //\r
+ goto Done;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+Done:\r
+ if (HiiFormPackage != NULL) {\r
+ FreePool (HiiFormPackage);\r
+ }\r
+\r
+ if (VarStoreName != NULL) {\r
+ FreePool (VarStoreName);\r
+ }\r
+\r
+ return FindVarstore;\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 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
+ are conflicted. \r
+ @retval EFI_OUT_OF_RESOURCES No enough memory.\r
+**/\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
+ IN IFR_BLOCK_DATA *RequestBlockArray,\r
+ IN OUT IFR_VARSTORAGE_DATA *VarStorageData,\r
+ OUT IFR_DEFAULT_DATA *DefaultIdArray\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN IfrOffset;\r
+ UINTN PackageOffset;\r
+ EFI_IFR_VARSTORE *IfrVarStore;\r
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;\r
+ EFI_IFR_OP_HEADER *IfrOpHdr;\r
+ EFI_IFR_ONE_OF *IfrOneOf;\r
+ EFI_IFR_REF4 *IfrRef;\r
+ EFI_IFR_ONE_OF_OPTION *IfrOneOfOption;\r
+ EFI_IFR_DEFAULT *IfrDefault;\r
+ EFI_IFR_ORDERED_LIST *IfrOrderedList;\r
+ EFI_IFR_CHECKBOX *IfrCheckBox;\r
+ EFI_IFR_PASSWORD *IfrPassword;\r
+ EFI_IFR_STRING *IfrString;\r
+ EFI_IFR_DATE *IfrDate;\r
+ EFI_IFR_TIME *IfrTime;\r
+ IFR_DEFAULT_DATA DefaultData;\r
+ IFR_DEFAULT_DATA *DefaultDataPtr;\r
+ IFR_BLOCK_DATA *BlockData;\r
+ CHAR16 *VarStoreName;\r
+ UINT16 VarWidth;\r
+ UINT16 VarDefaultId;\r
+ BOOLEAN FirstOneOfOption;\r
+ LIST_ENTRY *LinkData;\r
+ LIST_ENTRY *LinkDefault;\r
+ EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;\r
+ EFI_HII_PACKAGE_HEADER *PackageHeader;\r
+ EFI_VARSTORE_ID VarStoreId;\r
+\r
+ Status = EFI_SUCCESS;\r
+ BlockData = NULL;\r
+ DefaultDataPtr = NULL;\r
+ FirstOneOfOption = FALSE;\r
+ VarStoreId = 0;\r
+ ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));\r
+\r
+ //\r
+ // Go through the form package to parse OpCode one by one.\r
+ //\r
+ PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) Package;\r
+ IfrOffset = PackageOffset;\r
+ while (IfrOffset < PackageLength) {\r
+\r
+ //\r
+ // More than one form package found.\r
+ //\r
+ if (PackageOffset >= PackageHeader->Length) {\r
+ //\r
+ // Already found varstore for this request, break;\r
+ //\r
+ if (VarStoreId != 0) {\r
+ VarStoreId = 0;\r
+ }\r
+\r
+ //\r
+ // Get next package header info.\r
+ //\r
+ IfrOffset += sizeof (EFI_HII_PACKAGE_HEADER);\r
+ PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) (Package + IfrOffset);\r
+ }\r
+\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (Package + IfrOffset);\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 (VarStoreId != 0) {\r
+ break;\r
+ }\r
+\r
+ IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
+\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)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
+\r
+ if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+ //\r
+ // Find the matched VarStore\r
+ //\r
+ CopyGuid (&VarStorageData->Guid, (EFI_GUID *) (VOID *) &IfrVarStore->Guid);\r
+ VarStorageData->Size = IfrVarStore->Size;\r
+ VarStorageData->Name = VarStoreName;\r
+ VarStorageData->Type = EFI_HII_VARSTORE_BUFFER;\r
+ VarStoreId = IfrVarStore->VarStoreId;\r
+ }\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 (VarStoreId != 0) {\r
+ break;\r
+ }\r
+\r
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+\r
+ //\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 (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+ break;\r
+ }\r
+\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)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
+\r
+ if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
+ //\r
+ // Find the matched VarStore\r
+ //\r
+ CopyGuid (&VarStorageData->Guid, (EFI_GUID *) (VOID *) &IfrEfiVarStore->Guid);\r
+ VarStorageData->Size = IfrEfiVarStore->Size;\r
+ VarStorageData->Name = VarStoreName;\r
+ VarStorageData->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;\r
+ VarStoreId = IfrEfiVarStore->VarStoreId;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
+ //\r
+ // VarStore is found. Don't need to search any more.\r
+ //\r
+ if (VarStoreId != 0) {\r
+ break;\r
+ }\r
+\r
+ IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;\r
+\r
+ if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {\r
+ //\r
+ // Find the matched VarStore\r
+ //\r
+ CopyGuid (&VarStorageData->Guid, (EFI_GUID *) (VOID *) &IfrNameValueVarStore->Guid);\r
+ VarStorageData->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
+ VarStoreId = IfrNameValueVarStore->VarStoreId;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_DEFAULTSTORE_OP:\r
+ //\r
+ // Add new the map between default id and default name.\r
+ //\r
+ DefaultDataPtr = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+ if (DefaultDataPtr == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ DefaultDataPtr->DefaultId = ((EFI_IFR_DEFAULTSTORE *) IfrOpHdr)->DefaultId;\r
+ InsertTailList (&DefaultIdArray->Entry, &DefaultDataPtr->Entry);\r
+ DefaultDataPtr = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ case EFI_IFR_FORM_MAP_OP:\r
+ //\r
+ // No matched varstore is found and directly return.\r
+ //\r
+ if ( VarStoreId == 0) {\r
+ Status = EFI_SUCCESS;\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_REF_OP:\r
+ //\r
+ // Ref question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if ( VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrRef = (EFI_IFR_REF4 *) IfrOpHdr;\r
+ if (IfrRef->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+ VarWidth = (UINT16) (sizeof (EFI_HII_REF));\r
+\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_NUMERIC_OP:\r
+ //\r
+ // Numeric and OneOf has the same opcode structure.\r
+ //\r
+\r
+ //\r
+ // Numeric and OneOf question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpHdr;\r
+ if (IfrOneOf->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+ VarWidth = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ if (BlockData == NULL) {\r
+ //\r
+ // BlockData == NULL means this opcode is not in the requst array.\r
+ //\r
+ break;\r
+ }\r
+\r
+ if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {\r
+ //\r
+ // Set this flag to TRUE for the first oneof option.\r
+ //\r
+ FirstOneOfOption = TRUE;\r
+ } else if (IfrOpHdr->OpCode == EFI_IFR_NUMERIC_OP) {\r
+ //\r
+ // Numeric minimum value will be used as default value when no default is specified. \r
+ //\r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {\r
+ case EFI_IFR_NUMERIC_SIZE_1:\r
+ DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_2:\r
+ CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_4:\r
+ CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_SIZE_8:\r
+ CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // 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
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ //\r
+ // offset by question header\r
+ // width by EFI_IFR_ORDERED_LIST MaxContainers * OneofOption Type\r
+ // no default value and default id, how to define its default value?\r
+ //\r
+\r
+ //\r
+ // OrderedList question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrOrderedList = (EFI_IFR_ORDERED_LIST *) IfrOpHdr;\r
+ if (IfrOrderedList->Question.VarStoreId != VarStoreId) {\r
+ BlockData = NULL;\r
+ break;\r
+ }\r
+ VarWidth = IfrOrderedList->MaxContainers;\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ //\r
+ // EFI_IFR_DEFAULT_OP\r
+ // offset by question header\r
+ // width is 1 sizeof (BOOLEAN)\r
+ // default id by CheckBox Flags if CheckBox flags (Default or Mau) is set, the default value is 1 to be set.\r
+ // value by DefaultOption\r
+ // default id by DeaultOption DefaultId can override CheckBox Flags and Default value.\r
+ // \r
+\r
+ //\r
+ // CheckBox question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpHdr;\r
+ if (IfrCheckBox->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+ VarWidth = (UINT16) sizeof (BOOLEAN);\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ if (BlockData == NULL) {\r
+ //\r
+ // BlockData == NULL means this opcode is not in the requst array.\r
+ //\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Add default value for standard ID by CheckBox Flag\r
+ //\r
+ VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.DefaultId = VarDefaultId;\r
+ if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {\r
+ //\r
+ // When flag is set, defautl value is TRUE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromFlag;\r
+ DefaultData.Value.b = TRUE;\r
+ } else {\r
+ //\r
+ // When flag is not set, defautl value is FASLE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ DefaultData.Value.b = FALSE;\r
+ }\r
+ //\r
+ // Add DefaultValue into current BlockData\r
+ //\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+ //\r
+ // Add default value for Manufacture ID by CheckBox Flag\r
+ //\r
+ VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.DefaultId = VarDefaultId;\r
+ if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {\r
+ //\r
+ // When flag is set, defautl value is TRUE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromFlag;\r
+ DefaultData.Value.b = TRUE;\r
+ } else {\r
+ //\r
+ // When flag is not set, defautl value is FASLE.\r
+ //\r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ DefaultData.Value.b = FALSE;\r
+ }\r
+ //\r
+ // Add DefaultValue into current BlockData\r
+ //\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ break;\r
+\r
+ case EFI_IFR_DATE_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // Date question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrDate = (EFI_IFR_DATE *) IfrOpHdr;\r
+ if (IfrDate->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ VarWidth = (UINT16) sizeof (EFI_HII_DATE);\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_TIME_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // Time question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrTime = (EFI_IFR_TIME *) IfrOpHdr;\r
+ if (IfrTime->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ VarWidth = (UINT16) sizeof (EFI_HII_TIME);\r
+ Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_STRING_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // String question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrString = (EFI_IFR_STRING *) IfrOpHdr;\r
+ if (IfrString->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ 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
+\r
+ //\r
+ // No default value for string.\r
+ //\r
+ BlockData = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_PASSWORD_OP:\r
+ //\r
+ // offset by question header\r
+ // width MaxSize * sizeof (CHAR16)\r
+ // no default value, only block array\r
+ //\r
+\r
+ //\r
+ // Password question is not in IFR Form. This IFR form is not valid. \r
+ //\r
+ if (VarStoreId == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ //\r
+ // Check whether this question is for the requested varstore.\r
+ //\r
+ IfrPassword = (EFI_IFR_PASSWORD *) IfrOpHdr;\r
+ if (IfrPassword->Question.VarStoreId != VarStoreId) {\r
+ break;\r
+ }\r
+\r
+ 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
+\r
+ //\r
+ // No default value for string.\r
+ //\r
+ BlockData = NULL;\r
+ break;\r
+\r
+ case EFI_IFR_ONE_OF_OPTION_OP:\r
+ //\r
+ // No matched block data is ignored.\r
+ //\r
+ if (BlockData == NULL || BlockData->Scope == 0) {\r
+ break;\r
+ }\r
+\r
+ IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpHdr;\r
+ if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+ //\r
+ // Get ordered list option data type.\r
+ //\r
+ if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_8 || IfrOneOfOption->Type == EFI_IFR_TYPE_BOOLEAN) {\r
+ VarWidth = 1;\r
+ } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_16) {\r
+ VarWidth = 2;\r
+ } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_32) {\r
+ VarWidth = 4;\r
+ } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_64) {\r
+ VarWidth = 8;\r
+ } else {\r
+ //\r
+ // Invalid ordered list option data type.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
+ FreePool (BlockData);\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Calculate Ordered list QuestionId width.\r
+ //\r
+ BlockData->Width = (UINT16) (BlockData->Width * VarWidth);\r
+ //\r
+ // Check whether this question is in requested block array.\r
+ //\r
+ if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, (BOOLEAN)(BlockData->Name != NULL), HiiHandle)) {\r
+ //\r
+ // This question is not in the requested string. Skip it.\r
+ //\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
+ FreePool (BlockData);\r
+ BlockData = NULL;\r
+ break;\r
+ }\r
+ //\r
+ // Check this var question is in the var storage \r
+ //\r
+ if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ if (BlockData->Name != NULL) {\r
+ FreePool (BlockData->Name);\r
+ }\r
+ FreePool (BlockData);\r
+ goto Done;\r
+ }\r
+ //\r
+ // Add Block Data into VarStorageData BlockEntry\r
+ //\r
+ InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+ //\r
+ // No default data for OrderedList.\r
+ //\r
+ BlockData = NULL;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // 1. Set default value for OneOf option when flag field has default attribute.\r
+ //\r
+ if (((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) ||\r
+ ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG)) {\r
+ //\r
+ // This flag is used to specify whether this option is the first. Set it to FALSE for the following options. \r
+ // The first oneof option value will be used as default value when no default value is specified. \r
+ //\r
+ FirstOneOfOption = FALSE;\r
+ \r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.Type = DefaultValueFromFlag;\r
+ CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+ if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {\r
+ DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ } \r
+ if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {\r
+ DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+\r
+ //\r
+ // 2. Set as the default value when this is the first option.\r
+ // The first oneof option value will be used as default value when no default value is specified. \r
+ //\r
+ if (FirstOneOfOption) {\r
+ // This flag is used to specify whether this option is the first. Set it to FALSE for the following options. \r
+ FirstOneOfOption = FALSE;\r
+ \r
+ //\r
+ // Prepare new DefaultValue\r
+ // \r
+ DefaultData.Type = DefaultValueFromDefault;\r
+ CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
+ for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+ DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry); \r
+ DefaultData.DefaultId = DefaultDataPtr->DefaultId;\r
+ InsertDefaultValue (BlockData, &DefaultData);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_DEFAULT_OP:\r
+ //\r
+ // Update Current BlockData to the default value.\r
+ //\r
+ if (BlockData == NULL || BlockData->Scope == 0) {\r
+ //\r
+ // No matched block data is ignored.\r
+ //\r
+ break;\r
+ }\r
+\r
+ if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
+ //\r
+ // OrderedList Opcode is no default value.\r
+ //\r
+ break;\r
+ }\r
+ //\r
+ // Get the DefaultId\r
+ //\r
+ IfrDefault = (EFI_IFR_DEFAULT *) IfrOpHdr;\r
+ VarDefaultId = IfrDefault->DefaultId;\r
+ //\r
+ // Prepare new DefaultValue\r
+ //\r
+ DefaultData.Type = DefaultValueFromOpcode;\r
+ DefaultData.DefaultId = VarDefaultId;\r
+ CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
+\r
+ // If the value field is expression, set the cleaned flag.\r
+ if (IfrDefault->Type == EFI_IFR_TYPE_OTHER) {\r
+ DefaultData.Cleaned = TRUE;\r
+ }\r
+ //\r
+ // Add DefaultValue into current BlockData\r
+ //\r
+ InsertDefaultValue (BlockData, &DefaultData);\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
+ // use it.\r
+ //\r
+ DefaultData.Cleaned = FALSE;\r
+ break;\r
+\r
+ case EFI_IFR_END_OP:\r
+ //\r
+ // End Opcode is for Var question.\r
+ //\r
+ if (BlockData != NULL) {\r
+ if (BlockData->Scope > 0) {\r
+ BlockData->Scope--;\r
+ }\r
+ if (BlockData->Scope == 0) {\r
+ BlockData = NULL;\r
+ }\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ if (BlockData != NULL) {\r
+ if (BlockData->Scope > 0) {\r
+ BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);\r
+ }\r
+\r
+ if (BlockData->Scope == 0) {\r
+ BlockData = NULL;\r
+ }\r
+ }\r
+ break;\r
+ }\r
+\r
+ IfrOffset += IfrOpHdr->Length;\r
+ PackageOffset += IfrOpHdr->Length;\r
+ }\r
+\r
+Done:\r
+ for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+ BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+ for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; ) {\r
+ DefaultDataPtr = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+ LinkDefault = LinkDefault->ForwardLink;\r
+ if (DefaultDataPtr->Cleaned == TRUE) {\r
+ RemoveEntryList (&DefaultDataPtr->Entry);\r
+ FreePool (DefaultDataPtr);\r
+ }\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ parse the configrequest string, get the elements.\r
+\r
+ @param ConfigRequest The input configrequest string.\r
+ @param Progress Return the progress data.\r
+\r
+ @retval Block data pointer.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetBlockElement (\r
+ IN EFI_STRING ConfigRequest,\r
+ OUT EFI_STRING *Progress\r
+ )\r
+{\r
+ EFI_STRING StringPtr;\r
+ IFR_BLOCK_DATA *BlockData;\r
+ IFR_BLOCK_DATA *RequestBlockArray;\r
+ EFI_STATUS Status;\r
+ UINT8 *TmpBuffer;\r
+ UINT16 Offset;\r
+ UINT16 Width;\r
+ LIST_ENTRY *Link;\r
+ IFR_BLOCK_DATA *NextBlockData;\r
+ UINTN Length;\r
+\r
+ //\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
+ @retval EFI_SUCCESS The Results string is set to the full request string.\r
+ And AltCfgResp contains all default value string.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory for the return string.\r
+ @retval EFI_NOT_FOUND The varstore (Guid and Name) in Request string \r
+ can't be found in Form package.\r
+ @retval EFI_NOT_FOUND HiiPackage can't be got on the input HiiHandle.\r
+ @retval EFI_INVALID_PARAMETER Request points to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetFullStringFromHiiFormPackages (\r
+ IN HII_DATABASE_RECORD *DataBaseRecord,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN OUT EFI_STRING *Request,\r
+ IN OUT EFI_STRING *AltCfgResp,\r
+ OUT EFI_STRING *PointerProgress OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *HiiFormPackage;\r
+ UINTN PackageSize;\r
+ IFR_BLOCK_DATA *RequestBlockArray;\r
+ IFR_BLOCK_DATA *BlockData;\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 ConfigHdr;\r
+ EFI_STRING StringPtr;\r
+ EFI_STRING Progress;\r
+\r
+ if (DataBaseRecord == NULL || DevicePath == NULL || Request == NULL || AltCfgResp == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Initialize the local variables.\r
+ //\r
+ RequestBlockArray = NULL;\r
+ DefaultIdArray = NULL;\r
+ VarStorageData = NULL;\r
+ DefaultAltCfgResp = NULL;\r
+ ConfigHdr = NULL;\r
+ HiiFormPackage = NULL;\r
+ PackageSize = 0;\r
+ Progress = *Request;\r
+\r
+ Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // 1. Get the request block array by Request String when Request string containts the block array.\r
+ //\r
+ StringPtr = NULL;\r
+ if (*Request != NULL) {\r
+ StringPtr = *Request;\r
+ //\r
+ // Jump <ConfigHdr>\r
+ //\r
+ if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\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
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+ StringPtr += StrLen (L"&NAME=");\r
+ while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+ StringPtr++;\r
+ }\r
+ if (*StringPtr == L'\0') {\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
+ if (*StringPtr == L'\0') {\r
+ //\r
+ // No request block is found.\r
+ //\r
+ StringPtr = NULL;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If StringPtr != NULL, get the request elements.\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
+ // 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
+ // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
+ //\r
+\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
+ // No requested varstore in IFR data and directly return\r
+ //\r
+ if (VarStorageData->Type == 0 && VarStorageData->Name == NULL) {\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
+\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
+ //\r
+ if (*AltCfgResp != NULL && DefaultAltCfgResp != NULL) {\r
+ Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);\r
+ FreePool (DefaultAltCfgResp);\r
+ } else if (*AltCfgResp == NULL) {\r
+ *AltCfgResp = DefaultAltCfgResp;\r
+ }\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
+ if (VarStorageData != NULL) {\r
+ //\r
+ // Free link array VarStorageData\r
+ //\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
+ while (!IsListEmpty (&BlockData->DefaultValueEntry)) {\r
+ DefaultValueData = BASE_CR (BlockData->DefaultValueEntry.ForwardLink, IFR_DEFAULT_DATA, Entry);\r
+ RemoveEntryList (&DefaultValueData->Entry);\r
+ FreePool (DefaultValueData);\r
+ }\r
+ FreePool (BlockData);\r
+ }\r
+ FreePool (VarStorageData);\r
+ }\r
+\r
+ if (DefaultIdArray != NULL) {\r
+ //\r
+ // Free DefaultId Array\r
+ //\r
+ while (!IsListEmpty (&DefaultIdArray->Entry)) {\r
+ DefaultId = BASE_CR (DefaultIdArray->Entry.ForwardLink, IFR_DEFAULT_DATA, Entry);\r
+ RemoveEntryList (&DefaultId->Entry);\r
+ FreePool (DefaultId);\r
+ }\r
+ FreePool (DefaultIdArray);\r
+ }\r
+\r
+ //\r
+ // Free the allocated string \r
+ //\r
+ if (ConfigHdr != NULL) {\r
+ FreePool (ConfigHdr);\r
+ }\r
+\r
+ //\r
+ // Free Pacakge data\r
+ //\r
+ if (HiiFormPackage != NULL) {\r
+ FreePool (HiiFormPackage);\r
+ }\r
+\r
+ if (PointerProgress != NULL) {\r
+ if (*Request == NULL) {\r
+ *PointerProgress = NULL;\r
+ } else if (EFI_ERROR (Status)) {\r
+ *PointerProgress = *Request;\r
+ } else {\r
+ *PointerProgress = *Request + StrLen (*Request);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function gets the full request resp string by \r
+ parsing IFR data in HII form packages.\r
+\r
+ @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
+ instance.\r
+ @param EfiVarStoreInfo The efi varstore info which is save in the EFI \r
+ varstore data structure. \r
+ @param Request Pointer to a null-terminated Unicode string in\r
+ <ConfigRequest> format.\r
+ @param RequestResp Pointer to a null-terminated Unicode string in\r
+ <ConfigResp> format.\r
+ @param AccessProgress 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
+\r
+ @retval EFI_SUCCESS The Results string is set to the full request string.\r
+ And AltCfgResp contains all default value string.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory for the return string.\r
+ @retval EFI_INVALID_PARAMETER Request points to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+GetConfigRespFromEfiVarStore (\r
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,\r
+ IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo, \r
+ IN EFI_STRING Request,\r
+ OUT EFI_STRING *RequestResp,\r
+ OUT EFI_STRING *AccessProgress\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING VarStoreName;\r
+ UINT8 *VarStore;\r
+ UINTN BufferSize;\r
+\r
+ Status = EFI_SUCCESS;\r
+ BufferSize = 0;\r
+ VarStore = NULL;\r
+ VarStoreName = NULL;\r
+ *AccessProgress = Request;\r
+ \r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));\r
+ if (VarStoreName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ AsciiStrToUnicodeStr ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName);\r
+ \r
+ \r
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ goto Done;\r
+ }\r
+\r
+ VarStore = AllocateZeroPool (BufferSize);\r
+ ASSERT (VarStore != NULL);\r
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = HiiBlockToConfig(This, Request, VarStore, BufferSize, RequestResp, AccessProgress);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+Done:\r
+ if (VarStoreName != NULL) {\r
+ FreePool (VarStoreName);\r
+ }\r
+\r
+ if (VarStore != NULL) {\r
+ FreePool (VarStore);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ This function route the full request resp string for efi varstore. \r
+\r
+ @param This A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL\r
+ instance.\r
+ @param EfiVarStoreInfo The efi varstore info which is save in the EFI \r
+ varstore data structure. \r
+ @param RequestResp Pointer to a null-terminated Unicode string in\r
+ <ConfigResp> format.\r
+ @param Result Pointer to a null-terminated Unicode string in\r
+ <ConfigResp> format.\r
+ \r
+ @retval EFI_SUCCESS The Results string is set to the full request string.\r
+ And AltCfgResp contains all default value string.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory for the return string.\r
+ @retval EFI_INVALID_PARAMETER Request points to NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+RouteConfigRespForEfiVarStore (\r
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,\r
+ IN EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo, \r
+ IN EFI_STRING RequestResp,\r
+ OUT EFI_STRING *Result\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING VarStoreName;\r
+ UINT8 *VarStore;\r
+ UINTN BufferSize;\r
+ UINTN BlockSize;\r
+\r
+ Status = EFI_SUCCESS;\r
+ BufferSize = 0;\r
+ VarStore = NULL;\r
+ VarStoreName = NULL;\r
+\r
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));\r
+ if (VarStoreName == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+ AsciiStrToUnicodeStr ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName);\r
+ \r
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ goto Done;\r
+ }\r
+\r
+ BlockSize = BufferSize;\r
+ VarStore = AllocateZeroPool (BufferSize);\r
+ ASSERT (VarStore != NULL);\r
+ Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = HiiConfigToBlock(This, RequestResp, VarStore, &BlockSize, Result);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ Status = gRT->SetVariable (VarStoreName, &EfiVarStoreInfo->Guid, EfiVarStoreInfo->Attributes, BufferSize, VarStore);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+Done:\r
+ if (VarStoreName != NULL) {\r
+ FreePool (VarStoreName);\r
+ }\r
+\r
+ if (VarStore != NULL) {\r
+ FreePool (VarStore);\r
+ }\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