X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FHiiDatabaseDxe%2FString.c;h=9b6a5a3556dc24405c8b13bcea4ddc786aaa5274;hb=255a3f33bd8474f8835857a13ed7564cdbe5a39b;hp=d4fcc971e55ea441c6567ccba8543a132d1a60b8;hpb=676df92c2c0c5bdeb0f8e27349f5dd467928ce09;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/String.c b/MdeModulePkg/Universal/HiiDatabaseDxe/String.c index d4fcc971e5..9b6a5a3556 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/String.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/String.c @@ -2,8 +2,8 @@ Implementation for EFI_HII_STRING_PROTOCOL. -Copyright (c) 2007, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2007 - 2010, 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 @@ -124,7 +124,7 @@ ConvertToUnicodeText ( ASSERT (StringSrc != NULL && BufferSize != NULL); StringSize = AsciiStrSize (StringSrc) * 2; - if (*BufferSize < StringSize) { + if (*BufferSize < StringSize || StringDest == NULL) { *BufferSize = StringSize; return EFI_BUFFER_TOO_SMALL; } @@ -235,25 +235,26 @@ GetStringFontInfo ( /** 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 StringId = 0, output the string id of last string block (EFI_HII_SIBT_END). - - @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. - - @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. + 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. + + @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 @@ -295,8 +296,15 @@ FindStringBlock ( 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)); @@ -547,13 +555,12 @@ FindStringBlock ( BlockHdr = StringPackage->StringBlock + BlockSize; } - + + // + // Get last string ID + // if (StringId == (EFI_STRING_ID) (-1)) { - return EFI_SUCCESS; - } - - if (StringId == 0 && LastStringId != NULL) { - *LastStringId = CurrentStringId; + *LastStringId = (EFI_STRING_ID) (CurrentStringId - 1); return EFI_SUCCESS; } @@ -592,7 +599,7 @@ GetStringWorker ( IN HII_STRING_PACKAGE_INSTANCE *StringPackage, IN EFI_STRING_ID StringId, OUT EFI_STRING String, - IN OUT UINTN *StringSize, + IN OUT UINTN *StringSize, OPTIONAL OUT EFI_FONT_INFO **StringFontInfo OPTIONAL ) { @@ -603,7 +610,7 @@ GetStringWorker ( EFI_STATUS Status; UINT8 FontId; - ASSERT (StringPackage != NULL && StringSize != NULL); + ASSERT (StringPackage != NULL); ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE); // @@ -622,6 +629,13 @@ GetStringWorker ( return Status; } + if (StringSize == NULL) { + // + // String text buffer is not requested + // + return EFI_SUCCESS; + } + // // Get the string text. // @@ -909,7 +923,10 @@ SetStringWorker ( /** 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. + 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 @@ -952,7 +969,6 @@ HiiNewString ( { EFI_STATUS Status; LIST_ENTRY *Link; - BOOLEAN Matched; HII_DATABASE_PRIVATE_DATA *Private; HII_DATABASE_RECORD *DatabaseRecord; HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode; @@ -968,6 +984,12 @@ HiiNewString ( 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; @@ -1004,37 +1026,113 @@ HiiNewString ( return EFI_NOT_FOUND; } - // - // Try to get the matching string package. Create a new string package when failed. - // + Status = EFI_SUCCESS; + NewStringPackageCreated = FALSE; + NewStringId = 0; + NextStringId = 0; StringPackage = NULL; - Matched = FALSE; + 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); - if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) { - Matched = TRUE; - break; + // + // 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 + ); + 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; + 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 (!Matched) { + if (MatchStringPackage != NULL) { + StringPackage = MatchStringPackage; + } else { // // LanguageName is required to create a new string package. // if (LanguageName == NULL) { - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE)); if (StringPackage == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } - StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE; - StringPackage->FontId = 0; + StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE; + StringPackage->MaxStringId = *StringId; + StringPackage->FontId = 0; InitializeListHead (&StringPackage->FontInfoList); // @@ -1044,12 +1142,13 @@ HiiNewString ( StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize); if (StringPackage->StringPkgHdr == NULL) { FreePool (StringPackage); - return EFI_OUT_OF_RESOURCES; + 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));; + CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16)); StringPackage->StringPkgHdr->LanguageName = 1; AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language); @@ -1057,15 +1156,16 @@ HiiNewString ( // 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) + - sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16)); + 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); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // @@ -1076,7 +1176,10 @@ HiiNewString ( 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 // @@ -1088,24 +1191,7 @@ HiiNewString ( StringPackage->StringPkgHdr->Header.Length = HeaderSize + BlockSize; PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length; InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry); - - } - - // - // 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, - StringId - ); - if (EFI_ERROR (Status)) { - return Status; + NewStringPackageCreated = TRUE; } OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize; @@ -1114,13 +1200,13 @@ HiiNewString ( // // 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) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Copy original string blocks, except the EFI_HII_SIBT_END. @@ -1159,7 +1245,8 @@ HiiNewString ( // StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize); if (StringBlock == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Copy original string blocks, except the EFI_HII_SIBT_END. @@ -1195,7 +1282,8 @@ HiiNewString ( sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16)); StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize); if (StringBlock == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Copy original string blocks, except the EFI_HII_SIBT_END. @@ -1225,7 +1313,7 @@ HiiNewString ( &((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 // @@ -1253,7 +1341,42 @@ HiiNewString ( } } - return EFI_SUCCESS; +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); + } + + return Status; } @@ -1340,7 +1463,7 @@ HiiGetString ( Link = Link->ForwardLink ) { StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); - if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) { + if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) { Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo); if (Status != EFI_NOT_FOUND) { return Status; @@ -1355,7 +1478,7 @@ HiiGetString ( Link = Link->ForwardLink ) { StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); - Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo); + Status = GetStringWorker (Private, StringPackage, StringId, NULL, NULL, NULL); if (!EFI_ERROR (Status)) { return EFI_INVALID_LANGUAGE; } @@ -1433,7 +1556,7 @@ HiiSetString ( Link = Link->ForwardLink ) { StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); - if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) { + if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) { OldPackageLen = StringPackage->StringPkgHdr->Header.Length; Status = SetStringWorker ( Private, @@ -1523,7 +1646,7 @@ HiiGetLanguages ( ) { StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); ResultSize += AsciiStrSize (StringPackage->StringPkgHdr->Language); - if (ResultSize < *LanguagesSize) { + if (ResultSize <= *LanguagesSize) { AsciiStrCpy (Languages, StringPackage->StringPkgHdr->Language); Languages += AsciiStrSize (StringPackage->StringPkgHdr->Language); *(Languages - 1) = L';'; @@ -1622,7 +1745,7 @@ HiiGetSecondaryLanguages ( Link1 = Link1->ForwardLink ) { StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); - if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) FirstLanguage)) { + if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) FirstLanguage)) { Languages = StringPackage->StringPkgHdr->Language; // // Language is a series of ';' terminated strings, first one is primary @@ -1650,3 +1773,41 @@ HiiGetSecondaryLanguages ( return EFI_INVALID_LANGUAGE; } +/** + Compare whether two names of languages are identical. + + @param Language1 Name of language 1 + @param Language2 Name of language 2 + + @retval TRUE same + @retval FALSE not same + +**/ +BOOLEAN +HiiCompareLanguage ( + IN CHAR8 *Language1, + IN CHAR8 *Language2 + ) +{ + // + // Porting Guide: + // This library interface is simply obsolete. + // Include the source code to user code. + // + UINTN Index; + + for (Index = 0; (Language1[Index] != 0) && (Language2[Index] != 0); Index++) { + if (Language1[Index] != Language2[Index]) { + return FALSE; + } + } + + if (((Language1[Index] == 0) && (Language2[Index] == 0)) || + ((Language1[Index] == 0) && (Language2[Index] != ';')) || + ((Language1[Index] == ';') && (Language2[Index] != 0)) || + ((Language1[Index] == ';') && (Language2[Index] != ';'))) { + return TRUE; + } + + return FALSE; +}