/** @file
Implementation for EFI_HII_DATABASE_PROTOCOL.

Copyright (c) 2007 - 2009, Intel Corporation
All rights reserved. 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"

//
// Global variables
//
EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID;


/**
  This function generates a HII_DATABASE_RECORD node and adds into hii database.
  This is a internal function.

  @param  Private                hii database private structure
  @param  DatabaseNode           HII_DATABASE_RECORD node which is used to store a
                                 package list

  @retval EFI_SUCCESS            A database record is generated successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 database contents.
  @retval EFI_INVALID_PARAMETER  Private is NULL or DatabaseRecord is NULL.

**/
EFI_STATUS
GenerateHiiDatabaseRecord (
  IN  HII_DATABASE_PRIVATE_DATA *Private,
  OUT HII_DATABASE_RECORD       **DatabaseNode
  )
{
  HII_DATABASE_RECORD                *DatabaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList;
  HII_HANDLE                         *HiiHandle;

  if (Private == NULL || DatabaseNode == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DatabaseRecord = (HII_DATABASE_RECORD *) AllocateZeroPool (sizeof (HII_DATABASE_RECORD));
  if (DatabaseRecord == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  DatabaseRecord->Signature = HII_DATABASE_RECORD_SIGNATURE;

  DatabaseRecord->PackageList = AllocateZeroPool (sizeof (HII_DATABASE_PACKAGE_LIST_INSTANCE));
  if (DatabaseRecord->PackageList == NULL) {
    FreePool (DatabaseRecord);
    return EFI_OUT_OF_RESOURCES;
  }

  PackageList = DatabaseRecord->PackageList;

  InitializeListHead (&PackageList->GuidPkgHdr);
  InitializeListHead (&PackageList->FormPkgHdr);
  InitializeListHead (&PackageList->KeyboardLayoutHdr);
  InitializeListHead (&PackageList->StringPkgHdr);
  InitializeListHead (&PackageList->FontPkgHdr);
  InitializeListHead (&PackageList->SimpleFontPkgHdr);
  PackageList->ImagePkg      = NULL;
  PackageList->DevicePathPkg = NULL;

  //
  // Create a new hii handle
  //
  HiiHandle = (HII_HANDLE *) AllocateZeroPool (sizeof (HII_HANDLE));
  if (HiiHandle == NULL) {
    FreePool (DatabaseRecord->PackageList);
    FreePool (DatabaseRecord);
    return EFI_OUT_OF_RESOURCES;
  }
  HiiHandle->Signature = HII_HANDLE_SIGNATURE;
  //
  // Backup the number of Hii handles
  //
  Private->HiiHandleCount++;
  HiiHandle->Key = Private->HiiHandleCount;
  //
  // Insert the handle to hii handle list of the whole database.
  //
  InsertTailList (&Private->HiiHandleList, &HiiHandle->Handle);

  DatabaseRecord->Handle = (EFI_HII_HANDLE) HiiHandle;

  //
  // Insert the Package List node to Package List link of the whole database.
  //
  InsertTailList (&Private->DatabaseList, &DatabaseRecord->DatabaseEntry);

  *DatabaseNode = DatabaseRecord;

  return EFI_SUCCESS;

}


/**
  This function checks whether a handle is a valid EFI_HII_HANDLE
  This is a internal function.

  @param  Handle                 Pointer to a EFI_HII_HANDLE

  @retval TRUE                   Valid
  @retval FALSE                  Invalid

**/
BOOLEAN
IsHiiHandleValid (
  EFI_HII_HANDLE Handle
  )
{
  HII_HANDLE    *HiiHandle;

  HiiHandle = (HII_HANDLE *) Handle;

  if (HiiHandle == NULL) {
    return FALSE;
  }

  if (HiiHandle->Signature != HII_HANDLE_SIGNATURE) {
    return FALSE;
  }

  return TRUE;
}


/**
  This function invokes the matching registered function.
  This is a internal function.

  @param  Private                HII Database driver private structure.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageInstance        Points to the package referred to by the
                                 notification.
  @param  PackageType            Package type
  @param  Handle                 The handle of the package list which contains the
                                 specified package.

  @retval EFI_SUCCESS            Already checked all registered function and
                                 invoked  if matched.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
InvokeRegisteredFunction (
  IN HII_DATABASE_PRIVATE_DATA    *Private,
  IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
  IN VOID                         *PackageInstance,
  IN UINT8                        PackageType,
  IN EFI_HII_HANDLE               Handle
  )
{
  HII_DATABASE_NOTIFY             *Notify;
  LIST_ENTRY                      *Link;
  EFI_HII_PACKAGE_HEADER          *Package;
  UINT8                           *Buffer;
  UINT32                          BufferSize;
  UINT32                          HeaderSize;
  UINT32                          ImageBlockSize;
  UINT32                          PaletteInfoSize;

  if (Private == NULL || (NotifyType & 0xF) == 0 || PackageInstance == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }
  if (!IsHiiHandleValid (Handle)) {
    return EFI_INVALID_PARAMETER;
  }

  Buffer  = NULL;
  Package = NULL;

  //
  // Convert the incoming package from hii database storage format to UEFI
  // storage format. e.g. HII_GUID_PACKAGE_INSTANCE to EFI_HII_GUID_PACKAGE_HDR.
  //
  switch (PackageType) {
  case EFI_HII_PACKAGE_TYPE_GUID:
    Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg);
    break;

  case EFI_HII_PACKAGE_FORMS:
    BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length;
    Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
    ASSERT (Buffer != NULL);
    CopyMem (
      Buffer,
      &((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr,
      sizeof (EFI_HII_PACKAGE_HEADER)
      );
    CopyMem (
      Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
      ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->IfrData,
      BufferSize - sizeof (EFI_HII_PACKAGE_HEADER)
      );
    Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
    break;

  case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
    Package = (EFI_HII_PACKAGE_HEADER *) (((HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *) PackageInstance)->KeyboardPkg);
    break;

  case EFI_HII_PACKAGE_STRINGS:
    BufferSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->Header.Length;
    HeaderSize = ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr->HdrSize;
    Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
    ASSERT (Buffer != NULL);
    CopyMem (
      Buffer,
      ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringPkgHdr,
      HeaderSize
      );
    CopyMem (
      Buffer + HeaderSize,
      ((HII_STRING_PACKAGE_INSTANCE *) PackageInstance)->StringBlock,
      BufferSize - HeaderSize
      );
    Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
    break;

  case EFI_HII_PACKAGE_FONTS:
    BufferSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->Header.Length;
    HeaderSize = ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr->HdrSize;
    Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
    ASSERT (Buffer != NULL);
    CopyMem (
      Buffer,
      ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->FontPkgHdr,
      HeaderSize
      );
    CopyMem (
      Buffer + HeaderSize,
      ((HII_FONT_PACKAGE_INSTANCE *) PackageInstance)->GlyphBlock,
      BufferSize - HeaderSize
      );
    Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
    break;

  case EFI_HII_PACKAGE_IMAGES:
    BufferSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr.Header.Length;
    HeaderSize = sizeof (EFI_HII_IMAGE_PACKAGE_HDR);
    Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
    ASSERT (Buffer != NULL);

    CopyMem (
      Buffer,
      &((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImagePkgHdr,
      HeaderSize
      );
    CopyMem (
      Buffer + sizeof (EFI_HII_PACKAGE_HEADER),
      &HeaderSize,
      sizeof (UINT32)
      );

    ImageBlockSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlockSize;
    if (ImageBlockSize != 0) {
      CopyMem (
        Buffer + HeaderSize,
        ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->ImageBlock,
        ImageBlockSize
        );
    }

    PaletteInfoSize = ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteInfoSize;
    if (PaletteInfoSize != 0) {
      CopyMem (
        Buffer + HeaderSize + ImageBlockSize,
        ((HII_IMAGE_PACKAGE_INSTANCE *) PackageInstance)->PaletteBlock,
        PaletteInfoSize
        );
      HeaderSize += ImageBlockSize;
      CopyMem (
        Buffer + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT32),
        &HeaderSize,
        sizeof (UINT32)
        );
    }
    Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
    break;

  case EFI_HII_PACKAGE_SIMPLE_FONTS:
    BufferSize = ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr->Header.Length;
    Buffer = (UINT8 *) AllocateZeroPool (BufferSize);
    ASSERT (Buffer != NULL);
    CopyMem (
      Buffer,
      ((HII_SIMPLE_FONT_PACKAGE_INSTANCE *) PackageInstance)->SimpleFontPkgHdr,
      BufferSize
      );
    Package = (EFI_HII_PACKAGE_HEADER *) Buffer;
    break;

  case EFI_HII_PACKAGE_DEVICE_PATH:
    Package = (EFI_HII_PACKAGE_HEADER *) PackageInstance;
    break;

  default:
    return EFI_INVALID_PARAMETER;
  }

  for (Link = Private->DatabaseNotifyList.ForwardLink;
       Link != &Private->DatabaseNotifyList;
       Link = Link->ForwardLink
      ) {
    Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
    if (Notify->NotifyType == NotifyType && Notify->PackageType == PackageType) {
      //
      // Check in case PackageGuid is not NULL when Package is GUID package
      //
      if (PackageType != EFI_HII_PACKAGE_TYPE_GUID) {
        Notify->PackageGuid = NULL;
      }
      //
      // Status of Registered Function is unknown so did not check it
      //
      Notify->PackageNotifyFn (
        Notify->PackageType,
        Notify->PackageGuid,
        Package,
        Handle,
        NotifyType
        );
    }
  }

  if (Buffer != NULL) {
    FreePool (Buffer);
  }

  return EFI_SUCCESS;
}


/**
  This function insert a GUID package to a package list node.
  This is a internal function.

  @param  PackageHdr             Pointer to a buffer stored with GUID package
                                 information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created GUID pacakge

  @retval EFI_SUCCESS            Guid Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Guid package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.

**/
EFI_STATUS
InsertGuidPackage (
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT    HII_GUID_PACKAGE_INSTANCE          **Package
  )
{
  HII_GUID_PACKAGE_INSTANCE            *GuidPackage;
  EFI_HII_PACKAGE_HEADER               PackageHeader;

  if (PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));

  //
  // Create a GUID package node
  //
  GuidPackage = (HII_GUID_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_GUID_PACKAGE_INSTANCE));
  if (GuidPackage == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  GuidPackage->GuidPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);
  if (GuidPackage->GuidPkg == NULL) {
    FreePool (GuidPackage);
    return EFI_OUT_OF_RESOURCES;
  }

  GuidPackage->Signature = HII_GUID_PACKAGE_SIGNATURE;
  CopyMem (GuidPackage->GuidPkg, PackageHdr, PackageHeader.Length);
  InsertTailList (&PackageList->GuidPkgHdr, &GuidPackage->GuidEntry);
  *Package = GuidPackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
  }

  return EFI_SUCCESS;
}


