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