git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@263 6f19259b...
[mirror_edk2.git] / MdePkg / Library / BasePrintLib / PrintLib.c
CommitLineData
878ddf1f 1/** @file\r
2 Print Library.\r
3\r
4 Copyright (c) 2006, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 Module Name: PrintLib.c\r
14\r
15**/\r
16\r
17#include "PrintLibInternal.h"\r
18\r
19typedef struct {\r
20 RETURN_STATUS Status;\r
21 CHAR8 *String;\r
22} STATUS_LOOKUP_TABLE_ENTRY;\r
23\r
24static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString[] = {\r
25 { RETURN_SUCCESS, "Success" },\r
26 { RETURN_LOAD_ERROR, "Load Error" },\r
27 { RETURN_INVALID_PARAMETER, "Invalid Parameter" },\r
28 { RETURN_UNSUPPORTED, "Unsupported" },\r
29 { RETURN_BAD_BUFFER_SIZE, "Bad Buffer Size" },\r
30 { RETURN_BUFFER_TOO_SMALL, "Buffer Too Small" },\r
31 { RETURN_NOT_READY, "Not Ready" },\r
32 { RETURN_DEVICE_ERROR, "Device Error" },\r
33 { RETURN_WRITE_PROTECTED, "Write Protected" },\r
34 { RETURN_OUT_OF_RESOURCES, "Out of Resources" },\r
35 { RETURN_VOLUME_CORRUPTED, "Volume Corrupt" },\r
36 { RETURN_VOLUME_FULL, "Volume Full" },\r
37 { RETURN_NO_MEDIA, "No Media" },\r
38 { RETURN_MEDIA_CHANGED, "Media changed" },\r
39 { RETURN_NOT_FOUND, "Not Found" },\r
40 { RETURN_ACCESS_DENIED, "Access Denied" },\r
41 { RETURN_NO_RESPONSE, "No Response" },\r
42 { RETURN_NO_MAPPING, "No mapping" },\r
43 { RETURN_TIMEOUT, "Time out" },\r
44 { RETURN_NOT_STARTED, "Not started" },\r
45 { RETURN_ALREADY_STARTED, "Already started" },\r
46 { RETURN_ABORTED, "Aborted" },\r
47 { RETURN_ICMP_ERROR, "ICMP Error" },\r
48 { RETURN_TFTP_ERROR, "TFTP Error" },\r
49 { RETURN_PROTOCOL_ERROR, "Protocol Error" },\r
50 { RETURN_WARN_UNKNOWN_GLYPH, "Warning Unknown Glyph" },\r
51 { RETURN_WARN_DELETE_FAILURE, "Warning Delete Failure" },\r
52 { RETURN_WARN_WRITE_FAILURE, "Warning Write Failure" },\r
53 { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" },\r
54 { 0, NULL }\r
55};\r
56\r
57\r
58/**\r
59 VSPrint function to process format and place the results in Buffer. Since a \r
60 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus \r
61 this is the main print working routine\r
62\r
63 @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into.\r
64 \r
65 @param BufferSize Maximum number of characters to put into buffer. Zero means\r
66 no limit.\r
67 \r
68 @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
69 \r
70 @param FormatString Unicode format string see file header for more details.\r
71 \r
72 @param Marker Vararg list consumed by processing Format.\r
73\r
74 @return Number of characters printed.\r
75\r
76**/\r
77UINTN\r
78BasePrintLibVSPrint (\r
79 OUT CHAR8 *Buffer,\r
80 IN UINTN BufferSize,\r
81 IN UINTN Flags,\r
82 IN CONST CHAR8 *Format,\r
83 IN VA_LIST Marker\r
84 )\r
85{\r
86 CHAR8 *OriginalBuffer;\r
87 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
88 UINTN BytesPerOutputCharacter;\r
89 UINTN BytesPerFormatCharacter;\r
90 UINTN FormatMask;\r
91 UINTN FormatCharacter;\r
92 UINTN Width;\r
93 UINTN Precision;\r
94 INT64 Value;\r
95 CHAR8 *ArgumentString;\r
96 UINTN Character;\r
97 GUID *TmpGuid;\r
98 TIME *TmpTime;\r
99 UINTN Count;\r
100 UINTN ArgumentMask;\r
101 INTN BytesPerArgumentCharacter;\r
102 UINTN ArgumentCharacter;\r
103 BOOLEAN Done;\r
104 UINTN Index;\r
105 CHAR8 Prefix;\r
106 BOOLEAN ZeroPad;\r
107 BOOLEAN Comma;\r
108 UINTN Digits;\r
109 UINTN Radix;\r
110 RETURN_STATUS Status;\r
111\r
112 OriginalBuffer = Buffer;\r
113\r
114 if ((Flags & OUTPUT_UNICODE) != 0) {\r
115 BytesPerOutputCharacter = 2;\r
116 } else {\r
117 BytesPerOutputCharacter = 1;\r
118 }\r
119 if ((Flags & FORMAT_UNICODE) != 0) {\r
120 BytesPerFormatCharacter = 2;\r
121 FormatMask = 0xffff;\r
122 } else {\r
123 BytesPerFormatCharacter = 1;\r
124 FormatMask = 0xff;\r
125 }\r
126\r
127 //\r
128 // Reserve space for the Null terminator.\r
129 // If BufferSize is 0, this will set BufferSize to the max unsigned value\r
130 //\r
131 BufferSize--;\r
132\r
133 //\r
134 // Get the first character from the format string\r
135 //\r
da4aa0f2 136 FormatCharacter = (*Format | (*(Format - 1) << 8)) & FormatMask;\r
878ddf1f 137\r
138 //\r
139 // Loop until the end of the format string is reached or the output buffer is full\r
140 //\r
141 while (FormatCharacter != 0 && BufferSize > 0) {\r
142 //\r
143 // Clear all the flag bits except those that may have been passed in\r
144 //\r
145 Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE);\r
146\r
147 //\r
148 // Set the default width to zero, and the default precision to 1\r
149 //\r
150 Width = 0;\r
151 Precision = 1;\r
152 Prefix = 0;\r
153 Comma = FALSE;\r
154 ZeroPad = FALSE;\r
155 Count = 0;\r
156 Digits = 0;\r
157\r
158 switch (FormatCharacter) {\r
159 case '%':\r
160 //\r
161 // Parse Flags and Width\r
162 //\r
163 for (Done = FALSE; !Done; ) {\r
164 Format += BytesPerFormatCharacter;\r
165 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
166 switch (FormatCharacter) {\r
167 case '.': \r
168 Flags |= PRECISION; \r
169 break;\r
170 case '-': \r
171 Flags |= LEFT_JUSTIFY; \r
172 break;\r
173 case '+': \r
174 Flags |= PREFIX_SIGN; \r
175 break;\r
176 case ' ': \r
177 Flags |= PREFIX_BLANK; \r
178 break;\r
179 case ',': \r
180 Flags |= COMMA_TYPE; \r
181 break;\r
182 case 'L':\r
183 case 'l': \r
184 Flags |= LONG_TYPE; \r
185 break;\r
186 case '*':\r
187 if ((Flags & PRECISION) == 0) {\r
188 Flags |= PAD_TO_WIDTH;\r
189 Width = VA_ARG (Marker, UINTN);\r
190 } else {\r
191 Precision = VA_ARG (Marker, UINTN);\r
192 }\r
193 break;\r
194 case '0':\r
195 if ((Flags & PRECISION) == 0) {\r
196 Flags |= PREFIX_ZERO;\r
197 }\r
198 case '1':\r
199 case '2':\r
200 case '3':\r
201 case '4':\r
202 case '5':\r
203 case '6':\r
204 case '7':\r
205 case '8':\r
206 case '9':\r
207 for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){\r
208 Count = (Count * 10) + FormatCharacter - '0';\r
209 Format += BytesPerFormatCharacter;\r
210 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
211 }\r
212 Format -= BytesPerFormatCharacter;\r
213 if ((Flags & PRECISION) == 0) {\r
214 Flags |= PAD_TO_WIDTH;\r
215 Width = Count;\r
216 } else {\r
217 Precision = Count;\r
218 }\r
219 break;\r
220 default:\r
221 Done = TRUE;\r
222 break;\r
223 }\r
224 } \r
225\r
226 //\r
227 // Limit the maximum field width to the remaining characters in the output buffer\r
228 //\r
229 if (Width > BufferSize) {\r
230 Width = BufferSize;\r
231 }\r
232\r
233 //\r
234 // Handle each argument type\r
235 //\r
236 switch (FormatCharacter) {\r
237 case 'X':\r
238 Flags |= PREFIX_ZERO;\r
239 //\r
240 // break skiped on purpose\r
241 //\r
242 case 'x':\r
243 Flags |= RADIX_HEX;\r
244 //\r
245 // break skiped on purpose\r
246 //\r
247 case 'd':\r
248 if ((Flags & LONG_TYPE) == 0) {\r
249 Value = (VA_ARG (Marker, INTN));\r
250 } else {\r
251 Value = VA_ARG (Marker, INT64);\r
252 }\r
253 if ((Flags & PREFIX_BLANK) != 0) {\r
254 Prefix = ' ';\r
255 }\r
256 if ((Flags & PREFIX_SIGN) != 0) {\r
257 Prefix = '+';\r
258 }\r
259 if ((Flags & COMMA_TYPE) != 0) {\r
260 Comma = TRUE;\r
261 }\r
262 if ((Flags & RADIX_HEX) == 0) {\r
263 Radix = 10;\r
264 if (Comma) {\r
265 Flags &= (~PREFIX_ZERO);\r
266 Precision = 1;\r
267 }\r
268 if (Value < 0) {\r
269 Flags |= PREFIX_SIGN;\r
270 Prefix = '-';\r
271 Value = -Value;\r
272 }\r
273 } else {\r
274 Radix = 16;\r
275 Comma = FALSE;\r
276 if ((Flags & LONG_TYPE) == 0 && Value < 0) {\r
277 Value = (UINTN)Value;\r
278 }\r
279 }\r
280 //\r
281 // Convert Value to a reversed string\r
282 //\r
283 Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
284 if (Value == 0 && Precision == 0) {\r
285 Count = 0;\r
286 }\r
287 ArgumentString = (CHAR8 *)ValueBuffer + Count;\r
288 Digits = 3 - (Count % 3);\r
289 if (Comma && Count != 0) {\r
290 Count += ((Count - 1) / 3);\r
291 }\r
292 if (Prefix != 0) {\r
293 Count++;\r
294 }\r
295 Flags |= ARGUMENT_REVERSED;\r
296 ZeroPad = TRUE;\r
297 if ((Flags & PREFIX_ZERO) != 0) {\r
298 if ((Flags & PAD_TO_WIDTH) != 0) {\r
299 if ((Flags & PRECISION) == 0) {\r
300 Precision = Width;\r
301 }\r
302 }\r
303 }\r
304 break;\r
305\r
306 case 's':\r
307 case 'S':\r
308 Flags |= ARGUMENT_UNICODE;\r
309 //\r
310 // break skipped on purpose\r
311 //\r
312 case 'a':\r
313 ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);\r
314 if (ArgumentString == NULL) {\r
315 Flags &= (~ARGUMENT_UNICODE);\r
316 ArgumentString = "<null string>";\r
317 }\r
318 break;\r
319\r
320 case 'c':\r
321 Character = VA_ARG (Marker, UINTN) & 0xffff;\r
322 ArgumentString = (CHAR8 *)&Character;\r
323 Flags |= ARGUMENT_UNICODE;\r
324 break;\r
325\r
326 case 'g':\r
327 TmpGuid = VA_ARG (Marker, GUID *);\r
328 if (TmpGuid == NULL) {\r
329 ArgumentString = "<null guid>";\r
330 } else {\r
331 BasePrintLibSPrint (\r
332 ValueBuffer,\r
333 0, \r
334 0,\r
335 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
da4aa0f2 336 (UINTN) TmpGuid->Data1,\r
337 (UINTN) TmpGuid->Data2,\r
338 (UINTN) TmpGuid->Data3,\r
339 (UINTN) TmpGuid->Data4[0],\r
340 (UINTN) TmpGuid->Data4[1],\r
341 (UINTN) TmpGuid->Data4[2],\r
342 (UINTN) TmpGuid->Data4[3],\r
343 (UINTN) TmpGuid->Data4[4],\r
344 (UINTN) TmpGuid->Data4[5],\r
345 (UINTN) TmpGuid->Data4[6],\r
346 (UINTN) TmpGuid->Data4[7]\r
878ddf1f 347 );\r
348 ArgumentString = ValueBuffer;\r
349 }\r
350 break;\r
351\r
352 case 't':\r
353 TmpTime = VA_ARG (Marker, TIME *); \r
354 if (TmpTime == NULL) {\r
355 ArgumentString = "<null time>";\r
356 } else {\r
357 BasePrintLibSPrint (\r
358 ValueBuffer,\r
359 0,\r
360 0,\r
361 "%02d/%02d/%04d %02d:%02d",\r
da4aa0f2 362 (UINTN) TmpTime->Month,\r
363 (UINTN) TmpTime->Day,\r
364 (UINTN) TmpTime->Year,\r
365 (UINTN) TmpTime->Hour,\r
366 (UINTN) TmpTime->Minute\r
878ddf1f 367 );\r
368 ArgumentString = ValueBuffer;\r
369 }\r
370 break;\r
371\r
372 case 'r':\r
373 Status = VA_ARG (Marker, RETURN_STATUS);\r
374 ArgumentString = ValueBuffer;\r
375 for (Index = 0; StatusString[Index].String != NULL; Index++) {\r
376 if (Status == StatusString[Index].Status) {\r
377 ArgumentString = StatusString[Index].String;\r
378 }\r
379 }\r
380 if (ArgumentString == ValueBuffer) {\r
381 BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status);\r
382 }\r
383 break;\r
384\r
385 case '%':\r
386 default:\r
387 //\r
388 // if the type is '%' or unknown, then print it to the screen\r
389 //\r
390 ArgumentString = (CHAR8 *)&FormatCharacter;\r
391 Flags |= ARGUMENT_UNICODE;\r
392 break;\r
393 }\r
394 break;\r
395 case '\n':\r
396 ArgumentString = "\r\n";\r
397 break;\r
398 default:\r
399 ArgumentString = (CHAR8 *)&FormatCharacter;\r
400 Flags |= ARGUMENT_UNICODE;\r
401 break;\r
402 }\r
403\r
404 //\r
405 // Retrieve the ArgumentString attriubutes\r
406 //\r
407 if ((Flags & ARGUMENT_UNICODE) != 0) {\r
408 ArgumentMask = 0xffff;\r
409 BytesPerArgumentCharacter = 2;\r
410 } else {\r
411 ArgumentMask = 0xff;\r
412 BytesPerArgumentCharacter = 1;\r
413 }\r
414 if ((Flags & ARGUMENT_REVERSED) != 0) {\r
415 BytesPerArgumentCharacter = -BytesPerArgumentCharacter;\r
416 } else {\r
417 //\r
418 // Compute the number of characters in ArgumentString and store it in Count\r
419 // ArgumentString is either null-terminated, or it contains Precision characters\r
420 //\r
421 for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {\r
422 ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;\r
423 if (ArgumentCharacter == 0) {\r
424 break;\r
425 }\r
426 }\r
427 }\r
428\r
429 //\r
430 // Limit the length of the string to append to the remaining characters in the output buffer\r
431 //\r
432 if (Count > BufferSize) {\r
433 Count = BufferSize;\r
434 }\r
435 if (Precision < Count) {\r
436 Precision = Count;\r
437 }\r
438\r
439 //\r
440 // Pad before the string\r
441 //\r
442 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {\r
443 Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
444 }\r
445\r
446 if (ZeroPad) {\r
447 if (Prefix != 0) {\r
448 Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);\r
449 }\r
450 Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter);\r
451 } else {\r
452 Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter);\r
453 if (Prefix != 0) {\r
454 Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);\r
455 }\r
456 }\r
457\r
458 //\r
459 // Output the Prefix character if it is present\r
460 //\r
461 Index = 0;\r
462 if (Prefix) {\r
463 Index++;\r
464 }\r
465\r
466 //\r
467 // Copy the string into the output buffer performing the required type conversions\r
468 //\r
469 while (Index < Count) {\r
470 ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;\r
471\r
472 Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter);\r
473 ArgumentString += BytesPerArgumentCharacter;\r
474 Index++;\r
475 if (Comma) {\r
476 Digits++;\r
477 if (Digits == 3) {\r
478 Digits = 0;\r
479 Index++;\r
480 if (Index < Count) {\r
481 Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter);\r
482 }\r
483 }\r
484 }\r
485 }\r
486\r
487 //\r
488 // Pad after the string\r
489 //\r
490 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {\r
491 Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
492 }\r
493\r
494 //\r
495 // Reduce the number of characters\r
496 //\r
497 BufferSize -= Count;\r
498\r
499 //\r
500 // Get the next character from the format string\r
501 //\r
502 Format += BytesPerFormatCharacter;\r
503\r
504 //\r
505 // Get the next character from the format string\r
506 //\r
507 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
508 }\r
509\r
510 //\r
511 // Null terminate the Unicode or ASCII string\r
512 //\r
513 Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter);\r
514 \r
515 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);\r
516}\r
517\r
518UINTN\r
519BasePrintLibSPrint (\r
520 OUT CHAR8 *StartOfBuffer,\r
521 IN UINTN BufferSize,\r
522 IN UINTN Flags,\r
523 IN CONST CHAR8 *FormatString,\r
524 ...\r
525 )\r
526{\r
527 VA_LIST Marker;\r
528\r
529 VA_START (Marker, FormatString);\r
530 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);\r
531}\r
532\r
533UINTN\r
534EFIAPI\r
535UnicodeVSPrint (\r
536 OUT CHAR16 *StartOfBuffer,\r
537 IN UINTN BufferSize,\r
538 IN CONST CHAR16 *FormatString,\r
539 IN VA_LIST Marker\r
540 )\r
541{\r
542 return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker);\r
543}\r
544\r
545UINTN\r
546EFIAPI\r
547UnicodeSPrint (\r
548 OUT CHAR16 *StartOfBuffer,\r
549 IN UINTN BufferSize,\r
550 IN CONST CHAR16 *FormatString,\r
551 ...\r
552 )\r
553{\r
554 VA_LIST Marker;\r
555\r
556 VA_START (Marker, FormatString);\r
557 return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
558}\r
559\r
560UINTN\r
561EFIAPI\r
562UnicodeVSPrintAsciiFormat (\r
563 OUT CHAR16 *StartOfBuffer,\r
564 IN UINTN BufferSize,\r
565 IN CONST CHAR8 *FormatString,\r
566 IN VA_LIST Marker\r
567 )\r
568{\r
569 return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker);\r
570}\r
571\r
572UINTN\r
573EFIAPI\r
574UnicodeSPrintAsciiFormat (\r
575 OUT CHAR16 *StartOfBuffer,\r
576 IN UINTN BufferSize,\r
577 IN CONST CHAR8 *FormatString,\r
578 ...\r
579 )\r
580{\r
581 VA_LIST Marker;\r
582\r
583 VA_START (Marker, FormatString);\r
584 return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker);\r
585}\r
586\r
587UINTN\r
588EFIAPI\r
589AsciiVSPrint (\r
590 OUT CHAR8 *StartOfBuffer,\r
591 IN UINTN BufferSize,\r
592 IN CONST CHAR8 *FormatString,\r
593 IN VA_LIST Marker\r
594 )\r
595{\r
596 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker);\r
597}\r
598\r
599UINTN\r
600EFIAPI\r
601AsciiSPrint (\r
602 OUT CHAR8 *StartOfBuffer,\r
603 IN UINTN BufferSize,\r
604 IN CONST CHAR8 *FormatString,\r
605 ...\r
606 )\r
607{\r
608 VA_LIST Marker;\r
609\r
610 VA_START (Marker, FormatString);\r
611 return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
612}\r
613\r
614UINTN\r
615EFIAPI\r
616AsciiVSPrintUnicodeFormat (\r
617 OUT CHAR8 *StartOfBuffer,\r
618 IN UINTN BufferSize,\r
619 IN CONST CHAR16 *FormatString,\r
620 IN VA_LIST Marker\r
621 )\r
622{\r
623 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker);\r
624}\r
625\r
626UINTN\r
627EFIAPI\r
628AsciiSPrintUnicodeFormat (\r
629 OUT CHAR8 *StartOfBuffer,\r
630 IN UINTN BufferSize,\r
631 IN CONST CHAR16 *FormatString,\r
632 ...\r
633 )\r
634{\r
635 VA_LIST Marker;\r
636\r
637 VA_START (Marker, FormatString);\r
638 return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
639}\r