/**
  This function exports GUID packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            Guid Packages are exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportGuidPackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  HII_GUID_PACKAGE_INSTANCE            *GuidPackage;
  LIST_ENTRY                           *Link;
  UINTN                                PackageLength;
  EFI_HII_PACKAGE_HEADER               PackageHeader;
  EFI_STATUS                           Status;

  if (PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = 0;
  Status        = EFI_SUCCESS;

  for (Link = PackageList->GuidPkgHdr.ForwardLink; Link != &PackageList->GuidPkgHdr; Link = Link->ForwardLink) {
    GuidPackage = CR (Link, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
    CopyMem (&PackageHeader, GuidPackage->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
    PackageLength += PackageHeader.Length;
    if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
      Status = InvokeRegisteredFunction (
                 Private,
                 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
                 (VOID *) GuidPackage,
                 EFI_HII_PACKAGE_TYPE_GUID,
                 Handle
                 );
      ASSERT_EFI_ERROR (Status);
      CopyMem (Buffer, GuidPackage->GuidPkg, PackageHeader.Length);
      Buffer = (UINT8 *) Buffer + PackageHeader.Length;
    }
  }

  *ResultSize += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function deletes all GUID packages from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed GUID packages.
  @param  PackageList            Pointer to a package list that contains removing
                                 packages.

  @retval EFI_SUCCESS            GUID Package(s) is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveGuidPackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  LIST_ENTRY                           *ListHead;
  HII_GUID_PACKAGE_INSTANCE            *Package;
  EFI_STATUS                           Status;
  EFI_HII_PACKAGE_HEADER               PackageHeader;

  ListHead = &PackageList->GuidPkgHdr;

  while (!IsListEmpty (ListHead)) {
    Package = CR (
                ListHead->ForwardLink,
                HII_GUID_PACKAGE_INSTANCE,
                GuidEntry,
                HII_GUID_PACKAGE_SIGNATURE
                );
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_TYPE_GUID,
               Handle
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    RemoveEntryList (&Package->GuidEntry);
    CopyMem (&PackageHeader, Package->GuidPkg, sizeof (EFI_HII_PACKAGE_HEADER));
    PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
    FreePool (Package->GuidPkg);
    FreePool (Package);
  }

  return EFI_SUCCESS;
}


/**
  This function insert a Form package to a package list node.
  This is a internal function.

  @param  PackageHdr             Pointer to a buffer stored with Form package
                                 information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created Form package

  @retval EFI_SUCCESS            Form Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Form package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.

**/
EFI_STATUS
InsertFormPackage (
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT    HII_IFR_PACKAGE_INSTANCE           **Package
  )
{
  HII_IFR_PACKAGE_INSTANCE *FormPackage;
  EFI_HII_PACKAGE_HEADER   PackageHeader;

  if (PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the length of the package, including package header itself
  //
  CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));

  //
  // Create a Form package node
  //
  FormPackage = (HII_IFR_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IFR_PACKAGE_INSTANCE));
  if (FormPackage == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  FormPackage->IfrData = (UINT8 *) AllocateZeroPool (PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER));
  if (FormPackage->IfrData == NULL) {
    FreePool (FormPackage);
    return EFI_OUT_OF_RESOURCES;
  }

  FormPackage->Signature = HII_IFR_PACKAGE_SIGNATURE;
  //
  // Copy Package Header
  //
  CopyMem (&FormPackage->FormPkgHdr, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));

  //
  // Copy Ifr contents
  //
  CopyMem (
    FormPackage->IfrData,
    (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER),
    PackageHeader.Length - sizeof (EFI_HII_PACKAGE_HEADER)
    );

  InsertTailList (&PackageList->FormPkgHdr, &FormPackage->IfrEntry);
  *Package = FormPackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += FormPackage->FormPkgHdr.Length;
  }
  return EFI_SUCCESS;
}


