/** @file
Implementation for EFI_HII_DATABASE_PROTOCOL.

Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HiiDatabase.h"

#define BASE_NUMBER  10

EFI_HII_PACKAGE_LIST_HEADER  *gRTDatabaseInfoBuffer = NULL;
EFI_STRING                   gRTConfigRespBuffer    = NULL;
UINTN                        gDatabaseInfoSize      = 0;
UINTN                        gConfigRespSize        = 0;
BOOLEAN                      gExportConfigResp      = FALSE;
UINTN                        gNvDefaultStoreSize    = 0;
SKU_ID                       gSkuId                 = 0xFFFFFFFFFFFFFFFF;
LIST_ENTRY                   gVarStorageList        = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);

//
// HII database lock.
//
EFI_LOCK  mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);

/**
  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 = (UINTN)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 package

  @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;
}

/**
  Check the input question related to EFI variable

  @param IfrQuestionHdr     Point to Question header
  @param EfiVarStoreList    Point to EFI VarStore List
  @param EfiVarStoreNumber  The number of EFI VarStore

  @retval Index             The index of the found EFI varstore in EFI varstore list
                            EfiVarStoreNumber will return if no EFI varstore is found.
**/
UINTN
IsEfiVarStoreQuestion (
  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr,
  EFI_IFR_VARSTORE_EFI     **EfiVarStoreList,
  UINTN                    EfiVarStoreNumber
  )
{
  UINTN  Index;

  for (Index = 0; Index < EfiVarStoreNumber; Index++) {
    if (IfrQuestionHdr->VarStoreId == EfiVarStoreList[Index]->VarStoreId) {
      return Index;
    }
  }

  return EfiVarStoreNumber;
}

