]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / DxePrintLibPrint2Protocol / PrintLib.c
index 438ac9e84706dcce9a81dc313b776c7596254a8f..3a051fd58003d9678e311b73f5752fea99b9d21c 100644 (file)
@@ -1,19 +1,13 @@
 /** @file\r
-  Instance of Print Library based on gEfiPrint2ProtocolGuid.\r
+  Instance of Print Library based on gEfiPrint2SProtocolGuid.\r
 \r
-  Implement the print library instance by wrap the interface \r
-  provided in the Print2 protocol. This protocol is defined as the internal\r
-  protocol related to this implementation, not in the public spec. So, this \r
+  Implement the print library instance by wrap the interface\r
+  provided in the Print2S protocol. This protocol is defined as the internal\r
+  protocol related to this implementation, not in the public spec. So, this\r
   library instance is only for this code base.\r
 \r
-Copyright (c) 2009 - 2017, 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) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -43,17 +37,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     } \\r
   } while (FALSE)\r
 \r
-EFI_PRINT2_PROTOCOL  *mPrint2Protocol = NULL;\r
+EFI_PRINT2S_PROTOCOL  *mPrint2SProtocol = NULL;\r
 \r
 /**\r
-  The constructor function caches the pointer to Print2 protocol.\r
-  \r
-  The constructor function locates Print2 protocol from protocol database.\r
-  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
+  The constructor function caches the pointer to Print2S protocol.\r
+\r
+  The constructor function locates Print2S protocol from protocol database.\r
+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
 \r
   @param  ImageHandle   The firmware allocated handle for the EFI image.\r
   @param  SystemTable   A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.\r
 \r
 **/\r
