]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/SafeString.c
MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
index f80db9f780d204eaf19d33aecb4e5a3b80baa4db..cf6f3e9eb90a3acfb079d5807306e3d0ef44c8ef 100644 (file)
 \r
 **/\r
 \r
-#include <Base.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/BaseLib.h>\r
+#include "BaseLibInternals.h"\r
 \r
 #define RSIZE_MAX  (PcdGet32 (PcdMaximumUnicodeStringLength))\r
 \r
@@ -131,9 +128,9 @@ StrnLenS (
   ASSERT (((UINTN) String & BIT0) == 0);\r
 \r
   //\r
-  // If String is a null pointer, then the StrnLenS function returns zero.\r
+  // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.\r
   //\r
-  if (String == NULL) {\r
+  if ((String == NULL) || (MaxSize == 0)) {\r
     return 0;\r
   }\r
 \r
@@ -585,281 +582,1386 @@ StrnCatS (
 }\r
 \r
 /**\r
-  Returns the length of a Null-terminated Ascii string.\r
-\r
-  This function is similar as strlen_s defined in C11.\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
+  Convert a Null-terminated Unicode decimal string to a value of type UINTN.\r
+\r
+  This function outputs a value of type UINTN by interpreting the contents of\r
+  the Unicode string specified by String as a decimal number. The format of the\r
+  input Unicode string String is:\r
+\r
+                  [spaces] [decimal digits].\r
+\r
+  The valid decimal digit character is in the range [0-9]. The function will\r
+  ignore the pad space, which includes spaces or tab characters, before\r
+  [decimal digits]. The running zero in the beginning of [decimal digits] will\r
+  be ignored. Then, the function stops at the first character that is a not a\r
+  valid decimal character or a Null-terminator, whichever one comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid decimal digits in the above format, then 0 is stored\r
+  at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINTN, then\r
+  MAX_UINTN is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  decimal digits right after the optional pad spaces, the value of String is\r
+  stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not\r
+                                   zero, and String contains more than\r
+                                   PcdMaximumUnicodeStringLength Unicode\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINTN.\r
 \r
 **/\r
-UINTN\r
+RETURN_STATUS\r
 EFIAPI\r
-AsciiStrnLenS (\r
-  IN CONST CHAR8               *String,\r
-  IN UINTN                     MaxSize\r
+StrDecimalToUintnS (\r
+  IN  CONST CHAR16             *String,\r
+  OUT       CHAR16             **EndPointer,  OPTIONAL\r
+  OUT       UINTN              *Data\r
   )\r
 {\r
-  UINTN                             Length;\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
 \r
   //\r
-  // If String is a null pointer, then the AsciiStrnLenS function returns zero.\r
+  // 1. Neither String nor Data shall be a null pointer.\r
   //\r
-  if (String == NULL) {\r
-    return 0;\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. The length of String shall not be greater than RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\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
+  // Ignore the pad spaces (space or tab)\r
   //\r
-  Length = 0;\r
-  while (String[Length] != 0) {\r
-    if (Length >= MaxSize - 1) {\r
-      return MaxSize;\r
-    }\r
-    Length++;\r
+  while ((*String == L' ') || (*String == L'\t')) {\r
+    String++;\r
   }\r
-  return Length;\r
-}\r
 \r
-/**\r
-  Returns the size of a Null-terminated Ascii string in bytes, including the\r
-  Null terminator.\r
+  //\r
+  // Ignore leading Zeros after the spaces\r
+  //\r
+  while (*String == L'0') {\r
+    String++;\r
+  }\r
 \r
-  This function returns the size of the Null-terminated Ascii string specified\r
-  by String in bytes, including the Null terminator.\r
+  *Data = 0;\r
 \r
-  @param  String   A pointer to a Null-terminated Ascii string.\r
-  @param  MaxSize  The maximum number of Destination Ascii\r
-                   char, including the Null terminator.\r
+  while (InternalIsDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINTN, then MAX_UINTN is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {\r
+      *Data = MAX_UINTN;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR16 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
 \r
-  @retval 0  If String is NULL.\r
-  @retval (sizeof (CHAR8) * (MaxSize + 1))\r
-             If there is no Null terminator in the first MaxSize characters of\r
-             String.\r
-  @return The size of the Null-terminated Ascii string in bytes, including the\r
-          Null terminator.\r
+    *Data = *Data * 10 + (*String - L'0');\r
+    String++;\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Unicode decimal string to a value of type UINT64.\r
+\r
+  This function outputs a value of type UINT64 by interpreting the contents of\r
+  the Unicode string specified by String as a decimal number. The format of the\r
+  input Unicode string String is:\r
+\r
+                  [spaces] [decimal digits].\r
+\r
+  The valid decimal digit character is in the range [0-9]. The function will\r
+  ignore the pad space, which includes spaces or tab characters, before\r
+  [decimal digits]. The running zero in the beginning of [decimal digits] will\r
+  be ignored. Then, the function stops at the first character that is a not a\r
+  valid decimal character or a Null-terminator, whichever one comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid decimal digits in the above format, then 0 is stored\r
+  at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINT64, then\r
+  MAX_UINT64 is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  decimal digits right after the optional pad spaces, the value of String is\r
+  stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not\r
+                                   zero, and String contains more than\r
+                                   PcdMaximumUnicodeStringLength Unicode\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINT64.\r
 \r
 **/\r
-UINTN\r
+RETURN_STATUS\r
 EFIAPI\r
-AsciiStrnSizeS (\r
-  IN CONST CHAR8               *String,\r
-  IN UINTN                     MaxSize\r
+StrDecimalToUint64S (\r
+  IN  CONST CHAR16             *String,\r
+  OUT       CHAR16             **EndPointer,  OPTIONAL\r
+  OUT       UINT64             *Data\r
   )\r
 {\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
   //\r
-  // If String is a null pointer, then the AsciiStrnSizeS function returns\r
-  // zero.\r
+  // 1. Neither String nor Data shall be a null pointer.\r
   //\r
-  if (String == NULL) {\r
-    return 0;\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. The length of String shall not be greater than RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\r
   }\r
 \r
   //\r
-  // Otherwise, the AsciiStrnSizeS function returns the size of the\r
-  // Null-terminated Ascii string in bytes, including the Null terminator. If\r
-  // there is no Null terminator in the first MaxSize characters of String,\r
-  // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a\r
-  // consistent map with the AsciiStrnLenS function.\r
+  // Ignore the pad spaces (space or tab)\r
   //\r
-  return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
-}\r
+  while ((*String == L' ') || (*String == L'\t')) {\r
+    String++;\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
+  // Ignore leading Zeros after the spaces\r
+  //\r
+  while (*String == L'0') {\r
+    String++;\r
+  }\r
 \r
-  This function is similar as strcpy_s defined in C11.\r
+  *Data = 0;\r
 \r
-  If an error would be returned, then the function will also ASSERT().\r
+  while (InternalIsDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {\r
+      *Data = MAX_UINT64;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR16 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
 \r
-  If an error is returned, then the Destination is unmodified.\r
+    *Data = MultU64x32 (*Data, 10) + (*String - L'0');\r
+    String++;\r
+  }\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
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Unicode hexadecimal string to a value of type\r
+  UINTN.\r
+\r
+  This function outputs a value of type UINTN by interpreting the contents of\r
+  the Unicode string specified by String as a hexadecimal number. The format of\r
+  the input Unicode string String is:\r
+\r
+                  [spaces][zeros][x][hexadecimal digits].\r
+\r
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
+  If "x" appears in the input string, it must be prefixed with at least one 0.\r
+  The function will ignore the pad space, which includes spaces or tab\r
+  characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
+  before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
+  after [x] or the first valid hexadecimal digit. Then, the function stops at\r
+  the first character that is a not a valid hexadecimal character or NULL,\r
+  whichever one comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid hexadecimal digits in the above format, then 0 is\r
+  stored at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINTN, then\r
+  MAX_UINTN is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  hexadecimal digits right after the optional pad spaces, the value of String\r
+  is stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not\r
+                                   zero, and String contains more than\r
+                                   PcdMaximumUnicodeStringLength Unicode\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINTN.\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
+StrHexToUintnS (\r
+  IN  CONST CHAR16             *String,\r
+  OUT       CHAR16             **EndPointer,  OPTIONAL\r
+  OUT       UINTN              *Data\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
+  ASSERT (((UINTN) String & BIT0) == 0);\r
 \r
   //\r
-  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
+  // 1. Neither String nor Data shall be a null pointer.\r
   //\r
-  if (ASCII_RSIZE_MAX != 0) {\r
-    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
-  }\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
 \r
   //\r
-  // 3. DestMax shall not equal zero.\r
+  // 2. The length of String shall not be greater than RSIZE_MAX.\r
   //\r
-  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\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
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\r
+  }\r
 \r
   //\r
-  // 5. Copying shall not take place between objects that overlap.\r
+  // Ignore the pad spaces (space or tab)\r
   //\r
-  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+  while ((*String == L' ') || (*String == L'\t')) {\r
+    String++;\r
+  }\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
+  // Ignore leading Zeros after the spaces\r
   //\r
-  while (*Source != 0) {\r
-    *(Destination++) = *(Source++);\r
+  while (*String == L'0') {\r
+    String++;\r
   }\r
-  *Destination = 0;\r
 \r
-  return RETURN_SUCCESS;\r
-}\r
+  if (InternalCharToUpper (*String) == L'X') {\r
+    if (*(String - 1) != L'0') {\r
+      *Data = 0;\r
+      return RETURN_SUCCESS;\r
+    }\r
+    //\r
+    // Skip the 'X'\r
+    //\r
+    String++;\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
+  *Data = 0;\r
 \r
-  This function is similar as strncpy_s defined in C11.\r
+  while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINTN, then MAX_UINTN is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {\r
+      *Data = MAX_UINTN;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR16 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
 \r
-  If an error would be returned, then the function will also ASSERT().\r
+    *Data = (*Data << 4) + InternalHexCharToUintn (*String);\r
+    String++;\r
+  }\r
 \r
-  If an error is returned, then the Destination is unmodified.\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\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
+  Convert a Null-terminated Unicode hexadecimal string to a value of type\r
+  UINT64.\r
+\r
+  This function outputs a value of type UINT64 by interpreting the contents of\r
+  the Unicode string specified by String as a hexadecimal number. The format of\r
+  the input Unicode string String is:\r
+\r
+                  [spaces][zeros][x][hexadecimal digits].\r
+\r
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
+  If "x" appears in the input string, it must be prefixed with at least one 0.\r
+  The function will ignore the pad space, which includes spaces or tab\r
+  characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
+  before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
+  after [x] or the first valid hexadecimal digit. Then, the function stops at\r
+  the first character that is a not a valid hexadecimal character or NULL,\r
+  whichever one comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid hexadecimal digits in the above format, then 0 is\r
+  stored at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINT64, then\r
+  MAX_UINT64 is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  hexadecimal digits right after the optional pad spaces, the value of String\r
+  is stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not\r
+                                   zero, and String contains more than\r
+                                   PcdMaximumUnicodeStringLength Unicode\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINT64.\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
+StrHexToUint64S (\r
+  IN  CONST CHAR16             *String,\r
+  OUT       CHAR16             **EndPointer,  OPTIONAL\r
+  OUT       UINT64             *Data\r
   )\r
 {\r
-  UINTN            SourceLen;\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
 \r
   //\r
-  // 1. Neither Destination nor Source shall be a null pointer.\r
+  // 1. Neither String nor Data 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
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
 \r
   //\r
-  // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX\r
+  // 2. The length of String shall not be greater than 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
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= 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
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\r
+  }\r
 \r
   //\r
-  // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
+  // Ignore the pad spaces (space or tab)\r
   //\r
-  SourceLen = AsciiStrnLenS (Source, DestMax);\r
-  if (Length >= DestMax) {\r
-    SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+  while ((*String == L' ') || (*String == L'\t')) {\r
+    String++;\r
   }\r
 \r
   //\r
-  // 5. Copying shall not take place between objects that overlap.\r
+  // Ignore leading Zeros after the spaces\r
   //\r
-  if (SourceLen > Length) {\r
-    SourceLen = Length;\r
+  while (*String == L'0') {\r
+    String++;\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
+  if (InternalCharToUpper (*String) == L'X') {\r
+    if (*(String - 1) != L'0') {\r
+      *Data = 0;\r
+      return RETURN_SUCCESS;\r
+    }\r
+    //\r
+    // Skip the 'X'\r
+    //\r
+    String++;\r
+  }\r
+\r
+  *Data = 0;\r
+\r
+  while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {\r
+      *Data = MAX_UINT64;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR16 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);\r
+    String++;\r
   }\r
-  *Destination = 0;\r
 \r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) String;\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
+  Convert a Null-terminated Unicode string to IPv6 address and prefix length.\r
 \r
-  This function is similar as strcat_s defined in C11.\r
+  This function outputs a value of type IPv6_ADDRESS and may output a value\r
+  of type UINT8 by interpreting the contents of the Unicode string specified\r
+  by String. The format of the input Unicode string String is as follows:\r
 \r
-  If an error would be returned, then the function will also ASSERT().\r
+                  X:X:X:X:X:X:X:X[/P]\r
 \r
-  If an error is returned, then the Destination is unmodified.\r
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
+  memory address and high byte is stored in high memory address. P contains decimal\r
+  digit characters in the range [0-9]. The running zero in the beginning of P will\r
+  be ignored. /P is optional.\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
+  When /P is not in the String, the function stops at the first character that is\r
+  not a valid hexadecimal digit character after eight X's are converted.\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
+  When /P is in the String, the function stops at the first character that is not\r
+  a valid decimal digit character after P is converted.\r
+\r
+  "::" can be used to compress one or more groups of X when X contains only 0.\r
+  The "::" can only appear once in the String.\r
+\r
+  If String is NULL, then ASSERT().\r
+\r
+  If Address is NULL, then ASSERT().\r
+\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If EndPointer is not NULL and Address is translated from String, a pointer\r
+  to the character that stopped the scan is stored at the location pointed to\r
+  by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Address                  Pointer to the converted IPv6 address.\r
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix\r
+                                   length. MAX_UINT8 is returned when /P is\r
+                                   not in the String.\r
+\r
+  @retval RETURN_SUCCESS           Address is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+  @retval RETURN_UNSUPPORTED       If X contains more than four hexadecimal\r
+                                    digit characters.\r
+                                   If String contains "::" and number of X\r
+                                    is not less than 8.\r
+                                   If P starts with character that is not a\r
+                                    valid decimal digit character.\r
+                                   If the decimal number converted from P\r
+                                    exceeds 128.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrToIpv6Address (\r
+  IN  CONST CHAR16       *String,\r
+  OUT CHAR16             **EndPointer, OPTIONAL\r
+  OUT IPv6_ADDRESS       *Address,\r
+  OUT UINT8              *PrefixLength OPTIONAL\r
+  )\r
+{\r
+  RETURN_STATUS          Status;\r
+  UINTN                  AddressIndex;\r
+  UINTN                  Uintn;\r
+  IPv6_ADDRESS           LocalAddress;\r
+  UINT8                  LocalPrefixLength;\r
+  CONST CHAR16           *Pointer;\r
+  CHAR16                 *End;\r
+  UINTN                  CompressStart;\r
+  BOOLEAN                ExpectPrefix;\r
+\r
+  LocalPrefixLength = MAX_UINT8;\r
+  CompressStart     = ARRAY_SIZE (Address->Addr);\r
+  ExpectPrefix      = FALSE;\r
+\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
+  //\r
+  // 1. None of String or Guid shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
+    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
+      if (*Pointer != L':') {\r
+        //\r
+        // ":" or "/" should be followed by digit characters.\r
+        //\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+\r
+      //\r
+      // Meet second ":" after previous ":" or "/"\r
+      // or meet first ":" in the beginning of String.\r
+      //\r
+      if (ExpectPrefix) {\r
+        //\r
+        // ":" shall not be after "/"\r
+        //\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+\r
+      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
+        //\r
+        // "::" can only appear once.\r
+        // "::" can only appear when address is not full length.\r
+        //\r
+        return RETURN_UNSUPPORTED;\r
+      } else {\r
+        //\r
+        // Remember the start of zero compressing.\r
+        //\r
+        CompressStart = AddressIndex;\r
+        Pointer++;\r
+\r
+        if (CompressStart == 0) {\r
+          if (*Pointer != L':') {\r
+            //\r
+            // Single ":" shall not be in the beginning of String.\r
+            //\r
+            return RETURN_UNSUPPORTED;\r
+          }\r
+          Pointer++;\r
+        }\r
+      }\r
+    }\r
+\r
+    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
+      if (*Pointer == L'/') {\r
+        //\r
+        // Might be optional "/P" after "::".\r
+        //\r
+        if (CompressStart != AddressIndex) {\r
+          return RETURN_UNSUPPORTED;\r
+        }\r
+      } else {\r
+        break;\r
+      }\r
+    } else {\r
+      if (!ExpectPrefix) {\r
+        //\r
+        // Get X.\r
+        //\r
+        Status = StrHexToUintnS (Pointer, &End, &Uintn);\r
+        if (RETURN_ERROR (Status) || End - Pointer > 4) {\r
+          //\r
+          // Number of hexadecimal digit characters is no more than 4.\r
+          //\r
+          return RETURN_UNSUPPORTED;\r
+        }\r
+        Pointer = End;\r
+        //\r
+        // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
+        //\r
+        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);\r
+        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;\r
+        AddressIndex += 2;\r
+      } else {\r
+        //\r
+        // Get P, then exit the loop.\r
+        //\r
+        Status = StrDecimalToUintnS (Pointer, &End, &Uintn);\r
+        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {\r
+          //\r
+          // Prefix length should not exceed 128.\r
+          //\r
+          return RETURN_UNSUPPORTED;\r
+        }\r
+        LocalPrefixLength = (UINT8) Uintn;\r
+        Pointer = End;\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Skip ':' or "/"\r
+    //\r
+    if (*Pointer == L'/') {\r
+      ExpectPrefix = TRUE;\r
+    } else if (*Pointer == L':') {\r
+      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
+        //\r
+        // Meet additional ":" after all 8 16-bit address\r
+        //\r
+        break;\r
+      }\r
+    } else {\r
+      //\r
+      // Meet other character that is not "/" or ":" after all 8 16-bit address\r
+      //\r
+      break;\r
+    }\r
+    Pointer++;\r
+  }\r
+\r
+  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||\r
+    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))\r
+      ) {\r
+    //\r
+    // Full length of address shall not have compressing zeros.\r
+    // Non-full length of address shall have compressing zeros.\r
+    //\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
+  ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
+  CopyMem (\r
+    &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
+    &LocalAddress.Addr[CompressStart],\r
+    AddressIndex - CompressStart\r
+    );\r
+\r
+  if (PrefixLength != NULL) {\r
+    *PrefixLength = LocalPrefixLength;\r
+  }\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR16 *) Pointer;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Unicode string to IPv4 address and prefix length.\r
+\r
+  This function outputs a value of type IPv4_ADDRESS and may output a value\r
+  of type UINT8 by interpreting the contents of the Unicode string specified\r
+  by String. The format of the input Unicode string String is as follows:\r
+\r
+                  D.D.D.D[/P]\r
+\r
+  D and P are decimal digit characters in the range [0-9]. The running zero in\r
+  the beginning of D and P will be ignored. /P is optional.\r
+\r
+  When /P is not in the String, the function stops at the first character that is\r
+  not a valid decimal digit character after four D's are converted.\r
+\r
+  When /P is in the String, the function stops at the first character that is not\r
+  a valid decimal digit character after P is converted.\r
+\r
+  If String is NULL, then ASSERT().\r
+\r
+  If Address is NULL, then ASSERT().\r
+\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If EndPointer is not NULL and Address is translated from String, a pointer\r
+  to the character that stopped the scan is stored at the location pointed to\r
+  by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Address                  Pointer to the converted IPv4 address.\r
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix\r
+                                   length. MAX_UINT8 is returned when /P is\r
+                                   not in the String.\r
+\r
+  @retval RETURN_SUCCESS           Address is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+  @retval RETURN_UNSUPPORTED       If String is not in the correct format.\r
+                                   If any decimal number converted from D\r
+                                    exceeds 255.\r
+                                   If the decimal number converted from P\r
+                                    exceeds 32.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrToIpv4Address (\r
+  IN  CONST CHAR16       *String,\r
+  OUT CHAR16             **EndPointer, OPTIONAL\r
+  OUT IPv4_ADDRESS       *Address,\r
+  OUT UINT8              *PrefixLength OPTIONAL\r
+  )\r
+{\r
+  RETURN_STATUS          Status;\r
+  UINTN                  AddressIndex;\r
+  UINTN                  Uintn;\r
+  IPv4_ADDRESS           LocalAddress;\r
+  UINT8                  LocalPrefixLength;\r
+  CHAR16                 *Pointer;\r
+\r
+  LocalPrefixLength = MAX_UINT8;\r
+\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
+  //\r
+  // 1. None of String or Guid shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
+    if (!InternalIsDecimalDigitCharacter (*Pointer)) {\r
+      //\r
+      // D or P contains invalid characters.\r
+      //\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Get D or P.\r
+    //\r
+    Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn);\r
+    if (RETURN_ERROR (Status)) {\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
+      //\r
+      // It's P.\r
+      //\r
+      if (Uintn > 32) {\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+      LocalPrefixLength = (UINT8) Uintn;\r
+    } else {\r
+      //\r
+      // It's D.\r
+      //\r
+      if (Uintn > MAX_UINT8) {\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;\r
+      AddressIndex++;\r
+    }\r
+\r
+    //\r
+    // Check the '.' or '/', depending on the AddressIndex.\r
+    //\r
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
+      if (*Pointer == L'/') {\r
+        //\r
+        // '/P' is in the String.\r
+        // Skip "/" and get P in next loop.\r
+        //\r
+        Pointer++;\r
+      } else {\r
+        //\r
+        // '/P' is not in the String.\r
+        //\r
+        break;\r
+      }\r
+    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
+      if (*Pointer == L'.') {\r
+        //\r
+        // D should be followed by '.'\r
+        //\r
+        Pointer++;\r
+      } else {\r
+        return RETURN_UNSUPPORTED;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  CopyMem (Address, &LocalAddress, sizeof (*Address));\r
+  if (PrefixLength != NULL) {\r
+    *PrefixLength = LocalPrefixLength;\r
+  }\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = Pointer;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Unicode GUID string to a value of type\r
+  EFI_GUID.\r
+\r
+  This function outputs a GUID value by interpreting the contents of\r
+  the Unicode string specified by String. The format of the input\r
+  Unicode string String consists of 36 characters, as follows:\r
+\r
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
+\r
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
+  [A-F], with each pair representing a single byte hexadecimal value.\r
+\r
+  The mapping between String and the EFI_GUID structure is as follows:\r
+                  aa          Data1[24:31]\r
+                  bb          Data1[16:23]\r
+                  cc          Data1[8:15]\r
+                  dd          Data1[0:7]\r
+                  ee          Data2[8:15]\r
+                  ff          Data2[0:7]\r
+                  gg          Data3[8:15]\r
+                  hh          Data3[0:7]\r
+                  ii          Data4[0:7]\r
+                  jj          Data4[8:15]\r
+                  kk          Data4[16:23]\r
+                  ll          Data4[24:31]\r
+                  mm          Data4[32:39]\r
+                  nn          Data4[40:47]\r
+                  oo          Data4[48:55]\r
+                  pp          Data4[56:63]\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Guid is NULL, then ASSERT().\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  Guid                     Pointer to the converted GUID.\r
+\r
+  @retval RETURN_SUCCESS           Guid is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+  @retval RETURN_UNSUPPORTED       If String is not as the above format.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrToGuid (\r
+  IN  CONST CHAR16       *String,\r
+  OUT GUID               *Guid\r
+  )\r
+{\r
+  RETURN_STATUS          Status;\r
+  GUID                   LocalGuid;\r
+\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
+  //\r
+  // 1. None of String or Guid shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // Get aabbccdd in big-endian.\r
+  //\r
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Convert big-endian to little-endian.\r
+  //\r
+  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
+  String += 2 * sizeof (LocalGuid.Data1) + 1;\r
+\r
+  //\r
+  // Get eeff in big-endian.\r
+  //\r
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Convert big-endian to little-endian.\r
+  //\r
+  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
+  String += 2 * sizeof (LocalGuid.Data2) + 1;\r
+\r
+  //\r
+  // Get gghh in big-endian.\r
+  //\r
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Convert big-endian to little-endian.\r
+  //\r
+  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
+  String += 2 * sizeof (LocalGuid.Data3) + 1;\r
+\r
+  //\r
+  // Get iijj.\r
+  //\r
+  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
+  if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+  String += 2 * 2 + 1;\r
+\r
+  //\r
+  // Get kkllmmnnoopp.\r
+  //\r
+  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
+  if (RETURN_ERROR (Status)) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  CopyGuid (Guid, &LocalGuid);\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Unicode hexadecimal string to a byte array.\r
+\r
+  This function outputs a byte array by interpreting the contents of\r
+  the Unicode string specified by String in hexadecimal format. The format of\r
+  the input Unicode string String is:\r
+\r
+                  [XX]*\r
+\r
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
+  The function decodes every two hexadecimal digit characters as one byte. The\r
+  decoding stops after Length of characters and outputs Buffer containing\r
+  (Length / 2) bytes.\r
+\r
+  If String is not aligned in a 16-bit boundary, then ASSERT().\r
+\r
+  If String is NULL, then ASSERT().\r
+\r
+  If Buffer is NULL, then ASSERT().\r
+\r
+  If Length is not multiple of 2, then ASSERT().\r
+\r
+  If PcdMaximumUnicodeStringLength is not zero and Length is greater than\r
+  PcdMaximumUnicodeStringLength, then ASSERT().\r
+\r
+  If MaxBufferSize is less than (Length / 2), then ASSERT().\r
+\r
+  @param  String                   Pointer to a Null-terminated Unicode string.\r
+  @param  Length                   The number of Unicode characters to decode.\r
+  @param  Buffer                   Pointer to the converted bytes array.\r
+  @param  MaxBufferSize            The maximum size of Buffer.\r
+\r
+  @retval RETURN_SUCCESS           Buffer is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If Length is not multiple of 2.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and Length is greater than\r
+                                    PcdMaximumUnicodeStringLength.\r
+  @retval RETURN_UNSUPPORTED       If Length of characters from String contain\r
+                                    a character that is not valid hexadecimal\r
+                                    digit characters, or a Null-terminator.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StrHexToBytes (\r
+  IN  CONST CHAR16       *String,\r
+  IN  UINTN              Length,\r
+  OUT UINT8              *Buffer,\r
+  IN  UINTN              MaxBufferSize\r
+  )\r
+{\r
+  UINTN                  Index;\r
+\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
+  //\r
+  // 1. None of String or Buffer shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Length shall not be greater than RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. Length shall not be odd.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 5. String shall not contains invalid hexadecimal digits.\r
+  //\r
+  for (Index = 0; Index < Length; Index++) {\r
+    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {\r
+      break;\r
+    }\r
+  }\r
+  if (Index != Length) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Convert the hex string to bytes.\r
+  //\r
+  for(Index = 0; Index < Length; Index++) {\r
+\r
+    //\r
+    // For even characters, write the upper nibble for each buffer byte,\r
+    // and for even characters, the lower nibble.\r
+    //\r
+    if ((Index & BIT0) == 0) {\r
+      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn (String[Index]) << 4;\r
+    } else {\r
+      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);\r
+    }\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns the length of a Null-terminated Ascii string.\r
+\r
+  This function is similar as strlen_s defined in C11.\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 or MaxSize is 0, then the AsciiStrnLenS function returns zero.\r
+  //\r
+  if ((String == NULL) || (MaxSize == 0)) {\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
+  Length = 0;\r
+  while (String[Length] != 0) {\r
+    if (Length >= MaxSize - 1) {\r
+      return MaxSize;\r
+    }\r
+    Length++;\r
+  }\r
+  return Length;\r
+}\r
+\r
+/**\r
+  Returns the size of a Null-terminated Ascii string in bytes, including the\r
+  Null terminator.\r
+\r
+  This function returns the size of the Null-terminated Ascii string specified\r
+  by String in bytes, including the Null terminator.\r
+\r
+  @param  String   A pointer to a Null-terminated Ascii string.\r
+  @param  MaxSize  The maximum number of Destination Ascii\r
+                   char, including the Null terminator.\r
+\r
+  @retval 0  If String is NULL.\r
+  @retval (sizeof (CHAR8) * (MaxSize + 1))\r
+             If there is no Null terminator in the first MaxSize characters of\r
+             String.\r
+  @return The size of the Null-terminated Ascii string in bytes, including the\r
+          Null terminator.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrnSizeS (\r
+  IN CONST CHAR8               *String,\r
+  IN UINTN                     MaxSize\r
+  )\r
+{\r
+  //\r
+  // If String is a null pointer, then the AsciiStrnSizeS function returns\r
+  // zero.\r
+  //\r
+  if (String == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Otherwise, the AsciiStrnSizeS function returns the size of the\r
+  // Null-terminated Ascii string in bytes, including the Null terminator. If\r
+  // there is no Null terminator in the first MaxSize characters of String,\r
+  // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a\r
+  // consistent map with the AsciiStrnLenS function.\r
+  //\r
+  return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);\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
+  This function is similar as strcpy_s defined in C11.\r
+\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  If an error is returned, then the Destination is unmodified.\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
+  This function is similar as strncpy_s defined in C11.\r
+\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  If an error is returned, then the Destination is unmodified.\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
+  This function is similar as strcat_s defined in C11.\r
+\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  If an error is returned, then the Destination is unmodified.\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
@@ -915,128 +2017,606 @@ AsciiStrCatS (
   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
 \r
   //\r
-  // 6. Copying shall not take place between objects that overlap.\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
+  This function is similar as strncat_s defined in C11.\r
+\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  If an error is returned, then the Destination is unmodified.\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
+\r
+/**\r
+  Convert a Null-terminated Ascii decimal string to a value of type UINTN.\r
+\r
+  This function outputs a value of type UINTN by interpreting the contents of\r
+  the Ascii string specified by String as a decimal number. The format of the\r
+  input Ascii string String is:\r
+\r
+                  [spaces] [decimal digits].\r
+\r
+  The valid decimal digit character is in the range [0-9]. The function will\r
+  ignore the pad space, which includes spaces or tab characters, before\r
+  [decimal digits]. The running zero in the beginning of [decimal digits] will\r
+  be ignored. Then, the function stops at the first character that is a not a\r
+  valid decimal character or a Null-terminator, whichever one comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
+  PcdMaximumAsciiStringLength Ascii characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid decimal digits in the above format, then 0 is stored\r
+  at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINTN, then\r
+  MAX_UINTN is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  decimal digits right after the optional pad spaces, the value of String is\r
+  stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Ascii string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                   and String contains more than\r
+                                   PcdMaximumAsciiStringLength Ascii\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINTN.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrDecimalToUintnS (\r
+  IN  CONST CHAR8              *String,\r
+  OUT       CHAR8              **EndPointer,  OPTIONAL\r
+  OUT       UINTN              *Data\r
+  )\r
+{\r
+  //\r
+  // 1. Neither String nor Data shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
+\r
+  //\r
+  // Ignore the pad spaces (space or tab)\r
+  //\r
+  while ((*String == ' ') || (*String == '\t')) {\r
+    String++;\r
+  }\r
+\r
+  //\r
+  // Ignore leading Zeros after the spaces\r
+  //\r
+  while (*String == '0') {\r
+    String++;\r
+  }\r
+\r
+  *Data = 0;\r
+\r
+  while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINTN, then MAX_UINTN is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {\r
+      *Data = MAX_UINTN;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR8 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    *Data = *Data * 10 + (*String - '0');\r
+    String++;\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Ascii decimal string to a value of type UINT64.\r
+\r
+  This function outputs a value of type UINT64 by interpreting the contents of\r
+  the Ascii string specified by String as a decimal number. The format of the\r
+  input Ascii string String is:\r
+\r
+                  [spaces] [decimal digits].\r
+\r
+  The valid decimal digit character is in the range [0-9]. The function will\r
+  ignore the pad space, which includes spaces or tab characters, before\r
+  [decimal digits]. The running zero in the beginning of [decimal digits] will\r
+  be ignored. Then, the function stops at the first character that is a not a\r
+  valid decimal character or a Null-terminator, whichever one comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
+  PcdMaximumAsciiStringLength Ascii characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid decimal digits in the above format, then 0 is stored\r
+  at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINT64, then\r
+  MAX_UINT64 is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  decimal digits right after the optional pad spaces, the value of String is\r
+  stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Ascii string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                   and String contains more than\r
+                                   PcdMaximumAsciiStringLength Ascii\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINT64.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrDecimalToUint64S (\r
+  IN  CONST CHAR8              *String,\r
+  OUT       CHAR8              **EndPointer,  OPTIONAL\r
+  OUT       UINT64             *Data\r
+  )\r
+{\r
+  //\r
+  // 1. Neither String nor Data shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
+\r
+  //\r
+  // Ignore the pad spaces (space or tab)\r
+  //\r
+  while ((*String == ' ') || (*String == '\t')) {\r
+    String++;\r
+  }\r
+\r
+  //\r
+  // Ignore leading Zeros after the spaces\r
+  //\r
+  while (*String == '0') {\r
+    String++;\r
+  }\r
+\r
+  *Data = 0;\r
+\r
+  while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {\r
+      *Data = MAX_UINT64;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR8 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    *Data = MultU64x32 (*Data, 10) + (*String - '0');\r
+    String++;\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.\r
+\r
+  This function outputs a value of type UINTN by interpreting the contents of\r
+  the Ascii string specified by String as a hexadecimal number. The format of\r
+  the input Ascii string String is:\r
+\r
+                  [spaces][zeros][x][hexadecimal digits].\r
+\r
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
+  "x" appears in the input string, it must be prefixed with at least one 0. The\r
+  function will ignore the pad space, which includes spaces or tab characters,\r
+  before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
+  [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
+  the first valid hexadecimal digit. Then, the function stops at the first\r
+  character that is a not a valid hexadecimal character or Null-terminator,\r
+  whichever on comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
+  PcdMaximumAsciiStringLength Ascii characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid hexadecimal digits in the above format, then 0 is\r
+  stored at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINTN, then\r
+  MAX_UINTN is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  hexadecimal digits right after the optional pad spaces, the value of String\r
+  is stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Ascii string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                   and String contains more than\r
+                                   PcdMaximumAsciiStringLength Ascii\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINTN.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrHexToUintnS (\r
+  IN  CONST CHAR8              *String,\r
+  OUT       CHAR8              **EndPointer,  OPTIONAL\r
+  OUT       UINTN              *Data\r
+  )\r
+{\r
+  //\r
+  // 1. Neither String nor Data shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
+\r
+  //\r
+  // Ignore the pad spaces (space or tab)\r
   //\r
-  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+  while ((*String == ' ') || (*String == '\t')) {\r
+    String++;\r
+  }\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
+  // Ignore leading Zeros after the spaces\r
   //\r
-  Destination = Destination + DestLen;\r
-  while (*Source != 0) {\r
-    *(Destination++) = *(Source++);\r
+  while (*String == '0') {\r
+    String++;\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
+  if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
+    if (*(String - 1) != '0') {\r
+      *Data = 0;\r
+      return RETURN_SUCCESS;\r
+    }\r
+    //\r
+    // Skip the 'X'\r
+    //\r
+    String++;\r
+  }\r
 \r
-  This function is similar as strncat_s defined in C11.\r
+  *Data = 0;\r
 \r
-  If an error would be returned, then the function will also ASSERT().\r
+  while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINTN, then MAX_UINTN is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {\r
+      *Data = MAX_UINTN;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR8 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
 \r
-  If an error is returned, then the Destination is unmodified.\r
+    *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);\r
+    String++;\r
+  }\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
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\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
+/**\r
+  Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.\r
+\r
+  This function outputs a value of type UINT64 by interpreting the contents of\r
+  the Ascii string specified by String as a hexadecimal number. The format of\r
+  the input Ascii string String is:\r
+\r
+                  [spaces][zeros][x][hexadecimal digits].\r
+\r
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
+  "x" appears in the input string, it must be prefixed with at least one 0. The\r
+  function will ignore the pad space, which includes spaces or tab characters,\r
+  before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
+  [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
+  the first valid hexadecimal digit. Then, the function stops at the first\r
+  character that is a not a valid hexadecimal character or Null-terminator,\r
+  whichever on comes first.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If Data is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
+  PcdMaximumAsciiStringLength Ascii characters, not including the\r
+  Null-terminator, then ASSERT().\r
+\r
+  If String has no valid hexadecimal digits in the above format, then 0 is\r
+  stored at the location pointed to by Data.\r
+  If the number represented by String exceeds the range defined by UINT64, then\r
+  MAX_UINT64 is stored at the location pointed to by Data.\r
+\r
+  If EndPointer is not NULL, a pointer to the character that stopped the scan\r
+  is stored at the location pointed to by EndPointer. If String has no valid\r
+  hexadecimal digits right after the optional pad spaces, the value of String\r
+  is stored at the location pointed to by EndPointer.\r
+\r
+  @param  String                   Pointer to a Null-terminated Ascii string.\r
+  @param  EndPointer               Pointer to character that stops scan.\r
+  @param  Data                     Pointer to the converted value.\r
+\r
+  @retval RETURN_SUCCESS           Value is translated from String.\r
+  @retval RETURN_INVALID_PARAMETER If String is NULL.\r
+                                   If Data 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
+                                   and String contains more than\r
+                                   PcdMaximumAsciiStringLength Ascii\r
+                                   characters, not including the\r
+                                   Null-terminator.\r
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds\r
+                                   the range defined by UINT64.\r
+\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
+AsciiStrHexToUint64S (\r
+  IN  CONST CHAR8              *String,\r
+  OUT       CHAR8              **EndPointer,  OPTIONAL\r
+  OUT       UINT64             *Data\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
+  // 1. Neither String nor Data 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
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
 \r
   //\r
-  // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.\r
+  // 2. The length of String 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
-    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= 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
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
 \r
   //\r
-  // 4. CopyLen shall not equal zero.\r
+  // Ignore the pad spaces (space or tab)\r
   //\r
-  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
+  while ((*String == ' ') || (*String == '\t')) {\r
+    String++;\r
+  }\r
 \r
   //\r
-  // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
+  // Ignore leading Zeros after the spaces\r
   //\r
-  SourceLen = AsciiStrnLenS (Source, CopyLen);\r
-  if (Length >= CopyLen) {\r
-    SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+  while (*String == '0') {\r
+    String++;\r
   }\r
 \r
-  //\r
-  // 6. Copying shall not take place between objects that overlap.\r
-  //\r
-  if (SourceLen > Length) {\r
-    SourceLen = Length;\r
+  if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
+    if (*(String - 1) != '0') {\r
+      *Data = 0;\r
+      return RETURN_SUCCESS;\r
+    }\r
+    //\r
+    // Skip the 'X'\r
+    //\r
+    String++;\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
+  *Data = 0;\r
+\r
+  while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
+    //\r
+    // If the number represented by String overflows according to the range\r
+    // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
+    // RETURN_UNSUPPORTED is returned.\r
+    //\r
+    if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {\r
+      *Data = MAX_UINT64;\r
+      if (EndPointer != NULL) {\r
+        *EndPointer = (CHAR8 *) String;\r
+      }\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+\r
+    *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);\r
+    String++;\r
   }\r
-  *Destination = 0;\r
 \r
+  if (EndPointer != NULL) {\r
+    *EndPointer = (CHAR8 *) String;\r
+  }\r
   return RETURN_SUCCESS;\r
 }\r
 \r
@@ -1141,6 +2721,128 @@ UnicodeStrToAsciiStrS (
   return RETURN_SUCCESS;\r
 }\r
 \r
+/**\r
+  Convert not more than Length successive characters from a Null-terminated\r
+  Unicode string to a Null-terminated Ascii string. If no null char is copied\r
+  from Source, then Destination[Length] is always set to null.\r
+\r
+  This function converts not more than Length successive characters from the\r
+  Unicode string Source to the Ascii string Destination by copying the lower 8\r
+  bits of each Unicode character. The function terminates the Ascii string\r
+  Destination by appending a Null-terminator character at the end.\r
+\r
+  The caller is responsible to make sure Destination points to a buffer with\r
+  size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))\r
+  in bytes.\r
+\r
+  If any Unicode characters in Source contain non-zero value in the upper 8\r
+  bits, then ASSERT().\r
+  If Source 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
+  If an error is returned, then Destination and DestinationLength are\r
+  unmodified.\r
+\r
+  @param  Source             The pointer to a Null-terminated Unicode string.\r
+  @param  Length             The maximum number of Unicode characters to\r
+                             convert.\r
+  @param  Destination        The pointer to a Null-terminated Ascii string.\r
+  @param  DestMax            The maximum number of Destination Ascii char,\r
+                             including terminating null char.\r
+  @param  DestinationLength  The number of Unicode characters converted.\r
+\r
+  @retval RETURN_SUCCESS            String is converted.\r
+  @retval RETURN_INVALID_PARAMETER  If Destination is NULL.\r
+                                    If Source is NULL.\r
+                                    If DestinationLength is NULL.\r
+                                    If PcdMaximumAsciiStringLength is not zero,\r
+                                    and Length or DestMax is greater than\r
+                                    PcdMaximumAsciiStringLength.\r
+                                    If PcdMaximumUnicodeStringLength is not\r
+                                    zero, and Length or DestMax is greater than\r
+                                    PcdMaximumUnicodeStringLength.\r
+                                    If DestMax is 0.\r
+  @retval RETURN_BUFFER_TOO_SMALL   If DestMax is NOT greater than\r
+                                    MIN(StrLen(Source), Length).\r
+  @retval RETURN_ACCESS_DENIED      If Source and Destination overlap.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UnicodeStrnToAsciiStrS (\r
+  IN      CONST CHAR16              *Source,\r
+  IN      UINTN                     Length,\r
+  OUT     CHAR8                     *Destination,\r
+  IN      UINTN                     DestMax,\r
+  OUT     UINTN                     *DestinationLength\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+\r
+  ASSERT (((UINTN) Source & BIT0) == 0);\r
+\r
+  //\r
+  // 1. None of Destination, Source or DestinationLength shall be a null\r
+  // pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
+  // RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\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. If Length is not less than DestMax, then DestMax shall be greater than\r
+  // 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 (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);\r
+\r
+  *DestinationLength = 0;\r
+\r
+  //\r
+  // Convert string\r
+  //\r
+  while ((*Source != 0) && (SourceLen > 0)) {\r
+    //\r
+    // If any Unicode characters in Source contain non-zero value in the upper\r
+    // 8 bits, then ASSERT().\r
+    //\r
+    ASSERT (*Source < 0x100);\r
+    *(Destination++) = (CHAR8) *(Source++);\r
+    SourceLen--;\r
+    (*DestinationLength)++;\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
 \r
 /**\r
   Convert one Null-terminated ASCII string to a Null-terminated\r
@@ -1233,3 +2935,118 @@ AsciiStrToUnicodeStrS (
 \r
   return RETURN_SUCCESS;\r
 }\r
+\r
+/**\r
+  Convert not more than Length successive characters from a Null-terminated\r
+  Ascii string to a Null-terminated Unicode string. If no null char is copied\r
+  from Source, then Destination[Length] is always set to null.\r
+\r
+  This function converts not more than Length successive characters from the\r
+  Ascii string Source to the Unicode string Destination. The function\r
+  terminates the Unicode string Destination by appending a Null-terminator\r
+  character at the end.\r
+\r
+  The caller is responsible to make sure Destination points to a buffer with\r
+  size not smaller than\r
+  ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.\r
+\r
+  If Destination 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
+  If an error is returned, then Destination and DestinationLength are\r
+  unmodified.\r
+\r
+  @param  Source             The pointer to a Null-terminated Ascii string.\r
+  @param  Length             The maximum number of Ascii characters to convert.\r
+  @param  Destination        The pointer to a Null-terminated Unicode string.\r
+  @param  DestMax            The maximum number of Destination Unicode char,\r
+                             including terminating null char.\r
+  @param  DestinationLength  The number of Ascii characters converted.\r
+\r
+  @retval RETURN_SUCCESS            String is converted.\r
+  @retval RETURN_INVALID_PARAMETER  If Destination is NULL.\r
+                                    If Source is NULL.\r
+                                    If DestinationLength is NULL.\r
+                                    If PcdMaximumUnicodeStringLength is not\r
+                                    zero, and Length or DestMax is greater than\r
+                                    PcdMaximumUnicodeStringLength.\r
+                                    If PcdMaximumAsciiStringLength is not zero,\r
+                                    and Length or DestMax is greater than\r
+                                    PcdMaximumAsciiStringLength.\r
+                                    If DestMax is 0.\r
+  @retval RETURN_BUFFER_TOO_SMALL   If DestMax is NOT greater than\r
+                                    MIN(AsciiStrLen(Source), Length).\r
+  @retval RETURN_ACCESS_DENIED      If Source and Destination overlap.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrnToUnicodeStrS (\r
+  IN      CONST CHAR8               *Source,\r
+  IN      UINTN                     Length,\r
+  OUT     CHAR16                    *Destination,\r
+  IN      UINTN                     DestMax,\r
+  OUT     UINTN                     *DestinationLength\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+\r
+  ASSERT (((UINTN) Destination & BIT0) == 0);\r
+\r
+  //\r
+  // 1. None of Destination, Source or DestinationLength shall be a null\r
+  // pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
+  // RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\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. If Length is not less than DestMax, then DestMax shall be greater than\r
+  // 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 (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  *DestinationLength = 0;\r
+\r
+  //\r
+  // Convert string\r
+  //\r
+  while ((*Source != 0) && (SourceLen > 0)) {\r
+    *(Destination++) = (CHAR16)*(Source++);\r
+    SourceLen--;\r
+    (*DestinationLength)++;\r
+  }\r
+  *Destination = 0;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r