]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Application/Shell/ConsoleLogger.c
fix comments.
[mirror_edk2.git] / ShellPkg / Application / Shell / ConsoleLogger.c
CommitLineData
a405b86d 1/** @file\r
2 Provides interface to shell console logger.\r
3\r
4 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
5 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\r
14#include "ConsoleLogger.h"\r
15#include "Shell.h"\r
16\r
17STATIC CONST CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
18\r
19/**\r
20 Install our intermediate ConOut into the system table to\r
21 keep a log of all the info that is displayed to the user.\r
22\r
23 @param[in] ScreensToSave Sets how many screen-worths of data to save.\r
24 @param[out] ConsoleInfo The object to pass into later functions.\r
25\r
26 @retval EFI_SUCCESS The operation was successful.\r
27 @return other The operation failed.\r
28\r
29 @sa ConsoleLoggerResetBuffers\r
30 @sa InstallProtocolInterface\r
31**/\r
32EFI_STATUS\r
33EFIAPI\r
34ConsoleLoggerInstall(\r
35 IN CONST UINTN ScreensToSave,\r
36 OUT CONSOLE_LOGGER_PRIVATE_DATA **ConsoleInfo\r
37 )\r
38{\r
39 EFI_STATUS Status;\r
40 ASSERT(ConsoleInfo != NULL);\r
41\r
3c865f20 42 (*ConsoleInfo) = AllocatePool(sizeof(CONSOLE_LOGGER_PRIVATE_DATA));\r
43 if ((*ConsoleInfo) == NULL) {\r
44 return (EFI_OUT_OF_RESOURCES);\r
45 }\r
a405b86d 46\r
47 (*ConsoleInfo)->Signature = CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE;\r
48 (*ConsoleInfo)->OldConOut = NULL;\r
49 (*ConsoleInfo)->OldConHandle = NULL;\r
50 (*ConsoleInfo)->Buffer = NULL;\r
51 (*ConsoleInfo)->BufferSize = 0;\r
52 (*ConsoleInfo)->OriginalStartRow = 0;\r
53 (*ConsoleInfo)->CurrentStartRow = 0;\r
54 (*ConsoleInfo)->RowsPerScreen = 0;\r
55 (*ConsoleInfo)->ColsPerScreen = 0;\r
56 (*ConsoleInfo)->Attributes = NULL;\r
57 (*ConsoleInfo)->AttribSize = 0;\r
58 (*ConsoleInfo)->ScreenCount = ScreensToSave;\r
59 (*ConsoleInfo)->HistoryMode.MaxMode = 1;\r
60 (*ConsoleInfo)->HistoryMode.Mode = 0;\r
61 (*ConsoleInfo)->HistoryMode.Attribute = 0;\r
62 (*ConsoleInfo)->HistoryMode.CursorColumn = 0;\r
63 (*ConsoleInfo)->HistoryMode.CursorRow = 0;\r
64 (*ConsoleInfo)->HistoryMode.CursorVisible = FALSE;\r
65 (*ConsoleInfo)->OurConOut.Reset = ConsoleLoggerReset;\r
66 (*ConsoleInfo)->OurConOut.OutputString = ConsoleLoggerOutputString;\r
67 (*ConsoleInfo)->OurConOut.TestString = ConsoleLoggerTestString;\r
68 (*ConsoleInfo)->OurConOut.QueryMode = ConsoleLoggerQueryMode;\r
69 (*ConsoleInfo)->OurConOut.SetMode = ConsoleLoggerSetMode;\r
70 (*ConsoleInfo)->OurConOut.SetAttribute = ConsoleLoggerSetAttribute;\r
71 (*ConsoleInfo)->OurConOut.ClearScreen = ConsoleLoggerClearScreen;\r
72 (*ConsoleInfo)->OurConOut.SetCursorPosition = ConsoleLoggerSetCursorPosition;\r
73 (*ConsoleInfo)->OurConOut.EnableCursor = ConsoleLoggerEnableCursor;\r
74 (*ConsoleInfo)->OurConOut.Mode = NULL;\r
75 (*ConsoleInfo)->Enabled = TRUE;\r
76\r
77 Status = ConsoleLoggerResetBuffers(*ConsoleInfo);\r
78 if (EFI_ERROR(Status)) {\r
8be0ba36 79 SHELL_FREE_NON_NULL((*ConsoleInfo));\r
80 *ConsoleInfo = NULL;\r
a405b86d 81 return (Status);\r
82 }\r
83\r
84 Status = gBS->InstallProtocolInterface(&gImageHandle, &gEfiSimpleTextOutProtocolGuid, EFI_NATIVE_INTERFACE, (VOID*)&((*ConsoleInfo)->OurConOut));\r
8be0ba36 85 if (EFI_ERROR(Status)) {\r
86 SHELL_FREE_NON_NULL((*ConsoleInfo)->Buffer);\r
87 SHELL_FREE_NON_NULL((*ConsoleInfo)->Attributes);\r
88 SHELL_FREE_NON_NULL((*ConsoleInfo));\r
89 *ConsoleInfo = NULL;\r
90 return (Status);\r
91 }\r
a405b86d 92\r
93 (*ConsoleInfo)->OldConOut = gST->ConOut;\r
94 (*ConsoleInfo)->OldConHandle = gST->ConsoleOutHandle;\r
95\r
96 gST->ConsoleOutHandle = gImageHandle;\r
97 gST->ConOut = &(*ConsoleInfo)->OurConOut;\r
98\r
99 return (Status);\r
100}\r
101\r
102/**\r
103 Return the system to the state it was before InstallConsoleLogger\r
104 was installed.\r
105\r
106 @param[in,out] ConsoleInfo The object from the install function.\r
107\r
108 @retval EFI_SUCCESS The operation was successful\r
109 @return other The operation failed. This was from UninstallProtocolInterface.\r
110**/\r
111EFI_STATUS\r
112EFIAPI\r
113ConsoleLoggerUninstall(\r
114 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
115 )\r
116{\r
117 ASSERT(ConsoleInfo != NULL);\r
118 ASSERT(ConsoleInfo->OldConOut != NULL);\r
119\r
120 if (ConsoleInfo->Buffer != NULL) {\r
121 FreePool(ConsoleInfo->Buffer);\r
122 DEBUG_CODE(ConsoleInfo->Buffer = NULL;);\r
123 DEBUG_CODE(ConsoleInfo->BufferSize = 0;);\r
124 }\r
125 if (ConsoleInfo->Attributes != NULL) {\r
126 FreePool(ConsoleInfo->Attributes);\r
127 DEBUG_CODE(ConsoleInfo->Attributes = NULL;);\r
128 DEBUG_CODE(ConsoleInfo->AttribSize = 0;);\r
129 }\r
130\r
131 gST->ConsoleOutHandle = ConsoleInfo->OldConHandle;\r
132 gST->ConOut = ConsoleInfo->OldConOut;\r
133\r
134 return (gBS->UninstallProtocolInterface(gImageHandle, &gEfiSimpleTextOutProtocolGuid, (VOID*)&ConsoleInfo->OurConOut));\r
135}\r
136\r
137/**\r
138 Displays previously logged output back to the screen.\r
139\r
140 This will scroll the screen forwards and backwards through the log of previous\r
141 output. If Rows is 0 then the size of 1/2 the screen will be scrolled. If Rows\r
142 is (UINTN)(-1) then the size of the screen will be scrolled.\r
143\r
144 @param[in] Forward If TRUE then the log will be displayed forwards (scroll to newer).\r
145 If FALSE then the log will be displayed backwards (scroll to older).\r
146 @param[in] Rows Determines how many rows the log should scroll.\r
147 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
148**/\r
149EFI_STATUS\r
150EFIAPI\r
151ConsoleLoggerDisplayHistory(\r
152 IN CONST BOOLEAN Forward,\r
153 IN CONST UINTN Rows,\r
154 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
155 )\r
156{\r
157 UINTN RowChange;\r
158\r
159 ASSERT(ConsoleInfo != NULL);\r
160\r
161 //\r
162 // Calculate the row number change\r
163 //\r
164 switch (Rows) {\r
165 case ((UINTN)(-1)):\r
166 RowChange = ConsoleInfo->RowsPerScreen;\r
167 break;\r
168 case (0):\r
169 RowChange = ConsoleInfo->RowsPerScreen / 2;\r
170 break;\r
171 default:\r
172 RowChange = Rows;\r
173 break;\r
174 }\r
175\r
176 //\r
177 // Do the math for direction\r
178 //\r
179 if (Forward) {\r
180 if ((ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow) < RowChange) {\r
181 RowChange = ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow;\r
182 }\r
183 } else {\r
184 if (ConsoleInfo->CurrentStartRow < RowChange) {\r
185 RowChange = ConsoleInfo->CurrentStartRow;\r
186 }\r
187 }\r
188\r
189 //\r
190 // If we are already at one end or the other\r
191 //\r
192 if (RowChange == 0) {\r
193 return (EFI_SUCCESS);\r
194 }\r
195\r
196 //\r
197 // Clear the screen\r
198 //\r
199 ConsoleInfo->OldConOut->ClearScreen(ConsoleInfo->OldConOut);\r
200\r
201 //\r
202 // Set the new start row\r
203 //\r
204 if (Forward) {\r
205 ConsoleInfo->CurrentStartRow += RowChange;\r
206 } else {\r
207 ConsoleInfo->CurrentStartRow -= RowChange;\r
208 }\r
209\r
210 //\r
211 // Change the screen\r
212 //\r
213 return (UpdateDisplayFromHistory(ConsoleInfo));\r
214}\r
215\r
216/**\r
217 Function to return to normal output whent he scrolling is complete.\r
218 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
219\r
220 @retval EFI_SUCCESS The operation was successful.\r
221 @return other The operation failed. See UpdateDisplayFromHistory.\r
222\r
223 @sa UpdateDisplayFromHistory\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
227ConsoleLoggerStopHistory(\r
228 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
229 )\r
230{\r
231 ASSERT(ConsoleInfo != NULL);\r
232 if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {\r
233 return (EFI_SUCCESS);\r
234 }\r
235 ConsoleInfo->CurrentStartRow = ConsoleInfo->OriginalStartRow;\r
236 return (UpdateDisplayFromHistory(ConsoleInfo));\r
237}\r
238\r
239/**\r
240 Updates the hidden ConOut to be displaying the correct stuff.\r
241 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
242\r
243 @retval EFI_SUCCESS The operation was successful.\r
244 @return other The operation failed.\r
245**/\r
246EFI_STATUS\r
247EFIAPI\r
248UpdateDisplayFromHistory(\r
249 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
250 )\r
251{\r
252 EFI_STATUS Status;\r
253 EFI_STATUS RetVal;\r
254 CHAR16 *Screen;\r
255 INT32 *Attributes;\r
256 UINTN CurrentRow;\r
257 CHAR16 TempCharHolder;\r
258 UINTN Column;\r
259 INT32 CurrentAttrib;\r
260 UINTN CurrentColumn;\r
261 CHAR16 *StringSegment;\r
262 CHAR16 *StringSegmentEnd;\r
263 CHAR16 StringSegmentEndChar;\r
264\r
265 ASSERT(ConsoleInfo != NULL);\r
266 TempCharHolder = CHAR_NULL;\r
267 RetVal = EFI_SUCCESS;\r
268\r
269 //\r
270 // Disable cursor visibility and move it to the top left corner\r
271 //\r
272 ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, FALSE);\r
273 ConsoleInfo->OldConOut->SetCursorPosition (ConsoleInfo->OldConOut, 0, 0);\r
274\r
275 Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];\r
276 Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];\r
277 for ( CurrentRow = 0\r
278 ; CurrentRow < ConsoleInfo->RowsPerScreen\r
279 ; CurrentRow++\r
280 , Screen += (ConsoleInfo->ColsPerScreen + 2)\r
281 , Attributes += ConsoleInfo->ColsPerScreen\r
282 ){\r
283 //\r
284 // dont use the last char - prevents screen scroll\r
285 //\r
286 if (CurrentRow == (ConsoleInfo->RowsPerScreen-1)){\r
287 TempCharHolder = Screen[ConsoleInfo->ColsPerScreen - 1];\r
288 Screen[ConsoleInfo->ColsPerScreen - 1] = CHAR_NULL;\r
289 }\r
290\r
291 for ( Column = 0\r
292 ; Column < ConsoleInfo->ColsPerScreen\r
293 ; Column++\r
294 ){\r
295 if (Screen[Column] != CHAR_NULL) {\r
296 CurrentAttrib = Attributes[Column];\r
297 CurrentColumn = Column;\r
298 StringSegment = &Screen[Column];\r
299\r
300 //\r
301 // Find the first char with a different arrribute and make that temporarily NULL\r
302 // so we can do fewer printout statements. (later) restore that one and we will\r
303 // start at that collumn on the next loop.\r
304 //\r
305 StringSegmentEndChar = CHAR_NULL;\r
306 for ( StringSegmentEnd = StringSegment\r
307 ; StringSegmentEnd != CHAR_NULL\r
308 ; StringSegmentEnd++\r
309 , Column++\r
310 ){\r
311 if (Attributes[Column] != CurrentAttrib) {\r
312 StringSegmentEndChar = *StringSegmentEnd;\r
313 *StringSegmentEnd = CHAR_NULL;\r
314 break;\r
315 }\r
316 } // StringSegmentEnd loop\r
317\r
318 //\r
319 // Now write out as much as had the same Attributes\r
320 //\r
321\r
322 ConsoleInfo->OldConOut->SetAttribute(ConsoleInfo->OldConOut, CurrentAttrib);\r
323 ConsoleInfo->OldConOut->SetCursorPosition(ConsoleInfo->OldConOut, CurrentColumn, CurrentRow);\r
324 Status = ConsoleInfo->OldConOut->OutputString(ConsoleInfo->OldConOut, StringSegment);\r
325\r
326 if (EFI_ERROR(Status)) {\r
327 ASSERT(FALSE);\r
328 RetVal = Status;\r
329 }\r
330\r
331 //\r
332 // If we found a change in attribute put the character back and decrement the column\r
333 // so when it increments it will point at that character and we will start printing\r
334 // a segment with that new attribute\r
335 //\r
336 if (StringSegmentEndChar != CHAR_NULL) {\r
337 *StringSegmentEnd = StringSegmentEndChar;\r
338 StringSegmentEndChar = CHAR_NULL;\r
339 Column--;\r
340 }\r
341 }\r
342 } // column for loop\r
343\r
344 //\r
345 // If we removed the last char and this was the last row put it back\r
346 //\r
347 if (TempCharHolder != CHAR_NULL) {\r
348 Screen[ConsoleInfo->ColsPerScreen - 1] = TempCharHolder;\r
349 TempCharHolder = CHAR_NULL;\r
350 }\r
351 } // row for loop\r
352\r
353 //\r
354 // If we are setting the screen back to original turn on the cursor and make it visible\r
355 // and set the attributes back to what they were\r
356 //\r
357 if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {\r
358 ConsoleInfo->OldConOut->SetAttribute (\r
359 ConsoleInfo->OldConOut,\r
360 ConsoleInfo->HistoryMode.Attribute\r
361 );\r
362 ConsoleInfo->OldConOut->SetCursorPosition (\r
363 ConsoleInfo->OldConOut,\r
364 ConsoleInfo->HistoryMode.CursorColumn,\r
365 ConsoleInfo->HistoryMode.CursorRow - ConsoleInfo->OriginalStartRow\r
366 );\r
367\r
368 Status = ConsoleInfo->OldConOut->EnableCursor (\r
369 ConsoleInfo->OldConOut,\r
370 ConsoleInfo->HistoryMode.CursorVisible\r
371 );\r
372 if (EFI_ERROR (Status)) {\r
373 RetVal = Status;\r
374 }\r
375 }\r
376\r
377 return (RetVal);\r
378}\r
379\r
380/**\r
381 Reset the text output device hardware and optionaly run diagnostics\r
382\r
383 @param This pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
384 @param ExtendedVerification Indicates that a more extensive test may be performed\r
385\r
386 @retval EFI_SUCCESS The text output device was reset.\r
387 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and\r
388 could not be reset.\r
389**/\r
390EFI_STATUS\r
391EFIAPI\r
392ConsoleLoggerReset (\r
393 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
394 IN BOOLEAN ExtendedVerification\r
395 )\r
396{\r
397 EFI_STATUS Status;\r
398 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
399 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
400\r
401 //\r
402 // Forward the request to the original ConOut\r
403 //\r
404 Status = ConsoleInfo->OldConOut->Reset (ConsoleInfo->OldConOut, ExtendedVerification);\r
405\r
406 //\r
407 // Check that the buffers are still correct for logging\r
408 //\r
409 if (!EFI_ERROR (Status)) {\r
410 ConsoleLoggerResetBuffers(ConsoleInfo);\r
411 }\r
412\r
413 return Status;\r
414}\r
415\r
416/**\r
417 Appends a string to the history buffer. If the buffer is full then the oldest\r
418 information in the buffer will be dropped. Information is added in a line by\r
419 line manner such that an empty line takes up just as much space as a full line.\r
420\r
421 @param[in] String String pointer to add.\r
422 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
423**/\r
424EFI_STATUS\r
425EFIAPI\r
426AppendStringToHistory(\r
427 IN CONST CHAR16 *String,\r
428 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
429 )\r
430{\r
431 CONST CHAR16 *Walker;\r
432 UINTN CopySize;\r
433 UINTN PrintIndex;\r
434 UINTN Index;\r
435\r
436 ASSERT(ConsoleInfo != NULL);\r
437\r
438 for ( Walker = String\r
439 ; Walker != NULL && *Walker != CHAR_NULL\r
440 ; Walker++\r
441 ){\r
442 switch (*Walker) {\r
443 case (CHAR_BACKSPACE):\r
444 if (ConsoleInfo->HistoryMode.CursorColumn > 0) {\r
445 ConsoleInfo->HistoryMode.CursorColumn--;\r
446 }\r
447 break;\r
448 case (CHAR_LINEFEED):\r
449 if (ConsoleInfo->HistoryMode.CursorRow >= (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1)) {\r
450 //\r
451 // Should never be bigger\r
452 //\r
453 ASSERT(ConsoleInfo->HistoryMode.CursorRow == (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1));\r
454\r
455 //\r
456 // scroll history attributes 'up' 1 row and set the last row to default attribute\r
457 //\r
458 CopySize = ConsoleInfo->ColsPerScreen\r
459 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)\r
460 * sizeof(ConsoleInfo->Attributes[0]);\r
461 ASSERT(CopySize < ConsoleInfo->AttribSize);\r
462 CopyMem(\r
463 ConsoleInfo->Attributes,\r
464 ConsoleInfo->Attributes + ConsoleInfo->ColsPerScreen,\r
465 CopySize\r
466 );\r
467\r
468 for ( Index = 0\r
469 ; Index < ConsoleInfo->ColsPerScreen\r
470 ; Index++\r
471 ){\r
472 *(ConsoleInfo->Attributes + (CopySize/sizeof(ConsoleInfo->Attributes)) + Index) = ConsoleInfo->HistoryMode.Attribute;\r
473 }\r
474\r
475 //\r
476 // scroll history buffer 'up' 1 row and set the last row to spaces (L' ')\r
477 //\r
478 CopySize = (ConsoleInfo->ColsPerScreen + 2)\r
479 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)\r
480 * sizeof(ConsoleInfo->Buffer[0]);\r
481 ASSERT(CopySize < ConsoleInfo->BufferSize);\r
482 CopyMem(\r
483 ConsoleInfo->Buffer,\r
484 ConsoleInfo->Buffer + (ConsoleInfo->ColsPerScreen + 2),\r
485 CopySize\r
486 );\r
487\r
488 //\r
489 // Set that last row of chars to spaces\r
490 //\r
491 SetMem16(((UINT8*)ConsoleInfo->Buffer)+CopySize, ConsoleInfo->ColsPerScreen*sizeof(CHAR16), L' ');\r
492 } else {\r
493 //\r
494 // we are not on the last row\r
495 //\r
496\r
497 //\r
498 // We should not be scrolling history\r
499 //\r
500 ASSERT (ConsoleInfo->OriginalStartRow == ConsoleInfo->CurrentStartRow);\r
501 //\r
502 // are we at the end of a row?\r
503 //\r
504 if (ConsoleInfo->HistoryMode.CursorRow == (INT32) (ConsoleInfo->OriginalStartRow + ConsoleInfo->RowsPerScreen - 1)) {\r
505 ConsoleInfo->OriginalStartRow++;\r
506 ConsoleInfo->CurrentStartRow++;\r
507 }\r
508 ConsoleInfo->HistoryMode.CursorRow++;\r
509 }\r
510 break;\r
511 case (CHAR_CARRIAGE_RETURN):\r
512 //\r
513 // Move the cursor to the beginning of the current row.\r
514 //\r
515 ConsoleInfo->HistoryMode.CursorColumn = 0;\r
516 break;\r
517 default:\r
518 //\r
519 // Acrtually print characters into the history buffer\r
520 //\r
521\r
522 PrintIndex = ConsoleInfo->HistoryMode.CursorRow * ConsoleInfo->ColsPerScreen + ConsoleInfo->HistoryMode.CursorColumn;\r
523\r
524 for ( // no initializer needed\r
525 ; ConsoleInfo->HistoryMode.CursorColumn < (INT32) ConsoleInfo->ColsPerScreen\r
526 ; ConsoleInfo->HistoryMode.CursorColumn++\r
527 , PrintIndex++\r
528 , Walker++\r
529 ){\r
530 if (*Walker == CHAR_NULL\r
531 ||*Walker == CHAR_BACKSPACE\r
532 ||*Walker == CHAR_LINEFEED\r
533 ||*Walker == CHAR_CARRIAGE_RETURN\r
534 ){\r
535 Walker--;\r
536 break;\r
537 }\r
538 //\r
539 // The buffer is 2*CursorRow more since it has that many \r\n characters at the end of each row.\r
540 //\r
541\r
542 ASSERT(PrintIndex + ConsoleInfo->HistoryMode.CursorRow < ConsoleInfo->BufferSize);\r
543 ConsoleInfo->Buffer[PrintIndex + (2*ConsoleInfo->HistoryMode.CursorRow)] = *Walker;\r
544 ASSERT(PrintIndex < ConsoleInfo->AttribSize);\r
545 ConsoleInfo->Attributes[PrintIndex] = ConsoleInfo->HistoryMode.Attribute;\r
546 } // for loop\r
547\r
548 //\r
549 // Add the carriage return and line feed at the end of the lines\r
550 //\r
551 if (ConsoleInfo->HistoryMode.CursorColumn >= (INT32)ConsoleInfo->ColsPerScreen) {\r
552 AppendStringToHistory(L"\r\n", ConsoleInfo);\r
553 Walker--;\r
554 }\r
555\r
556 break;\r
557 } // switch for character\r
558 } // for loop\r
559\r
560 return (EFI_SUCCESS);\r
561}\r
562\r
563/**\r
564 Worker function to handle printing the output to the screen\r
565 and the history buffer\r
566\r
567 @param[in] String The string to output\r
568 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
569\r
570 @retval EFI_SUCCESS The string was printed\r
571 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
572 the text.\r
573 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
574 defined text mode.\r
575 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
576 characters in the Unicode string could not be\r
577 rendered and were skipped.\r
578**/\r
579EFI_STATUS\r
580EFIAPI\r
581ConsoleLoggerOutputStringSplit(\r
582 IN CONST CHAR16 *String,\r
583 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
584 )\r
585{\r
586 EFI_STATUS Status;\r
587\r
588 //\r
589 // Forward the request to the original ConOut\r
590 //\r
591 Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, (CHAR16*)String);\r
592\r
593 if (EFI_ERROR(Status)) {\r
594 return (Status);\r
595 }\r
596\r
597 return (AppendStringToHistory(String, ConsoleInfo));\r
598}\r
599\r
600/**\r
601 Function to handle page break mode.\r
602\r
603 This function will prompt for continue or break.\r
604\r
605 @retval EFI_SUCCESS Continue was choosen\r
606 @return other Break was choosen\r
607**/\r
608EFI_STATUS\r
609EFIAPI\r
610ConsoleLoggerDoPageBreak(\r
611 VOID\r
612 )\r
613{\r
614 SHELL_PROMPT_RESPONSE *Resp;\r
615 EFI_STATUS Status;\r
616\r
617 Resp = NULL;\r
618 ASSERT(ShellInfoObject.PageBreakEnabled);\r
619 ShellInfoObject.PageBreakEnabled = FALSE;\r
620 Status = ShellPromptForResponseHii(ShellPromptResponseTypeQuitContinue, STRING_TOKEN(STR_SHELL_QUIT_CONT), ShellInfoObject.HiiHandle, (VOID**)&Resp);\r
621 ShellInfoObject.PageBreakEnabled = TRUE;\r
622 ASSERT(Resp != NULL);\r
623 if (Resp == NULL) {\r
624 return (EFI_NOT_FOUND);\r
625 }\r
626 if (EFI_ERROR(Status)) {\r
627 if (Resp != NULL) {\r
628 FreePool(Resp);\r
629 }\r
630 return (Status);\r
631 }\r
632 if (*Resp == ShellPromptResponseContinue) {\r
633 FreePool(Resp);\r
634 ShellInfoObject.ConsoleInfo->RowCounter = 0;\r
635 return (EFI_SUCCESS);\r
636 } else if (*Resp == ShellPromptResponseQuit) {\r
637 FreePool(Resp);\r
638 ShellInfoObject.ConsoleInfo->Enabled = FALSE;\r
639 return (EFI_DEVICE_ERROR);\r
640 } else {\r
641 ASSERT(FALSE);\r
642 }\r
643 return (EFI_SUCCESS);\r
644}\r
645/**\r
646 Worker function to handle printing the output with page breaks.\r
647\r
648 @param[in] String The string to output\r
649 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
650\r
651 @retval EFI_SUCCESS The string was printed\r
652 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
653 the text.\r
654 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
655 defined text mode.\r
656 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
657 characters in the Unicode string could not be\r
658 rendered and were skipped.\r
659**/\r
660EFI_STATUS\r
661EFIAPI\r
662ConsoleLoggerPrintWithPageBreak(\r
663 IN CHAR16 *String,\r
664 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
665 )\r
666{\r
667 CONST CHAR16 *Walker;\r
668 CONST CHAR16 *LineStart;\r
669 CHAR16 TempChar;\r
670\r
671 for ( Walker = String\r
672 , LineStart = String\r
673 ; Walker != NULL && *Walker != CHAR_NULL\r
674 ; Walker++\r
675 ){\r
676 switch (*Walker) {\r
677 case (CHAR_BACKSPACE):\r
678 if (ConsoleInfo->OurConOut.Mode->CursorColumn > 0) {\r
679 ConsoleInfo->OurConOut.Mode->CursorColumn--;\r
680 }\r
681 break;\r
682 case (CHAR_LINEFEED):\r
683 //\r
684 // add a temp NULL terminator\r
685 //\r
686 TempChar = *(Walker + 1);\r
687 *((CHAR16*)(Walker+1)) = CHAR_NULL;\r
688\r
689 //\r
690 // output the string\r
691 //\r
692 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);\r
693\r
694 //\r
695 // restore the temp NULL terminator to it's original character\r
696 //\r
697 *((CHAR16*)(Walker+1)) = TempChar;\r
698\r
699 //\r
700 // Update LineStart Variable\r
701 //\r
702 LineStart = Walker + 1;\r
703\r
704 //\r
705 // increment row count\r
706 //\r
707 ShellInfoObject.ConsoleInfo->RowCounter++;\r
708 ConsoleInfo->OurConOut.Mode->CursorRow++;\r
709\r
710 break;\r
711 case (CHAR_CARRIAGE_RETURN):\r
712 //\r
713 // Move the cursor to the beginning of the current row.\r
714 //\r
715 ConsoleInfo->OurConOut.Mode->CursorColumn = 0;\r
716 break;\r
717 default:\r
718 //\r
719 // increment column count\r
720 //\r
721 ConsoleInfo->OurConOut.Mode->CursorColumn++;\r
722 //\r
723 // check if that is the last column\r
724 //\r
725 if ((INTN)ConsoleInfo->ColsPerScreen == ConsoleInfo->OurConOut.Mode->CursorColumn - 1) {\r
726 //\r
727 // output a line similar to the linefeed character.\r
728 //\r
729\r
730 //\r
731 // add a temp NULL terminator\r
732 //\r
733 TempChar = *(Walker + 1);\r
734 *((CHAR16*)(Walker+1)) = CHAR_NULL;\r
735\r
736 //\r
737 // output the string\r
738 //\r
739 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);\r
740\r
741 //\r
742 // restore the temp NULL terminator to it's original character\r
743 //\r
744 *((CHAR16*)(Walker+1)) = TempChar;\r
745\r
746 //\r
747 // Update LineStart Variable\r
748 //\r
749 LineStart = Walker;\r
750\r
751 //\r
752 // increment row count and zero the column\r
753 //\r
754 ShellInfoObject.ConsoleInfo->RowCounter++;\r
755 ConsoleInfo->OurConOut.Mode->CursorRow++;\r
756 ConsoleInfo->OurConOut.Mode->CursorColumn = 0;\r
757 } // last column on line\r
758 break;\r
759 } // switch for character\r
760\r
761 //\r
762 // check if that was the last printable row. If yes handle PageBreak mode\r
763 //\r
764 if ((ConsoleInfo->RowsPerScreen) -1 == ShellInfoObject.ConsoleInfo->RowCounter) {\r
765 if (EFI_ERROR(ConsoleLoggerDoPageBreak())) {\r
766 //\r
767 // We got an error which means 'break' and halt the printing\r
768 //\r
769 return (EFI_DEVICE_ERROR);\r
770 }\r
771 }\r
772 } // for loop\r
773\r
774 if (LineStart != NULL && *LineStart != CHAR_NULL) {\r
775 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);\r
776 }\r
777\r
778 return (EFI_SUCCESS);\r
779}\r
780\r
781/**\r
782 Write a Unicode string to the output device.\r
783\r
784 @param[in] This Protocol instance pointer.\r
785 @param[in] WString The NULL-terminated Unicode string to be displayed on the output\r
786 device(s). All output devices must also support the Unicode\r
787 drawing defined in this file.\r
788 @retval EFI_SUCCESS The string was output to the device.\r
789 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
790 the text.\r
791 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
792 defined text mode.\r
793 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
794 characters in the Unicode string could not be\r
795 rendered and were skipped.\r
796**/\r
797EFI_STATUS\r
798EFIAPI\r
799ConsoleLoggerOutputString (\r
800 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
801 IN CHAR16 *WString\r
802 )\r
803{\r
804 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
805 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
806 ASSERT(ShellInfoObject.ConsoleInfo == ConsoleInfo);\r
807 if (!ShellInfoObject.ConsoleInfo->Enabled) {\r
808 return (EFI_DEVICE_ERROR);\r
809 } else if (ShellInfoObject.PageBreakEnabled) {\r
810 return (ConsoleLoggerPrintWithPageBreak(WString, ConsoleInfo));\r
811 } else {\r
812 return (ConsoleLoggerOutputStringSplit(WString, ConsoleInfo));\r
813 }\r
814}\r
815\r
816/**\r
817 Verifies that all characters in a Unicode string can be output to the\r
818 target device.\r
819\r
820 @param[in] This Protocol instance pointer.\r
821 @param[in] WString The NULL-terminated Unicode string to be examined for the output\r
822 device(s).\r
823\r
824 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
825 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
826 rendered by one or more of the output devices mapped\r
827 by the EFI handle.\r
828\r
829**/\r
830EFI_STATUS\r
831EFIAPI\r
832ConsoleLoggerTestString (\r
833 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
834 IN CHAR16 *WString\r
835 )\r
836{\r
837 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
838 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
839 //\r
840 // Forward the request to the original ConOut\r
841 //\r
842 return (ConsoleInfo->OldConOut->TestString (ConsoleInfo->OldConOut, WString));\r
843}\r
844\r
845/**\r
846 Returns information for an available text mode that the output device(s)\r
847 supports.\r
848\r
849 @param[in] This Protocol instance pointer.\r
850 @param[in] ModeNumber The mode number to return information on.\r
851 @param[out] Columns Upon return, the number of columns in the selected geometry\r
852 @param[out] Rows Upon return, the number of rows in the selected geometry\r
853\r
854 @retval EFI_SUCCESS The requested mode information was returned.\r
855 @retval EFI_DEVICE_ERROR The device had an error and could not\r
856 complete the request.\r
857 @retval EFI_UNSUPPORTED The mode number was not valid.\r
858**/\r
859EFI_STATUS\r
860EFIAPI\r
861ConsoleLoggerQueryMode (\r
862 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
863 IN UINTN ModeNumber,\r
864 OUT UINTN *Columns,\r
865 OUT UINTN *Rows\r
866 )\r
867{\r
868 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
869 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
870 //\r
871 // Forward the request to the original ConOut\r
872 //\r
873 return (ConsoleInfo->OldConOut->QueryMode (\r
874 ConsoleInfo->OldConOut,\r
875 ModeNumber,\r
876 Columns,\r
877 Rows\r
878 ));\r
879}\r
880\r
881/**\r
882 Sets the output device(s) to a specified mode.\r
883\r
884 @param[in] This Protocol instance pointer.\r
885 @param[in] ModeNumber The mode number to set.\r
886\r
887\r
888 @retval EFI_SUCCESS The requested text mode was set.\r
889 @retval EFI_DEVICE_ERROR The device had an error and\r
890 could not complete the request.\r
891 @retval EFI_UNSUPPORTED The mode number was not valid.\r
892**/\r
893EFI_STATUS\r
894EFIAPI\r
895ConsoleLoggerSetMode (\r
896 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
897 IN UINTN ModeNumber\r
898 )\r
899{\r
900 EFI_STATUS Status;\r
901\r
902 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
903 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
904\r
905 //\r
906 // Forward the request to the original ConOut\r
907 //\r
908 Status = ConsoleInfo->OldConOut->SetMode (ConsoleInfo->OldConOut, ModeNumber);\r
909\r
910 //\r
911 // Check that the buffers are still correct for logging\r
912 //\r
913 if (!EFI_ERROR (Status)) {\r
914 ConsoleLoggerResetBuffers(ConsoleInfo);\r
915 }\r
916\r
917 return Status;\r
918}\r
919\r
920/**\r
921 Sets the background and foreground colors for the OutputString () and\r
922 ClearScreen () functions.\r
923\r
924 @param[in] This Protocol instance pointer.\r
925 @param[in] Attribute The attribute to set. Bits 0..3 are the foreground color, and\r
926 bits 4..6 are the background color. All other bits are undefined\r
927 and must be zero. The valid Attributes are defined in this file.\r
928\r
929 @retval EFI_SUCCESS The attribute was set.\r
930 @retval EFI_DEVICE_ERROR The device had an error and\r
931 could not complete the request.\r
932 @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
933\r
934**/\r
935EFI_STATUS\r
936EFIAPI\r
937ConsoleLoggerSetAttribute (\r
938 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
939 IN UINTN Attribute\r
940 )\r
941{\r
942 EFI_STATUS Status;\r
943\r
944 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
945 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
946\r
947 //\r
948 // Forward the request to the original ConOut\r
949 //\r
950 Status = ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, Attribute);\r
951\r
952 //\r
953 // Record console output history\r
954 //\r
955 if (!EFI_ERROR (Status)) {\r
956 ConsoleInfo->HistoryMode.Attribute = (INT32) Attribute;\r
957 }\r
958\r
959 return Status;\r
960}\r
961\r
962/**\r
963 Clears the output device(s) display to the currently selected background\r
964 color.\r
965\r
966 @param[in] This Protocol instance pointer.\r
967\r
968 @retval EFI_SUCCESS The operation completed successfully.\r
969 @retval EFI_DEVICE_ERROR The device had an error and\r
970 could not complete the request.\r
971 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
972**/\r
973EFI_STATUS\r
974EFIAPI\r
975ConsoleLoggerClearScreen (\r
976 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
977 )\r
978{\r
979 EFI_STATUS Status;\r
980 CHAR16 *Screen;\r
981 INT32 *Attributes;\r
982 UINTN Row;\r
983 UINTN Column;\r
984\r
985\r
986 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
987 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
988\r
989 //\r
990 // Forward the request to the original ConOut\r
991 //\r
992 Status = ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);\r
993\r
994 //\r
995 // Record console output history\r
996 //\r
997 if (!EFI_ERROR (Status)) {\r
998 Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 1) * ConsoleInfo->CurrentStartRow];\r
999 Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];\r
1000 for ( Row = ConsoleInfo->OriginalStartRow\r
1001 ; Row < (ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)\r
1002 ; Row++\r
1003 ){\r
1004 for ( Column = 0\r
1005 ; Column < ConsoleInfo->ColsPerScreen\r
1006 ; Column++\r
1007 , Screen++\r
1008 , Attributes++\r
1009 ){\r
1010 *Screen = L' ';\r
1011 *Attributes = ConsoleInfo->OldConOut->Mode->Attribute;\r
1012 }\r
1013 //\r
1014 // Skip the NULL on each column end in text buffer only\r
1015 //\r
1016 Screen++;\r
1017 }\r
1018 ConsoleInfo->HistoryMode.CursorColumn = 0;\r
1019 ConsoleInfo->HistoryMode.CursorRow = 0;\r
1020 }\r
1021\r
1022 return Status;\r
1023}\r
1024\r
1025/**\r
1026 Sets the current coordinates of the cursor position\r
1027\r
1028 @param[in] This Protocol instance pointer.\r
1029 @param[in] Column Column to put the cursor in. Must be between zero and Column returned from QueryMode\r
1030 @param[in] Row Row to put the cursor in. Must be between zero and Row returned from QueryMode\r
1031\r
1032 @retval EFI_SUCCESS The operation completed successfully.\r
1033 @retval EFI_DEVICE_ERROR The device had an error and\r
1034 could not complete the request.\r
1035 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the\r
1036 cursor position is invalid for the current mode.\r
1037**/\r
1038EFI_STATUS\r
1039EFIAPI\r
1040ConsoleLoggerSetCursorPosition (\r
1041 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1042 IN UINTN Column,\r
1043 IN UINTN Row\r
1044 )\r
1045{\r
1046 EFI_STATUS Status;\r
1047\r
1048 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
1049 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
1050 //\r
1051 // Forward the request to the original ConOut\r
1052 //\r
1053 Status = ConsoleInfo->OldConOut->SetCursorPosition (\r
1054 ConsoleInfo->OldConOut,\r
1055 Column,\r
1056 Row\r
1057 );\r
1058\r
1059 //\r
1060 // Record console output history\r
1061 //\r
1062 if (!EFI_ERROR (Status)) {\r
1063 ConsoleInfo->HistoryMode.CursorColumn = (INT32)Column;\r
1064 ConsoleInfo->HistoryMode.CursorRow = (INT32)(ConsoleInfo->OriginalStartRow + Row);\r
1065 }\r
1066\r
1067 return Status;\r
1068}\r
1069\r
1070/**\r
1071 Makes the cursor visible or invisible\r
1072\r
1073 @param[in] This Protocol instance pointer.\r
1074 @param[in] Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is\r
1075 set to be invisible.\r
1076\r
1077 @retval EFI_SUCCESS The operation completed successfully.\r
1078 @retval EFI_DEVICE_ERROR The device had an error and could not complete the\r
1079 request, or the device does not support changing\r
1080 the cursor mode.\r
1081 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
1082**/\r
1083EFI_STATUS\r
1084EFIAPI\r
1085ConsoleLoggerEnableCursor (\r
1086 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1087 IN BOOLEAN Visible\r
1088 )\r
1089{\r
1090 EFI_STATUS Status;\r
1091\r
1092 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
1093 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
1094 //\r
1095 // Forward the request to the original ConOut\r
1096 //\r
1097 Status = ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, Visible);\r
1098\r
1099 //\r
1100 // Record console output history\r
1101 //\r
1102 if (!EFI_ERROR (Status)) {\r
1103 ConsoleInfo->HistoryMode.CursorVisible = Visible;\r
1104 }\r
1105\r
1106 return Status;\r
1107}\r
1108\r
1109/**\r
1110 Function to update and verify that the current buffers are correct.\r
1111\r
1112 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
1113\r
1114 This will be used when a mode has changed or a reset ocurred to verify all\r
1115 history buffers.\r
1116**/\r
1117EFI_STATUS\r
1118EFIAPI\r
1119ConsoleLoggerResetBuffers(\r
1120 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
1121 )\r
1122{\r
1123 EFI_STATUS Status;\r
1124\r
1125 if (ConsoleInfo->Buffer != NULL) {\r
1126 FreePool(ConsoleInfo->Buffer);\r
1127 ConsoleInfo->Buffer = NULL;\r
1128 ConsoleInfo->BufferSize = 0;\r
1129 }\r
1130 if (ConsoleInfo->Attributes != NULL) {\r
1131 FreePool(ConsoleInfo->Attributes);\r
1132 ConsoleInfo->Attributes = NULL;\r
1133 ConsoleInfo->AttribSize = 0;\r
1134 }\r
1135\r
1136 Status = gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &ConsoleInfo->ColsPerScreen, &ConsoleInfo->RowsPerScreen);\r
1137 if (EFI_ERROR(Status)){\r
1138 return (Status);\r
1139 }\r
1140\r
1141 ConsoleInfo->BufferSize = (ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof(ConsoleInfo->Buffer[0]);\r
1142 ConsoleInfo->AttribSize = ConsoleInfo->ColsPerScreen * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof(ConsoleInfo->Attributes[0]);\r
1143\r
1144 ConsoleInfo->Buffer = (CHAR16*)AllocateZeroPool(ConsoleInfo->BufferSize);\r
1145\r
1146 if (ConsoleInfo->Buffer == NULL) {\r
1147 return (EFI_OUT_OF_RESOURCES);\r
1148 }\r
1149\r
1150 ConsoleInfo->Attributes = (INT32*)AllocateZeroPool(ConsoleInfo->AttribSize);\r
1151 if (ConsoleInfo->Attributes == NULL) {\r
1152 FreePool(ConsoleInfo->Buffer);\r
1153 ConsoleInfo->Buffer = NULL;\r
1154 return (EFI_OUT_OF_RESOURCES);\r
1155 }\r
1156\r
1157 ConsoleInfo->OurConOut.Mode = gST->ConOut->Mode;\r
1158 ConsoleInfo->OldConOut = gST->ConOut;\r
1159 CopyMem (&ConsoleInfo->HistoryMode, ConsoleInfo->OldConOut->Mode, sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));\r
1160\r
1161 return (EFI_SUCCESS);\r
1162}\r