/**
  This function exports Form packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            Form Packages are exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportFormPackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  HII_IFR_PACKAGE_INSTANCE *FormPackage;
  UINTN                    PackageLength;
  LIST_ENTRY               *Link;
  EFI_STATUS               Status;

  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = 0;
  Status        = EFI_SUCCESS;

  //
  // Export Form packages.
  //
  for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {
    FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);
    PackageLength += FormPackage->FormPkgHdr.Length;
    if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {
      //
      // Invoke registered notification if exists
      //
      Status = InvokeRegisteredFunction (
                 Private,
                 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
                 (VOID *) FormPackage,
                 EFI_HII_PACKAGE_FORMS,
                 Handle
                 );
      ASSERT_EFI_ERROR (Status);
      //
      // Copy the Form package content.
      //
      CopyMem (Buffer, (VOID *) (&FormPackage->FormPkgHdr), sizeof (EFI_HII_PACKAGE_HEADER));
      Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_PACKAGE_HEADER);
      CopyMem (
        Buffer,
        (VOID *) FormPackage->IfrData,
        FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER)
        );
      Buffer = (UINT8 *) Buffer + FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
    }
  }

  *ResultSize += PackageLength;

  return EFI_SUCCESS;

}


/**
  This function deletes all Form packages from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed Form packages.
  @param  PackageList            Pointer to a package list that contains removing
                                 packages.

  @retval EFI_SUCCESS            Form Package(s) is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveFormPackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  LIST_ENTRY                      *ListHead;
  HII_IFR_PACKAGE_INSTANCE        *Package;
  EFI_STATUS                      Status;

  ListHead = &PackageList->FormPkgHdr;

  while (!IsListEmpty (ListHead)) {
    Package = CR (
                ListHead->ForwardLink,
                HII_IFR_PACKAGE_INSTANCE,
                IfrEntry,
                HII_IFR_PACKAGE_SIGNATURE
                );
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_FORMS,
               Handle
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    RemoveEntryList (&Package->IfrEntry);
    PackageList->PackageListHdr.PackageLength -= Package->FormPkgHdr.Length;
    FreePool (Package->IfrData);
    FreePool (Package);

  }

  return EFI_SUCCESS;
}



/**
  This function insert a String package to a package list node.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  PackageHdr             Pointer to a buffer stored with String package
                                 information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created String package

  @retval EFI_SUCCESS            String Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 String package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.
  @retval EFI_UNSUPPORTED        A string package with the same language already
                                 exists in current package list.

**/
EFI_STATUS
InsertStringPackage (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT    HII_STRING_PACKAGE_INSTANCE        **Package

  )
{
  HII_STRING_PACKAGE_INSTANCE *StringPackage;
  UINT32                      HeaderSize;
  EFI_STATUS                  Status;
  EFI_HII_PACKAGE_HEADER      PackageHeader;
  CHAR8                       *Language;
  UINT32                      LanguageSize;
  LIST_ENTRY                  *Link;

  if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
  CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));

  //
  // It is illegal to have two string packages with same language within one packagelist
  // since the stringid will be duplicate if so. Check it to avoid this potential issue.
  //
  LanguageSize = HeaderSize - sizeof (EFI_HII_STRING_PACKAGE_HDR) + sizeof (CHAR8);
  Language = (CHAR8 *) AllocateZeroPool (LanguageSize);
  if (Language == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize);
  for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) {
      FreePool (Language);
      return EFI_UNSUPPORTED;
    }
  }
  FreePool (Language);

  //
  // Create a String package node
  //
  StringPackage = (HII_STRING_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
  if (StringPackage == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  StringPackage->StringPkgHdr = (EFI_HII_STRING_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);
  if (StringPackage->StringPkgHdr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);
  if (StringPackage->StringBlock == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
  StringPackage->FontId    = 0;
  InitializeListHead (&StringPackage->FontInfoList);

  //
  // Copy the String package header.
  //
  CopyMem (StringPackage->StringPkgHdr, PackageHdr, HeaderSize);

  //
  // Copy the String blocks
  //
  CopyMem (
    StringPackage->StringBlock,
    (UINT8 *) PackageHdr + HeaderSize,
    PackageHeader.Length - HeaderSize
    );

  //
  // Collect all font block info
  //
  Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Insert to String package array
  //
  InsertTailList (&PackageList->StringPkgHdr, &StringPackage->StringEntry);
  *Package = StringPackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
  }

  return EFI_SUCCESS;

Error:

  if (StringPackage != NULL) {
    if (StringPackage->StringBlock != NULL) {
      FreePool (StringPackage->StringBlock);
    }
    if (StringPackage->StringPkgHdr != NULL) {
      FreePool (StringPackage->StringPkgHdr);
    }
    FreePool (StringPackage);
  }
  return Status;

}


/**
  This function exports String packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            String Packages are exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportStringPackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  LIST_ENTRY                  *Link;
  UINTN                       PackageLength;
  EFI_STATUS                  Status;
  HII_STRING_PACKAGE_INSTANCE *StringPackage;

  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = 0;
  Status        = EFI_SUCCESS;

  for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    PackageLength += StringPackage->StringPkgHdr->Header.Length;
    if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
      //
      // Invoke registered notification function with EXPORT_PACK notify type
      //
      Status = InvokeRegisteredFunction (
                 Private,
                 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
                 (VOID *) StringPackage,
                 EFI_HII_PACKAGE_STRINGS,
                 Handle
                 );
      ASSERT_EFI_ERROR (Status);
      //
      // Copy String package header
      //
      CopyMem (Buffer, StringPackage->StringPkgHdr, StringPackage->StringPkgHdr->HdrSize);
      Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->HdrSize;

      //
      // Copy String blocks information
      //
      CopyMem (
        Buffer,
        StringPackage->StringBlock,
        StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize
        );
      Buffer = (UINT8 *) Buffer + StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
    }
  }

  *ResultSize += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function deletes all String packages from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed String packages.
  @param  PackageList            Pointer to a package list that contains removing
                                 packages.

  @retval EFI_SUCCESS            String Package(s) is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveStringPackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  LIST_ENTRY                      *ListHead;
  HII_STRING_PACKAGE_INSTANCE     *Package;
  HII_FONT_INFO                   *FontInfo;
  EFI_STATUS                      Status;

  ListHead = &PackageList->StringPkgHdr;

  while (!IsListEmpty (ListHead)) {
    Package = CR (
                ListHead->ForwardLink,
                HII_STRING_PACKAGE_INSTANCE,
                StringEntry,
                HII_STRING_PACKAGE_SIGNATURE
                );
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_STRINGS,
               Handle
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    RemoveEntryList (&Package->StringEntry);
    PackageList->PackageListHdr.PackageLength -= Package->StringPkgHdr->Header.Length;
    FreePool (Package->StringBlock);
    FreePool (Package->StringPkgHdr);
    //
    // Delete font information
    //
    while (!IsListEmpty (&Package->FontInfoList)) {
      FontInfo = CR (
                   Package->FontInfoList.ForwardLink,
                   HII_FONT_INFO,
                   Entry,
                   HII_FONT_INFO_SIGNATURE
                   );
      RemoveEntryList (&FontInfo->Entry);
      FreePool (FontInfo);
    }

    FreePool (Package);
  }

  return EFI_SUCCESS;
}


/**
  This function insert a Font package to a package list node.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  PackageHdr             Pointer to a buffer stored with Font package
                                 information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created Font package

  @retval EFI_SUCCESS            Font Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Font package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.
  @retval EFI_UNSUPPORTED        A font package with same EFI_FONT_INFO already
                                 exists in current hii database.

**/
EFI_STATUS
InsertFontPackage (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT    HII_FONT_PACKAGE_INSTANCE          **Package
  )
{
  HII_FONT_PACKAGE_INSTANCE *FontPackage;
  EFI_HII_FONT_PACKAGE_HDR  *FontPkgHdr;
  UINT32                    HeaderSize;
  EFI_STATUS                Status;
  EFI_HII_PACKAGE_HEADER    PackageHeader;
  EFI_FONT_INFO             *FontInfo;
  UINT32                    FontInfoSize;
  HII_GLOBAL_FONT_INFO      *GlobalFont;

  if (Private == NULL || PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));
  CopyMem (&HeaderSize, (UINT8 *) PackageHdr + sizeof (EFI_HII_PACKAGE_HEADER), sizeof (UINT32));

  FontInfo    = NULL;
  FontPackage = NULL;
  GlobalFont  = NULL;

  //
  // It is illegal to have two font packages with same EFI_FONT_INFO within hii
  // database. EFI_FONT_INFO (FontName, FontSize, FontStyle) describes font's
  // attributes and identify a font uniquely.
  //
  FontPkgHdr = (EFI_HII_FONT_PACKAGE_HDR *) AllocateZeroPool (HeaderSize);
  if (FontPkgHdr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  CopyMem (FontPkgHdr, PackageHdr, HeaderSize);

  FontInfoSize = sizeof (EFI_FONT_INFO) + HeaderSize - sizeof (EFI_HII_FONT_PACKAGE_HDR);
  FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoSize);
  if (FontInfo == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  FontInfo->FontStyle = FontPkgHdr->FontStyle;
  FontInfo->FontSize  = FontPkgHdr->Cell.Height;
  StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily);

  if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) {
    Status = EFI_UNSUPPORTED;
    goto Error;
  }

  //
  // Create a Font package node
  //
  FontPackage = (HII_FONT_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_FONT_PACKAGE_INSTANCE));
  if (FontPackage == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  FontPackage->Signature  = HII_FONT_PACKAGE_SIGNATURE;
  FontPackage->FontPkgHdr = FontPkgHdr;
  InitializeListHead (&FontPackage->GlyphInfoList);

  FontPackage->GlyphBlock = (UINT8 *) AllocateZeroPool (PackageHeader.Length - HeaderSize);
  if (FontPackage->GlyphBlock == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  CopyMem (FontPackage->GlyphBlock, (UINT8 *) PackageHdr + HeaderSize, PackageHeader.Length - HeaderSize);

  //
  // Collect all default character cell information and backup in GlyphInfoList.
  //
  Status = FindGlyphBlock (FontPackage, (CHAR16) (-1), NULL, NULL, NULL);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // This font package describes an unique EFI_FONT_INFO. Backup it in global
  // font info list.
  //
  GlobalFont = (HII_GLOBAL_FONT_INFO *) AllocateZeroPool (sizeof (HII_GLOBAL_FONT_INFO));
  if (GlobalFont == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  GlobalFont->Signature    = HII_GLOBAL_FONT_INFO_SIGNATURE;
  GlobalFont->FontPackage  = FontPackage;
  GlobalFont->FontInfoSize = FontInfoSize;
  GlobalFont->FontInfo     = FontInfo;
  InsertTailList (&Private->FontInfoList, &GlobalFont->Entry);

  //
  // Insert this font package to Font package array
  //
  InsertTailList (&PackageList->FontPkgHdr, &FontPackage->FontEntry);
  *Package = FontPackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += FontPackage->FontPkgHdr->Header.Length;
  }

  return EFI_SUCCESS;

Error:

  if (FontPkgHdr != NULL) {
    FreePool (FontPkgHdr);
  }
  if (FontInfo != NULL) {
    FreePool (FontInfo);
  }
  if (FontPackage != NULL) {
    if (FontPackage->GlyphBlock != NULL) {
      FreePool (FontPackage->GlyphBlock);
    }
    FreePool (FontPackage);
  }
  if (GlobalFont != NULL) {
    FreePool (GlobalFont);
  }

  return Status;

}


/**
  This function exports Font packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            Font Packages are exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportFontPackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  LIST_ENTRY                  *Link;
  UINTN                       PackageLength;
  EFI_STATUS                  Status;
  HII_FONT_PACKAGE_INSTANCE   *Package;


  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = 0;
  Status        = EFI_SUCCESS;

  for (Link = PackageList->FontPkgHdr.ForwardLink; Link != &PackageList->FontPkgHdr; Link = Link->ForwardLink) {
    Package = CR (Link, HII_FONT_PACKAGE_INSTANCE, FontEntry, HII_FONT_PACKAGE_SIGNATURE);
    PackageLength += Package->FontPkgHdr->Header.Length;
    if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
      //
      // Invoke registered notification function with EXPORT_PACK notify type
      //
      Status = InvokeRegisteredFunction (
                 Private,
                 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
                 (VOID *) Package,
                 EFI_HII_PACKAGE_FONTS,
                 Handle
                 );
      ASSERT_EFI_ERROR (Status);
      //
      // Copy Font package header
      //
      CopyMem (Buffer, Package->FontPkgHdr, Package->FontPkgHdr->HdrSize);
      Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->HdrSize;

      //
      // Copy Glyph blocks information
      //
      CopyMem (
        Buffer,
        Package->GlyphBlock,
        Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize
        );
      Buffer = (UINT8 *) Buffer + Package->FontPkgHdr->Header.Length - Package->FontPkgHdr->HdrSize;
    }
  }

  *ResultSize += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function deletes all Font packages from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed Font packages.
  @param  PackageList            Pointer to a package list that contains removing
                                 packages.

  @retval EFI_SUCCESS            Font Package(s) is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveFontPackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  LIST_ENTRY                      *ListHead;
  HII_FONT_PACKAGE_INSTANCE       *Package;
  EFI_STATUS                      Status;
  HII_GLYPH_INFO                  *GlyphInfo;
  LIST_ENTRY                      *Link;
  HII_GLOBAL_FONT_INFO            *GlobalFont;

  ListHead = &PackageList->FontPkgHdr;

  while (!IsListEmpty (ListHead)) {
    Package = CR (
                ListHead->ForwardLink,
                HII_FONT_PACKAGE_INSTANCE,
                FontEntry,
                HII_FONT_PACKAGE_SIGNATURE
                );
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_FONTS,
               Handle
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    RemoveEntryList (&Package->FontEntry);
    PackageList->PackageListHdr.PackageLength -= Package->FontPkgHdr->Header.Length;

    if (Package->GlyphBlock != NULL) {
      FreePool (Package->GlyphBlock);
    }
    FreePool (Package->FontPkgHdr);
    //
    // Delete default character cell information
    //
    while (!IsListEmpty (&Package->GlyphInfoList)) {
      GlyphInfo = CR (
                    Package->GlyphInfoList.ForwardLink,
                    HII_GLYPH_INFO,
                    Entry,
                    HII_GLYPH_INFO_SIGNATURE
                    );
      RemoveEntryList (&GlyphInfo->Entry);
      FreePool (GlyphInfo);
    }

    //
    // Remove corresponding global font info
    //
    for (Link = Private->FontInfoList.ForwardLink; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
      GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
      if (GlobalFont->FontPackage == Package) {
        RemoveEntryList (&GlobalFont->Entry);
        FreePool (GlobalFont->FontInfo);
        FreePool (GlobalFont);
        break;
      }
    }

    FreePool (Package);
  }

  return EFI_SUCCESS;
}


/**
  This function insert a Image package to a package list node.
  This is a internal function.

  @param  PackageHdr             Pointer to a buffer stored with Image package
                                 information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created Image package

  @retval EFI_SUCCESS            Image Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Image package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.

**/
EFI_STATUS
InsertImagePackage (
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT    HII_IMAGE_PACKAGE_INSTANCE         **Package
  )
{
  HII_IMAGE_PACKAGE_INSTANCE        *ImagePackage;
  UINT32                            PaletteSize;
  UINT32                            ImageSize;
  UINT16                            Index;
  EFI_HII_IMAGE_PALETTE_INFO_HEADER *PaletteHdr;
  EFI_HII_IMAGE_PALETTE_INFO        *PaletteInfo;
  UINT32                            PaletteInfoOffset;
  UINT32                            ImageInfoOffset;
  UINT16                            CurrentSize;

  if (PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Less than one image package is allowed in one package list.
  //
  if (PackageList->ImagePkg != NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Create a Image package node
  //
  ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));
  if (ImagePackage == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Copy the Image package header.
  //
  CopyMem (&ImagePackage->ImagePkgHdr, PackageHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));

  PaletteInfoOffset = ImagePackage->ImagePkgHdr.PaletteInfoOffset;
  ImageInfoOffset   = ImagePackage->ImagePkgHdr.ImageInfoOffset;

  //
  // If PaletteInfoOffset is zero, there are no palettes in this image package.
  //
  PaletteSize                = 0;
  ImagePackage->PaletteBlock = NULL;
  if (PaletteInfoOffset != 0) {
    PaletteHdr  = (EFI_HII_IMAGE_PALETTE_INFO_HEADER *) ((UINT8 *) PackageHdr + PaletteInfoOffset);
    PaletteSize = sizeof (EFI_HII_IMAGE_PALETTE_INFO_HEADER);
    PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteHdr + PaletteSize);

    for (Index = 0; Index < PaletteHdr->PaletteCount; Index++) {
      CopyMem (&CurrentSize, PaletteInfo, sizeof (UINT16));
      CurrentSize += sizeof (UINT16);
      PaletteSize += (UINT32) CurrentSize;
      PaletteInfo = (EFI_HII_IMAGE_PALETTE_INFO *) ((UINT8 *) PaletteInfo + CurrentSize);
    }

    ImagePackage->PaletteBlock = (UINT8 *) AllocateZeroPool (PaletteSize);
    if (ImagePackage->PaletteBlock == NULL) {
      FreePool (ImagePackage);
      return EFI_OUT_OF_RESOURCES;
    }
    CopyMem (
      ImagePackage->PaletteBlock,
      (UINT8 *) PackageHdr + PaletteInfoOffset,
      PaletteSize
      );
  }

  //
  // If ImageInfoOffset is zero, there are no images in this package.
  //
  ImageSize                = 0;
  ImagePackage->ImageBlock = NULL;
  if (ImageInfoOffset != 0) {
    ImageSize = ImagePackage->ImagePkgHdr.Header.Length -
                sizeof (EFI_HII_IMAGE_PACKAGE_HDR) - PaletteSize;
    ImagePackage->ImageBlock = (UINT8 *) AllocateZeroPool (ImageSize);
    if (ImagePackage->ImageBlock == NULL) {
      FreePool (ImagePackage->PaletteBlock);
      FreePool (ImagePackage);
      return EFI_OUT_OF_RESOURCES;
    }
    CopyMem (
      ImagePackage->ImageBlock,
      (UINT8 *) PackageHdr + ImageInfoOffset,
      ImageSize
      );
  }

  ImagePackage->ImageBlockSize  = ImageSize;
  ImagePackage->PaletteInfoSize = PaletteSize;
  PackageList->ImagePkg         = ImagePackage;
  *Package                      = ImagePackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += ImagePackage->ImagePkgHdr.Header.Length;
  }

  return EFI_SUCCESS;
}


