IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,\r
IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList,\r
OUT HII_STRING_PACKAGE_INSTANCE **Package\r
-\r
)\r
{\r
HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
\r
}\r
\r
+/**\r
+ Adjust all string packages in a single package list to have the same max string ID.\r
+ \r
+ @param PackageList Pointer to a package list which will be adjusted.\r
+\r
+ @retval EFI_SUCCESS Adjust all string packages successfully.\r
+ @retval others Can't adjust string packges.\r
+\r
+**/\r
+EFI_STATUS\r
+AdjustStringPackage (\r
+ IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList\r
+)\r
+{\r
+ LIST_ENTRY *Link;\r
+ HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
+ UINT32 Skip2BlockSize;\r
+ UINT32 OldBlockSize;\r
+ UINT8 *StringBlock;\r
+ UINT8 *BlockPtr;\r
+ EFI_STRING_ID MaxStringId;\r
+ UINT16 SkipCount;\r
+\r
+ MaxStringId = 0;\r
+ for (Link = PackageList->StringPkgHdr.ForwardLink;\r
+ Link != &PackageList->StringPkgHdr;\r
+ Link = Link->ForwardLink\r
+ ) {\r
+ StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
+ if (MaxStringId < StringPackage->MaxStringId) {\r
+ MaxStringId = StringPackage->MaxStringId;\r
+ }\r
+ }\r
+\r
+ for (Link = PackageList->StringPkgHdr.ForwardLink;\r
+ Link != &PackageList->StringPkgHdr;\r
+ Link = Link->ForwardLink\r
+ ) {\r
+ StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
+ if (StringPackage->MaxStringId < MaxStringId) {\r
+ OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
+ //\r
+ // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs.\r
+ //\r
+ SkipCount = (UINT16) (MaxStringId - StringPackage->MaxStringId);\r
+ Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+\r
+ StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize);\r
+ if (StringBlock == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Copy original string blocks, except the EFI_HII_SIBT_END.\r
+ //\r
+ CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK));\r
+ //\r
+ // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks\r
+ //\r
+ BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
+ *BlockPtr = EFI_HII_SIBT_SKIP2;\r
+ CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16));\r
+ BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
+\r
+ //\r
+ // Append a EFI_HII_SIBT_END block to the end.\r
+ //\r
+ *BlockPtr = EFI_HII_SIBT_END;\r
+ FreePool (StringPackage->StringBlock);\r
+ StringPackage->StringBlock = StringBlock;\r
+ StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize;\r
+ PackageList->PackageListHdr.PackageLength += Skip2BlockSize;\r
+ StringPackage->MaxStringId = MaxStringId;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
\r
/**\r
This function exports String packages to a buffer.\r
EFI_HII_PACKAGE_HEADER *PackageHdrPtr;\r
EFI_HII_PACKAGE_HEADER PackageHeader;\r
UINT32 OldPackageListLen;\r
+ BOOLEAN StringPkgIsAdd;\r
\r
//\r
// Initialize Variables\r
//\r
+ StringPkgIsAdd = FALSE;\r
FontPackage = NULL;\r
\r
//\r
(UINT8) (PackageHeader.Type),\r
DatabaseRecord->Handle\r
);\r
+ StringPkgIsAdd = TRUE;\r
break;\r
case EFI_HII_PACKAGE_FONTS:\r
Status = InsertFontPackage (\r
PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length);\r
CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER));\r
}\r
+ \r
+ //\r
+ // Adjust String Package to make sure all string packages have the same max string ID.\r
+ //\r
+ if (!EFI_ERROR (Status) && StringPkgIsAdd) {\r
+ Status = AdjustStringPackage (DatabaseRecord->PackageList);\r
+ }\r
\r
return Status;\r
}\r