]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/String.c
Fix AutoUpdateLangVariable() logic to handle the case PlatformLang/Lang is set before...
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / String.c
index d4fcc971e55ea441c6567ccba8543a132d1a60b8..9b6a5a3556dc24405c8b13bcea4ddc786aaa5274 100644 (file)
@@ -2,8 +2,8 @@
 Implementation for EFI_HII_STRING_PROTOCOL.\r
 \r
 \r
-Copyright (c) 2007, 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
@@ -124,7 +124,7 @@ ConvertToUnicodeText (
   ASSERT (StringSrc != NULL && BufferSize != NULL);\r
 \r
   StringSize = AsciiStrSize (StringSrc) * 2;\r
-  if (*BufferSize < StringSize) {\r
+  if (*BufferSize < StringSize || StringDest == NULL) {\r
     *BufferSize = StringSize;\r
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
@@ -235,25 +235,26 @@ 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.\r
-  If StringId = 0, output the string id of last string block (EFI_HII_SIBT_END).\r
-\r
-  @param  Private                Hii database private structure.\r
-  @param  StringPackage          Hii string package instance.\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
-  @param  StringTextOffset       Offset, relative to the found block address, of\r
-                                 the  string text information.\r
-  @param  LastStringId           Output the last string id when StringId = 0.\r
-\r
-  @retval EFI_SUCCESS            The string text and font is retrieved\r
-                                 successfully.\r
-  @retval EFI_NOT_FOUND          The specified text or font info can not be found\r
-                                 out.\r
-  @retval EFI_OUT_OF_RESOURCES   The system is out of resources to accomplish the\r
-                                 task.\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
+  @param  Private                 Hii database private structure.\r
+  @param  StringPackage           Hii string package instance.\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
+  @param  StringTextOffset        Offset, relative to the found block address, of\r
+                                  the  string text information.\r
+  @param  LastStringId            Output the last string id when StringId = 0 or StringId = -1.\r
+\r
+  @retval EFI_SUCCESS             The string text and font is retrieved\r
+                                  successfully.\r
+  @retval EFI_NOT_FOUND           The specified text or font info can not be found\r
+                                  out.\r
+  @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the\r
+                                  task.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -295,8 +296,15 @@ FindStringBlock (
 \r
   if (StringId != (EFI_STRING_ID) (-1) && StringId != 0) {\r
     ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL);\r
+    if (StringId > StringPackage->MaxStringId) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
   } else {\r
     ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
+    if (StringId == 0 && LastStringId != NULL) {\r
+      *LastStringId = StringPackage->MaxStringId;\r
+      return EFI_SUCCESS;\r
+    }\r
   }\r
 \r
   ZeroMem (&Zero, sizeof (CHAR16));\r
@@ -547,13 +555,12 @@ FindStringBlock (
     BlockHdr  = StringPackage->StringBlock + BlockSize;\r
 \r
   }\r
-\r
+  \r
+  //\r
+  // Get last string ID\r
+  //\r
   if (StringId == (EFI_STRING_ID) (-1)) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (StringId == 0 && LastStringId != NULL) {\r
-    *LastStringId = CurrentStringId;\r
+    *LastStringId = (EFI_STRING_ID) (CurrentStringId - 1);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -592,7 +599,7 @@ GetStringWorker (
   IN  HII_STRING_PACKAGE_INSTANCE     *StringPackage,\r
   IN  EFI_STRING_ID                   StringId,\r
   OUT EFI_STRING                      String,\r
-  IN  OUT UINTN                       *StringSize,\r
+  IN  OUT UINTN                       *StringSize, OPTIONAL\r
   OUT EFI_FONT_INFO                   **StringFontInfo OPTIONAL\r
   )\r
 {\r
@@ -603,7 +610,7 @@ GetStringWorker (
   EFI_STATUS                           Status;\r
   UINT8                                FontId;\r
 \r
-  ASSERT (StringPackage != NULL && StringSize != NULL);\r
+  ASSERT (StringPackage != NULL);\r
   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
 \r
   //\r
@@ -622,6 +629,13 @@ GetStringWorker (
     return Status;\r
   }\r
 \r
+  if (StringSize == NULL) {\r
+    //\r
+    // String text buffer is not requested\r
+    //\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   // Get the string text.\r
   //\r
@@ -909,7 +923,10 @@ 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
+  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
   @param  PackageList            Handle of the package list where this string will\r
@@ -952,7 +969,6 @@ HiiNewString (
 {\r
   EFI_STATUS                          Status;\r
   LIST_ENTRY                          *Link;\r
-  BOOLEAN                             Matched;\r
   HII_DATABASE_PRIVATE_DATA           *Private;\r
   HII_DATABASE_RECORD                 *DatabaseRecord;\r
   HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;\r
@@ -968,6 +984,12 @@ HiiNewString (
   EFI_HII_SIBT_EXT2_BLOCK             Ext2;\r
   HII_FONT_INFO                       *LocalFont;\r
   HII_GLOBAL_FONT_INFO                *GlobalFont;\r
+  EFI_STRING_ID                       NewStringId;\r
+  EFI_STRING_ID                       NextStringId;\r
+  EFI_STRING_ID                       Index;\r
+  HII_STRING_PACKAGE_INSTANCE         *MatchStringPackage;\r
+  BOOLEAN                             NewStringPackageCreated;\r
+\r
 \r
   if (This == NULL || String == NULL || StringId == NULL || Language == NULL || PackageList == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1004,37 +1026,113 @@ HiiNewString (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  //\r
-  // Try to get the matching string package. Create a new string package when failed.\r
-  //\r
+  Status = EFI_SUCCESS;\r
+  NewStringPackageCreated = FALSE;\r
+  NewStringId   = 0;\r
+  NextStringId  = 0;\r
   StringPackage = NULL;\r
-  Matched       = FALSE;\r
+  MatchStringPackage = NULL;\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
-    if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
-      Matched = TRUE;\r
-      break;\r
+    //\r
+    // Create a string block and corresponding font block if exists, then append them\r
+    // to the end of the string package.\r
+    //\r
+    Status = FindStringBlock (\r
+               Private,\r
+               StringPackage,\r
+               0,\r
+               NULL,\r
+               NULL,\r
+               NULL,\r
+               &NextStringId\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+    //\r
+    // Make sure that new StringId is same in all String Packages for the different language.\r
+    //\r
+    if (NewStringId != 0 && NewStringId != NextStringId) {\r
+      ASSERT (FALSE);\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+    NewStringId = NextStringId;\r
+    //\r
+    // Get the matched string package with language.\r
+    //\r
+    if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
+      MatchStringPackage = StringPackage;\r
+    } else {\r
+      OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
+      //\r
+      // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID.\r
+      //\r
+      Ucs2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);\r
+\r
+      StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize);\r
+      if (StringBlock == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\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 a blank EFI_HII_SIBT_STRING_UCS2 block\r
+      //\r
+      BlockPtr  = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK);\r
+      *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
+      BlockPtr  += sizeof (EFI_HII_SIBT_STRING_UCS2_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 += Ucs2BlockSize;\r
+      PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;\r
     }\r
   }\r
+  if (NewStringId == 0) {\r
+    //\r
+    // No string package is found.\r
+    // Create new string package. StringId 1 is reserved for Language Name string.\r
+    //\r
+    *StringId = 2;\r
+  } else {\r
+    //\r
+    // Set new StringId\r
+    //\r
+    *StringId = (EFI_STRING_ID) (NewStringId + 1);\r
+  }\r
 \r
-  if (!Matched) {\r
+  if (MatchStringPackage != NULL) {\r
+    StringPackage = MatchStringPackage;\r
+  } else {\r
     //\r
     // LanguageName is required to create a new string package.\r
     //\r
     if (LanguageName == NULL) {\r
-      return EFI_INVALID_PARAMETER;\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
     }\r
 \r
     StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));\r
     if (StringPackage == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
     }\r
 \r
-    StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;\r
-    StringPackage->FontId    = 0;\r
+    StringPackage->Signature   = HII_STRING_PACKAGE_SIGNATURE;\r
+    StringPackage->MaxStringId = *StringId;\r
+    StringPackage->FontId      = 0;\r
     InitializeListHead (&StringPackage->FontInfoList);\r
 \r
     //\r
@@ -1044,12 +1142,13 @@ HiiNewString (
     StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);\r
     if (StringPackage->StringPkgHdr == NULL) {\r
       FreePool (StringPackage);\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
     }\r
     StringPackage->StringPkgHdr->Header.Type      = EFI_HII_PACKAGE_STRINGS;\r
     StringPackage->StringPkgHdr->HdrSize          = HeaderSize;\r
     StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;\r
-    CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));;\r
+    CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));\r
     StringPackage->StringPkgHdr->LanguageName     = 1;\r
     AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language);\r
 \r
@@ -1057,15 +1156,16 @@ HiiNewString (
     // 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
-                              sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16));\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
     StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (BlockSize);\r
     if (StringPackage->StringBlock == NULL) {\r
       FreePool (StringPackage->StringPkgHdr);\r
       FreePool (StringPackage);\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
     }\r
 \r
     //\r
@@ -1076,7 +1176,10 @@ HiiNewString (
     BlockPtr  += sizeof (EFI_HII_STRING_BLOCK);\r
     CopyMem (BlockPtr, (EFI_STRING) LanguageName, StrSize ((EFI_STRING) LanguageName));\r
     BlockPtr += StrSize ((EFI_STRING) LanguageName);\r
-\r
+    for (Index = 2; Index <= *StringId - 1; Index ++) {\r
+      *BlockPtr = EFI_HII_SIBT_STRING_UCS2;\r
+      BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK);\r
+    }\r
     //\r
     // Insert the end block\r
     //\r
@@ -1088,24 +1191,7 @@ HiiNewString (
     StringPackage->StringPkgHdr->Header.Length    = HeaderSize + BlockSize;\r
     PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;\r
     InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry);\r
-\r
-  }\r
-\r
-  //\r
-  // Create a string block and corresponding font block if exists, then append them\r
-  // to the end of the string package.\r
-  //\r
-  Status = FindStringBlock (\r
-             Private,\r
-             StringPackage,\r
-             0,\r
-             NULL,\r
-             NULL,\r
-             NULL,\r
-             StringId\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    NewStringPackageCreated = TRUE;\r
   }\r
 \r
   OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
@@ -1114,13 +1200,13 @@ HiiNewString (
     //\r
     // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified.\r
     //\r
-\r
     Ucs2BlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK)\r
                               - sizeof (CHAR16));\r
 \r
     StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize);\r
     if (StringBlock == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
     }\r
     //\r
     // Copy original string blocks, except the EFI_HII_SIBT_END.\r
@@ -1159,7 +1245,8 @@ HiiNewString (
       //\r
       StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize);\r
       if (StringBlock == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
       }\r
       //\r
       // Copy original string blocks, except the EFI_HII_SIBT_END.\r
@@ -1195,7 +1282,8 @@ HiiNewString (
                                 sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16));\r
       StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize);\r
       if (StringBlock == NULL) {\r
-        return EFI_OUT_OF_RESOURCES;\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
       }\r
       //\r
       // Copy original string blocks, except the EFI_HII_SIBT_END.\r
