/** @file
Implementation for EFI_HII_STRING_PROTOCOL.


Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HiiDatabase.h"

CHAR16  mLanguageWindow[16] = {
  0x0000, 0x0080, 0x0100, 0x0300,
  0x2000, 0x2080, 0x2100, 0x3000,
  0x0080, 0x00C0, 0x0400, 0x0600,
  0x0900, 0x3040, 0x30A0, 0xFF00
};

/**
  This function checks whether a global font info is referred by local
  font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create
  a HII_FONT_INFO to refer it locally.

  This is a internal function.


  @param  Private                Hii database private structure.
  @param  StringPackage          HII string package instance.
  @param  FontId                Font identifer, which must be unique within the string package.
  @param  DuplicateEnable        If true, duplicate HII_FONT_INFO which refers to
                                 the same EFI_FONT_INFO is permitted. Otherwise it
                                 is not allowed.
  @param  GlobalFontInfo         Input a global font info which specify a
                                 EFI_FONT_INFO.
  @param  LocalFontInfo          Output a local font info which refers to a
                                 EFI_FONT_INFO.

  @retval TRUE                   Already referred before calling this function.
  @retval FALSE                  Not referred before calling this function.

**/
BOOLEAN
ReferFontInfoLocally (
  IN  HII_DATABASE_PRIVATE_DATA    *Private,
  IN  HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN  UINT8                        FontId,
  IN  BOOLEAN                      DuplicateEnable,
  IN  HII_GLOBAL_FONT_INFO         *GlobalFontInfo,
  OUT HII_FONT_INFO                **LocalFontInfo
  )
{
  HII_FONT_INFO  *LocalFont;
  LIST_ENTRY     *Link;

  ASSERT (Private != NULL && StringPackage != NULL && GlobalFontInfo != NULL && LocalFontInfo != NULL);

  if (!DuplicateEnable) {
    for (Link = StringPackage->FontInfoList.ForwardLink;
         Link != &StringPackage->FontInfoList;
         Link = Link->ForwardLink
         )
    {
      LocalFont = CR (Link, HII_FONT_INFO, Entry, HII_FONT_INFO_SIGNATURE);
      if (LocalFont->GlobalEntry == &GlobalFontInfo->Entry) {
        //
        // Already referred by local font info list, return directly.
        //
        *LocalFontInfo = LocalFont;
        return TRUE;
      }
    }
  }

  // FontId identifies EFI_FONT_INFO in local string package uniquely.
  // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies
  // EFI_FONT_INFO uniquely in whole hii database.
  //
  LocalFont = (HII_FONT_INFO *)AllocateZeroPool (sizeof (HII_FONT_INFO));
  ASSERT (LocalFont != NULL);

  LocalFont->Signature   = HII_FONT_INFO_SIGNATURE;
  LocalFont->FontId      = FontId;
  LocalFont->GlobalEntry = &GlobalFontInfo->Entry;
  InsertTailList (&StringPackage->FontInfoList, &LocalFont->Entry);

  *LocalFontInfo = LocalFont;
  return FALSE;
}

