X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FHiiDatabaseDxe%2FDatabase.c;h=ec56795ebb1924942403472a062cc3129aecbc8c;hp=5a37dd0ef37b9d369355b67692331b08e81c1f67;hb=4d5b08684f08db04ee95cf94f913135e1eecd0f7;hpb=676df92c2c0c5bdeb0f8e27349f5dd467928ce09 diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c index 5a37dd0ef3..ec56795ebb 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c @@ -1,9 +1,8 @@ /** @file Implementation for EFI_HII_DATABASE_PROTOCOL. - -Copyright (c) 2007 - 2008, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -16,12 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "HiiDatabase.h" -// -// Global variables -// -EFI_GUID mHiiDatabaseNotifyGuid = HII_DATABASE_NOTIFY_GUID; - - /** This function generates a HII_DATABASE_RECORD node and adds into hii database. This is a internal function. @@ -87,7 +80,7 @@ GenerateHiiDatabaseRecord ( // Backup the number of Hii handles // Private->HiiHandleCount++; - HiiHandle->Key = Private->HiiHandleCount; + HiiHandle->Key = (UINTN) Private->HiiHandleCount; // // Insert the handle to hii handle list of the whole database. // @@ -195,7 +188,7 @@ InvokeRegisteredFunction ( Package = (EFI_HII_PACKAGE_HEADER *) (((HII_GUID_PACKAGE_INSTANCE *) PackageInstance)->GuidPkg); break; - case EFI_HII_PACKAGE_FORM: + case EFI_HII_PACKAGE_FORMS: BufferSize = ((HII_IFR_PACKAGE_INSTANCE *) PackageInstance)->FormPkgHdr.Length; Buffer = (UINT8 *) AllocateZeroPool (BufferSize); ASSERT (Buffer != NULL); @@ -659,7 +652,7 @@ ExportFormPackages ( for (Link = PackageList->FormPkgHdr.ForwardLink; Link != &PackageList->FormPkgHdr; Link = Link->ForwardLink) { FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE); PackageLength += FormPackage->FormPkgHdr.Length; - if (PackageLength + *ResultSize + UsedSize <= BufferSize) { + if ((Buffer != NULL) && (PackageLength + *ResultSize + UsedSize <= BufferSize)) { // // Invoke registered notification if exists // @@ -667,7 +660,7 @@ ExportFormPackages ( Private, EFI_HII_DATABASE_NOTIFY_EXPORT_PACK, (VOID *) FormPackage, - EFI_HII_PACKAGE_FORM, + EFI_HII_PACKAGE_FORMS, Handle ); ASSERT_EFI_ERROR (Status); @@ -730,7 +723,7 @@ RemoveFormPackages ( Private, EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, (VOID *) Package, - EFI_HII_PACKAGE_FORM, + EFI_HII_PACKAGE_FORMS, Handle ); if (EFI_ERROR (Status)) { @@ -776,7 +769,6 @@ InsertStringPackage ( IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType, IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList, OUT HII_STRING_PACKAGE_INSTANCE **Package - ) { HII_STRING_PACKAGE_INSTANCE *StringPackage; @@ -806,10 +798,10 @@ InsertStringPackage ( if (Language == NULL) { return EFI_OUT_OF_RESOURCES; } - AsciiStrCpy (Language, (CHAR8 *) PackageHdr + HeaderSize - LanguageSize); + AsciiStrCpyS (Language, LanguageSize / sizeof (CHAR8), (CHAR8 *) PackageHdr + HeaderSize - LanguageSize); for (Link = PackageList->StringPkgHdr.ForwardLink; Link != &PackageList->StringPkgHdr; Link = Link->ForwardLink) { StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); - if (R8_EfiLibCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) { + if (HiiCompareLanguage (Language, StringPackage->StringPkgHdr->Language)) { FreePool (Language); return EFI_UNSUPPORTED; } @@ -858,7 +850,7 @@ InsertStringPackage ( // // Collect all font block info // - Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL); + Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId, NULL); if (EFI_ERROR (Status)) { return Status; } @@ -877,19 +869,96 @@ InsertStringPackage ( Error: - if (StringPackage->StringBlock != NULL) { - FreePool (StringPackage->StringBlock); - } - if (StringPackage->StringPkgHdr != NULL) { - FreePool (StringPackage->StringPkgHdr); - } if (StringPackage != NULL) { + if (StringPackage->StringBlock != NULL) { + FreePool (StringPackage->StringBlock); + } + if (StringPackage->StringPkgHdr != NULL) { + FreePool (StringPackage->StringPkgHdr); + } FreePool (StringPackage); } return Status; } +/** + Adjust all string packages in a single package list to have the same max string ID. + + @param PackageList Pointer to a package list which will be adjusted. + + @retval EFI_SUCCESS Adjust all string packages successfully. + @retval others Can't adjust string packges. + +**/ +EFI_STATUS +AdjustStringPackage ( + IN OUT HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageList +) +{ + LIST_ENTRY *Link; + HII_STRING_PACKAGE_INSTANCE *StringPackage; + UINT32 Skip2BlockSize; + UINT32 OldBlockSize; + UINT8 *StringBlock; + UINT8 *BlockPtr; + EFI_STRING_ID MaxStringId; + UINT16 SkipCount; + + MaxStringId = 0; + for (Link = PackageList->StringPkgHdr.ForwardLink; + Link != &PackageList->StringPkgHdr; + Link = Link->ForwardLink + ) { + StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); + if (MaxStringId < StringPackage->MaxStringId) { + MaxStringId = StringPackage->MaxStringId; + } + } + + for (Link = PackageList->StringPkgHdr.ForwardLink; + Link != &PackageList->StringPkgHdr; + Link = Link->ForwardLink + ) { + StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); + if (StringPackage->MaxStringId < MaxStringId) { + OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize; + // + // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCKs to reserve the missing string IDs. + // + SkipCount = (UINT16) (MaxStringId - StringPackage->MaxStringId); + Skip2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_SKIP2_BLOCK); + + StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Skip2BlockSize); + if (StringBlock == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Copy original string blocks, except the EFI_HII_SIBT_END. + // + CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK)); + // + // Create SKIP2 EFI_HII_SIBT_SKIP2_BLOCK blocks + // + BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK); + *BlockPtr = EFI_HII_SIBT_SKIP2; + CopyMem (BlockPtr + 1, &SkipCount, sizeof (UINT16)); + BlockPtr += sizeof (EFI_HII_SIBT_SKIP2_BLOCK); + + // + // Append a EFI_HII_SIBT_END block to the end. + // + *BlockPtr = EFI_HII_SIBT_END; + FreePool (StringPackage->StringBlock); + StringPackage->StringBlock = StringBlock; + StringPackage->StringPkgHdr->Header.Length += Skip2BlockSize; + PackageList->PackageListHdr.PackageLength += Skip2BlockSize; + StringPackage->MaxStringId = MaxStringId; + } + } + + return EFI_SUCCESS; +} /** This function exports String packages to a buffer. @@ -1113,7 +1182,7 @@ InsertFontPackage ( } FontInfo->FontStyle = FontPkgHdr->FontStyle; FontInfo->FontSize = FontPkgHdr->Cell.Height; - StrCpy (FontInfo->FontName, FontPkgHdr->FontFamily); + StrCpyS (FontInfo->FontName, (FontInfoSize - OFFSET_OF(EFI_FONT_INFO,FontName)) / sizeof (CHAR16), FontPkgHdr->FontFamily); if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, NULL)) { Status = EFI_UNSUPPORTED; @@ -1182,10 +1251,10 @@ Error: if (FontInfo != NULL) { FreePool (FontInfo); } - if (FontPackage->GlyphBlock != NULL) { - FreePool (FontPackage->GlyphBlock); - } if (FontPackage != NULL) { + if (FontPackage->GlyphBlock != NULL) { + FreePool (FontPackage->GlyphBlock); + } FreePool (FontPackage); } if (GlobalFont != NULL) { @@ -1713,10 +1782,10 @@ InsertSimpleFontPackage ( Error: - if (SimpleFontPackage->SimpleFontPkgHdr != NULL) { - FreePool (SimpleFontPackage->SimpleFontPkgHdr); - } if (SimpleFontPackage != NULL) { + if (SimpleFontPackage->SimpleFontPkgHdr != NULL) { + FreePool (SimpleFontPackage->SimpleFontPkgHdr); + } FreePool (SimpleFontPackage); } return Status; @@ -2158,10 +2227,11 @@ InsertKeyboardLayoutPackage ( Error: - if (KeyboardLayoutPackage->KeyboardPkg != NULL) { - FreePool (KeyboardLayoutPackage->KeyboardPkg); - } + if (KeyboardLayoutPackage != NULL) { + if (KeyboardLayoutPackage->KeyboardPkg != NULL) { + FreePool (KeyboardLayoutPackage->KeyboardPkg); + } FreePool (KeyboardLayoutPackage); } @@ -2342,11 +2412,19 @@ AddPackages ( EFI_HII_PACKAGE_HEADER *PackageHdrPtr; EFI_HII_PACKAGE_HEADER PackageHeader; UINT32 OldPackageListLen; + BOOLEAN StringPkgIsAdd; // // Initialize Variables // - FontPackage = NULL; + StringPkgIsAdd = FALSE; + FontPackage = NULL; + StringPackage = NULL; + GuidPackage = NULL; + FormPackage = NULL; + ImagePackage = NULL; + SimpleFontPackage = NULL; + KeyboardLayoutPackage = NULL; // // Process the package list header @@ -2386,7 +2464,7 @@ AddPackages ( DatabaseRecord->Handle ); break; - case EFI_HII_PACKAGE_FORM: + case EFI_HII_PACKAGE_FORMS: Status = InsertFormPackage ( PackageHdrPtr, NotifyType, @@ -2433,6 +2511,7 @@ AddPackages ( if (EFI_ERROR (Status)) { return Status; } + ASSERT (StringPackage != NULL); Status = InvokeRegisteredFunction ( Private, NotifyType, @@ -2440,6 +2519,7 @@ AddPackages ( (UINT8) (PackageHeader.Type), DatabaseRecord->Handle ); + StringPkgIsAdd = TRUE; break; case EFI_HII_PACKAGE_FONTS: Status = InsertFontPackage ( @@ -2517,6 +2597,13 @@ AddPackages ( PackageHdrPtr = (EFI_HII_PACKAGE_HEADER *) ((UINT8 *) PackageHdrPtr + PackageHeader.Length); CopyMem (&PackageHeader, PackageHdrPtr, sizeof (EFI_HII_PACKAGE_HEADER)); } + + // + // Adjust String Package to make sure all string packages have the same max string ID. + // + if (!EFI_ERROR (Status) && StringPkgIsAdd) { + Status = AdjustStringPackage (DatabaseRecord->PackageList); + } return Status; } @@ -2555,7 +2642,7 @@ ExportPackageList ( UINTN ResultSize; EFI_HII_PACKAGE_HEADER EndofPackageList; - ASSERT (Private != NULL || PackageList != NULL || UsedSize != NULL); + ASSERT (Private != NULL && PackageList != NULL && UsedSize != NULL); ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE); ASSERT (IsHiiHandleValid (Handle)); @@ -2699,6 +2786,8 @@ ExportPackageList ( @param PackageList A pointer to an EFI_HII_PACKAGE_LIST_HEADER structure. @param DriverHandle Associate the package list with this EFI handle. + If a NULL is specified, this data will not be associate + with any drivers and cannot have a callback induced. @param Handle A pointer to the EFI_HII_HANDLE instance. @retval EFI_SUCCESS The package list associated with the Handle was @@ -2714,7 +2803,7 @@ EFIAPI HiiNewPackageList ( IN CONST EFI_HII_DATABASE_PROTOCOL *This, IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList, - IN CONST EFI_HANDLE DriverHandle, + IN CONST EFI_HANDLE DriverHandle, OPTIONAL OUT EFI_HII_HANDLE *Handle ) { @@ -2739,9 +2828,8 @@ HiiNewPackageList ( DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE); if (CompareGuid ( &(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid), - &PackageListGuid - ) - ) { + &PackageListGuid) && + DatabaseRecord->DriverHandle == DriverHandle) { return EFI_INVALID_PARAMETER; } } @@ -2957,7 +3045,7 @@ HiiUpdatePackageList ( case EFI_HII_PACKAGE_TYPE_GUID: Status = RemoveGuidPackages (Private, Handle, OldPackageList); break; - case EFI_HII_PACKAGE_FORM: + case EFI_HII_PACKAGE_FORMS: Status = RemoveFormPackages (Private, Handle, OldPackageList); break; case EFI_HII_PACKAGE_KEYBOARD_LAYOUT: @@ -3019,17 +3107,18 @@ HiiUpdatePackageList ( @param Handle An array of EFI_HII_HANDLE instances returned. @retval EFI_SUCCESS The matching handles are outputed successfully. - HandleBufferLength is updated with the actual length. + HandleBufferLength is updated with the actual length. @retval EFI_BUFFER_TO_SMALL The HandleBufferLength parameter indicates that Handle is too small to support the number of handles. HandleBufferLength is updated with a value that will enable the data to fit. @retval EFI_NOT_FOUND No matching handle could not be found in database. - @retval EFI_INVALID_PARAMETER Handle or HandleBufferLength was NULL. - + @retval EFI_INVALID_PARAMETER HandleBufferLength was NULL. + @retval EFI_INVALID_PARAMETER The value referenced by HandleBufferLength was not + zero and Handle was NULL. @retval EFI_INVALID_PARAMETER PackageType is not a EFI_HII_PACKAGE_TYPE_GUID but - PackageGuid is not NULL, PackageType is a EFI_HII_ - PACKAGE_TYPE_GUID but PackageGuid is NULL. + PackageGuid is not NULL, PackageType is a EFI_HII_ + PACKAGE_TYPE_GUID but PackageGuid is NULL. **/ EFI_STATUS @@ -3087,7 +3176,7 @@ HiiListPackageLists ( } } break; - case EFI_HII_PACKAGE_FORM: + case EFI_HII_PACKAGE_FORMS: if (!IsListEmpty (&PackageList->FormPkgHdr)) { Matched = TRUE; } @@ -3182,7 +3271,9 @@ HiiListPackageLists ( value that will enable the data to fit. @retval EFI_NOT_FOUND The specifiecd Handle could not be found in the current database. - @retval EFI_INVALID_PARAMETER Handle or Buffer or BufferSize was NULL. + @retval EFI_INVALID_PARAMETER BufferSize was NULL. + @retval EFI_INVALID_PARAMETER The value referenced by BufferSize was not zero + and Buffer was NULL. **/ EFI_STATUS @@ -3200,13 +3291,13 @@ HiiExportPackageLists ( HII_DATABASE_RECORD *Node; UINTN UsedSize; - if (This == NULL || BufferSize == NULL || Handle == NULL) { + if (This == NULL || BufferSize == NULL) { return EFI_INVALID_PARAMETER; } if (*BufferSize > 0 && Buffer == NULL) { return EFI_INVALID_PARAMETER; } - if (!IsHiiHandleValid (Handle)) { + if ((Handle != NULL) && (!IsHiiHandleValid (Handle))) { return EFI_NOT_FOUND; } @@ -3228,8 +3319,7 @@ HiiExportPackageLists ( (EFI_HII_PACKAGE_LIST_HEADER *)((UINT8 *) Buffer + UsedSize) ); ASSERT_EFI_ERROR (Status); - } - else if (Handle != NULL && Node->Handle == Handle) { + } else if (Handle != NULL && Node->Handle == Handle) { Status = ExportPackageList ( Private, Handle, @@ -3333,7 +3423,7 @@ HiiRegisterPackageNotify ( // Status = gBS->InstallMultipleProtocolInterfaces ( &Notify->NotifyHandle, - &mHiiDatabaseNotifyGuid, + &gEfiCallerIdGuid, NULL, NULL ); @@ -3391,7 +3481,7 @@ HiiUnregisterPackageNotify ( Status = gBS->OpenProtocol ( NotificationHandle, - &mHiiDatabaseNotifyGuid, + &gEfiCallerIdGuid, NULL, NULL, NULL, @@ -3412,7 +3502,7 @@ HiiUnregisterPackageNotify ( RemoveEntryList (&Notify->DatabaseNotifyEntry); Status = gBS->UninstallMultipleProtocolInterfaces ( Notify->NotifyHandle, - &mHiiDatabaseNotifyGuid, + &gEfiCallerIdGuid, NULL, NULL ); @@ -3445,7 +3535,9 @@ HiiUnregisterPackageNotify ( number of GUIDs. KeyGuidBufferLength is updated with a value that will enable the data to fit. - @retval EFI_INVALID_PARAMETER The KeyGuidBuffer or KeyGuidBufferLength was NULL. + @retval EFI_INVALID_PARAMETER The KeyGuidBufferLength is NULL. + @retval EFI_INVALID_PARAMETER The value referenced by KeyGuidBufferLength is not + zero and KeyGuidBuffer is NULL. @retval EFI_NOT_FOUND There was no keyboard layout. **/