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