/**
  Find the matched variable from the input variable storage.

  @param[in] VariableStorage Point to the variable storage header.
  @param[in] VarGuid         A unique identifier for the variable.
  @param[in] VarAttribute    The attributes bitmask for the variable.
  @param[in] VarName         A Null-terminated ascii string that is the name of the variable.

  @return Pointer to the matched variable header or NULL if not found.
**/
VARIABLE_HEADER *
FindVariableData (
  IN  VARIABLE_STORE_HEADER  *VariableStorage,
  IN  EFI_GUID               *VarGuid,
  IN  UINT32                 VarAttribute,
  IN  CHAR16                 *VarName
  )
{
  VARIABLE_HEADER  *VariableHeader;
  VARIABLE_HEADER  *VariableEnd;

  VariableEnd    = (VARIABLE_HEADER *)((UINT8 *)VariableStorage + VariableStorage->Size);
  VariableHeader = (VARIABLE_HEADER *)(VariableStorage + 1);
  VariableHeader = (VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
  while (VariableHeader < VariableEnd) {
    if (CompareGuid (&VariableHeader->VendorGuid, VarGuid) &&
        (VariableHeader->Attributes == VarAttribute) &&
        (StrCmp (VarName, (CHAR16 *)(VariableHeader + 1)) == 0))
    {
      return VariableHeader;
    }

    VariableHeader = (VARIABLE_HEADER *)((UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize);
    VariableHeader = (VARIABLE_HEADER *)HEADER_ALIGN (VariableHeader);
  }

  return NULL;
}

/**
  Find question default value from PcdNvStoreDefaultValueBuffer

  @param DefaultId          Default store ID
  @param EfiVarStore        Point to EFI VarStore header
  @param IfrQuestionHdr     Point to Question header
  @param ValueBuffer        Point to Buffer includes the found default setting
  @param Width              Width of the default value
  @param BitFieldQuestion   Whether the Question is stored in Bit field.

  @retval EFI_SUCCESS       Question default value is found.
  @retval EFI_NOT_FOUND     Question default value is not found.
**/
EFI_STATUS
FindQuestionDefaultSetting (
  IN  UINT16                   DefaultId,
  IN  EFI_IFR_VARSTORE_EFI     *EfiVarStore,
  IN  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr,
  OUT VOID                     *ValueBuffer,
  IN  UINTN                    Width,
  IN  BOOLEAN                  BitFieldQuestion
  )
{
  VARIABLE_HEADER          *VariableHeader;
  VARIABLE_STORE_HEADER    *VariableStorage;
  LIST_ENTRY               *Link;
  VARSTORAGE_DEFAULT_DATA  *Entry;
  VARIABLE_STORE_HEADER    *NvStoreBuffer;
  UINT8                    *DataBuffer;
  UINT8                    *BufferEnd;
  BOOLEAN                  IsFound;
  UINTN                    Index;
  UINT32                   BufferValue;
  UINT32                   BitFieldVal;
  UINTN                    BitOffset;
  UINTN                    ByteOffset;
  UINTN                    BitWidth;
  UINTN                    StartBit;
  UINTN                    EndBit;
  PCD_DEFAULT_DATA         *DataHeader;
  PCD_DEFAULT_INFO         *DefaultInfo;
  PCD_DATA_DELTA           *DeltaData;

  if (gSkuId == 0xFFFFFFFFFFFFFFFF) {
    gSkuId = LibPcdGetSku ();
  }

  //
  // Find the DefaultId setting from the full DefaultSetting
  //
  VariableStorage = NULL;
  Link            = gVarStorageList.ForwardLink;
  while (Link != &gVarStorageList) {
    Entry = BASE_CR (Link, VARSTORAGE_DEFAULT_DATA, Entry);
    if (Entry->DefaultId == DefaultId) {
      VariableStorage = Entry->VariableStorage;
      break;
    }

    Link = Link->ForwardLink;
  }

  if (Link == &gVarStorageList) {
    DataBuffer          = (UINT8 *)PcdGetPtr (PcdNvStoreDefaultValueBuffer);
    gNvDefaultStoreSize = ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Length;
    //
    // The first section data includes NV storage default setting.
    //
    DataHeader      = (PCD_DEFAULT_DATA *)(DataBuffer + sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER));
    NvStoreBuffer   = (VARIABLE_STORE_HEADER *)((UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize);
    VariableStorage = AllocatePool (NvStoreBuffer->Size);
    ASSERT (VariableStorage != NULL);
    CopyMem (VariableStorage, NvStoreBuffer, NvStoreBuffer->Size);

    //
    // Find the matched SkuId and DefaultId in the first section
    //
    IsFound     = FALSE;
    DefaultInfo = &(DataHeader->DefaultInfo[0]);
    BufferEnd   = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
    while ((UINT8 *)DefaultInfo < BufferEnd) {
      if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == gSkuId)) {
        IsFound = TRUE;
        break;
      }

      DefaultInfo++;
    }

    //
    // Find the matched SkuId and DefaultId in the remaining section
    //
    Index      = sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHeader->DataSize + 7) & (~7));
    DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
    while (!IsFound && Index < gNvDefaultStoreSize && DataHeader->DataSize != 0xFFFF) {
      DefaultInfo = &(DataHeader->DefaultInfo[0]);
      BufferEnd   = (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + DataHeader->HeaderSize;
      while ((UINT8 *)DefaultInfo < BufferEnd) {
        if ((DefaultInfo->DefaultId == DefaultId) && (DefaultInfo->SkuId == gSkuId)) {
          IsFound = TRUE;
          break;
        }

        DefaultInfo++;
      }

      if (IsFound) {
        DeltaData = (PCD_DATA_DELTA *)BufferEnd;
        BufferEnd = (UINT8 *)DataHeader + DataHeader->DataSize;
        while ((UINT8 *)DeltaData < BufferEnd) {
          *((UINT8 *)VariableStorage + DeltaData->Offset) = (UINT8)DeltaData->Value;
          DeltaData++;
        }

        break;
      }

      Index      = (Index + DataHeader->DataSize + 7) & (~7);
      DataHeader = (PCD_DEFAULT_DATA *)(DataBuffer + Index);
    }

    //
    // Cache the found result in VarStorageList
    //
    if (!IsFound) {
      FreePool (VariableStorage);
      VariableStorage = NULL;
    }

    Entry = AllocatePool (sizeof (VARSTORAGE_DEFAULT_DATA));
    if (Entry != NULL) {
      Entry->DefaultId       = DefaultId;
      Entry->VariableStorage = VariableStorage;
      InsertTailList (&gVarStorageList, &Entry->Entry);
    } else if (VariableStorage != NULL) {
      FreePool (VariableStorage);
      VariableStorage = NULL;
    }
  }

  //
  // The matched variable storage is not found.
  //
  if (VariableStorage == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Find the question default value from the variable storage
  //
  VariableHeader = FindVariableData (VariableStorage, &EfiVarStore->Guid, EfiVarStore->Attributes, (CHAR16 *)EfiVarStore->Name);
  if (VariableHeader == NULL) {
    return EFI_NOT_FOUND;
  }

  StartBit   = 0;
  EndBit     = 0;
  ByteOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
  if (BitFieldQuestion) {
    BitOffset  = IfrQuestionHdr->VarStoreInfo.VarOffset;
    ByteOffset = BitOffset / 8;
    BitWidth   = Width;
    StartBit   = BitOffset % 8;
    EndBit     = StartBit + BitWidth - 1;
    Width      = EndBit / 8 + 1;
  }

  if (VariableHeader->DataSize < ByteOffset + Width) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Copy the question value
  //
  if (ValueBuffer != NULL) {
    if (BitFieldQuestion) {
      CopyMem (&BufferValue, (UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + ByteOffset, Width);
      BitFieldVal = BitFieldRead32 (BufferValue, StartBit, EndBit);
      CopyMem (ValueBuffer, &BitFieldVal, Width);
    } else {
      CopyMem (ValueBuffer, (UINT8 *)VariableHeader + sizeof (VARIABLE_HEADER) + VariableHeader->NameSize + IfrQuestionHdr->VarStoreInfo.VarOffset, Width);
    }
  }

  return EFI_SUCCESS;
}

/**
  Update IFR default setting in Form Package.

  @param  FormPackage              Form Package to be updated

**/
VOID
UpdateDefaultSettingInFormPackage (
  HII_IFR_PACKAGE_INSTANCE  *FormPackage
  )
{
  UINTN                    IfrOffset;
  UINTN                    PackageLength;
  EFI_IFR_VARSTORE_EFI     *IfrEfiVarStore;
  EFI_IFR_OP_HEADER        *IfrOpHdr;
  EFI_IFR_ONE_OF_OPTION    *IfrOneOfOption;
  UINT8                    IfrQuestionType;
  UINT8                    IfrScope;
  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;
  EFI_IFR_VARSTORE_EFI     **EfiVarStoreList;
  UINTN                    EfiVarStoreMaxNum;
  UINTN                    EfiVarStoreNumber;
  UINT16                   *DefaultIdList;
  UINTN                    DefaultIdNumber;
  UINTN                    DefaultIdMaxNum;
  UINTN                    Index;
  UINTN                    EfiVarStoreIndex;
  EFI_IFR_TYPE_VALUE       IfrValue;
  EFI_IFR_TYPE_VALUE       IfrManufactValue;
  BOOLEAN                  StandardDefaultIsSet;
  BOOLEAN                  ManufactDefaultIsSet;
  EFI_IFR_CHECKBOX         *IfrCheckBox;
  EFI_STATUS               Status;
  EFI_IFR_DEFAULT          *IfrDefault;
  UINTN                    Width;
  EFI_IFR_QUESTION_HEADER  VarStoreQuestionHeader;
  BOOLEAN                  QuestionReferBitField;

  //
  // If no default setting, do nothing
  //
  if (gNvDefaultStoreSize == 0) {
    gNvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);
  }

  if (gNvDefaultStoreSize < sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
    return;
  }

  ZeroMem (&VarStoreQuestionHeader, sizeof (VarStoreQuestionHeader));
  PackageLength         = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
  Width                 = 0;
  IfrOffset             = 0;
  IfrScope              = 0;
  IfrOpHdr              = (EFI_IFR_OP_HEADER *)FormPackage->IfrData;
  IfrQuestionHdr        = NULL;
  IfrQuestionType       = 0;
  EfiVarStoreMaxNum     = 0;
  EfiVarStoreNumber     = 0;
  DefaultIdMaxNum       = 0;
  DefaultIdNumber       = 0;
  EfiVarStoreList       = NULL;
  DefaultIdList         = NULL;
  StandardDefaultIsSet  = FALSE;
  ManufactDefaultIsSet  = FALSE;
  QuestionReferBitField = FALSE;

  while (IfrOffset < PackageLength) {
    switch (IfrOpHdr->OpCode) {
      case EFI_IFR_VARSTORE_EFI_OP:
        if (EfiVarStoreNumber >= EfiVarStoreMaxNum) {
          //
          // Reallocate EFI VarStore Buffer
          //
          EfiVarStoreList = ReallocatePool (EfiVarStoreMaxNum * sizeof (UINTN), (EfiVarStoreMaxNum + BASE_NUMBER) * sizeof (UINTN), EfiVarStoreList);
          if (EfiVarStoreList == NULL) {
            goto Done;
          }

          EfiVarStoreMaxNum = EfiVarStoreMaxNum + BASE_NUMBER;
        }

        IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
        //
        // Convert VarStore Name from ASCII string to Unicode string.
        //
        EfiVarStoreList[EfiVarStoreNumber] = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));
        if (EfiVarStoreList[EfiVarStoreNumber] == NULL) {
          break;
        }

        CopyMem (EfiVarStoreList[EfiVarStoreNumber], IfrEfiVarStore, IfrEfiVarStore->Header.Length);
        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *)&(EfiVarStoreList[EfiVarStoreNumber]->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
        Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreNumber], &VarStoreQuestionHeader, NULL, IfrEfiVarStore->Size, FALSE);
        if (!EFI_ERROR (Status)) {
          EfiVarStoreNumber++;
        } else {
          FreePool (EfiVarStoreList[EfiVarStoreNumber]);
          EfiVarStoreList[EfiVarStoreNumber] = NULL;
        }

        break;
      case EFI_IFR_DEFAULTSTORE_OP:
        if (DefaultIdNumber >= DefaultIdMaxNum) {
          //
          // Reallocate DefaultIdNumber
          //
          DefaultIdList = ReallocatePool (DefaultIdMaxNum * sizeof (UINT16), (DefaultIdMaxNum + BASE_NUMBER) * sizeof (UINT16), DefaultIdList);
          if (DefaultIdList == NULL) {
            goto Done;
          }

          DefaultIdMaxNum = DefaultIdMaxNum + BASE_NUMBER;
        }

        DefaultIdList[DefaultIdNumber++] = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;
        break;
      case EFI_IFR_FORM_OP:
      case EFI_IFR_FORM_MAP_OP:
        //
        // No EFI varstore is found and directly return.
        //
        if ((EfiVarStoreNumber == 0) || (DefaultIdNumber == 0)) {
          goto Done;
        }

        break;
      case EFI_IFR_CHECKBOX_OP:
        IfrScope         = IfrOpHdr->Scope;
        IfrQuestionType  = IfrOpHdr->OpCode;
        IfrQuestionHdr   = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
        IfrCheckBox      = (EFI_IFR_CHECKBOX *)IfrOpHdr;
        EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
        Width            = sizeof (BOOLEAN);
        if (EfiVarStoreIndex < EfiVarStoreNumber) {
          for (Index = 0; Index < DefaultIdNumber; Index++) {
            if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {
              Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);
              if (!EFI_ERROR (Status)) {
                if (IfrValue.b) {
                  IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT;
                } else {
                  IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT);
                }
              }
            } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
              Status = FindQuestionDefaultSetting (DefaultIdList[Index], EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, sizeof (BOOLEAN), QuestionReferBitField);
              if (!EFI_ERROR (Status)) {
                if (IfrValue.b) {
                  IfrCheckBox->Flags = IfrCheckBox->Flags | EFI_IFR_CHECKBOX_DEFAULT_MFG;
                } else {
                  IfrCheckBox->Flags = IfrCheckBox->Flags & (~EFI_IFR_CHECKBOX_DEFAULT_MFG);
                }
              }
            }
          }
        }

        break;
      case EFI_IFR_NUMERIC_OP:
        IfrScope        = IfrOpHdr->Scope;
        IfrQuestionType = IfrOpHdr->OpCode;
        IfrQuestionHdr  = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
        if (QuestionReferBitField) {
          Width = (UINTN)(((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);
        } else {
          Width = (UINTN)((UINT32)1 << (((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));
        }

        break;
      case EFI_IFR_ONE_OF_OP:
        IfrScope        = IfrOpHdr->Scope;
        IfrQuestionType = IfrOpHdr->OpCode;
        IfrQuestionHdr  = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
        if (QuestionReferBitField) {
          Width = (UINTN)(((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EDKII_IFR_NUMERIC_SIZE_BIT);
        } else {
          Width = (UINTN)((UINT32)1 << (((EFI_IFR_ONE_OF *)IfrOpHdr)->Flags & EFI_IFR_NUMERIC_SIZE));
        }

        EfiVarStoreIndex     = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
        StandardDefaultIsSet = FALSE;
        ManufactDefaultIsSet = FALSE;
        //
        // Find Default and Manufacturing default for OneOf question
        //
        if (EfiVarStoreIndex < EfiVarStoreNumber) {
          for (Index = 0; Index < DefaultIdNumber; Index++) {
            if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_STANDARD) {
              Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_STANDARD, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrValue, Width, QuestionReferBitField);
              if (!EFI_ERROR (Status)) {
                StandardDefaultIsSet = TRUE;
              }
            } else if (DefaultIdList[Index] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
              Status = FindQuestionDefaultSetting (EFI_HII_DEFAULT_CLASS_MANUFACTURING, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrManufactValue, Width, QuestionReferBitField);
              if (!EFI_ERROR (Status)) {
                ManufactDefaultIsSet = TRUE;
              }
            }
          }
        }

        break;
      case EFI_IFR_ORDERED_LIST_OP:
        IfrScope        = IfrOpHdr->Scope;
        IfrQuestionType = IfrOpHdr->OpCode;
        IfrQuestionHdr  = (EFI_IFR_QUESTION_HEADER *)(IfrOpHdr + 1);
        break;
      case EFI_IFR_ONE_OF_OPTION_OP:
        if ((IfrQuestionHdr != NULL) && (IfrScope > 0)) {
          IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;
          if (IfrQuestionType == EFI_IFR_ONE_OF_OP) {
            Width = (UINTN)((UINT32)1 << (IfrOneOfOption->Flags & EFI_IFR_NUMERIC_SIZE));
            if (StandardDefaultIsSet) {
              if (CompareMem (&IfrOneOfOption->Value, &IfrValue, Width) == 0) {
                IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT;
              } else {
                IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT;
              }
            }

            if (ManufactDefaultIsSet) {
              if (CompareMem (&IfrOneOfOption->Value, &IfrManufactValue, Width) == 0) {
                IfrOneOfOption->Flags |= EFI_IFR_OPTION_DEFAULT_MFG;
              } else {
                IfrOneOfOption->Flags &= ~EFI_IFR_OPTION_DEFAULT_MFG;
              }
            }
          }
        }

        break;
      case EFI_IFR_DEFAULT_OP:
        if ((IfrQuestionHdr != NULL) && (IfrScope > 0)) {
          IfrDefault = (EFI_IFR_DEFAULT *)IfrOpHdr;
          //
          // Collect default value width
          //
          if (!QuestionReferBitField) {
            Width = 0;
            if ((IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN)) {
              Width = 1;
            } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_16) {
              Width = 2;
            } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_32) {
              Width = 4;
            } else if (IfrDefault->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
              Width = 8;
            } else if (IfrDefault->Type == EFI_IFR_TYPE_BUFFER) {
              Width = IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value);
            }
          }

          //
          // Update the default value
          //
          if (Width > 0) {
            EfiVarStoreIndex = IsEfiVarStoreQuestion (IfrQuestionHdr, EfiVarStoreList, EfiVarStoreNumber);
            if (EfiVarStoreIndex < EfiVarStoreNumber) {
              Status = FindQuestionDefaultSetting (IfrDefault->DefaultId, EfiVarStoreList[EfiVarStoreIndex], IfrQuestionHdr, &IfrDefault->Value, Width, QuestionReferBitField);
            }
          }
        }

        break;
      case EFI_IFR_END_OP:
        if (IfrQuestionHdr != NULL) {
          if (IfrScope > 0) {
            IfrScope--;
          }

          if (IfrScope == 0) {
            IfrQuestionHdr        = NULL;
            QuestionReferBitField = FALSE;
          }
        }

        break;
      case EFI_IFR_GUID_OP:
        if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
          QuestionReferBitField = TRUE;
        }

        break;
      default:
        break;
    }

    IfrOffset = IfrOffset + IfrOpHdr->Length;
    IfrOpHdr  = (EFI_IFR_OP_HEADER *)((UINT8 *)IfrOpHdr + IfrOpHdr->Length);
    if (IfrScope > 0) {
      IfrScope += IfrOpHdr->Scope;
    }
  }