/**
  Convert Ascii string text to unicode string test.

  This is a internal function.


  @param  StringDest             Buffer to store the string text. If it is NULL,
                                 only the size will be returned.
  @param  StringSrc              Points to current null-terminated string.
  @param  BufferSize             Length of the buffer.

  @retval EFI_SUCCESS            The string text was outputted successfully.
  @retval EFI_BUFFER_TOO_SMALL   Buffer is insufficient to store the found string
                                 text. BufferSize is updated to the required buffer
                                 size.

**/
EFI_STATUS
ConvertToUnicodeText (
  OUT EFI_STRING  StringDest,
  IN  CHAR8       *StringSrc,
  IN  OUT UINTN   *BufferSize
  )
{
  UINTN  StringSize;
  UINTN  Index;

  ASSERT (StringSrc != NULL && BufferSize != NULL);

  StringSize = AsciiStrSize (StringSrc) * 2;
  if ((*BufferSize < StringSize) || (StringDest == NULL)) {
    *BufferSize = StringSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  for (Index = 0; Index < AsciiStrLen (StringSrc); Index++) {
    StringDest[Index] = (CHAR16)StringSrc[Index];
  }

  StringDest[Index] = 0;
  return EFI_SUCCESS;
}

/**
  Calculate the size of StringSrc and output it. If StringDest is not NULL,
  copy string text from src to dest.

  This is a internal function.

  @param  StringDest             Buffer to store the string text. If it is NULL,
                                 only the size will be returned.
  @param  StringSrc              Points to current null-terminated string.
  @param  BufferSize             Length of the buffer.

  @retval EFI_SUCCESS            The string text was outputted successfully.
  @retval EFI_BUFFER_TOO_SMALL   Buffer is insufficient to store the found string
                                 text. BufferSize is updated to the required buffer
                                 size.

**/
EFI_STATUS
GetUnicodeStringTextOrSize (
  OUT EFI_STRING  StringDest  OPTIONAL,
  IN  UINT8       *StringSrc,
  IN  OUT UINTN   *BufferSize
  )
{
  UINTN  StringSize;
  UINT8  *StringPtr;

  ASSERT (StringSrc != NULL && BufferSize != NULL);

  StringSize = sizeof (CHAR16);
  StringPtr  = StringSrc;
  while (ReadUnaligned16 ((UINT16 *)StringPtr) != 0) {
    StringSize += sizeof (CHAR16);
    StringPtr  += sizeof (CHAR16);
  }

  if (*BufferSize < StringSize) {
    *BufferSize = StringSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  if (StringDest != NULL) {
    CopyMem (StringDest, StringSrc, StringSize);
  }

  *BufferSize = StringSize;
  return EFI_SUCCESS;
}

/**
  Copy string font info to a buffer.

  This is a internal function.

  @param  StringPackage          Hii string package instance.
  @param  FontId                 Font identifier which is unique in a string
                                 package.
  @param  StringFontInfo         Buffer to record the output font info. It's
                                 caller's responsibility to free this buffer.

  @retval EFI_SUCCESS            The string font is outputted successfully.
  @retval EFI_NOT_FOUND          The specified font id does not exist.

**/
EFI_STATUS
GetStringFontInfo (
  IN  HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN  UINT8                        FontId,
  OUT EFI_FONT_INFO                **StringFontInfo
  )
{
  LIST_ENTRY            *Link;
  HII_FONT_INFO         *FontInfo;
  HII_GLOBAL_FONT_INFO  *GlobalFont;

  ASSERT (StringFontInfo != NULL && StringPackage != NULL);

  for (Link = StringPackage->FontInfoList.ForwardLink; Link != &StringPackage->FontInfoList; Link = Link->ForwardLink) {
    FontInfo = CR (Link, HII_FONT_INFO, Entry, HII_FONT_INFO_SIGNATURE);
    if (FontInfo->FontId == FontId) {
      GlobalFont      = CR (FontInfo->GlobalEntry, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
      *StringFontInfo = (EFI_FONT_INFO *)AllocateZeroPool (GlobalFont->FontInfoSize);
      if (*StringFontInfo == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (*StringFontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Parse all string blocks to find a String block specified by StringId.
  If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks
  within this string package and backup its information. If LastStringId is
  specified, the string id of last string block will also be output.
  If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING).

  @param  Private                 Hii database private structure.
  @param  StringPackage           Hii string package instance.
  @param  StringId                The string's id, which is unique within
                                  PackageList.
  @param  BlockType               Output the block type of found string block.
  @param  StringBlockAddr         Output the block address of found string block.
  @param  StringTextOffset        Offset, relative to the found block address, of
                                  the  string text information.
  @param  LastStringId            Output the last string id when StringId = 0 or StringId = -1.
  @param  StartStringId           The first id in the skip block which StringId in the block.

  @retval EFI_SUCCESS             The string text and font is retrieved
                                  successfully.
  @retval EFI_NOT_FOUND           The specified text or font info can not be found
                                  out.
  @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
                                  task.

**/
EFI_STATUS
FindStringBlock (
  IN HII_DATABASE_PRIVATE_DATA     *Private,
  IN  HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN  EFI_STRING_ID                StringId,
  OUT UINT8                        *BlockType  OPTIONAL,
  OUT UINT8                        **StringBlockAddr  OPTIONAL,
  OUT UINTN                        *StringTextOffset  OPTIONAL,
  OUT EFI_STRING_ID                *LastStringId  OPTIONAL,
  OUT EFI_STRING_ID                *StartStringId OPTIONAL
  )
{
  UINT8                    *BlockHdr;
  EFI_STRING_ID            CurrentStringId;
  UINTN                    BlockSize;
  UINTN                    Index;
  UINT8                    *StringTextPtr;
  UINTN                    Offset;
  HII_FONT_INFO            *LocalFont;
  EFI_FONT_INFO            *FontInfo;
  HII_GLOBAL_FONT_INFO     *GlobalFont;
  UINTN                    FontInfoSize;
  UINT16                   StringCount;
  UINT16                   SkipCount;
  EFI_HII_FONT_STYLE       FontStyle;
  UINT16                   FontSize;
  UINT8                    Length8;
  EFI_HII_SIBT_EXT2_BLOCK  Ext2;
  UINT8                    FontId;
  UINT32                   Length32;
  UINTN                    StringSize;
  CHAR16                   Zero;

  ASSERT (StringPackage != NULL);
  ASSERT (StringPackage->Signature == HII_STRING_PACKAGE_SIGNATURE);

  CurrentStringId = 1;
  StringSize      = 0;

  if ((StringId != (EFI_STRING_ID)(-1)) && (StringId != 0)) {
    ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
    if (StringId > StringPackage->MaxStringId) {
      return EFI_NOT_FOUND;
    }
  } else {
    ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
    if ((StringId == 0) && (LastStringId != NULL)) {
      *LastStringId = StringPackage->MaxStringId;
      return EFI_SUCCESS;
    }
  }

  ZeroMem (&Zero, sizeof (CHAR16));

  //
  // Parse the string blocks to get the string text and font.
  //
  BlockHdr  = StringPackage->StringBlock;
  BlockSize = 0;
  Offset    = 0;
  while (*BlockHdr != EFI_HII_SIBT_END) {
    switch (*BlockHdr) {
      case EFI_HII_SIBT_STRING_SCSU:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_SCSU_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_SCSU:
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
          if (CurrentStringId == StringId) {
            ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
            *BlockType        = *BlockHdr;
            *StringBlockAddr  = BlockHdr;
            *StringTextOffset = StringTextPtr - BlockHdr;
            return EFI_SUCCESS;
          }

          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
          if (CurrentStringId == StringId) {
            ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
            *BlockType        = *BlockHdr;
            *StringBlockAddr  = BlockHdr;
            *StringTextOffset = StringTextPtr - BlockHdr;
            return EFI_SUCCESS;
          }

          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRING_UCS2:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;
        //
        // Use StringSize to store the size of the specified string, including the NULL
        // terminator.
        //
        GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
        BlockSize += Offset + StringSize;
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        //
        // Use StrSize to store the size of the specified string, including the NULL
        // terminator.
        //
        GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
        BlockSize += Offset + StringSize;
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_UCS2:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        for (Index = 0; Index < StringCount; Index++) {
          GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
          BlockSize += StringSize;
          if (CurrentStringId == StringId) {
            ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
            *BlockType        = *BlockHdr;
            *StringBlockAddr  = BlockHdr;
            *StringTextOffset = StringTextPtr - BlockHdr;
            return EFI_SUCCESS;
          }

          StringTextPtr = StringTextPtr + StringSize;
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        for (Index = 0; Index < StringCount; Index++) {
          GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);
          BlockSize += StringSize;
          if (CurrentStringId == StringId) {
            ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
            *BlockType        = *BlockHdr;
            *StringBlockAddr  = BlockHdr;
            *StringTextOffset = StringTextPtr - BlockHdr;
            return EFI_SUCCESS;
          }

          StringTextPtr = StringTextPtr + StringSize;
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_DUPLICATE:
        if (CurrentStringId == StringId) {
          //
          // Incoming StringId is an id of a duplicate string block.
          // Update the StringId to be the previous string block.
          // Go back to the header of string block to search.
          //
          CopyMem (
            &StringId,
            BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
            sizeof (EFI_STRING_ID)
            );
          ASSERT (StringId != CurrentStringId);
          CurrentStringId = 1;
          BlockSize       = 0;
        } else {
          BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_SKIP1:
        SkipCount       = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
        break;

      case EFI_HII_SIBT_SKIP2:
        CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
        break;

      case EFI_HII_SIBT_EXT1:
        CopyMem (
          &Length8,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT8)
          );
        BlockSize += Length8;
        break;

      case EFI_HII_SIBT_EXT2:
        CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
        if ((Ext2.BlockType2 == EFI_HII_SIBT_FONT) && (StringId == (EFI_STRING_ID)(-1))) {
          //
          // Find the relationship between global font info and the font info of
          // this EFI_HII_SIBT_FONT block then backup its information in local package.
          //
          BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);
          CopyMem (&FontId, BlockHdr, sizeof (UINT8));
          BlockHdr++;
          CopyMem (&FontSize, BlockHdr, sizeof (UINT16));
          BlockHdr += sizeof (UINT16);
          CopyMem (&FontStyle, BlockHdr, sizeof (EFI_HII_FONT_STYLE));
          BlockHdr += sizeof (EFI_HII_FONT_STYLE);
          GetUnicodeStringTextOrSize (NULL, BlockHdr, &StringSize);

          FontInfoSize = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + StringSize;
          FontInfo     = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoSize);
          if (FontInfo == NULL) {
            return EFI_OUT_OF_RESOURCES;
          }

          FontInfo->FontStyle = FontStyle;
          FontInfo->FontSize  = FontSize;
          CopyMem (FontInfo->FontName, BlockHdr, StringSize);

          //
          // If find the corresponding global font info, save the relationship.
          // Otherwise ignore this EFI_HII_SIBT_FONT block.
          //
          if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {
            ReferFontInfoLocally (Private, StringPackage, FontId, TRUE, GlobalFont, &LocalFont);
          }

          //
          // Since string package tool set FontId initially to 0 and increases it
          // progressively by one, StringPackage->FondId always represents an unique
          // and available FontId.
          //
          StringPackage->FontId++;

          FreePool (FontInfo);
        }

        BlockSize += Ext2.Length;

        break;

      case EFI_HII_SIBT_EXT4:
        CopyMem (
          &Length32,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT32)
          );

        BlockSize += Length32;
        break;

      default:
        break;
    }

    if ((StringId > 0) && (StringId != (EFI_STRING_ID)(-1))) {
      ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);
      *BlockType        = *BlockHdr;
      *StringBlockAddr  = BlockHdr;
      *StringTextOffset = Offset;

      if (StringId == CurrentStringId - 1) {
        //
        // if only one skip item, return EFI_NOT_FOUND.
        //
        if ((*BlockType == EFI_HII_SIBT_SKIP2) || (*BlockType == EFI_HII_SIBT_SKIP1)) {
          return EFI_NOT_FOUND;
        } else {
          return EFI_SUCCESS;
        }
      }

      if (StringId < CurrentStringId - 1) {
        return EFI_NOT_FOUND;
      }
    }

    BlockHdr = StringPackage->StringBlock + BlockSize;
    if (StartStringId != NULL) {
      *StartStringId = CurrentStringId;
    }
  }

  //
  // Get last string ID
  //
  if ((StringId == (EFI_STRING_ID)(-1)) && (LastStringId != NULL)) {
    *LastStringId = (EFI_STRING_ID)(CurrentStringId - 1);
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Parse all string blocks to get a string specified by StringId.

  This is a internal function.

  @param  Private                Hii database private structure.
  @param  StringPackage          Hii string package instance.
  @param  StringId               The string's id, which is unique within
                                 PackageList.
  @param  String                 Points to retrieved null-terminated string.
  @param  StringSize             On entry, points to the size of the buffer pointed
                                 to by String, in bytes. On return, points to the
                                 length of the string, in bytes.
  @param  StringFontInfo         If not NULL, allocate a buffer to record the
                                 output font info. It's caller's responsibility to
                                 free this buffer.

  @retval EFI_SUCCESS            The string text and font is retrieved
                                 successfully.
  @retval EFI_NOT_FOUND          The specified text or font info can not be found
                                 out.
  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by StringSize is too small to
                                 hold the string.

**/
EFI_STATUS
GetStringWorker (
  IN HII_DATABASE_PRIVATE_DATA     *Private,
  IN  HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN  EFI_STRING_ID                StringId,
  OUT EFI_STRING                   String,
  IN  OUT UINTN                    *StringSize  OPTIONAL,
  OUT EFI_FONT_INFO                **StringFontInfo OPTIONAL
  )
{
  UINT8       *StringTextPtr;
  UINT8       BlockType;
  UINT8       *StringBlockAddr;
  UINTN       StringTextOffset;
  EFI_STATUS  Status;
  UINT8       FontId;

  ASSERT (StringPackage != NULL);
  ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);

  //
  // Find the specified string block
  //
  Status = FindStringBlock (
             Private,
             StringPackage,
             StringId,
             &BlockType,
             &StringBlockAddr,
             &StringTextOffset,
             NULL,
             NULL
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (StringSize == NULL) {
    //
    // String text buffer is not requested
    //
    return EFI_SUCCESS;
  }

  //
  // Get the string text.
  //
  StringTextPtr = StringBlockAddr + StringTextOffset;
  switch (BlockType) {
    case EFI_HII_SIBT_STRING_SCSU:
    case EFI_HII_SIBT_STRING_SCSU_FONT:
    case EFI_HII_SIBT_STRINGS_SCSU:
    case EFI_HII_SIBT_STRINGS_SCSU_FONT:
      Status = ConvertToUnicodeText (String, (CHAR8 *)StringTextPtr, StringSize);
      break;
    case EFI_HII_SIBT_STRING_UCS2:
    case EFI_HII_SIBT_STRING_UCS2_FONT:
    case EFI_HII_SIBT_STRINGS_UCS2:
    case EFI_HII_SIBT_STRINGS_UCS2_FONT:
      Status = GetUnicodeStringTextOrSize (String, StringTextPtr, StringSize);
      break;
    default:
      return EFI_NOT_FOUND;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the string font. The FontId 0 is the default font for those string blocks which
  // do not specify a font identifier. If default font is not specified, return NULL.
  //
  if (StringFontInfo != NULL) {
    switch (BlockType) {
      case EFI_HII_SIBT_STRING_SCSU_FONT:
      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
      case EFI_HII_SIBT_STRING_UCS2_FONT:
      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
        FontId = *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK));
        break;
      default:
        FontId = 0;
    }

    Status = GetStringFontInfo (StringPackage, FontId, StringFontInfo);
    if (Status == EFI_NOT_FOUND) {
      *StringFontInfo = NULL;
    }
  }

  return EFI_SUCCESS;
}

/**
  If GetStringBlock find the StringId's string is not saved in the exist string block,
  this function will create the UCS2 string block to save the string; also split the
  skip block into two or one skip block.

  This is a internal function.

  @param  StringPackage           Hii string package instance.
  @param  StartStringId           The first id in the skip block which StringId in the block.
  @param  StringId                The string's id, which is unique within
                                  PackageList.
  @param  BlockType               Output the block type of found string block.
  @param  StringBlockAddr         Output the block address of found string block.
  @param  FontBlock               whether this string block has font info.

  @retval EFI_SUCCESS            The string font is outputted successfully.
  @retval EFI_OUT_OF_RESOURCES   NO resource for the memory to save the new string block.

**/
EFI_STATUS
InsertLackStringBlock (
  IN OUT HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN EFI_STRING_ID                    StartStringId,
  IN EFI_STRING_ID                    StringId,
  IN OUT UINT8                        *BlockType,
  IN OUT UINT8                        **StringBlockAddr,
  IN BOOLEAN                          FontBlock
  )
{
  UINT8   *BlockPtr;
  UINT8   *StringBlock;
  UINT32  SkipLen;
  UINT32  OldBlockSize;
  UINT32  NewBlockSize;
  UINT32  FrontSkipNum;
  UINT32  NewUCSBlockLen;
  UINT8   *OldStringAddr;
  UINT32  IdCount;

  FrontSkipNum  = 0;
  SkipLen       = 0;
  OldStringAddr = *StringBlockAddr;

  ASSERT (*BlockType == EFI_HII_SIBT_SKIP1 || *BlockType == EFI_HII_SIBT_SKIP2);
  //
  // Old skip block size.
  //
  if (*BlockType == EFI_HII_SIBT_SKIP1) {
    SkipLen = sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
    IdCount = *(UINT8 *)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));
  } else {
    SkipLen = sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
    IdCount = *(UINT16 *)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));
  }

  //
  // New create UCS or UCS2 block size.
  //
  if (FontBlock) {
    NewUCSBlockLen = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK);
  } else {
    NewUCSBlockLen = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);
  }

  OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;

  if (StartStringId == StringId) {
    //
    // New block + [Skip block]
    //
    if (IdCount > 1) {
      NewBlockSize = OldBlockSize + NewUCSBlockLen;
    } else {
      NewBlockSize = OldBlockSize + NewUCSBlockLen - SkipLen;
    }
  } else if (StartStringId + IdCount - 1 == StringId) {
    //
    // Skip block + New block
    //
    NewBlockSize = OldBlockSize + NewUCSBlockLen;
    FrontSkipNum = StringId - StartStringId;
  } else {
    //
    // Skip block + New block + [Skip block]
    //
    NewBlockSize = OldBlockSize + NewUCSBlockLen + SkipLen;
    FrontSkipNum = StringId - StartStringId;
  }

  StringBlock = (UINT8 *)AllocateZeroPool (NewBlockSize);
  if (StringBlock == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Copy old block in front of skip block.
  //
  CopyMem (StringBlock, StringPackage->StringBlock, OldStringAddr - StringPackage->StringBlock);
  BlockPtr = StringBlock + (OldStringAddr - StringPackage->StringBlock);

  if (FrontSkipNum > 0) {
    *BlockPtr = *BlockType;
    if (*BlockType == EFI_HII_SIBT_SKIP1) {
      *(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT8)FrontSkipNum;
    } else {
      *(UINT16 *)(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT16)FrontSkipNum;
    }

    BlockPtr += SkipLen;
  }

  //
  // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
  //
  *StringBlockAddr = BlockPtr;
  if (FontBlock) {
    *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
  } else {
    *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
  }

  BlockPtr += NewUCSBlockLen;

  if (IdCount > FrontSkipNum + 1) {
    *BlockPtr = *BlockType;
    if (*BlockType == EFI_HII_SIBT_SKIP1) {
      *(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT8)(IdCount - FrontSkipNum - 1);
    } else {
      *(UINT16 *)(BlockPtr + sizeof (EFI_HII_STRING_BLOCK)) = (UINT16)(IdCount - FrontSkipNum - 1);
    }

    BlockPtr += SkipLen;
  }

  //
  // Append a EFI_HII_SIBT_END block to the end.
  //
  CopyMem (BlockPtr, OldStringAddr + SkipLen, OldBlockSize - (OldStringAddr - StringPackage->StringBlock) - SkipLen);

  if (FontBlock) {
    *BlockType = EFI_HII_SIBT_STRING_UCS2_FONT;
  } else {
    *BlockType = EFI_HII_SIBT_STRING_UCS2;
  }

  FreePool (StringPackage->StringBlock);
  StringPackage->StringBlock                  = StringBlock;
  StringPackage->StringPkgHdr->Header.Length += NewBlockSize - OldBlockSize;

  return EFI_SUCCESS;
}

