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