]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/String.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / String.c
index eeac9c20879cef1e4530a38b6f6526cb3145fb6c..505e063d49c39dbda15a86ca578b7fd9b16be48d 100644 (file)
@@ -2,14 +2,9 @@
 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
@@ -105,7 +100,7 @@ ReferFontInfoLocally (
   @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
@@ -149,7 +144,7 @@ ConvertToUnicodeText (
   @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
@@ -198,7 +193,7 @@ GetUnicodeStringTextOrSize (
   @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
@@ -235,7 +230,7 @@ GetStringFontInfo (
 /**\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
@@ -295,6 +290,7 @@ FindStringBlock (
   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
@@ -335,12 +331,13 @@ FindStringBlock (
 \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
@@ -354,15 +351,16 @@ FindStringBlock (
     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
@@ -406,6 +404,7 @@ FindStringBlock (
         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
@@ -422,13 +421,14 @@ FindStringBlock (
       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
@@ -461,7 +461,7 @@ FindStringBlock (
       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
@@ -475,7 +475,7 @@ FindStringBlock (
     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
@@ -490,7 +490,7 @@ FindStringBlock (
         //\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
@@ -518,7 +518,7 @@ FindStringBlock (
         // 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
@@ -531,7 +531,7 @@ FindStringBlock (
     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
@@ -568,11 +568,11 @@ FindStringBlock (
         *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
@@ -675,7 +675,7 @@ GetStringWorker (
   }\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
@@ -700,20 +700,20 @@ GetStringWorker (
 \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
@@ -729,7 +729,7 @@ InsertLackStringBlock (
 {\r
   UINT8                                *BlockPtr;\r
   UINT8                                *StringBlock;\r
-  UINT32                               SkipLen;    \r
+  UINT32                               SkipLen;\r
   UINT32                               OldBlockSize;\r
   UINT32                               NewBlockSize;\r
   UINT32                               FrontSkipNum;\r
@@ -740,7 +740,7 @@ InsertLackStringBlock (
   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
@@ -751,7 +751,7 @@ InsertLackStringBlock (
   } 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
@@ -795,7 +795,7 @@ InsertLackStringBlock (
   //\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
@@ -832,7 +832,7 @@ InsertLackStringBlock (
   //\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
@@ -895,6 +895,7 @@ SetStringWorker (
   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
@@ -911,9 +912,9 @@ SetStringWorker (
              &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
@@ -940,11 +941,11 @@ SetStringWorker (
       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
@@ -955,7 +956,7 @@ SetStringWorker (
     // 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
@@ -966,7 +967,7 @@ SetStringWorker (
       // 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
@@ -997,7 +998,7 @@ SetStringWorker (
     }\r
     *BlockPtr++ = 0;\r
 \r
-    \r
+\r
     TmpSize = OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - AsciiStrSize ((CHAR8 *) StringTextPtr);\r
     CopyMem (\r
       BlockPtr,\r
@@ -1075,7 +1076,7 @@ SetStringWorker (
   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
@@ -1100,9 +1101,9 @@ SetStringWorker (
 \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
@@ -1203,6 +1204,8 @@ HiiNewString (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Status = EFI_SUCCESS;\r
   NewStringPackageCreated = FALSE;\r
   NewStringId   = 0;\r
@@ -1328,13 +1331,13 @@ HiiNewString (
     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
@@ -1437,7 +1440,7 @@ HiiNewString (
       *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
@@ -1481,7 +1484,7 @@ HiiNewString (
       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
@@ -1498,7 +1501,7 @@ HiiNewString (
       *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
@@ -1512,7 +1515,7 @@ HiiNewString (
       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
@@ -1553,6 +1556,20 @@ Done:
     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
@@ -1585,7 +1602,8 @@ Done:
   @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
@@ -1651,16 +1669,16 @@ HiiGetString (
       //\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
@@ -1718,6 +1736,8 @@ HiiSetString (
     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
@@ -1744,14 +1764,24 @@ HiiSetString (
                    (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
@@ -1763,13 +1793,15 @@ HiiSetString (
 \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
@@ -1793,7 +1825,10 @@ HiiGetLanguages (
   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
@@ -1825,7 +1860,7 @@ HiiGetLanguages (
     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
@@ -1851,26 +1886,30 @@ HiiGetLanguages (
 \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
@@ -1878,7 +1917,7 @@ EFIAPI
 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
@@ -1892,10 +1931,10 @@ HiiGetSecondaryLanguages (
   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
@@ -1904,7 +1943,7 @@ HiiGetSecondaryLanguages (
 \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
@@ -1915,7 +1954,7 @@ HiiGetSecondaryLanguages (
     if (PackageListNode == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
-      \r
+\r
     Languages  = NULL;\r
     ResultSize = 0;\r
     for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;\r
@@ -1923,7 +1962,7 @@ HiiGetSecondaryLanguages (
          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
@@ -1938,7 +1977,7 @@ HiiGetSecondaryLanguages (
 \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
@@ -1951,6 +1990,31 @@ HiiGetSecondaryLanguages (
   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
@@ -1967,11 +2031,48 @@ HiiCompareLanguage (
   IN  CHAR8  *Language2\r
   )\r
 {\r
-  UINTN Language2Len;\r
+  UINTN  Index;\r
+  UINTN  StrLen;\r
+  CHAR8  *Lan1;\r
+  CHAR8  *Lan2;\r
+\r
+  //\r
+  // Convert to lower to compare.\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
+  // Compare the Primary Language in Language1 to Language2\r
+  //\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
+  FreePool (Lan1);\r
+  FreePool (Lan2);\r
 \r
   //\r
-  // When languages are exactly same, they will be identical. \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
-  Language2Len = AsciiStrLen (Language2);\r
-  return  (BOOLEAN) (AsciiStrnCmp (Language1, Language2, Language2Len) == 0);\r
+  return (BOOLEAN) (Language2[Index] == 0);\r
 }\r