@@ -67,19 +61,19 @@ PrintLibConstructor (
   EFI_STATUS                   Status;\r
 \r
   Status = SystemTable->BootServices->LocateProtocol (\r
-                                        &gEfiPrint2ProtocolGuid,\r
+                                        &gEfiPrint2SProtocolGuid,\r
                                         NULL,\r
-                                        (VOID**) &mPrint2Protocol\r
+                                        (VOID**) &mPrint2SProtocol\r
                                         );\r
   ASSERT_EFI_ERROR (Status);\r
-  ASSERT (mPrint2Protocol != NULL);\r
+  ASSERT (mPrint2SProtocol != NULL);\r
 \r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated \r
+  Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated\r
   format string.\r
 \r
   @param  AsciiFormat     TRUE if Format is an ASCII string.  FALSE if Format is a Unicode string.\r
@@ -130,7 +124,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
   //\r
   // Get the first character from the format string\r
   //\r
-  FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+  FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
 \r
   while (FormatCharacter != 0) {\r
     if (FormatCharacter == '%') {\r
@@ -148,14 +142,14 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
         //\r
         // Get the next character from the format string\r
         //\r
-        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+        FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
 \r
         switch (FormatCharacter) {\r
-        case '.': \r
-        case '-': \r
-        case '+': \r
-        case ' ': \r
-        case ',': \r
+        case '.':\r
+        case '-':\r
+        case '+':\r
+        case ' ':\r
+        case ',':\r
         case '0':\r
         case '1':\r
         case '2':\r
@@ -168,7 +162,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
         case '9':\r
           break;\r
         case 'L':\r
-        case 'l': \r
+        case 'l':\r
           Long = TRUE;\r
           break;\r
         case '*':\r
@@ -177,7 +171,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
         case '\0':\r
           //\r
           // Make no output if Format string terminates unexpectedly when\r
-          // looking up for flag, width, precision and type. \r
+          // looking up for flag, width, precision and type.\r
           //\r
           Format -= BytesPerFormatCharacter;\r
           //\r
@@ -187,8 +181,8 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
           Done = TRUE;\r
           break;\r
         }\r
-      } \r
-        \r
+      }\r
+\r
       //\r
       // Handle each argument type\r
       //\r
@@ -226,7 +220,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
     //\r
     // If BASE_LIST is larger than Size, then return FALSE\r
     //\r
-    if ((UINTN)((UINT8 *)BaseListMarker - (UINT8 *)BaseListStart) > Size) {\r
+    if (((UINTN)BaseListMarker - (UINTN)BaseListStart) > Size) {\r
       DEBUG ((DEBUG_ERROR, "The input variable argument list is too long. Please consider breaking into multiple print calls.\n"));\r
       return FALSE;\r
     }\r
@@ -239,7 +233,7 @@ DxePrintLibPrint2ProtocolVaListToBaseList (
     //\r
     // Get the next character from the format string\r
     //\r
-    FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+    FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
   }\r
   return TRUE;\r
 }\r
@@ -362,7 +356,7 @@ UnicodeBSPrint (
 {\r
   ASSERT_UNICODE_BUFFER (StartOfBuffer);\r
   ASSERT_UNICODE_BUFFER (FormatString);\r
-  return mPrint2Protocol->UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  return mPrint2SProtocol->UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -537,7 +531,7 @@ UnicodeBSPrintAsciiFormat (
   )\r
 {\r
   ASSERT_UNICODE_BUFFER (StartOfBuffer);\r
-  return mPrint2Protocol->UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  return mPrint2SProtocol->UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -598,28 +592,32 @@ UnicodeSPrintAsciiFormat (
   return NumberOfPrinted;\r
 }\r
 \r
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES\r
+\r
 /**\r
+  [ATTENTION] This function is deprecated for security reason.\r
+\r
   Converts a decimal value to a Null-terminated Unicode string.\r
-  \r
-  Converts the decimal number specified by Value to a Null-terminated Unicode \r
-  string specified by Buffer containing at most Width characters. No padding of spaces \r
+\r
+  Converts the decimal number specified by Value to a Null-terminated Unicode\r
+  string specified by Buffer containing at most Width characters. No padding of spaces\r
   is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.\r
   The number of Unicode characters in Buffer is returned not including the Null-terminator.\r
   If the conversion contains more than Width characters, then only the first\r
-  Width characters are returned, and the total number of characters \r
+  Width characters are returned, and the total number of characters\r
   required to perform the conversion is returned.\r
-  Additional conversion parameters are specified in Flags.  \r
-  \r
+  Additional conversion parameters are specified in Flags.\r
+\r
   The Flags bit LEFT_JUSTIFY is always ignored.\r
   All conversions are left justified in Buffer.\r
   If Width is 0, PREFIX_ZERO is ignored in Flags.\r
   If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas\r
   are inserted every 3rd digit starting from the right.\r
-  If RADIX_HEX is set in Flags, then the output buffer will be \r
+  If RADIX_HEX is set in Flags, then the output buffer will be\r
   formatted in hexadecimal format.\r
   If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.\r
-  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, \r
-  then Buffer is padded with '0' characters so the combination of the optional '-' \r
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,\r
+  then Buffer is padded with '0' characters so the combination of the optional '-'\r
   sign character, '0' characters, digit characters for Value, and the Null-terminator\r
   add up to Width characters.\r
   If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().\r
@@ -635,7 +633,7 @@ UnicodeSPrintAsciiFormat (
   @param  Value   The 64-bit signed value to convert to a string.\r
   @param  Width   The maximum number of Unicode characters to place in Buffer, not including\r
                   the Null-terminator.\r
-  \r
+\r
   @return The number of Unicode characters in Buffer not including the Null-terminator.\r
 \r
 **/\r
@@ -648,7 +646,87 @@ UnicodeValueToString (
   IN UINTN       Width\r
   )\r
 {\r
-  return mPrint2Protocol->UnicodeValueToString (Buffer, Flags, Value, Width);\r
+  RETURN_STATUS  Status;\r
+  UINTN          BufferSize;\r
+\r
+  if (Width == 0) {\r
+    BufferSize = (MAXIMUM_VALUE_CHARACTERS + 1) * sizeof (CHAR16);\r
+  } else {\r
+    BufferSize = (Width + 1) * sizeof (CHAR16);\r
+  }\r
+\r
+  Status = mPrint2SProtocol->UnicodeValueToStringS (Buffer, BufferSize, Flags, Value, Width);\r
+  if (RETURN_ERROR (Status)) {\r
+    return 0;\r
+  }\r
+\r
+  return StrnLenS (Buffer, BufferSize / sizeof (CHAR16));\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+  Converts a decimal value to a Null-terminated Unicode string.\r
+\r
+  Converts the decimal number specified by Value to a Null-terminated Unicode\r
+  string specified by Buffer containing at most Width characters. No padding of\r
+  spaces is ever performed. If Width is 0 then a width of\r
+  MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than\r
+  Width characters, then only the first Width characters are placed in Buffer.\r
+  Additional conversion parameters are specified in Flags.\r
+\r
+  The Flags bit LEFT_JUSTIFY is always ignored.\r
+  All conversions are left justified in Buffer.\r
+  If Width is 0, PREFIX_ZERO is ignored in Flags.\r
+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and\r
+  commas are inserted every 3rd digit starting from the right.\r
+  If RADIX_HEX is set in Flags, then the output buffer will be formatted in\r
+  hexadecimal format.\r
+  If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in\r
+  Buffer is a '-'.\r
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then\r
+  Buffer is padded with '0' characters so the combination of the optional '-'\r
+  sign character, '0' characters, digit characters for Value, and the\r
+  Null-terminator add up to Width characters.\r
+\r
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  @param  Buffer      The pointer to the output buffer for the produced\r
+                      Null-terminated Unicode string.\r
+  @param  BufferSize  The size of Buffer in bytes, including the\r
+                      Null-terminator.\r
+  @param  Flags       The bitmask of flags that specify left justification,\r
+                      zero pad, and commas.\r
+  @param  Value       The 64-bit signed value to convert to a string.\r
+  @param  Width       The maximum number of Unicode characters to place in\r
+                      Buffer, not including the Null-terminator.\r
+\r
+  @retval RETURN_SUCCESS           The decimal value is converted.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If BufferSize cannot hold the converted\r
+                                   value.\r
+  @retval RETURN_INVALID_PARAMETER If Buffer is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not\r
+                                   zero, and BufferSize is greater than\r
+                                   (PcdMaximumUnicodeStringLength *\r
+                                   sizeof (CHAR16) + 1).\r
+                                   If unsupported bits are set in Flags.\r
+                                   If both COMMA_TYPE and RADIX_HEX are set in\r
+                                   Flags.\r
+                                   If Width >= MAXIMUM_VALUE_CHARACTERS.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UnicodeValueToStringS (\r
+  IN OUT CHAR16  *Buffer,\r
+  IN UINTN       BufferSize,\r
+  IN UINTN       Flags,\r
+  IN INT64       Value,\r
+  IN UINTN       Width\r
+  )\r
+{\r
+  return mPrint2SProtocol->UnicodeValueToStringS (Buffer, BufferSize, Flags, Value, Width);\r
 }\r
 \r
 /**\r
@@ -758,7 +836,7 @@ AsciiBSPrint (
   IN  BASE_LIST     Marker\r
   )\r
 {\r
-  return mPrint2Protocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  return mPrint2SProtocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -931,7 +1009,7 @@ AsciiBSPrintUnicodeFormat (
   )\r
 {\r
   ASSERT_UNICODE_BUFFER (FormatString);\r
-  return mPrint2Protocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
+  return mPrint2SProtocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
 }\r
 \r
 /**\r
@@ -993,31 +1071,35 @@ AsciiSPrintUnicodeFormat (
 }\r
 \r
 \r
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES\r
+\r
 /**\r
+  [ATTENTION] This function is deprecated for security reason.\r
+\r
   Converts a decimal value to a Null-terminated ASCII string.\r
-  \r
-  Converts the decimal number specified by Value to a Null-terminated ASCII string \r
-  specified by Buffer containing at most Width characters. No padding of spaces \r
+\r
+  Converts the decimal number specified by Value to a Null-terminated ASCII string\r
+  specified by Buffer containing at most Width characters. No padding of spaces\r
   is ever performed.\r
   If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.\r
   The number of ASCII characters in Buffer is returned not including the Null-terminator.\r
   If the conversion contains more than Width characters, then only the first Width\r
   characters are returned, and the total number of characters required to perform\r
   the conversion is returned.\r
-  Additional conversion parameters are specified in Flags.  \r
+  Additional conversion parameters are specified in Flags.\r
   The Flags bit LEFT_JUSTIFY is always ignored.\r
   All conversions are left justified in Buffer.\r
   If Width is 0, PREFIX_ZERO is ignored in Flags.\r
   If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas\r
   are inserted every 3rd digit starting from the right.\r
-  If RADIX_HEX is set in Flags, then the output buffer will be \r
+  If RADIX_HEX is set in Flags, then the output buffer will be\r
   formatted in hexadecimal format.\r
   If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.\r
-  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, \r
-  then Buffer is padded with '0' characters so the combination of the optional '-' \r
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,\r
+  then Buffer is padded with '0' characters so the combination of the optional '-'\r
   sign character, '0' characters, digit characters for Value, and the Null-terminator\r
   add up to Width characters.\r
-  \r
+\r
   If Buffer is NULL, then ASSERT().\r
   If unsupported bits are set in Flags, then ASSERT().\r
   If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().\r
@@ -1029,7 +1111,7 @@ AsciiSPrintUnicodeFormat (
   @param  Value   The 64-bit signed value to convert to a string.\r
   @param  Width   The maximum number of ASCII characters to place in Buffer, not including\r
                   the Null-terminator.\r
-  \r
+\r
   @return The number of ASCII characters in Buffer not including the Null-terminator.\r
 \r
 **/\r
@@ -1042,7 +1124,85 @@ AsciiValueToString (
   IN  UINTN      Width\r
   )\r
 {\r
-  return mPrint2Protocol->AsciiValueToString (Buffer, Flags, Value, Width);\r
+  RETURN_STATUS  Status;\r
+  UINTN          BufferSize;\r
+\r
+  if (Width == 0) {\r
+    BufferSize = (MAXIMUM_VALUE_CHARACTERS + 1) * sizeof (CHAR8);\r
+  } else {\r
+    BufferSize = (Width + 1) * sizeof (CHAR8);\r
+  }\r
+\r
+  Status = mPrint2SProtocol->AsciiValueToStringS (Buffer, BufferSize, Flags, Value, Width);\r
+  if (RETURN_ERROR (Status)) {\r
+    return 0;\r
+  }\r
+\r
+  return AsciiStrnLenS (Buffer, BufferSize / sizeof (CHAR8));\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+  Converts a decimal value to a Null-terminated Ascii string.\r
+\r
+  Converts the decimal number specified by Value to a Null-terminated Ascii\r
+  string specified by Buffer containing at most Width characters. No padding of\r
+  spaces is ever performed. If Width is 0 then a width of\r
+  MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than\r
+  Width characters, then only the first Width characters are placed in Buffer.\r
+  Additional conversion parameters are specified in Flags.\r
+\r
+  The Flags bit LEFT_JUSTIFY is always ignored.\r
+  All conversions are left justified in Buffer.\r
+  If Width is 0, PREFIX_ZERO is ignored in Flags.\r
+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and\r
+  commas are inserted every 3rd digit starting from the right.\r
+  If RADIX_HEX is set in Flags, then the output buffer will be formatted in\r
+  hexadecimal format.\r
+  If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in\r
+  Buffer is a '-'.\r
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then\r
+  Buffer is padded with '0' characters so the combination of the optional '-'\r
+  sign character, '0' characters, digit characters for Value, and the\r
+  Null-terminator add up to Width characters.\r
+\r
+  If an error would be returned, then the function will ASSERT().\r
+\r
+  @param  Buffer      The pointer to the output buffer for the produced\r
+                      Null-terminated Ascii string.\r
+  @param  BufferSize  The size of Buffer in bytes, including the\r
+                      Null-terminator.\r
+  @param  Flags       The bitmask of flags that specify left justification,\r
+                      zero pad, and commas.\r
+  @param  Value       The 64-bit signed value to convert to a string.\r
+  @param  Width       The maximum number of Ascii characters to place in\r
+                      Buffer, not including the Null-terminator.\r
+\r
+  @retval RETURN_SUCCESS           The decimal value is converted.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If BufferSize cannot hold the converted\r
+                                   value.\r
+  @retval RETURN_INVALID_PARAMETER If Buffer is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not\r
+                                   zero, and BufferSize is greater than\r
+                                   PcdMaximumAsciiStringLength.\r
+                                   If unsupported bits are set in Flags.\r
+                                   If both COMMA_TYPE and RADIX_HEX are set in\r
+                                   Flags.\r
+                                   If Width >= MAXIMUM_VALUE_CHARACTERS.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiValueToStringS (\r
+  IN OUT CHAR8   *Buffer,\r
+  IN UINTN       BufferSize,\r
+  IN UINTN       Flags,\r
+  IN INT64       Value,\r
+  IN UINTN       Width\r
+  )\r
+{\r
+  return mPrint2SProtocol->AsciiValueToStringS (Buffer, BufferSize, Flags, Value, Width);\r
 }\r
 \r
 #define PREFIX_SIGN           BIT1\r
@@ -1090,8 +1250,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','
 **/\r
 CHAR8 *\r
 InternalPrintLibValueToString (\r
-  IN OUT CHAR8  *Buffer, \r
-  IN INT64      Value, \r
+  IN OUT CHAR8  *Buffer,\r
+  IN INT64      Value,\r
   IN UINTN      Radix\r
   )\r
 {\r
@@ -1113,21 +1273,21 @@ InternalPrintLibValueToString (
 }\r
 \r
 /**\r
-  Worker function that produces a Null-terminated string in an output buffer \r
+  Worker function that produces a Null-terminated string in an output buffer\r
   based on a Null-terminated format string and a VA_LIST argument list.\r
 \r
-  VSPrint function to process format and place the results in Buffer. Since a \r
-  VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
+  VSPrint function to process format and place the results in Buffer. Since a\r
+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus\r
   this is the main print working routine.\r
 \r
   If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.\r
 \r
-  @param[out] Buffer          The character buffer to print the results of the \r
+  @param[out] Buffer          The character buffer to print the results of the\r
                               parsing of Format into.\r
-  @param[in]  BufferSize      The maximum number of characters to put into \r
+  @param[in]  BufferSize      The maximum number of characters to put into\r
                               buffer.\r
   @param[in]  Flags           Initial flags value.\r
-                              Can only have FORMAT_UNICODE, OUTPUT_UNICODE, \r
+                              Can only have FORMAT_UNICODE, OUTPUT_UNICODE,\r
                               and COUNT_ONLY_NO_PRINT set.\r
   @param[in]  Format          A Null-terminated format string.\r
   @param[in]  VaListMarker    VA_LIST style variable argument list consumed by\r
@@ -1151,11 +1311,11 @@ InternalPrintLibSPrintMarker (
   );\r
 \r
 /**\r
-  Worker function that produces a Null-terminated string in an output buffer \r
+  Worker function that produces a Null-terminated string in an output buffer\r
   based on a Null-terminated format string and variable argument list.\r
 \r
-  VSPrint function to process format and place the results in Buffer. Since a \r
-  VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
+  VSPrint function to process format and place the results in Buffer. Since a\r
+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus\r
   this is the main print working routine\r
 \r
   @param  StartOfBuffer The character buffer to print the results of the parsing\r
@@ -1241,7 +1401,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * CONST mStatusString[] = {
 \r
   @param  Buffer      The buffer to place the Unicode or ASCII string.\r
   @param  EndBuffer   The end of the input Buffer. No characters will be\r
-                      placed after that. \r
+                      placed after that.\r
   @param  Length      The count of character to be placed into Buffer.\r
                       (Negative value indicates no buffer fill.)\r
   @param  Character   The character to be placed into Buffer.\r
@@ -1260,7 +1420,7 @@ InternalPrintLibFillBuffer (
   )\r
 {\r
   INTN  Index;\r
-  \r
+\r
   for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {\r
     *Buffer = (CHAR8) Character;\r
     if (Increment != 1) {\r
@@ -1273,21 +1433,21 @@ InternalPrintLibFillBuffer (
 }\r
 \r
 /**\r
-  Worker function that produces a Null-terminated string in an output buffer \r
+  Worker function that produces a Null-terminated string in an output buffer\r
   based on a Null-terminated format string and a VA_LIST argument list.\r
 \r
-  VSPrint function to process format and place the results in Buffer. Since a \r
-  VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
+  VSPrint function to process format and place the results in Buffer. Since a\r
+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus\r
   this is the main print working routine.\r
 \r
   If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.\r
 \r
-  @param[out] Buffer          The character buffer to print the results of the \r
+  @param[out] Buffer          The character buffer to print the results of the\r
                               parsing of Format into.\r
-  @param[in]  BufferSize      The maximum number of characters to put into \r
+  @param[in]  BufferSize      The maximum number of characters to put into\r
                               buffer.\r
   @param[in]  Flags           Initial flags value.\r
-                              Can only have FORMAT_UNICODE, OUTPUT_UNICODE, \r
+                              Can only have FORMAT_UNICODE, OUTPUT_UNICODE,\r
                               and COUNT_ONLY_NO_PRINT set.\r
   @param[in]  Format          A Null-terminated format string.\r
   @param[in]  VaListMarker    VA_LIST style variable argument list consumed by\r
@@ -1343,7 +1503,7 @@ InternalPrintLibSPrintMarker (
 \r
   //\r
   // If you change this code be sure to match the 2 versions of this function.\r
-  // Nearly identical logic is found in the BasePrintLib and \r
+  // Nearly identical logic is found in the BasePrintLib and\r
   // DxePrintLibPrint2Protocol (both PrintLib instances).\r
   //\r
 \r
@@ -1430,7 +1590,7 @@ InternalPrintLibSPrintMarker (
   //\r
   // Get the first character from the format string\r
   //\r
-  FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+  FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
 \r
   //\r
   // Loop until the end of the format string is reached or the output buffer is full\r
@@ -1462,26 +1622,26 @@ InternalPrintLibSPrintMarker (
       //\r
       for (Done = FALSE; !Done; ) {\r
         Format += BytesPerFormatCharacter;\r
-        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+        FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
         switch (FormatCharacter) {\r
-        case '.': \r
-          Flags |= PRECISION; \r
+        case '.':\r
+          Flags |= PRECISION;\r
           break;\r
-        case '-': \r
-          Flags |= LEFT_JUSTIFY; \r
+        case '-':\r
+          Flags |= LEFT_JUSTIFY;\r
           break;\r
-        case '+': \r
-          Flags |= PREFIX_SIGN;  \r
+        case '+':\r
+          Flags |= PREFIX_SIGN;\r
           break;\r
-        case ' ': \r
-          Flags |= PREFIX_BLANK; \r
+        case ' ':\r
+          Flags |= PREFIX_BLANK;\r
           break;\r
-        case ',': \r
-          Flags |= COMMA_TYPE; \r
+        case ',':\r
+          Flags |= COMMA_TYPE;\r
           break;\r
         case 'L':\r
-        case 'l': \r
-          Flags |= LONG_TYPE;    \r
+        case 'l':\r
+          Flags |= LONG_TYPE;\r
           break;\r
         case '*':\r
           if ((Flags & PRECISION) == 0) {\r
@@ -1515,7 +1675,7 @@ InternalPrintLibSPrintMarker (
           for (Count = 0; ((FormatCharacter >= '0') &&  (FormatCharacter <= '9')); ){\r
             Count = (Count * 10) + FormatCharacter - '0';\r
             Format += BytesPerFormatCharacter;\r
-            FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+            FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
           }\r
           Format -= BytesPerFormatCharacter;\r
           if ((Flags & PRECISION) == 0) {\r
@@ -1525,11 +1685,11 @@ InternalPrintLibSPrintMarker (
             Precision = Count;\r
           }\r
           break;\r
-       \r
+\r
         case '\0':\r
           //\r
           // Make no output if Format string terminates unexpectedly when\r
-          // looking up for flag, width, precision and type. \r
+          // looking up for flag, width, precision and type.\r
           //\r
           Format   -= BytesPerFormatCharacter;\r
           Precision = 0;\r
@@ -1540,7 +1700,7 @@ InternalPrintLibSPrintMarker (
           Done = TRUE;\r
           break;\r
         }\r
-      } \r
+      }\r
 \r
       //\r
       // Handle each argument type\r
@@ -1580,9 +1740,9 @@ InternalPrintLibSPrintMarker (
           //\r
           // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
           // This assumption is made so the format string definition is compatible with the ANSI C\r
-          // Specification for formatted strings.  It is recommended that the Base Types be used \r
-          // everywhere, but in this one case, compliance with ANSI C is more important, and \r
-          // provides an implementation that is compatible with that largest possible set of CPU \r
+          // Specification for formatted strings.  It is recommended that the Base Types be used\r
+          // everywhere, but in this one case, compliance with ANSI C is more important, and\r
+          // provides an implementation that is compatible with that largest possible set of CPU\r
           // architectures.  This is why the type "int" is used in this one case.\r
           //\r
           if (BaseListMarker == NULL) {\r
@@ -1620,9 +1780,9 @@ InternalPrintLibSPrintMarker (
             //\r
             // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
             // This assumption is made so the format string definition is compatible with the ANSI C\r
-            // Specification for formatted strings.  It is recommended that the Base Types be used \r
-            // everywhere, but in this one case, compliance with ANSI C is more important, and \r
-            // provides an implementation that is compatible with that largest possible set of CPU \r
+            // Specification for formatted strings.  It is recommended that the Base Types be used\r
+            // everywhere, but in this one case, compliance with ANSI C is more important, and\r
+            // provides an implementation that is compatible with that largest possible set of CPU\r
             // architectures.  This is why the type "unsigned int" is used in this one case.\r
             //\r
             Value = (unsigned int)Value;\r
@@ -1634,9 +1794,9 @@ InternalPrintLibSPrintMarker (
             //\r
             // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
             // This assumption is made so the format string definition is compatible with the ANSI C\r
-            // Specification for formatted strings.  It is recommended that the Base Types be used \r
-            // everywhere, but in this one case, compliance with ANSI C is more important, and \r
-            // provides an implementation that is compatible with that largest possible set of CPU \r
+            // Specification for formatted strings.  It is recommended that the Base Types be used\r
+            // everywhere, but in this one case, compliance with ANSI C is more important, and\r
+            // provides an implementation that is compatible with that largest possible set of CPU\r
             // architectures.  This is why the type "unsigned int" is used in this one case.\r
             //\r
             Value = (unsigned int)Value;\r
@@ -1650,7 +1810,7 @@ InternalPrintLibSPrintMarker (
           Count = 0;\r
         }\r
         ArgumentString = (CHAR8 *)ValueBuffer + Count;\r
-        \r
+\r
         Digits = Count % 3;\r
         if (Digits != 0) {\r
           Digits = 3 - Digits;\r
@@ -1723,7 +1883,7 @@ InternalPrintLibSPrintMarker (
           GuidData3 = ReadUnaligned16 (&(TmpGuid->Data3));\r
           InternalPrintLibSPrint (\r
             ValueBuffer,\r
-            MAXIMUM_VALUE_CHARACTERS, \r
+            MAXIMUM_VALUE_CHARACTERS,\r
             0,\r
             "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
             GuidData1,\r
@@ -1744,9 +1904,9 @@ InternalPrintLibSPrintMarker (
 \r
       case 't':\r
         if (BaseListMarker == NULL) {\r
-          TmpTime = VA_ARG (VaListMarker, TIME *); \r
+          TmpTime = VA_ARG (VaListMarker, TIME *);\r
         } else {\r
-          TmpTime = BASE_ARG (BaseListMarker, TIME *); \r
+          TmpTime = BASE_ARG (BaseListMarker, TIME *);\r
         }\r
         if (TmpTime == NULL) {\r
           ArgumentString = "<null time>";\r
@@ -1794,7 +1954,7 @@ InternalPrintLibSPrintMarker (
 \r
       case '\r':\r
         Format += BytesPerFormatCharacter;\r
-        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+        FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
         if (FormatCharacter == '\n') {\r
           //\r
           // Translate '\r\n' to '\r\n'\r
@@ -1815,7 +1975,7 @@ InternalPrintLibSPrintMarker (
         //\r
         ArgumentString = "\r\n";\r
         Format += BytesPerFormatCharacter;\r
-        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+        FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
         if (FormatCharacter != '\r') {\r
           Format   -= BytesPerFormatCharacter;\r
         }\r
@@ -1831,10 +1991,10 @@ InternalPrintLibSPrintMarker (
         break;\r
       }\r
       break;\r
\r
+\r
     case '\r':\r
       Format += BytesPerFormatCharacter;\r
-      FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+      FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
       if (FormatCharacter == '\n') {\r
         //\r
         // Translate '\r\n' to '\r\n'\r
@@ -1855,7 +2015,7 @@ InternalPrintLibSPrintMarker (
       //\r
       ArgumentString = "\r\n";\r
       Format += BytesPerFormatCharacter;\r
-      FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+      FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
       if (FormatCharacter != '\r') {\r
         Format   -= BytesPerFormatCharacter;\r
       }\r
@@ -1884,7 +2044,12 @@ InternalPrintLibSPrintMarker (
       // Compute the number of characters in ArgumentString and store it in Count\r
       // ArgumentString is either null-terminated, or it contains Precision characters\r
       //\r
-      for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {\r
+      for (Count = 0;\r
+            (ArgumentString[Count * BytesPerArgumentCharacter] != '\0' ||\r
+             (BytesPerArgumentCharacter > 1 &&\r
+              ArgumentString[Count * BytesPerArgumentCharacter + 1]!= '\0')) &&\r
+            (Count < Precision || ((Flags & PRECISION) == 0));\r
+            Count++) {\r
         ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;\r
         if (ArgumentCharacter == 0) {\r
           break;\r
@@ -1941,8 +2106,10 @@ InternalPrintLibSPrintMarker (
     //\r
     // Copy the string into the output buffer performing the required type conversions\r
     //\r
-    while (Index < Count) {\r
-      ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;\r
+    while (Index < Count &&\r
+           (ArgumentString[0] != '\0' ||\r
+            (BytesPerArgumentCharacter > 1 && ArgumentString[1] != '\0'))) {\r
+      ArgumentCharacter = ((*ArgumentString & 0xff) | (((UINT8)*(ArgumentString + 1)) << 8)) & ArgumentMask;\r
 \r
       LengthToReturn += (1 * BytesPerOutputCharacter);\r
       if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
@@ -1983,7 +2150,7 @@ InternalPrintLibSPrintMarker (
     //\r
     // Get the next character from the format string\r
     //\r
-    FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
+    FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;\r
   }\r
 \r
   if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {\r
@@ -2000,7 +2167,7 @@ InternalPrintLibSPrintMarker (
 }\r
 \r
 /**\r
-  Returns the number of characters that would be produced by if the formatted \r
+  Returns the number of characters that would be produced by if the formatted\r
   output were produced not including the Null-terminator.\r
 \r
   If FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
@@ -2013,7 +2180,7 @@ InternalPrintLibSPrintMarker (
   @param[in]  FormatString    A Null-terminated Unicode format string.\r
   @param[in]  Marker          VA_LIST marker for the variable argument list.\r
 \r
-  @return The number of characters that would be produced, not including the \r
+  @return The number of characters that would be produced, not including the\r
           Null-terminator.\r
 **/\r
 UINTN\r
@@ -2028,7 +2195,7 @@ SPrintLength (
 }\r
 \r
 /**\r
-  Returns the number of characters that would be produced by if the formatted \r
+  Returns the number of characters that would be produced by if the formatted\r
   output were produced not including the Null-terminator.\r
 \r
   If FormatString is NULL, then ASSERT() and 0 is returned.\r
@@ -2039,7 +2206,7 @@ SPrintLength (
   @param[in]  FormatString    A Null-terminated ASCII format string.\r
   @param[in]  Marker          VA_LIST marker for the variable argument list.\r
 \r
-  @return The number of characters that would be produced, not including the \r
+  @return The number of characters that would be produced, not including the\r
           Null-terminator.\r
 **/\r
 UINTN\r