\r
#include "HiiDatabase.h"\r
\r
+EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
+EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+\r
+\r
EFI_GUID *\r
GetGuidOfFirstFormset (\r
CONST EFI_HII_FORM_PACKAGE * FormPackage\r
) \r
{\r
- UINT8 *StartOfNextPackage;\r
- EFI_IFR_OP_HEADER *OpCodeData;\r
+ UINT8 *StartOfNextPackage;\r
+ EFI_IFR_OP_HEADER *OpCodeData;\r
\r
StartOfNextPackage = (UINT8 *) FormPackage + FormPackage->Header.Length;\r
OpCodeData = (EFI_IFR_OP_HEADER *) (FormPackage + 1);\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
+FwHiiHandleToUefiHiiHandle (\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
+ IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\r
)\r
{\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
- ASSERT (FrameworkHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
+ ASSERT (FwHiiHandle != (FRAMEWORK_EFI_HII_HANDLE) 0);\r
ASSERT (Private != NULL);\r
\r
- HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, FrameworkHiiHandle);\r
+ ThunkContext = FwHiiHandleToThunkContext (Private, FwHiiHandle);\r
\r
- if (HandleMapEntry != NULL) {\r
- return HandleMapEntry->UefiHiiHandle;\r
+ if (ThunkContext != NULL) {\r
+ return ThunkContext->UefiHiiHandle;\r
}\r
\r
return (EFI_HII_HANDLE) NULL;\r
}\r
\r
\r
-HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *\r
-FrameworkHiiHandleToMapDatabaseEntry (\r
- IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private,\r
- IN FRAMEWORK_EFI_HII_HANDLE FrameworkHiiHandle\r
+HII_THUNK_CONTEXT *\r
+FwHiiHandleToThunkContext (\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
+ IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle\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
\r
- for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
- ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
- ListEntry = ListEntry->ForwardLink\r
- ) {\r
- HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
\r
- if (FrameworkHiiHandle == HandleMapEntry->FrameworkHiiHandle) {\r
- return HandleMapEntry;\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
+\r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
- return (HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *) NULL;\r
+ return NULL;\r
}\r
\r
-HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *\r
-UefiHiiHandleToMapDatabaseEntry (\r
- IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private,\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 *ListEntry;\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
+ LIST_ENTRY *Link;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
- for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
- ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
- ListEntry = ListEntry->ForwardLink\r
- ) {\r
- HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
\r
- if (UefiHiiHandle == HandleMapEntry->UefiHiiHandle) {\r
- return HandleMapEntry;\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 (HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *) NULL;\r
+ return NULL;\r
}\r
\r
EFI_HII_HANDLE *\r
-TagGuidToUefiIfrHiiHandle (\r
- IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private,\r
+TagGuidToUefiHiiHandle (\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
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
\r
- for (ListEntry = Private->HiiThunkHandleMappingDBListHead.ForwardLink;\r
- ListEntry != &Private->HiiThunkHandleMappingDBListHead;\r
- ListEntry = ListEntry->ForwardLink\r
- ) {\r
- HandleMapEntry = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_FROM_LISTENTRY (ListEntry);\r
+ while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+ ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
\r
- if (CompareGuid (Guid, &HandleMapEntry->TagGuid) && HandleMapEntry->DoesPackageListImportStringPackages) {\r
- return HandleMapEntry->UefiHiiHandle;\r
+ if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
+ return ThunkContext->UefiHiiHandle;\r
}\r
+\r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
- return (EFI_HII_HANDLE *) NULL;\r
+ return NULL;\r
\r
}\r
\r
BOOLEAN\r
IsFrameworkHiiDatabaseHandleDepleted (\r
- IN CONST EFI_HII_THUNK_PRIVATE_DATA *Private\r
+ IN CONST HII_THUNK_PRIVATE_DATA *Private\r
)\r
{\r
return (BOOLEAN) (Private->StaticHiiHandle == (UINTN) Private->StaticPureUefiHiiHandle);\r
}\r
\r
EFI_STATUS\r
-\r
-AssignHiiHandle (\r
- IN OUT EFI_HII_THUNK_PRIVATE_DATA *Private,\r
+AssignFrameworkHiiHandle (\r
+ IN OUT HII_THUNK_PRIVATE_DATA *Private,\r
+ IN BOOLEAN FromFwHiiNewPack,\r
OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
)\r
{\r
ASSERT (Handle != NULL);\r
\r
- *Handle = Private->StaticHiiHandle;\r
- Private->StaticHiiHandle += 1;\r
+ if (FromFwHiiNewPack) {\r
+\r
+ *Handle = Private->StaticHiiHandle;\r
+ Private->StaticHiiHandle += 1;\r
+\r
+ if (IsFrameworkHiiDatabaseHandleDepleted (Private)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ } else {\r
+\r
+ *Handle = Private->StaticPureUefiHiiHandle;\r
+ Private->StaticPureUefiHiiHandle -= 1;\r
+ \r
+ if (IsFrameworkHiiDatabaseHandleDepleted (Private)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
\r
- if (IsFrameworkHiiDatabaseHandleDepleted (Private)) {\r
- return EFI_OUT_OF_RESOURCES;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
EFI_STATUS\r
-AssignPureUefiHiiHandle (\r
- IN OUT EFI_HII_THUNK_PRIVATE_DATA *Private,\r
- OUT FRAMEWORK_EFI_HII_HANDLE *Handle\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
+ ASSERT (IsListEmpty (&ThunkContext->OneOfOptionMapListHead));\r
+ ASSERT (IsListEmpty (&ThunkContext->QuestionIdMapListHead));\r
+ \r
+ RemoveEntryList (&ThunkContext->Link);\r
+\r
+ FreePool (ThunkContext);\r
+ \r
+ return EFI_SUCCESS;\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 HII_THUNK_PRIVATE_DATA *Private,\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GUID PackageGuid;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ ThunkContext = AllocateZeroPool (sizeof (*ThunkContext));\r
+ ASSERT (ThunkContext != NULL);\r
+ \r
+ ThunkContext->Signature = HII_THUNK_CONTEXT_SIGNATURE;\r
+\r
+ Status = AssignFrameworkHiiHandle (Private, FALSE, &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
+ InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\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
- ASSERT (Handle != NULL);\r
+ UINTN Count;\r
+ EFI_HII_PACKAGE_HEADER *PackageHeader;\r
+\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
+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 NULL;\r
+}\r
\r
- *Handle = Private->StaticPureUefiHiiHandle;\r
- Private->StaticPureUefiHiiHandle -= 1;\r
\r
- if (IsFrameworkHiiDatabaseHandleDepleted (Private)) {\r
- return EFI_OUT_OF_RESOURCES;\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
+ \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
+ break;\r
+ \r
+ case EFI_IFR_GUID_OP:\r
+ OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCode;\r
+ if (CompareGuid (&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
+ OneOfOptionMap->ValueType = EFI_IFR_TYPE_NUM_SIZE_8;\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 (&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
+ ThunkContext->FormSetSubClass = ((EFI_IFR_GUID_SUBCLASS *) Class)->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