/** @file
Implementation for EFI_HII_DATABASE_PROTOCOL.

Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/


#include "HiiDatabase.h"

#define BASE_NUMBER        10

EFI_HII_PACKAGE_LIST_HEADER    *gRTDatabaseInfoBuffer = NULL;
EFI_STRING                     gRTConfigRespBuffer    = NULL;
UINTN                          gDatabaseInfoSize = 0;
UINTN                          gConfigRespSize = 0;
BOOLEAN                        gExportConfigResp = TRUE;
UINTN                          gNvDefaultStoreSize = 0;
SKU_ID                         gSkuId              = 0xFFFFFFFFFFFFFFFF;
LIST_ENTRY                     gVarStorageList     = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);

/**
  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 + 1);
      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){
      gConfigRespSize = ConfigSize;
      if (gRTConfigRespBuffer != NULL){
        FreePool(gRTConfigRespBuffer);
      }
      gRTConfigRespBuffer = (EFI_STRING)AllocateRuntimeZeroPool(ConfigSize);
      if (gRTConfigRespBuffer == NULL){
        FreePool(ConfigAltResp);
        DEBUG ((DEBUG_ERROR, "Not enough memory resource to get the ConfigResp string.\n"));
        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 ) {
    gDatabaseInfoSize = DatabaseInfoSize;
    if (gRTDatabaseInfoBuffer != NULL){
      FreePool(gRTDatabaseInfoBuffer);
    }
    gRTDatabaseInfoBuffer = AllocateRuntimeZeroPool(DatabaseInfoSize);
    if (gRTDatabaseInfoBuffer == NULL){
      DEBUG ((DEBUG_ERROR, "Not enough memory resource to get the HiiDatabase info.\n"));
      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 mainly use to get and update configuration settings 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 Configuration Setting data.

**/
EFI_STATUS
HiiGetConfigurationSetting(
  IN CONST EFI_HII_DATABASE_PROTOCOL        *This
  )
{
  EFI_STATUS                          Status;

  //
  // Get the HiiDatabase info.
  //
  Status = HiiGetDatabaseInfo(This);

  //
  // Get ConfigResp string
  //
  if (gExportConfigResp) {
    Status = HiiGetConfigRespInfo (This);
    gExportConfigResp = FALSE;
  }
  return Status;

}


/**
  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;
    }
  }

  //
  // Build a PackageList node
  //
  Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Fill in information of the created Package List node
  // according to incoming package list.
  //
  Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DatabaseRecord->DriverHandle = DriverHandle;

  //
  // Create a Device path package and add into the package list if exists.
  //
  Status = gBS->HandleProtocol (
                  DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath
                  );
  if (!EFI_ERROR (Status)) {
    Status = AddDevicePathPackage (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, DevicePath, DatabaseRecord);
    ASSERT_EFI_ERROR (Status);
  }

  *Handle = DatabaseRecord->Handle;

  //
  // Check whether need to get the Database and configuration setting info.
  // Only after ReadyToBoot, need to do the export.
  //
  if (gExportAfterReadyToBoot) {
    HiiGetConfigurationSetting(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;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  //
  // Get the packagelist to be removed.
  //
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (Node->Handle == Handle) {
      PackageList = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (Node->PackageList);
      ASSERT (PackageList != NULL);

      //
      // Call registered functions with REMOVE_PACK before removing packages
      // then remove them.
      //
      Status = RemoveGuidPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveFormPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveStringPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveFontPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveImagePackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveSimpleFontPackages (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }
      Status = RemoveDevicePathPackage (Private, Handle, PackageList);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Free resources of the package list
      //
      RemoveEntryList (&Node->DatabaseEntry);

      HiiHandle = (HII_HANDLE *) Handle;
      RemoveEntryList (&HiiHandle->Handle);
      Private->HiiHandleCount--;
      ASSERT (Private->HiiHandleCount >= 0);

      HiiHandle->Signature = 0;
      FreePool (HiiHandle);
      FreePool (Node->PackageList);
      FreePool (Node);

      //
      // Check whether need to get the Database and configuration setting info.
      // Only after ReadyToBoot, need to do the export.
      //
      if (gExportAfterReadyToBoot) {
        HiiGetConfigurationSetting(This);
      }
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}


/**
  This function updates the existing package list (which has the specified Handle)
  in the HII databases, using the new package list specified by PackageList.

  @param  This                   A pointer to the EFI_HII_DATABASE_PROTOCOL
                                 instance.
  @param  Handle                 The handle that was registered to the data that is
                                  requested to be updated.
  @param  PackageList            A pointer to an EFI_HII_PACKAGE_LIST_HEADER
                                 package.

  @retval EFI_SUCCESS            The HII database was successfully updated.
  @retval EFI_OUT_OF_RESOURCES   Unable to allocate enough memory for the updated
                                 database.
  @retval EFI_INVALID_PARAMETER  PackageList was NULL.
  @retval EFI_NOT_FOUND          The specified Handle is not in database.

**/
EFI_STATUS
EFIAPI
HiiUpdatePackageList (
  IN CONST EFI_HII_DATABASE_PROTOCOL    *This,
  IN EFI_HII_HANDLE                     Handle,
  IN CONST EFI_HII_PACKAGE_LIST_HEADER  *PackageList
  )
{
  EFI_STATUS                          Status;
  HII_DATABASE_PRIVATE_DATA           *Private;
  LIST_ENTRY                          *Link;
  HII_DATABASE_RECORD                 *Node;
  EFI_HII_PACKAGE_HEADER              *PackageHdrPtr;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *OldPackageList;
  EFI_HII_PACKAGE_HEADER              PackageHeader;

  if (This == NULL || PackageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (Handle)) {
    return EFI_NOT_FOUND;
  }

  Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageList + sizeof (EFI_HII_PACKAGE_LIST_HEADER));

  Status = EFI_SUCCESS;

  //
  // Get original packagelist to be updated
  //
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (Node->Handle == Handle) {
      OldPackageList = Node->PackageList;
      //
      // Remove the package if its type matches one of the package types which is
      // contained in the new package list.
      //
      CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
      while (PackageHeader.Type != EFI_HII_PACKAGE_END) {
        switch (PackageHeader.Type) {
        case EFI_HII_PACKAGE_TYPE_GUID:
          Status = RemoveGuidPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_FORMS:
          Status = RemoveFormPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
          Status = RemoveKeyboardLayoutPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_STRINGS:
          Status = RemoveStringPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_FONTS:
          Status = RemoveFontPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_IMAGES:
          Status = RemoveImagePackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_SIMPLE_FONTS:
          Status = RemoveSimpleFontPackages (Private, Handle, OldPackageList);
          break;
        case EFI_HII_PACKAGE_DEVICE_PATH:
          Status = RemoveDevicePathPackage (Private, Handle, OldPackageList);
          break;
        }

        if (EFI_ERROR (Status)) {
          return Status;
        }

        PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);
        CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));
      }

      //
      // Add all of the packages within the new package list
      //
      Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_ADD_PACK, PackageList, Node);

      //
      // Check whether need to get the Database and configuration setting info.
      // Only after ReadyToBoot, need to do the export.
      //
      if (gExportAfterReadyToBoot) {
        if (Status == EFI_SUCCESS){
          HiiGetConfigurationSetting(This);
        }
      }

      return Status;
    }
  }

  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;
}