/**
  This function exports Image packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            Image Packages are exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportImagePackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  UINTN                       PackageLength;
  EFI_STATUS                  Status;
  HII_IMAGE_PACKAGE_INSTANCE  *Package;


  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  Package = PackageList->ImagePkg;

  if (Package == NULL) {
    return EFI_SUCCESS;
  }

  PackageLength = Package->ImagePkgHdr.Header.Length;

  if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
    //
    // Invoke registered notification function with EXPORT_PACK notify type
    //
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_IMAGES,
               Handle
               );
    ASSERT_EFI_ERROR (Status);
    ASSERT (Package->ImagePkgHdr.Header.Length ==
            sizeof (EFI_HII_IMAGE_PACKAGE_HDR) + Package->ImageBlockSize + Package->PaletteInfoSize);
    //
    // Copy Image package header,
    // then justify the offset for image info and palette info in the header.
    //
    CopyMem (Buffer, &Package->ImagePkgHdr, sizeof (EFI_HII_IMAGE_PACKAGE_HDR));
    Buffer = (UINT8 *) Buffer + sizeof (EFI_HII_IMAGE_PACKAGE_HDR);

    //
    // Copy Image blocks information
    //
    if (Package->ImageBlockSize != 0) {
      CopyMem (Buffer, Package->ImageBlock, Package->ImageBlockSize);
      Buffer = (UINT8 *) Buffer + Package->ImageBlockSize;
    }
    //
    // Copy Palette information
    //
    if (Package->PaletteInfoSize != 0) {
      CopyMem (Buffer, Package->PaletteBlock, Package->PaletteInfoSize);
      Buffer = (UINT8 *) Buffer + Package->PaletteInfoSize;
    }
  }

  *ResultSize += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function deletes Image package from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed Image packages.
  @param  PackageList            Package List which contains the to be  removed
                                 Image package.

  @retval EFI_SUCCESS            Image Package(s) is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveImagePackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  HII_IMAGE_PACKAGE_INSTANCE      *Package;
  EFI_STATUS                      Status;

  Package = PackageList->ImagePkg;

  //
  // Image package does not exist, return directly.
  //
  if (Package == NULL) {
    return EFI_SUCCESS;
  }

  Status = InvokeRegisteredFunction (
             Private,
             EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
             (VOID *) Package,
             EFI_HII_PACKAGE_IMAGES,
             Handle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  PackageList->PackageListHdr.PackageLength -= Package->ImagePkgHdr.Header.Length;

  FreePool (Package->ImageBlock);
  if (Package->PaletteBlock != NULL) {
    FreePool (Package->PaletteBlock);
  }
  FreePool (Package);

  PackageList->ImagePkg = NULL;

  return EFI_SUCCESS;
}


/**
  This function insert a Simple Font package to a package list node.
  This is a internal function.

  @param  PackageHdr             Pointer to a buffer stored with Simple Font
                                 package information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created Simple Font package

  @retval EFI_SUCCESS            Simple Font Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Simple Font package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.

**/
EFI_STATUS
InsertSimpleFontPackage (
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT HII_SIMPLE_FONT_PACKAGE_INSTANCE      **Package
  )
{
  HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFontPackage;
  EFI_STATUS                       Status;
  EFI_HII_PACKAGE_HEADER           Header;

  if (PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Create a Simple Font package node
  //
  SimpleFontPackage = AllocateZeroPool (sizeof (HII_SIMPLE_FONT_PACKAGE_INSTANCE));
  if (SimpleFontPackage == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  SimpleFontPackage->Signature = HII_S_FONT_PACKAGE_SIGNATURE;

  //
  // Copy the Simple Font package.
  //
  CopyMem (&Header, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));

  SimpleFontPackage->SimpleFontPkgHdr = AllocateZeroPool (Header.Length);
  if (SimpleFontPackage->SimpleFontPkgHdr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  CopyMem (SimpleFontPackage->SimpleFontPkgHdr, PackageHdr, Header.Length);

  //
  // Insert to Simple Font package array
  //
  InsertTailList (&PackageList->SimpleFontPkgHdr, &SimpleFontPackage->SimpleFontEntry);
  *Package = SimpleFontPackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += Header.Length;
  }

  return EFI_SUCCESS;

Error:

  if (SimpleFontPackage != NULL) {
    if (SimpleFontPackage->SimpleFontPkgHdr != NULL) {
      FreePool (SimpleFontPackage->SimpleFontPkgHdr);
    }
    FreePool (SimpleFontPackage);
  }
  return Status;
}


/**
  This function exports SimpleFont packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            SimpleFont Packages are exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportSimpleFontPackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  LIST_ENTRY                        *Link;
  UINTN                             PackageLength;
  EFI_STATUS                        Status;
  HII_SIMPLE_FONT_PACKAGE_INSTANCE  *Package;

  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = 0;
  Status        = EFI_SUCCESS;

  for (Link = PackageList->SimpleFontPkgHdr.ForwardLink; Link != &PackageList->SimpleFontPkgHdr; Link = Link->ForwardLink) {
    Package = CR (Link, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
    PackageLength += Package->SimpleFontPkgHdr->Header.Length;
    if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
      //
      // Invoke registered notification function with EXPORT_PACK notify type
      //
      Status = InvokeRegisteredFunction (
                 Private,
                 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
                 (VOID *) Package,
                 EFI_HII_PACKAGE_SIMPLE_FONTS,
                 Handle
                 );
      ASSERT_EFI_ERROR (Status);

      //
      // Copy SimpleFont package
      //
      CopyMem (Buffer, Package->SimpleFontPkgHdr, Package->SimpleFontPkgHdr->Header.Length);
      Buffer = (UINT8 *) Buffer + Package->SimpleFontPkgHdr->Header.Length;
    }
  }

  *ResultSize += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function deletes all Simple Font packages from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed Simple Font packages.
  @param  PackageList            Pointer to a package list that contains removing
                                 packages.

  @retval EFI_SUCCESS            Simple Font Package(s) is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveSimpleFontPackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  LIST_ENTRY                       *ListHead;
  HII_SIMPLE_FONT_PACKAGE_INSTANCE *Package;
  EFI_STATUS                       Status;

  ListHead = &PackageList->SimpleFontPkgHdr;

  while (!IsListEmpty (ListHead)) {
    Package = CR (
                ListHead->ForwardLink,
                HII_SIMPLE_FONT_PACKAGE_INSTANCE,
                SimpleFontEntry,
                HII_S_FONT_PACKAGE_SIGNATURE
                );
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_SIMPLE_FONTS,
               Handle
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    RemoveEntryList (&Package->SimpleFontEntry);
    PackageList->PackageListHdr.PackageLength -= Package->SimpleFontPkgHdr->Header.Length;
    FreePool (Package->SimpleFontPkgHdr);
    FreePool (Package);
  }

  return EFI_SUCCESS;
}


/**
  This function insert a Device path package to a package list node.
  This is a internal function.

  @param  DevicePath             Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
                                 instance
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.

  @retval EFI_SUCCESS            Device path Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Device path package.
  @retval EFI_INVALID_PARAMETER  DevicePath is NULL or PackageList is NULL.

**/
EFI_STATUS
InsertDevicePathPackage (
  IN     EFI_DEVICE_PATH_PROTOCOL           *DevicePath,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  UINT32                           PackageLength;
  EFI_HII_PACKAGE_HEADER           Header;

  if (DevicePath == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Less than one device path package is allowed in one package list.
  //
  if (PackageList->DevicePathPkg != NULL) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = (UINT32) GetDevicePathSize (DevicePath) + sizeof (EFI_HII_PACKAGE_HEADER);
  PackageList->DevicePathPkg = (UINT8 *) AllocateZeroPool (PackageLength);
  if (PackageList->DevicePathPkg == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Header.Length = PackageLength;
  Header.Type   = EFI_HII_PACKAGE_DEVICE_PATH;
  CopyMem (PackageList->DevicePathPkg, &Header, sizeof (EFI_HII_PACKAGE_HEADER));
  CopyMem (
    PackageList->DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER),
    DevicePath,
    PackageLength - sizeof (EFI_HII_PACKAGE_HEADER)
    );

  //
  // Since Device Path package is created by NewPackageList, either NEW_PACK
  // or ADD_PACK should increase the length of package list.
  //
  PackageList->PackageListHdr.PackageLength += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function exports device path package to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            Device path Package is exported successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportDevicePathPackage (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  EFI_STATUS                       Status;
  UINT8                            *Package;
  EFI_HII_PACKAGE_HEADER           Header;

  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  Package = PackageList->DevicePathPkg;

  if (Package == NULL) {
    return EFI_SUCCESS;
  }

  CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));

  if (Header.Length + *ResultSize + UsedSize <= BufferSize) {
    //
    // Invoke registered notification function with EXPORT_PACK notify type
    //
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_DEVICE_PATH,
               Handle
               );
    ASSERT_EFI_ERROR (Status);

    //
    // Copy Device path package
    //
    CopyMem (Buffer, Package, Header.Length);
  }

  *ResultSize += Header.Length;
  return EFI_SUCCESS;
}


