]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/String.c
MdeModulePkg Variable: Align TPL level for (Smm)EndOfDxe callback
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / String.c
index bec8ce748c7aa265431d761477b1b960483bfe4e..d5a7488a79d39ee2201560dc8146881e805451e0 100644 (file)
@@ -2,7 +2,8 @@
 Implementation for EFI_HII_STRING_PROTOCOL.\r
 \r
 \r
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
@@ -105,7 +106,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 +150,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 +199,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
@@ -295,6 +296,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 +337,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 +357,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 +410,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 +427,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 +467,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 +481,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 +496,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
@@ -531,7 +537,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
@@ -572,7 +578,7 @@ FindStringBlock (
   //\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
@@ -713,7 +719,7 @@ GetStringWorker (
   @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
@@ -895,6 +901,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
@@ -1075,7 +1082,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
@@ -1328,7 +1335,7 @@ 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
@@ -1437,7 +1444,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 +1488,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 +1505,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
@@ -1553,6 +1560,18 @@ 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
   return Status;\r
 }\r
@@ -1585,7 +1604,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
@@ -1747,6 +1767,13 @@ HiiSetString (
           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
         return EFI_SUCCESS;\r
       }\r
     }\r
@@ -1770,7 +1797,8 @@ HiiSetString (
                                  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
@@ -1794,7 +1822,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
@@ -1826,7 +1857,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
@@ -1866,15 +1897,16 @@ HiiGetLanguages (
                                  points to the length of SecondaryLanguages in bytes.\r
 \r
   @retval EFI_SUCCESS            Secondary languages were correctly returned.\r
-  @retval EFI_INVALID_PARAMETER  PrimaryLanguage 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
                                  SecondaryLanguageSize is updated to hold the size of\r
                                  the buffer required.\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
+  @retval EFI_NOT_FOUND          The specified PackageList is not in the Database.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1896,10 +1928,10 @@ HiiGetSecondaryLanguages (
   CHAR8                               *Languages;\r
   UINTN                               ResultSize;\r
 \r
-  if (This == NULL || PackageList == NULL || PrimaryLanguage == 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
@@ -1942,7 +1974,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
@@ -1955,6 +1987,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
@@ -1972,19 +2029,42 @@ HiiCompareLanguage (
   )\r
 {\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; Language1[Index] != 0 && Language1[Index] != ';'; Index++) {\r
-    if (Language1[Index] != Language2[Index]) {\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
   // 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