]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Print.c
Add Missing invocations to VA_END() for VA_START().
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Print.c
1 /*++
2
3 Copyright (c) 2004 - 2012, 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
8
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.
11
12 Module Name:
13
14 Print.c
15
16 Abstract:
17
18 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
19 simple implemenation of SPrint() and Print() to support debug.
20
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
22 time. This makes the implementation very simple.
23
24 VSPrint, Print, SPrint format specification has the follwoing form
25
26 %[flags][width]type
27
28 flags:
29 '-' - Left justify
30 '+' - Prefix a sign
31 ' ' - Prefix a blank
32 ',' - Place commas in numberss
33 '0' - Prefix for width with zeros
34 'l' - UINT64
35 'L' - UINT64
36
37 width:
38 '*' - Get width from a UINTN argumnet from the argument list
39 Decimal number that represents width of print
40
41 type:
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
51 '%' - Print a %
52
53 --*/
54
55 #include "Tiano.h"
56 #include "EfiDriverLib.h"
57 #include "TianoCommon.h"
58 #include "EfiCommonLib.h"
59 #include "PrintWidth.h"
60 #include "EfiPrintLib.h"
61 #include "Print.h"
62 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
63 #include EFI_PROTOCOL_DEFINITION (HiiFont)
64 #else
65 #include EFI_PROTOCOL_DEFINITION (Hii)
66 #endif
67
68
69 STATIC
70 UINTN
71 GuidToString (
72 IN EFI_GUID *Guid,
73 IN OUT CHAR_W *Buffer,
74 IN UINTN BufferSize
75 );
76
77 STATIC
78 UINTN
79 TimeToString (
80 IN EFI_TIME *Time,
81 IN OUT CHAR_W *Buffer,
82 IN UINTN BufferSize
83 );
84
85 STATIC
86 UINTN
87 EfiStatusToString (
88 IN EFI_STATUS Status,
89 OUT CHAR_W *Buffer,
90 IN UINTN BufferSize
91 );
92
93 static EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {
94 {0x00, 0x00, 0x00, 0x00},
95 {0x98, 0x00, 0x00, 0x00},
96 {0x00, 0x98, 0x00, 0x00},
97 {0x98, 0x98, 0x00, 0x00},
98 {0x00, 0x00, 0x98, 0x00},
99 {0x98, 0x00, 0x98, 0x00},
100 {0x00, 0x98, 0x98, 0x00},
101 {0x98, 0x98, 0x98, 0x00},
102 {0x10, 0x10, 0x10, 0x00},
103 {0xff, 0x10, 0x10, 0x00},
104 {0x10, 0xff, 0x10, 0x00},
105 {0xff, 0xff, 0x10, 0x00},
106 {0x10, 0x10, 0xff, 0x00},
107 {0xf0, 0x10, 0xff, 0x00},
108 {0x10, 0xff, 0xff, 0x00},
109 {0xff, 0xff, 0xff, 0x00},
110 };
111
112
113 UINTN
114 _IPrint (
115 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
116 IN EFI_UGA_DRAW_PROTOCOL *UgaDraw,
117 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto,
118 IN UINTN X,
119 IN UINTN Y,
120 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
121 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background,
122 IN CHAR16 *fmt,
123 IN VA_LIST args
124 )
125 /*++
126
127 Routine Description:
128
129 Display string worker for: Print, PrintAt, IPrint, IPrintAt
130
131 Arguments:
132
133 GraphicsOutput - Graphics output protocol interface
134
135 UgaDraw - UGA draw protocol interface
136
137 Sto - Simple text out protocol interface
138
139 X - X coordinate to start printing
140
141 Y - Y coordinate to start printing
142
143 Foreground - Foreground color
144
145 Background - Background color
146
147 fmt - Format string
148
149 args - Print arguments
150
151 Returns:
152
153 Length of string printed to the console
154
155 --*/
156 {
157 VOID *Buffer;
158 EFI_STATUS Status;
159 UINTN Index;
160 CHAR16 *UnicodeWeight;
161 UINT32 HorizontalResolution;
162 UINT32 VerticalResolution;
163 UINT32 ColorDepth;
164 UINT32 RefreshRate;
165 UINTN BufferLen;
166 UINTN LineBufferLen;
167 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
168 EFI_HII_FONT_PROTOCOL *HiiFont;
169 EFI_IMAGE_OUTPUT *Blt;
170 EFI_FONT_DISPLAY_INFO *FontInfo;
171 #else
172 EFI_HII_PROTOCOL *Hii;
173 UINT16 GlyphWidth;
174 UINT32 GlyphStatus;
175 UINT16 StringIndex;
176 EFI_NARROW_GLYPH *Glyph;
177 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LineBuffer;
178 #endif
179
180 //
181 // For now, allocate an arbitrarily long buffer
182 //
183 BufferLen = 0;
184 Buffer = EfiLibAllocateZeroPool (0x10000);
185 if (Buffer == NULL) {
186 return 0;
187 }
188
189 if (GraphicsOutput != NULL) {
190 HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
191 VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
192 } else {
193 UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);
194 }
195 ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));
196
197 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
198 Blt = NULL;
199 FontInfo = NULL;
200 ASSERT (GraphicsOutput != NULL);
201 Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);
202 if (EFI_ERROR (Status)) {
203 goto Error;
204 }
205 #else
206 LineBuffer = NULL;
207 Status = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, (VOID**)&Hii);
208 if (EFI_ERROR (Status)) {
209 goto Error;
210 }
211 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * GLYPH_HEIGHT;
212 LineBuffer = EfiLibAllocatePool (LineBufferLen);
213 if (LineBuffer == NULL) {
214 Status = EFI_OUT_OF_RESOURCES;
215 goto Error;
216 }
217 #endif
218
219 VSPrint (Buffer, 0x10000, fmt, args);
220
221 UnicodeWeight = (CHAR16 *) Buffer;
222
223 for (Index = 0; UnicodeWeight[Index] != 0; Index++) {
224 if (UnicodeWeight[Index] == CHAR_BACKSPACE ||
225 UnicodeWeight[Index] == CHAR_LINEFEED ||
226 UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {
227 UnicodeWeight[Index] = 0;
228 }
229 }
230
231 BufferLen = EfiStrLen (Buffer);
232
233
234 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
235 LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * EFI_GLYPH_HEIGHT;
236 if (EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
237 Status = EFI_INVALID_PARAMETER;
238 goto Error;
239 }
240
241 Blt = (EFI_IMAGE_OUTPUT *) EfiLibAllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
242 if (Blt == NULL) {
243 Status = EFI_OUT_OF_RESOURCES;
244 goto Error;
245 }
246
247 Blt->Width = (UINT16) (HorizontalResolution);
248 Blt->Height = (UINT16) (VerticalResolution);
249 Blt->Image.Screen = GraphicsOutput;
250
251 FontInfo = (EFI_FONT_DISPLAY_INFO *) EfiLibAllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));
252 if (FontInfo == NULL) {
253 Status = EFI_OUT_OF_RESOURCES;
254 goto Error;
255 }
256 if (Foreground != NULL) {
257 EfiCopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
258 } else {
259 EfiCopyMem (
260 &FontInfo->ForegroundColor,
261 &mEfiColors[Sto->Mode->Attribute & 0x0f],
262 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
263 );
264 }
265 if (Background != NULL) {
266 EfiCopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
267 } else {
268 EfiCopyMem (
269 &FontInfo->BackgroundColor,
270 &mEfiColors[Sto->Mode->Attribute >> 4],
271 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
272 );
273 }
274
275 Status = HiiFont->StringToImage (
276 HiiFont,
277 EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,
278 Buffer,
279 FontInfo,
280 &Blt,
281 X,
282 Y,
283 NULL,
284 NULL,
285 NULL
286 );
287
288 #else
289 GlyphStatus = 0;
290
291 if (GLYPH_WIDTH * GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {
292 Status = EFI_INVALID_PARAMETER;
293 goto Error;
294 }
295
296 for (Index = 0; Index < BufferLen; Index++) {
297 StringIndex = (UINT16) Index;
298 Status = Hii->GetGlyph (Hii, UnicodeWeight, &StringIndex, (UINT8 **) &Glyph, &GlyphWidth, &GlyphStatus);
299 if (EFI_ERROR (Status)) {
300 goto Error;
301 }
302
303 if (Foreground == NULL || Background == NULL) {
304 Status = Hii->GlyphToBlt (
305 Hii,
306 (UINT8 *) Glyph,
307 mEfiColors[Sto->Mode->Attribute & 0x0f],
308 mEfiColors[Sto->Mode->Attribute >> 4],
309 BufferLen,
310 GlyphWidth,
311 GLYPH_HEIGHT,
312 &LineBuffer[Index * GLYPH_WIDTH]
313 );
314 } else {
315 Status = Hii->GlyphToBlt (
316 Hii,
317 (UINT8 *) Glyph,
318 *Foreground,
319 *Background,
320 BufferLen,
321 GlyphWidth,
322 GLYPH_HEIGHT,
323 &LineBuffer[Index * GLYPH_WIDTH]
324 );
325 }
326 }
327
328 //
329 // Blt a character to the screen
330 //
331 if (GraphicsOutput != NULL) {
332 Status = GraphicsOutput->Blt (
333 GraphicsOutput,
334 LineBuffer,
335 EfiBltBufferToVideo,
336 0,
337 0,
338 X,
339 Y,
340 GLYPH_WIDTH * BufferLen,
341 GLYPH_HEIGHT,
342 GLYPH_WIDTH * BufferLen * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
343 );
344 } else {
345 Status = UgaDraw->Blt (
346 UgaDraw,
347 (EFI_UGA_PIXEL *) LineBuffer,
348 EfiUgaBltBufferToVideo,
349 0,
350 0,
351 X,
352 Y,
353 GLYPH_WIDTH * BufferLen,
354 GLYPH_HEIGHT,
355 GLYPH_WIDTH * BufferLen * sizeof (EFI_UGA_PIXEL)
356 );
357 }
358
359 #endif
360
361 Error:
362 #if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
363 EfiLibSafeFreePool (Blt);
364 EfiLibSafeFreePool (FontInfo);
365 #else
366 EfiLibSafeFreePool (LineBuffer);
367 #endif
368 gBS->FreePool (Buffer);
369
370 if (EFI_ERROR (Status)) {
371 return 0;
372 }
373
374 return BufferLen;
375 }
376
377
378 UINTN
379 PrintXY (
380 IN UINTN X,
381 IN UINTN Y,
382 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ForeGround, OPTIONAL
383 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackGround, OPTIONAL
384 IN CHAR_W *Fmt,
385 ...
386 )
387 /*++
388
389 Routine Description:
390
391 Prints a formatted unicode string to the default console
392
393 Arguments:
394
395 X - X coordinate to start printing
396
397 Y - Y coordinate to start printing
398
399 ForeGround - Foreground color
400
401 BackGround - Background color
402
403 Fmt - Format string
404
405 ... - Print arguments
406
407 Returns:
408
409 Length of string printed to the console
410
411 --*/
412 {
413 EFI_HANDLE Handle;
414 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
415 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
416 EFI_SIMPLE_TEXT_OUT_PROTOCOL *Sto;
417 EFI_STATUS Status;
418 VA_LIST Args;
419 UINTN LengthOfPrinted;
420
421 Handle = gST->ConsoleOutHandle;
422
423 GraphicsOutput = NULL;
424 UgaDraw = NULL;
425 Status = gBS->HandleProtocol (
426 Handle,
427 &gEfiGraphicsOutputProtocolGuid,
428 (VOID**)&GraphicsOutput
429 );
430
431 if (EFI_ERROR (Status) || (GraphicsOutput == NULL)) {
432 GraphicsOutput = NULL;
433
434 Status = gBS->HandleProtocol (
435 Handle,
436 &gEfiUgaDrawProtocolGuid,
437 (VOID**)&UgaDraw
438 );
439
440 if (EFI_ERROR (Status) || (UgaDraw == NULL)) {
441 return 0;
442 }
443 }
444
445 Sto = NULL;
446 Status = gBS->HandleProtocol (
447 Handle,
448 &gEfiSimpleTextOutProtocolGuid,
449 (VOID**)&Sto
450 );
451
452 if (EFI_ERROR (Status) || (Sto == NULL)) {
453 return 0;
454 }
455
456 VA_START (Args, Fmt);
457 LengthOfPrinted = _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);
458 VA_END (Args);
459 return LengthOfPrinted;
460 }
461
462
463 UINTN
464 SPrint (
465 OUT CHAR_W *Buffer,
466 IN UINTN BufferSize,
467 IN CONST CHAR_W *Format,
468 ...
469 )
470 /*++
471
472 Routine Description:
473
474 SPrint function to process format and place the results in Buffer.
475
476 Arguments:
477
478 Buffer - Wide char buffer to print the results of the parsing of Format into.
479
480 BufferSize - Maximum number of characters to put into buffer. Zero means no
481 limit.
482
483 Format - Format string see file header for more details.
484
485 ... - Vararg list consumed by processing Format.
486
487 Returns:
488
489 Number of characters printed.
490
491 --*/
492 {
493 UINTN Return;
494 VA_LIST Marker;
495
496 VA_START (Marker, Format);
497 Return = VSPrint (Buffer, BufferSize, Format, Marker);
498 VA_END (Marker);
499
500 return Return;
501 }
502
503 UINTN
504 EFIAPI
505 VSPrint (
506 OUT CHAR_W *StartOfBuffer,
507 IN UINTN BufferSize,
508 IN CONST CHAR_W *FormatString,
509 IN VA_LIST Marker
510 )
511 /*++
512
513 Routine Description:
514
515 VSPrint function to process format and place the results in Buffer. Since a
516 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
517 this is the main print working routine
518
519 Arguments:
520
521 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.
522
523 BufferSize - Maximum number of characters to put into buffer. Zero means
524 no limit.
525
526 FormatString - Unicode format string see file header for more details.
527
528 Marker - Vararg list consumed by processing Format.
529
530 Returns:
531
532 Number of characters printed.
533
534 --*/
535 {
536 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
537 CHAR_W *Buffer;
538 CHAR8 *AsciiStr;
539 CHAR16 *UnicodeStr;
540 CHAR_W *Format;
541 UINTN Index;
542 UINTN Flags;
543 UINTN Width;
544 UINTN Count;
545 UINTN NumberOfCharacters;
546 UINTN BufferLeft;
547 UINT64 Value;
548 EFI_GUID *TmpGUID;
549 BOOLEAN Done;
550
551 //
552 // Process the format string. Stop if Buffer is over run.
553 //
554
555 Buffer = StartOfBuffer;
556 Format = (CHAR_W *) FormatString;
557 NumberOfCharacters = BufferSize / sizeof (CHAR_W);
558 BufferLeft = BufferSize;
559 for (Index = 0; (*Format != '\0') && (Index < NumberOfCharacters - 1); Format++) {
560 if (*Format != '%') {
561 if ((*Format == '\n') && (Index < NumberOfCharacters - 2)) {
562 //
563 // If carage return add line feed
564 //
565 Buffer[Index++] = '\r';
566 BufferLeft -= sizeof (CHAR_W);
567 }
568
569 Buffer[Index++] = *Format;
570 BufferLeft -= sizeof (CHAR_W);
571 } else {
572
573 //
574 // Now it's time to parse what follows after %
575 //
576 Flags = 0;
577 Width = 0;
578 for (Done = FALSE; !Done;) {
579 Format++;
580
581 switch (*Format) {
582
583 case '-':
584 Flags |= LEFT_JUSTIFY;
585 break;
586
587 case '+':
588 Flags |= PREFIX_SIGN;
589 break;
590
591 case ' ':
592 Flags |= PREFIX_BLANK;
593 break;
594
595 case ',':
596 Flags |= COMMA_TYPE;
597 break;
598
599 case 'L':
600 case 'l':
601 Flags |= LONG_TYPE;
602 break;
603
604 case '*':
605 Width = VA_ARG (Marker, UINTN);
606 break;
607
608 case '0':
609 Flags |= PREFIX_ZERO;
610
611 case '1':
612 case '2':
613 case '3':
614 case '4':
615 case '5':
616 case '6':
617 case '7':
618 case '8':
619 case '9':
620 Count = 0;
621 do {
622 Count = (Count * 10) +*Format - '0';
623 Format++;
624 } while ((*Format >= '0') && (*Format <= '9'));
625 Format--;
626 Width = Count;
627 break;
628
629 default:
630 Done = TRUE;
631 }
632 }
633
634 switch (*Format) {
635 case 'p':
636 //
637 // Flag space, +, 0, L & l are invalid for type p.
638 //
639 Flags &= ~(PREFIX_BLANK| PREFIX_SIGN | LONG_TYPE);
640 if (sizeof (VOID *) > 4) {
641 Flags |= LONG_TYPE;
642 Value = VA_ARG (Marker, UINT64);
643 } else {
644 Value = VA_ARG (Marker, UINTN);
645 }
646 Flags |= PREFIX_ZERO;
647
648 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
649 UnicodeStr = TempBuffer;
650
651 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
652 Buffer[Index++] = *UnicodeStr;
653 }
654 break;
655
656 case 'X':
657 Flags |= PREFIX_ZERO;
658 Width = sizeof (UINT64) * 2;
659
660 //
661 // break skiped on purpose
662 //
663 case 'x':
664 if ((Flags & LONG_TYPE) == LONG_TYPE) {
665 Value = VA_ARG (Marker, UINT64);
666 } else {
667 Value = VA_ARG (Marker, UINTN);
668 }
669
670 EfiValueToHexStr (TempBuffer, Value, Flags, Width);
671 UnicodeStr = TempBuffer;
672
673 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
674 Buffer[Index++] = *UnicodeStr;
675 }
676 break;
677
678 case 'd':
679 if ((Flags & LONG_TYPE) == LONG_TYPE) {
680 Value = VA_ARG (Marker, UINT64);
681 } else {
682 Value = (UINTN) VA_ARG (Marker, UINTN);
683 }
684
685 EfiValueToString (TempBuffer, Value, Flags, Width);
686 UnicodeStr = TempBuffer;
687
688 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {
689 Buffer[Index++] = *UnicodeStr;
690 }
691 break;
692
693 case 's':
694 case 'S':
695 UnicodeStr = (CHAR16 *) VA_ARG (Marker, CHAR_W *);
696 if (UnicodeStr == NULL) {
697 UnicodeStr = L"<null string>";
698 }
699
700 for (Count = 0; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++, Count++) {
701 Buffer[Index++] = *UnicodeStr;
702 }
703 //
704 // Add padding if needed
705 //
706 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
707 Buffer[Index++] = ' ';
708 }
709
710 break;
711
712 case 'a':
713 AsciiStr = (CHAR8 *) VA_ARG (Marker, CHAR8 *);
714 if (AsciiStr == NULL) {
715 AsciiStr = (CHAR8 *) "<null string>";
716 }
717
718 for (Count = 0; (*AsciiStr != '\0') && (Index < NumberOfCharacters - 1); AsciiStr++, Count++) {
719 Buffer[Index++] = (CHAR_W) * AsciiStr;
720 }
721 //
722 // Add padding if needed
723 //
724 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {
725 Buffer[Index++] = ' ';
726 }
727 break;
728
729 case 'c':
730 Buffer[Index++] = (CHAR_W) VA_ARG (Marker, UINTN);
731 break;
732
733 case 'g':
734 TmpGUID = VA_ARG (Marker, EFI_GUID *);
735 if (TmpGUID != NULL) {
736 Index += GuidToString (
737 TmpGUID,
738 &Buffer[Index],
739 BufferLeft
740 );
741 }
742 break;
743
744 case 't':
745 Index += TimeToString (
746 VA_ARG (Marker, EFI_TIME *),
747 &Buffer[Index],
748 BufferLeft
749 );
750 break;
751
752 case 'r':
753 Index += EfiStatusToString (
754 VA_ARG (Marker, EFI_STATUS),
755 &Buffer[Index],
756 BufferLeft
757 );
758 break;
759
760 case '%':
761 Buffer[Index++] = *Format;
762 break;
763
764 default:
765 //
766 // if the type is unknown print it to the screen
767 //
768 Buffer[Index++] = *Format;
769 }
770
771 BufferLeft = BufferSize - Index * sizeof (CHAR_W);
772 }
773 }
774
775 Buffer[Index++] = '\0';
776
777 return &Buffer[Index] - StartOfBuffer;
778 }
779
780 STATIC
781 UINTN
782 GuidToString (
783 IN EFI_GUID *Guid,
784 IN CHAR_W *Buffer,
785 IN UINTN BufferSize
786 )
787 /*++
788
789 Routine Description:
790
791 VSPrint worker function that prints an EFI_GUID.
792
793 Arguments:
794
795 Guid - Pointer to GUID to print.
796
797 Buffer - Buffe to print Guid into.
798
799 BufferSize - Size of Buffer.
800
801 Returns:
802
803 Number of characters printed.
804
805 --*/
806 {
807 UINTN Size;
808
809 Size = SPrint (
810 Buffer,
811 BufferSize,
812 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
813 (UINTN)Guid->Data1,
814 (UINTN)Guid->Data2,
815 (UINTN)Guid->Data3,
816 (UINTN)Guid->Data4[0],
817 (UINTN)Guid->Data4[1],
818 (UINTN)Guid->Data4[2],
819 (UINTN)Guid->Data4[3],
820 (UINTN)Guid->Data4[4],
821 (UINTN)Guid->Data4[5],
822 (UINTN)Guid->Data4[6],
823 (UINTN)Guid->Data4[7]
824 );
825
826 //
827 // SPrint will null terminate the string. The -1 skips the null
828 //
829 return Size - 1;
830 }
831
832
833 STATIC
834 UINTN
835 TimeToString (
836 IN EFI_TIME *Time,
837 OUT CHAR_W *Buffer,
838 IN UINTN BufferSize
839 )
840 /*++
841
842 Routine Description:
843
844 VSPrint worker function that prints EFI_TIME.
845
846 Arguments:
847
848 Time - Pointer to EFI_TIME sturcture to print.
849
850 Buffer - Buffer to print Time into.
851
852 BufferSize - Size of Buffer.
853
854 Returns:
855
856 Number of characters printed.
857
858 --*/
859 {
860 UINTN Size;
861
862 Size = SPrint (
863 Buffer,
864 BufferSize,
865 STRING_W ("%02d/%02d/%04d %02d:%02d"),
866 (UINTN)Time->Month,
867 (UINTN)Time->Day,
868 (UINTN)Time->Year,
869 (UINTN)Time->Hour,
870 (UINTN)Time->Minute
871 );
872
873 //
874 // SPrint will null terminate the string. The -1 skips the null
875 //
876 return Size - 1;
877 }
878
879 STATIC
880 UINTN
881 EfiStatusToString (
882 IN EFI_STATUS Status,
883 OUT CHAR_W *Buffer,
884 IN UINTN BufferSize
885 )
886 /*++
887
888 Routine Description:
889
890 VSPrint worker function that prints EFI_STATUS as a string. If string is
891 not known a hex value will be printed.
892
893 Arguments:
894
895 Status - EFI_STATUS sturcture to print.
896
897 Buffer - Buffer to print EFI_STATUS message string into.
898
899 BufferSize - Size of Buffer.
900
901 Returns:
902
903 Number of characters printed.
904
905 --*/
906 {
907 UINTN Size;
908 CHAR8 *Desc;
909
910 Desc = NULL;
911
912 //
913 // Can't use global Status String Array as UINTN is not constant for EBC
914 //
915 if (Status == EFI_SUCCESS) { Desc = (CHAR8 *) "Success"; } else
916 if (Status == EFI_LOAD_ERROR) { Desc = (CHAR8 *) "Load Error"; } else
917 if (Status == EFI_INVALID_PARAMETER) { Desc = (CHAR8 *) "Invalid Parameter"; } else
918 if (Status == EFI_UNSUPPORTED) { Desc = (CHAR8 *) "Unsupported"; } else
919 if (Status == EFI_BAD_BUFFER_SIZE) { Desc = (CHAR8 *) "Bad Buffer Size"; } else
920 if (Status == EFI_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Buffer Too Small"; } else
921 if (Status == EFI_NOT_READY) { Desc = (CHAR8 *) "Not Ready"; } else
922 if (Status == EFI_DEVICE_ERROR) { Desc = (CHAR8 *) "Device Error"; } else
923 if (Status == EFI_WRITE_PROTECTED) { Desc = (CHAR8 *) "Write Protected"; } else
924 if (Status == EFI_OUT_OF_RESOURCES) { Desc = (CHAR8 *) "Out of Resources"; } else
925 if (Status == EFI_VOLUME_CORRUPTED) { Desc = (CHAR8 *) "Volume Corrupt"; } else
926 if (Status == EFI_VOLUME_FULL) { Desc = (CHAR8 *) "Volume Full"; } else
927 if (Status == EFI_NO_MEDIA) { Desc = (CHAR8 *) "No Media"; } else
928 if (Status == EFI_MEDIA_CHANGED) { Desc = (CHAR8 *) "Media changed"; } else
929 if (Status == EFI_NOT_FOUND) { Desc = (CHAR8 *) "Not Found"; } else
930 if (Status == EFI_ACCESS_DENIED) { Desc = (CHAR8 *) "Access Denied"; } else
931 if (Status == EFI_NO_RESPONSE) { Desc = (CHAR8 *) "No Response"; } else
932 if (Status == EFI_NO_MAPPING) { Desc = (CHAR8 *) "No mapping"; } else
933 if (Status == EFI_TIMEOUT) { Desc = (CHAR8 *) "Time out"; } else
934 if (Status == EFI_NOT_STARTED) { Desc = (CHAR8 *) "Not started"; } else
935 if (Status == EFI_ALREADY_STARTED) { Desc = (CHAR8 *) "Already started"; } else
936 if (Status == EFI_ABORTED) { Desc = (CHAR8 *) "Aborted"; } else
937 if (Status == EFI_ICMP_ERROR) { Desc = (CHAR8 *) "ICMP Error"; } else
938 if (Status == EFI_TFTP_ERROR) { Desc = (CHAR8 *) "TFTP Error"; } else
939 if (Status == EFI_PROTOCOL_ERROR) { Desc = (CHAR8 *) "Protocol Error"; } else
940 if (Status == EFI_WARN_UNKNOWN_GLYPH) { Desc = (CHAR8 *) "Warning Unknown Glyph"; } else
941 if (Status == EFI_WARN_DELETE_FAILURE) { Desc = (CHAR8 *) "Warning Delete Failure"; } else
942 if (Status == EFI_WARN_WRITE_FAILURE) { Desc = (CHAR8 *) "Warning Write Failure"; } else
943 if (Status == EFI_WARN_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Warning Buffer Too Small"; }
944
945 //
946 // If we found a match, copy the message to the user's buffer. Otherwise
947 // sprint the hex status code to their buffer.
948 //
949 if (Desc != NULL) {
950 Size = SPrint (Buffer, BufferSize, STRING_W ("%a"), Desc);
951 } else {
952 Size = SPrint (Buffer, BufferSize, STRING_W ("%X"), Status);
953 }
954
955 return Size - 1;
956 }