/**
  This function deletes Device Path package from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list.
  @param  PackageList            Package List which contains the to be  removed
                                 Device Path package.

  @retval EFI_SUCCESS            Device Path Package is deleted successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveDevicePathPackage (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  EFI_STATUS                       Status;
  UINT8                            *Package;
  EFI_HII_PACKAGE_HEADER           Header;

  Package = PackageList->DevicePathPkg;

  //
  // No device path, return directly.
  //
  if (Package == NULL) {
    return EFI_SUCCESS;
  }

  Status = InvokeRegisteredFunction (
             Private,
             EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
             (VOID *) Package,
             EFI_HII_PACKAGE_DEVICE_PATH,
             Handle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  CopyMem (&Header, Package, sizeof (EFI_HII_PACKAGE_HEADER));
  PackageList->PackageListHdr.PackageLength -= Header.Length;

  FreePool (Package);

  PackageList->DevicePathPkg = NULL;

  return EFI_SUCCESS;
}


/**
  This function will insert a device path package to package list firstly then
  invoke notification functions if any.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  NotifyType             The type of change concerning the database.
  @param  DevicePath             Pointer to a EFI_DEVICE_PATH_PROTOCOL protocol
                                 instance
  @param  DatabaseRecord         Pointer to a database record contains  a package
                                 list which will be inserted to.

  @retval EFI_SUCCESS            Device path Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Device path package.
  @retval EFI_INVALID_PARAMETER  DevicePath is NULL or PackageList is NULL.

**/
EFI_STATUS
AddDevicePathPackage (
  IN HII_DATABASE_PRIVATE_DATA        *Private,
  IN EFI_HII_DATABASE_NOTIFY_TYPE     NotifyType,
  IN EFI_DEVICE_PATH_PROTOCOL         *DevicePath,
  IN OUT HII_DATABASE_RECORD          *DatabaseRecord
  )
{
  EFI_STATUS                          Status;

  if (DevicePath == NULL) {
    return EFI_SUCCESS;
  }

  ASSERT (Private != NULL);
  ASSERT (DatabaseRecord != NULL);

  //
  // Create a device path package and insert to packagelist
  //
  Status = InsertDevicePathPackage (
               DevicePath,
               NotifyType,
               DatabaseRecord->PackageList
               );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return InvokeRegisteredFunction (
            Private,
            NotifyType,
            (VOID *) DatabaseRecord->PackageList->DevicePathPkg,
            EFI_HII_PACKAGE_DEVICE_PATH,
            DatabaseRecord->Handle
            );
}


/**
  This function insert a Keyboard Layout package to a package list node.
  This is a internal function.

  @param  PackageHdr             Pointer to a buffer stored with Keyboard Layout
                                 package information.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list which will be inserted
                                 to.
  @param  Package                Created Keyboard Layout package

  @retval EFI_SUCCESS            Keyboard Layout Package is inserted successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Keyboard Layout package.
  @retval EFI_INVALID_PARAMETER  PackageHdr is NULL or PackageList is NULL.

**/
EFI_STATUS
InsertKeyboardLayoutPackage (
  IN     VOID                               *PackageHdr,
  IN     EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  OUT HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE  **Package
  )
{
  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
  EFI_HII_PACKAGE_HEADER               PackageHeader;
  EFI_STATUS                           Status;

  if (PackageHdr == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&PackageHeader, PackageHdr, sizeof (EFI_HII_PACKAGE_HEADER));

  //
  // Create a Keyboard Layout package node
  //
  KeyboardLayoutPackage = AllocateZeroPool (sizeof (HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE));
  if (KeyboardLayoutPackage == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  KeyboardLayoutPackage->Signature = HII_KB_LAYOUT_PACKAGE_SIGNATURE;

  KeyboardLayoutPackage->KeyboardPkg = (UINT8 *) AllocateZeroPool (PackageHeader.Length);
  if (KeyboardLayoutPackage->KeyboardPkg == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  CopyMem (KeyboardLayoutPackage->KeyboardPkg, PackageHdr, PackageHeader.Length);
  InsertTailList (&PackageList->KeyboardLayoutHdr, &KeyboardLayoutPackage->KeyboardEntry);

  *Package = KeyboardLayoutPackage;

  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    PackageList->PackageListHdr.PackageLength += PackageHeader.Length;
  }

  return EFI_SUCCESS;

Error:


  if (KeyboardLayoutPackage != NULL) {
    if (KeyboardLayoutPackage->KeyboardPkg != NULL) {
      FreePool (KeyboardLayoutPackage->KeyboardPkg);
    }
    FreePool (KeyboardLayoutPackage);
  }

  return Status;
}


/**
  This function exports Keyboard Layout packages to a buffer.
  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer be used.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.
  @param  ResultSize             The size of the already exported content of  this
                                 package list.

  @retval EFI_SUCCESS            Keyboard Layout Packages are exported
                                 successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportKeyboardLayoutPackages (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN UINTN                              UsedSize,
  IN UINTN                              BufferSize,
  IN OUT VOID                           *Buffer,
  IN OUT UINTN                          *ResultSize
  )
{
  LIST_ENTRY                           *Link;
  UINTN                                PackageLength;
  EFI_STATUS                           Status;
  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
  EFI_HII_PACKAGE_HEADER               PackageHeader;

  if (Private == NULL || PackageList == NULL || ResultSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  PackageLength = 0;
  Status        = EFI_SUCCESS;

  for (Link = PackageList->KeyboardLayoutHdr.ForwardLink; Link != &PackageList->KeyboardLayoutHdr; Link = Link->ForwardLink) {
    Package = CR (Link, HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE, KeyboardEntry, HII_KB_LAYOUT_PACKAGE_SIGNATURE);
    CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
    PackageLength += PackageHeader.Length;
    if (PackageLength + *ResultSize + UsedSize <= BufferSize) {
      //
      // Invoke registered notification function with EXPORT_PACK notify type
      //
      Status = InvokeRegisteredFunction (
                 Private,
                 EFI_HII_DATABASE_NOTIFY_EXPORT_PACK,
                 (EFI_HII_PACKAGE_HEADER *) Package,
                 EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
                 Handle
                 );
      ASSERT_EFI_ERROR (Status);

      //
      // Copy Keyboard Layout package
      //
      CopyMem (Buffer, Package->KeyboardPkg, PackageHeader.Length);
      Buffer = (UINT8 *) Buffer + PackageHeader.Length;
    }
  }

  *ResultSize += PackageLength;
  return EFI_SUCCESS;
}


/**
  This function deletes all Keyboard Layout packages from a package list node.
  This is a internal function.

  @param  Private                Hii database private data.
  @param  Handle                 Handle of the package list which contains the to
                                 be  removed Keyboard Layout packages.
  @param  PackageList            Pointer to a package list that contains removing
                                 packages.

  @retval EFI_SUCCESS            Keyboard Layout Package(s) is deleted
                                 successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is not valid.

**/
EFI_STATUS
RemoveKeyboardLayoutPackages (
  IN     HII_DATABASE_PRIVATE_DATA          *Private,
  IN     EFI_HII_HANDLE                     Handle,
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList
  )
{
  LIST_ENTRY                           *ListHead;
  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;
  EFI_HII_PACKAGE_HEADER               PackageHeader;
  EFI_STATUS                           Status;

  ListHead = &PackageList->KeyboardLayoutHdr;

  while (!IsListEmpty (ListHead)) {
    Package = CR (
                ListHead->ForwardLink,
                HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
                KeyboardEntry,
                HII_KB_LAYOUT_PACKAGE_SIGNATURE
                );
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
               (VOID *) Package,
               EFI_HII_PACKAGE_KEYBOARD_LAYOUT,
               Handle
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    RemoveEntryList (&Package->KeyboardEntry);
    CopyMem (&PackageHeader, Package->KeyboardPkg, sizeof (EFI_HII_PACKAGE_HEADER));
    PackageList->PackageListHdr.PackageLength -= PackageHeader.Length;
    FreePool (Package->KeyboardPkg);
    FreePool (Package);
  }

  return EFI_SUCCESS;
}


/**
  This function will insert a package list to hii database firstly then
  invoke notification functions if any. It is the worker function of
  HiiNewPackageList and HiiUpdatePackageList.

  This is a internal function.

  @param  Private                Hii database private structure.
  @param  NotifyType             The type of change concerning the database.
  @param  PackageList            Pointer to a package list.
  @param  DatabaseRecord         Pointer to a database record contains  a package
                                 list instance which will be inserted to.

  @retval EFI_SUCCESS            All incoming packages are inserted to current
                                 database.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 Device path package.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
AddPackages (
  IN HII_DATABASE_PRIVATE_DATA         *Private,
  IN EFI_HII_DATABASE_NOTIFY_TYPE      NotifyType,
  IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
  IN OUT   HII_DATABASE_RECORD         *DatabaseRecord
  )
{
  EFI_STATUS                           Status;
  HII_GUID_PACKAGE_INSTANCE            *GuidPackage;
  HII_IFR_PACKAGE_INSTANCE             *FormPackage;
  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *KeyboardLayoutPackage;
  HII_STRING_PACKAGE_INSTANCE          *StringPackage;
  HII_FONT_PACKAGE_INSTANCE            *FontPackage;
  HII_SIMPLE_FONT_PACKAGE_INSTANCE     *SimpleFontPackage;
  HII_IMAGE_PACKAGE_INSTANCE           *ImagePackage;
  EFI_HII_PACKAGE_HEADER               *PackageHdrPtr;
  EFI_HII_PACKAGE_HEADER               PackageHeader;
  UINT32                               OldPackageListLen;

  //
  // Initialize Variables
  //
  FontPackage = NULL;

  //
  // Process the package list header
  //
  OldPackageListLen = DatabaseRecord->PackageList->PackageListHdr.PackageLength;
  CopyMem (
    &DatabaseRecord->PackageList->PackageListHdr,
    (VOID *) PackageList,
    sizeof (EFI_HII_PACKAGE_LIST_HEADER)
    );
  if (NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
    DatabaseRecord->PackageList->PackageListHdr.PackageLength = OldPackageListLen;
  }

  PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));
  CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));

  Status = EFI_SUCCESS;

  while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
    switch (PackageHeader.Type) {
    case EFI_HII_PACKAGE_TYPE_GUID:
      Status = InsertGuidPackage (
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &GuidPackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) GuidPackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_FORMS:
      Status = InsertFormPackage (
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &FormPackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) FormPackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
      Status = InsertKeyboardLayoutPackage (
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &KeyboardLayoutPackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) KeyboardLayoutPackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_STRINGS:
      Status = InsertStringPackage (
                 Private,
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &StringPackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) StringPackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_FONTS:
      Status = InsertFontPackage (
                 Private,
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &FontPackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) FontPackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_IMAGES:
      Status = InsertImagePackage (
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &ImagePackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) ImagePackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_SIMPLE_FONTS:
      Status = InsertSimpleFontPackage (
                 PackageHdrPtr,
                 NotifyType,
                 DatabaseRecord->PackageList,
                 &SimpleFontPackage
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = InvokeRegisteredFunction (
                 Private,
                 NotifyType,
                 (VOID *) SimpleFontPackage,
                 (UINT8) (PackageHeader.Type),
                 DatabaseRecord->Handle
                 );
      break;
    case EFI_HII_PACKAGE_DEVICE_PATH:
      Status = AddDevicePathPackage (
                 Private,
                 NotifyType,
                 (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 *) PackageHdrPtr + sizeof (EFI_HII_PACKAGE_HEADER)),
                 DatabaseRecord
                 );
      break;
    default:
      break;
    }

    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // goto header of next package
    //
    PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
    CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
  }

  return Status;
}


/**
  This function exports a package list to a buffer. It is the worker function
  of HiiExportPackageList.

  This is a internal function.

  @param  Private                Hii database private structure.
  @param  Handle                 Identification of a package list.
  @param  PackageList            Pointer to a package list which will be exported.
  @param  UsedSize               The length of buffer has been used by exporting
                                 package lists when Handle is NULL.
  @param  BufferSize             Length of the Buffer.
  @param  Buffer                 Allocated space for storing exported data.

  @retval EFI_SUCCESS            Keyboard Layout Packages are exported
                                 successfully.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
ExportPackageList (
  IN HII_DATABASE_PRIVATE_DATA          *Private,
  IN EFI_HII_HANDLE                     Handle,
  IN HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,
  IN OUT UINTN                          *UsedSize,
  IN UINTN                              BufferSize,
  OUT EFI_HII_PACKAGE_LIST_HEADER       *Buffer
  )
{
  EFI_STATUS                          Status;
  UINTN                               ResultSize;
  EFI_HII_PACKAGE_HEADER              EndofPackageList;

  ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL);
  ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
  ASSERT (IsHiiHandleValid (Handle));

  if (BufferSize > 0 && Buffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Copy the package list header
  // ResultSize indicates the length of the exported bytes of this package list
  //
  ResultSize = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
  if (ResultSize + *UsedSize <= BufferSize) {
    CopyMem ((VOID *) Buffer, PackageList, ResultSize);
  }
  //
  // Copy the packages and invoke EXPORT_PACK notify functions if exists.
  //
  Status = ExportGuidPackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportFormPackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportKeyboardLayoutPackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportStringPackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportFontPackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportImagePackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportSimpleFontPackages (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = ExportDevicePathPackage (
             Private,
             Handle,
             PackageList,
             *UsedSize,
             BufferSize,
             (VOID *) ((UINT8 *) Buffer + ResultSize),
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Append the package list end.
  //
  EndofPackageList.Length = sizeof (EFI_HII_PACKAGE_HEADER);
  EndofPackageList.Type   = EFI_HII_PACKAGE_END;
  if (ResultSize + *UsedSize + sizeof (EFI_HII_PACKAGE_HEADER) <= BufferSize) {
    CopyMem (
      (VOID *) ((UINT8 *) Buffer + ResultSize),
      (VOID *) &EndofPackageList,
      sizeof (EFI_HII_PACKAGE_HEADER)
      );
  }

  *UsedSize += ResultSize + sizeof (EFI_HII_PACKAGE_HEADER);

  return EFI_SUCCESS;
}


/**
  This function adds the packages in the package list to the database and returns a handle. If there is a
  EFI_DEVICE_PATH_PROTOCOL associated with the DriverHandle, then this function will
  create a package of type EFI_PACKAGE_TYPE_DEVICE_PATH and add it to the package list.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  PackageList            A pointer to an EFI_HII_PACKAGE_LIST_HEADER
                                 structure.
  @param  DriverHandle           Associate the package list with this EFI handle.
  @param  Handle                 A pointer to the EFI_HII_HANDLE instance.

  @retval EFI_SUCCESS            The package list associated with the Handle was
                                 added to the HII database.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary resources for the new
                                 database contents.
  @retval EFI_INVALID_PARAMETER  PackageList is NULL or Handle is NULL.
  @retval EFI_INVALID_PARAMETER  PackageListGuid already exists in database.

**/
EFI_STATUS
EFIAPI
HiiNewPackageList (
  IN CONST EFI_HII_DATABASE_PROTOCOL    *This,
  IN CONST EFI_HII_PACKAGE_LIST_HEADER  *PackageList,
  IN CONST EFI_HANDLE                   DriverHandle,
  OUT EFI_HII_HANDLE                    *Handle
  )
{
  EFI_STATUS                          Status;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *DatabaseRecord;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  LIST_ENTRY                          *Link;
  EFI_GUID                            PackageListGuid;

  if (This == NULL || PackageList == NULL || Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  CopyMem (&PackageListGuid, (VOID *) PackageList, sizeof (EFI_GUID));

  //
  // Check the Package list GUID to guarantee this GUID is unique in database.
  //
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (CompareGuid (
          &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),
          &PackageListGuid) && 
        DatabaseRecord->DriverHandle == DriverHandle) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Build a PackageList node
  //
  Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Fill in information of the created Package List node
  // according to incoming package list.
  //
  Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DatabaseRecord->DriverHandle = DriverHandle;

  //
  // Create a Device path package and add into the package list if exists.
  //
  Status = gBS->HandleProtocol (
                  DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath
                  );
  if (!EFI_ERROR (Status)) {
    Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);
    ASSERT_EFI_ERROR (Status);
  }

  *Handle = DatabaseRecord->Handle;
  return EFI_SUCCESS;
}


