TianoCore EDK2 master
Loading...
Searching...
No Matches
ConsoleLogger.c
Go to the documentation of this file.
1
10#include "Shell.h"
11
27 IN CONST UINTN ScreensToSave,
29 )
30{
31 EFI_STATUS Status;
32
33 ASSERT (ConsoleInfo != NULL);
34
35 (*ConsoleInfo) = AllocateZeroPool (sizeof (CONSOLE_LOGGER_PRIVATE_DATA));
36 if ((*ConsoleInfo) == NULL) {
37 return (EFI_OUT_OF_RESOURCES);
38 }
39
40 (*ConsoleInfo)->Signature = CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE;
41 (*ConsoleInfo)->OldConOut = gST->ConOut;
42 (*ConsoleInfo)->OldConHandle = gST->ConsoleOutHandle;
43 (*ConsoleInfo)->Buffer = NULL;
44 (*ConsoleInfo)->BufferSize = 0;
45 (*ConsoleInfo)->OriginalStartRow = 0;
46 (*ConsoleInfo)->CurrentStartRow = 0;
47 (*ConsoleInfo)->RowsPerScreen = 0;
48 (*ConsoleInfo)->ColsPerScreen = 0;
49 (*ConsoleInfo)->Attributes = NULL;
50 (*ConsoleInfo)->AttribSize = 0;
51 (*ConsoleInfo)->ScreenCount = ScreensToSave;
52 (*ConsoleInfo)->HistoryMode.MaxMode = 1;
53 (*ConsoleInfo)->HistoryMode.Mode = 0;
54 (*ConsoleInfo)->HistoryMode.Attribute = 0;
55 (*ConsoleInfo)->HistoryMode.CursorColumn = 0;
56 (*ConsoleInfo)->HistoryMode.CursorRow = 0;
57 (*ConsoleInfo)->HistoryMode.CursorVisible = FALSE;
58 (*ConsoleInfo)->OurConOut.Reset = ConsoleLoggerReset;
59 (*ConsoleInfo)->OurConOut.OutputString = ConsoleLoggerOutputString;
60 (*ConsoleInfo)->OurConOut.TestString = ConsoleLoggerTestString;
61 (*ConsoleInfo)->OurConOut.QueryMode = ConsoleLoggerQueryMode;
62 (*ConsoleInfo)->OurConOut.SetMode = ConsoleLoggerSetMode;
63 (*ConsoleInfo)->OurConOut.SetAttribute = ConsoleLoggerSetAttribute;
64 (*ConsoleInfo)->OurConOut.ClearScreen = ConsoleLoggerClearScreen;
65 (*ConsoleInfo)->OurConOut.SetCursorPosition = ConsoleLoggerSetCursorPosition;
66 (*ConsoleInfo)->OurConOut.EnableCursor = ConsoleLoggerEnableCursor;
67 (*ConsoleInfo)->OurConOut.Mode = gST->ConOut->Mode;
68 (*ConsoleInfo)->Enabled = TRUE;
69
70 Status = ConsoleLoggerResetBuffers (*ConsoleInfo);
71 if (EFI_ERROR (Status)) {
72 SHELL_FREE_NON_NULL ((*ConsoleInfo));
73 *ConsoleInfo = NULL;
74 return (Status);
75 }
76
77 Status = gBS->InstallProtocolInterface (&gImageHandle, &gEfiSimpleTextOutProtocolGuid, EFI_NATIVE_INTERFACE, (VOID *)&((*ConsoleInfo)->OurConOut));
78 if (EFI_ERROR (Status)) {
79 SHELL_FREE_NON_NULL ((*ConsoleInfo)->Buffer);
80 SHELL_FREE_NON_NULL ((*ConsoleInfo)->Attributes);
81 SHELL_FREE_NON_NULL ((*ConsoleInfo));
82 *ConsoleInfo = NULL;
83 return (Status);
84 }
85
87 gST->ConOut = &(*ConsoleInfo)->OurConOut;
88
89 //
90 // Update the CRC32 in the EFI System Table header
91 //
92 gST->Hdr.CRC32 = 0;
93 gBS->CalculateCrc32 (
94 (UINT8 *)&gST->Hdr,
96 &gST->Hdr.CRC32
97 );
98 return (Status);
99}
100
113 )
114{
115 ASSERT (ConsoleInfo != NULL);
116 ASSERT (ConsoleInfo->OldConOut != NULL);
117
118 if (ConsoleInfo->Buffer != NULL) {
119 FreePool (ConsoleInfo->Buffer);
120 DEBUG_CODE (
121 ConsoleInfo->Buffer = NULL;
122 );
123 DEBUG_CODE (
124 ConsoleInfo->BufferSize = 0;
125 );
126 }
127
128 if (ConsoleInfo->Attributes != NULL) {
129 FreePool (ConsoleInfo->Attributes);
130 DEBUG_CODE (
131 ConsoleInfo->Attributes = NULL;
132 );
133 DEBUG_CODE (
134 ConsoleInfo->AttribSize = 0;
135 );
136 }
137
138 gST->ConsoleOutHandle = ConsoleInfo->OldConHandle;
139 gST->ConOut = ConsoleInfo->OldConOut;
140
141 //
142 // Update the CRC32 in the EFI System Table header
143 //
144 gST->Hdr.CRC32 = 0;
145 gBS->CalculateCrc32 (
146 (UINT8 *)&gST->Hdr,
148 &gST->Hdr.CRC32
149 );
150
151 return (gBS->UninstallProtocolInterface (gImageHandle, &gEfiSimpleTextOutProtocolGuid, (VOID *)&ConsoleInfo->OurConOut));
152}
153
168 IN CONST BOOLEAN Forward,
169 IN CONST UINTN Rows,
171 )
172{
173 UINTN RowChange;
174
175 ASSERT (ConsoleInfo != NULL);
176
177 //
178 // Calculate the row number change
179 //
180 switch (Rows) {
181 case ((UINTN)(-1)):
182 RowChange = ConsoleInfo->RowsPerScreen;
183 break;
184 case (0):
185 RowChange = ConsoleInfo->RowsPerScreen / 2;
186 break;
187 default:
188 RowChange = Rows;
189 break;
190 }
191
192 //
193 // Do the math for direction
194 //
195 if (Forward) {
196 if ((ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow) < RowChange) {
197 RowChange = ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow;
198 }
199 } else {
200 if (ConsoleInfo->CurrentStartRow < RowChange) {
201 RowChange = ConsoleInfo->CurrentStartRow;
202 }
203 }
204
205 //
206 // If we are already at one end or the other
207 //
208 if (RowChange == 0) {
209 return (EFI_SUCCESS);
210 }
211
212 //
213 // Clear the screen
214 //
215 ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);
216
217 //
218 // Set the new start row
219 //
220 if (Forward) {
221 ConsoleInfo->CurrentStartRow += RowChange;
222 } else {
223 ConsoleInfo->CurrentStartRow -= RowChange;
224 }
225
226 //
227 // Change the screen
228 //
229 return (UpdateDisplayFromHistory (ConsoleInfo));
230}
231
244 )
245{
246 ASSERT (ConsoleInfo != NULL);
247 if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {
248 return (EFI_SUCCESS);
249 }
250
251 //
252 // Clear the screen
253 //
254 ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);
255
256 ConsoleInfo->CurrentStartRow = ConsoleInfo->OriginalStartRow;
257 return (UpdateDisplayFromHistory (ConsoleInfo));
258}
259
270 )
271{
272 EFI_STATUS Status;
273 EFI_STATUS RetVal;
274 CHAR16 *Screen;
275 INT32 *Attributes;
276 UINTN CurrentRow;
277 CHAR16 TempCharHolder;
278 UINTN Column;
279 INT32 CurrentAttrib;
280 UINTN CurrentColumn;
281 CHAR16 *StringSegment;
282 CHAR16 *StringSegmentEnd;
283 CHAR16 StringSegmentEndChar;
284 INT32 OrigAttribute;
285
286 ASSERT (ConsoleInfo != NULL);
287 TempCharHolder = CHAR_NULL;
288 RetVal = EFI_SUCCESS;
289 OrigAttribute = ConsoleInfo->OldConOut->Mode->Attribute;
290
291 //
292 // Disable cursor visibility and move it to the top left corner
293 //
294 ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, FALSE);
295 ConsoleInfo->OldConOut->SetCursorPosition (ConsoleInfo->OldConOut, 0, 0);
296
297 Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
298 Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
299 for ( CurrentRow = 0
300 ; CurrentRow < ConsoleInfo->RowsPerScreen
301 ; CurrentRow++,
302 Screen += (ConsoleInfo->ColsPerScreen + 2),
303 Attributes += ConsoleInfo->ColsPerScreen
304 )
305 {
306 //
307 // dont use the last char - prevents screen scroll
308 //
309 if (CurrentRow == (ConsoleInfo->RowsPerScreen-1)) {
310 TempCharHolder = Screen[ConsoleInfo->ColsPerScreen - 1];
311 Screen[ConsoleInfo->ColsPerScreen - 1] = CHAR_NULL;
312 }
313
314 for ( Column = 0
315 ; Column < ConsoleInfo->ColsPerScreen
316 ; Column++
317 )
318 {
319 if (Screen[Column] != CHAR_NULL) {
320 CurrentAttrib = Attributes[Column];
321 CurrentColumn = Column;
322 StringSegment = &Screen[Column];
323
324 //
325 // Find the first char with a different attribute and make that temporarily NULL
326 // so we can do fewer printout statements. (later) restore that one and we will
327 // start at that column on the next loop.
328 //
329 StringSegmentEndChar = CHAR_NULL;
330 for ( StringSegmentEnd = StringSegment
331 ; *StringSegmentEnd != CHAR_NULL
332 ; StringSegmentEnd++,
333 Column++
334 )
335 {
336 if (Attributes[Column] != CurrentAttrib) {
337 StringSegmentEndChar = *StringSegmentEnd;
338 *StringSegmentEnd = CHAR_NULL;
339 break;
340 }
341 } // StringSegmentEnd loop
342
343 //
344 // Now write out as much as had the same Attributes
345 //
346
347 ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, CurrentAttrib);
348 ConsoleInfo->OldConOut->SetCursorPosition (ConsoleInfo->OldConOut, CurrentColumn, CurrentRow);
349 Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, StringSegment);
350
351 if (EFI_ERROR (Status)) {
352 ASSERT (FALSE);
353 RetVal = Status;
354 }
355
356 //
357 // If we found a change in attribute put the character back and decrement the column
358 // so when it increments it will point at that character and we will start printing
359 // a segment with that new attribute
360 //
361 if (StringSegmentEndChar != CHAR_NULL) {
362 *StringSegmentEnd = StringSegmentEndChar;
363 StringSegmentEndChar = CHAR_NULL;
364 Column--;
365 }
366 }
367 } // column for loop
368
369 //
370 // If we removed the last char and this was the last row put it back
371 //
372 if (TempCharHolder != CHAR_NULL) {
373 Screen[ConsoleInfo->ColsPerScreen - 1] = TempCharHolder;
374 TempCharHolder = CHAR_NULL;
375 }
376 } // row for loop
377
378 //
379 // If we are setting the screen back to original turn on the cursor and make it visible
380 // and set the attributes back to what they were
381 //
382 if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {
383 ConsoleInfo->OldConOut->SetAttribute (
384 ConsoleInfo->OldConOut,
385 ConsoleInfo->HistoryMode.Attribute
386 );
387 ConsoleInfo->OldConOut->SetCursorPosition (
388 ConsoleInfo->OldConOut,
389 ConsoleInfo->HistoryMode.CursorColumn,
390 ConsoleInfo->HistoryMode.CursorRow - ConsoleInfo->OriginalStartRow
391 );
392
393 Status = ConsoleInfo->OldConOut->EnableCursor (
394 ConsoleInfo->OldConOut,
395 ConsoleInfo->HistoryMode.CursorVisible
396 );
397 if (EFI_ERROR (Status)) {
398 RetVal = Status;
399 }
400 } else {
401 ConsoleInfo->OldConOut->SetAttribute (
402 ConsoleInfo->OldConOut,
403 OrigAttribute
404 );
405 }
406
407 return (RetVal);
408}
409
421EFIAPI
424 IN BOOLEAN ExtendedVerification
425 )
426{
427 EFI_STATUS Status;
428 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
429
430 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
431
432 //
433 // Forward the request to the original ConOut
434 //
435 Status = ConsoleInfo->OldConOut->Reset (ConsoleInfo->OldConOut, ExtendedVerification);
436
437 //
438 // Check that the buffers are still correct for logging
439 //
440 if (!EFI_ERROR (Status)) {
441 ConsoleLoggerResetBuffers (ConsoleInfo);
442 if (ExtendedVerification) {
443 ConsoleInfo->OriginalStartRow = 0;
444 ConsoleInfo->CurrentStartRow = 0;
445 }
446 }
447
448 return Status;
449}
450
461 IN CONST CHAR16 *String,
463 )
464{
465 CONST CHAR16 *Walker;
466 UINTN CopySize;
467 UINTN PrintIndex;
468 UINTN Index;
469
470 ASSERT (ConsoleInfo != NULL);
471
472 for ( Walker = String
473 ; Walker != NULL && *Walker != CHAR_NULL
474 ; Walker++
475 )
476 {
477 switch (*Walker) {
478 case (CHAR_BACKSPACE):
479 if (ConsoleInfo->HistoryMode.CursorColumn > 0) {
480 ConsoleInfo->HistoryMode.CursorColumn--;
481 }
482
483 break;
484 case (CHAR_LINEFEED):
485 if (ConsoleInfo->HistoryMode.CursorRow >= (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1)) {
486 //
487 // Should never be bigger
488 //
489 ASSERT (ConsoleInfo->HistoryMode.CursorRow == (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1));
490
491 //
492 // scroll history attributes 'up' 1 row and set the last row to default attribute
493 //
494 CopySize = ConsoleInfo->ColsPerScreen
495 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)
496 * sizeof (ConsoleInfo->Attributes[0]);
497 ASSERT (CopySize < ConsoleInfo->AttribSize);
498 CopyMem (
499 ConsoleInfo->Attributes,
500 ConsoleInfo->Attributes + ConsoleInfo->ColsPerScreen,
501 CopySize
502 );
503
504 for ( Index = 0
505 ; Index < ConsoleInfo->ColsPerScreen
506 ; Index++
507 )
508 {
509 *(ConsoleInfo->Attributes + (CopySize/sizeof (ConsoleInfo->Attributes[0])) + Index) = ConsoleInfo->HistoryMode.Attribute;
510 }
511
512 //
513 // scroll history buffer 'up' 1 row and set the last row to spaces (L' ')
514 //
515 CopySize = (ConsoleInfo->ColsPerScreen + 2)
516 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)
517 * sizeof (ConsoleInfo->Buffer[0]);
518 ASSERT (CopySize < ConsoleInfo->BufferSize);
519 CopyMem (
520 ConsoleInfo->Buffer,
521 ConsoleInfo->Buffer + (ConsoleInfo->ColsPerScreen + 2),
522 CopySize
523 );
524
525 //
526 // Set that last row of chars to spaces
527 //
528 SetMem16 (((UINT8 *)ConsoleInfo->Buffer)+CopySize, ConsoleInfo->ColsPerScreen*sizeof (CHAR16), L' ');
529 } else {
530 //
531 // we are not on the last row
532 //
533
534 //
535 // We should not be scrolling history
536 //
537 ASSERT (ConsoleInfo->OriginalStartRow == ConsoleInfo->CurrentStartRow);
538 //
539 // are we at the end of a row?
540 //
541 if (ConsoleInfo->HistoryMode.CursorRow == (INT32)(ConsoleInfo->OriginalStartRow + ConsoleInfo->RowsPerScreen - 1)) {
542 ConsoleInfo->OriginalStartRow++;
543 ConsoleInfo->CurrentStartRow++;
544 }
545
546 ConsoleInfo->HistoryMode.CursorRow++;
547 }
548
549 break;
550 case (CHAR_CARRIAGE_RETURN):
551 //
552 // Move the cursor to the beginning of the current row.
553 //
554 ConsoleInfo->HistoryMode.CursorColumn = 0;
555 break;
556 default:
557 //
558 // Acrtually print characters into the history buffer
559 //
560
561 PrintIndex = ConsoleInfo->HistoryMode.CursorRow * ConsoleInfo->ColsPerScreen + ConsoleInfo->HistoryMode.CursorColumn;
562
563 for ( // no initializer needed
564 ; ConsoleInfo->HistoryMode.CursorColumn < (INT32)ConsoleInfo->ColsPerScreen
565 ; ConsoleInfo->HistoryMode.CursorColumn++,
566 PrintIndex++,
567 Walker++
568 )
569 {
570 if ( (*Walker == CHAR_NULL)
571 || (*Walker == CHAR_BACKSPACE)
572 || (*Walker == CHAR_LINEFEED)
573 || (*Walker == CHAR_CARRIAGE_RETURN)
574 )
575 {
576 Walker--;
577 break;
578 }
579
580 //
581 // The buffer is 2*CursorRow more since it has that many \r\n characters at the end of each row.
582 //
583
584 ASSERT (PrintIndex + ConsoleInfo->HistoryMode.CursorRow < ConsoleInfo->BufferSize);
585 ConsoleInfo->Buffer[PrintIndex + (2*ConsoleInfo->HistoryMode.CursorRow)] = *Walker;
586 ASSERT (PrintIndex < ConsoleInfo->AttribSize);
587 ConsoleInfo->Attributes[PrintIndex] = ConsoleInfo->HistoryMode.Attribute;
588 } // for loop
589
590 //
591 // Add the carriage return and line feed at the end of the lines
592 //
593 if (ConsoleInfo->HistoryMode.CursorColumn >= (INT32)ConsoleInfo->ColsPerScreen) {
594 AppendStringToHistory (L"\r\n", ConsoleInfo);
595 Walker--;
596 }
597
598 break;
599 } // switch for character
600 } // for loop
601
602 return (EFI_SUCCESS);
603}
604
623 IN CONST CHAR16 *String,
625 )
626{
627 EFI_STATUS Status;
628
629 //
630 // Forward the request to the original ConOut
631 //
632 Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, (CHAR16 *)String);
633
634 if (EFI_ERROR (Status)) {
635 return (Status);
636 }
637
638 return (AppendStringToHistory (String, ConsoleInfo));
639}
640
651 VOID
652 )
653{
655 EFI_STATUS Status;
656
657 Resp = NULL;
658 ASSERT (ShellInfoObject.PageBreakEnabled);
659 ShellInfoObject.PageBreakEnabled = FALSE;
660 Status = ShellPromptForResponseHii (ShellPromptResponseTypeQuitContinue, STRING_TOKEN (STR_SHELL_QUIT_CONT), ShellInfoObject.HiiHandle, (VOID **)&Resp);
661 ShellInfoObject.PageBreakEnabled = TRUE;
662 ASSERT (Resp != NULL);
663 if (Resp == NULL) {
664 return (EFI_NOT_FOUND);
665 }
666
667 if (EFI_ERROR (Status)) {
668 if (Resp != NULL) {
669 FreePool (Resp);
670 }
671
672 return (Status);
673 }
674
675 if (*Resp == ShellPromptResponseContinue) {
676 FreePool (Resp);
677 ShellInfoObject.ConsoleInfo->RowCounter = 0;
678 // ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorRow = 0;
679 // ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
680
681 return (EFI_SUCCESS);
682 } else if (*Resp == ShellPromptResponseQuit) {
683 FreePool (Resp);
684 ShellInfoObject.ConsoleInfo->Enabled = FALSE;
685 //
686 // When user wants to quit, the shell should stop running the command.
687 //
688 gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
689 return (EFI_DEVICE_ERROR);
690 } else {
691 ASSERT (FALSE);
692 }
693
694 return (EFI_SUCCESS);
695}
696
714 IN CONST CHAR16 *String,
716 )
717{
718 CONST CHAR16 *Walker;
719 CONST CHAR16 *LineStart;
720 CHAR16 *StringCopy;
721 CHAR16 TempChar;
722
723 StringCopy = NULL;
724 StringCopy = StrnCatGrow (&StringCopy, NULL, String, 0);
725 if (StringCopy == NULL) {
726 return (EFI_OUT_OF_RESOURCES);
727 }
728
729 for ( Walker = StringCopy,
730 LineStart = StringCopy
731 ; Walker != NULL && *Walker != CHAR_NULL
732 ; Walker++
733 )
734 {
735 switch (*Walker) {
736 case (CHAR_BACKSPACE):
737 if (ConsoleInfo->OurConOut.Mode->CursorColumn > 0) {
738 ConsoleInfo->OurConOut.Mode->CursorColumn--;
739 }
740
741 break;
742 case (CHAR_LINEFEED):
743 //
744 // add a temp NULL terminator
745 //
746 TempChar = *(Walker + 1);
747 *((CHAR16 *)(Walker+1)) = CHAR_NULL;
748
749 //
750 // output the string
751 //
752 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
753
754 //
755 // restore the temp NULL terminator to its original character
756 //
757 *((CHAR16 *)(Walker+1)) = TempChar;
758
759 //
760 // Update LineStart Variable
761 //
762 LineStart = Walker + 1;
763
764 //
765 // increment row count
766 //
767 ShellInfoObject.ConsoleInfo->RowCounter++;
768 ConsoleInfo->OurConOut.Mode->CursorRow++;
769
770 break;
771 case (CHAR_CARRIAGE_RETURN):
772 //
773 // Move the cursor to the beginning of the current row.
774 //
775 ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
776 break;
777 default:
778 //
779 // increment column count
780 //
781 ConsoleInfo->OurConOut.Mode->CursorColumn++;
782 //
783 // check if that is the last column
784 //
785 if ((INTN)ConsoleInfo->ColsPerScreen == ConsoleInfo->OurConOut.Mode->CursorColumn + 1) {
786 //
787 // output a line similar to the linefeed character.
788 //
789
790 //
791 // add a temp NULL terminator
792 //
793 TempChar = *(Walker + 1);
794 *((CHAR16 *)(Walker+1)) = CHAR_NULL;
795
796 //
797 // output the string
798 //
799 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
800
801 //
802 // restore the temp NULL terminator to its original character
803 //
804 *((CHAR16 *)(Walker+1)) = TempChar;
805
806 //
807 // Update LineStart Variable
808 //
809 LineStart = Walker + 1;
810
811 //
812 // increment row count and zero the column
813 //
814 ShellInfoObject.ConsoleInfo->RowCounter++;
815 ConsoleInfo->OurConOut.Mode->CursorRow++;
816 ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
817 } // last column on line
818
819 break;
820 } // switch for character
821
822 //
823 // check if that was the last printable row. If yes handle PageBreak mode
824 //
825 if ((ConsoleInfo->RowsPerScreen) -1 == ShellInfoObject.ConsoleInfo->RowCounter) {
826 if (EFI_ERROR (ConsoleLoggerDoPageBreak ())) {
827 //
828 // We got an error which means 'break' and halt the printing
829 //
830 SHELL_FREE_NON_NULL (StringCopy);
831 return (EFI_DEVICE_ERROR);
832 }
833 }
834 } // for loop
835
836 if ((LineStart != NULL) && (*LineStart != CHAR_NULL)) {
837 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
838 }
839
840 SHELL_FREE_NON_NULL (StringCopy);
841 return (EFI_SUCCESS);
842}
843
861EFIAPI
864 IN CHAR16 *WString
865 )
866{
867 EFI_STATUS Status;
869 EFI_KEY_DATA KeyData;
870 UINTN EventIndex;
871 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
872
873 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
874 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
875 return (EFI_UNSUPPORTED);
876 }
877
878 ASSERT (ShellInfoObject.ConsoleInfo == ConsoleInfo);
879
880 Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&TxtInEx);
881 if (!EFI_ERROR (Status)) {
882 while (ShellInfoObject.HaltOutput) {
883 ShellInfoObject.HaltOutput = FALSE;
884 //
885 // just get some key
886 //
887 Status = gBS->WaitForEvent (1, &TxtInEx->WaitForKeyEx, &EventIndex);
888 ASSERT_EFI_ERROR (Status);
889 Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
890 if (EFI_ERROR (Status)) {
891 break;
892 }
893
894 if ((KeyData.Key.UnicodeChar == L's') && (KeyData.Key.ScanCode == SCAN_NULL) &&
895 ((KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED)) ||
896 (KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED))
897 )
898 )
899 {
900 ShellInfoObject.HaltOutput = TRUE;
901 }
902 }
903 }
904
905 if (!ShellInfoObject.ConsoleInfo->Enabled) {
906 return (EFI_DEVICE_ERROR);
907 } else if (ShellInfoObject.PageBreakEnabled) {
908 return (ConsoleLoggerPrintWithPageBreak (WString, ConsoleInfo));
909 } else {
910 return (ConsoleLoggerOutputStringSplit (WString, ConsoleInfo));
911 }
912}
913
929EFIAPI
932 IN CHAR16 *WString
933 )
934{
935 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
936
937 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
938 //
939 // Forward the request to the original ConOut
940 //
941 return (ConsoleInfo->OldConOut->TestString (ConsoleInfo->OldConOut, WString));
942}
943
959EFIAPI
962 IN UINTN ModeNumber,
963 OUT UINTN *Columns,
964 OUT UINTN *Rows
965 )
966{
967 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
968
969 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
970 //
971 // Forward the request to the original ConOut
972 //
973 return (ConsoleInfo->OldConOut->QueryMode (
974 ConsoleInfo->OldConOut,
975 ModeNumber,
976 Columns,
977 Rows
978 ));
979}
980
994EFIAPI
997 IN UINTN ModeNumber
998 )
999{
1000 EFI_STATUS Status;
1001
1002 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
1003
1004 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
1005
1006 //
1007 // Forward the request to the original ConOut
1008 //
1009 Status = ConsoleInfo->OldConOut->SetMode (ConsoleInfo->OldConOut, ModeNumber);
1010
1011 //
1012 // Check that the buffers are still correct for logging
1013 //
1014 if (!EFI_ERROR (Status)) {
1015 ConsoleInfo->OurConOut.Mode = ConsoleInfo->OldConOut->Mode;
1016 ConsoleLoggerResetBuffers (ConsoleInfo);
1017 ConsoleInfo->OriginalStartRow = 0;
1018 ConsoleInfo->CurrentStartRow = 0;
1019 ConsoleInfo->OurConOut.ClearScreen (&ConsoleInfo->OurConOut);
1020 }
1021
1022 return Status;
1023}
1024
1041EFIAPI
1044 IN UINTN Attribute
1045 )
1046{
1047 EFI_STATUS Status;
1048
1049 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
1050
1051 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
1052
1053 //
1054 // Forward the request to the original ConOut
1055 //
1056 Status = ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, Attribute);
1057
1058 //
1059 // Record console output history
1060 //
1061 if (!EFI_ERROR (Status)) {
1062 ConsoleInfo->HistoryMode.Attribute = (INT32)Attribute;
1063 }
1064
1065 return Status;
1066}
1067
1080EFIAPI
1083 )
1084{
1085 EFI_STATUS Status;
1086 CHAR16 *Screen;
1087 INT32 *Attributes;
1088 UINTN Row;
1089 UINTN Column;
1090 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
1091
1092 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
1093 return (EFI_UNSUPPORTED);
1094 }
1095
1096 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
1097
1098 //
1099 // Forward the request to the original ConOut
1100 //
1101 Status = ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);
1102
1103 //
1104 // Record console output history
1105 //
1106 if (!EFI_ERROR (Status)) {
1107 Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
1108 Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
1109 for ( Row = ConsoleInfo->OriginalStartRow
1110 ; Row < (ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)
1111 ; Row++
1112 )
1113 {
1114 for ( Column = 0
1115 ; Column < ConsoleInfo->ColsPerScreen
1116 ; Column++,
1117 Screen++,
1118 Attributes++
1119 )
1120 {
1121 *Screen = L' ';
1122 *Attributes = ConsoleInfo->OldConOut->Mode->Attribute;
1123 }
1124
1125 //
1126 // Skip the NULL on each column end in text buffer only
1127 //
1128 Screen += 2;
1129 }
1130
1131 ConsoleInfo->HistoryMode.CursorColumn = 0;
1132 ConsoleInfo->HistoryMode.CursorRow = 0;
1133 }
1134
1135 return Status;
1136}
1137
1152EFIAPI
1155 IN UINTN Column,
1156 IN UINTN Row
1157 )
1158{
1159 EFI_STATUS Status;
1160 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
1161
1162 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
1163 return (EFI_UNSUPPORTED);
1164 }
1165
1166 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
1167 //
1168 // Forward the request to the original ConOut
1169 //
1170 Status = ConsoleInfo->OldConOut->SetCursorPosition (
1171 ConsoleInfo->OldConOut,
1172 Column,
1173 Row
1174 );
1175
1176 //
1177 // Record console output history
1178 //
1179 if (!EFI_ERROR (Status)) {
1180 ConsoleInfo->HistoryMode.CursorColumn = (INT32)Column;
1181 ConsoleInfo->HistoryMode.CursorRow = (INT32)(ConsoleInfo->OriginalStartRow + Row);
1182 }
1183
1184 return Status;
1185}
1186
1201EFIAPI
1204 IN BOOLEAN Visible
1205 )
1206{
1207 EFI_STATUS Status;
1208
1209 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
1210
1211 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
1212 //
1213 // Forward the request to the original ConOut
1214 //
1215 Status = ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, Visible);
1216
1217 //
1218 // Record console output history
1219 //
1220 if (!EFI_ERROR (Status)) {
1221 ConsoleInfo->HistoryMode.CursorVisible = Visible;
1222 }
1223
1224 return Status;
1225}
1226
1237 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo
1238 )
1239{
1240 EFI_STATUS Status;
1241
1242 if (ConsoleInfo->Buffer != NULL) {
1243 FreePool (ConsoleInfo->Buffer);
1244 ConsoleInfo->Buffer = NULL;
1245 ConsoleInfo->BufferSize = 0;
1246 }
1247
1248 if (ConsoleInfo->Attributes != NULL) {
1249 FreePool (ConsoleInfo->Attributes);
1250 ConsoleInfo->Attributes = NULL;
1251 ConsoleInfo->AttribSize = 0;
1252 }
1253
1254 Status = gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &ConsoleInfo->ColsPerScreen, &ConsoleInfo->RowsPerScreen);
1255 if (EFI_ERROR (Status)) {
1256 return (Status);
1257 }
1258
1259 ConsoleInfo->BufferSize = (ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof (ConsoleInfo->Buffer[0]);
1260 ConsoleInfo->AttribSize = ConsoleInfo->ColsPerScreen * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof (ConsoleInfo->Attributes[0]);
1261
1262 ConsoleInfo->Buffer = (CHAR16 *)AllocateZeroPool (ConsoleInfo->BufferSize);
1263
1264 if (ConsoleInfo->Buffer == NULL) {
1265 return (EFI_OUT_OF_RESOURCES);
1266 }
1267
1268 ConsoleInfo->Attributes = (INT32 *)AllocateZeroPool (ConsoleInfo->AttribSize);
1269 if (ConsoleInfo->Attributes == NULL) {
1270 FreePool (ConsoleInfo->Buffer);
1271 ConsoleInfo->Buffer = NULL;
1272 return (EFI_OUT_OF_RESOURCES);
1273 }
1274
1275 CopyMem (&ConsoleInfo->HistoryMode, ConsoleInfo->OldConOut->Mode, sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));
1276
1277 return (EFI_SUCCESS);
1278}
UINT64 UINTN
INT64 INTN
VOID *EFIAPI SetMem16(OUT VOID *Buffer, IN UINTN Length, IN UINT16 Value)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS ConsoleLoggerResetBuffers(IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS ConsoleLoggerPrintWithPageBreak(IN CONST CHAR16 *String, IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS ConsoleLoggerDoPageBreak(VOID)
EFI_STATUS EFIAPI ConsoleLoggerTestString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString)
EFI_STATUS EFIAPI ConsoleLoggerEnableCursor(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN Visible)
EFI_STATUS ConsoleLoggerDisplayHistory(IN CONST BOOLEAN Forward, IN CONST UINTN Rows, IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS AppendStringToHistory(IN CONST CHAR16 *String, IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS EFIAPI ConsoleLoggerSetAttribute(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Attribute)
EFI_STATUS EFIAPI ConsoleLoggerClearScreen(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This)
EFI_STATUS UpdateDisplayFromHistory(IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS EFIAPI ConsoleLoggerReset(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
EFI_STATUS EFIAPI ConsoleLoggerSetCursorPosition(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN Column, IN UINTN Row)
EFI_STATUS ConsoleLoggerStopHistory(IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS EFIAPI ConsoleLoggerSetMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber)
EFI_STATUS EFIAPI ConsoleLoggerQueryMode(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN UINTN ModeNumber, OUT UINTN *Columns, OUT UINTN *Rows)
EFI_STATUS ConsoleLoggerInstall(IN CONST UINTN ScreensToSave, OUT CONSOLE_LOGGER_PRIVATE_DATA **ConsoleInfo)
Definition: ConsoleLogger.c:26
EFI_STATUS EFIAPI ConsoleLoggerOutputString(IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, IN CHAR16 *WString)
EFI_STATUS ConsoleLoggerUninstall(IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
EFI_STATUS ConsoleLoggerOutputStringSplit(IN CONST CHAR16 *String, IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
EFI_STATUS EFIAPI ShellPromptForResponseHii(IN SHELL_PROMPT_REQUEST_TYPE Type, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle, IN OUT VOID **Response)
CHAR16 *EFIAPI StrnCatGrow(IN OUT CHAR16 **Destination, IN OUT UINTN *CurrentSize, IN CONST CHAR16 *Source, IN UINTN Count)
SHELL_PROMPT_RESPONSE
Definition: ShellLib.h:1198
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define STRING_TOKEN(t)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_SIMPLE_TEXT_OUTPUT_MODE HistoryMode
mode of the history log
Definition: ConsoleLogger.h:34
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * OldConOut
old protocol to reinstall upon exiting
Definition: ConsoleLogger.h:18
UINTN CurrentStartRow
what the currently visible start row is
Definition: ConsoleLogger.h:26
BOOLEAN Enabled
Set to FALSE when a break is requested.
Definition: ConsoleLogger.h:35
UINTN OriginalStartRow
What the originally visible start row was.
Definition: ConsoleLogger.h:25
UINTN ColsPerScreen
how many columns the screen can display
Definition: ConsoleLogger.h:29
UINTN RowCounter
Initial row of each print job.
Definition: ConsoleLogger.h:36
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL OurConOut
the protocol we installed onto the system table
Definition: ConsoleLogger.h:17
UINTN RowsPerScreen
how many rows the screen can display
Definition: ConsoleLogger.h:28
INT32 * Attributes
Buffer for Attribute to be saved for each character.
Definition: ConsoleLogger.h:31
UINTN ScreenCount
How many screens worth of data to save.
Definition: ConsoleLogger.h:20
CHAR16 * Buffer
Buffer to save data.
Definition: ConsoleLogger.h:21
UINT32 KeyShiftState
EFI_SIMPLE_TEXT_OUTPUT_MODE * Mode
EFI_INPUT_KEY Key
EFI_KEY_STATE KeyState
EFI_HANDLE ConsoleInHandle
Definition: UefiSpec.h:2048
EFI_HANDLE ConsoleOutHandle
Definition: UefiSpec.h:2059
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * ConOut
Definition: UefiSpec.h:2064
EFI_TABLE_HEADER Hdr
Definition: UefiSpec.h:2032
UINT32 NoConsoleOut
Was "-noconsoleout" found on command line.
Definition: Shell.h:67
BOOLEAN HaltOutput
TRUE to start a CTRL-S halt.
Definition: Shell.h:122
EFI_HII_HANDLE HiiHandle
Handle from HiiLib.
Definition: Shell.h:105
CONSOLE_LOGGER_PRIVATE_DATA * ConsoleInfo
Pointer for ConsoleInformation.
Definition: Shell.h:110