/** Clean up the HII Thunk Context for a UEFI HII Handle. @param Private The HII Thunk Module Private context. @param UefiHiiHandle The UEFI HII Handle. **/ VOID DestroyThunkContextForUefiHiiHandle ( IN HII_THUNK_PRIVATE_DATA *Private, IN EFI_HII_HANDLE UefiHiiHandle ) { HII_THUNK_CONTEXT *ThunkContext; ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle); ASSERT (ThunkContext != NULL); DestroyThunkContext (ThunkContext); }
/** Remove a package from the HII database. @param This Pointer of Frameowk HII protocol instance. @param Handle Handle value to be removed. @retval EFI_SUCCESS Packages has added to HII database successfully. @retval EFI_INVALID_PARAMETER If Handle or Packages is NULL. **/ EFI_STATUS EFIAPI HiiRemovePack ( IN EFI_HII_PROTOCOL *This, IN FRAMEWORK_EFI_HII_HANDLE Handle ) { EFI_STATUS Status; HII_THUNK_PRIVATE_DATA *Private; HII_THUNK_CONTEXT *ThunkContext; EFI_TPL OldTpl; OldTpl = gBS->RaiseTPL (TPL_NOTIFY); mInFrameworkHiiRemovePack = TRUE; Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This); ThunkContext = FwHiiHandleToThunkContext (Private, Handle); if (ThunkContext != NULL) { Status = mHiiDatabase->RemovePackageList ( mHiiDatabase, ThunkContext->UefiHiiHandle ); ASSERT_EFI_ERROR (Status); if (ThunkContext->IfrPackageCount != 0) { UninstallDefaultConfigAccessProtocol (ThunkContext); } DestroyThunkContext (ThunkContext); }else { Status = EFI_NOT_FOUND; } mInFrameworkHiiRemovePack = FALSE; gBS->RestoreTPL (OldTpl); return Status; }
/** Register the Package List passed from the Framework HII NewPack () interface. The FRAMEWORK_EFI_HII_HANDLE will be returned. @param This The EFI_HII_PROTOCOL context data. Only used to call HiiRemovePack. @param Private The HII THUNK driver context data. @param Packages Package List. @param Handle On output, a FRAMEWORK_EFI_HII_HANDLE number is returned. @retval EFI_SUCCESS The Package List is registered successfully in the database. @retval EFI_UNSUPPORTED The number of IFR package in the package list is greater than 1. @retval EFI_OUT_OF_RESOURCE Not enough resouce. **/ EFI_STATUS UefiRegisterPackageList ( IN EFI_HII_PROTOCOL *This, IN HII_THUNK_PRIVATE_DATA *Private, IN EFI_HII_PACKAGES *Packages, OUT FRAMEWORK_EFI_HII_HANDLE *Handle ) { EFI_STATUS Status; UINTN StringPackageCount; UINTN IfrPackageCount; UINTN FontPackageCount; EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; HII_THUNK_CONTEXT *ThunkContext; HII_THUNK_CONTEXT *ThunkContextToRemove; EFI_GUID GuidId; EFI_HII_PACKAGE_HEADER *IfrPackage; PackageListHeader = NULL; Status = GetPackageCount (Packages, &IfrPackageCount, &StringPackageCount, &FontPackageCount); ASSERT_EFI_ERROR (Status); if (IfrPackageCount > 1) { // // HII Thunk only handle package with 0 or 1 IFR package. // ASSERT (FALSE); return EFI_UNSUPPORTED; } ThunkContext = CreateThunkContext (Private, StringPackageCount, IfrPackageCount); if (ThunkContext == NULL) { return EFI_OUT_OF_RESOURCES; } ThunkContext->ByFrameworkHiiNewPack = TRUE; if (Packages->GuidId == NULL) { // // UEFI HII Database require Package List GUID must be unique. // // If Packages->GuidId is NULL, the caller of FramworkHii->NewPack is registering // packages with at least 1 StringPack and 1 IfrPack. Therefore, Packages->GuidId is // not used as the name of the package list. Formset GUID is used as the Package List // GUID instead. // ASSERT ((StringPackageCount >=1 && IfrPackageCount == 1) || (FontPackageCount > 0)); if (IfrPackageCount > 0) { IfrPackage = GetIfrPackage (Packages); if (IfrPackage == NULL) { Status = EFI_NOT_FOUND; goto Done; } GetFormSetGuid (IfrPackage, &ThunkContext->TagGuid); } else { ASSERT (FontPackageCount > 0); GenerateRandomGuid (&ThunkContext->TagGuid); } } else { ThunkContextToRemove = TagGuidToIfrPackThunkContext (Private, Packages->GuidId); if (IfrPackageCount > 0 && StringPackageCount > 0 && (ThunkContextToRemove != NULL)) { DEBUG((EFI_D_WARN, "Framework code registers HII package list with the same GUID more than once.\n")); DEBUG((EFI_D_WARN, "Remove the previously registered package list and register the new one.\n")); HiiRemovePack (This, ThunkContextToRemove->FwHiiHandle); } CopyGuid (&ThunkContext->TagGuid, Packages->GuidId); } // // UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so // that Setup Utility can load the Buffer Storage using this protocol. An UEFI VFR can only // produce IFR package generated with Buffer Storage type and EFI Variable Storage. // The default EFI_HII_CONFIG_ACCESS_PROTOCOL is used to Get/Set the Buffer Storage. // if (IfrPackageCount != 0) { InstallDefaultConfigAccessProtocol (Packages, ThunkContext); } PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &ThunkContext->TagGuid); Status = mHiiDatabase->NewPackageList ( mHiiDatabase, PackageListHeader, ThunkContext->UefiHiiDriverHandle, &ThunkContext->UefiHiiHandle ); if (Status == EFI_INVALID_PARAMETER) { FreePool (PackageListHeader); // // UEFI HII database does not allow two package list with the same GUID. // In Framework HII implementation, Packages->GuidId is used as an identifier to associate // a PackageList with only IFR to a Package list the with String package. // GenerateRandomGuid (&GuidId); PackageListHeader = PrepareUefiPackageListFromFrameworkHiiPackages (Packages, &GuidId); Status = mHiiDatabase->NewPackageList ( mHiiDatabase, PackageListHeader, ThunkContext->UefiHiiDriverHandle, &ThunkContext->UefiHiiHandle ); } // // BUGBUG: Remove when development is done // ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { goto Done; } if (IfrPackageCount == 0) { if (StringPackageCount != 0) { // // Look for a Package List with only IFR Package with the same TAG GUID name. // If found one, add the String Packages to the found Package List. // This is needed because Framework HII Module may not register the String Package // and IFR Package in one NewPack () call. // UpdatePackListWithOnlyIfrPack ( Private, ThunkContext, PackageListHeader ); } } else { if (StringPackageCount == 0) { // // Look for the String Package with the same TAG GUID name and add // the found String Package to this Package List. // This is needed because Framework HII Module may not register the String Package // and IFR Package in one NewPack () call. // Status = FindStringPackAndUpdatePackListWithOnlyIfrPack ( Private, ThunkContext ); if (EFI_ERROR (Status)) { goto Done; } } // // Parse the Formset. Must be called after FindStringPackAndUpdatePackListWithOnlyIfrPack is called so // that String Package is ready. // ThunkContext->FormSet = ParseFormSet (ThunkContext->UefiHiiHandle); ASSERT (ThunkContext->FormSet != NULL); } Done: if (EFI_ERROR (Status)) { DestroyThunkContext (ThunkContext); } else { InsertTailList (&Private->ThunkContextListHead, &ThunkContext->Link); *Handle = ThunkContext->FwHiiHandle; } if (PackageListHeader != NULL) { FreePool (PackageListHeader); } return Status; }