/**@file\r
-\r
- This file contains the keyboard processing code to the HII database.\r
+ Implement protocol interface related to package registrations.\r
\r
Copyright (c) 2006 - 2008, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
#include "HiiDatabase.h"\r
\r
\r
-BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
-BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
+STATIC BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
+STATIC BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
+BOOLEAN mInFrameworkUpdatePakcage = FALSE;\r
\r
\r
EFI_STATUS\r
-GetIfrAndStringPackNum (\r
+GetPackageCount (\r
IN CONST EFI_HII_PACKAGES *Packages,\r
- UINTN *IfrPackNum,\r
- UINTN *StringPackNum\r
+ UINTN *IfrPackageCount,\r
+ UINTN *StringPackageCount\r
)\r
{\r
UINTN Index;\r
TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
\r
ASSERT (Packages != NULL);\r
- ASSERT (IfrPackNum != NULL);\r
- ASSERT (StringPackNum != NULL);\r
+ ASSERT (IfrPackageCount != NULL);\r
+ ASSERT (StringPackageCount != NULL);\r
\r
- *IfrPackNum = 0;\r
- *StringPackNum = 0;\r
+ *IfrPackageCount = 0;\r
+ *StringPackageCount = 0;\r
\r
TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));\r
+ \r
for (Index = 0; Index < Packages->NumberOfPackages; Index++) {\r
//\r
// BugBug: The current UEFI HII build tool generate a binary in the format defined in: \r
// TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in\r
- // this binary is with same package type. So the returned IfrPackNum and StringPackNum\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
- *IfrPackNum += 1;\r
+ *IfrPackageCount += 1;\r
break;\r
case EFI_HII_PACKAGE_STRINGS:\r
- *StringPackNum += 1;\r
+ *StringPackageCount += 1;\r
break;\r
\r
case EFI_HII_PACKAGE_SIMPLE_FONTS:\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS \r
-LibExportPackageLists (\r
- IN EFI_HII_HANDLE UefiHiiHandle,\r
- OUT EFI_HII_PACKAGE_LIST_HEADER **PackageListHeader,\r
- OUT UINTN *PackageListSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Size;\r
- EFI_HII_PACKAGE_LIST_HEADER *PackageListHdr;\r
-\r
- ASSERT (PackageListSize != NULL);\r
- ASSERT (PackageListHeader != NULL);\r
-\r
- Size = 0;\r
- PackageListHdr = NULL;\r
- Status = mHiiDatabase->ExportPackageLists (\r
- mHiiDatabase,\r
- UefiHiiHandle,\r
- &Size,\r
- PackageListHdr\r
- );\r
- ASSERT_EFI_ERROR (Status == EFI_BUFFER_TOO_SMALL);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- PackageListHdr = AllocateZeroPool (Size);\r
- ASSERT (PackageListHdr != NULL);\r
- \r
- if (PackageListHeader == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- } else {\r
- Status = mHiiDatabase->ExportPackageLists (\r
- mHiiDatabase,\r
- UefiHiiHandle,\r
- &Size,\r
- PackageListHdr\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- *PackageListHeader = PackageListHdr;\r
- *PackageListSize = Size;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-InsertStringPackagesToIfrPackageList (\r
- IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader,\r
- IN EFI_HII_HANDLE UefiHiiHandle \r
- )\r
-{\r
- EFI_STATUS Status;\r
- Status = mHiiDatabase->UpdatePackageList (\r
- mHiiDatabase,\r
- UefiHiiHandle,\r
- StringPackageListHeader\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-\r
/**\r
Removes a node from a doubly linked list, and returns the node that follows\r
the removed node.\r
\r
**/\r
EFI_STATUS\r
-AddStringPackagesToMatchingIfrPackageList (\r
- IN EFI_HII_THUNK_PRIVATE_DATA *Private,\r
+FindPackListWithOnlyIfrPackAndAddStringPack (\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN HII_THUNK_CONTEXT *StringPackageThunkContext,\r
IN CONST EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader\r
)\r
{\r
EFI_STATUS Status;\r
- LIST_ENTRY *ListEntry;\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\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
- if (CompareGuid (&StringPackageListHeader->PackageListGuid, &HandleMapEntry->TagGuid)) {\r
- Status = InsertStringPackagesToIfrPackageList (StringPackageListHeader, HandleMapEntry->UefiHiiHandle);\r
+ LIST_ENTRY *Link;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
+ while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+\r
+ ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+ if (StringPackageThunkContext != ThunkContext) {\r
+ //\r
+ // Skip the String Package Thunk Entry itself.\r
+ //\r
+ \r
+ if (CompareGuid (&StringPackageListHeader->PackageListGuid, &ThunkContext->TagGuid)) {\r
+\r
+ ASSERT (ThunkContext->StringPackageCount == 0 && ThunkContext->IfrPackageCount == 1);\r
+\r
+ ThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
+ \r
+ Status = mHiiDatabase->UpdatePackageList (\r
+ mHiiDatabase,\r
+ ThunkContext->UefiHiiHandle,\r
+ StringPackageListHeader\r
+ );\r
+ ASSERT (Status != EFI_NOT_FOUND);\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
}\r
+ \r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
}\r
\r
+\r
return EFI_NOT_FOUND;\r
}\r
+\r
+\r
EFI_HII_PACKAGE_LIST_HEADER *\r
PrepareUefiPackageListFromFrameworkHiiPackages (\r
IN CONST EFI_HII_PACKAGES *Packages,\r
}\r
\r
EFI_STATUS\r
-FindAndAddStringPackageToIfrPackageList(\r
- EFI_HII_THUNK_PRIVATE_DATA *Private,\r
- EFI_GUID *GuidId,\r
- EFI_HII_HANDLE UefiIfrHiiHandle\r
+FindStringPackAndAddToPackListWithOnlyIfrPack(\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN HII_THUNK_CONTEXT *IfrThunkContext\r
)\r
{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *ListEntry;\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
- EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
- UINTN Size;\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
- if (CompareGuid (GuidId, &HandleMapEntry->TagGuid) && (!HandleMapEntry->DoesPackageListImportStringPackages)) {\r
- Status = LibExportPackageLists (HandleMapEntry->UefiHiiHandle, &StringPackageListHeader, &Size);\r
- ASSERT_EFI_ERROR (Status);\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ EFI_HII_PACKAGE_LIST_HEADER *StringPackageListHeader;\r
+ UINTN Size;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
\r
- //\r
- // Add Function to only get only String Packages from the Package List\r
- //\r
+ \r
+ Link = GetFirstNode (&Private->ThunkContextListHead);\r
+\r
+ while (!IsNull (&Private->ThunkContextListHead, Link)) {\r
+\r
+ ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);\r
+\r
+ if (ThunkContext != IfrThunkContext) {\r
+ if (CompareGuid (&IfrThunkContext->TagGuid, &ThunkContext->TagGuid) && (ThunkContext->IfrPackageCount == 0)) {\r
+ Status = HiiLibExportPackageLists (ThunkContext->UefiHiiHandle, &StringPackageListHeader, &Size);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ IfrThunkContext->StringPackageCount = GetPackageCountByType (StringPackageListHeader, EFI_HII_PACKAGE_STRINGS);\r
+ //\r
+ // Add Function to only get only String Packages from the Package List\r
+ //\r
+ Status = mHiiDatabase->UpdatePackageList (\r
+ mHiiDatabase,\r
+ IfrThunkContext->UefiHiiHandle,\r
+ StringPackageListHeader\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ FreePool (StringPackageListHeader);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
\r
- Status = InsertStringPackagesToIfrPackageList (StringPackageListHeader, UefiIfrHiiHandle);\r
- ASSERT_EFI_ERROR (Status);\r
+ Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\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 = AssignFrameworkHiiHandle (Private, TRUE, &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
+FreeFrameworkHiiHandle (\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN FRAMEWORK_EFI_HII_HANDLE FwHandle\r
+ )\r
+{\r
+ //\r
+ // TODO: \r
+ //\r
+ \r
+ return;\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
- FreePool (StringPackageListHeader);\r
- return EFI_SUCCESS;\r
+ MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link);\r
+\r
+ RemoveEntryList (Link2);\r
+\r
+ FreePool (MapEntry);\r
}\r
+\r
+ RemoveEntryList (Link);\r
+ FreePool (Map);\r
}\r
+}\r
\r
- return EFI_NOT_FOUND;\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 (Link);\r
+\r
+ RemoveEntryList (Link2);\r
+\r
+ FreePool (IdMapEntry);\r
+ }\r
+\r
+ RemoveEntryList (Link);\r
+ FreePool (IdMap);\r
+ }\r
+}\r
+\r
+VOID\r
+DestroyThunkContext (\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN HII_THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ ASSERT (ThunkContext != NULL);\r
+\r
+ FreeFrameworkHiiHandle (Private, ThunkContext->FwHiiHandle);\r
+\r
+ DestroyQuestionIdMap (&ThunkContext->QuestionIdMapListHead);\r
+\r
+ DestoryOneOfOptionMap (&ThunkContext->OneOfOptionMapListHead);\r
+\r
+ FreePool (ThunkContext);\r
}\r
\r
CONST EFI_GUID mAGuid = \r
\r
EFI_STATUS\r
UefiRegisterPackageList(\r
- EFI_HII_THUNK_PRIVATE_DATA *Private,\r
- EFI_HII_PACKAGES *Packages,\r
- FRAMEWORK_EFI_HII_HANDLE *Handle\r
+ IN HII_THUNK_PRIVATE_DATA *Private,\r
+ IN EFI_HII_PACKAGES *Packages,\r
+ OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN StringPackNum;\r
- UINTN IfrPackNum;\r
- EFI_HII_PACKAGE_LIST_HEADER *UefiPackageListHeader;\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMappingEntry;\r
+ UINTN StringPackageCount;\r
+ UINTN IfrPackageCount;\r
+ EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
EFI_GUID GuidId;\r
\r
- UefiPackageListHeader = NULL;\r
+ PackageListHeader = NULL;\r
\r
- Status = GetIfrAndStringPackNum (Packages, &IfrPackNum, &StringPackNum);\r
+ Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount);\r
ASSERT_EFI_ERROR (Status);\r
- //\r
- // Thunk Layer only handle the following combinations of IfrPack, StringPkg and FontPack.\r
- // Thunk Layer only allow zero or one IfrPack in the Package List.\r
- //\r
- if (IfrPackNum > 1) {\r
+ \r
+ if (IfrPackageCount > 1) {\r
+ //\r
+ // HII Thunk only handle package with 0 or 1 IFR package. \r
+ //\r
return EFI_UNSUPPORTED;\r
}\r
\r
- HandleMappingEntry = AllocateZeroPool (sizeof (*HandleMappingEntry));\r
- ASSERT (HandleMappingEntry != NULL);\r
- \r
- HandleMappingEntry->Signature = HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY_SIGNATURE;\r
- Status = AssignHiiHandle (Private, &HandleMappingEntry->FrameworkHiiHandle);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
+ ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);\r
+ if (ThunkContext == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- //\r
- // Packages->GuidId may be NULL. In such case, caller of FramworkHii->NewPack is registering\r
- // package with StringPack and IfrPack.\r
- //\r
if (Packages->GuidId == NULL) {\r
+ //\r
+ // UEFI HII Database require Package List GUID must be unique.\r
+ //\r
+ // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering\r
+ // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is\r
+ // not used as the name of the package list. A GUID is generated as a Package List\r
+ // GUID.\r
+ //\r
+ ASSERT (StringPackageCount >=1 && IfrPackageCount == 1);\r
Packages->GuidId = &GuidId;\r
GenerateGuidId (&mAGuid, Packages->GuidId);\r
} else {\r
+ //BugBug We need fix this.\r
+ //ASSERT (StringPackageCount == 0 || IfrPackageCount == 0);\r
CopyGuid (&GuidId, Packages->GuidId);\r
}\r
- \r
- CopyGuid (&HandleMappingEntry->TagGuid, Packages->GuidId);\r
\r
- if ((StringPackNum == 0) && (IfrPackNum != 0)) {\r
+ //\r
+ // Record the Package List GUID, it is used as a name for the package list by Framework HII.\r
+ //\r
+ CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
+\r
+ if ((StringPackageCount == 0) && (IfrPackageCount != 0)) {\r
//\r
// UEFI HII database does not allow two package list with the same GUID.\r
// In Framework HII implementation, Packages->GuidId is used as an identifier to associate \r
// UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
// that Setup Utility can load the Buffer Storage using this protocol.\r
//\r
- if (IfrPackNum != 0) {\r
- InstallDefaultUefiConfigAccessProtocol (Packages, HandleMappingEntry);\r
+ if (IfrPackageCount != 0) {\r
+ InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
}\r
- UefiPackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
+ PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
Status = mHiiDatabase->NewPackageList (\r
mHiiDatabase,\r
- UefiPackageListHeader, \r
- HandleMappingEntry->UefiHiiDriverHandle,\r
- &HandleMappingEntry->UefiHiiHandle\r
+ PackageListHeader, \r
+ ThunkContext->UefiHiiDriverHandle,\r
+ &ThunkContext->UefiHiiHandle\r
);\r
+\r
+ //\r
+ // BUGBUG: Remove when development is done\r
+ //\r
ASSERT_EFI_ERROR (Status);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (IfrPackNum == 0) {\r
- if (StringPackNum != 0) {\r
+ if (IfrPackageCount == 0) {\r
+ if (StringPackageCount != 0) {\r
//\r
- // Look for a package list with IFR Pack which has already registed with HII Database\r
+ // Find if there is Package List with only IFR Package in the databasee with the same\r
+ // tag. If found, add the String Package to this Package List.\r
//\r
- HandleMappingEntry->IsPackageListWithOnlyStringPackages = TRUE;\r
- Status = AddStringPackagesToMatchingIfrPackageList (\r
+ Status = FindPackListWithOnlyIfrPackAndAddStringPack (\r
Private,\r
- UefiPackageListHeader\r
+ ThunkContext,\r
+ PackageListHeader\r
);\r
\r
- if (!EFI_ERROR (Status) || Status == EFI_NOT_FOUND) {\r
-\r
- if (Status == EFI_NOT_FOUND) {\r
- Status = EFI_SUCCESS;\r
- }\r
+ if (Status == EFI_NOT_FOUND) {\r
+ Status = EFI_SUCCESS;\r
}\r
}\r
} else {\r
- if (StringPackNum == 0) {\r
+ CreateQuestionIdMap (ThunkContext);\r
+ \r
+ if (StringPackageCount == 0) {\r
//\r
// Register the Package List to UEFI HII first.\r
//\r
- Status = FindAndAddStringPackageToIfrPackageList (\r
+ Status = FindStringPackAndAddToPackListWithOnlyIfrPack (\r
Private,\r
- Packages->GuidId,\r
- HandleMappingEntry->UefiHiiHandle\r
+ ThunkContext\r
);\r
ASSERT_EFI_ERROR (Status);\r
- if (!EFI_ERROR (Status)) {\r
- HandleMappingEntry->DoesPackageListImportStringPackages = TRUE;\r
- }\r
}\r
}\r
\r
- if (!EFI_ERROR (Status)) {\r
- InsertTailList (&Private->HiiThunkHandleMappingDBListHead, &HandleMappingEntry->List);\r
- }\r
-\r
Done:\r
if (EFI_ERROR (Status)) {\r
- FreePool (HandleMappingEntry);\r
+ DestroyThunkContext (Private, ThunkContext);\r
} else {\r
- *Handle = HandleMappingEntry->FrameworkHiiHandle;\r
+ InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
+ *Handle = ThunkContext->FwHiiHandle;\r
}\r
\r
- SafeFreePool (UefiPackageListHeader);\r
+ SafeFreePool (PackageListHeader);\r
\r
return Status;\r
}\r
--*/\r
{\r
EFI_STATUS Status;\r
- EFI_HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
EFI_TPL OldTpl;\r
\r
if (Handle == NULL) {\r
//\r
mInFrameworkHiiNewPack = TRUE;\r
\r
- Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+ Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
\r
Status = UefiRegisterPackageList (\r
Private,\r
--*/\r
{\r
EFI_STATUS Status;\r
- EFI_HII_THUNK_PRIVATE_DATA *Private;\r
- HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
EFI_TPL OldTpl;\r
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
\r
mInFrameworkHiiRemovePack = TRUE;\r
\r
- Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
+ Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
\r
- HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
+ ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
\r
- if (HandleMapEntry != NULL) {\r
+ if (ThunkContext != NULL) {\r
Status = mHiiDatabase->RemovePackageList (\r
mHiiDatabase,\r
- HandleMapEntry->UefiHiiHandle\r
+ ThunkContext->UefiHiiHandle\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- HiiLibDestroyHiiDriverHandle (HandleMapEntry->UefiHiiHandle);\r
-\r
- Status = gBS->HandleProtocol (\r
- HandleMapEntry->UefiHiiDriverHandle,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- (VOID **) &ConfigAccess\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->UninstallProtocolInterface (\r
- HandleMapEntry->UefiHiiDriverHandle,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- ConfigAccess\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- } else {\r
- Status = EFI_SUCCESS;\r
+ if (ThunkContext->IfrPackageCount != 0) {\r
+ UninstallDefaultConfigAccessProtocol (ThunkContext);\r
}\r
\r
- RemoveEntryList (&HandleMapEntry->List);\r
-\r
- FreePool (HandleMapEntry);\r
+ RemoveEntryList (&ThunkContext->Link);\r
\r
+ DestroyThunkContext (Private, ThunkContext);\r
}else {\r
Status = EFI_NOT_FOUND;\r
}\r
\r
return Status;\r
}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+NewOrAddPackNotify (\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT *ThunkContext;\r
+\r
+ ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS || PackageType == EFI_HII_PACKAGE_FORM);\r
+ ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK);\r
+\r
+ Status = EFI_SUCCESS;\r
+ Private = mHiiThunkPrivateData;\r
+\r
+ if (mInFrameworkHiiNewPack || mInFrameworkUpdatePakcage) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // We only create a ThunkContext if the Uefi Hii Handle is only already registered\r
+ // by the HII Thunk Layer.\r
+ //\r
+ ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
+ if (ThunkContext == NULL) {\r
+ ThunkContext = CreateThunkContextForUefiHiiHandle (Private, Handle);\r
+ ASSERT (ThunkContext != NULL);\r
+ } \r
+\r
+\r
+ if (PackageType == EFI_HII_PACKAGE_FORM) {\r
+ Status = CreateQuestionIdMap (ThunkContext);\r
+ }\r
+\r
+ return Status; \r
+}\r
+\r
+\r
+BOOLEAN\r
+IsRemovingLastStringPack (\r
+ IN EFI_HII_HANDLE Handle\r
+ )\r
+{\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ EFI_STATUS Status;\r
+ EFI_HII_PACKAGE_HEADER *PackageHeader;\r
+ UINTN StringPackageCount;\r
+\r
+ HiiPackageList = NULL;\r
+ BufferSize = 0;\r
+ StringPackageCount = 0;\r
+\r
+ Status = HiiLibExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) HiiPackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
+\r
+ while (PackageHeader->Type != EFI_HII_PACKAGE_END) {\r
+ switch (PackageHeader->Type) {\r
+ case EFI_HII_PACKAGE_STRINGS:\r
+ StringPackageCount++;\r
+\r
+ if (StringPackageCount > 1) {\r
+ //\r
+ // More than one String Pack in the package list\r
+ //\r
+ FreePool (HiiPackageList);\r
+ return FALSE;\r
+ }\r
+ break; \r
+\r
+ default:\r
+ break;\r
+ }\r
+ //\r
+ // goto header of next package\r
+ //\r
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHeader + PackageHeader->Length);\r
+ }\r
+\r
+\r
+ //\r
+ // We will always be notified for the removal of String Pack from a package list.\r
+ // So StringPackageCount must be one at this point.\r
+ //\r
+ ASSERT (StringPackageCount == 1);\r
+ \r
+ FreePool (HiiPackageList);\r
+ return TRUE;\r
+}\r
+\r
+\r
+\r
+// Framework HII module may cache a GUID as the name of the package list.\r
+// Then search for the Framework HII handle database for the handle matching\r
+// this GUID\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+RemovePackNotify (\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ HII_THUNK_PRIVATE_DATA *Private;\r
+ HII_THUNK_CONTEXT * ThunkContext;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ ASSERT (PackageType == EFI_HII_PACKAGE_STRINGS);\r
+ ASSERT (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);\r
+\r
+ if (mInFrameworkHiiRemovePack || mInFrameworkUpdatePakcage) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Private = mHiiThunkPrivateData;\r
+\r
+ ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
+\r
+ if (ThunkContext->FwHiiHandle > Private->StaticHiiHandle) {\r
+ if (IsRemovingLastStringPack (Handle)) {\r
+ //\r
+ // If the string package will be removed is the last string package\r
+ // in the package list, we will remove the HII Thunk entry from the\r
+ // database.\r
+ //\r
+ Status = DestroyThunkContextForUefiHiiHandle (Private, Handle);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+\r