+++ /dev/null
-/** @file\r
- Implement protocol interface related to package registrations.\r
-\r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-\r
-#include "HiiDatabase.h"\r
-#include "HiiHandle.h"\r
-\r
-\r
-BOOLEAN mInFrameworkHiiNewPack = FALSE;\r
-BOOLEAN mInFrameworkHiiRemovePack = FALSE;\r
-BOOLEAN mInFrameworkUpdatePakcage = FALSE;\r
-UINT64 mGuidCount = 0;\r
-\r
-EFI_GUID mGuidBase = { 0x14f95e01, 0xd562, 0x432e, { 0x84, 0x4a, 0x95, 0xa4, 0x39, 0x5, 0x10, 0x7e }};\r
-\r
-\r
-\r
-/**\r
- Get the number of Form, STRING and Font packages in the package list passed in.\r
-\r
- @param Packages Package List.\r
- @param IfrPackageCount Number of IFR Packages.\r
- @param StringPackageCount Number of String Packages.\r
- @param FontPackageCount Number of Font Packages.\r
-\r
- @retval EFI_INVALID_PARAMETER If the Package List has package with type of \r
- EFI_HII_PACKAGE_KEYBOARD_LAYOUT, EFI_HII_PACKAGE_FONTS, EFI_HII_PACKAGE_IMAGES.\r
- @retval EFI_SUCCESS Successfully get the number of IFR and STRING package.\r
- \r
-\r
-**/\r
-EFI_STATUS\r
-GetPackageCount (\r
- IN CONST EFI_HII_PACKAGES *Packages,\r
- OUT UINTN *IfrPackageCount,\r
- OUT UINTN *StringPackageCount,\r
- OUT UINTN *FontPackageCount\r
- )\r
-{\r
- UINTN Index;\r
- TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
-\r
- ASSERT (Packages != NULL);\r
- ASSERT (IfrPackageCount != NULL);\r
- ASSERT (StringPackageCount != NULL);\r
- ASSERT (FontPackageCount != NULL);\r
-\r
- *IfrPackageCount = 0;\r
- *StringPackageCount = 0;\r
- *FontPackageCount = 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
- // 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]->FrameworkPackageHeader.Type) {\r
- case EFI_HII_IFR:\r
- *IfrPackageCount += 1;\r
- break;\r
- case EFI_HII_STRING:\r
- *StringPackageCount += 1;\r
- break;\r
-\r
- case EFI_HII_FONT:\r
- *FontPackageCount += 1;\r
- break;\r
-\r
- //\r
- // The following fonts are invalid for a module that using Framework to UEFI thunk layer.\r
- //\r
- default:\r
- ASSERT (FALSE);\r
- return EFI_INVALID_PARAMETER;\r
- break;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Insert the String Package into the Package Lists which has the TAG GUID matching\r
- the PackageListGuid of the String Package. \r
-\r
- The Package List must have only IFR Package and no String Package. \r
- Otherwise, ASSERT.\r
-\r
- @param Private The HII THUNK driver context data.\r
- @param StringPackageThunkContext The HII THUNK context data.\r
- @param StringPackageListHeader The String Package List Header.\r
- \r
-**/\r
-VOID\r
-UpdatePackListWithOnlyIfrPack (\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 *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_EFI_ERROR (Status);\r
-\r
- ThunkContext->SharingStringPack = TRUE;\r
- StringPackageThunkContext->SharingStringPack = TRUE;\r
-\r
- }\r
- }\r
- \r
- Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
- }\r
-\r
-}\r
-\r
-/**\r
- Caculate the size of UEFI Simple Font Package that is needed to \r
- convert all the font a Framework Font Paackage.\r
-\r
- ONLY Narrow Font is supported. Wide Font is discarded. \r
-\r
- If the Package Header is not of EFI_HII_FONT type, then ASSERT.\r
-\r
- @param PackHeader Pointer to Framework Font Package.\r
- \r
- @return The size of the UEFI Simple Font Package.\r
- \r
-**/\r
-UINTN\r
-GetUefiSimpleFontPackSize (\r
- IN CONST EFI_HII_PACK_HEADER * PackHeader\r
- )\r
-{\r
- UINTN Size;\r
- EFI_HII_FONT_PACK *FwFontPack;\r
-\r
- FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;\r
-\r
- ASSERT (FwFontPack->Header.Type == EFI_HII_FONT);\r
- \r
- Size = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR) \r
- + (FwFontPack->NumberOfNarrowGlyphs * sizeof (EFI_NARROW_GLYPH));\r
-\r
- return Size;\r
-}\r
-\r
-\r
-/**\r
- Convert Font Package in Framework format to a newly allocated UEFI\r
- Simple Font Package.\r
-\r
- ONLY Narrow Font is supported. Wide Font is discarded. \r
-\r
- If memory allocation fails, then ASSERT.\r
-\r
- @param PackHeader Pointer to Framework Font Package header.\r
-\r
- @return UEFI Simple Font Package.\r
-**/\r
-EFI_HII_SIMPLE_FONT_PACKAGE_HDR *\r
-FrameworkFontPackToUefiSimpliedFont (\r
- IN CONST EFI_HII_PACK_HEADER * PackHeader\r
- )\r
-{\r
- EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
- UINTN Size;\r
- EFI_NARROW_GLYPH *FwNarrowGlyph;\r
- EFI_NARROW_GLYPH *NarrowGlyph;\r
- UINTN Idx;\r
- EFI_HII_FONT_PACK *FwFontPack;\r
-\r
- Size = GetUefiSimpleFontPackSize (PackHeader);\r
-\r
- FwFontPack = (EFI_HII_FONT_PACK *) PackHeader;\r
-\r
- FontPack = AllocateZeroPool (Size);\r
- ASSERT (FontPack != NULL);\r
-\r
- //\r
- // Prepare the Header information.\r
- //\r
- FontPack->Header.Length = (UINT32) Size;\r
- FontPack->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;\r
-\r
- FontPack->NumberOfNarrowGlyphs = FwFontPack->NumberOfNarrowGlyphs;\r
- \r
- //\r
- // ONLY Narrow Font is supported. Wide Font is discarded. \r
- //\r
- FontPack->NumberOfWideGlyphs = 0;\r
- \r
- //\r
- // Copy Narrow Glyph\r
- //\r
- NarrowGlyph = (EFI_NARROW_GLYPH *) (FontPack + 1);\r
- FwNarrowGlyph = (EFI_NARROW_GLYPH *) (FwFontPack + 1);\r
- CopyMem (NarrowGlyph, FwNarrowGlyph, sizeof (EFI_NARROW_GLYPH) * FwFontPack->NumberOfNarrowGlyphs);\r
- for (Idx = 0; Idx < FwFontPack->NumberOfNarrowGlyphs; Idx++) {\r
- //\r
- // Clear the GLYPH_NON_BREAKING (EFI_GLYPH_WIDE is used here as they are all 0x02)\r
- // attribute which is not defined in UEFI EFI_NARROW_GLYPH\r
- //\r
- NarrowGlyph[Idx].Attributes = (UINT8) (NarrowGlyph[Idx].Attributes & ~(EFI_GLYPH_WIDE));\r
- }\r
-\r
- return FontPack;\r
-}\r
-\r
-/**\r
- Prepare a UEFI Package List from a Framework HII package list registered\r
- from a Framework HII NewPack () function.\r
-\r
- If either Packages or PackageListGuid is NULL, then ASSERT.\r
- \r
- @param Packages The Framework HII Package List.\r
- @param PackageListGuid The Package List GUID.\r
-\r
-\r
- @return The UEFI Package List. \r
-**/\r
-EFI_HII_PACKAGE_LIST_HEADER *\r
-PrepareUefiPackageListFromFrameworkHiiPackages (\r
- IN CONST EFI_HII_PACKAGES *Packages,\r
- IN CONST EFI_GUID *PackageListGuid\r
- )\r
-{\r
- UINTN NumberOfPackages;\r
- EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
- UINT8 *PackageListData;\r
- UINT32 PackageListLength;\r
- UINT32 PackageLength;\r
- EFI_HII_PACKAGE_HEADER PackageHeader;\r
- UINTN Index;\r
- TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;\r
- EFI_HII_SIMPLE_FONT_PACKAGE_HDR *FontPack;\r
- \r
-\r
- ASSERT (Packages != NULL);\r
- ASSERT (PackageListGuid != NULL);\r
-\r
- TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) ((UINT8 *) &Packages->GuidId + sizeof (Packages->GuidId));\r
- NumberOfPackages = Packages->NumberOfPackages;\r
-\r
- PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-\r
- for (Index = 0; Index < NumberOfPackages; Index++) {\r
- if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {\r
- //\r
- // There is no tool to generate Font package in Framework HII's implementation.\r
- // Therefore, Font Package be a C structure defined in Framework HII code. \r
- // Therefore, Font Package will be in Framework HII format defined by EFI_HII_FONT_PACK.\r
- // We need to create a UEFI Simple Font Package and copy over all data. Hence, EFI_HII_FONT\r
- // is handled differently than EFI_HII_IFR and EFI_HII_STRING.\r
- //\r
- PackageListLength = (UINT32) (PackageListLength + GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader));\r
- \r
- } else {\r
- //\r
- // For EFI_HII_IFR and EFI_HII_STRING, EDK II's VFR Compiler and Build.exe will generate a binary in a format\r
- // defined by TIANO_AUTOGEN_PACKAGES_HEADER. A Framework HII's EFI_HII_PACK_HEADER is inserted before\r
- // the UEFI package data.\r
- //\r
- CopyMem (&PackageLength, &TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length, sizeof (UINT32));\r
- //\r
- // EFI_HII_PACK_HEADER.FrameworkPackageHeader.Length include the sizeof FrameworkPackageHeader itself.\r
- //\r
- PackageListLength += (PackageLength - sizeof(EFI_HII_PACK_HEADER));\r
- \r
- }\r
- }\r
-\r
- //\r
- // Include the lenght of EFI_HII_PACKAGE_END\r
- //\r
- PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);\r
- PackageListHeader = AllocateZeroPool (PackageListLength);\r
- ASSERT (PackageListHeader != NULL);\r
-\r
- CopyMem (&PackageListHeader->PackageListGuid, PackageListGuid, sizeof (EFI_GUID));\r
- PackageListHeader->PackageLength = PackageListLength;\r
-\r
- PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
-\r
- //\r
- // Build the UEFI Package List.\r
- //\r
- for (Index = 0; Index < NumberOfPackages; Index++) {\r
- if (TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Type == EFI_HII_FONT) {\r
- PackageLength = (UINT32) GetUefiSimpleFontPackSize (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);\r
- FontPack = FrameworkFontPackToUefiSimpliedFont (&TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader);\r
- CopyMem (PackageListData, FontPack, PackageLength);\r
- FreePool (FontPack);\r
- \r
- } else {\r
- CopyMem (&PackageLength, &(TianoAutogenPackageHdrArray[Index]->FrameworkPackageHeader.Length), sizeof (UINT32));\r
- PackageLength -= sizeof (EFI_HII_PACK_HEADER);\r
- CopyMem (PackageListData, &(TianoAutogenPackageHdrArray[Index]->PackageHeader), PackageLength);\r
- \r
- }\r
- PackageListData += PackageLength;\r
- }\r
-\r
- //\r
- // Append EFI_HII_PACKAGE_END\r
- //\r
- PackageHeader.Type = EFI_HII_PACKAGE_END;\r
- PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
- CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);\r
-\r
- return PackageListHeader; \r
-}\r
-\r
-\r
-/**\r
- Generate a Random GUID.\r
- \r
- @param Guid On output, a Random GUID will be filled.\r
-\r
-**/\r
-VOID\r
-GenerateRandomGuid (\r
- OUT EFI_GUID * Guid\r
- )\r
-{\r
- CopyGuid (Guid, &mGuidBase);\r
-\r
- mGuidCount++; \r
- *((UINT64 *) Guid) = *((UINT64 *) Guid) + mGuidCount;\r
-}\r
-\r
-/**\r
- Given a Package List with only a IFR package, find the Package List that only has a String Package based on\r
- the TAG GUID. Then export the String Package from the Package List and insert it\r
- to the given IFR package.\r
-\r
- This is to handle the case of Framework HII interface which allow String Package\r
- and IFR package to be registered using two different NewPack () calls.\r
-\r
- @param Private The HII THUNK driver context data.\r
- @param IfrThunkContext Package List with only a IFR package.\r
-\r
- @retval EFI_SUCCESS If the String Package is found and inserted to the\r
- Package List with only a IFR package.\r
- @retval EFI_NOT_FOUND No String Package matching the TAG GUID is found.\r
-**/\r
-EFI_STATUS\r
-FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
- IN HII_THUNK_PRIVATE_DATA *Private,\r
- IN HII_THUNK_CONTEXT *IfrThunkContext\r
- )\r
-{\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
- 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
- StringPackageListHeader = NULL;\r
- Status = ExportPackageLists (ThunkContext->UefiHiiHandle, &StringPackageListHeader, &Size);\r
- ASSERT_EFI_ERROR (Status);\r
- if (StringPackageListHeader == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\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
-\r
- IfrThunkContext->SharingStringPack = TRUE;\r
- ThunkContext->SharingStringPack = TRUE;\r
- \r
- return EFI_SUCCESS;\r
-\r
- }\r
- }\r
-\r
- Link = GetNextNode (&Private->ThunkContextListHead, Link);\r
- }\r
-\r
- //\r
- // A Form Package must have a String Package to function.\r
- // If ASSERT here, check the sequence of call to Hii->NewPack. \r
- // String Pack must be registered before Ifr Package is registered.\r
- //\r
- ASSERT (FALSE);\r
- return EFI_NOT_FOUND;\r
- \r
-}\r
-\r
-\r
-/**\r
- Register the Package List passed from the Framework HII NewPack () interface.\r
- The FRAMEWORK_EFI_HII_HANDLE will be returned.\r
-\r
- @param This The EFI_HII_PROTOCOL context data. Only used\r
- to call HiiRemovePack.\r
- @param Private The HII THUNK driver context data.\r
- @param Packages Package List.\r
- @param Handle On output, a FRAMEWORK_EFI_HII_HANDLE number is\r
- returned.\r
-\r
- @retval EFI_SUCCESS The Package List is registered successfully in\r
- the database.\r
- @retval EFI_UNSUPPORTED The number of IFR package in the package list\r
- is greater than 1.\r
- @retval EFI_OUT_OF_RESOURCE Not enough resouce.\r
- \r
-**/\r
-EFI_STATUS\r
-UefiRegisterPackageList (\r
- IN EFI_HII_PROTOCOL *This,\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 StringPackageCount;\r
- UINTN IfrPackageCount;\r
- UINTN FontPackageCount;\r
- EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
- HII_THUNK_CONTEXT *ThunkContextToRemove;\r
- EFI_GUID GuidId;\r
- EFI_HII_PACKAGE_HEADER *IfrPackage;\r
-\r
- PackageListHeader = NULL;\r
-\r
- Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount);\r
- ASSERT_EFI_ERROR (Status);\r
- \r
- if (IfrPackageCount > 1) {\r
- //\r
- // HII Thunk only handle package with 0 or 1 IFR package. \r
- //\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount);\r
- if (ThunkContext == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ThunkContext->ByFrameworkHiiNewPack = TRUE;\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. Formset GUID is used as the Package List\r
- // GUID instead.\r
- //\r
- ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0));\r
- if (IfrPackageCount > 0) {\r
- IfrPackage = GetIfrPackage (Packages);\r
- if (IfrPackage == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
- }\r
- GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid);\r
- } else {\r
- ASSERT (FontPackageCount > 0);\r
- GenerateRandomGuid (&ThunkContext->TagGuid);\r
- }\r
- \r
- } else {\r
- ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId);\r
- \r
- if (IfrPackageCount > 0 && \r
- StringPackageCount > 0 && \r
- (ThunkContextToRemove != NULL)) {\r
- DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n"));\r
- DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n"));\r
- HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle);\r
- }\r
- CopyGuid (&ThunkContext->TagGuid, Packages->GuidId);\r
- \r
- }\r
-\r
- //\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. An UEFI VFR can only\r
- // produce IFR package generated with Buffer Storage type and EFI Variable Storage.\r
- // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage.\r
- //\r
- if (IfrPackageCount != 0) {\r
- InstallDefaultConfigAccessProtocol (Packages, ThunkContext);\r
- }\r
- \r
- PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid);\r
- Status = mHiiDatabase->NewPackageList (\r
- mHiiDatabase,\r
- PackageListHeader, \r
- ThunkContext->UefiHiiDriverHandle,\r
- &ThunkContext->UefiHiiHandle\r
- );\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- FreePool (PackageListHeader);\r
- \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
- // a PackageList with only IFR to a Package list the with String package.\r
- //\r
- GenerateRandomGuid (&GuidId);\r
-\r
- PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId);\r
- Status = mHiiDatabase->NewPackageList (\r
- mHiiDatabase,\r
- PackageListHeader, \r
- ThunkContext->UefiHiiDriverHandle,\r
- &ThunkContext->UefiHiiHandle\r
- );\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 (IfrPackageCount == 0) {\r
- if (StringPackageCount != 0) {\r
- //\r
- // Look for a Package List with only IFR Package with the same TAG GUID name.\r
- // If found one, add the String Packages to the found Package List.\r
- // This is needed because Framework HII Module may not register the String Package\r
- // and IFR Package in one NewPack () call.\r
- //\r
- UpdatePackListWithOnlyIfrPack (\r
- Private,\r
- ThunkContext,\r
- PackageListHeader\r
- );\r
- }\r
- } else {\r
- if (StringPackageCount == 0) {\r
- //\r
- // Look for the String Package with the same TAG GUID name and add\r
- // the found String Package to this Package List.\r
- // This is needed because Framework HII Module may not register the String Package\r
- // and IFR Package in one NewPack () call.\r
- //\r
- Status = FindStringPackAndUpdatePackListWithOnlyIfrPack (\r
- Private,\r
- ThunkContext\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
- \r
- //\r
- // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so\r
- // that String Package is ready.\r
- //\r
- ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
- ASSERT (ThunkContext->FormSet != NULL);\r
- \r
- }\r
-\r
-Done:\r
- if (EFI_ERROR (Status)) {\r
- DestroyThunkContext (ThunkContext);\r
- } else {\r
- InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
- *Handle = ThunkContext->FwHiiHandle;\r
- }\r
-\r
- if (PackageListHeader != NULL) {\r
- FreePool (PackageListHeader);\r
- }\r
- \r
- return Status;\r
-}\r
-\r
-\r
-/**\r
-\r
- Registers the various packages that are passed in a Package List.\r
-\r
- @param This Pointer of Frameowk HII protocol instance.\r
- @param Packages Pointer of HII packages.\r
- @param Handle Handle value to be returned.\r
-\r
- @retval EFI_SUCCESS Packages has added to HII database successfully.\r
- @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HiiNewPack (\r
- IN EFI_HII_PROTOCOL *This,\r
- IN EFI_HII_PACKAGES *Packages,\r
- OUT FRAMEWORK_EFI_HII_HANDLE *Handle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- HII_THUNK_PRIVATE_DATA *Private;\r
- EFI_TPL OldTpl;\r
-\r
- if (Handle == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Packages == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
- \r
- //\r
- // We use a simple Global variable to inform NewOrAddPackNotify()\r
- // that the package list registered here is already registered\r
- // in the HII Thunk Layer. So NewOrAddPackNotify () does not need to\r
- // call registered the Package List again.\r
- //\r
- mInFrameworkHiiNewPack = TRUE;\r
-\r
- Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- Status = UefiRegisterPackageList (\r
- This,\r
- Private,\r
- Packages,\r
- Handle\r
- );\r
-\r
- mInFrameworkHiiNewPack = FALSE;\r
-\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
-\r
- Remove a package from the HII database.\r
-\r
- @param This Pointer of Frameowk HII protocol instance.\r
- @param Handle Handle value to be removed.\r
-\r
- @retval EFI_SUCCESS Packages has added to HII database successfully.\r
- @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HiiRemovePack (\r
- IN EFI_HII_PROTOCOL *This,\r
- IN FRAMEWORK_EFI_HII_HANDLE Handle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- HII_THUNK_PRIVATE_DATA *Private;\r
- HII_THUNK_CONTEXT *ThunkContext;\r
- EFI_TPL OldTpl;\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
- mInFrameworkHiiRemovePack = TRUE;\r
-\r
- Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- ThunkContext = FwHiiHandleToThunkContext (Private, Handle);\r
-\r
- if (ThunkContext != NULL) {\r
- Status = mHiiDatabase->RemovePackageList (\r
- mHiiDatabase,\r
- ThunkContext->UefiHiiHandle\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- if (ThunkContext->IfrPackageCount != 0) {\r
- UninstallDefaultConfigAccessProtocol (ThunkContext);\r
- }\r
-\r
- DestroyThunkContext (ThunkContext);\r
- }else {\r
- Status = EFI_NOT_FOUND;\r
- }\r
-\r
- mInFrameworkHiiRemovePack = FALSE;\r
- gBS->RestoreTPL (OldTpl);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This notification function will be called when a Package List is registered\r
- using UEFI HII interface. The Package List registered need to be recorded in\r
- Framework Thunk module as Thunk Module may need to look for String Package in\r
- the package registered.\r
-\r
- If the Package List registered is not either Sting Package or IFR package, \r
- then ASSERT. If the NotifyType is not ADD_PACK or NEW_PACK, then ASSERT.\r
- Both cases means UEFI HII Database itself is buggy. \r
-\r
- @param PackageType The Package Type.\r
- @param PackageGuid The Package GUID.\r
- @param Package The Package Header.\r
- @param Handle The HII Handle of this Package List.\r
- @param NotifyType The reason of the notification. \r
-\r
- @retval EFI_SUCCESS The notification function is successful.\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_FORMS);\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 will create a ThunkContext to log the package list only if the\r
- // package is not registered with by Framework HII Thunk module yet.\r
- //\r
- ThunkContext = UefiHiiHandleToThunkContext (Private, Handle);\r
- if (ThunkContext == NULL) {\r
- ThunkContext = CreateThunkContextForUefiHiiHandle (Handle);\r
- ASSERT (ThunkContext != NULL);\r
-\r
- InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link);\r
- } \r
-\r
- if (PackageType == EFI_HII_PACKAGE_FORMS) {\r
- if (ThunkContext->FormSet != NULL) {\r
- DestroyFormSet (ThunkContext->FormSet);\r
- }\r
-\r
- //\r
- // Reparse the FormSet.\r
- //\r
- ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle);\r
- }\r
-\r
- return Status; \r
-}\r
-\r
-/**\r
- This notification function will be called when a Package List is removed\r
- using UEFI HII interface. The Package List removed need to be removed from\r
- Framework Thunk module too.\r
-\r
- If the Package List registered is not Sting Package, \r
- then ASSERT. If the NotifyType is not REMOVE_PACK, then ASSERT.\r
- Both cases means UEFI HII Database itself is buggy. \r
-\r
- @param PackageType The Package Type.\r
- @param PackageGuid The Package GUID.\r
- @param Package The Package Header.\r
- @param Handle The HII Handle of this Package List.\r
- @param NotifyType The reason of the notification. \r
-\r
- @retval EFI_SUCCESS The notification function is successful.\r
- \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
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
- UINTN BufferSize;\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
- //\r
- // BugBug: Change to ASSERT if HII Database fix the bug and to also invoke \r
- // NEW_PACK_NOTIFY for package (String Package) created internally.\r
- //\r
- if (ThunkContext != NULL) {\r
- if (!ThunkContext->ByFrameworkHiiNewPack) {\r
- HiiPackageList = NULL;\r
- Status = ExportPackageLists (Handle, &HiiPackageList, &BufferSize);\r
- ASSERT_EFI_ERROR (Status);\r
- if (HiiPackageList == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (GetPackageCountByType (HiiPackageList, EFI_HII_PACKAGE_STRINGS) == 1) {\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
- DestroyThunkContextForUefiHiiHandle (Private, Handle);\r
- }\r
-\r
- FreePool (HiiPackageList);\r
- }\r
- }\r
-\r
- \r
- return Status;\r
-}\r
-\r
-\r
-\r