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;
}

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;
       
       
       
      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;
      }
       
       
       
      CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));
       
       
       
      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);

       
       
       
      *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;
}