/**
  This function removes the package list that is associated with a handle Handle
  from the HII database. Before removing the package, any registered functions
  with the notification type REMOVE_PACK and the same package type will be called.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  Handle                 The handle that was registered to the data that is
                                 requested  for removal.

  @retval EFI_SUCCESS            The data associated with the Handle was removed
                                 from  the HII database.
  @retval EFI_NOT_FOUND          The specified andle is not in database.
  @retval EFI_INVALID_PARAMETER  The Handle was not valid.

**/
EFI_STATUS
EFIAPI
HiiRemovePackageList (
  IN CONST EFI_HII_DATABASE_PROTOCOL    *This,
  IN EFI_HII_HANDLE                     Handle
  )
{
  EFI_STATUS                          Status;
  HII_DATABASE_PRIVATE_DATA           *Private;
  LIST_ENTRY                          *Link;
  HII_DATABASE_RECORD                 *Node;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageList;
  HII_HANDLE                          *HiiHandle;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (Handle)) {
    return EFI_NOT_FOUND;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  //
  // Get the packagelist to be removed.
  //
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (Node->Handle == Handle) {
      PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
      ASSERT (PackageList != NULL);

      //
      // Call registered functions with REMOVE_PACK before removing packages
      // then remove them.
      //
      Status = RemoveGuidPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveFormPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveStringPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveFontPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveImagePackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveDevicePathPackage (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Free resources of the package list
      //
      RemoveEntryList (&Node->DatabaseEntry);

      HiiHandle = (HII_HANDLE *) Handle;
      RemoveEntryList (&HiiHandle->Handle);
      Private->HiiHandleCount--;
      ASSERT (Private->HiiHandleCount >= 0);

      HiiHandle->Signature = 0;
      FreePool (HiiHandle);
      FreePool (Node->PackageList);
      FreePool (Node);

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}


/**
  This function updates the existing package list (which has the specified Handle)
  in the HII databases, using the new package list specified by PackageList.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  Handle                 The handle that was registered to the data that is
                                  requested to be updated.
  @param  PackageList            A pointer to an EFI_HII_PACKAGE_LIST_HEADER
                                 package.

  @retval EFI_SUCCESS            The HII database was successfully updated.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate enough memory for the updated
                                 database.
  @retval EFI_INVALID_PARAMETER  PackageList was NULL.
  @retval EFI_NOT_FOUND          The specified Handle is not in database.

**/
EFI_STATUS
EFIAPI
HiiUpdatePackageList (
  IN CONST EFI_HII_DATABASE_PROTOCOL    *This,
  IN EFI_HII_HANDLE                     Handle,
  IN CONST EFI_HII_PACKAGE_LIST_HEADER  *PackageList
  )
{
  EFI_STATUS                          Status;
  HII_DATABASE_PRIVATE_DATA           *Private;
  LIST_ENTRY                          *Link;
  HII_DATABASE_RECORD                 *Node;
  EFI_HII_PACKAGE_HEADER              *PackageHdrPtr;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *OldPackageList;
  EFI_HII_PACKAGE_HEADER              PackageHeader;

  if (This == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (Handle)) {
    return EFI_NOT_FOUND;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));

  Status = EFI_SUCCESS;

  //
  // Get original packagelist to be updated
  //
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (Node->Handle == Handle) {
      OldPackageList = Node->PackageList;
      //
      // Remove the package if its type matches one of the package types which is
      // contained in the new package list.
      //
      CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
      while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
        switch (PackageHeader.Type) {
        case EFI_HII_PACKAGE_TYPE_GUID:
          Status = RemoveGuidPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_FORMS:
          Status = RemoveFormPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
          Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_STRINGS:
          Status = RemoveStringPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_FONTS:
          Status = RemoveFontPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_IMAGES:
          Status = RemoveImagePackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_SIMPLE_FONTS:
          Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_DEVICE_PATH:
          Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);
          break;
        }

        if (EFI_ERROR (Status)) {
          return Status;
        }

        PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
        CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
      }

      //
      // Add all of the packages within the new package list
      //
      return AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);
    }
  }

  return EFI_NOT_FOUND;
}