/**
  Parse all string blocks to set a String specified by StringId.

  This is a internal function.

  @param  Private                HII database driver private structure.
  @param  StringPackage          HII string package instance.
  @param  StringId               The string's id, which is unique within
                                 PackageList.
  @param  String                 Points to the new null-terminated string.
  @param  StringFontInfo         Points to the input font info.

  @retval EFI_SUCCESS            The string was updated successfully.
  @retval EFI_NOT_FOUND          The string specified by StringId is not in the
                                 database.
  @retval EFI_INVALID_PARAMETER  The String or Language was NULL.
  @retval EFI_INVALID_PARAMETER  The specified StringFontInfo does not exist in
                                 current database.
  @retval EFI_OUT_OF_RESOURCES   The system is out of resources to accomplish the
                                 task.

**/
EFI_STATUS
SetStringWorker (
  IN  HII_DATABASE_PRIVATE_DATA       *Private,
  IN OUT HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN  EFI_STRING_ID                   StringId,
  IN  EFI_STRING                      String,
  IN  EFI_FONT_INFO                   *StringFontInfo OPTIONAL
  )
{
  UINT8                    *StringTextPtr;
  UINT8                    BlockType;
  UINT8                    *StringBlockAddr;
  UINTN                    StringTextOffset;
  EFI_STATUS               Status;
  UINT8                    *Block;
  UINT8                    *BlockPtr;
  UINTN                    BlockSize;
  UINTN                    OldBlockSize;
  HII_FONT_INFO            *LocalFont;
  HII_GLOBAL_FONT_INFO     *GlobalFont;
  BOOLEAN                  Referred;
  EFI_HII_SIBT_EXT2_BLOCK  Ext2;
  UINTN                    StringSize;
  UINTN                    TmpSize;
  EFI_STRING_ID            StartStringId;

  StartStringId = 0;
  StringSize    = 0;
  ASSERT (Private != NULL && StringPackage != NULL && String != NULL);
  ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
  //
  // Find the specified string block
  //
  Status = FindStringBlock (
             Private,
             StringPackage,
             StringId,
             &BlockType,
             &StringBlockAddr,
             &StringTextOffset,
             NULL,
             &StartStringId
             );
  if (EFI_ERROR (Status) && ((BlockType == EFI_HII_SIBT_SKIP1) || (BlockType == EFI_HII_SIBT_SKIP2))) {
    Status = InsertLackStringBlock (
               StringPackage,
               StartStringId,
               StringId,
               &BlockType,
               &StringBlockAddr,
               (BOOLEAN)(StringFontInfo != NULL)
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (StringFontInfo != NULL) {
      StringTextOffset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
    } else {
      StringTextOffset = sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16);
    }
  }

  LocalFont  = NULL;
  GlobalFont = NULL;
  Referred   = FALSE;

  //
  // The input StringFontInfo should exist in current database if specified.
  //
  if (StringFontInfo != NULL) {
    if (!IsFontInfoExisted (Private, StringFontInfo, NULL, NULL, &GlobalFont)) {
      return EFI_INVALID_PARAMETER;
    } else {
      Referred = ReferFontInfoLocally (
                   Private,
                   StringPackage,
                   StringPackage->FontId,
                   FALSE,
                   GlobalFont,
                   &LocalFont
                   );
      if (!Referred) {
        StringPackage->FontId++;
      }
    }

    //
    // Update the FontId of the specified string block to input font info.
    //
    switch (BlockType) {
      case EFI_HII_SIBT_STRING_SCSU_FONT:
      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
      case EFI_HII_SIBT_STRING_UCS2_FONT:
      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
        *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK)) = LocalFont->FontId;
        break;
      default:
        //
        // When modify the font info of these blocks, the block type should be updated
        // to contain font info thus the whole structure should be revised.
        // It is recommended to use tool to modify the block type not in the code.
        //
        return EFI_UNSUPPORTED;
    }
  }

  OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;

  //
  // Set the string text and font.
  //
  StringTextPtr = StringBlockAddr + StringTextOffset;
  switch (BlockType) {
    case EFI_HII_SIBT_STRING_SCSU:
    case EFI_HII_SIBT_STRING_SCSU_FONT:
    case EFI_HII_SIBT_STRINGS_SCSU:
    case EFI_HII_SIBT_STRINGS_SCSU_FONT:
      BlockSize  = OldBlockSize + StrLen (String);
      BlockSize -= AsciiStrSize ((CHAR8 *)StringTextPtr);
      Block      = AllocateZeroPool (BlockSize);
      if (Block == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);
      BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);

      while (*String != 0) {
        *BlockPtr++ = (CHAR8)*String++;
      }

      *BlockPtr++ = 0;

      TmpSize = OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - AsciiStrSize ((CHAR8 *)StringTextPtr);
      CopyMem (
        BlockPtr,
        StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr),
        TmpSize
        );

      ZeroMem (StringPackage->StringBlock, OldBlockSize);
      FreePool (StringPackage->StringBlock);
      StringPackage->StringBlock                  = Block;
      StringPackage->StringPkgHdr->Header.Length += (UINT32)(BlockSize - OldBlockSize);
      break;

    case EFI_HII_SIBT_STRING_UCS2:
    case EFI_HII_SIBT_STRING_UCS2_FONT:
    case EFI_HII_SIBT_STRINGS_UCS2:
    case EFI_HII_SIBT_STRINGS_UCS2_FONT:
      //
      // Use StrSize to store the size of the specified string, including the NULL
      // terminator.
      //
      GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);

      BlockSize = OldBlockSize + StrSize (String) - StringSize;
      Block     = AllocateZeroPool (BlockSize);
      if (Block == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (Block, StringPackage->StringBlock, StringTextPtr - StringPackage->StringBlock);
      BlockPtr = Block + (StringTextPtr - StringPackage->StringBlock);

      CopyMem (BlockPtr, String, StrSize (String));
      BlockPtr += StrSize (String);

      CopyMem (
        BlockPtr,
        StringTextPtr + StringSize,
        OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - StringSize
        );

      ZeroMem (StringPackage->StringBlock, OldBlockSize);
      FreePool (StringPackage->StringBlock);
      StringPackage->StringBlock                  = Block;
      StringPackage->StringPkgHdr->Header.Length += (UINT32)(BlockSize - OldBlockSize);
      break;

    default:
      return EFI_NOT_FOUND;
  }

  //
  // Insert a new EFI_HII_SIBT_FONT_BLOCK to the header of string block, if incoming
  // StringFontInfo does not exist in current string package.
  //
  // This new block does not impact on the value of StringId.
  //
  //
  if ((StringFontInfo == NULL) || Referred) {
    return EFI_SUCCESS;
  }

  OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
  BlockSize    = OldBlockSize + sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16) +
                 StrSize (GlobalFont->FontInfo->FontName);

  Block = AllocateZeroPool (BlockSize);
  if (Block == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  BlockPtr              = Block;
  Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;
  Ext2.BlockType2       = EFI_HII_SIBT_FONT;
  Ext2.Length           = (UINT16)(BlockSize - OldBlockSize);
  CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
  BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);

  *BlockPtr = LocalFont->FontId;
  BlockPtr++;
  CopyMem (BlockPtr, &GlobalFont->FontInfo->FontSize, sizeof (UINT16));
  BlockPtr += sizeof (UINT16);
  CopyMem (BlockPtr, &GlobalFont->FontInfo->FontStyle, sizeof (UINT32));
  BlockPtr += sizeof (UINT32);
  CopyMem (
    BlockPtr,
    GlobalFont->FontInfo->FontName,
    StrSize (GlobalFont->FontInfo->FontName)
    );
  BlockPtr += StrSize (GlobalFont->FontInfo->FontName);

  CopyMem (BlockPtr, StringPackage->StringBlock, OldBlockSize);

  ZeroMem (StringPackage->StringBlock, OldBlockSize);
  FreePool (StringPackage->StringBlock);
  StringPackage->StringBlock                  = Block;
  StringPackage->StringPkgHdr->Header.Length += Ext2.Length;

  return EFI_SUCCESS;
}

