\r
\r
#include "HiiDatabase.h"\r
+#include "HiiHandle.h"\r
\r
-EFI_GUID *\r
-GetGuidOfFirstFormset (\r
- CONST EFI_HII_FORM_PACKAGE * FormPackage\r
-) \r
+EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
+EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+\r
+\r
+EFI_HII_HANDLE\r
+FwHiiHandleToUefiHiiHandle (\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
+ IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
+ )\r
+{\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
+ ASSERT (Private != NULL);\r
+\r
+ ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);\r
+\r
+ if (ThunkContext != NULL) {\r
+ return ThunkContext->UefiHiiHandle;\r
+ }\r
+ \r
+ return (EFI_HII_HANDLE) NULL;\r
+}\r
+\r
+\r
+HII_THUNK_CONTEXT *\r
+FwHiiHandleToThunkContext (\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
+ IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
+ )\r
{\r
- UINT8 *StartOfNextPackage;\r
- EFI_IFR_OP_HEADER *OpCodeData;\r
+ LIST_ENTRY *Link;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
\r
- StartOfNextPackage = (UINT8 *) FormPackage + FormPackage->Header.Length;\r
- OpCodeData = (EFI_IFR_OP_HEADER *) (FormPackage + 1);\r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
\r
- while ((UINT8 *) OpCodeData < StartOfNextPackage) {\r
- if (OpCodeData->OpCode == EFI_IFR_FORM_SET_OP) {\r
- return &(((EFI_IFR_FORM_SET *) OpCodeData)->Guid);\r
+ while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+ ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+ if (FwHiiHandle == ThunkContext->FwHiiHandle) {\r
+ return ThunkContext;\r
}\r
- OpCodeData = (EFI_IFR_OP_HEADER *) ((UINT8 *) OpCodeData + OpCodeData->Length);\r
+\r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
- ASSERT (FALSE);\r
+ return NULL;\r
+}\r
+\r
+HII_THUNK_CONTEXT *\r
+UefiHiiHandleToThunkContext (\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
+\r
+ while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+ ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+ if (UefiHiiHandle == ThunkContext->UefiHiiHandle) {\r
+ return ThunkContext;\r
+ }\r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
+ }\r
\r
return NULL;\r
}\r
\r
-EFI_HII_HANDLE\r
-FrameworkHiiHandleToUefiHiiHandle (\r
- IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private,\r
- IN FRAMEWORK_EFI_HII_HANDLE FrameworkHiiHandle\r
+HII_THUNK_CONTEXT *\r
+TagGuidToIfrPackThunkContext (\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
+ IN CONST EFI_GUID *Guid\r
)\r
{\r
- LIST_ENTRY *ListEntry;\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
+ LIST_ENTRY *Link;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
- ASSERT (FrameworkHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
- ASSERT (Private != NULL);\r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
+\r
+ while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+ ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+ if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
+ return ThunkContext;\r
+ }\r
+\r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
+ }\r
+\r
+ return NULL;\r
+ \r
+}\r
+\r
+\r
+VOID\r
+DestroyThunkContextForUefiHiiHandle (\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);\r
+ ASSERT (ThunkContext != NULL);\r
+\r
+ DestroyThunkContext (ThunkContext);\r
+}\r
+\r
+\r
+/**\r
+ This function create a HII_THUNK_CONTEXT for a package list registered\r
+ by a module calling EFI_HII_DATABASE_PROTOCOL.NewPackageList. It records\r
+ the PackageListGuid in EFI_HII_PACKAGE_LIST_HEADER in the TagGuid in \r
+ HII_THUNK_CONTEXT created. This TagGuid will be used as a key to s\r
+\r
+**/\r
+HII_THUNK_CONTEXT *\r
+CreateThunkContextForUefiHiiHandle (\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GUID PackageGuid;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
- for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
- ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
- ListEntry = ListEntry->ForwardLink\r
- ) {\r
+ ThunkContext = AllocateZeroPool (sizeof (*ThunkContext));\r
+ ASSERT (ThunkContext != NULL);\r
+ \r
+ ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
+\r
+ Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+ \r
+ ThunkContext->UefiHiiHandle = UefiHiiHandle;\r
+ \r
+ Status = HiiLibExtractGuidFromHiiHandle (UefiHiiHandle, &PackageGuid);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ CopyGuid(&ThunkContext->TagGuid, &PackageGuid);\r
+\r
+ InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
+ InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
+ \r
+ return ThunkContext;\r
+}\r
+\r
+\r
+UINTN\r
+GetPackageCountByType (\r
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
+ IN UINT8 PackageType\r
+ )\r
+{\r
+ UINTN Count;\r
+ EFI_HII_PACKAGE_HEADER *PackageHeader;\r
\r
- HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageListHeader + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
+ Count = 0;\r
+ \r
+ while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
+ if (PackageHeader->Type == PackageType ) {\r
+ Count++;\r
+ }\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
+ }\r
+ \r
+ \r
+ return Count;\r
+}\r
\r
- if (FrameworkHiiHandle == HandleMapEntry->FrameworkHiiHandle) {\r
- return HandleMapEntry->UefiHiiHandle;\r
+LIST_ENTRY *\r
+GetOneOfOptionMapEntryListHead (\r
+ IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
+ IN UINT16 QuestionId\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ ONE_OF_OPTION_MAP *Map;\r
+\r
+ Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+ while (!IsNull (&ThunkContext->OneOfOptionMapListHead, Link)) {\r
+ Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+ if (QuestionId == Map->QuestionId) {\r
+ return &Map->OneOfOptionMapEntryListHead;\r
}\r
+ Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);\r
}\r
\r
- return (EFI_HII_HANDLE) NULL;\r
+ return NULL;\r
+}\r
+\r
+EFI_HII_PACKAGE_HEADER *\r
+GetIfrPackage (\r
+ IN CONST EFI_HII_PACKAGES *Packages\r
+ )\r
+{\r
+ UINTN Index;\r
+ TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
+\r
+ ASSERT (Packages != NULL);\r
+\r
+ TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
+ \r
+ for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
+ //\r
+ // The current UEFI HII build tool generate a binary in the format defined by \r
+ // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
+ // this binary is with same package type. So the returned IfrPackageCount and StringPackageCount\r
+ // may not be the exact number of valid package number in the binary generated \r
+ // by HII Build tool.\r
+ //\r
+ switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {\r
+ case EFI_HII_PACKAGE_FORM:\r
+ return &TianoAutogenPackageHdrArray[Index]->PackageHeader;\r
+ break;\r
+ case EFI_HII_PACKAGE_STRINGS:\r
+ case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
+ break;\r
+\r
+ //\r
+ // The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
+ //\r
+ case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:\r
+ case EFI_HII_PACKAGE_FONTS:\r
+ case EFI_HII_PACKAGE_IMAGES:\r
+ default:\r
+ ASSERT (FALSE);\r
+ return NULL;\r
+ break;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+VOID\r
+GetFormSetGuid (\r
+ IN EFI_HII_PACKAGE_HEADER *Package,\r
+ OUT EFI_GUID *FormSetGuid\r
+ )\r
+{\r
+ UINTN Offset;\r
+ EFI_IFR_OP_HEADER *OpCode;\r
+ EFI_IFR_FORM_SET *FormSet;\r
+\r
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset < Package->Length) {\r
+ OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
+\r
+ switch (OpCode->OpCode) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
+ CopyGuid (FormSetGuid, (EFI_GUID *)(VOID *)&FormSet->Guid);\r
+ return;\r
+ \r
+ default:\r
+ break;\r
+ \r
+ }\r
+ Offset += OpCode->Length;\r
+ }\r
+\r
+ //\r
+ // A proper IFR must have a formset opcode.\r
+ //\r
+ ASSERT (FALSE);\r
+\r
}\r
\r
+\r
+VOID\r
+GetAttributesOfFirstFormSet (\r
+ IN OUT HII_THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_LIST_HEADER *List;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINTN Size;\r
+ EFI_IFR_OP_HEADER *OpCode;\r
+ UINTN Offset;\r
+ EFI_IFR_GUID_CLASS *Class;\r
+ EFI_IFR_FORM_SET *FormSet;\r
+ EFI_IFR_GUID_SUBCLASS *SubClass;\r
+\r
+ Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // There must be at least one EFI_HII_PACKAGE_FORM in the package list.\r
+ //\r
+ ASSERT (GetPackageCountByType (List, EFI_HII_PACKAGE_FORM) >= 1);\r
+\r
+ //\r
+ // Skip the package list header.\r
+ //\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);\r
+\r
+ while (Package->Type != EFI_HII_PACKAGE_END) {\r
+\r
+ if (Package->Type == EFI_HII_PACKAGE_FORM) {\r
+\r
+ //\r
+ // Skip the package header\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset < Package->Length) {\r
+ OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
+\r
+ switch (OpCode->OpCode) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
+ ThunkContext->FormSetTitle = FormSet->FormSetTitle;\r
+ ThunkContext->FormSetHelp = FormSet->Help;\r
+ break;\r
+ \r
+\r
+ case EFI_IFR_GUID_OP:\r
+ Class = (EFI_IFR_GUID_CLASS*) OpCode;\r
+ if (CompareGuid ((EFI_GUID *)(VOID *)&Class->Guid, &gTianoHiiIfrGuid)) {\r
+ Class = (EFI_IFR_GUID_CLASS *) OpCode;\r
+\r
+ switch (Class->ExtendOpCode) {\r
+ case EFI_IFR_EXTEND_OP_CLASS:\r
+ ThunkContext->FormSetClass = Class->Class;\r
+ break;\r
+ case EFI_IFR_EXTEND_OP_SUBCLASS:\r
+ SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;\r
+ ThunkContext->FormSetSubClass = SubClass->SubClass;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ \r
+ default:\r
+ break;\r
+ \r
+ }\r
+\r
+ Offset += OpCode->Length;\r
+ }\r
+ //\r
+ // The attributes of first FormSet is ready now.\r
+ //\r
+ FreePool (List);\r
+ return;\r
+ \r
+ break;\r
+ }\r
+\r
+ Package = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) Package + Package->Length);\r
+ }\r
+\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CreateQuestionIdMap (\r
+ IN OUT HII_THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_LIST_HEADER *List;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINTN Size;\r
+ EFI_IFR_OP_HEADER *OpCode;\r
+ UINTN Offset;\r
+ QUESTION_ID_MAP *IdMap;\r
+ EFI_IFR_VARSTORE *VarStore;\r
+ EFI_IFR_FORM_SET *FormSet;\r
+ EFI_IFR_QUESTION_HEADER *Question;\r
+ LIST_ENTRY *QuestionIdMapEntryListHead;\r
+ LIST_ENTRY *OneOfOptinMapEntryListHead;\r
+ QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
+ EFI_IFR_GUID_OPTIONKEY *OptionMap;\r
+ ONE_OF_OPTION_MAP *OneOfOptionMap;\r
+ ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
+ EFI_IFR_GUID_CLASS *Class;\r
+ EFI_IFR_GUID_SUBCLASS *SubClass;\r
+ UINT8 OneOfType;\r
+ EFI_IFR_ONE_OF *OneOfOpcode;\r
+\r
+ //\r
+ // Set to a invalid value.\r
+ //\r
+ OneOfType = (UINT8) -1;\r
+ \r
+\r
+ Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &List, &Size);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get all VarStoreId and build the the QuestionId map.\r
+ // EFI_IFR_QUESTION_HEADER.VarStoreInfo.VarOffset -> Framework Question ID\r
+ // EFI_IFR_QUESTION_HEADER.QuestionId -> UEFI Question ID\r
+ //\r
+\r
+ //\r
+ // Skip the package list header.\r
+ //\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (List + 1);\r
+\r
+ while (Package->Type != EFI_HII_PACKAGE_END) {\r
+\r
+ if (Package->Type == EFI_HII_PACKAGE_FORM) {\r
+\r
+ //\r
+ // Skip the package header\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset < Package->Length) {\r
+ OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\r
+\r
+ switch (OpCode->OpCode) {\r
+ case EFI_IFR_FORM_SET_OP:\r
+ FormSet = (EFI_IFR_FORM_SET *) OpCode;\r
+ ThunkContext->FormSetTitle = FormSet->FormSetTitle;\r
+ ThunkContext->FormSetHelp = FormSet->Help;\r
+ break;\r
+ \r
+ case EFI_IFR_VARSTORE_OP:\r
+ //\r
+ // IFR built from Framework VFR only has UEFI Buffer Type Storage\r
+ //\r
+ VarStore = (EFI_IFR_VARSTORE *) OpCode;\r
+ IdMap = AllocateZeroPool (sizeof (QUESTION_ID_MAP));\r
+ ASSERT (IdMap != NULL);\r
+ \r
+ IdMap->Signature = QUESTION_ID_MAP_SIGNATURE;\r
+ IdMap->VarStoreId = VarStore->VarStoreId;\r
+ IdMap->VarSize = VarStore->Size;\r
+ InitializeListHead (&IdMap->MapEntryListHead);\r
+ InsertTailList (&ThunkContext->QuestionIdMapListHead, &IdMap->Link);\r
+ break;\r
+\r
+ case EFI_IFR_NUMERIC_OP:\r
+ case EFI_IFR_CHECKBOX_OP:\r
+ case EFI_IFR_ONE_OF_OP:\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ case EFI_IFR_STRING_OP:\r
+ //case EFI_IFR_PASSWORD_OP:\r
+ Question = (EFI_IFR_QUESTION_HEADER *)(OpCode + 1);\r
+ QuestionIdMapEntryListHead = GetMapEntryListHead (ThunkContext, Question->VarStoreId);\r
+\r
+ if (QuestionIdMapEntryListHead != NULL) {\r
+ //\r
+ // If the Question is using Buffer (EFI_IFR_VARSTORE_OP) type VarStore.\r
+ //\r
+ IdMapEntry = AllocateZeroPool (sizeof (QUESTION_ID_MAP_ENTRY));\r
+ ASSERT (IdMapEntry != NULL);\r
+\r
+ IdMapEntry->FwQId = Question->VarStoreInfo.VarOffset;\r
+ IdMapEntry->UefiQid = Question->QuestionId;\r
+ IdMapEntry->Signature = QUESTION_ID_MAP_ENTRY_SIGNATURE;\r
+\r
+ InsertTailList (QuestionIdMapEntryListHead, &IdMapEntry->Link);\r
+ }\r
+\r
+ if (OpCode->OpCode == EFI_IFR_ONE_OF_OP) {\r
+ OneOfOpcode = (EFI_IFR_ONE_OF *) OpCode;\r
+ OneOfType = OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE;\r
+ }\r
+\r
+ break;\r
+ \r
+ case EFI_IFR_GUID_OP:\r
+ OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCode;\r
+ if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &gFrameworkHiiCompatbilityGuid)) {\r
+ if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {\r
+ OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (ThunkContext, OptionMap->QuestionId);\r
+ if (OneOfOptinMapEntryListHead == NULL) {\r
+ OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));\r
+ ASSERT (OneOfOptionMap != NULL);\r
+\r
+ OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;\r
+ OneOfOptionMap->QuestionId = OptionMap->QuestionId;\r
+\r
+ //\r
+ // Make sure OneOfType is initialized.\r
+ //\r
+ ASSERT (OneOfType != (UINT8) -1);\r
+ OneOfOptionMap->ValueType = OneOfType;\r
+ InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
+ OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;\r
+ InsertTailList (&ThunkContext->OneOfOptionMapListHead, &OneOfOptionMap->Link);\r
+ }\r
+ OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));\r
+ ASSERT (OneOfOptionMapEntry != NULL);\r
+\r
+ OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;\r
+ OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;\r
+ CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));\r
+ \r
+ InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);\r
+ }\r
+ } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &gTianoHiiIfrGuid)) {\r
+ Class = (EFI_IFR_GUID_CLASS *) OpCode;\r
+\r
+ switch (Class->ExtendOpCode) {\r
+ case EFI_IFR_EXTEND_OP_CLASS:\r
+ ThunkContext->FormSetClass = Class->Class;\r
+ break;\r
+ case EFI_IFR_EXTEND_OP_SUBCLASS:\r
+ SubClass = (EFI_IFR_GUID_SUBCLASS *) OpCode;\r
+ ThunkContext->FormSetSubClass = SubClass->SubClass;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ \r
+ default:\r
+ break;\r
+ \r
+ }\r
+\r
+ Offset += OpCode->Length;\r
+ }\r
+ //\r
+ // Only Form Package is in a Package List.\r
+ //\r
+ break;\r
+ }\r
+\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (UINT8 *) Package + Package->Length;\r
+ }\r
+\r
+ FreePool (List);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+LIST_ENTRY *\r
+GetMapEntryListHead (\r
+ IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
+ IN UINT16 VarStoreId\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ QUESTION_ID_MAP *Map;\r
+\r
+ Link = GetFirstNode (&ThunkContext->QuestionIdMapListHead);\r
+\r
+ while (!IsNull (&ThunkContext->QuestionIdMapListHead, Link)) {\r
+ Map = QUESTION_ID_MAP_FROM_LINK (Link);\r
+ if (VarStoreId == Map->VarStoreId) {\r
+ return &Map->MapEntryListHead;\r
+ }\r
+ Link = GetNextNode (&ThunkContext->QuestionIdMapListHead, Link);\r
+ }\r
+ return NULL;\r
+}\r
+\r
+\r
+HII_THUNK_CONTEXT *\r
+CreateThunkContext (\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN UINTN StringPackageCount,\r
+ IN UINTN IfrPackageCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ ThunkContext = AllocateZeroPool (sizeof (HII_THUNK_CONTEXT));\r
+ ASSERT (ThunkContext != NULL);\r
+ \r
+ ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
+ ThunkContext->IfrPackageCount = IfrPackageCount;\r
+ ThunkContext->StringPackageCount = StringPackageCount;\r
+ Status = AllocateHiiHandle (&ThunkContext->FwHiiHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
+ InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+\r
+ return ThunkContext;\r
+ \r
+}\r
+\r
+VOID\r
+DestroyThunkContext (\r
+ IN HII_THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ ASSERT (ThunkContext != NULL);\r
+\r
+ FreeHiiHandle (ThunkContext->FwHiiHandle);\r
+\r
+ DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);\r
+\r
+ DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+ RemoveEntryList (&ThunkContext->Link);\r
+\r
+ FreePool (ThunkContext);\r
+}\r
+\r
+\r
+VOID\r
+DestroyQuestionIdMap (\r
+ IN LIST_ENTRY *QuestionIdMapListHead\r
+ )\r
+{\r
+ QUESTION_ID_MAP *IdMap;\r
+ QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *Link2;\r
+\r
+ while (!IsListEmpty (QuestionIdMapListHead)) {\r
+ Link = GetFirstNode (QuestionIdMapListHead);\r
+ \r
+ IdMap = QUESTION_ID_MAP_FROM_LINK (Link);\r
+\r
+ while (!IsListEmpty (&IdMap->MapEntryListHead)) {\r
+ Link2 = GetFirstNode (&IdMap->MapEntryListHead);\r
+ \r
+ IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link2);\r
+\r
+ RemoveEntryList (Link2);\r
+\r
+ FreePool (IdMapEntry);\r
+ }\r
+\r
+ RemoveEntryList (Link);\r
+ FreePool (IdMap);\r
+ }\r
+}\r
+\r
+VOID\r
+DestoryOneOfOptionMap (\r
+ IN LIST_ENTRY *OneOfOptionMapListHead\r
+ )\r
+{\r
+ ONE_OF_OPTION_MAP *Map;\r
+ ONE_OF_OPTION_MAP_ENTRY *MapEntry;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *Link2;\r
+\r
+ while (!IsListEmpty (OneOfOptionMapListHead)) {\r
+ Link = GetFirstNode (OneOfOptionMapListHead);\r
+ \r
+ Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+\r
+ while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
+ Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
+ \r
+ MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);\r
+\r
+ RemoveEntryList (Link2);\r
+\r
+ FreePool (MapEntry);\r
+ }\r
+\r
+ RemoveEntryList (Link);\r
+ FreePool (Map);\r
+ }\r
+}\r
+\r
+\r
+\r
+\r