Done:
  if (EfiVarStoreList != NULL) {
    for (Index = 0; Index < EfiVarStoreNumber; Index++) {
      FreePool (EfiVarStoreList[Index]);
    }
  }

  return;
}

/**
  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;

  //
  // Update FormPackage with the default setting
  //
  UpdateDefaultSettingInFormPackage (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);
    //
    // If Hii runtime support feature is enabled,
    // will export Hii info for runtime use after ReadyToBoot event triggered.
    // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
    // will need to export the content of HiiDatabase.
    // But if form packages removed, also need to export the ConfigResp string
    //
    if (gExportAfterReadyToBoot) {
      gExportConfigResp = TRUE;
    }
  }

  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;
  }

  AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (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, &StringPackage->MaxStringId, 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;
}

/**
 Adjust all string packages in a single package list to have the same max string ID.

 @param  PackageList        Pointer to a package list which will be adjusted.

 @retval EFI_SUCCESS  Adjust all string packages successfully.
 @retval others       Can't adjust string packages.

**/
EFI_STATUS
AdjustStringPackage (
  IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageList
  )
{
  LIST_ENTRY                   *Link;
  HII_STRING_PACKAGE_INSTANCE  *StringPackage;
  UINT32                       Skip2BlockSize;
  UINT32                       OldBlockSize;
  UINT8                        *StringBlock;
  UINT8                        *BlockPtr;
  EFI_STRING_ID                MaxStringId;
  UINT16                       SkipCount;

  MaxStringId = 0;
  for (Link = PackageList->StringPkgHdr.ForwardLink;
       Link != &PackageList->StringPkgHdr;
       Link = Link->ForwardLink
       )
  {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    if (MaxStringId < StringPackage->MaxStringId) {
      MaxStringId = StringPackage->MaxStringId;
    }
  }

  for (Link = PackageList->StringPkgHdr.ForwardLink;
       Link != &PackageList->StringPkgHdr;
       Link = Link->ForwardLink
       )
  {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    if (StringPackage->MaxStringId < MaxStringId) {
      OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
      //
      // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.
      //
      SkipCount      = (UINT16)(MaxStringId - StringPackage->MaxStringId);
      Skip2BlockSize = (UINT32)sizeof (EFI_HII_SIBT_SKIP2_BLOCK);

      StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Skip2BlockSize);
      if (StringBlock == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Copy original string blocks, except the EFI_HII_SIBT_END.
      //
      CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
      //
      // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks
      //
      BlockPtr  = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
      *BlockPtr = EFI_HII_SIBT_SKIP2;
      CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));
      BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);

      //
      // Append a EFI_HII_SIBT_END block to the end.
      //
      *BlockPtr = EFI_HII_SIBT_END;
      FreePool (StringPackage->StringBlock);
      StringPackage->StringBlock                  = StringBlock;
      StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;
      PackageList->PackageListHdr.PackageLength  += Skip2BlockSize;
      StringPackage->MaxStringId                  = MaxStringId;
    }
  }

  return EFI_SUCCESS;
}

