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