]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/Graphics/Print.c
Update the copyright notice format
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Graphics / Print.c
CommitLineData
3eb9473e 1/*++\r
2\r
4ea9375a
HT
3Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>\r
4This program and the accompanying materials \r
3eb9473e 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
0f77dfb6 576 case 'p':\r
577 //\r
578 // Flag space, +, 0, L & l are invalid for type p.\r
579 //\r
580 Flags &= ~(PREFIX_BLANK| PREFIX_SIGN | LONG_TYPE);\r
581 if (sizeof (VOID *) > 4) {\r
582 Flags |= LONG_TYPE;\r
583 Value = VA_ARG (Marker, UINT64);\r
584 } else {\r
585 Value = VA_ARG (Marker, UINTN);\r
586 }\r
587 Flags |= PREFIX_ZERO;\r
588 \r
589 EfiValueToHexStr (TempBuffer, Value, Flags, Width);\r
590 UnicodeStr = TempBuffer;\r
591 \r
592 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {\r
593 Buffer[Index++] = *UnicodeStr;\r
594 }\r
595 break;\r
596 \r
3eb9473e 597 case 'X':\r
598 Flags |= PREFIX_ZERO;\r
599 Width = sizeof (UINT64) * 2;\r
600\r
601 //\r
602 // break skiped on purpose\r
603 //\r
604 case 'x':\r
605 if ((Flags & LONG_TYPE) == LONG_TYPE) {\r
606 Value = VA_ARG (Marker, UINT64);\r
607 } else {\r
608 Value = VA_ARG (Marker, UINTN);\r
609 }\r
610\r
611 EfiValueToHexStr (TempBuffer, Value, Flags, Width);\r
612 UnicodeStr = TempBuffer;\r
613\r
614 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {\r
615 Buffer[Index++] = *UnicodeStr;\r
616 }\r
617 break;\r
618\r
619 case 'd':\r
620 if ((Flags & LONG_TYPE) == LONG_TYPE) {\r
621 Value = VA_ARG (Marker, UINT64);\r
622 } else {\r
623 Value = (UINTN) VA_ARG (Marker, UINTN);\r
624 }\r
625\r
626 EfiValueToString (TempBuffer, Value, Flags, Width);\r
627 UnicodeStr = TempBuffer;\r
628\r
629 for (; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {\r
630 Buffer[Index++] = *UnicodeStr;\r
631 }\r
632 break;\r
633\r
634 case 's':\r
635 case 'S':\r
636 UnicodeStr = (CHAR16 *) VA_ARG (Marker, CHAR_W *);\r
637 if (UnicodeStr == NULL) {\r
638 UnicodeStr = L"<null string>";\r
639 }\r
640\r
641 for (Count = 0; (*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++, Count++) {\r
642 Buffer[Index++] = *UnicodeStr;\r
643 }\r
644 //\r
645 // Add padding if needed\r
646 //\r
647 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {\r
648 Buffer[Index++] = ' ';\r
649 }\r
650\r
651 break;\r
652\r
653 case 'a':\r
654 AsciiStr = (CHAR8 *) VA_ARG (Marker, CHAR8 *);\r
655 if (AsciiStr == NULL) {\r
57d40fe2 656 AsciiStr = (CHAR8 *) "<null string>";\r
3eb9473e 657 }\r
658\r
659 for (Count = 0; (*AsciiStr != '\0') && (Index < NumberOfCharacters - 1); AsciiStr++, Count++) {\r
660 Buffer[Index++] = (CHAR_W) * AsciiStr;\r
661 }\r
662 //\r
663 // Add padding if needed\r
664 //\r
665 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {\r
666 Buffer[Index++] = ' ';\r
667 }\r
668 break;\r
669\r
670 case 'c':\r
671 Buffer[Index++] = (CHAR_W) VA_ARG (Marker, UINTN);\r
672 break;\r
673\r
674 case 'g':\r
675 TmpGUID = VA_ARG (Marker, EFI_GUID *);\r
676 if (TmpGUID != NULL) {\r
677 Index += GuidToString (\r
678 TmpGUID,\r
679 &Buffer[Index],\r
680 BufferLeft\r
681 );\r
682 }\r
683 break;\r
684\r
685 case 't':\r
686 Index += TimeToString (\r
687 VA_ARG (Marker, EFI_TIME *), \r
688 &Buffer[Index],\r
689 BufferLeft\r
690 );\r
691 break;\r
692\r
693 case 'r':\r
694 Index += EfiStatusToString (\r
695 VA_ARG (Marker, EFI_STATUS), \r
696 &Buffer[Index],\r
697 BufferLeft\r
698 );\r
699 break;\r
700\r
701 case '%':\r
702 Buffer[Index++] = *Format;\r
703 break;\r
704\r
705 default:\r
706 //\r
707 // if the type is unknown print it to the screen\r
708 //\r
709 Buffer[Index++] = *Format;\r
710 }\r
711\r
712 BufferLeft = BufferSize - Index * sizeof (CHAR_W);\r
713 }\r
714 }\r
715\r
716 Buffer[Index++] = '\0';\r
717\r
718 return &Buffer[Index] - StartOfBuffer;\r
719}\r
720\r
721STATIC\r
722CHAR_W *\r
723GetFlagsAndWidth (\r
724 IN CHAR_W *Format,\r
725 OUT UINTN *Flags,\r
726 OUT UINTN *Width,\r
727 IN OUT VA_LIST *Marker\r
728 )\r
729/*++\r
730\r
731Routine Description:\r
732\r
733 VSPrint worker function that parses flag and width information from the \r
734 Format string and returns the next index into the Format string that needs\r
735 to be parsed. See file headed for details of Flag and Width.\r
736\r
737Arguments:\r
738\r
739 Format - Current location in the VSPrint format string.\r
740\r
741 Flags - Returns flags\r
742\r
743 Width - Returns width of element\r
744\r
745 Marker - Vararg list that may be paritally consumed and returned.\r
746\r
747Returns: \r
748\r
749 Pointer indexed into the Format string for all the information parsed\r
750 by this routine.\r
751\r
752--*/\r
753{\r
754 UINTN Count;\r
755 BOOLEAN Done;\r
756\r
757 *Flags = 0;\r
758 *Width = 0;\r
759 for (Done = FALSE; !Done;) {\r
760 Format++;\r
761\r
762 switch (*Format) {\r
763\r
764 case '-':\r
765 *Flags |= LEFT_JUSTIFY;\r
766 break;\r
767\r
768 case '+':\r
769 *Flags |= PREFIX_SIGN;\r
770 break;\r
771\r
772 case ' ':\r
773 *Flags |= PREFIX_BLANK;\r
774 break;\r
775\r
776 case ',':\r
777 *Flags |= COMMA_TYPE;\r
778 break;\r
779\r
780 case 'L':\r
781 case 'l':\r
782 *Flags |= LONG_TYPE;\r
783 break;\r
784\r
785 case '*':\r
786 *Width = VA_ARG (*Marker, UINTN);\r
787 break;\r
788\r
789 case '0':\r
790 *Flags |= PREFIX_ZERO;\r
791\r
792 case '1':\r
793 case '2':\r
794 case '3':\r
795 case '4':\r
796 case '5':\r
797 case '6':\r
798 case '7':\r
799 case '8':\r
800 case '9':\r
801 Count = 0;\r
802 do {\r
803 Count = (Count * 10) +*Format - '0';\r
804 Format++;\r
805 } while ((*Format >= '0') && (*Format <= '9'));\r
806 Format--;\r
807 *Width = Count;\r
808 break;\r
809\r
810 default:\r
811 Done = TRUE;\r
812 }\r
813 }\r
814\r
815 return Format;\r
816}\r
817\r
818STATIC\r
819UINTN\r
820GuidToString (\r
821 IN EFI_GUID *Guid,\r
822 IN CHAR_W *Buffer,\r
823 IN UINTN BufferSize\r
824 )\r
825/*++\r
826\r
827Routine Description:\r
828\r
829 VSPrint worker function that prints an EFI_GUID.\r
830\r
831Arguments:\r
832\r
833 Guid - Pointer to GUID to print.\r
834\r
835 Buffer - Buffe to print Guid into.\r
836 \r
837 BufferSize - Size of Buffer.\r
838\r
839Returns: \r
840\r
841 Number of characters printed. \r
842\r
843--*/\r
844{\r
845 UINTN Size;\r
846\r
847 Size = SPrint (\r
848 Buffer,\r
849 BufferSize,\r
850 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),\r
851 (UINTN)Guid->Data1,\r
852 (UINTN)Guid->Data2,\r
853 (UINTN)Guid->Data3,\r
854 (UINTN)Guid->Data4[0],\r
855 (UINTN)Guid->Data4[1],\r
856 (UINTN)Guid->Data4[2],\r
857 (UINTN)Guid->Data4[3],\r
858 (UINTN)Guid->Data4[4],\r
859 (UINTN)Guid->Data4[5],\r
860 (UINTN)Guid->Data4[6],\r
861 (UINTN)Guid->Data4[7]\r
862 );\r
863\r
864 //\r
865 // SPrint will null terminate the string. The -1 skips the null\r
866 //\r
867 return Size - 1;\r
868}\r
869\r
870\r
871STATIC\r
872UINTN\r
873TimeToString (\r
874 IN EFI_TIME *Time,\r
875 OUT CHAR_W *Buffer,\r
876 IN UINTN BufferSize\r
877 )\r
878/*++\r
879\r
880Routine Description:\r
881\r
882 VSPrint worker function that prints EFI_TIME.\r
883\r
884Arguments:\r
885\r
886 Time - Pointer to EFI_TIME sturcture to print.\r
887\r
888 Buffer - Buffer to print Time into.\r
889 \r
890 BufferSize - Size of Buffer.\r
891\r
892Returns: \r
893\r
894 Number of characters printed. \r
895\r
896--*/\r
897{\r
898 UINTN Size;\r
899\r
900 Size = SPrint (\r
901 Buffer,\r
902 BufferSize,\r
903 STRING_W ("%02d/%02d/%04d %02d:%02d"),\r
904 (UINTN)Time->Month,\r
905 (UINTN)Time->Day,\r
906 (UINTN)Time->Year,\r
907 (UINTN)Time->Hour,\r
908 (UINTN)Time->Minute\r
909 );\r
910\r
911 //\r
912 // SPrint will null terminate the string. The -1 skips the null\r
913 //\r
914 return Size - 1;\r
915}\r
916\r
917STATIC\r
918UINTN\r
919EfiStatusToString (\r
920 IN EFI_STATUS Status,\r
921 OUT CHAR_W *Buffer,\r
922 IN UINTN BufferSize\r
923 )\r
924/*++\r
925\r
926Routine Description:\r
927\r
928 VSPrint worker function that prints EFI_STATUS as a string. If string is\r
929 not known a hex value will be printed.\r
930\r
931Arguments:\r
932\r
933 Status - EFI_STATUS sturcture to print.\r
934\r
935 Buffer - Buffer to print EFI_STATUS message string into.\r
936 \r
937 BufferSize - Size of Buffer.\r
938\r
939Returns: \r
940\r
941 Number of characters printed. \r
942\r
943--*/\r
944{\r
945 UINTN Size;\r
946 CHAR8 *Desc;\r
947\r
948 Desc = NULL;\r
949 \r
950 //\r
951 // Can't use global Status String Array as UINTN is not constant for EBC\r
952 //\r
57d40fe2 953 if (Status == EFI_SUCCESS) { Desc = (CHAR8 *) "Success"; } else \r
954 if (Status == EFI_LOAD_ERROR) { Desc = (CHAR8 *) "Load Error"; } else\r
955 if (Status == EFI_INVALID_PARAMETER) { Desc = (CHAR8 *) "Invalid Parameter"; } else\r
956 if (Status == EFI_UNSUPPORTED) { Desc = (CHAR8 *) "Unsupported"; } else\r
957 if (Status == EFI_BAD_BUFFER_SIZE) { Desc = (CHAR8 *) "Bad Buffer Size"; } else\r
958 if (Status == EFI_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Buffer Too Small"; } else\r
959 if (Status == EFI_NOT_READY) { Desc = (CHAR8 *) "Not Ready"; } else\r
960 if (Status == EFI_DEVICE_ERROR) { Desc = (CHAR8 *) "Device Error"; } else\r
961 if (Status == EFI_WRITE_PROTECTED) { Desc = (CHAR8 *) "Write Protected"; } else\r
962 if (Status == EFI_OUT_OF_RESOURCES) { Desc = (CHAR8 *) "Out of Resources"; } else\r
963 if (Status == EFI_VOLUME_CORRUPTED) { Desc = (CHAR8 *) "Volume Corrupt"; } else\r
964 if (Status == EFI_VOLUME_FULL) { Desc = (CHAR8 *) "Volume Full"; } else\r
965 if (Status == EFI_NO_MEDIA) { Desc = (CHAR8 *) "No Media"; } else\r
966 if (Status == EFI_MEDIA_CHANGED) { Desc = (CHAR8 *) "Media changed"; } else\r
967 if (Status == EFI_NOT_FOUND) { Desc = (CHAR8 *) "Not Found"; } else\r
968 if (Status == EFI_ACCESS_DENIED) { Desc = (CHAR8 *) "Access Denied"; } else\r
969 if (Status == EFI_NO_RESPONSE) { Desc = (CHAR8 *) "No Response"; } else\r
970 if (Status == EFI_NO_MAPPING) { Desc = (CHAR8 *) "No mapping"; } else\r
971 if (Status == EFI_TIMEOUT) { Desc = (CHAR8 *) "Time out"; } else\r
972 if (Status == EFI_NOT_STARTED) { Desc = (CHAR8 *) "Not started"; } else\r
973 if (Status == EFI_ALREADY_STARTED) { Desc = (CHAR8 *) "Already started"; } else\r
974 if (Status == EFI_ABORTED) { Desc = (CHAR8 *) "Aborted"; } else\r
975 if (Status == EFI_ICMP_ERROR) { Desc = (CHAR8 *) "ICMP Error"; } else\r
976 if (Status == EFI_TFTP_ERROR) { Desc = (CHAR8 *) "TFTP Error"; } else\r
977 if (Status == EFI_PROTOCOL_ERROR) { Desc = (CHAR8 *) "Protocol Error"; } else\r
978 if (Status == EFI_WARN_UNKNOWN_GLYPH) { Desc = (CHAR8 *) "Warning Unknown Glyph"; } else\r
979 if (Status == EFI_WARN_DELETE_FAILURE) { Desc = (CHAR8 *) "Warning Delete Failure"; } else\r
980 if (Status == EFI_WARN_WRITE_FAILURE) { Desc = (CHAR8 *) "Warning Write Failure"; } else\r
981 if (Status == EFI_WARN_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Warning Buffer Too Small"; } \r
3eb9473e 982\r
983 //\r
984 // If we found a match, copy the message to the user's buffer. Otherwise\r
985 // sprint the hex status code to their buffer.\r
986 //\r
987 if (Desc != NULL) {\r
988 Size = SPrint (Buffer, BufferSize, STRING_W ("%a"), Desc);\r
989 } else {\r
990 Size = SPrint (Buffer, BufferSize, STRING_W ("%X"), Status);\r
991 }\r
992\r
993 return Size - 1;\r
994}\r