/**
  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;
  StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF (EFI_FONT_INFO, FontName)) / sizeof (CHAR16), 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 = 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;
  BOOLEAN                               StringPkgIsAdd;

  //
  // Initialize Variables
  //
  StringPkgIsAdd        = FALSE;
  FontPackage           = NULL;
  StringPackage         = NULL;
  GuidPackage           = NULL;
  FormPackage           = NULL;
  ImagePackage          = NULL;
  SimpleFontPackage     = NULL;
  KeyboardLayoutPackage = 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
                   );
        //
        // If Hii runtime support feature is enabled,
        // will export Hii info for runtime use after ReadyToBoot event triggered.
        // If some driver add/update/remove packages from HiiDatabase after ReadyToBoot,
        // will need to export the content of HiiDatabase.
        // But if form packages added/updated, also need to export the ConfigResp string.
        //
        if (gExportAfterReadyToBoot) {
          gExportConfigResp = TRUE;
        }

        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;
        }

        ASSERT (StringPackage != NULL);
        Status = InvokeRegisteredFunction (
                   Private,
                   NotifyType,
                   (VOID *)StringPackage,
                   (UINT8)(PackageHeader.Type),
                   DatabaseRecord->Handle
                   );
        StringPkgIsAdd = TRUE;
        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));
  }

  //
  // Adjust String Package to make sure all string packages have the same max string ID.
  //
  if (!EFI_ERROR (Status) && StringPkgIsAdd) {
    Status = AdjustStringPackage (DatabaseRecord->PackageList);
  }

  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 mainly use to get and update ConfigResp string.

@param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.

@retval EFI_SUCCESS            Get the information successfully.
@retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Configuration Setting data.

**/
EFI_STATUS
HiiGetConfigRespInfo (
  IN CONST EFI_HII_DATABASE_PROTOCOL  *This
  )
{
  EFI_STATUS                 Status;
  HII_DATABASE_PRIVATE_DATA  *Private;
  EFI_STRING                 ConfigAltResp;
  UINTN                      ConfigSize;

  ConfigAltResp = NULL;
  ConfigSize    = 0;

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  //
  // Get ConfigResp string
  //
  Status = HiiConfigRoutingExportConfig (&Private->ConfigRouting, &ConfigAltResp);

  if (!EFI_ERROR (Status)) {
    ConfigSize = StrSize (ConfigAltResp);
    if (ConfigSize > gConfigRespSize) {
      //
      // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
      // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
      //
      gConfigRespSize = ConfigSize + (ConfigSize >> 2);
      if (gRTConfigRespBuffer != NULL) {
        FreePool (gRTConfigRespBuffer);
        DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
      }

      gRTConfigRespBuffer = (EFI_STRING)AllocateRuntimeZeroPool (gConfigRespSize);
      if (gRTConfigRespBuffer == NULL) {
        FreePool (ConfigAltResp);
        DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the ConfigResp string.\n"));
        //
        // Remove from the System Table when the configuration runtime buffer is freed.
        //
        gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, NULL);
        return EFI_OUT_OF_RESOURCES;
      }
    } else {
      ZeroMem (gRTConfigRespBuffer, gConfigRespSize);
    }

    CopyMem (gRTConfigRespBuffer, ConfigAltResp, ConfigSize);
    gBS->InstallConfigurationTable (&gEfiHiiConfigRoutingProtocolGuid, gRTConfigRespBuffer);
    FreePool (ConfigAltResp);
  }

  return EFI_SUCCESS;
}

