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