/**
  This function adds the string String to the group of strings owned by PackageList, with the
  specified font information StringFontInfo and returns a new string id.
  The new string identifier is guaranteed to be unique within the package list.
  That new string identifier is reserved for all languages in the package list.


  @param  This                   A pointer to the EFI_HII_STRING_PROTOCOL instance.
  @param  PackageList            Handle of the package list where this string will
                                 be added.
  @param  StringId               On return, contains the new strings id, which is
                                 unique within PackageList.
  @param  Language               Points to the language for the new string.
  @param  LanguageName           Points to the printable language name to associate
                                 with the passed in  Language field.If LanguageName
                                 is not NULL and the string package header's
                                 LanguageName  associated with a given Language is
                                 not zero, the LanguageName being passed  in will
                                 be ignored.
  @param  String                 Points to the new null-terminated string.
  @param  StringFontInfo         Points to the new string's font information or
                                 NULL if the string should have the default system
                                 font, size and style.

  @retval EFI_SUCCESS            The new string was added successfully.
  @retval EFI_NOT_FOUND          The specified PackageList could not be found in
                                 database.
  @retval EFI_OUT_OF_RESOURCES   Could not add the string due to lack of resources.
  @retval EFI_INVALID_PARAMETER  String is NULL or StringId is NULL or Language is
                                 NULL.
  @retval EFI_INVALID_PARAMETER  The specified StringFontInfo does not exist in
                                 current database.

**/
EFI_STATUS
EFIAPI
HiiNewString (
  IN  CONST EFI_HII_STRING_PROTOCOL  *This,
  IN  EFI_HII_HANDLE                 PackageList,
  OUT EFI_STRING_ID                  *StringId,
  IN  CONST CHAR8                    *Language,
  IN  CONST CHAR16                   *LanguageName  OPTIONAL,
  IN  CONST EFI_STRING               String,
  IN  CONST EFI_FONT_INFO            *StringFontInfo OPTIONAL
  )
{
  EFI_STATUS                          Status;
  LIST_ENTRY                          *Link;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *DatabaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;
  UINT32                              HeaderSize;
  UINT32                              BlockSize;
  UINT32                              OldBlockSize;
  UINT8                               *StringBlock;
  UINT8                               *BlockPtr;
  UINT32                              Ucs2BlockSize;
  UINT32                              FontBlockSize;
  UINT32                              Ucs2FontBlockSize;
  EFI_HII_SIBT_EXT2_BLOCK             Ext2;
  HII_FONT_INFO                       *LocalFont;
  HII_GLOBAL_FONT_INFO                *GlobalFont;
  EFI_STRING_ID                       NewStringId;
  EFI_STRING_ID                       NextStringId;
  EFI_STRING_ID                       Index;
  HII_STRING_PACKAGE_INSTANCE         *MatchStringPackage;
  BOOLEAN                             NewStringPackageCreated;

  if ((This == NULL) || (String == NULL) || (StringId == NULL) || (Language == NULL) || (PackageList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (PackageList)) {
    return EFI_NOT_FOUND;
  }

  Private    = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  GlobalFont = NULL;

  //
  // If StringFontInfo specify a paritcular font, it should exist in current database.
  //
  if (StringFontInfo != NULL) {
    if (!IsFontInfoExisted (Private, (EFI_FONT_INFO *)StringFontInfo, NULL, NULL, &GlobalFont)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Get the matching package list.
  //
  PackageListNode = NULL;
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (DatabaseRecord->Handle == PackageList) {
      PackageListNode = DatabaseRecord->PackageList;
      break;
    }
  }

  if (PackageListNode == NULL) {
    return EFI_NOT_FOUND;
  }

  EfiAcquireLock (&mHiiDatabaseLock);

  Status                  = EFI_SUCCESS;
  NewStringPackageCreated = FALSE;
  NewStringId             = 0;
  NextStringId            = 0;
  StringPackage           = NULL;
  MatchStringPackage      = NULL;
  for (Link = PackageListNode->StringPkgHdr.ForwardLink;
       Link != &PackageListNode->StringPkgHdr;
       Link = Link->ForwardLink
       )
  {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    //
    // Create a string block and corresponding font block if exists, then append them
    // to the end of the string package.
    //
    Status = FindStringBlock (
               Private,
               StringPackage,
               0,
               NULL,
               NULL,
               NULL,
               &NextStringId,
               NULL
               );
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    //
    // Make sure that new StringId is same in all String Packages for the different language.
    //
    if ((NewStringId != 0) && (NewStringId != NextStringId)) {
      ASSERT (FALSE);
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    NewStringId = NextStringId;
    //
    // Get the matched string package with language.
    //
    if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)Language)) {
      MatchStringPackage = StringPackage;
    } else {
      OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;
      //
      // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.
      //
      Ucs2BlockSize = (UINT32)sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);

      StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Ucs2BlockSize);
      if (StringBlock == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      //
      // Copy original string blocks, except the EFI_HII_SIBT_END.
      //
      CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
      //
      // Create a blank EFI_HII_SIBT_STRING_UCS2 block
      //
      BlockPtr  = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
      *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
      BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);

      //
      // Append a EFI_HII_SIBT_END block to the end.
      //
      *BlockPtr = EFI_HII_SIBT_END;
      ZeroMem (StringPackage->StringBlock, OldBlockSize);
      FreePool (StringPackage->StringBlock);
      StringPackage->StringBlock                     = StringBlock;
      StringPackage->StringPkgHdr->Header.Length    += Ucs2BlockSize;
      PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;
    }
  }

  if (NewStringId == 0) {
    //
    // No string package is found.
    // Create new string package. StringId 1 is reserved for Language Name string.
    //
    *StringId = 2;
  } else {
    //
    // Set new StringId
    //
    *StringId = (EFI_STRING_ID)(NewStringId + 1);
  }

  if (MatchStringPackage != NULL) {
    StringPackage = MatchStringPackage;
  } else {
    //
    // LanguageName is required to create a new string package.
    //
    if (LanguageName == NULL) {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
    if (StringPackage == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    StringPackage->Signature   = HII_STRING_PACKAGE_SIGNATURE;
    StringPackage->MaxStringId = *StringId;
    StringPackage->FontId      = 0;
    InitializeListHead (&StringPackage->FontInfoList);

    //
    // Fill in the string package header
    //
    HeaderSize                  = (UINT32)(AsciiStrSize ((CHAR8 *)Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));
    StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);
    if (StringPackage->StringPkgHdr == NULL) {
      FreePool (StringPackage);
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    StringPackage->StringPkgHdr->Header.Type      = EFI_HII_PACKAGE_STRINGS;
    StringPackage->StringPkgHdr->HdrSize          = HeaderSize;
    StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;
    CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));
    StringPackage->StringPkgHdr->LanguageName = 1;
    AsciiStrCpyS (StringPackage->StringPkgHdr->Language, (HeaderSize - OFFSET_OF (EFI_HII_STRING_PACKAGE_HDR, Language)) / sizeof (CHAR8), (CHAR8 *)Language);

    //
    // Calculate the length of the string blocks, including string block to record
    // printable language full name and EFI_HII_SIBT_END_BLOCK.
    //
    Ucs2BlockSize = (UINT32)(StrSize ((CHAR16 *)LanguageName) +
                             (*StringId - 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16));

    BlockSize                  = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK);
    StringPackage->StringBlock = (UINT8 *)AllocateZeroPool (BlockSize);
    if (StringPackage->StringBlock == NULL) {
      FreePool (StringPackage->StringPkgHdr);
      FreePool (StringPackage);
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    //
    // Insert the string block of printable language full name
    //
    BlockPtr  = StringPackage->StringBlock;
    *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
    BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
    CopyMem (BlockPtr, (EFI_STRING)LanguageName, StrSize ((EFI_STRING)LanguageName));
    BlockPtr += StrSize ((EFI_STRING)LanguageName);
    for (Index = 2; Index <= *StringId - 1; Index++) {
      *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
      BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);
    }

    //
    // Insert the end block
    //
    *BlockPtr = EFI_HII_SIBT_END;

    //
    // Append this string package node to string package array in this package list.
    //
    StringPackage->StringPkgHdr->Header.Length     = HeaderSize + BlockSize;
    PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
    InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry);
    NewStringPackageCreated = TRUE;
  }

  OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;

  if (StringFontInfo == NULL) {
    //
    // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.
    //
    Ucs2BlockSize = (UINT32)(StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK)
                             - sizeof (CHAR16));

    StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Ucs2BlockSize);
    if (StringBlock == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    //
    // Copy original string blocks, except the EFI_HII_SIBT_END.
    //
    CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
    //
    // Create a EFI_HII_SIBT_STRING_UCS2 block
    //
    BlockPtr  = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
    *BlockPtr = EFI_HII_SIBT_STRING_UCS2;
    BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
    CopyMem (BlockPtr, (EFI_STRING)String, StrSize ((EFI_STRING)String));
    BlockPtr += StrSize ((EFI_STRING)String);

    //
    // Append a EFI_HII_SIBT_END block to the end.
    //
    *BlockPtr = EFI_HII_SIBT_END;
    ZeroMem (StringPackage->StringBlock, OldBlockSize);
    FreePool (StringPackage->StringBlock);
    StringPackage->StringBlock                     = StringBlock;
    StringPackage->StringPkgHdr->Header.Length    += Ucs2BlockSize;
    PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;
  } else {
    //
    // StringFontInfo is specified here. If there is a EFI_HII_SIBT_FONT_BLOCK
    // which refers to this font info, create a EFI_HII_SIBT_STRING_UCS2_FONT block
    // only. Otherwise create a EFI_HII_SIBT_FONT block with a EFI_HII_SIBT_STRING
    // _UCS2_FONT block.
    //
    Ucs2FontBlockSize = (UINT32)(StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) -
                                 sizeof (CHAR16));
    if (ReferFontInfoLocally (Private, StringPackage, StringPackage->FontId, FALSE, GlobalFont, &LocalFont)) {
      //
      // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.
      //
      StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize);
      if (StringBlock == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      //
      // Copy original string blocks, except the EFI_HII_SIBT_END.
      //
      CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
      //
      // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
      //
      BlockPtr  = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);
      *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
      BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
      *BlockPtr = LocalFont->FontId;
      BlockPtr++;
      CopyMem (BlockPtr, (EFI_STRING)String, StrSize ((EFI_STRING)String));
      BlockPtr += StrSize ((EFI_STRING)String);

      //
      // Append a EFI_HII_SIBT_END block to the end.
      //
      *BlockPtr = EFI_HII_SIBT_END;
      ZeroMem (StringPackage->StringBlock, OldBlockSize);
      FreePool (StringPackage->StringBlock);
      StringPackage->StringBlock                     = StringBlock;
      StringPackage->StringPkgHdr->Header.Length    += Ucs2FontBlockSize;
      PackageListNode->PackageListHdr.PackageLength += Ucs2FontBlockSize;
    } else {
      //
      // EFI_HII_SIBT_FONT_BLOCK does not exist in current string package, so
      // create a EFI_HII_SIBT_FONT block to record the font info, then generate
      // a EFI_HII_SIBT_STRING_UCS2_FONT block to record the incoming string.
      //
      FontBlockSize = (UINT32)(StrSize (((EFI_FONT_INFO *)StringFontInfo)->FontName) +
                               sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16));
      StringBlock = (UINT8 *)AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize);
      if (StringBlock == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      //
      // Copy original string blocks, except the EFI_HII_SIBT_END.
      //
      CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));

      //
      // Create a EFI_HII_SIBT_FONT block firstly and then backup its info in string
      // package instance for future reference.
      //
      BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);

      Ext2.Header.BlockType = EFI_HII_SIBT_EXT2;
      Ext2.BlockType2       = EFI_HII_SIBT_FONT;
      Ext2.Length           = (UINT16)FontBlockSize;
      CopyMem (BlockPtr, &Ext2, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
      BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);

      *BlockPtr = LocalFont->FontId;
      BlockPtr++;
      CopyMem (BlockPtr, &((EFI_FONT_INFO *)StringFontInfo)->FontSize, sizeof (UINT16));
      BlockPtr += sizeof (UINT16);
      CopyMem (BlockPtr, &((EFI_FONT_INFO *)StringFontInfo)->FontStyle, sizeof (EFI_HII_FONT_STYLE));
      BlockPtr += sizeof (EFI_HII_FONT_STYLE);
      CopyMem (
        BlockPtr,
        &((EFI_FONT_INFO *)StringFontInfo)->FontName,
        StrSize (((EFI_FONT_INFO *)StringFontInfo)->FontName)
        );
      BlockPtr += StrSize (((EFI_FONT_INFO *)StringFontInfo)->FontName);
      //
      // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK
      //
      *BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;
      BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
      *BlockPtr = LocalFont->FontId;
      BlockPtr++;
      CopyMem (BlockPtr, (EFI_STRING)String, StrSize ((EFI_STRING)String));
      BlockPtr += StrSize ((EFI_STRING)String);

      //
      // Append a EFI_HII_SIBT_END block to the end.
      //
      *BlockPtr = EFI_HII_SIBT_END;
      ZeroMem (StringPackage->StringBlock, OldBlockSize);
      FreePool (StringPackage->StringBlock);
      StringPackage->StringBlock                     = StringBlock;
      StringPackage->StringPkgHdr->Header.Length    += FontBlockSize + Ucs2FontBlockSize;
      PackageListNode->PackageListHdr.PackageLength += FontBlockSize + Ucs2FontBlockSize;

      //
      // Increase the FontId to make it unique since we already add
      // a EFI_HII_SIBT_FONT block to this string package.
      //
      StringPackage->FontId++;
    }
  }