/**
This is an internal function,mainly use to get HiiDatabase information.

@param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL instance.

@retval EFI_SUCCESS            Get the information successfully.
@retval EFI_OUT_OF_RESOURCES   Not enough memory to store the Hiidatabase data.

**/
EFI_STATUS
HiiGetDatabaseInfo (
  IN CONST EFI_HII_DATABASE_PROTOCOL  *This
  )
{
  EFI_STATUS                   Status;
  EFI_HII_PACKAGE_LIST_HEADER  *DatabaseInfo;
  UINTN                        DatabaseInfoSize;

  DatabaseInfo     = NULL;
  DatabaseInfoSize = 0;

  //
  // Get HiiDatabase information.
  //
  Status = HiiExportPackageLists (This, NULL, &DatabaseInfoSize, DatabaseInfo);

  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

  if (DatabaseInfoSize > gDatabaseInfoSize ) {
    //
    // Do 25% overallocation to minimize the number of memory allocations after ReadyToBoot.
    // Since lots of allocation after ReadyToBoot may change memory map and cause S4 resume issue.
    //
    gDatabaseInfoSize = DatabaseInfoSize + (DatabaseInfoSize >> 2);
    if (gRTDatabaseInfoBuffer != NULL) {
      FreePool (gRTDatabaseInfoBuffer);
      DEBUG ((DEBUG_WARN, "[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue.\n"));
    }

    gRTDatabaseInfoBuffer = AllocateRuntimeZeroPool (gDatabaseInfoSize);
    if (gRTDatabaseInfoBuffer == NULL) {
      DEBUG ((DEBUG_ERROR, "[HiiDatabase]: No enough memory resource to store the HiiDatabase info.\n"));
      //
      // Remove from the System Table when the configuration runtime buffer is freed.
      //
      gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, NULL);
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    ZeroMem (gRTDatabaseInfoBuffer, gDatabaseInfoSize);
  }

  Status = HiiExportPackageLists (This, NULL, &DatabaseInfoSize, gRTDatabaseInfoBuffer);
  ASSERT_EFI_ERROR (Status);
  gBS->InstallConfigurationTable (&gEfiHiiDatabaseProtocolGuid, gRTDatabaseInfoBuffer);

  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.
                                 If a NULL is specified, this data will not be associate
                                 with any drivers and cannot have a callback induced.
  @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  OPTIONAL,
  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;
    }
  }

  EfiAcquireLock (&mHiiDatabaseLock);

  //
  // Build a PackageList node
  //
  Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
  if (EFI_ERROR (Status)) {
    EfiReleaseLock (&mHiiDatabaseLock);
    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)) {
    EfiReleaseLock (&mHiiDatabaseLock);
    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;

  //
  // Check whether need to get the Database info.
  // Only after ReadyToBoot, need to do the export.
  //
  if (gExportAfterReadyToBoot) {
    HiiGetDatabaseInfo (This);
  }

  EfiReleaseLock (&mHiiDatabaseLock);

  //
  // Notes:
  // HiiGetDatabaseInfo () will get the contents of HII data base,
  // belong to the atomic behavior of Hii Database update.
  // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
  // we can not think it belong to the atomic behavior of Hii Database update.
  // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
  //

  // Check whether need to get the configuration setting info from HII drivers.
  // When after ReadyToBoot and need to do the export for form package add.
  //
  if (gExportAfterReadyToBoot && gExportConfigResp) {
    HiiGetConfigRespInfo (This);
  }

  return EFI_SUCCESS;
}

