Add safe string function to base lib.
authorjyao1 <jyao1@Edk2>
Fri, 7 Nov 2014 13:43:05 +0000 (13:43 +0000)
committerjyao1 <jyao1@Edk2>
Fri, 7 Nov 2014 13:43:05 +0000 (13:43 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0

signed off by: Yao, Jiewen <jiewen.yao@intel.com>
reviewed by: Ni, Ruiyu <ruiyu.ni@intel.com>
reviewed by: Long, Qin <qin.long@intel.com>
reviewed by: Kinney, Michael D <michael.d.kinney@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16312 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Include/Library/BaseLib.h
MdePkg/Library/BaseLib/BaseLib.inf
MdePkg/Library/BaseLib/SafeString.c [new file with mode: 0644]

index 23e3376..d65b01a 100644 (file)
@@ -2,7 +2,7 @@
   Provides string functions, linked list functions, math functions, synchronization\r
   functions, and CPU architecture-specific functions.\r
 \r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
 Portions copyright (c) 2008 - 2009, Apple Inc. 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
@@ -183,6 +183,304 @@ typedef struct {
 // String Services\r
 //\r
 \r
+\r
+/**\r
+  Returns the length of a Null-terminated Unicode string.\r
+\r
+  If String is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  String   A pointer to a Null-terminated Unicode string.\r
+  @param  MaxSize  The maximum number of Destination Unicode\r
+                   char, including terminating null char.\r
+\r
+  @retval 0        If String is NULL.\r
+  @retval MaxSize  If there is no null character in the first MaxSize characters of String.\r
+  @return The number of characters that percede the terminating null character.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrnLenS (\r
+  IN CONST CHAR16              *String,\r
+  IN UINTN                     MaxSize\r
+  );\r
+\r
+/**\r
+  Copies the string pointed to by Source (including the terminating null char)\r
+  to the array pointed to by Destination.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrCpyS (\r
+  OUT CHAR16       *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR16 *Source\r
+  );\r
+\r
+/**\r
+  Copies not more than Length successive char from the string pointed to by\r
+  Source to the array pointed to by Destination. If no null char is copied from\r
+  Source, then Destination[Length] is always set to null.\r
+\r
+  If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+  @param  Length                   The maximum number of Unicode characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than \r
+                                   MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrnCpyS (\r
+  OUT CHAR16       *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR16 *Source,\r
+  IN  UINTN        Length\r
+  );\r
+\r
+/**\r
+  Appends a copy of the string pointed to by Source (including the terminating\r
+  null char) to the end of the string pointed to by Destination.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than \r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrCatS (\r
+  IN OUT CHAR16       *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR16 *Source\r
+  );\r
+\r
+/**\r
+  Appends not more than Length successive char from the string pointed to by\r
+  Source to the end of the string pointed to by Destination. If no null char is\r
+  copied from Source, then Destination[StrLen(Destination) + Length] is always\r
+  set to null.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If and Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+  @param  Length                   The maximum number of Unicode characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than\r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrnCatS (\r
+  IN OUT CHAR16       *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR16 *Source,\r
+  IN     UINTN        Length\r
+  );\r
+\r
+/**\r
+  Returns the length of a Null-terminated Ascii string.\r
+\r
+  @param  String   A pointer to a Null-terminated Ascii string.\r
+  @param  MaxSize  The maximum number of Destination Ascii\r
+                   char, including terminating null char.\r
+\r
+  @retval 0        If String is NULL.\r
+  @retval MaxSize  If there is no null character in the first MaxSize characters of String.\r
+  @return The number of characters that percede the terminating null character.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrnLenS (\r
+  IN CONST CHAR8               *String,\r
+  IN UINTN                     MaxSize\r
+  );\r
+\r
+/**\r
+  Copies the string pointed to by Source (including the terminating null char)\r
+  to the array pointed to by Destination.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrCpyS (\r
+  OUT CHAR8        *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR8  *Source\r
+  );\r
+\r
+/**\r
+  Copies not more than Length successive char from the string pointed to by\r
+  Source to the array pointed to by Destination. If no null char is copied from\r
+  Source, then Destination[Length] is always set to null.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+  @param  Length                   The maximum number of Ascii characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than \r
+                                   MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrnCpyS (\r
+  OUT CHAR8        *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR8  *Source,\r
+  IN  UINTN        Length\r
+  );\r
+\r
+/**\r
+  Appends a copy of the string pointed to by Source (including the terminating\r
+  null char) to the end of the string pointed to by Destination.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than \r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrCatS (\r
+  IN OUT CHAR8        *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR8  *Source\r
+  );\r
+\r
+/**\r
+  Appends not more than Length successive char from the string pointed to by\r
+  Source to the end of the string pointed to by Destination. If no null char is\r
+  copied from Source, then Destination[StrLen(Destination) + Length] is always\r
+  set to null.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+  @param  Length                   The maximum number of Ascii characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than\r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrnCatS (\r
+  IN OUT CHAR8        *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR8  *Source,\r
+  IN     UINTN        Length\r
+  );\r
+\r
+\r
 /**\r
   Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
   string and returns the new Unicode string.\r
index 4c77762..6d03f94 100644 (file)
@@ -61,6 +61,7 @@
   CpuDeadLoop.c\r
   Cpu.c\r
   LinkedList.c\r
+  SafeString.c\r
   String.c\r
   BaseLibInternals.h\r
 \r
   gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength      ## SOMETIMES_CONSUMES\r
   gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength     ## SOMETIMES_CONSUMES\r
   gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength   ## SOMETIMES_CONSUMES\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask            ## SOMETIMES_CONSUMES\r
 \r
 [FeaturePcd]\r
   gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList  ## CONSUMES\r
diff --git a/MdePkg/Library/BaseLib/SafeString.c b/MdePkg/Library/BaseLib/SafeString.c
new file mode 100644 (file)
index 0000000..7d7765b
--- /dev/null
@@ -0,0 +1,896 @@
+/** @file\r
+  Safe String functions.\r
+\r
+  Copyright (c) 2014, 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
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/BaseLib.h>\r
+\r
+#define RSIZE_MAX  (PcdGet32 (PcdMaximumUnicodeStringLength))\r
+\r
+#define ASCII_RSIZE_MAX  (PcdGet32 (PcdMaximumAsciiStringLength))\r
+\r
+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status)  \\r
+  do { \\r
+    ASSERT (Expression); \\r
+    if (!(Expression)) { \\r
+      return Status; \\r
+    } \\r
+  } while (FALSE)\r
+\r
+/**\r
+  Returns if 2 memory blocks are overlapped.\r
+\r
+  @param  Base1  Base address of 1st memory block.\r
+  @param  Size1  Size of 1st memory block.\r
+  @param  Base2  Base address of 2nd memory block.\r
+  @param  Size2  Size of 2nd memory block.\r
+\r
+  @retval TRUE  2 memory blocks are overlapped.\r
+  @retval FALSE 2 memory blocks are not overlapped.\r
+**/\r
+BOOLEAN\r
+InternalSafeStringIsOverlap (\r
+  IN VOID    *Base1,\r
+  IN UINTN   Size1,\r
+  IN VOID    *Base2,\r
+  IN UINTN   Size2\r
+  )\r
+{\r
+  if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||\r
+      (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {\r
+    return TRUE;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Returns if 2 Unicode strings are not overlapped.\r
+\r
+  @param  Str1   Start address of 1st Unicode string.\r
+  @param  Size1  The number of char in 1st Unicode string,\r
+                 including terminating null char.\r
+  @param  Str2   Start address of 2nd Unicode string.\r
+  @param  Size2  The number of char in 2nd Unicode string,\r
+                 including terminating null char.\r
+\r
+  @retval TRUE  2 Unicode strings are NOT overlapped.\r
+  @retval FALSE 2 Unicode strings are overlapped.\r
+**/\r
+BOOLEAN\r
+InternalSafeStringNoStrOverlap (\r
+  IN CHAR16  *Str1,\r
+  IN UINTN   Size1,\r
+  IN CHAR16  *Str2,\r
+  IN UINTN   Size2\r
+  )\r
+{\r
+  return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));\r
+}\r
+\r
+/**\r
+  Returns if 2 Ascii strings are not overlapped.\r
+\r
+  @param  Str1   Start address of 1st Ascii string.\r
+  @param  Size1  The number of char in 1st Ascii string,\r
+                 including terminating null char.\r
+  @param  Str2   Start address of 2nd Ascii string.\r
+  @param  Size2  The number of char in 2nd Ascii string,\r
+                 including terminating null char.\r
+\r
+  @retval TRUE  2 Ascii strings are NOT overlapped.\r
+  @retval FALSE 2 Ascii strings are overlapped.\r
+**/\r
+BOOLEAN\r
+InternalSafeStringNoAsciiStrOverlap (\r
+  IN CHAR8   *Str1,\r
+  IN UINTN   Size1,\r
+  IN CHAR8   *Str2,\r
+  IN UINTN   Size2\r
+  )\r
+{\r
+  return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);\r
+}\r
+\r
+/**\r
+  Returns the length of a Null-terminated Unicode string.\r
+\r
+  If String is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  String   A pointer to a Null-terminated Unicode string.\r
+  @param  MaxSize  The maximum number of Destination Unicode\r
+                   char, including terminating null char.\r
+\r
+  @retval 0        If String is NULL.\r
+  @retval MaxSize  If there is no null character in the first MaxSize characters of String.\r
+  @return The number of characters that percede the terminating null character.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrnLenS (\r
+  IN CONST CHAR16              *String,\r
+  IN UINTN                     MaxSize\r
+  )\r
+{\r
+  UINTN                             Length;\r
+\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
+  //\r
+  // If String is a null pointer, then the StrnLenS function returns zero.\r
+  //\r
+  if (String == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Otherwise, the StrnLenS function returns the number of characters that precede the\r
+  // terminating null character. If there is no null character in the first MaxSize characters of\r
+  // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
+  // be accessed by StrnLenS.\r
+  //\r
+  for (Length = 0; (*String != 0) && (Length < MaxSize); String++, Length++) {\r
+    ;\r
+  }\r
+  return Length;\r
+}\r
+\r
+/**\r
+  Copies the string pointed to by Source (including the terminating null char)\r
+  to the array pointed to by Destination.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrCpyS (\r
+  OUT CHAR16       *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR16 *Source\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+  \r
+  ASSERT (((UINTN) Destination & BIT0) == 0);\r
+  ASSERT (((UINTN) Source & BIT0) == 0);\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. DestMax shall not be greater than RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. DestMax shall be greater than StrnLenS(Source, DestMax).\r
+  //\r
+  SourceLen = StrnLenS (Source, DestMax);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 5. Copying shall not take place between objects that overlap.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The StrCpyS function copies the string pointed to by Source (including the terminating\r
+  // null character) into the array pointed to by Destination.\r
+  //\r
+  while (*Source != 0) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Copies not more than Length successive char from the string pointed to by\r
+  Source to the array pointed to by Destination. If no null char is copied from\r
+  Source, then Destination[Length] is always set to null.\r
+\r
+  If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+  @param  Length                   The maximum number of Unicode characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than \r
+                                   MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrnCpyS (\r
+  OUT CHAR16       *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR16 *Source,\r
+  IN  UINTN        Length\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+\r
+  ASSERT (((UINTN) Destination & BIT0) == 0);\r
+  ASSERT (((UINTN) Source & BIT0) == 0);\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).\r
+  //\r
+  SourceLen = StrnLenS (Source, DestMax);\r
+  if (Length >= DestMax) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+  }\r
+\r
+  //\r
+  // 5. Copying shall not take place between objects that overlap.\r
+  //\r
+  if (SourceLen > Length) {\r
+    SourceLen = Length;\r
+  }\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The StrnCpyS function copies not more than Length successive characters (characters that\r
+  // follow a null character are not copied) from the array pointed to by Source to the array\r
+  // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
+  // character.\r
+  //\r
+  while ((*Source != 0) && (SourceLen > 0)) {\r
+    *(Destination++) = *(Source++);\r
+    SourceLen--;\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Appends a copy of the string pointed to by Source (including the terminating\r
+  null char) to the end of the string pointed to by Destination.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than \r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrCatS (\r
+  IN OUT CHAR16       *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR16 *Source\r
+  )\r
+{\r
+  UINTN               DestLen;\r
+  UINTN               CopyLen;\r
+  UINTN               SourceLen;\r
+  \r
+  ASSERT (((UINTN) Destination & BIT0) == 0);\r
+  ASSERT (((UINTN) Source & BIT0) == 0);\r
+\r
+  //\r
+  // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.\r
+  //\r
+  DestLen = StrnLenS (Destination, DestMax);\r
+  CopyLen = DestMax - DestLen;\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. DestMax shall not be greater than RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. CopyLen shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
+\r
+  //\r
+  // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
+  //\r
+  SourceLen = StrnLenS (Source, CopyLen);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 6. Copying shall not take place between objects that overlap.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The StrCatS function appends a copy of the string pointed to by Source (including the\r
+  // terminating null character) to the end of the string pointed to by Destination. The initial character\r
+  // from Source overwrites the null character at the end of Destination.\r
+  //\r
+  Destination = Destination + DestLen;\r
+  while (*Source != 0) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Appends not more than Length successive char from the string pointed to by\r
+  Source to the end of the string pointed to by Destination. If no null char is\r
+  copied from Source, then Destination[StrLen(Destination) + Length] is always\r
+  set to null.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If and Source is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  Destination              A pointer to a Null-terminated Unicode string.\r
+  @param  DestMax                  The maximum number of Destination Unicode\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Unicode string.\r
+  @param  Length                   The maximum number of Unicode characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than\r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrnCatS (\r
+  IN OUT CHAR16       *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR16 *Source,\r
+  IN     UINTN        Length\r
+  )\r
+{\r
+  UINTN               DestLen;\r
+  UINTN               CopyLen;\r
+  UINTN               SourceLen;\r
+  \r
+  ASSERT (((UINTN) Destination & BIT0) == 0);\r
+  ASSERT (((UINTN) Source & BIT0) == 0);\r
+\r
+  //\r
+  // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.\r
+  //\r
+  DestLen = StrnLenS (Destination, DestMax);\r
+  CopyLen = DestMax - DestLen;\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. CopyLen shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
+\r
+  //\r
+  // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
+  //\r
+  SourceLen = StrnLenS (Source, CopyLen);\r
+  if (Length >= CopyLen) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+  }\r
+\r
+  //\r
+  // 6. Copying shall not take place between objects that overlap.\r
+  //\r
+  if (SourceLen > Length) {\r
+    SourceLen = Length;\r
+  }\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The StrnCatS function appends not more than Length successive characters (characters\r
+  // that follow a null character are not copied) from the array pointed to by Source to the end of\r
+  // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
+  // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
+  // a null character.\r
+  //\r
+  Destination = Destination + DestLen;\r
+  while ((*Source != 0) && (SourceLen > 0)) {\r
+    *(Destination++) = *(Source++);\r
+    SourceLen--;\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns the length of a Null-terminated Ascii string.\r
+\r
+  @param  String   A pointer to a Null-terminated Ascii string.\r
+  @param  MaxSize  The maximum number of Destination Ascii\r
+                   char, including terminating null char.\r
+\r
+  @retval 0        If String is NULL.\r
+  @retval MaxSize  If there is no null character in the first MaxSize characters of String.\r
+  @return The number of characters that percede the terminating null character.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrnLenS (\r
+  IN CONST CHAR8               *String,\r
+  IN UINTN                     MaxSize\r
+  )\r
+{\r
+  UINTN                             Length;\r
+\r
+  //\r
+  // If String is a null pointer, then the AsciiStrnLenS function returns zero.\r
+  //\r
+  if (String == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the\r
+  // terminating null character. If there is no null character in the first MaxSize characters of\r
+  // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
+  // be accessed by AsciiStrnLenS.\r
+  //\r
+  for (Length = 0; (*String != 0) && (Length < MaxSize); String++, Length++) {\r
+    ;\r
+  }\r
+  return Length;\r
+}\r
+\r
+/**\r
+  Copies the string pointed to by Source (including the terminating null char)\r
+  to the array pointed to by Destination.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrCpyS (\r
+  OUT CHAR8        *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR8  *Source\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+  \r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
+  //\r
+  SourceLen = AsciiStrnLenS (Source, DestMax);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 5. Copying shall not take place between objects that overlap.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating\r
+  // null character) into the array pointed to by Destination.\r
+  //\r
+  while (*Source != 0) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Copies not more than Length successive char from the string pointed to by\r
+  Source to the array pointed to by Destination. If no null char is copied from\r
+  Source, then Destination[Length] is always set to null.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+  @param  Length                   The maximum number of Ascii characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is copied.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than \r
+                                   MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrnCpyS (\r
+  OUT CHAR8        *Destination,\r
+  IN  UINTN        DestMax,\r
+  IN  CONST CHAR8  *Source,\r
+  IN  UINTN        Length\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
+  //\r
+  SourceLen = AsciiStrnLenS (Source, DestMax);\r
+  if (Length >= DestMax) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+  }\r
+\r
+  //\r
+  // 5. Copying shall not take place between objects that overlap.\r
+  //\r
+  if (SourceLen > Length) {\r
+    SourceLen = Length;\r
+  }\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The AsciiStrnCpyS function copies not more than Length successive characters (characters that\r
+  // follow a null character are not copied) from the array pointed to by Source to the array\r
+  // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
+  // character.\r
+  //\r
+  while ((*Source != 0) && (SourceLen > 0)) {\r
+    *(Destination++) = *(Source++);\r
+    SourceLen--;\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Appends a copy of the string pointed to by Source (including the terminating\r
+  null char) to the end of the string pointed to by Destination.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than \r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrCatS (\r
+  IN OUT CHAR8        *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR8  *Source\r
+  )\r
+{\r
+  UINTN               DestLen;\r
+  UINTN               CopyLen;\r
+  UINTN               SourceLen;\r
+  \r
+  //\r
+  // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.\r
+  //\r
+  DestLen = AsciiStrnLenS (Destination, DestMax);\r
+  CopyLen = DestMax - DestLen;\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. CopyLen shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
+\r
+  //\r
+  // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
+  //\r
+  SourceLen = AsciiStrnLenS (Source, CopyLen);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 6. Copying shall not take place between objects that overlap.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the\r
+  // terminating null character) to the end of the string pointed to by Destination. The initial character\r
+  // from Source overwrites the null character at the end of Destination.\r
+  //\r
+  Destination = Destination + DestLen;\r
+  while (*Source != 0) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Appends not more than Length successive char from the string pointed to by\r
+  Source to the end of the string pointed to by Destination. If no null char is\r
+  copied from Source, then Destination[StrLen(Destination) + Length] is always\r
+  set to null.\r
+\r
+  @param  Destination              A pointer to a Null-terminated Ascii string.\r
+  @param  DestMax                  The maximum number of Destination Ascii\r
+                                   char, including terminating null char.\r
+  @param  Source                   A pointer to a Null-terminated Ascii string.\r
+  @param  Length                   The maximum number of Ascii characters to copy.\r
+\r
+  @retval RETURN_SUCCESS           String is appended.\r
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than\r
+                                   StrLen(Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT\r
+                                   greater than MIN(StrLen(Source), Length).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than \r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrnCatS (\r
+  IN OUT CHAR8        *Destination,\r
+  IN     UINTN        DestMax,\r
+  IN     CONST CHAR8  *Source,\r
+  IN     UINTN        Length\r
+  )\r
+{\r
+  UINTN               DestLen;\r
+  UINTN               CopyLen;\r
+  UINTN               SourceLen;\r
+  \r
+  //\r
+  // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.\r
+  //\r
+  DestLen = AsciiStrnLenS (Destination, DestMax);\r
+  CopyLen = DestMax - DestLen;\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. CopyLen shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
+\r
+  //\r
+  // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
+  //\r
+  SourceLen = AsciiStrnLenS (Source, CopyLen);\r
+  if (Length >= CopyLen) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+  }\r
+\r
+  //\r
+  // 6. Copying shall not take place between objects that overlap.\r
+  //\r
+  if (SourceLen > Length) {\r
+    SourceLen = Length;\r
+  }\r
+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // The AsciiStrnCatS function appends not more than Length successive characters (characters\r
+  // that follow a null character are not copied) from the array pointed to by Source to the end of\r
+  // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
+  // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
+  // a null character.\r
+  //\r
+  Destination = Destination + DestLen;\r
+  while ((*Source != 0) && (SourceLen > 0)) {\r
+    *(Destination++) = *(Source++);\r
+    SourceLen--;\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r