Done:
  if (!EFI_ERROR (Status) && NewStringPackageCreated) {
    //
    // Trigger any registered notification function for new string package
    //
    Status = InvokeRegisteredFunction (
               Private,
               EFI_HII_DATABASE_NOTIFY_NEW_PACK,
               (VOID *)StringPackage,
               EFI_HII_PACKAGE_STRINGS,
               PackageList
               );
  }

  if (!EFI_ERROR (Status)) {
    //
    // Update MaxString Id to new StringId
    //
    for (Link = PackageListNode->StringPkgHdr.ForwardLink;
         Link != &PackageListNode->StringPkgHdr;
         Link = Link->ForwardLink
         )
    {
      StringPackage              = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
      StringPackage->MaxStringId = *StringId;
    }
  } else if (NewStringPackageCreated) {
    //
    // Free the allocated new string Package when new string can't be added.
    //
    RemoveEntryList (&StringPackage->StringEntry);
    FreePool (StringPackage->StringBlock);
    FreePool (StringPackage->StringPkgHdr);
    FreePool (StringPackage);
  }

  //
  // The contents of HiiDataBase may updated,need to check.
  //
  //
  // Check whether need to get the contents of HiiDataBase.
  // Only after ReadyToBoot to do the export.
  //
  if (gExportAfterReadyToBoot) {
    if (!EFI_ERROR (Status)) {
      HiiGetDatabaseInfo (&Private->HiiDatabase);
    }
  }

  EfiReleaseLock (&mHiiDatabaseLock);

  return Status;
}

