X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FLibrary%2FDxePrintLibPrint2Protocol%2FPrintLib.c;h=d22d4d5566488f5f6636085b5501bc7119eab60d;hp=3923f956cb4ea67853e30e4d41f3d0658749f92b;hb=504dcb0a4e04dd76db230cc55c4f95f7a911d127;hpb=bee675553c31877c58d825787232f76e4b0d1b33 diff --git a/MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c b/MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c index 3923f956cb..d22d4d5566 100644 --- a/MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c +++ b/MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c @@ -18,7 +18,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include + #include + +#include + +#include #include #include @@ -57,6 +62,166 @@ PrintLibConstructor ( } +/** + Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated + format string. + + @param AsciiFormat TRUE if Format is an ASCII string. FALSE if Format is a Unicode string. + @param Format Null-terminated format string. + @param VaListMarker VA_LIST style variable argument list consumed by processing Format. + @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format. + @param Size The size, in bytes, of the BaseListMarker buffer. + + @return The number of bytes in BaseListMarker. 0 if BaseListMarker is too small. + +**/ +BOOLEAN +DxePrintLibPrint2ProtocolVaListToBaseList ( + IN BOOLEAN AsciiFormat, + IN CONST CHAR8 *Format, + IN VA_LIST VaListMarker, + OUT BASE_LIST BaseListMarker, + IN UINTN Size + ) +{ + BASE_LIST BaseListStart; + UINTN BytesPerFormatCharacter; + UINTN FormatMask; + UINTN FormatCharacter; + BOOLEAN Long; + BOOLEAN Done; + + ASSERT (Format != NULL); + ASSERT (VaListMarker != NULL); + ASSERT (BaseListMarker != NULL); + + BaseListStart = BaseListMarker; + + if (AsciiFormat) { + ASSERT (AsciiStrSize (Format) != 0); + BytesPerFormatCharacter = 1; + FormatMask = 0xff; + } else { + ASSERT (StrSize ((CHAR16 *) Format) != 0); + BytesPerFormatCharacter = 2; + FormatMask = 0xffff; + } + + // + // Get the first character from the format string + // + FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; + + while (FormatCharacter != 0) { + if (FormatCharacter == '%') { + Long = FALSE; + + // + // Parse Flags and Width + // + for (Done = FALSE; !Done; ) { + // + // Get the next character from the format string + // + Format += BytesPerFormatCharacter; + + // + // Get the next character from the format string + // + FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; + + switch (FormatCharacter) { + case '.': + case '-': + case '+': + case ' ': + case ',': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + case 'L': + case 'l': + Long = TRUE; + break; + case '*': + BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN); + break; + case '\0': + // + // Make no output if Format string terminates unexpectedly when + // looking up for flag, width, precision and type. + // + Format -= BytesPerFormatCharacter; + // + // break skipped on purpose. + // + default: + Done = TRUE; + break; + } + } + + // + // Handle each argument type + // + switch (FormatCharacter) { + case 'p': + if (sizeof (VOID *) > 4) { + Long = TRUE; + } + case 'X': + case 'x': + case 'd': + if (Long) { + BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64); + } else { + BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int); + } + break; + case 's': + case 'S': + case 'a': + case 'g': + case 't': + BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *); + break; + case 'c': + BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN); + break; + case 'r': + BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS); + break; + } + } + + // + // If BASE_LIST is larger than Size, then return FALSE + // + if ((UINTN)((UINT8 *)BaseListMarker - (UINT8 *)BaseListStart) > Size) { + return FALSE; + } + + // + // Get the next character from the format string + // + Format += BytesPerFormatCharacter; + + // + // Get the next character from the format string + // + FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask; + } + return TRUE; +} + /** Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated Unicode format string and a VA_LIST argument list @@ -100,7 +265,63 @@ UnicodeVSPrint ( IN VA_LIST Marker ) { - return mPrint2Protocol->UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); + UINT8 BaseListMarker[256]; + + DxePrintLibPrint2ProtocolVaListToBaseList ( + FALSE, + (CHAR8 *)FormatString, + Marker, + (BASE_LIST)BaseListMarker, + sizeof (BaseListMarker) - 8 + ); + + return UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker); +} + +/** + Produces a Null-terminated Unicode string in an output buffer based on + a Null-terminated Unicode format string and a BASE_LIST argument list + + Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer + and BufferSize. + The Unicode string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on the + contents of the format string. + The number of Unicode characters in the produced output buffer is returned not including + the Null-terminator. + If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. + + If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). + If BufferSize > 1 and FormatString is NULL, then ASSERT(). + If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then + ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength Unicode characters not including the + Null-terminator, then ASSERT(). + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker BASE_LIST marker for the variable argument list. + + @return The number of Unicode characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +UnicodeBSPrint ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + IN BASE_LIST Marker + ) +{ + return mPrint2Protocol->UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, Marker); } /** @@ -194,7 +415,62 @@ UnicodeVSPrintAsciiFormat ( IN VA_LIST Marker ) { - return mPrint2Protocol->UnicodeSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker); + UINT8 BaseListMarker[256]; + + DxePrintLibPrint2ProtocolVaListToBaseList ( + TRUE, + FormatString, + Marker, + (BASE_LIST)BaseListMarker, + sizeof (BaseListMarker) - 8 + ); + + return UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker); +} + +/** + Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated + ASCII format string and a BASE_LIST argument list + + Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer + and BufferSize. + The Unicode string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on the + contents of the format string. + The number of Unicode characters in the produced output buffer is returned not including + the Null-terminator. + If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. + + If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). + If BufferSize > 1 and FormatString is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than + PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then + ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string + contains more than PcdMaximumUnicodeStringLength Unicode characters not including the + Null-terminator, then ASSERT(). + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker BASE_LIST marker for the variable argument list. + + @return The number of Unicode characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +UnicodeBSPrintAsciiFormat ( + OUT CHAR16 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN BASE_LIST Marker + ) +{ + return mPrint2Protocol->UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker); } /** @@ -340,7 +616,61 @@ AsciiVSPrint ( IN VA_LIST Marker ) { - return mPrint2Protocol->AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); + UINT8 BaseListMarker[256]; + + DxePrintLibPrint2ProtocolVaListToBaseList ( + TRUE, + FormatString, + Marker, + (BASE_LIST)BaseListMarker, + sizeof (BaseListMarker) - 8 + ); + + return AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker); +} + +/** + Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated + ASCII format string and a BASE_LIST argument list. + + Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer + and BufferSize. + The ASCII string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on + the contents of the format string. + The number of ASCII characters in the produced output buffer is returned not including + the Null-terminator. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize > 0 and FormatString is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than + PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then + ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string + contains more than PcdMaximumAsciiStringLength ASCII characters not including the + Null-terminator, then ASSERT(). + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker BASE_LIST marker for the variable argument list. + + @return The number of ASCII characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +AsciiBSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN BASE_LIST Marker + ) +{ + return mPrint2Protocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker); } /** @@ -433,7 +763,62 @@ AsciiVSPrintUnicodeFormat ( IN VA_LIST Marker ) { - return mPrint2Protocol->AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker); + UINT8 BaseListMarker[256]; + + DxePrintLibPrint2ProtocolVaListToBaseList ( + FALSE, + (CHAR8 *)FormatString, + Marker, + (BASE_LIST)BaseListMarker, + sizeof (BaseListMarker) - 8 + ); + + return AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker); +} + +/** + Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated + ASCII format string and a BASE_LIST argument list. + + Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer + and BufferSize. + The ASCII string is produced by parsing the format string specified by FormatString. + Arguments are pulled from the variable argument list specified by Marker based on + the contents of the format string. + The number of ASCII characters in the produced output buffer is returned not including + the Null-terminator. + If BufferSize is 0, then no output buffer is produced and 0 is returned. + + If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). + If BufferSize > 0 and FormatString is NULL, then ASSERT(). + If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than + PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then + ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string + contains more than PcdMaximumAsciiStringLength ASCII characters not including the + Null-terminator, then ASSERT(). + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString Null-terminated Unicode format string. + @param Marker BASE_LIST marker for the variable argument list. + + @return The number of ASCII characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +AsciiBSPrintUnicodeFormat ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR16 *FormatString, + IN BASE_LIST Marker + ) +{ + return mPrint2Protocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker); } /**