\r
#include "HiiDatabase.h"\r
#include "HiiHandle.h"\r
+#include <Library/DebugLib.h>\r
\r
-EFI_GUID gFrameworkHiiCompatbilityGuid = EFI_IFR_FRAMEWORK_GUID;\r
-EFI_GUID gTianoHiiIfrGuid = EFI_IFR_TIANO_GUID;\r
+CONST EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
\r
+/**\r
+ Find the corressponding UEFI HII Handle from a Framework HII Handle given.\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
-\r
- StartOfNextPackage = (UINT8 *) FormPackage + FormPackage->Header.Length;\r
- OpCodeData = (EFI_IFR_OP_HEADER *) (FormPackage + 1);\r
-\r
- while ((UINT8 *) OpCodeData < StartOfNextPackage) {\r
- if (OpCodeData->OpCode == EFI_IFR_FORM_SET_OP) {\r
- return AllocateCopyPool (sizeof(EFI_GUID), &(((EFI_IFR_FORM_SET *) OpCodeData)->Guid));\r
- }\r
- OpCodeData = (EFI_IFR_OP_HEADER *) ((UINT8 *) OpCodeData + OpCodeData->Length);\r
- }\r
-\r
- ASSERT (FALSE);\r
-\r
- return NULL;\r
-}\r
+ @param Private The HII Thunk Module Private context.\r
+ @param FwHiiHandle The Framemwork HII Handle.\r
\r
+ @return NULL If Framework HII Handle is invalid.\r
+ @return The corresponding UEFI HII Handle.\r
+**/\r
EFI_HII_HANDLE\r
FwHiiHandleToUefiHiiHandle (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
}\r
\r
\r
+/**\r
+ Find the corressponding HII Thunk Context from a Framework HII Handle given.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param FwHiiHandle The Framemwork HII Handle.\r
+\r
+ @return NULL If Framework HII Handle is invalid.\r
+ @return The corresponding HII Thunk Context.\r
+**/\r
HII_THUNK_CONTEXT *\r
FwHiiHandleToThunkContext (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
return NULL;\r
}\r
\r
+/**\r
+ Find the corressponding HII Thunk Context from a UEFI HII Handle given.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param UEFIHiiHandle The UEFI HII Handle.\r
+\r
+ @return NULL If UEFI HII Handle is invalid.\r
+ @return The corresponding HII Thunk Context.\r
+**/\r
HII_THUNK_CONTEXT *\r
UefiHiiHandleToThunkContext (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
return NULL;\r
}\r
\r
-EFI_HII_HANDLE *\r
-TagGuidToUefiHiiHandle (\r
+/**\r
+ Find the corressponding HII Thunk Context from a Tag GUID.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param Guid The Tag GUID.\r
+\r
+ @return NULL No HII Thunk Context matched the Tag GUID.\r
+ @return The corresponding HII Thunk Context.\r
+**/\r
+HII_THUNK_CONTEXT *\r
+TagGuidToIfrPackThunkContext (\r
IN CONST HII_THUNK_PRIVATE_DATA *Private,\r
IN CONST EFI_GUID *Guid\r
)\r
ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
\r
if (CompareGuid (Guid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount != 0)) {\r
- return ThunkContext->UefiHiiHandle;\r
+ return ThunkContext;\r
}\r
\r
Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
\r
}\r
\r
+/**\r
+ Clean up the HII Thunk Context for a UEFI HII Handle.\r
+\r
+ @param Private The HII Thunk Module Private context.\r
+ @param UEFIHiiHandle The UEFI HII Handle.\r
\r
+**/\r
VOID\r
DestroyThunkContextForUefiHiiHandle (\r
IN HII_THUNK_PRIVATE_DATA *Private,\r
\r
CopyGuid(&ThunkContext->TagGuid, &PackageGuid);\r
\r
- InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
- InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
- \r
return ThunkContext;\r
}\r
\r
\r
+/**\r
+ Get the number of HII Package for a Package type.\r
+\r
+ @param PackageListHeader The Package List.\r
+ @param PackageType The Package Type.\r
+\r
+ @return The number of Package for given type.\r
+**/\r
UINTN\r
GetPackageCountByType (\r
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader,\r
return Count;\r
}\r
\r
-LIST_ENTRY *\r
-GetOneOfOptionMapEntryListHead (\r
- IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
- IN UINT16 QuestionId\r
+/**\r
+ Get the Form Package from a Framework Package List.\r
+\r
+ @param Packages Framework Package List.\r
+\r
+ @return The Form Package Header found.\r
+**/\r
+EFI_HII_PACKAGE_HEADER *\r
+GetIfrPackage (\r
+ IN CONST EFI_HII_PACKAGES *Packages\r
)\r
{\r
- LIST_ENTRY *Link;\r
- ONE_OF_OPTION_MAP *Map;\r
+ UINTN Index;\r
+ TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
\r
- Link = GetFirstNode (&ThunkContext->OneOfOptionMapListHead);\r
+ ASSERT (Packages != NULL);\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
+ 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_FORMS:\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
- Link = GetNextNode (&ThunkContext->OneOfOptionMapListHead, Link);\r
}\r
- \r
+\r
return NULL;\r
}\r
\r
+/**\r
+ Get FormSet GUID.\r
+\r
+ ASSERT if no FormSet Opcode is found.\r
\r
-EFI_STATUS\r
-CreateQuestionIdMap (\r
- IN OUT HII_THUNK_CONTEXT *ThunkContext\r
+ @param Packages Form Framework Package.\r
+ @param FormSetGuid Return the FormSet Guid.\r
+\r
+**/\r
+VOID\r
+GetFormSetGuid (\r
+ IN EFI_HII_PACKAGE_HEADER *Package,\r
+ OUT EFI_GUID *FormSetGuid\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_OP_HEADER *OpCode;\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
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset < Package->Length) {\r
+ OpCode = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + Offset);\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
+ 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
- // Skip the package list header.\r
+ // A proper IFR must have a formset opcode.\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
+ ASSERT (FALSE);\r
\r
- FreePool (List);\r
- return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Creat a Thunk Context.\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
+ ASSERT if no FormSet Opcode is found.\r
\r
+ @param Private The HII Thunk Private Context.\r
+ @param StringPackageCount The String package count.\r
+ @param FormSetGuid The IFR Package count.\r
\r
+ @return A newly created Thunk Context.\r
+ @retval NULL No resource to create a new Thunk Context.\r
+**/\r
HII_THUNK_CONTEXT *\r
CreateThunkContext (\r
IN HII_THUNK_PRIVATE_DATA *Private,\r
return NULL;\r
}\r
\r
- InitializeListHead (&ThunkContext->QuestionIdMapListHead);\r
- InitializeListHead (&ThunkContext->OneOfOptionMapListHead);\r
-\r
-\r
return ThunkContext;\r
\r
}\r
\r
+/**\r
+ Destroy the Thunk Context and free up all resource.\r
+\r
+ @param ThunkContext The HII Thunk Private Context to be freed.\r
+\r
+**/\r
VOID\r
DestroyThunkContext (\r
IN HII_THUNK_CONTEXT *ThunkContext\r
\r
FreeHiiHandle (ThunkContext->FwHiiHandle);\r
\r
- DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);\r
-\r
- DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);\r
-\r
RemoveEntryList (&ThunkContext->Link);\r
\r
+ if (ThunkContext->FormSet != NULL) {\r
+ DestroyFormSet (ThunkContext->FormSet);\r
+ }\r
+\r
FreePool (ThunkContext);\r
}\r
\r
+/**\r
+ Get the FormSet's Default Varstore ID based on the rule (Descending Priority):\r
+\r
+ 1) Var Store ID of FRAMEWORK_RESERVED_VARSTORE_ID (0x01).\r
+ 2) First Var Store ID.\r
\r
+ @param FormSet The Form Set.\r
+ \r
+**/\r
VOID\r
-DestroyQuestionIdMap (\r
- IN LIST_ENTRY *QuestionIdMapListHead\r
+GetFormsetDefaultVarstoreId (\r
+ IN OUT FORM_BROWSER_FORMSET * FormSet\r
)\r
{\r
- QUESTION_ID_MAP *IdMap;\r
- QUESTION_ID_MAP_ENTRY *IdMapEntry;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *Link2;\r
+ LIST_ENTRY *StorageList;\r
+ FORMSET_STORAGE *Storage;\r
\r
- while (!IsListEmpty (QuestionIdMapListHead)) {\r
- Link = GetFirstNode (QuestionIdMapListHead);\r
- \r
- IdMap = QUESTION_ID_MAP_FROM_LINK (Link);\r
+ //\r
+ // VarStoreId 0 is invalid in UEFI IFR.\r
+ //\r
+ FormSet->DefaultVarStoreId = 0;\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
\r
- while (!IsListEmpty (&IdMap->MapEntryListHead)) {\r
- Link2 = GetFirstNode (&IdMap->MapEntryListHead);\r
- \r
- IdMapEntry = QUESTION_ID_MAP_ENTRY_FROM_LINK (Link);\r
+ while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
\r
- RemoveEntryList (Link2);\r
+ DEBUG ((EFI_D_INFO, "FormSet %g: Found Varstore ID %x\n", &FormSet->Guid, Storage->VarStoreId));\r
\r
- FreePool (IdMapEntry);\r
+ if (Storage->VarStoreId == FRAMEWORK_RESERVED_VARSTORE_ID) {\r
+ FormSet->DefaultVarStoreId = FRAMEWORK_RESERVED_VARSTORE_ID;\r
+ break;\r
}\r
\r
- RemoveEntryList (Link);\r
- FreePool (IdMap);\r
+ StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
}\r
+\r
+ if (FormSet->DefaultVarStoreId != FRAMEWORK_RESERVED_VARSTORE_ID) {\r
+ StorageList = GetFirstNode (&FormSet->StorageListHead);\r
+ if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
+ Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
+ FormSet->DefaultVarStoreId = Storage->VarStoreId;\r
+ }\r
+ \r
+ }\r
+\r
+ DEBUG_CODE_BEGIN ();\r
+ if (FormSet->DefaultVarStoreId == 0) {\r
+ DEBUG ((EFI_D_INFO, "FormSet %g: No Varstore Found\n", &FormSet->Guid));\r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "FormSet %g: Default Varstore ID is %x\n", &FormSet->Guid, FormSet->DefaultVarStoreId));\r
+ }\r
+ DEBUG_CODE_END ();\r
+ \r
+ return;\r
}\r
\r
-VOID\r
-DestoryOneOfOptionMap (\r
- IN LIST_ENTRY *OneOfOptionMapListHead\r
+/**\r
+ Fetch the Ifr binary data of a FormSet.\r
+\r
+ @param Handle PackageList Handle\r
+ @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
+ GUID), take the first FormSet found in package\r
+ list.\r
+ @param BinaryLength The length of the FormSet IFR binary.\r
+ @param BinaryData The buffer designed to receive the FormSet.\r
+\r
+ @retval EFI_SUCCESS Buffer filled with the requested FormSet.\r
+ BufferLength was updated.\r
+ @retval EFI_INVALID_PARAMETER The handle is unknown.\r
+ @retval EFI_NOT_FOUND A form or FormSet on the requested handle cannot\r
+ be found with the requested FormId.\r
+\r
+**/\r
+EFI_STATUS\r
+GetIfrBinaryData (\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN OUT EFI_GUID *FormSetGuid,\r
+ OUT UINTN *BinaryLength,\r
+ OUT UINT8 **BinaryData\r
)\r
{\r
- ONE_OF_OPTION_MAP *Map;\r
- ONE_OF_OPTION_MAP_ENTRY *MapEntry;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *Link2;\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ UINT8 *Package;\r
+ UINT8 *OpCodeData;\r
+ UINT32 Offset;\r
+ UINT32 Offset2;\r
+ BOOLEAN ReturnDefault;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+\r
+ OpCodeData = NULL;\r
+ Package = NULL;\r
+ ZeroMem (&PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));;\r
\r
- while (!IsListEmpty (OneOfOptionMapListHead)) {\r
- Link = GetFirstNode (OneOfOptionMapListHead);\r
- \r
- Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);\r
+ //\r
+ // if FormSetGuid is NULL or zero GUID, return first FormSet in the package list\r
+ //\r
+ if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {\r
+ ReturnDefault = TRUE;\r
+ } else {\r
+ ReturnDefault = FALSE;\r
+ }\r
\r
- while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {\r
- Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);\r
- \r
- MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link);\r
+ //\r
+ // Get HII PackageList\r
+ //\r
+ BufferSize = 0;\r
+ HiiPackageList = NULL;\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocatePool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get Form package from this HII package List\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ Offset2 = 0;\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+\r
+ while (Offset < PackageListLength) {\r
+ Package = ((UINT8 *) HiiPackageList) + Offset;\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+ //\r
+ // Search FormSet in this Form Package\r
+ //\r
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset2 < PackageHeader.Length) {\r
+ OpCodeData = Package + Offset2;\r
+\r
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+ //\r
+ // Check whether return default FormSet\r
+ //\r
+ if (ReturnDefault) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // FormSet GUID is specified, check it\r
+ //\r
+ if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ break;\r
+ }\r
+ }\r
\r
- RemoveEntryList (Link2);\r
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
+ }\r
\r
- FreePool (MapEntry);\r
+ if (Offset2 < PackageHeader.Length) {\r
+ //\r
+ // Target formset found\r
+ //\r
+ break;\r
+ }\r
}\r
\r
- RemoveEntryList (Link);\r
- FreePool (Map);\r
+ Offset += PackageHeader.Length;\r
+ }\r
+\r
+ if (Offset >= PackageListLength) {\r
+ //\r
+ // Form package not found in this Package List\r
+ //\r
+ gBS->FreePool (HiiPackageList);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (ReturnDefault && FormSetGuid != NULL) {\r
+ //\r
+ // Return the default FormSet GUID\r
+ //\r
+ CopyMem (FormSetGuid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
+ }\r
+\r
+ //\r
+ // To determine the length of a whole FormSet IFR binary, one have to parse all the Opcodes\r
+ // in this FormSet; So, here just simply copy the data from start of a FormSet to the end\r
+ // of the Form Package.\r
+ //\r
+ *BinaryLength = PackageHeader.Length - Offset2;\r
+ *BinaryData = AllocateCopyPool (*BinaryLength, OpCodeData);\r
+\r
+ gBS->FreePool (HiiPackageList);\r
+\r
+ if (*BinaryData == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Initialize the internal data structure of a FormSet.\r
+\r
+ @param Handle PackageList Handle\r
+ @param FormSetGuid GUID of a formset. If not specified (NULL or zero\r
+ GUID), take the first FormSet found in package\r
+ list.\r
+ @param FormSet FormSet data structure.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The specified FormSet could not be found.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeFormSet (\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN OUT EFI_GUID *FormSetGuid,\r
+ OUT FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ FormSet->HiiHandle = Handle;\r
+ CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));\r
+\r
+ //\r
+ // Parse the IFR binary OpCodes\r
+ //\r
+ Status = ParseOpCodes (FormSet);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
+\r
+ GetFormsetDefaultVarstoreId (FormSet);\r
+ return Status;\r
}\r
\r
+/**\r
+ Parse the Form Package and build a FORM_BROWSER_FORMSET structure.\r
+\r
+ @param UefiHiiHandle PackageList Handle\r
+\r
+ @return A pointer to FORM_BROWSER_FORMSET.\r
+\r
+**/\r
+FORM_BROWSER_FORMSET *\r
+ParseFormSet (\r
+ IN EFI_HII_HANDLE UefiHiiHandle\r
+ )\r
+{\r
+ FORM_BROWSER_FORMSET *FormSet;\r
+ EFI_GUID FormSetGuid;\r
+ EFI_STATUS Status;\r
+ \r
+ FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); \r
+ ASSERT (FormSet != NULL);\r
\r
+ CopyGuid (&FormSetGuid, &gZeroGuid);\r
+ Status = InitializeFormSet (UefiHiiHandle, &FormSetGuid, FormSet);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
+ return FormSet;\r
+}\r
\r