/**
  This function retrieves the string specified by StringId which is associated
  with the specified PackageList in the language Language and copies it into
  the buffer specified by String.

  @param  This                   A pointer to the EFI_HII_STRING_PROTOCOL instance.
  @param  Language               Points to the language for the retrieved string.
  @param  PackageList            The package list in the HII database to search for
                                 the  specified string.
  @param  StringId               The string's id, which is unique within
                                 PackageList.
  @param  String                 Points to the new null-terminated string.
  @param  StringSize             On entry, points to the size of the buffer pointed
                                 to by  String, in bytes. On return, points to the
                                 length of the string, in bytes.
  @param  StringFontInfo         If not NULL, points to the string's font
                                 information.  It's caller's responsibility to free
                                 this buffer.

  @retval EFI_SUCCESS            The string was returned successfully.
  @retval EFI_NOT_FOUND          The string specified by StringId is not available.
  @retval EFI_NOT_FOUND          The string specified by StringId is available but
                                                not in the specified language.
                                                The specified PackageList is not in the database.
  @retval EFI_INVALID_LANGUAGE   - The string specified by StringId is available but
  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by StringSize is too small to
                                  hold the string.
  @retval EFI_INVALID_PARAMETER  The Language or StringSize was NULL.
  @retval EFI_INVALID_PARAMETER  The value referenced by StringSize was not zero and String was NULL.
  @retval EFI_OUT_OF_RESOURCES   There were insufficient resources to complete the
                                 request.

**/
EFI_STATUS
EFIAPI
HiiGetString (
  IN  CONST EFI_HII_STRING_PROTOCOL  *This,
  IN  CONST CHAR8                    *Language,
  IN  EFI_HII_HANDLE                 PackageList,
  IN  EFI_STRING_ID                  StringId,
  OUT EFI_STRING                     String,
  IN  OUT UINTN                      *StringSize,
  OUT EFI_FONT_INFO                  **StringFontInfo OPTIONAL
  )
{
  EFI_STATUS                          Status;
  LIST_ENTRY                          *Link;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *DatabaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;

  if ((This == NULL) || (Language == NULL) || (StringId < 1) || (StringSize == NULL) || (PackageList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((String == NULL) && (*StringSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (PackageList)) {
    return EFI_NOT_FOUND;
  }

  Private         = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  PackageListNode = NULL;

  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (DatabaseRecord->Handle == PackageList) {
      PackageListNode = DatabaseRecord->PackageList;
      break;
    }
  }

  if (PackageListNode != NULL) {
    //
    // First search: to match the StringId in the specified language.
    //
    for (Link =  PackageListNode->StringPkgHdr.ForwardLink;
         Link != &PackageListNode->StringPkgHdr;
         Link =  Link->ForwardLink
         )
    {
      StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
      if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)Language)) {
        Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);
        if (Status != EFI_NOT_FOUND) {
          return Status;
        }
      }
    }

    //
    // Second search: to match the StringId in other available languages if exist.
    //
    for (Link =  PackageListNode->StringPkgHdr.ForwardLink;
         Link != &PackageListNode->StringPkgHdr;
         Link =  Link->ForwardLink
         )
    {
      StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
      Status        = GetStringWorker (Private, StringPackage, StringId, NULL, NULL, NULL);
      if (!EFI_ERROR (Status)) {
        return EFI_INVALID_LANGUAGE;
      }
    }
  }

  return EFI_NOT_FOUND;
}