@@ -1225,7 +1313,7 @@ HiiNewString (
         &((EFI_FONT_INFO *) StringFontInfo)->FontName,\r
         StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName)\r
         );\r
-\r
+      BlockPtr += StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName);\r
       //\r
       // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK\r
       //\r
@@ -1253,7 +1341,42 @@ HiiNewString (
     }\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+Done:\r
+  if (!EFI_ERROR (Status) && NewStringPackageCreated) {\r
+    //\r
+    // Trigger any registered notification function for new string package\r
+    //\r
+    Status = InvokeRegisteredFunction (\r
+      Private,\r
+      EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
+      (VOID *) StringPackage,\r
+      EFI_HII_PACKAGE_STRINGS,\r
+      PackageList\r
+      );\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Update MaxString Id to new StringId\r
+    //\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->MaxStringId = *StringId;\r
+    }\r
+  } else if (NewStringPackageCreated) {\r
+    //\r
+    // Free the allocated new string Package when new string can't be added.\r
+    //\r
+    RemoveEntryList (&StringPackage->StringEntry);\r
+    FreePool (StringPackage->StringBlock);\r
+    FreePool (StringPackage->StringPkgHdr);\r
+    FreePool (StringPackage);\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -1340,7 +1463,7 @@ HiiGetString (
          Link =  Link->ForwardLink\r
         ) {\r
         StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
-        if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
+        if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
           Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);\r
           if (Status != EFI_NOT_FOUND) {\r
             return Status;\r
@@ -1355,7 +1478,7 @@ HiiGetString (
            Link =  Link->ForwardLink\r
           ) {\r
       StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);      \r
-      Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);\r
+      Status = GetStringWorker (Private, StringPackage, StringId, NULL, NULL, NULL);\r
       if (!EFI_ERROR (Status)) {\r
         return EFI_INVALID_LANGUAGE;\r
       }\r
@@ -1433,7 +1556,7 @@ HiiSetString (
          Link =  Link->ForwardLink\r
         ) {\r
       StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
-      if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
+      if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
         OldPackageLen = StringPackage->StringPkgHdr->Header.Length;\r
         Status = SetStringWorker (\r
                    Private,\r
@@ -1523,7 +1646,7 @@ HiiGetLanguages (
       ) {\r
     StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
     ResultSize += AsciiStrSize (StringPackage->StringPkgHdr->Language);\r
-    if (ResultSize < *LanguagesSize) {\r
+    if (ResultSize <= *LanguagesSize) {\r
       AsciiStrCpy (Languages, StringPackage->StringPkgHdr->Language);\r
       Languages += AsciiStrSize (StringPackage->StringPkgHdr->Language);\r
       *(Languages - 1) = L';';\r
@@ -1622,7 +1745,7 @@ HiiGetSecondaryLanguages (
          Link1 = Link1->ForwardLink\r
         ) {\r
     StringPackage = CR (Link1, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
-    if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) FirstLanguage)) {\r
+    if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) FirstLanguage)) {\r
       Languages = StringPackage->StringPkgHdr->Language;\r
       //\r
       // Language is a series of ';' terminated strings, first one is primary\r
@@ -1650,3 +1773,41 @@ HiiGetSecondaryLanguages (
   return EFI_INVALID_LANGUAGE;\r
 }\r
 \r
+/**\r
+  Compare whether two names of languages are identical.\r
+\r
+  @param  Language1              Name of language 1\r
+  @param  Language2              Name of language 2\r
+\r
+  @retval TRUE                   same\r
+  @retval FALSE                  not same\r
+\r
+**/\r
+BOOLEAN\r
+HiiCompareLanguage (\r
+  IN  CHAR8  *Language1,\r
+  IN  CHAR8  *Language2\r
+  )\r
+{\r
+  //\r
+  // Porting Guide:\r
+  // This library interface is simply obsolete.\r
+  // Include the source code to user code.\r
+  //\r
+  UINTN Index;\r
+\r
+  for (Index = 0; (Language1[Index] != 0) && (Language2[Index] != 0); Index++) {\r
+    if (Language1[Index] != Language2[Index]) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  if (((Language1[Index] == 0) && (Language2[Index] == 0))   || \r
+         ((Language1[Index] == 0) && (Language2[Index] != ';')) ||\r
+         ((Language1[Index] == ';') && (Language2[Index] != 0)) ||\r
+         ((Language1[Index] == ';') && (Language2[Index] != ';'))) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r