/**
  This function returns a list of the package handles of the specified type
  that are currently active in the database. The pseudo-type
  EFI_HII_PACKAGE_TYPE_ALL will cause all package handles to be listed.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  PackageType            Specifies the package type of the packages to list
                                 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
                                 listed.
  @param  PackageGuid            If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
                                 this  is the pointer to the GUID which must match
                                 the Guid field of EFI_HII_GUID_PACKAGE_GUID_HDR.
                                 Otherwise,  it must be NULL.
  @param  HandleBufferLength     On input, a pointer to the length of the handle
                                 buffer.  On output, the length of the handle
                                 buffer that is required for the handles found.
  @param  Handle                 An array of EFI_HII_HANDLE instances returned.

  @retval EFI_SUCCESS            The matching handles are outputed successfully.
                                               HandleBufferLength is updated with the actual length.
  @retval EFI_BUFFER_TO_SMALL    The HandleBufferLength parameter indicates that
                                 Handle is too small to support the number of
                                 handles. HandleBufferLength is updated with a
                                 value that will  enable the data to fit.
  @retval EFI_NOT_FOUND          No matching handle could not be found in database.
  @retval EFI_INVALID_PARAMETER  Handle or HandleBufferLength was NULL.
  
  @retval EFI_INVALID_PARAMETER  PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but
                                                     PackageGuid is not NULL, PackageType is a EFI_HII_
                                                     PACKAGE_TYPE_GUID but PackageGuid is NULL.

**/
EFI_STATUS
EFIAPI
HiiListPackageLists (
  IN  CONST EFI_HII_DATABASE_PROTOCOL   *This,
  IN  UINT8                             PackageType,
  IN  CONST EFI_GUID                    *PackageGuid,
  IN  OUT UINTN                         *HandleBufferLength,
  OUT EFI_HII_HANDLE                    *Handle
  )
{
  HII_GUID_PACKAGE_INSTANCE           *GuidPackage;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *Node;
  LIST_ENTRY                          *Link;
  BOOLEAN                             Matched;
  HII_HANDLE                          **Result;
  UINTN                               ResultSize;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageList;
  LIST_ENTRY                          *Link1;

  //
  // Check input parameters
  //
  if (This == NULL || HandleBufferLength == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (*HandleBufferLength > 0 && Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
      (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Private    = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  Matched    = FALSE;
  Result     = (HII_HANDLE **) Handle;
  ResultSize = 0;

  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
    switch (PackageType) {
      case EFI_HII_PACKAGE_TYPE_GUID:
        for (Link1 = PackageList->GuidPkgHdr.ForwardLink; Link1 != &PackageList->GuidPkgHdr; Link1 = Link1->ForwardLink) {
          GuidPackage = CR (Link1, HII_GUID_PACKAGE_INSTANCE, GuidEntry, HII_GUID_PACKAGE_SIGNATURE);
          if (CompareGuid (
                (EFI_GUID *) PackageGuid,
                (EFI_GUID *) (GuidPackage->GuidPkg + sizeof (EFI_HII_PACKAGE_HEADER))
                )) {
            Matched = TRUE;
            break;
          }
        }
        break;
      case EFI_HII_PACKAGE_FORMS:
        if (!IsListEmpty (&PackageList->FormPkgHdr)) {
          Matched = TRUE;
        }
        break;
      case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
        if (!IsListEmpty (&PackageList->KeyboardLayoutHdr)) {
          Matched = TRUE;
        }
        break;
      case EFI_HII_PACKAGE_STRINGS:
        if (!IsListEmpty (&PackageList->StringPkgHdr)) {
          Matched = TRUE;
        }
        break;
      case EFI_HII_PACKAGE_FONTS:
        if (!IsListEmpty (&PackageList->FontPkgHdr)) {
          Matched = TRUE;
        }
        break;
      case EFI_HII_PACKAGE_IMAGES:
        if (PackageList->ImagePkg != NULL) {
          Matched = TRUE;
        }
        break;
      case EFI_HII_PACKAGE_SIMPLE_FONTS:
        if (!IsListEmpty (&PackageList->SimpleFontPkgHdr)) {
          Matched = TRUE;
        }
        break;
      case EFI_HII_PACKAGE_DEVICE_PATH:
        if (PackageList->DevicePathPkg != NULL) {
          Matched = TRUE;
        }
        break;
        //
        // Pesudo-type EFI_HII_PACKAGE_TYPE_ALL will cause all package handles
        // to be listed.
        //
      case EFI_HII_PACKAGE_TYPE_ALL:
        Matched = TRUE;
        break;
      default:
        break;
    }

    //
    // This active package list has the specified package type, list it.
    //
    if (Matched) {
      ResultSize += sizeof (EFI_HII_HANDLE);
      if (ResultSize <= *HandleBufferLength) {
        *Result++ = Node->Handle;
      }
    }
    Matched = FALSE;
  }

  if (ResultSize == 0) {
    return EFI_NOT_FOUND;
  }

  if (*HandleBufferLength < ResultSize) {
    *HandleBufferLength = ResultSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  *HandleBufferLength = ResultSize;
  return EFI_SUCCESS;
}


/**
  This function will export one or all package lists in the database to a buffer.
  For each package list exported, this function will call functions registered
  with EXPORT_PACK and then copy the package list to the buffer.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  Handle                 An EFI_HII_HANDLE that corresponds to the desired
                                 package list in the HII database to export or NULL
                                 to indicate  all package lists should be exported.
  @param  BufferSize             On input, a pointer to the length of the buffer.
                                 On output, the length of the buffer that is
                                 required for the exported data.
  @param  Buffer                 A pointer to a buffer that will contain the
                                 results of  the export function.

  @retval EFI_SUCCESS            Package exported.
  @retval EFI_BUFFER_TO_SMALL    The HandleBufferLength parameter indicates that
                                 Handle is too small to support the number of
                                 handles.      HandleBufferLength is updated with a
                                 value that will enable the data to fit.
  @retval EFI_NOT_FOUND          The specifiecd Handle could not be found in the
                                 current database.
  @retval EFI_INVALID_PARAMETER  Handle or Buffer or BufferSize was NULL.

**/
EFI_STATUS
EFIAPI
HiiExportPackageLists (
  IN  CONST EFI_HII_DATABASE_PROTOCOL   *This,
  IN  EFI_HII_HANDLE                    Handle,
  IN  OUT UINTN                         *BufferSize,
  OUT EFI_HII_PACKAGE_LIST_HEADER       *Buffer
  )
{
  LIST_ENTRY                          *Link;
  EFI_STATUS                          Status;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *Node;
  UINTN                               UsedSize;

  if (This == NULL || BufferSize == NULL || Handle == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (*BufferSize > 0 && Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (!IsHiiHandleValid (Handle)) {
    return EFI_NOT_FOUND;
  }

  Private  = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  UsedSize = 0;

  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (Handle == NULL) {
      //
      // Export all package lists in current hii database.
      //
      Status = ExportPackageList (
                 Private,
                 Node->Handle,
                 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
                 &UsedSize,
                 *BufferSize,
                 (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize)
                 );
      ASSERT_EFI_ERROR (Status);
    } else if (Handle != NULL && Node->Handle == Handle) {
      Status = ExportPackageList (
                 Private,
                 Handle,
                 (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList),
                 &UsedSize,
                 *BufferSize,
                 Buffer
                 );
      ASSERT_EFI_ERROR (Status);
      if (*BufferSize < UsedSize) {
        *BufferSize = UsedSize;
        return EFI_BUFFER_TOO_SMALL;
      }
      return EFI_SUCCESS;
    }
  }

  if (Handle == NULL && UsedSize != 0) {
    if (*BufferSize < UsedSize) {
      *BufferSize = UsedSize;
      return EFI_BUFFER_TOO_SMALL;
    }
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}


/**
  This function registers a function which will be called when specified actions related to packages of
  the specified type occur in the HII database. By registering a function, other HII-related drivers are
  notified when specific package types are added, removed or updated in the HII database.
  Each driver or application which registers a notification should use
  EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify() before exiting.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  PackageType            Specifies the package type of the packages to list
                                 or EFI_HII_PACKAGE_TYPE_ALL for all packages to be
                                 listed.
  @param  PackageGuid            If PackageType is EFI_HII_PACKAGE_TYPE_GUID, then
                                 this is the pointer to the GUID which must match
                                 the Guid field of
                                 EFI_HII_GUID_PACKAGE_GUID_HDR. Otherwise, it must
                                 be NULL.
  @param  PackageNotifyFn        Points to the function to be called when the event
                                 specified by
                                 NotificationType occurs.
  @param  NotifyType             Describes the types of notification which this
                                 function will be receiving.
  @param  NotifyHandle           Points to the unique handle assigned to the
                                 registered notification. Can be used in
                                 EFI_HII_DATABASE_PROTOCOL.UnregisterPackageNotify()
                                 to stop notifications.

  @retval EFI_SUCCESS            Notification registered successfully.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate necessary data structures
  @retval EFI_INVALID_PARAMETER  NotifyHandle is NULL.
  @retval EFI_INVALID_PARAMETER  PackageGuid is not NULL when PackageType is not
                                 EFI_HII_PACKAGE_TYPE_GUID.
  @retval EFI_INVALID_PARAMETER  PackageGuid is NULL when PackageType is
                                 EFI_HII_PACKAGE_TYPE_GUID.

**/
EFI_STATUS
EFIAPI
HiiRegisterPackageNotify (
  IN  CONST EFI_HII_DATABASE_PROTOCOL   *This,
  IN  UINT8                             PackageType,
  IN  CONST EFI_GUID                    *PackageGuid,
  IN  CONST EFI_HII_DATABASE_NOTIFY     PackageNotifyFn,
  IN  EFI_HII_DATABASE_NOTIFY_TYPE      NotifyType,
  OUT EFI_HANDLE                        *NotifyHandle
  )
{
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_NOTIFY                 *Notify;
  EFI_STATUS                          Status;

  if (This == NULL || NotifyHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
      (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  //
  // Allocate a notification node
  //
  Notify = (HII_DATABASE_NOTIFY *) AllocateZeroPool (sizeof (HII_DATABASE_NOTIFY));
  if (Notify == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Generate a notify handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Notify->NotifyHandle,
                  &mHiiDatabaseNotifyGuid,
                  NULL,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Fill in the information to the notification node
  //
  Notify->Signature       = HII_DATABASE_NOTIFY_SIGNATURE;
  Notify->PackageType     = PackageType;
  Notify->PackageGuid     = (EFI_GUID *) PackageGuid;
  Notify->PackageNotifyFn = (EFI_HII_DATABASE_NOTIFY) PackageNotifyFn;
  Notify->NotifyType      = NotifyType;

  InsertTailList (&Private->DatabaseNotifyList, &Notify->DatabaseNotifyEntry);
  *NotifyHandle = Notify->NotifyHandle;

  return EFI_SUCCESS;
}


/**
  Removes the specified HII database package-related notification.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  NotificationHandle     The handle of the notification function being
                                 unregistered.

  @retval EFI_SUCCESS            Notification is unregistered successfully.
  @retval EFI_INVALID_PARAMETER  The Handle is invalid.
  @retval EFI_NOT_FOUND          The incoming notification handle does not exist
                                 in current hii database.

**/
EFI_STATUS
EFIAPI
HiiUnregisterPackageNotify (
  IN CONST EFI_HII_DATABASE_PROTOCOL    *This,
  IN EFI_HANDLE                         NotificationHandle
  )
{
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_NOTIFY                 *Notify;
  LIST_ENTRY                          *Link;
  EFI_STATUS                          Status;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (NotificationHandle == NULL) {
    return EFI_NOT_FOUND;
  }

  Status = gBS->OpenProtocol (
                  NotificationHandle,
                  &mHiiDatabaseNotifyGuid,
                  NULL,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  for (Link = Private->DatabaseNotifyList.ForwardLink; Link != &Private->DatabaseNotifyList; Link = Link->ForwardLink) {
    Notify = CR (Link, HII_DATABASE_NOTIFY, DatabaseNotifyEntry, HII_DATABASE_NOTIFY_SIGNATURE);
    if (Notify->NotifyHandle == NotificationHandle) {
      //
      // Remove the matching notification node
      //
      RemoveEntryList (&Notify->DatabaseNotifyEntry);
      Status = gBS->UninstallMultipleProtocolInterfaces (
                      Notify->NotifyHandle,
                      &mHiiDatabaseNotifyGuid,
                      NULL,
                      NULL
                      );
      ASSERT_EFI_ERROR (Status);
      FreePool (Notify);

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}


/**
  This routine retrieves an array of GUID values for each keyboard layout that
  was previously registered in the system.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  KeyGuidBufferLength    On input, a pointer to the length of the keyboard
                                 GUID  buffer. On output, the length of the handle
                                 buffer  that is required for the handles found.
  @param  KeyGuidBuffer          An array of keyboard layout GUID instances
                                 returned.

  @retval EFI_SUCCESS            KeyGuidBuffer was updated successfully.
  @retval EFI_BUFFER_TOO_SMALL   The KeyGuidBufferLength parameter indicates
                                 that KeyGuidBuffer is too small to support the
                                 number of GUIDs. KeyGuidBufferLength is
                                 updated with a value that will enable the data to
                                 fit.
  @retval EFI_INVALID_PARAMETER  The KeyGuidBuffer or KeyGuidBufferLength was NULL.
  @retval EFI_NOT_FOUND          There was no keyboard layout.

**/
EFI_STATUS
EFIAPI
HiiFindKeyboardLayouts (
  IN  CONST EFI_HII_DATABASE_PROTOCOL   *This,
  IN  OUT UINT16                        *KeyGuidBufferLength,
  OUT EFI_GUID                          *KeyGuidBuffer
  )
{
  HII_DATABASE_PRIVATE_DATA            *Private;
  HII_DATABASE_RECORD                  *Node;
  HII_DATABASE_PACKAGE_LIST_INSTANCE   *PackageList;
  LIST_ENTRY                           *Link;
  LIST_ENTRY                           *Link1;
  UINT16                               ResultSize;
  UINTN                                Index;
  UINT16                               LayoutCount;
  UINT16                               LayoutLength;
  UINT8                                *Layout;
  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;

  if (This == NULL || KeyGuidBufferLength == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (*KeyGuidBufferLength > 0 && KeyGuidBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private     = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  ResultSize  = 0;

  //
  // Search all package lists in whole database to retrieve keyboard layout.
  //
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    PackageList = Node->PackageList;
    for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
         Link1 != &PackageList->KeyboardLayoutHdr;
         Link1 = Link1->ForwardLink
        ) {
      //
      // Find out all Keyboard Layout packages in this package list.
      //
      Package = CR (
                  Link1,
                  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
                  KeyboardEntry,
                  HII_KB_LAYOUT_PACKAGE_SIGNATURE
                  );
      Layout = (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
      CopyMem (
        &LayoutCount,
        (UINT8 *) Package->KeyboardPkg + sizeof (EFI_HII_PACKAGE_HEADER),
        sizeof (UINT16)
        );
      for (Index = 0; Index < LayoutCount; Index++) {
        ResultSize += sizeof (EFI_GUID);
        if (ResultSize <= *KeyGuidBufferLength) {
          CopyMem (KeyGuidBuffer + (ResultSize / sizeof (EFI_GUID) - 1), Layout + sizeof (UINT16), sizeof (EFI_GUID));
          CopyMem (&LayoutLength, Layout, sizeof (UINT16));
          Layout = Layout + LayoutLength;
        }
      }
    }
  }

  if (ResultSize == 0) {
    return EFI_NOT_FOUND;
  }

  if (*KeyGuidBufferLength < ResultSize) {
    *KeyGuidBufferLength = ResultSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  *KeyGuidBufferLength = ResultSize;
  return EFI_SUCCESS;
}


/**
  This routine retrieves the requested keyboard layout. The layout is a physical description of the keys
  on a keyboard and the character(s) that are associated with a particular set of key strokes.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  KeyGuid                A pointer to the unique ID associated with a given
                                 keyboard layout. If KeyGuid is NULL then the
                                 current layout will be retrieved.
  @param  KeyboardLayoutLength   On input, a pointer to the length of the
                                 KeyboardLayout buffer.  On output, the length of
                                 the data placed into KeyboardLayout.
  @param  KeyboardLayout         A pointer to a buffer containing the retrieved
                                 keyboard layout.

  @retval EFI_SUCCESS            The keyboard layout was retrieved successfully.
  @retval EFI_NOT_FOUND          The requested keyboard layout was not found.
  @retval EFI_INVALID_PARAMETER  The KeyboardLayout or KeyboardLayoutLength was
                                 NULL.
  @retval EFI_BUFFER_TOO_SMALL   The KeyboardLayoutLength parameter indicates
                                 that KeyboardLayout is too small to support the
                                 requested keyboard layout. KeyboardLayoutLength is
                                        updated with a value that will enable the
                                 data to fit.

**/
EFI_STATUS
EFIAPI
HiiGetKeyboardLayout (
  IN  CONST EFI_HII_DATABASE_PROTOCOL   *This,
  IN  CONST EFI_GUID                          *KeyGuid,
  IN OUT UINT16                         *KeyboardLayoutLength,
  OUT EFI_HII_KEYBOARD_LAYOUT           *KeyboardLayout
  )
{
  HII_DATABASE_PRIVATE_DATA            *Private;
  HII_DATABASE_RECORD                  *Node;
  HII_DATABASE_PACKAGE_LIST_INSTANCE   *PackageList;
  LIST_ENTRY                           *Link;
  LIST_ENTRY                           *Link1;
  UINTN                                Index;
  UINT8                                *Layout;
  UINT16                               LayoutCount;
  UINT16                               LayoutLength;
  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE *Package;

  if (This == NULL || KeyboardLayoutLength == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (*KeyboardLayoutLength > 0 && KeyboardLayout == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  //
  // Retrieve the current keyboard layout.
  //
  if (KeyGuid == NULL) {
    if (Private->CurrentLayout == NULL) {
      return EFI_NOT_FOUND;
    }
    CopyMem (&LayoutLength, Private->CurrentLayout, sizeof (UINT16));
    if (*KeyboardLayoutLength < LayoutLength) {
      *KeyboardLayoutLength = LayoutLength;
      return EFI_BUFFER_TOO_SMALL;
    }
    CopyMem (KeyboardLayout, Private->CurrentLayout, LayoutLength);
    return EFI_SUCCESS;
  }

  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
    for (Link1 = PackageList->KeyboardLayoutHdr.ForwardLink;
         Link1 != &PackageList->KeyboardLayoutHdr;
         Link1 = Link1->ForwardLink
        ) {
      Package = CR (
                  Link1,
                  HII_KEYBOARD_LAYOUT_PACKAGE_INSTANCE,
                  KeyboardEntry,
                  HII_KB_LAYOUT_PACKAGE_SIGNATURE
                  );

      Layout = (UINT8 *) Package->KeyboardPkg +
               sizeof (EFI_HII_PACKAGE_HEADER) + sizeof (UINT16);
      CopyMem (&LayoutCount, Layout - sizeof (UINT16), sizeof (UINT16));
      for (Index = 0; Index < LayoutCount; Index++) {
        CopyMem (&LayoutLength, Layout, sizeof (UINT16));
        if (CompareMem (Layout + sizeof (UINT16), KeyGuid, sizeof (EFI_GUID)) == 0) {
          if (LayoutLength <= *KeyboardLayoutLength) {
            CopyMem (KeyboardLayout, Layout, LayoutLength);
            return EFI_SUCCESS;
          } else {
            *KeyboardLayoutLength = LayoutLength;
            return EFI_BUFFER_TOO_SMALL;
          }
        }
        Layout = Layout + LayoutLength;
      }
    }
  }

  return EFI_NOT_FOUND;
}


/**
  This routine sets the default keyboard layout to the one referenced by KeyGuid. When this routine
  is called, an event will be signaled of the EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID
  group type. This is so that agents which are sensitive to the current keyboard layout being changed
  can be notified of this change.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  KeyGuid                A pointer to the unique ID associated with a given
                                 keyboard layout.

  @retval EFI_SUCCESS            The current keyboard layout was successfully set.
  @retval EFI_NOT_FOUND          The referenced keyboard layout was not found, so
                                 action was taken.
  @retval EFI_INVALID_PARAMETER  The KeyGuid was NULL.

**/
EFI_STATUS
EFIAPI
HiiSetKeyboardLayout (
  IN CONST EFI_HII_DATABASE_PROTOCOL          *This,
  IN CONST EFI_GUID                           *KeyGuid
  )
{
  HII_DATABASE_PRIVATE_DATA            *Private;
  EFI_HII_KEYBOARD_LAYOUT              *KeyboardLayout;
  UINT16                               KeyboardLayoutLength;
  EFI_STATUS                           Status;

  if (This == NULL || KeyGuid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  //
  // The specified GUID equals the current keyboard layout GUID,
  // return directly.
  //
  if (CompareGuid (&Private->CurrentLayoutGuid, KeyGuid)) {
    return EFI_SUCCESS;
  }

  //
  // Try to find the incoming keyboard layout data in current database.
  //
  KeyboardLayoutLength = 0;
  KeyboardLayout       = NULL;
  Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return Status;
  }

  KeyboardLayout = (EFI_HII_KEYBOARD_LAYOUT *) AllocateZeroPool (KeyboardLayoutLength);
  ASSERT (KeyboardLayout != NULL);
  Status = HiiGetKeyboardLayout (This, KeyGuid, &KeyboardLayoutLength, KeyboardLayout);
  ASSERT_EFI_ERROR (Status);

  //
  // Backup current keyboard layout.
  //
  CopyMem (&Private->CurrentLayoutGuid, KeyGuid, sizeof (EFI_GUID));
  if (Private->CurrentLayout != NULL) {
    FreePool(Private->CurrentLayout);
  }
  Private->CurrentLayout = KeyboardLayout;

  //
  // Signal EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID group to notify
  // current keyboard layout is changed.
  //
  Status = gBS->SignalEvent (gHiiKeyboardLayoutChanged);
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}


/**
  Return the EFI handle associated with a package list.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  PackageListHandle      An EFI_HII_HANDLE that corresponds to the desired
                                 package list in the HIIdatabase.
  @param  DriverHandle           On return, contains the EFI_HANDLE which was
                                 registered with the package list in
                                 NewPackageList().

  @retval EFI_SUCCESS            The DriverHandle was returned successfully.
  @retval EFI_INVALID_PARAMETER  The PackageListHandle was not valid or
                                 DriverHandle was NULL.
  @retval EFI_NOT_FOUND          This PackageList handle can not be found in
                                 current database.

**/
EFI_STATUS
EFIAPI
HiiGetPackageListHandle (
  IN  CONST EFI_HII_DATABASE_PROTOCOL         *This,
  IN  EFI_HII_HANDLE                    PackageListHandle,
  OUT EFI_HANDLE                        *DriverHandle
  )
{
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *Node;
  LIST_ENTRY                          *Link;

  if (This == NULL || DriverHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (PackageListHandle)) {
    return EFI_INVALID_PARAMETER;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (Node->Handle == PackageListHandle) {
      *DriverHandle = Node->DriverHandle;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