/**
  This function updates the string specified by StringId in the specified PackageList to the text
  specified by String and, optionally, the font information specified by StringFontInfo.

  @param  This                   A pointer to the EFI_HII_STRING_PROTOCOL instance.
  @param  PackageList            The package list containing the strings.
  @param  StringId               The string's id, which is unique within
                                 PackageList.
  @param  Language               Points to the language for the updated string.
  @param  String                 Points to the new null-terminated string.
  @param  StringFontInfo         Points to the string's font information or NULL if
                                 the  string font information is not changed.

  @retval EFI_SUCCESS            The string was updated successfully.
  @retval EFI_NOT_FOUND          The string specified by StringId is not in the
                                 database.
  @retval EFI_INVALID_PARAMETER  The String or Language was NULL.
  @retval EFI_INVALID_PARAMETER  The specified StringFontInfo does not exist in
                                 current database.
  @retval EFI_OUT_OF_RESOURCES   The system is out of resources to accomplish the
                                 task.

**/
EFI_STATUS
EFIAPI
HiiSetString (
  IN CONST EFI_HII_STRING_PROTOCOL  *This,
  IN EFI_HII_HANDLE                 PackageList,
  IN EFI_STRING_ID                  StringId,
  IN CONST CHAR8                    *Language,
  IN CONST EFI_STRING               String,
  IN CONST EFI_FONT_INFO            *StringFontInfo OPTIONAL
  )
{
  EFI_STATUS                          Status;
  LIST_ENTRY                          *Link;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *DatabaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;
  UINT32                              OldPackageLen;

  if ((This == NULL) || (Language == NULL) || (StringId < 1) || (String == NULL) || (PackageList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (PackageList)) {
    return EFI_NOT_FOUND;
  }

  EfiAcquireLock (&mHiiDatabaseLock);

  Private         = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  PackageListNode = NULL;

  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (DatabaseRecord->Handle == PackageList) {
      PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(DatabaseRecord->PackageList);
    }
  }

  if (PackageListNode != NULL) {
    for (Link =  PackageListNode->StringPkgHdr.ForwardLink;
         Link != &PackageListNode->StringPkgHdr;
         Link =  Link->ForwardLink
         )
    {
      StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
      if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)Language)) {
        OldPackageLen = StringPackage->StringPkgHdr->Header.Length;
        Status        = SetStringWorker (
                          Private,
                          StringPackage,
                          StringId,
                          (EFI_STRING)String,
                          (EFI_FONT_INFO *)StringFontInfo
                          );
        if (EFI_ERROR (Status)) {
          EfiReleaseLock (&mHiiDatabaseLock);
          return Status;
        }

        PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length - OldPackageLen;
        //
        // Check whether need to get the contents of HiiDataBase.
        // Only after ReadyToBoot to do the export.
        //
        if (gExportAfterReadyToBoot) {
          HiiGetDatabaseInfo (&Private->HiiDatabase);
        }

        EfiReleaseLock (&mHiiDatabaseLock);
        return EFI_SUCCESS;
      }
    }
  }

  EfiReleaseLock (&mHiiDatabaseLock);
  return EFI_NOT_FOUND;
}

