]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/String.c
Fix a potential bug that GetLanguages() API may return incorrect languages in a strin...
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / String.c
index d408365a891464a23398f319c7482c2a1cc68424..c6edd87cfd0f37a4845c76882374e6330c595c42 100644 (file)
@@ -1,4 +1,6 @@
 /** @file\r
+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
@@ -9,17 +11,6 @@ http://opensource.org/licenses/bsd-license.php
 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
 \r
-Module Name:\r
-\r
-    String.c\r
-\r
-Abstract:\r
-\r
-    Implementation for EFI_HII_STRING_PROTOCOL.\r
-\r
-Revision History\r
-\r
-\r
 **/\r
 \r
 \r
@@ -38,8 +29,12 @@ CHAR16 mLanguageWindow[16] = {
   font info list or not. (i.e. HII_FONT_INFO is generated.) If not, create\r
   a HII_FONT_INFO to refer it locally.\r
 \r
+  This is a internal function.\r
+\r
+\r
   @param  Private                Hii database private structure.\r
   @param  StringPackage          HII string package instance.\r
+  @param  FontId                Font identifer, which must be unique within the string package.\r
   @param  DuplicateEnable        If true, duplicate HII_FONT_INFO which refers to\r
                                  the same EFI_FONT_INFO is permitted. Otherwise it\r
                                  is not allowed.\r
@@ -52,11 +47,11 @@ CHAR16 mLanguageWindow[16] = {
   @retval FALSE                  Not referred before calling this function.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 ReferFontInfoLocally (\r
   IN  HII_DATABASE_PRIVATE_DATA   *Private,\r
   IN  HII_STRING_PACKAGE_INSTANCE *StringPackage,\r
+  IN  UINT8                       FontId,\r
   IN  BOOLEAN                     DuplicateEnable,\r
   IN  HII_GLOBAL_FONT_INFO        *GlobalFontInfo,\r
   OUT HII_FONT_INFO               **LocalFontInfo\r
@@ -82,11 +77,6 @@ ReferFontInfoLocally (
       }\r
     }\r
   }\r
-  //\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
   // FontId identifies EFI_FONT_INFO in local string package uniquely.\r
   // GlobalEntry points to a HII_GLOBAL_FONT_INFO which identifies\r
   // EFI_FONT_INFO uniquely in whole hii database.\r
@@ -95,12 +85,10 @@ ReferFontInfoLocally (
   ASSERT (LocalFont != NULL);\r
 \r
   LocalFont->Signature   = HII_FONT_INFO_SIGNATURE;\r
-  LocalFont->FontId      = StringPackage->FontId;\r
+  LocalFont->FontId      = FontId;\r
   LocalFont->GlobalEntry = &GlobalFontInfo->Entry;\r
   InsertTailList (&StringPackage->FontInfoList, &LocalFont->Entry);\r
 \r
-  StringPackage->FontId++;\r
-\r
   *LocalFontInfo = LocalFont;\r
   return FALSE;\r
 }\r
@@ -109,8 +97,12 @@ ReferFontInfoLocally (
 /**\r
   Convert Ascii string text to unicode string test.\r
 \r
-  @param  StringSrc              Points to current null-terminated Ascii string.\r
-  @param  StringDest             Buffer to store the converted string text.\r
+  This is a internal function.\r
+\r
+\r
+  @param  StringDest             Buffer to store the string text. If it is NULL,\r
+                                 only the size will be returned.\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
@@ -119,7 +111,6 @@ ReferFontInfoLocally (
                                  size.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 ConvertToUnicodeText (\r
   OUT EFI_STRING       StringDest,\r
@@ -133,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
@@ -151,8 +142,11 @@ ConvertToUnicodeText (
   Calculate the size of StringSrc and output it. If StringDest is not NULL,\r
   copy string text from src to dest.\r
 \r
+  This is a internal function.\r
+\r
+  @param  StringDest             Buffer to store the string text. If it is NULL,\r
+                                 only the size will be returned.\r
   @param  StringSrc              Points to current null-terminated string.\r
-  @param  StringDest             Buffer to store the string text.\r
   @param  BufferSize             Length of the buffer.\r
 \r
   @retval EFI_SUCCESS            The string text was outputed successfully.\r
@@ -161,7 +155,6 @@ ConvertToUnicodeText (
                                  size.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetUnicodeStringTextOrSize (\r
   OUT EFI_STRING       StringDest, OPTIONAL\r
@@ -170,26 +163,23 @@ GetUnicodeStringTextOrSize (
   )\r
 {\r
   UINTN  StringSize;\r
-  CHAR16 Zero;\r
   UINT8  *StringPtr;\r
 \r
   ASSERT (StringSrc != NULL && BufferSize != NULL);\r
 \r
-  ZeroMem (&Zero, sizeof (CHAR16));\r
   StringSize = sizeof (CHAR16);\r
   StringPtr  = StringSrc;\r
-  while (CompareMem (StringPtr, &Zero, sizeof (CHAR16)) != 0) {\r
+  while (ReadUnaligned16 ((UINT16 *) StringPtr) != 0) {\r
     StringSize += sizeof (CHAR16);\r
     StringPtr += sizeof (CHAR16);\r
   }\r
 \r
+  if (*BufferSize < StringSize) {\r
+    *BufferSize = StringSize;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
   if (StringDest != NULL) {\r
-    if (*BufferSize < StringSize) {\r
-      *BufferSize = StringSize;\r
-      return EFI_BUFFER_TOO_SMALL;\r
-    }\r
     CopyMem (StringDest, StringSrc, StringSize);\r
-    return EFI_SUCCESS;\r
   }\r
 \r
   *BufferSize = StringSize;\r
@@ -200,6 +190,8 @@ GetUnicodeStringTextOrSize (
 /**\r
   Copy string font info to a buffer.\r
 \r
+  This is a internal function.\r
+\r
   @param  StringPackage          Hii string package instance.\r
   @param  FontId                 Font identifier which is unique in a string\r
                                  package.\r
@@ -210,7 +202,6 @@ GetUnicodeStringTextOrSize (
   @retval EFI_NOT_FOUND          The specified font id does not exist.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetStringFontInfo (\r
   IN  HII_STRING_PACKAGE_INSTANCE     *StringPackage,\r
@@ -249,7 +240,7 @@ GetStringFontInfo (
 \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
+  @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
@@ -292,6 +283,7 @@ FindStringBlock (
   UINT16                               FontSize;\r
   UINT8                                Length8;\r
   EFI_HII_SIBT_EXT2_BLOCK              Ext2;\r
+  UINT8                                FontId;\r
   UINT32                               Length32;\r
   UINTN                                StringSize;\r
   CHAR16                               Zero;\r
@@ -486,7 +478,9 @@ FindStringBlock (
         // Find the relationship between global font info and the font info of\r
         // this EFI_HII_SIBT_FONT block then backup its information in local package.\r
         //\r
-        BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK) + sizeof (UINT8);\r
+        BlockHdr += sizeof (EFI_HII_SIBT_EXT2_BLOCK);\r
+        CopyMem (&FontId, BlockHdr, sizeof (UINT8));\r
+        BlockHdr += sizeof (UINT8);\r
         CopyMem (&FontSize, BlockHdr, sizeof (UINT16));\r
         BlockHdr += sizeof (UINT16);\r
         CopyMem (&FontStyle, BlockHdr, sizeof (EFI_HII_FONT_STYLE));\r
@@ -502,17 +496,22 @@ FindStringBlock (
         FontInfo->FontSize  = FontSize;\r
         CopyMem (FontInfo->FontName, BlockHdr, StringSize);\r
 \r
+        //\r
+        // If find the corresponding global font info, save the relationship.\r
+        // Otherwise ignore this EFI_HII_SIBT_FONT block.\r
+        //\r
         if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {\r
-          //\r
-          // If find the corresponding global font info, save the relationship.\r
-          //\r
-          ReferFontInfoLocally (Private, StringPackage, TRUE, GlobalFont, &LocalFont);\r
+          ReferFontInfoLocally (Private, StringPackage, FontId, TRUE, GlobalFont, &LocalFont);\r
         }\r
 \r
         //\r
-        // If can not find, ignore this EFI_HII_SIBT_FONT block.\r
-        //\r
-        SafeFreePool (FontInfo);\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
+        StringPackage->FontId++;\r
+\r
+        FreePool (FontInfo);\r
       }\r
 \r
       BlockSize += Ext2.Length;\r
@@ -565,9 +564,11 @@ FindStringBlock (
 /**\r
   Parse all string blocks to get a string specified by StringId.\r
 \r
+  This is a internal function.\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
+  @param  StringId               The string's id, which is unique within\r
                                  PackageList.\r
   @param  String                 Points to retrieved null-terminated string.\r
   @param  StringSize             On entry, points to the size of the buffer pointed\r
@@ -585,7 +586,6 @@ FindStringBlock (
                                  hold the string.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetStringWorker (\r
   IN HII_DATABASE_PRIVATE_DATA        *Private,\r
@@ -647,7 +647,8 @@ GetStringWorker (
   }\r
 \r
   //\r
-  // Get the string font.\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
     switch (BlockType) {\r
@@ -656,10 +657,13 @@ GetStringWorker (
     case EFI_HII_SIBT_STRING_UCS2_FONT:\r
     case EFI_HII_SIBT_STRINGS_UCS2_FONT:\r
       FontId = *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK));\r
-      return GetStringFontInfo (StringPackage, FontId, StringFontInfo);\r
       break;\r
     default:\r
-      break;\r
+      FontId = 0;\r
+    }\r
+    Status = GetStringFontInfo (StringPackage, FontId, StringFontInfo);\r
+    if (Status == EFI_NOT_FOUND) {\r
+        *StringFontInfo = NULL;\r
     }\r
   }\r
 \r
@@ -670,9 +674,11 @@ GetStringWorker (
 /**\r
   Parse all string blocks to set a String specified by StringId.\r
 \r
+  This is a internal function.\r
+\r
   @param  Private                HII database driver private structure.\r
   @param  StringPackage          HII string package instance.\r
-  @param  StringId               The string¡¯s id, which is unique within\r
+  @param  StringId               The string's id, which is unique within\r
                                  PackageList.\r
   @param  String                 Points to the new null-terminated string.\r
   @param  StringFontInfo         Points to the input font info.\r
@@ -687,7 +693,6 @@ GetStringWorker (
                                  task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 SetStringWorker (\r
   IN  HII_DATABASE_PRIVATE_DATA       *Private,\r
@@ -737,38 +742,48 @@ SetStringWorker (
   Referred   = FALSE;\r
 \r
   //\r
-  // Set the string font according to input font information.\r
+  // The input StringFontInfo should exist in current database if specified.\r
   //\r
   if (StringFontInfo != NULL) {\r
-    //\r
-    // The input StringFontInfo should exist in current database\r
-    //\r
     if (!IsFontInfoExisted (Private, StringFontInfo, NULL, NULL, &GlobalFont)) {\r
       return EFI_INVALID_PARAMETER;\r
     } else {\r
-      Referred = ReferFontInfoLocally (Private, StringPackage, FALSE, GlobalFont, &LocalFont);\r
+      Referred = ReferFontInfoLocally (\r
+                   Private, \r
+                   StringPackage, \r
+                   StringPackage->FontId, \r
+                   FALSE, \r
+                   GlobalFont, \r
+                   &LocalFont\r
+                   );\r
+      if (!Referred) {\r
+        StringPackage->FontId++;\r
+      }\r
     }\r
-\r
     //\r
-    // Update the FontId of the specified string block\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
       *(StringBlockAddr + sizeof (EFI_HII_STRING_BLOCK)) = LocalFont->FontId;\r
       break;\r
     default:\r
-      return EFI_NOT_FOUND;\r
+      //\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
+      return EFI_UNSUPPORTED;\r
     }\r
-\r
   }\r
 \r
   OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize;\r
 \r
   //\r
-  // Set the string text.\r
+  // Set the string text and font.\r
   //\r
   StringTextPtr = StringBlockAddr + StringTextOffset;\r
   switch (BlockType) {\r
@@ -799,7 +814,7 @@ SetStringWorker (
       TmpSize\r
       );\r
 \r
-    SafeFreePool (StringPackage->StringBlock);\r
+    FreePool (StringPackage->StringBlock);\r
     StringPackage->StringBlock = Block;\r
     StringPackage->StringPkgHdr->Header.Length += (UINT32) (BlockSize - OldBlockSize);\r
     break;\r
@@ -832,7 +847,7 @@ SetStringWorker (
       OldBlockSize - (StringTextPtr - StringPackage->StringBlock) - StringSize\r
       );\r
 \r
-    SafeFreePool (StringPackage->StringBlock);\r
+    FreePool (StringPackage->StringBlock);\r
     StringPackage->StringBlock = Block;\r
     StringPackage->StringPkgHdr->Header.Length += (UINT32) (BlockSize - OldBlockSize);\r
     break;\r
@@ -883,7 +898,7 @@ SetStringWorker (
 \r
   CopyMem (BlockPtr, StringPackage->StringBlock, OldBlockSize);\r
 \r
-  SafeFreePool (StringPackage->StringBlock);\r
+  FreePool (StringPackage->StringBlock);\r
   StringPackage->StringBlock = Block;\r
   StringPackage->StringPkgHdr->Header.Length += Ext2.Length;\r
 \r
@@ -909,7 +924,7 @@ SetStringWorker (
                                  not zero, the LanguageName being passed  in will\r
                                  be ignored.\r
   @param  String                 Points to the new null-terminated string.\r
-  @param  StringFontInfo         Points to the new string¡¯s font information or\r
+  @param  StringFontInfo         Points to the new string's font information or\r
                                  NULL if the string should have the default system\r
                                  font, size and style.\r
 \r
@@ -1028,7 +1043,7 @@ HiiNewString (
     HeaderSize = (UINT32) (AsciiStrSize ((CHAR8 *) Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));\r
     StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);\r
     if (StringPackage->StringPkgHdr == NULL) {\r
-      SafeFreePool (StringPackage);\r
+      FreePool (StringPackage);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     StringPackage->StringPkgHdr->Header.Type      = EFI_HII_PACKAGE_STRINGS;\r
@@ -1048,8 +1063,8 @@ HiiNewString (
     BlockSize     = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK);\r
     StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (BlockSize);\r
     if (StringPackage->StringBlock == NULL) {\r
-      SafeFreePool (StringPackage->StringPkgHdr);\r
-      SafeFreePool (StringPackage);\r
+      FreePool (StringPackage->StringPkgHdr);\r
+      FreePool (StringPackage);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
@@ -1124,7 +1139,7 @@ HiiNewString (
     // Append a EFI_HII_SIBT_END block to the end.\r
     //\r
     *BlockPtr = EFI_HII_SIBT_END;\r
-    SafeFreePool (StringPackage->StringBlock);\r
+    FreePool (StringPackage->StringBlock);\r
     StringPackage->StringBlock = StringBlock;\r
     StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize;\r
     PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize;\r
@@ -1138,7 +1153,7 @@ HiiNewString (
     //\r
     Ucs2FontBlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) -\r
                                   sizeof (CHAR16));\r
-    if (ReferFontInfoLocally (Private, StringPackage, FALSE, GlobalFont, &LocalFont)) {\r
+    if (ReferFontInfoLocally (Private, StringPackage, StringPackage->FontId, FALSE, GlobalFont, &LocalFont)) {\r
       //\r
       // Create a EFI_HII_SIBT_STRING_UCS2_FONT block only.\r
       //\r
@@ -1165,7 +1180,7 @@ HiiNewString (
       // Append a EFI_HII_SIBT_END block to the end.\r
       //\r
       *BlockPtr = EFI_HII_SIBT_END;\r
-      SafeFreePool (StringPackage->StringBlock);\r
+      FreePool (StringPackage->StringBlock);\r
       StringPackage->StringBlock = StringBlock;\r
       StringPackage->StringPkgHdr->Header.Length += Ucs2FontBlockSize;\r
       PackageListNode->PackageListHdr.PackageLength += Ucs2FontBlockSize;\r
@@ -1225,13 +1240,32 @@ HiiNewString (
       // Append a EFI_HII_SIBT_END block to the end.\r
       //\r
       *BlockPtr = EFI_HII_SIBT_END;\r
-      SafeFreePool (StringPackage->StringBlock);\r
+      FreePool (StringPackage->StringBlock);\r
       StringPackage->StringBlock = StringBlock;\r
       StringPackage->StringPkgHdr->Header.Length += FontBlockSize + Ucs2FontBlockSize;\r
       PackageListNode->PackageListHdr.PackageLength += FontBlockSize + Ucs2FontBlockSize;\r
+\r
+      //\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
     }\r
   }\r
 \r
+  //\r
+  // Trigger any registered notification function\r
+  //\r
+  if (!Matched) {  \r
+    return InvokeRegisteredFunction (\r
+             Private,\r
+             EFI_HII_DATABASE_NOTIFY_NEW_PACK,\r
+             (VOID *) StringPackage,\r
+             EFI_HII_PACKAGE_STRINGS,\r
+             PackageList\r
+             );\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1251,14 +1285,16 @@ HiiNewString (
   @param  StringSize             On entry, points to the size of the buffer pointed\r
                                  to by  String, in bytes. On return, points to the\r
                                  length of the string, in bytes.\r
-  @param  StringFontInfo         If not NULL, points to the string¡¯s font\r
+  @param  StringFontInfo         If not NULL, points to the string's font\r
                                  information.  It's caller's responsibility to free\r
                                  this buffer.\r
 \r
   @retval EFI_SUCCESS            The string was returned successfully.\r
   @retval EFI_NOT_FOUND          The string specified by StringId is not available.\r
   @retval EFI_NOT_FOUND          The string specified by StringId is available but\r
-                                 not in the specified language.\r
+                                                not in the specified language.\r
+                                                The specified PackageList is not in the database.\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
@@ -1309,18 +1345,34 @@ HiiGetString (
   }\r
 \r
   if (PackageListNode != NULL) {\r
+    //\r
+    // First search: to match the StringId in the specified language.\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
-      if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
-        Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);\r
-        if (Status != EFI_NOT_FOUND) {\r
-          return Status;\r
+        StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);\r
+        if (R8_EfiLibCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {\r
+          Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);\r
+          if (Status != EFI_NOT_FOUND) {\r
+            return Status;\r
+          }\r
         }\r
       }\r
-    }\r
+      //\r
+      // Second search: to match the StringId in other available languages if exist.\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
+      Status = GetStringWorker (Private, StringPackage, StringId, String, StringSize, StringFontInfo);\r
+      if (!EFI_ERROR (Status)) {\r
+        return EFI_INVALID_LANGUAGE;\r
+      }\r
+    }    \r
   }\r
 \r
   return EFI_NOT_FOUND;\r
@@ -1334,11 +1386,11 @@ HiiGetString (
 \r
   @param  This                   A pointer to the EFI_HII_STRING_PROTOCOL instance.\r
   @param  PackageList            The package list containing the strings.\r
-  @param  StringId               The string¡¯s id, which is unique within\r
+  @param  StringId               The string's id, which is unique within\r
                                  PackageList.\r
   @param  Language               Points to the language for the updated string.\r
   @param  String                 Points to the new null-terminated string.\r
-  @param  StringFontInfo         Points to the string¡¯s font information or NULL if\r
+  @param  StringFontInfo         Points to the string's font information or NULL if\r
                                  the  string font information is not changed.\r
 \r
   @retval EFI_SUCCESS            The string was updated successfully.\r
@@ -1484,7 +1536,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
@@ -1517,19 +1569,20 @@ HiiGetLanguages (
                                  FirstLanguage. If there are no secondary\r
                                  languages, the function  returns successfully, but\r
                                  this is set to NULL.\r
-  @param  SecondaryLanguageSize  On entry, points to the size of the buffer pointed\r
-                                 to  by SecondLanguages, in bytes. On return,\r
-                                 points to the length of SecondLanguages in bytes.\r
+  @param  SecondaryLanguagesSize On entry, points to the size of the buffer pointed\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 SecondLanguages or\r
-                                 SecondLanguagesSize was NULL.\r
-  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by SecondLanguagesSize is\r
+  @retval EFI_INVALID_PARAMETER  FirstLanguage or SecondaryLanguages or\r
+                                 SecondaryLanguagesSize was 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
                                  the buffer required.\r
-  @retval EFI_NOT_FOUND          The language specified by FirstLanguage is not\r
-                                 present in the specified package list.\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
 \r
 **/\r
 EFI_STATUS\r
@@ -1538,8 +1591,8 @@ HiiGetSecondaryLanguages (
   IN CONST EFI_HII_STRING_PROTOCOL   *This,\r
   IN EFI_HII_HANDLE                  PackageList,\r
   IN CONST CHAR8                     *FirstLanguage,\r
-  IN OUT CHAR8                       *SecondLanguages,\r
-  IN OUT UINTN                       *SecondLanguagesSize\r
+  IN OUT CHAR8                       *SecondaryLanguages,\r
+  IN OUT UINTN                       *SecondaryLanguagesSize\r
   )\r
 {\r
   LIST_ENTRY                          *Link;\r
@@ -1554,7 +1607,7 @@ HiiGetSecondaryLanguages (
   if (This == NULL || PackageList == NULL || FirstLanguage == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (SecondLanguages == NULL || SecondLanguagesSize == NULL) {\r
+  if (SecondaryLanguages == NULL || SecondaryLanguagesSize == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if (!IsHiiHandleValid (PackageList)) {\r
@@ -1562,45 +1615,51 @@ HiiGetSecondaryLanguages (
   }\r
 \r
   Private    = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-  Languages  = NULL;\r
-  ResultSize = 0;\r
 \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
       PackageListNode = (HII_DATABASE_PACKAGE_LIST_INSTANCE *) (DatabaseRecord->PackageList);\r
-      for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;\r
-           Link1 != &PackageListNode->StringPkgHdr;\r
-           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
-          Languages = StringPackage->StringPkgHdr->Language;\r
-          //\r
-          // Language is a series of ';' terminated strings, first one is primary\r
-          // language and following with other secondary languages or NULL if no\r
-          // secondary languages any more.\r
-          //\r
-          Languages = AsciiStrStr (Languages, ";");\r
-          if (Languages == NULL) {\r
-            break;\r
-          }\r
-          Languages++;\r
-\r
-          ResultSize = AsciiStrSize (Languages);\r
-          if (ResultSize <= *SecondLanguagesSize) {\r
-            AsciiStrCpy (SecondLanguages, Languages);\r
-          } else {\r
-            *SecondLanguagesSize = ResultSize;\r
-            return EFI_BUFFER_TOO_SMALL;\r
-          }\r
+        break;\r
+      }\r
+    }\r
+    if (PackageListNode == NULL) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+      \r
+    Languages  = NULL;\r
+    ResultSize = 0;\r
+    for (Link1 = PackageListNode->StringPkgHdr.ForwardLink;\r
+         Link1 != &PackageListNode->StringPkgHdr;\r
+         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
+      Languages = StringPackage->StringPkgHdr->Language;\r
+      //\r
+      // Language is a series of ';' terminated strings, first one is primary\r
+      // language and following with other secondary languages or NULL if no\r
+      // secondary languages any more.\r
+      //\r
+      Languages = AsciiStrStr (Languages, ";");\r
+      if (Languages == NULL) {\r
+        break;\r
+      }\r
+      Languages++;\r
 \r
-          return EFI_SUCCESS;\r
-        }\r
+      ResultSize = AsciiStrSize (Languages);\r
+      if (ResultSize <= *SecondaryLanguagesSize) {\r
+        AsciiStrCpy (SecondaryLanguages, Languages);\r
+      } else {\r
+        *SecondaryLanguagesSize = ResultSize;\r
+        return EFI_BUFFER_TOO_SMALL;\r
       }\r
+\r
+      return EFI_SUCCESS;\r
     }\r
   }\r
 \r
-  return EFI_NOT_FOUND;\r
+  return EFI_INVALID_LANGUAGE;\r
 }\r
 \r