3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
19 simple implemenation of SPrint() and Print() to support debug.
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
24 VSPrint, Print, SPrint format specification has the follwoing form
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
42 'X' - argument is a UINTN hex number, prefix '0'
43 'x' - argument is a hex number
44 'd' - argument is a decimal number
45 'a' - argument is an ascii string
46 'S','s' - argument is an Unicode string
47 'g' - argument is a pointer to an EFI_GUID
48 't' - argument is a pointer to an EFI_TIME structure
49 'c' - argument is an ascii character
50 'r' - argument is EFI_STATUS
56 #include "EfiDriverLib.h"
57 #include "TianoCommon.h"
58 #include "EfiCommonLib.h"
59 #include "PrintWidth.h"
60 #include "EfiPrintLib.h"
62 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
63 #include EFI_PROTOCOL_DEFINITION (HiiFont)
65 #include EFI_PROTOCOL_DEFINITION (Hii)
74 IN OUT VA_LIST
*Marker
81 IN OUT CHAR_W
*Buffer
,
89 IN OUT CHAR_W
*Buffer
,
101 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors
[16] = {
102 {0x00, 0x00, 0x00, 0x00},
103 {0x98, 0x00, 0x00, 0x00},
104 {0x00, 0x98, 0x00, 0x00},
105 {0x98, 0x98, 0x00, 0x00},
106 {0x00, 0x00, 0x98, 0x00},
107 {0x98, 0x00, 0x98, 0x00},
108 {0x00, 0x98, 0x98, 0x00},
109 {0x98, 0x98, 0x98, 0x00},
110 {0x10, 0x10, 0x10, 0x00},
111 {0xff, 0x10, 0x10, 0x00},
112 {0x10, 0xff, 0x10, 0x00},
113 {0xff, 0xff, 0x10, 0x00},
114 {0x10, 0x10, 0xff, 0x00},
115 {0xf0, 0x10, 0xff, 0x00},
116 {0x10, 0xff, 0xff, 0x00},
117 {0xff, 0xff, 0xff, 0x00},
123 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
,
124 IN EFI_UGA_DRAW_PROTOCOL
*UgaDraw
,
125 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
,
128 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Foreground
,
129 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*Background
,
137 Display string worker for: Print, PrintAt, IPrint, IPrintAt
141 GraphicsOutput - Graphics output protocol interface
143 UgaDraw - UGA draw protocol interface
145 Sto - Simple text out protocol interface
147 X - X coordinate to start printing
149 Y - Y coordinate to start printing
151 Foreground - Foreground color
153 Background - Background color
157 args - Print arguments
161 Length of string printed to the console
168 CHAR16
*UnicodeWeight
;
169 UINT32 HorizontalResolution
;
170 UINT32 VerticalResolution
;
175 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
176 EFI_HII_FONT_PROTOCOL
*HiiFont
;
177 EFI_IMAGE_OUTPUT
*Blt
;
178 EFI_FONT_DISPLAY_INFO
*FontInfo
;
180 EFI_HII_PROTOCOL
*Hii
;
184 EFI_NARROW_GLYPH
*Glyph
;
185 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*LineBuffer
;
189 // For now, allocate an arbitrarily long buffer
192 Buffer
= EfiLibAllocateZeroPool (0x10000);
193 if (Buffer
== NULL
) {
197 if (GraphicsOutput
!= NULL
) {
198 HorizontalResolution
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
199 VerticalResolution
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
201 UgaDraw
->GetMode (UgaDraw
, &HorizontalResolution
, &VerticalResolution
, &ColorDepth
, &RefreshRate
);
203 ASSERT ((HorizontalResolution
!= 0) && (VerticalResolution
!=0));
205 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
208 ASSERT (GraphicsOutput
!= NULL
);
209 Status
= gBS
->LocateProtocol (&gEfiHiiFontProtocolGuid
, NULL
, (VOID
**) &HiiFont
);
210 if (EFI_ERROR (Status
)) {
215 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**)&Hii
);
216 if (EFI_ERROR (Status
)) {
219 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* GLYPH_HEIGHT
;
220 LineBuffer
= EfiLibAllocatePool (LineBufferLen
);
221 if (LineBuffer
== NULL
) {
222 Status
= EFI_OUT_OF_RESOURCES
;
227 VSPrint (Buffer
, 0x10000, fmt
, args
);
229 UnicodeWeight
= (CHAR16
*) Buffer
;
231 for (Index
= 0; UnicodeWeight
[Index
] != 0; Index
++) {
232 if (UnicodeWeight
[Index
] == CHAR_BACKSPACE
||
233 UnicodeWeight
[Index
] == CHAR_LINEFEED
||
234 UnicodeWeight
[Index
] == CHAR_CARRIAGE_RETURN
) {
235 UnicodeWeight
[Index
] = 0;
239 BufferLen
= EfiStrLen (Buffer
);
242 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
243 LineBufferLen
= sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * HorizontalResolution
* EFI_GLYPH_HEIGHT
;
244 if (EFI_GLYPH_WIDTH
* EFI_GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
245 Status
= EFI_INVALID_PARAMETER
;
249 Blt
= (EFI_IMAGE_OUTPUT
*) EfiLibAllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT
));
251 Status
= EFI_OUT_OF_RESOURCES
;
255 Blt
->Width
= (UINT16
) (HorizontalResolution
);
256 Blt
->Height
= (UINT16
) (VerticalResolution
);
257 Blt
->Image
.Screen
= GraphicsOutput
;
259 FontInfo
= (EFI_FONT_DISPLAY_INFO
*) EfiLibAllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO
));
260 if (FontInfo
== NULL
) {
261 Status
= EFI_OUT_OF_RESOURCES
;
264 if (Foreground
!= NULL
) {
265 EfiCopyMem (&FontInfo
->ForegroundColor
, Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
268 &FontInfo
->ForegroundColor
,
269 &mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
270 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
273 if (Background
!= NULL
) {
274 EfiCopyMem (&FontInfo
->BackgroundColor
, Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
));
277 &FontInfo
->BackgroundColor
,
278 &mEfiColors
[Sto
->Mode
->Attribute
>> 4],
279 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
283 Status
= HiiFont
->StringToImage (
285 EFI_HII_IGNORE_IF_NO_GLYPH
| EFI_HII_DIRECT_TO_SCREEN
,
299 if (GLYPH_WIDTH
* GLYPH_HEIGHT
* sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL
) * BufferLen
> LineBufferLen
) {
300 Status
= EFI_INVALID_PARAMETER
;
304 for (Index
= 0; Index
< BufferLen
; Index
++) {
305 StringIndex
= (UINT16
) Index
;
306 Status
= Hii
->GetGlyph (Hii
, UnicodeWeight
, &StringIndex
, (UINT8
**) &Glyph
, &GlyphWidth
, &GlyphStatus
);
307 if (EFI_ERROR (Status
)) {
311 if (Foreground
== NULL
|| Background
== NULL
) {
312 Status
= Hii
->GlyphToBlt (
315 mEfiColors
[Sto
->Mode
->Attribute
& 0x0f],
316 mEfiColors
[Sto
->Mode
->Attribute
>> 4],
320 &LineBuffer
[Index
* GLYPH_WIDTH
]
323 Status
= Hii
->GlyphToBlt (
331 &LineBuffer
[Index
* GLYPH_WIDTH
]
337 // Blt a character to the screen
339 if (GraphicsOutput
!= NULL
) {
340 Status
= GraphicsOutput
->Blt (
348 GLYPH_WIDTH
* BufferLen
,
350 GLYPH_WIDTH
* BufferLen
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
353 Status
= UgaDraw
->Blt (
355 (EFI_UGA_PIXEL
*) LineBuffer
,
356 EfiUgaBltBufferToVideo
,
361 GLYPH_WIDTH
* BufferLen
,
363 GLYPH_WIDTH
* BufferLen
* sizeof (EFI_UGA_PIXEL
)
370 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
371 EfiLibSafeFreePool (Blt
);
372 EfiLibSafeFreePool (FontInfo
);
374 EfiLibSafeFreePool (LineBuffer
);
376 gBS
->FreePool (Buffer
);
378 if (EFI_ERROR (Status
)) {
390 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*ForeGround
, OPTIONAL
391 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BackGround
, OPTIONAL
399 Prints a formatted unicode string to the default console
403 X - X coordinate to start printing
405 Y - Y coordinate to start printing
407 ForeGround - Foreground color
409 BackGround - Background color
413 ... - Print arguments
417 Length of string printed to the console
422 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
423 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
424 EFI_SIMPLE_TEXT_OUT_PROTOCOL
*Sto
;
428 VA_START (Args
, Fmt
);
430 Handle
= gST
->ConsoleOutHandle
;
432 GraphicsOutput
= NULL
;
434 Status
= gBS
->HandleProtocol (
436 &gEfiGraphicsOutputProtocolGuid
,
437 (VOID
**)&GraphicsOutput
440 if (EFI_ERROR (Status
) || (GraphicsOutput
== NULL
)) {
441 GraphicsOutput
= NULL
;
443 Status
= gBS
->HandleProtocol (
445 &gEfiUgaDrawProtocolGuid
,
449 if (EFI_ERROR (Status
) || (UgaDraw
== NULL
)) {
455 Status
= gBS
->HandleProtocol (
457 &gEfiSimpleTextOutProtocolGuid
,
461 if (EFI_ERROR (Status
) || (Sto
== NULL
)) {
465 return _IPrint (GraphicsOutput
, UgaDraw
, Sto
, X
, Y
, ForeGround
, BackGround
, Fmt
, Args
);
473 IN CONST CHAR_W
*Format
,
480 SPrint function to process format and place the results in Buffer.
484 Buffer - Wide char buffer to print the results of the parsing of Format into.
486 BufferSize - Maximum number of characters to put into buffer. Zero means no
489 Format - Format string see file header for more details.
491 ... - Vararg list consumed by processing Format.
495 Number of characters printed.
502 VA_START (Marker
, Format
);
503 Return
= VSPrint (Buffer
, BufferSize
, Format
, Marker
);
512 OUT CHAR_W
*StartOfBuffer
,
514 IN CONST CHAR_W
*FormatString
,
521 VSPrint function to process format and place the results in Buffer. Since a
522 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
523 this is the main print working routine
527 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
529 BufferSize - Maximum number of characters to put into buffer. Zero means
532 FormatString - Unicode format string see file header for more details.
534 Marker - Vararg list consumed by processing Format.
538 Number of characters printed.
542 CHAR16 TempBuffer
[CHARACTER_NUMBER_FOR_VALUE
];
551 UINTN NumberOfCharacters
;
557 // Process the format string. Stop if Buffer is over run.
560 Buffer
= StartOfBuffer
;
561 Format
= (CHAR_W
*) FormatString
;
562 NumberOfCharacters
= BufferSize
/ sizeof (CHAR_W
);
563 BufferLeft
= BufferSize
;
564 for (Index
= 0; (*Format
!= '\0') && (Index
< NumberOfCharacters
- 1); Format
++) {
565 if (*Format
!= '%') {
566 if ((*Format
== '\n') && (Index
< NumberOfCharacters
- 2)) {
568 // If carage return add line feed
570 Buffer
[Index
++] = '\r';
571 BufferLeft
-= sizeof (CHAR_W
);
574 Buffer
[Index
++] = *Format
;
575 BufferLeft
-= sizeof (CHAR_W
);
579 // Now it's time to parse what follows after %
581 Format
= GetFlagsAndWidth (Format
, &Flags
, &Width
, &Marker
);
585 // Flag space, +, 0, L & l are invalid for type p.
587 Flags
&= ~(PREFIX_BLANK
| PREFIX_SIGN
| LONG_TYPE
);
588 if (sizeof (VOID
*) > 4) {
590 Value
= VA_ARG (Marker
, UINT64
);
592 Value
= VA_ARG (Marker
, UINTN
);
594 Flags
|= PREFIX_ZERO
;
596 EfiValueToHexStr (TempBuffer
, Value
, Flags
, Width
);
597 UnicodeStr
= TempBuffer
;
599 for ( ;(*UnicodeStr
!= '\0') && (Index
< NumberOfCharacters
- 1); UnicodeStr
++) {
600 Buffer
[Index
++] = *UnicodeStr
;
605 Flags
|= PREFIX_ZERO
;
606 Width
= sizeof (UINT64
) * 2;
609 // break skiped on purpose
612 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
613 Value
= VA_ARG (Marker
, UINT64
);
615 Value
= VA_ARG (Marker
, UINTN
);
618 EfiValueToHexStr (TempBuffer
, Value
, Flags
, Width
);
619 UnicodeStr
= TempBuffer
;
621 for (; (*UnicodeStr
!= '\0') && (Index
< NumberOfCharacters
- 1); UnicodeStr
++) {
622 Buffer
[Index
++] = *UnicodeStr
;
627 if ((Flags
& LONG_TYPE
) == LONG_TYPE
) {
628 Value
= VA_ARG (Marker
, UINT64
);
630 Value
= (UINTN
) VA_ARG (Marker
, UINTN
);
633 EfiValueToString (TempBuffer
, Value
, Flags
, Width
);
634 UnicodeStr
= TempBuffer
;
636 for (; (*UnicodeStr
!= '\0') && (Index
< NumberOfCharacters
- 1); UnicodeStr
++) {
637 Buffer
[Index
++] = *UnicodeStr
;
643 UnicodeStr
= (CHAR16
*) VA_ARG (Marker
, CHAR_W
*);
644 if (UnicodeStr
== NULL
) {
645 UnicodeStr
= L
"<null string>";
648 for (Count
= 0; (*UnicodeStr
!= '\0') && (Index
< NumberOfCharacters
- 1); UnicodeStr
++, Count
++) {
649 Buffer
[Index
++] = *UnicodeStr
;
652 // Add padding if needed
654 for (; (Count
< Width
) && (Index
< NumberOfCharacters
- 1); Count
++) {
655 Buffer
[Index
++] = ' ';
661 AsciiStr
= (CHAR8
*) VA_ARG (Marker
, CHAR8
*);
662 if (AsciiStr
== NULL
) {
663 AsciiStr
= (CHAR8
*) "<null string>";
666 for (Count
= 0; (*AsciiStr
!= '\0') && (Index
< NumberOfCharacters
- 1); AsciiStr
++, Count
++) {
667 Buffer
[Index
++] = (CHAR_W
) * AsciiStr
;
670 // Add padding if needed
672 for (; (Count
< Width
) && (Index
< NumberOfCharacters
- 1); Count
++) {
673 Buffer
[Index
++] = ' ';
678 Buffer
[Index
++] = (CHAR_W
) VA_ARG (Marker
, UINTN
);
682 TmpGUID
= VA_ARG (Marker
, EFI_GUID
*);
683 if (TmpGUID
!= NULL
) {
684 Index
+= GuidToString (
693 Index
+= TimeToString (
694 VA_ARG (Marker
, EFI_TIME
*),
701 Index
+= EfiStatusToString (
702 VA_ARG (Marker
, EFI_STATUS
),
709 Buffer
[Index
++] = *Format
;
714 // if the type is unknown print it to the screen
716 Buffer
[Index
++] = *Format
;
719 BufferLeft
= BufferSize
- Index
* sizeof (CHAR_W
);
723 Buffer
[Index
++] = '\0';
725 return &Buffer
[Index
] - StartOfBuffer
;
734 IN OUT VA_LIST
*Marker
740 VSPrint worker function that parses flag and width information from the
741 Format string and returns the next index into the Format string that needs
742 to be parsed. See file headed for details of Flag and Width.
746 Format - Current location in the VSPrint format string.
748 Flags - Returns flags
750 Width - Returns width of element
752 Marker - Vararg list that may be paritally consumed and returned.
756 Pointer indexed into the Format string for all the information parsed
766 for (Done
= FALSE
; !Done
;) {
772 *Flags
|= LEFT_JUSTIFY
;
776 *Flags
|= PREFIX_SIGN
;
780 *Flags
|= PREFIX_BLANK
;
784 *Flags
|= COMMA_TYPE
;
793 *Width
= VA_ARG (*Marker
, UINTN
);
797 *Flags
|= PREFIX_ZERO
;
810 Count
= (Count
* 10) +*Format
- '0';
812 } while ((*Format
>= '0') && (*Format
<= '9'));
836 VSPrint worker function that prints an EFI_GUID.
840 Guid - Pointer to GUID to print.
842 Buffer - Buffe to print Guid into.
844 BufferSize - Size of Buffer.
848 Number of characters printed.
857 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
861 (UINTN
)Guid
->Data4
[0],
862 (UINTN
)Guid
->Data4
[1],
863 (UINTN
)Guid
->Data4
[2],
864 (UINTN
)Guid
->Data4
[3],
865 (UINTN
)Guid
->Data4
[4],
866 (UINTN
)Guid
->Data4
[5],
867 (UINTN
)Guid
->Data4
[6],
868 (UINTN
)Guid
->Data4
[7]
872 // SPrint will null terminate the string. The -1 skips the null
889 VSPrint worker function that prints EFI_TIME.
893 Time - Pointer to EFI_TIME sturcture to print.
895 Buffer - Buffer to print Time into.
897 BufferSize - Size of Buffer.
901 Number of characters printed.
910 STRING_W ("%02d/%02d/%04d %02d:%02d"),
919 // SPrint will null terminate the string. The -1 skips the null
927 IN EFI_STATUS Status
,
935 VSPrint worker function that prints EFI_STATUS as a string. If string is
936 not known a hex value will be printed.
940 Status - EFI_STATUS sturcture to print.
942 Buffer - Buffer to print EFI_STATUS message string into.
944 BufferSize - Size of Buffer.
948 Number of characters printed.
958 // Can't use global Status String Array as UINTN is not constant for EBC
960 if (Status
== EFI_SUCCESS
) { Desc
= (CHAR8
*) "Success"; } else
961 if (Status
== EFI_LOAD_ERROR
) { Desc
= (CHAR8
*) "Load Error"; } else
962 if (Status
== EFI_INVALID_PARAMETER
) { Desc
= (CHAR8
*) "Invalid Parameter"; } else
963 if (Status
== EFI_UNSUPPORTED
) { Desc
= (CHAR8
*) "Unsupported"; } else
964 if (Status
== EFI_BAD_BUFFER_SIZE
) { Desc
= (CHAR8
*) "Bad Buffer Size"; } else
965 if (Status
== EFI_BUFFER_TOO_SMALL
) { Desc
= (CHAR8
*) "Buffer Too Small"; } else
966 if (Status
== EFI_NOT_READY
) { Desc
= (CHAR8
*) "Not Ready"; } else
967 if (Status
== EFI_DEVICE_ERROR
) { Desc
= (CHAR8
*) "Device Error"; } else
968 if (Status
== EFI_WRITE_PROTECTED
) { Desc
= (CHAR8
*) "Write Protected"; } else
969 if (Status
== EFI_OUT_OF_RESOURCES
) { Desc
= (CHAR8
*) "Out of Resources"; } else
970 if (Status
== EFI_VOLUME_CORRUPTED
) { Desc
= (CHAR8
*) "Volume Corrupt"; } else
971 if (Status
== EFI_VOLUME_FULL
) { Desc
= (CHAR8
*) "Volume Full"; } else
972 if (Status
== EFI_NO_MEDIA
) { Desc
= (CHAR8
*) "No Media"; } else
973 if (Status
== EFI_MEDIA_CHANGED
) { Desc
= (CHAR8
*) "Media changed"; } else
974 if (Status
== EFI_NOT_FOUND
) { Desc
= (CHAR8
*) "Not Found"; } else
975 if (Status
== EFI_ACCESS_DENIED
) { Desc
= (CHAR8
*) "Access Denied"; } else
976 if (Status
== EFI_NO_RESPONSE
) { Desc
= (CHAR8
*) "No Response"; } else
977 if (Status
== EFI_NO_MAPPING
) { Desc
= (CHAR8
*) "No mapping"; } else
978 if (Status
== EFI_TIMEOUT
) { Desc
= (CHAR8
*) "Time out"; } else
979 if (Status
== EFI_NOT_STARTED
) { Desc
= (CHAR8
*) "Not started"; } else
980 if (Status
== EFI_ALREADY_STARTED
) { Desc
= (CHAR8
*) "Already started"; } else
981 if (Status
== EFI_ABORTED
) { Desc
= (CHAR8
*) "Aborted"; } else
982 if (Status
== EFI_ICMP_ERROR
) { Desc
= (CHAR8
*) "ICMP Error"; } else
983 if (Status
== EFI_TFTP_ERROR
) { Desc
= (CHAR8
*) "TFTP Error"; } else
984 if (Status
== EFI_PROTOCOL_ERROR
) { Desc
= (CHAR8
*) "Protocol Error"; } else
985 if (Status
== EFI_WARN_UNKNOWN_GLYPH
) { Desc
= (CHAR8
*) "Warning Unknown Glyph"; } else
986 if (Status
== EFI_WARN_DELETE_FAILURE
) { Desc
= (CHAR8
*) "Warning Delete Failure"; } else
987 if (Status
== EFI_WARN_WRITE_FAILURE
) { Desc
= (CHAR8
*) "Warning Write Failure"; } else
988 if (Status
== EFI_WARN_BUFFER_TOO_SMALL
) { Desc
= (CHAR8
*) "Warning Buffer Too Small"; }
991 // If we found a match, copy the message to the user's buffer. Otherwise
992 // sprint the hex status code to their buffer.
995 Size
= SPrint (Buffer
, BufferSize
, STRING_W ("%a"), Desc
);
997 Size
= SPrint (Buffer
, BufferSize
, STRING_W ("%X"), Status
);