/** @file\r
Implementation for EFI_HII_DATABASE_PROTOCOL.\r
\r
-\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) {\r
FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);\r
PackageLength += FormPackage->FormPkgHdr.Length;\r
- if (PackageLength + *ResultSize + UsedSize <= BufferSize) {\r
+ if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) {\r
//\r
// Invoke registered notification if exists\r
//\r
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
// Collect all font block info\r
//\r
- Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL);\r
+ Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\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
@param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER\r
structure.\r
@param DriverHandle Associate the package list with this EFI handle.\r
+ If a NULL is specified, this data will not be associate\r
+ with any drivers and cannot have a callback induced.\r
@param Handle A pointer to the EFI_HII_HANDLE instance.\r
\r
@retval EFI_SUCCESS The package list associated with the Handle was\r
HiiNewPackageList (\r
IN CONST EFI_HII_DATABASE_PROTOCOL *This,\r
IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,\r
- IN CONST EFI_HANDLE DriverHandle,\r
+ IN CONST EFI_HANDLE DriverHandle, OPTIONAL\r
OUT EFI_HII_HANDLE *Handle\r
)\r
{\r
DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
if (CompareGuid (\r
&(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),\r
- &PackageListGuid\r
- )\r
- ) {\r
+ &PackageListGuid) && \r
+ DatabaseRecord->DriverHandle == DriverHandle) {\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r