/**
  This function returns the list of supported languages, in the format specified
  in Appendix M of UEFI 2.1 spec.

  @param  This                   A pointer to the EFI_HII_STRING_PROTOCOL instance.
  @param  PackageList            The package list to examine.
  @param  Languages              Points to the buffer to hold the returned
                                 null-terminated ASCII string.
  @param  LanguagesSize          On entry, points to the size of the buffer pointed
                                 to by  Languages, in bytes. On  return, points to
                                 the length of Languages, in bytes.

  @retval EFI_SUCCESS            The languages were returned successfully.
  @retval EFI_INVALID_PARAMETER  The LanguagesSize was NULL.
  @retval EFI_INVALID_PARAMETER  The value referenced by LanguagesSize is not zero and Languages is NULL.
  @retval EFI_BUFFER_TOO_SMALL   The LanguagesSize is too small to hold the list of
                                  supported languages. LanguageSize is updated to
                                 contain the required size.
  @retval EFI_NOT_FOUND          Could not find string package in specified
                                 packagelist.

**/
EFI_STATUS
EFIAPI
HiiGetLanguages (
  IN CONST EFI_HII_STRING_PROTOCOL  *This,
  IN EFI_HII_HANDLE                 PackageList,
  IN OUT CHAR8                      *Languages,
  IN OUT UINTN                      *LanguagesSize
  )
{
  LIST_ENTRY                          *Link;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *DatabaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;
  UINTN                               ResultSize;

  if ((This == NULL) || (LanguagesSize == NULL) || (PackageList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((*LanguagesSize != 0) && (Languages == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (PackageList)) {
    return EFI_NOT_FOUND;
  }

  Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  PackageListNode = NULL;
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (DatabaseRecord->Handle == PackageList) {
      PackageListNode = DatabaseRecord->PackageList;
      break;
    }
  }

  if (PackageListNode == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Search the languages in the specified packagelist.
  //
  ResultSize = 0;
  for (Link = PackageListNode->StringPkgHdr.ForwardLink;
       Link != &PackageListNode->StringPkgHdr;
       Link = Link->ForwardLink
       )
  {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    ResultSize   += AsciiStrSize (StringPackage->StringPkgHdr->Language);
    if (ResultSize <= *LanguagesSize) {
      AsciiStrCpyS (Languages, *LanguagesSize / sizeof (CHAR8), StringPackage->StringPkgHdr->Language);
      Languages       += AsciiStrSize (StringPackage->StringPkgHdr->Language);
      *(Languages - 1) = L';';
    }
  }

  if (ResultSize == 0) {
    return EFI_NOT_FOUND;
  }

  if (*LanguagesSize < ResultSize) {
    *LanguagesSize = ResultSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  *(Languages - 1) = 0;
  return EFI_SUCCESS;
}

/**
  Each string package has associated with it a single primary language and zero
  or more secondary languages. This routine returns the secondary languages
  associated with a package list.

  @param  This                   A pointer to the EFI_HII_STRING_PROTOCOL instance.
  @param  PackageList            The package list to examine.
  @param  PrimaryLanguage        Points to the null-terminated ASCII string that specifies
                                 the primary language. Languages are specified in the
                                 format specified in Appendix M of the UEFI 2.0 specification.
  @param  SecondaryLanguages     Points to the buffer to hold the returned null-terminated
                                 ASCII string that describes the list of
                                 secondary languages for the specified
                                 PrimaryLanguage. If there are no secondary
                                 languages, the function returns successfully, but
                                 this is set to NULL.
  @param  SecondaryLanguagesSize On entry, points to the size of the buffer pointed
                                 to by SecondaryLanguages, in bytes. On return,
                                 points to the length of SecondaryLanguages in bytes.

  @retval EFI_SUCCESS            Secondary languages were correctly returned.
  @retval EFI_INVALID_PARAMETER  PrimaryLanguage or SecondaryLanguagesSize was NULL.
  @retval EFI_INVALID_PARAMETER  The value referenced by SecondaryLanguagesSize is not
                                 zero and SecondaryLanguages is NULL.
  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by SecondaryLanguagesSize is
                                 too small to hold the returned information.
                                 SecondaryLanguageSize is updated to hold the size of
                                 the buffer required.
  @retval EFI_INVALID_LANGUAGE   The language specified by PrimaryLanguage is not
                                 present in the specified package list.
  @retval EFI_NOT_FOUND          The specified PackageList is not in the Database.

**/
EFI_STATUS
EFIAPI
HiiGetSecondaryLanguages (
  IN CONST EFI_HII_STRING_PROTOCOL  *This,
  IN EFI_HII_HANDLE                 PackageList,
  IN CONST CHAR8                    *PrimaryLanguage,
  IN OUT CHAR8                      *SecondaryLanguages,
  IN OUT UINTN                      *SecondaryLanguagesSize
  )
{
  LIST_ENTRY                          *Link;
  LIST_ENTRY                          *Link1;
  HII_DATABASE_PRIVATE_DATA           *Private;
  HII_DATABASE_RECORD                 *DatabaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;
  CHAR8                               *Languages;
  UINTN                               ResultSize;

  if ((This == NULL) || (PackageList == NULL) || (PrimaryLanguage == NULL) || (SecondaryLanguagesSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((SecondaryLanguages == NULL) && (*SecondaryLanguagesSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsHiiHandleValid (PackageList)) {
    return EFI_NOT_FOUND;
  }

  Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  PackageListNode = NULL;
  for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
    DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if (DatabaseRecord->Handle == PackageList) {
      PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *)(DatabaseRecord->PackageList);
      break;
    }
  }

  if (PackageListNode == NULL) {
    return EFI_NOT_FOUND;
  }

  Languages  = NULL;
  ResultSize = 0;
  for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;
       Link1 != &PackageListNode->StringPkgHdr;
       Link1 = Link1->ForwardLink
       )
  {
    StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);
    if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *)PrimaryLanguage)) {
      Languages = StringPackage->StringPkgHdr->Language;
      //
      // Language is a series of ';' terminated strings, first one is primary
      // language and following with other secondary languages or NULL if no
      // secondary languages any more.
      //
      Languages = AsciiStrStr (Languages, ";");
      if (Languages == NULL) {
        break;
      }

      Languages++;

      ResultSize = AsciiStrSize (Languages);
      if (ResultSize <= *SecondaryLanguagesSize) {
        AsciiStrCpyS (SecondaryLanguages, *SecondaryLanguagesSize / sizeof (CHAR8), Languages);
      } else {
        *SecondaryLanguagesSize = ResultSize;
        return EFI_BUFFER_TOO_SMALL;
      }

      return EFI_SUCCESS;
    }
  }

  return EFI_INVALID_LANGUAGE;
}

/**
  Converts the ascii character of the string from uppercase to lowercase.
  This is a internal function.

  @param ConfigString  String to be converted

**/
VOID
EFIAPI
AsciiHiiToLower (
  IN CHAR8  *ConfigString
  )
{
  ASSERT (ConfigString != NULL);

  //
  // Convert all hex digits in range [A-F] in the configuration header to [a-f]
  //
  for ( ; *ConfigString != '\0'; ConfigString++) {
    if ((*ConfigString >= 'A') && (*ConfigString <= 'Z')) {
      *ConfigString = (CHAR8)(*ConfigString - 'A' + 'a');
    }
  }
}

/**
  Compare whether two names of languages are identical.

  @param  Language1              Name of language 1 from StringPackage
  @param  Language2              Name of language 2 to be compared with language 1.

  @retval TRUE                   same
  @retval FALSE                  not same

**/
BOOLEAN
HiiCompareLanguage (
  IN  CHAR8  *Language1,
  IN  CHAR8  *Language2
  )
{
  UINTN  Index;
  UINTN  StrLen;
  CHAR8  *Lan1;
  CHAR8  *Lan2;

  //
  // Convert to lower to compare.
  //
  StrLen = AsciiStrSize (Language1);
  Lan1   = AllocateZeroPool (StrLen);
  ASSERT (Lan1 != NULL);
  AsciiStrCpyS (Lan1, StrLen / sizeof (CHAR8), Language1);
  AsciiHiiToLower (Lan1);

  StrLen = AsciiStrSize (Language2);
  Lan2   = AllocateZeroPool (StrLen);
  ASSERT (Lan2 != NULL);
  AsciiStrCpyS (Lan2, StrLen / sizeof (CHAR8), Language2);
  AsciiHiiToLower (Lan2);

  //
  // Compare the Primary Language in Language1 to Language2
  //
  for (Index = 0; Lan1[Index] != 0 && Lan1[Index] != ';'; Index++) {
    if (Lan1[Index] != Lan2[Index]) {
      //
      // Return FALSE if any characters are different.
      //
      FreePool (Lan1);
      FreePool (Lan2);
      return FALSE;
    }
  }

  FreePool (Lan1);
  FreePool (Lan2);

  //
  // Only return TRUE if Language2[Index] is a Null-terminator which means
  // the Primary Language in Language1 is the same length as Language2.  If
  // Language2[Index] is not a Null-terminator, then Language2 is longer than
  // the Primary Language in Language1, and FALSE must be returned.
  //
  return (BOOLEAN)(Language2[Index] == 0);
}
