Implementation for EFI_HII_STRING_PROTOCOL.\r
\r
\r
-Copyright (c) 2007 - 2011, 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
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
@param StringSrc Points to current null-terminated string.\r
@param BufferSize Length of the buffer.\r
\r
- @retval EFI_SUCCESS The string text was outputed successfully.\r
+ @retval EFI_SUCCESS The string text was outputted successfully.\r
@retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string\r
text. BufferSize is updated to the required buffer\r
size.\r
@param StringSrc Points to current null-terminated string.\r
@param BufferSize Length of the buffer.\r
\r
- @retval EFI_SUCCESS The string text was outputed successfully.\r
+ @retval EFI_SUCCESS The string text was outputted successfully.\r
@retval EFI_BUFFER_TOO_SMALL Buffer is insufficient to store the found string\r
text. BufferSize is updated to the required buffer\r
size.\r
@param StringFontInfo Buffer to record the output font info. It's\r
caller's responsibility to free this buffer.\r
\r
- @retval EFI_SUCCESS The string font is outputed successfully.\r
+ @retval EFI_SUCCESS The string font is outputted successfully.\r
@retval EFI_NOT_FOUND The specified font id does not exist.\r
\r
**/\r
/**\r
Parse all string blocks to find a String block specified by StringId.\r
If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks\r
- within this string package and backup its information. If LastStringId is \r
+ within this string package and backup its information. If LastStringId is\r
specified, the string id of last string block will also be output.\r
If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING).\r
\r
ASSERT (StringPackage->Signature == HII_STRING_PACKAGE_SIGNATURE);\r
\r
CurrentStringId = 1;\r
+ StringSize = 0;\r
\r
if (StringId != (EFI_STRING_ID) (-1) && StringId != 0) {\r
ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
\r
case EFI_HII_SIBT_STRINGS_SCSU:\r
CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));\r
- StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);\r
+ StringTextPtr = (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));\r
BlockSize += StringTextPtr - BlockHdr;\r
\r
for (Index = 0; Index < StringCount; Index++) {\r
BlockSize += AsciiStrSize ((CHAR8 *) StringTextPtr);\r
if (CurrentStringId == StringId) {\r
+ ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
*BlockType = *BlockHdr;\r
*StringBlockAddr = BlockHdr;\r
*StringTextOffset = StringTextPtr - BlockHdr;\r
case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
CopyMem (\r
&StringCount,\r
- BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
sizeof (UINT16)\r
);\r
- StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);\r
+ StringTextPtr = (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));\r
BlockSize += StringTextPtr - BlockHdr;\r
\r
for (Index = 0; Index < StringCount; Index++) {\r
BlockSize += AsciiStrSize ((CHAR8 *) StringTextPtr);\r
if (CurrentStringId == StringId) {\r
+ ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
*BlockType = *BlockHdr;\r
*StringBlockAddr = BlockHdr;\r
*StringTextOffset = StringTextPtr - BlockHdr;\r
GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
BlockSize += StringSize;\r
if (CurrentStringId == StringId) {\r
+ ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
*BlockType = *BlockHdr;\r
*StringBlockAddr = BlockHdr;\r
*StringTextOffset = StringTextPtr - BlockHdr;\r
BlockSize += Offset;\r
CopyMem (\r
&StringCount,\r
- BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
sizeof (UINT16)\r
);\r
for (Index = 0; Index < StringCount; Index++) {\r
GetUnicodeStringTextOrSize (NULL, StringTextPtr, &StringSize);\r
BlockSize += StringSize;\r
if (CurrentStringId == StringId) {\r
+ ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
*BlockType = *BlockHdr;\r
*StringBlockAddr = BlockHdr;\r
*StringTextOffset = StringTextPtr - BlockHdr;\r
break;\r
\r
case EFI_HII_SIBT_SKIP1:\r
- SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
+ SkipCount = (UINT16) (*(UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));\r
CurrentStringId = (UINT16) (CurrentStringId + SkipCount);\r
BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);\r
break;\r
case EFI_HII_SIBT_EXT1:\r
CopyMem (\r
&Length8,\r
- BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
sizeof (UINT8)\r
);\r
BlockSize += Length8;\r
//\r
BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
CopyMem (&FontId, BlockHdr, sizeof (UINT8));\r
- BlockHdr += sizeof (UINT8);\r
+ BlockHdr ++;\r
CopyMem (&FontSize, BlockHdr, sizeof (UINT16));\r
BlockHdr += sizeof (UINT16);\r
CopyMem (&FontStyle, BlockHdr, sizeof (EFI_HII_FONT_STYLE));\r
// Since string package tool set FontId initially to 0 and increases it\r
// progressively by one, StringPackage->FondId always represents an unique\r
// and available FontId.\r
- // \r
+ //\r
StringPackage->FontId++;\r
\r
FreePool (FontInfo);\r
case EFI_HII_SIBT_EXT4:\r
CopyMem (\r
&Length32,\r
- BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),\r
+ (UINT8*)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),\r
sizeof (UINT32)\r
);\r
\r
*StartStringId = CurrentStringId;\r
}\r
}\r
- \r
+\r
//\r
// Get last string ID\r
//\r
- if (StringId == (EFI_STRING_ID) (-1)) {\r
+ if (StringId == (EFI_STRING_ID) (-1) && LastStringId != NULL) {\r
*LastStringId = (EFI_STRING_ID) (CurrentStringId - 1);\r
return EFI_SUCCESS;\r
}\r
}\r
\r
//\r
- // Get the string font. The FontId 0 is the default font for those string blocks which \r
+ // Get the string font. The FontId 0 is the default font for those string blocks which\r
// do not specify a font identifier. If default font is not specified, return NULL.\r
//\r
if (StringFontInfo != NULL) {\r
\r
/**\r
If GetStringBlock find the StringId's string is not saved in the exist string block,\r
- this function will create the UCS2 string block to save the string; also split the \r
+ this function will create the UCS2 string block to save the string; also split the\r
skip block into two or one skip block.\r
\r
This is a internal function.\r
- \r
+\r
@param StringPackage Hii string package instance.\r
@param StartStringId The first id in the skip block which StringId in the block.\r
@param StringId The string's id, which is unique within\r
- PackageList. \r
- @param BlockType Output the block type of found string block. \r
- @param StringBlockAddr Output the block address of found string block. \r
+ PackageList.\r
+ @param BlockType Output the block type of found string block.\r
+ @param StringBlockAddr Output the block address of found string block.\r
@param FontBlock whether this string block has font info.\r
\r
- @retval EFI_SUCCESS The string font is outputed successfully.\r
+ @retval EFI_SUCCESS The string font is outputted successfully.\r
@retval EFI_OUT_OF_RESOURCES NO resource for the memory to save the new string block.\r
\r
**/\r
{\r
UINT8 *BlockPtr;\r
UINT8 *StringBlock;\r
- UINT32 SkipLen; \r
+ UINT32 SkipLen;\r
UINT32 OldBlockSize;\r
UINT32 NewBlockSize;\r
UINT32 FrontSkipNum;\r
FrontSkipNum = 0;\r
SkipLen = 0;\r
OldStringAddr = *StringBlockAddr;\r
- \r
+\r
ASSERT (*BlockType == EFI_HII_SIBT_SKIP1 || *BlockType == EFI_HII_SIBT_SKIP2);\r
//\r
// Old skip block size.\r
} else {\r
SkipLen = sizeof (EFI_HII_SIBT_SKIP2_BLOCK);\r
IdCount = *(UINT16*)(OldStringAddr + sizeof (EFI_HII_STRING_BLOCK));\r
- } \r
+ }\r
\r
//\r
// New create UCS or UCS2 block size.\r
//\r
// Copy old block in front of skip block.\r
//\r
- CopyMem (StringBlock, StringPackage->StringBlock, OldStringAddr - StringPackage->StringBlock); \r
+ CopyMem (StringBlock, StringPackage->StringBlock, OldStringAddr - StringPackage->StringBlock);\r
BlockPtr = StringBlock + (OldStringAddr - StringPackage->StringBlock);\r
\r
if (FrontSkipNum > 0) {\r
//\r
// Append a EFI_HII_SIBT_END block to the end.\r
//\r
- CopyMem (BlockPtr, OldStringAddr + SkipLen, OldBlockSize - (OldStringAddr - StringPackage->StringBlock) - SkipLen); \r
+ CopyMem (BlockPtr, OldStringAddr + SkipLen, OldBlockSize - (OldStringAddr - StringPackage->StringBlock) - SkipLen);\r
\r
if (FontBlock) {\r
*BlockType = EFI_HII_SIBT_STRING_UCS2_FONT;\r
EFI_STRING_ID StartStringId;\r
\r
StartStringId = 0;\r
+ StringSize = 0;\r
ASSERT (Private != NULL && StringPackage != NULL && String != NULL);\r
ASSERT (Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
//\r
&StartStringId\r
);\r
if (EFI_ERROR (Status) && (BlockType == EFI_HII_SIBT_SKIP1 || BlockType == EFI_HII_SIBT_SKIP2)) {\r
- Status = InsertLackStringBlock(StringPackage, \r
- StartStringId, \r
- StringId, \r
+ Status = InsertLackStringBlock(StringPackage,\r
+ StartStringId,\r
+ StringId,\r
&BlockType,\r
&StringBlockAddr,\r
(BOOLEAN)(StringFontInfo != NULL)\r
return EFI_INVALID_PARAMETER;\r
} else {\r
Referred = ReferFontInfoLocally (\r
- Private, \r
- StringPackage, \r
- StringPackage->FontId, \r
- FALSE, \r
- GlobalFont, \r
+ Private,\r
+ StringPackage,\r
+ StringPackage->FontId,\r
+ FALSE,\r
+ GlobalFont,\r
&LocalFont\r
);\r
if (!Referred) {\r
// Update the FontId of the specified string block to input font info.\r
//\r
switch (BlockType) {\r
- case EFI_HII_SIBT_STRING_SCSU_FONT: \r
+ case EFI_HII_SIBT_STRING_SCSU_FONT:\r
case EFI_HII_SIBT_STRINGS_SCSU_FONT:\r
case EFI_HII_SIBT_STRING_UCS2_FONT:\r
case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
// When modify the font info of these blocks, the block type should be updated\r
// to contain font info thus the whole structure should be revised.\r
// It is recommended to use tool to modify the block type not in the code.\r
- // \r
+ //\r
return EFI_UNSUPPORTED;\r
}\r
}\r
}\r
*BlockPtr++ = 0;\r
\r
- \r
+\r
TmpSize = OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - AsciiStrSize ((CHAR8 *) StringTextPtr);\r
CopyMem (\r
BlockPtr,\r
BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
\r
*BlockPtr = LocalFont->FontId;\r
- BlockPtr += sizeof (UINT8);\r
+ BlockPtr ++;\r
CopyMem (BlockPtr, &GlobalFont->FontInfo->FontSize, sizeof (UINT16));\r
BlockPtr += sizeof (UINT16);\r
CopyMem (BlockPtr, &GlobalFont->FontInfo->FontStyle, sizeof (UINT32));\r
\r
/**\r
This function adds the string String to the group of strings owned by PackageList, with the\r
- specified font information StringFontInfo and returns a new string id. \r
- The new string identifier is guaranteed to be unique within the package list. \r
- That new string identifier is reserved for all languages in the package list. \r
+ specified font information StringFontInfo and returns a new string id.\r
+ The new string identifier is guaranteed to be unique within the package list.\r
+ That new string identifier is reserved for all languages in the package list.\r
\r
\r
@param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
return EFI_NOT_FOUND;\r
}\r
\r
+ EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
Status = EFI_SUCCESS;\r
NewStringPackageCreated = FALSE;\r
NewStringId = 0;\r
StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;\r
CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));\r
StringPackage->StringPkgHdr->LanguageName = 1;\r
- AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language);\r
+ AsciiStrCpyS (StringPackage->StringPkgHdr->Language, (HeaderSize - OFFSET_OF(EFI_HII_STRING_PACKAGE_HDR,Language)) / sizeof (CHAR8), (CHAR8 *) Language);\r
\r
//\r
// Calculate the length of the string blocks, including string block to record\r
// printable language full name and EFI_HII_SIBT_END_BLOCK.\r
//\r
- Ucs2BlockSize = (UINT32) (StrSize ((CHAR16 *) LanguageName) + \r
+ Ucs2BlockSize = (UINT32) (StrSize ((CHAR16 *) LanguageName) +\r
(*StringId - 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16));\r
\r
BlockSize = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK);\r
*BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;\r
BlockPtr += sizeof (EFI_HII_STRING_BLOCK);\r
*BlockPtr = LocalFont->FontId;\r
- BlockPtr += sizeof (UINT8);\r
+ BlockPtr ++;\r
CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));\r
BlockPtr += StrSize ((EFI_STRING) String);\r
\r
BlockPtr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
\r
*BlockPtr = LocalFont->FontId;\r
- BlockPtr += sizeof (UINT8);\r
+ BlockPtr ++;\r
CopyMem (BlockPtr, &((EFI_FONT_INFO *) StringFontInfo)->FontSize, sizeof (UINT16));\r
BlockPtr += sizeof (UINT16);\r
CopyMem (BlockPtr, &((EFI_FONT_INFO *) StringFontInfo)->FontStyle, sizeof (EFI_HII_FONT_STYLE));\r
*BlockPtr = EFI_HII_SIBT_STRING_UCS2_FONT;\r
BlockPtr += sizeof (EFI_HII_STRING_BLOCK);\r
*BlockPtr = LocalFont->FontId;\r
- BlockPtr += sizeof (UINT8);\r
+ BlockPtr ++;\r
CopyMem (BlockPtr, (EFI_STRING) String, StrSize ((EFI_STRING) String));\r
BlockPtr += StrSize ((EFI_STRING) String);\r
\r
PackageListNode->PackageListHdr.PackageLength += FontBlockSize + Ucs2FontBlockSize;\r
\r
//\r
- // Increase the FontId to make it unique since we already add \r
+ // Increase the FontId to make it unique since we already add\r
// a EFI_HII_SIBT_FONT block to this string package.\r
//\r
StringPackage->FontId++;\r
FreePool (StringPackage->StringPkgHdr);\r
FreePool (StringPackage);\r
}\r
+ //\r
+ // The contents of HiiDataBase may updated,need to check.\r
+ //\r
+ //\r
+ // Check whether need to get the contents of HiiDataBase.\r
+ // Only after ReadyToBoot to do the export.\r
+ //\r
+ if (gExportAfterReadyToBoot) {\r
+ if (!EFI_ERROR (Status)) {\r
+ HiiGetDatabaseInfo(&Private->HiiDatabase);\r
+ }\r
+ }\r
+\r
+ EfiReleaseLock (&mHiiDatabaseLock);\r
\r
return Status;\r
}\r
@retval EFI_INVALID_LANGUAGE - The string specified by StringId is available but\r
@retval EFI_BUFFER_TOO_SMALL The buffer specified by StringSize is too small to\r
hold the string.\r
- @retval EFI_INVALID_PARAMETER The String or Language or StringSize was NULL.\r
+ @retval EFI_INVALID_PARAMETER The Language or StringSize was NULL.\r
+ @retval EFI_INVALID_PARAMETER The value referenced by StringSize was not zero and String was NULL.\r
@retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the\r
request.\r
\r
//\r
// Second search: to match the StringId in other available languages if exist.\r
//\r
- for (Link = PackageListNode->StringPkgHdr.ForwardLink; \r
+ for (Link = PackageListNode->StringPkgHdr.ForwardLink;\r
Link != &PackageListNode->StringPkgHdr;\r
Link = Link->ForwardLink\r
) {\r
- StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); \r
+ StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
Status = GetStringWorker (Private, StringPackage, StringId, NULL, NULL, NULL);\r
if (!EFI_ERROR (Status)) {\r
return EFI_INVALID_LANGUAGE;\r
}\r
- } \r
+ }\r
}\r
\r
return EFI_NOT_FOUND;\r
return EFI_NOT_FOUND;\r
}\r
\r
+ EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
PackageListNode = NULL;\r
\r
(EFI_FONT_INFO *) StringFontInfo\r
);\r
if (EFI_ERROR (Status)) {\r
+ EfiReleaseLock (&mHiiDatabaseLock);\r
return Status;\r
}\r
PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length - OldPackageLen;\r
+ //\r
+ // Check whether need to get the contents of HiiDataBase.\r
+ // Only after ReadyToBoot to do the export.\r
+ //\r
+ if (gExportAfterReadyToBoot) {\r
+ HiiGetDatabaseInfo(&Private->HiiDatabase);\r
+ }\r
+ EfiReleaseLock (&mHiiDatabaseLock);\r
return EFI_SUCCESS;\r
}\r
}\r
}\r
\r
+ EfiReleaseLock (&mHiiDatabaseLock);\r
return EFI_NOT_FOUND;\r
}\r
\r
\r
@param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
@param PackageList The package list to examine.\r
- @param Languages Points to the buffer to hold the returned string.\r
+ @param Languages Points to the buffer to hold the returned\r
+ null-terminated ASCII string.\r
@param LanguagesSize On entry, points to the size of the buffer pointed\r
to by Languages, in bytes. On return, points to\r
the length of Languages, in bytes.\r
\r
@retval EFI_SUCCESS The languages were returned successfully.\r
- @retval EFI_INVALID_PARAMETER The Languages or LanguagesSize was NULL.\r
+ @retval EFI_INVALID_PARAMETER The LanguagesSize was NULL.\r
+ @retval EFI_INVALID_PARAMETER The value referenced by LanguagesSize is not zero and Languages is NULL.\r
@retval EFI_BUFFER_TOO_SMALL The LanguagesSize is too small to hold the list of\r
supported languages. LanguageSize is updated to\r
contain the required size.\r
HII_STRING_PACKAGE_INSTANCE *StringPackage;\r
UINTN ResultSize;\r
\r
- if (This == NULL || Languages == NULL || LanguagesSize == NULL || PackageList == NULL) {\r
+ if (This == NULL || LanguagesSize == NULL || PackageList == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (*LanguagesSize != 0 && Languages == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
if (!IsHiiHandleValid (PackageList)) {\r
StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
ResultSize += AsciiStrSize (StringPackage->StringPkgHdr->Language);\r
if (ResultSize <= *LanguagesSize) {\r
- AsciiStrCpy (Languages, StringPackage->StringPkgHdr->Language);\r
+ AsciiStrCpyS (Languages, *LanguagesSize / sizeof (CHAR8), StringPackage->StringPkgHdr->Language);\r
Languages += AsciiStrSize (StringPackage->StringPkgHdr->Language);\r
*(Languages - 1) = L';';\r
}\r
\r
@param This A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
@param PackageList The package list to examine.\r
- @param FirstLanguage Points to the primary language.\r
- @param SecondaryLanguages Points to the buffer to hold the returned list of\r
+ @param PrimaryLanguage Points to the null-terminated ASCII string that specifies\r
+ the primary language. Languages are specified in the\r
+ format specified in Appendix M of the UEFI 2.0 specification.\r
+ @param SecondaryLanguages Points to the buffer to hold the returned null-terminated\r
+ ASCII string that describes the list of\r
secondary languages for the specified\r
- FirstLanguage. If there are no secondary\r
- languages, the function returns successfully, but\r
+ PrimaryLanguage. If there are no secondary\r
+ languages, the function returns successfully, but\r
this is set to NULL.\r
@param SecondaryLanguagesSize On entry, points to the size of the buffer pointed\r
- to by SecondaryLanguages, in bytes. On return,\r
+ to by SecondaryLanguages, in bytes. On return,\r
points to the length of SecondaryLanguages in bytes.\r
\r
@retval EFI_SUCCESS Secondary languages were correctly returned.\r
- @retval EFI_INVALID_PARAMETER FirstLanguage or SecondaryLanguages or\r
- SecondaryLanguagesSize was NULL.\r
+ @retval EFI_INVALID_PARAMETER PrimaryLanguage or SecondaryLanguagesSize was NULL.\r
+ @retval EFI_INVALID_PARAMETER The value referenced by SecondaryLanguagesSize is not\r
+ zero and SecondaryLanguages is NULL.\r
@retval EFI_BUFFER_TOO_SMALL The buffer specified by SecondaryLanguagesSize is\r
too small to hold the returned information.\r
- SecondLanguageSize is updated to hold the size of\r
+ SecondaryLanguageSize is updated to hold the size of\r
the buffer required.\r
- @retval EFI_INVALID_LANGUAGE The language specified by FirstLanguage is not\r
- present in the specified package list.\r
- @retval EFI_NOT_FOUND The specified PackageList is not in the Database. \r
+ @retval EFI_INVALID_LANGUAGE The language specified by PrimaryLanguage is not\r
+ present in the specified package list.\r
+ @retval EFI_NOT_FOUND The specified PackageList is not in the Database.\r
\r
**/\r
EFI_STATUS\r
HiiGetSecondaryLanguages (\r
IN CONST EFI_HII_STRING_PROTOCOL *This,\r
IN EFI_HII_HANDLE PackageList,\r
- IN CONST CHAR8 *FirstLanguage,\r
+ IN CONST CHAR8 *PrimaryLanguage,\r
IN OUT CHAR8 *SecondaryLanguages,\r
IN OUT UINTN *SecondaryLanguagesSize\r
)\r
CHAR8 *Languages;\r
UINTN ResultSize;\r
\r
- if (This == NULL || PackageList == NULL || FirstLanguage == NULL) {\r
+ if (This == NULL || PackageList == NULL || PrimaryLanguage == NULL || SecondaryLanguagesSize == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- if (SecondaryLanguages == NULL || SecondaryLanguagesSize == NULL) {\r
+ if (SecondaryLanguages == NULL && *SecondaryLanguagesSize != 0) {\r
return EFI_INVALID_PARAMETER;\r
}\r
if (!IsHiiHandleValid (PackageList)) {\r
\r
Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
\r
- PackageListNode = NULL; \r
+ PackageListNode = NULL;\r
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
DatabaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
if (DatabaseRecord->Handle == PackageList) {\r
if (PackageListNode == NULL) {\r
return EFI_NOT_FOUND;\r
}\r
- \r
+\r
Languages = NULL;\r
ResultSize = 0;\r
for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;\r
Link1 = Link1->ForwardLink\r
) {\r
StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
- if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) FirstLanguage)) {\r
+ if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) PrimaryLanguage)) {\r
Languages = StringPackage->StringPkgHdr->Language;\r
//\r
// Language is a series of ';' terminated strings, first one is primary\r
\r
ResultSize = AsciiStrSize (Languages);\r
if (ResultSize <= *SecondaryLanguagesSize) {\r
- AsciiStrCpy (SecondaryLanguages, Languages);\r
+ AsciiStrCpyS (SecondaryLanguages, *SecondaryLanguagesSize / sizeof (CHAR8), Languages);\r
} else {\r
*SecondaryLanguagesSize = ResultSize;\r
return EFI_BUFFER_TOO_SMALL;\r
return EFI_INVALID_LANGUAGE;\r
}\r
\r
+/**\r
+ Converts the ascii character of the string from uppercase to lowercase.\r
+ This is a internal function.\r
+\r
+ @param ConfigString String to be converted\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsciiHiiToLower (\r
+ IN CHAR8 *ConfigString\r
+ )\r
+{\r
+ ASSERT (ConfigString != NULL);\r
+\r
+ //\r
+ // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
+ //\r
+ for (; *ConfigString != '\0'; ConfigString++) {\r
+ if ( *ConfigString >= 'A' && *ConfigString <= 'Z') {\r
+ *ConfigString = (CHAR8) (*ConfigString - 'A' + 'a');\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Compare whether two names of languages are identical.\r
\r
IN CHAR8 *Language2\r
)\r
{\r
- UINTN Language2Len;\r
+ UINTN Index;\r
+ UINTN StrLen;\r
+ CHAR8 *Lan1;\r
+ CHAR8 *Lan2;\r
\r
//\r
- // When languages are exactly same, they will be identical. \r
+ // Convert to lower to compare.\r
//\r
- Language2Len = AsciiStrLen (Language2);\r
- if (AsciiStrnCmp (Language2, Language1, Language2Len) == 0) {\r
- return TRUE;\r
- }\r
- \r
+ StrLen = AsciiStrSize (Language1);\r
+ Lan1 = AllocateZeroPool (StrLen);\r
+ ASSERT (Lan1 != NULL);\r
+ AsciiStrCpyS(Lan1, StrLen / sizeof (CHAR8), Language1);\r
+ AsciiHiiToLower (Lan1);\r
+\r
+ StrLen = AsciiStrSize (Language2);\r
+ Lan2 = AllocateZeroPool (StrLen);\r
+ ASSERT (Lan2 != NULL);\r
+ AsciiStrCpyS(Lan2, StrLen / sizeof (CHAR8), Language2);\r
+ AsciiHiiToLower (Lan2);\r
+\r
//\r
- // When Language1 is the sub tag of Language2, they will also be regarded as identical.\r
- // This is added to support current Shell. Shell string package uses "en" as language name. \r
- // But, it may use platform language "en-US" to get string value.\r
+ // Compare the Primary Language in Language1 to Language2\r
//\r
- if (AsciiStrStr (Language2, Language1) == Language2) {\r
- return TRUE;\r
+ for (Index = 0; Lan1[Index] != 0 && Lan1[Index] != ';'; Index++) {\r
+ if (Lan1[Index] != Lan2[Index]) {\r
+ //\r
+ // Return FALSE if any characters are different.\r
+ //\r
+ FreePool (Lan1);\r
+ FreePool (Lan2);\r
+ return FALSE;\r
+ }\r
}\r
- \r
- return FALSE;\r
+\r
+ FreePool (Lan1);\r
+ FreePool (Lan2);\r
+\r
+ //\r
+ // Only return TRUE if Language2[Index] is a Null-terminator which means\r
+ // the Primary Language in Language1 is the same length as Language2. If\r
+ // Language2[Index] is not a Null-terminator, then Language2 is longer than\r
+ // the Primary Language in Language1, and FALSE must be returned.\r
+ //\r
+ return (BOOLEAN) (Language2[Index] == 0);\r
}\r