/**
  This function removes the package list that is associated with 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 handle 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;
  }

  EfiAcquireLock (&mHiiDatabaseLock);

  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)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveFormPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveStringPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveFontPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveImagePackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        return Status;
      }

      Status = RemoveDevicePathPackage (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        EfiReleaseLock (&mHiiDatabaseLock);
        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);

      //
      // Check whether need to get the Database info.
      // Only after ReadyToBoot, need to do the export.
      //
      if (gExportAfterReadyToBoot) {
        HiiGetDatabaseInfo (This);
      }

      EfiReleaseLock (&mHiiDatabaseLock);

      //
      // Notes:
      // HiiGetDatabaseInfo () will get the contents of HII data base,
      // belong to the atomic behavior of Hii Database update.
      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
      // we can not think it belong to the atomic behavior of Hii Database update.
      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
      //

      //
      // Check whether need to get the configuration setting info from HII drivers.
      // When after ReadyToBoot and need to do the export for form package remove.
      //
      if (gExportAfterReadyToBoot && gExportConfigResp) {
        HiiGetConfigRespInfo (This);
      }

      return EFI_SUCCESS;
    }
  }

  EfiReleaseLock (&mHiiDatabaseLock);
  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;

  EfiAcquireLock (&mHiiDatabaseLock);
  //
  // 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)) {
          EfiReleaseLock (&mHiiDatabaseLock);
          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
      //
      Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);

      //
      // Check whether need to get the Database info.
      // Only after ReadyToBoot, need to do the export.
      //
      if (gExportAfterReadyToBoot && (Status == EFI_SUCCESS)) {
        HiiGetDatabaseInfo (This);
      }

      EfiReleaseLock (&mHiiDatabaseLock);

      //
      // Notes:
      // HiiGetDatabaseInfo () will get the contents of HII data base,
      // belong to the atomic behavior of Hii Database update.
      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers
      // we can not think it belong to the atomic behavior of Hii Database update.
      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().
      //

      //
      // Check whether need to get the configuration setting info from HII drivers.
      // When after ReadyToBoot and need to do the export for form package update.
      //
      if (gExportAfterReadyToBoot && gExportConfigResp && (Status == EFI_SUCCESS)) {
        HiiGetConfigRespInfo (This);
      }

      return Status;
    }
  }

  EfiReleaseLock (&mHiiDatabaseLock);
  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 outputted 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  HandleBufferLength was NULL.
  @retval EFI_INVALID_PARAMETER  The value referenced by HandleBufferLength was not
                                 zero and Handle 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;
      //
      // Pseudo-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 specified Handle could not be found in the
                                 current database.
  @retval EFI_INVALID_PARAMETER  BufferSize was NULL.
  @retval EFI_INVALID_PARAMETER  The value referenced by BufferSize was not zero
                                 and Buffer 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)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*BufferSize > 0) && (Buffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Handle != NULL) && (!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,
                  &gEfiCallerIdGuid,
                  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,
                  &gEfiCallerIdGuid,
                  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,
                      &gEfiCallerIdGuid,
                      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 KeyGuidBufferLength is NULL.
  @retval EFI_INVALID_PARAMETER  The value referenced by KeyGuidBufferLength is not
                                 zero and KeyGuidBuffer is 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;
}
