REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ShellPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			1279 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1279 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Provides interface to shell console logger.
 | |
| 
 | |
|   (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
 | |
|   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
|   (C) Copyright 2016 Hewlett-Packard Development Company, L.P.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| **/
 | |
| 
 | |
| #include "Shell.h"
 | |
| 
 | |
| /**
 | |
|   Install our intermediate ConOut into the system table to
 | |
|   keep a log of all the info that is displayed to the user.
 | |
| 
 | |
|   @param[in] ScreensToSave  Sets how many screen-worths of data to save.
 | |
|   @param[out] ConsoleInfo   The object to pass into later functions.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The operation was successful.
 | |
|   @return other             The operation failed.
 | |
| 
 | |
|   @sa ConsoleLoggerResetBuffers
 | |
|   @sa InstallProtocolInterface
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerInstall (
 | |
|   IN CONST UINTN                   ScreensToSave,
 | |
|   OUT CONSOLE_LOGGER_PRIVATE_DATA  **ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   ASSERT (ConsoleInfo != NULL);
 | |
| 
 | |
|   (*ConsoleInfo) = AllocateZeroPool (sizeof (CONSOLE_LOGGER_PRIVATE_DATA));
 | |
|   if ((*ConsoleInfo) == NULL) {
 | |
|     return (EFI_OUT_OF_RESOURCES);
 | |
|   }
 | |
| 
 | |
|   (*ConsoleInfo)->Signature                   = CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE;
 | |
|   (*ConsoleInfo)->OldConOut                   = gST->ConOut;
 | |
|   (*ConsoleInfo)->OldConHandle                = gST->ConsoleOutHandle;
 | |
|   (*ConsoleInfo)->Buffer                      = NULL;
 | |
|   (*ConsoleInfo)->BufferSize                  = 0;
 | |
|   (*ConsoleInfo)->OriginalStartRow            = 0;
 | |
|   (*ConsoleInfo)->CurrentStartRow             = 0;
 | |
|   (*ConsoleInfo)->RowsPerScreen               = 0;
 | |
|   (*ConsoleInfo)->ColsPerScreen               = 0;
 | |
|   (*ConsoleInfo)->Attributes                  = NULL;
 | |
|   (*ConsoleInfo)->AttribSize                  = 0;
 | |
|   (*ConsoleInfo)->ScreenCount                 = ScreensToSave;
 | |
|   (*ConsoleInfo)->HistoryMode.MaxMode         = 1;
 | |
|   (*ConsoleInfo)->HistoryMode.Mode            = 0;
 | |
|   (*ConsoleInfo)->HistoryMode.Attribute       = 0;
 | |
|   (*ConsoleInfo)->HistoryMode.CursorColumn    = 0;
 | |
|   (*ConsoleInfo)->HistoryMode.CursorRow       = 0;
 | |
|   (*ConsoleInfo)->HistoryMode.CursorVisible   = FALSE;
 | |
|   (*ConsoleInfo)->OurConOut.Reset             = ConsoleLoggerReset;
 | |
|   (*ConsoleInfo)->OurConOut.OutputString      = ConsoleLoggerOutputString;
 | |
|   (*ConsoleInfo)->OurConOut.TestString        = ConsoleLoggerTestString;
 | |
|   (*ConsoleInfo)->OurConOut.QueryMode         = ConsoleLoggerQueryMode;
 | |
|   (*ConsoleInfo)->OurConOut.SetMode           = ConsoleLoggerSetMode;
 | |
|   (*ConsoleInfo)->OurConOut.SetAttribute      = ConsoleLoggerSetAttribute;
 | |
|   (*ConsoleInfo)->OurConOut.ClearScreen       = ConsoleLoggerClearScreen;
 | |
|   (*ConsoleInfo)->OurConOut.SetCursorPosition = ConsoleLoggerSetCursorPosition;
 | |
|   (*ConsoleInfo)->OurConOut.EnableCursor      = ConsoleLoggerEnableCursor;
 | |
|   (*ConsoleInfo)->OurConOut.Mode              = gST->ConOut->Mode;
 | |
|   (*ConsoleInfo)->Enabled                     = TRUE;
 | |
| 
 | |
|   Status = ConsoleLoggerResetBuffers (*ConsoleInfo);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     SHELL_FREE_NON_NULL ((*ConsoleInfo));
 | |
|     *ConsoleInfo = NULL;
 | |
|     return (Status);
 | |
|   }
 | |
| 
 | |
|   Status = gBS->InstallProtocolInterface (&gImageHandle, &gEfiSimpleTextOutProtocolGuid, EFI_NATIVE_INTERFACE, (VOID *)&((*ConsoleInfo)->OurConOut));
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     SHELL_FREE_NON_NULL ((*ConsoleInfo)->Buffer);
 | |
|     SHELL_FREE_NON_NULL ((*ConsoleInfo)->Attributes);
 | |
|     SHELL_FREE_NON_NULL ((*ConsoleInfo));
 | |
|     *ConsoleInfo = NULL;
 | |
|     return (Status);
 | |
|   }
 | |
| 
 | |
|   gST->ConsoleOutHandle = gImageHandle;
 | |
|   gST->ConOut           = &(*ConsoleInfo)->OurConOut;
 | |
| 
 | |
|   //
 | |
|   // Update the CRC32 in the EFI System Table header
 | |
|   //
 | |
|   gST->Hdr.CRC32 = 0;
 | |
|   gBS->CalculateCrc32 (
 | |
|          (UINT8 *)&gST->Hdr,
 | |
|          gST->Hdr.HeaderSize,
 | |
|          &gST->Hdr.CRC32
 | |
|          );
 | |
|   return (Status);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return the system to the state it was before InstallConsoleLogger
 | |
|   was installed.
 | |
| 
 | |
|   @param[in] ConsoleInfo  The object from the install function.
 | |
| 
 | |
|   @retval EFI_SUCCESS     The operation was successful
 | |
|   @return other           The operation failed.  This was from UninstallProtocolInterface.
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerUninstall (
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   ASSERT (ConsoleInfo != NULL);
 | |
|   ASSERT (ConsoleInfo->OldConOut != NULL);
 | |
| 
 | |
|   if (ConsoleInfo->Buffer != NULL) {
 | |
|     FreePool (ConsoleInfo->Buffer);
 | |
|     DEBUG_CODE (
 | |
|       ConsoleInfo->Buffer = NULL;
 | |
|       );
 | |
|     DEBUG_CODE (
 | |
|       ConsoleInfo->BufferSize = 0;
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   if (ConsoleInfo->Attributes != NULL) {
 | |
|     FreePool (ConsoleInfo->Attributes);
 | |
|     DEBUG_CODE (
 | |
|       ConsoleInfo->Attributes = NULL;
 | |
|       );
 | |
|     DEBUG_CODE (
 | |
|       ConsoleInfo->AttribSize = 0;
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   gST->ConsoleOutHandle = ConsoleInfo->OldConHandle;
 | |
|   gST->ConOut           = ConsoleInfo->OldConOut;
 | |
| 
 | |
|   //
 | |
|   // Update the CRC32 in the EFI System Table header
 | |
|   //
 | |
|   gST->Hdr.CRC32 = 0;
 | |
|   gBS->CalculateCrc32 (
 | |
|          (UINT8 *)&gST->Hdr,
 | |
|          gST->Hdr.HeaderSize,
 | |
|          &gST->Hdr.CRC32
 | |
|          );
 | |
| 
 | |
|   return (gBS->UninstallProtocolInterface (gImageHandle, &gEfiSimpleTextOutProtocolGuid, (VOID *)&ConsoleInfo->OurConOut));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Displays previously logged output back to the screen.
 | |
| 
 | |
|   This will scroll the screen forwards and backwards through the log of previous
 | |
|   output.  If Rows is 0 then the size of 1/2 the screen will be scrolled.  If Rows
 | |
|   is (UINTN)(-1) then the size of the screen will be scrolled.
 | |
| 
 | |
|   @param[in] Forward      If TRUE then the log will be displayed forwards (scroll to newer).
 | |
|                           If FALSE then the log will be displayed backwards (scroll to older).
 | |
|   @param[in] Rows         Determines how many rows the log should scroll.
 | |
|   @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerDisplayHistory (
 | |
|   IN CONST BOOLEAN                Forward,
 | |
|   IN CONST UINTN                  Rows,
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   UINTN  RowChange;
 | |
| 
 | |
|   ASSERT (ConsoleInfo != NULL);
 | |
| 
 | |
|   //
 | |
|   // Calculate the row number change
 | |
|   //
 | |
|   switch (Rows) {
 | |
|     case ((UINTN)(-1)):
 | |
|       RowChange = ConsoleInfo->RowsPerScreen;
 | |
|       break;
 | |
|     case (0):
 | |
|       RowChange = ConsoleInfo->RowsPerScreen / 2;
 | |
|       break;
 | |
|     default:
 | |
|       RowChange = Rows;
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Do the math for direction
 | |
|   //
 | |
|   if (Forward) {
 | |
|     if ((ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow) < RowChange) {
 | |
|       RowChange = ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow;
 | |
|     }
 | |
|   } else {
 | |
|     if (ConsoleInfo->CurrentStartRow < RowChange) {
 | |
|       RowChange = ConsoleInfo->CurrentStartRow;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // If we are already at one end or the other
 | |
|   //
 | |
|   if (RowChange == 0) {
 | |
|     return (EFI_SUCCESS);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Clear the screen
 | |
|   //
 | |
|   ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);
 | |
| 
 | |
|   //
 | |
|   // Set the new start row
 | |
|   //
 | |
|   if (Forward) {
 | |
|     ConsoleInfo->CurrentStartRow += RowChange;
 | |
|   } else {
 | |
|     ConsoleInfo->CurrentStartRow -= RowChange;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Change the screen
 | |
|   //
 | |
|   return (UpdateDisplayFromHistory (ConsoleInfo));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Function to return to normal output whent he scrolling is complete.
 | |
|   @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
 | |
| 
 | |
|   @retval EFI_SUCCESS   The operation was successful.
 | |
|   @return other         The operation failed.  See UpdateDisplayFromHistory.
 | |
| 
 | |
|   @sa UpdateDisplayFromHistory
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerStopHistory (
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   ASSERT (ConsoleInfo != NULL);
 | |
|   if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {
 | |
|     return (EFI_SUCCESS);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Clear the screen
 | |
|   //
 | |
|   ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);
 | |
| 
 | |
|   ConsoleInfo->CurrentStartRow = ConsoleInfo->OriginalStartRow;
 | |
|   return (UpdateDisplayFromHistory (ConsoleInfo));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Updates the hidden ConOut to be displaying the correct stuff.
 | |
|   @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
 | |
| 
 | |
|   @retval EFI_SUCCESS     The operation was successful.
 | |
|   @return other           The operation failed.
 | |
| **/
 | |
| EFI_STATUS
 | |
| UpdateDisplayFromHistory (
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   EFI_STATUS  RetVal;
 | |
|   CHAR16      *Screen;
 | |
|   INT32       *Attributes;
 | |
|   UINTN       CurrentRow;
 | |
|   CHAR16      TempCharHolder;
 | |
|   UINTN       Column;
 | |
|   INT32       CurrentAttrib;
 | |
|   UINTN       CurrentColumn;
 | |
|   CHAR16      *StringSegment;
 | |
|   CHAR16      *StringSegmentEnd;
 | |
|   CHAR16      StringSegmentEndChar;
 | |
|   INT32       OrigAttribute;
 | |
| 
 | |
|   ASSERT (ConsoleInfo != NULL);
 | |
|   TempCharHolder = CHAR_NULL;
 | |
|   RetVal         = EFI_SUCCESS;
 | |
|   OrigAttribute  = ConsoleInfo->OldConOut->Mode->Attribute;
 | |
| 
 | |
|   //
 | |
|   // Disable cursor visibility and move it to the top left corner
 | |
|   //
 | |
|   ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, FALSE);
 | |
|   ConsoleInfo->OldConOut->SetCursorPosition (ConsoleInfo->OldConOut, 0, 0);
 | |
| 
 | |
|   Screen     = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
 | |
|   Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
 | |
|   for ( CurrentRow = 0
 | |
|         ; CurrentRow < ConsoleInfo->RowsPerScreen
 | |
|         ; CurrentRow++,
 | |
|         Screen += (ConsoleInfo->ColsPerScreen + 2),
 | |
|         Attributes += ConsoleInfo->ColsPerScreen
 | |
|         )
 | |
|   {
 | |
|     //
 | |
|     // dont use the last char - prevents screen scroll
 | |
|     //
 | |
|     if (CurrentRow == (ConsoleInfo->RowsPerScreen-1)) {
 | |
|       TempCharHolder                         = Screen[ConsoleInfo->ColsPerScreen - 1];
 | |
|       Screen[ConsoleInfo->ColsPerScreen - 1] = CHAR_NULL;
 | |
|     }
 | |
| 
 | |
|     for ( Column = 0
 | |
|           ; Column < ConsoleInfo->ColsPerScreen
 | |
|           ; Column++
 | |
|           )
 | |
|     {
 | |
|       if (Screen[Column] != CHAR_NULL) {
 | |
|         CurrentAttrib = Attributes[Column];
 | |
|         CurrentColumn = Column;
 | |
|         StringSegment = &Screen[Column];
 | |
| 
 | |
|         //
 | |
|         // Find the first char with a different attribute and make that temporarily NULL
 | |
|         // so we can do fewer printout statements.  (later) restore that one and we will
 | |
|         // start at that column on the next loop.
 | |
|         //
 | |
|         StringSegmentEndChar = CHAR_NULL;
 | |
|         for ( StringSegmentEnd = StringSegment
 | |
|               ; *StringSegmentEnd != CHAR_NULL
 | |
|               ; StringSegmentEnd++,
 | |
|               Column++
 | |
|               )
 | |
|         {
 | |
|           if (Attributes[Column] != CurrentAttrib) {
 | |
|             StringSegmentEndChar = *StringSegmentEnd;
 | |
|             *StringSegmentEnd    = CHAR_NULL;
 | |
|             break;
 | |
|           }
 | |
|         } // StringSegmentEnd loop
 | |
| 
 | |
|         //
 | |
|         // Now write out as much as had the same Attributes
 | |
|         //
 | |
| 
 | |
|         ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, CurrentAttrib);
 | |
|         ConsoleInfo->OldConOut->SetCursorPosition (ConsoleInfo->OldConOut, CurrentColumn, CurrentRow);
 | |
|         Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, StringSegment);
 | |
| 
 | |
|         if (EFI_ERROR (Status)) {
 | |
|           ASSERT (FALSE);
 | |
|           RetVal = Status;
 | |
|         }
 | |
| 
 | |
|         //
 | |
|         // If we found a change in attribute put the character back and decrement the column
 | |
|         // so when it increments it will point at that character and we will start printing
 | |
|         // a segment with that new attribute
 | |
|         //
 | |
|         if (StringSegmentEndChar != CHAR_NULL) {
 | |
|           *StringSegmentEnd    = StringSegmentEndChar;
 | |
|           StringSegmentEndChar = CHAR_NULL;
 | |
|           Column--;
 | |
|         }
 | |
|       }
 | |
|     } // column for loop
 | |
| 
 | |
|     //
 | |
|     // If we removed the last char and this was the last row put it back
 | |
|     //
 | |
|     if (TempCharHolder != CHAR_NULL) {
 | |
|       Screen[ConsoleInfo->ColsPerScreen - 1] = TempCharHolder;
 | |
|       TempCharHolder                         = CHAR_NULL;
 | |
|     }
 | |
|   } // row for loop
 | |
| 
 | |
|   //
 | |
|   // If we are setting the screen back to original turn on the cursor and make it visible
 | |
|   // and set the attributes back to what they were
 | |
|   //
 | |
|   if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {
 | |
|     ConsoleInfo->OldConOut->SetAttribute (
 | |
|                               ConsoleInfo->OldConOut,
 | |
|                               ConsoleInfo->HistoryMode.Attribute
 | |
|                               );
 | |
|     ConsoleInfo->OldConOut->SetCursorPosition (
 | |
|                               ConsoleInfo->OldConOut,
 | |
|                               ConsoleInfo->HistoryMode.CursorColumn,
 | |
|                               ConsoleInfo->HistoryMode.CursorRow - ConsoleInfo->OriginalStartRow
 | |
|                               );
 | |
| 
 | |
|     Status = ConsoleInfo->OldConOut->EnableCursor (
 | |
|                                        ConsoleInfo->OldConOut,
 | |
|                                        ConsoleInfo->HistoryMode.CursorVisible
 | |
|                                        );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       RetVal = Status;
 | |
|     }
 | |
|   } else {
 | |
|     ConsoleInfo->OldConOut->SetAttribute (
 | |
|                               ConsoleInfo->OldConOut,
 | |
|                               OrigAttribute
 | |
|                               );
 | |
|   }
 | |
| 
 | |
|   return (RetVal);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Reset the text output device hardware and optionally run diagnostics
 | |
| 
 | |
|   @param  This                pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
 | |
|   @param ExtendedVerification Indicates that a more extensive test may be performed
 | |
| 
 | |
|   @retval EFI_SUCCESS         The text output device was reset.
 | |
|   @retval EFI_DEVICE_ERROR    The text output device is not functioning correctly and
 | |
|                               could not be reset.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerReset (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  BOOLEAN                          ExtendedVerification
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                   Status;
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
| 
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->Reset (ConsoleInfo->OldConOut, ExtendedVerification);
 | |
| 
 | |
|   //
 | |
|   // Check that the buffers are still correct for logging
 | |
|   //
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     ConsoleLoggerResetBuffers (ConsoleInfo);
 | |
|     if (ExtendedVerification) {
 | |
|       ConsoleInfo->OriginalStartRow = 0;
 | |
|       ConsoleInfo->CurrentStartRow  = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Appends a string to the history buffer.  If the buffer is full then the oldest
 | |
|   information in the buffer will be dropped.  Information is added in a line by
 | |
|   line manner such that an empty line takes up just as much space as a full line.
 | |
| 
 | |
|   @param[in] String       String pointer to add.
 | |
|   @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
 | |
| **/
 | |
| EFI_STATUS
 | |
| AppendStringToHistory (
 | |
|   IN CONST CHAR16                 *String,
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   CONST CHAR16  *Walker;
 | |
|   UINTN         CopySize;
 | |
|   UINTN         PrintIndex;
 | |
|   UINTN         Index;
 | |
| 
 | |
|   ASSERT (ConsoleInfo != NULL);
 | |
| 
 | |
|   for ( Walker = String
 | |
|         ; Walker != NULL && *Walker != CHAR_NULL
 | |
|         ; Walker++
 | |
|         )
 | |
|   {
 | |
|     switch (*Walker) {
 | |
|       case (CHAR_BACKSPACE):
 | |
|         if (ConsoleInfo->HistoryMode.CursorColumn > 0) {
 | |
|           ConsoleInfo->HistoryMode.CursorColumn--;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case (CHAR_LINEFEED):
 | |
|         if (ConsoleInfo->HistoryMode.CursorRow >= (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1)) {
 | |
|           //
 | |
|           // Should never be bigger
 | |
|           //
 | |
|           ASSERT (ConsoleInfo->HistoryMode.CursorRow == (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1));
 | |
| 
 | |
|           //
 | |
|           // scroll history attributes 'up' 1 row and set the last row to default attribute
 | |
|           //
 | |
|           CopySize = ConsoleInfo->ColsPerScreen
 | |
|                      * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)
 | |
|                      * sizeof (ConsoleInfo->Attributes[0]);
 | |
|           ASSERT (CopySize < ConsoleInfo->AttribSize);
 | |
|           CopyMem (
 | |
|             ConsoleInfo->Attributes,
 | |
|             ConsoleInfo->Attributes + ConsoleInfo->ColsPerScreen,
 | |
|             CopySize
 | |
|             );
 | |
| 
 | |
|           for ( Index = 0
 | |
|                 ; Index < ConsoleInfo->ColsPerScreen
 | |
|                 ; Index++
 | |
|                 )
 | |
|           {
 | |
|             *(ConsoleInfo->Attributes + (CopySize/sizeof (ConsoleInfo->Attributes[0])) + Index) = ConsoleInfo->HistoryMode.Attribute;
 | |
|           }
 | |
| 
 | |
|           //
 | |
|           // scroll history buffer 'up' 1 row and set the last row to spaces (L' ')
 | |
|           //
 | |
|           CopySize = (ConsoleInfo->ColsPerScreen + 2)
 | |
|                      * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)
 | |
|                      * sizeof (ConsoleInfo->Buffer[0]);
 | |
|           ASSERT (CopySize < ConsoleInfo->BufferSize);
 | |
|           CopyMem (
 | |
|             ConsoleInfo->Buffer,
 | |
|             ConsoleInfo->Buffer + (ConsoleInfo->ColsPerScreen + 2),
 | |
|             CopySize
 | |
|             );
 | |
| 
 | |
|           //
 | |
|           // Set that last row of chars to spaces
 | |
|           //
 | |
|           SetMem16 (((UINT8 *)ConsoleInfo->Buffer)+CopySize, ConsoleInfo->ColsPerScreen*sizeof (CHAR16), L' ');
 | |
|         } else {
 | |
|           //
 | |
|           // we are not on the last row
 | |
|           //
 | |
| 
 | |
|           //
 | |
|           // We should not be scrolling history
 | |
|           //
 | |
|           ASSERT (ConsoleInfo->OriginalStartRow == ConsoleInfo->CurrentStartRow);
 | |
|           //
 | |
|           // are we at the end of a row?
 | |
|           //
 | |
|           if (ConsoleInfo->HistoryMode.CursorRow == (INT32)(ConsoleInfo->OriginalStartRow + ConsoleInfo->RowsPerScreen - 1)) {
 | |
|             ConsoleInfo->OriginalStartRow++;
 | |
|             ConsoleInfo->CurrentStartRow++;
 | |
|           }
 | |
| 
 | |
|           ConsoleInfo->HistoryMode.CursorRow++;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case (CHAR_CARRIAGE_RETURN):
 | |
|         //
 | |
|         // Move the cursor to the beginning of the current row.
 | |
|         //
 | |
|         ConsoleInfo->HistoryMode.CursorColumn = 0;
 | |
|         break;
 | |
|       default:
 | |
|         //
 | |
|         // Acrtually print characters into the history buffer
 | |
|         //
 | |
| 
 | |
|         PrintIndex = ConsoleInfo->HistoryMode.CursorRow * ConsoleInfo->ColsPerScreen + ConsoleInfo->HistoryMode.CursorColumn;
 | |
| 
 | |
|         for ( // no initializer needed
 | |
|               ; ConsoleInfo->HistoryMode.CursorColumn < (INT32)ConsoleInfo->ColsPerScreen
 | |
|               ; ConsoleInfo->HistoryMode.CursorColumn++,
 | |
|               PrintIndex++,
 | |
|               Walker++
 | |
|               )
 | |
|         {
 | |
|           if (  (*Walker == CHAR_NULL)
 | |
|              || (*Walker == CHAR_BACKSPACE)
 | |
|              || (*Walker == CHAR_LINEFEED)
 | |
|              || (*Walker == CHAR_CARRIAGE_RETURN)
 | |
|                 )
 | |
|           {
 | |
|             Walker--;
 | |
|             break;
 | |
|           }
 | |
| 
 | |
|           //
 | |
|           // The buffer is 2*CursorRow more since it has that many \r\n characters at the end of each row.
 | |
|           //
 | |
| 
 | |
|           ASSERT (PrintIndex + ConsoleInfo->HistoryMode.CursorRow < ConsoleInfo->BufferSize);
 | |
|           ConsoleInfo->Buffer[PrintIndex + (2*ConsoleInfo->HistoryMode.CursorRow)] = *Walker;
 | |
|           ASSERT (PrintIndex < ConsoleInfo->AttribSize);
 | |
|           ConsoleInfo->Attributes[PrintIndex] = ConsoleInfo->HistoryMode.Attribute;
 | |
|         } // for loop
 | |
| 
 | |
|         //
 | |
|         // Add the carriage return and line feed at the end of the lines
 | |
|         //
 | |
|         if (ConsoleInfo->HistoryMode.CursorColumn >= (INT32)ConsoleInfo->ColsPerScreen) {
 | |
|           AppendStringToHistory (L"\r\n", ConsoleInfo);
 | |
|           Walker--;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|     } // switch for character
 | |
|   } // for loop
 | |
| 
 | |
|   return (EFI_SUCCESS);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Worker function to handle printing the output to the screen
 | |
|   and the history buffer
 | |
| 
 | |
|   @param[in] String               The string to output
 | |
|   @param[in] ConsoleInfo          The pointer to the instance of the console logger information.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The string was printed
 | |
|   @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
 | |
|                                   the text.
 | |
|   @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
 | |
|                                   defined text mode.
 | |
|   @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
 | |
|                                   characters in the Unicode string could not be
 | |
|                                   rendered and were skipped.
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerOutputStringSplit (
 | |
|   IN CONST CHAR16                 *String,
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, (CHAR16 *)String);
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return (Status);
 | |
|   }
 | |
| 
 | |
|   return (AppendStringToHistory (String, ConsoleInfo));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Function to handle page break mode.
 | |
| 
 | |
|   This function will prompt for continue or break.
 | |
| 
 | |
|   @retval EFI_SUCCESS   Continue was choosen
 | |
|   @return other         Break was choosen
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerDoPageBreak (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   SHELL_PROMPT_RESPONSE  *Resp;
 | |
|   EFI_STATUS             Status;
 | |
| 
 | |
|   Resp = NULL;
 | |
|   ASSERT (ShellInfoObject.PageBreakEnabled);
 | |
|   ShellInfoObject.PageBreakEnabled = FALSE;
 | |
|   Status                           = ShellPromptForResponseHii (ShellPromptResponseTypeQuitContinue, STRING_TOKEN (STR_SHELL_QUIT_CONT), ShellInfoObject.HiiHandle, (VOID **)&Resp);
 | |
|   ShellInfoObject.PageBreakEnabled = TRUE;
 | |
|   ASSERT (Resp != NULL);
 | |
|   if (Resp == NULL) {
 | |
|     return (EFI_NOT_FOUND);
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     if (Resp != NULL) {
 | |
|       FreePool (Resp);
 | |
|     }
 | |
| 
 | |
|     return (Status);
 | |
|   }
 | |
| 
 | |
|   if (*Resp == ShellPromptResponseContinue) {
 | |
|     FreePool (Resp);
 | |
|     ShellInfoObject.ConsoleInfo->RowCounter = 0;
 | |
|     //    ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorRow    = 0;
 | |
|     //    ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
 | |
| 
 | |
|     return (EFI_SUCCESS);
 | |
|   } else if (*Resp == ShellPromptResponseQuit) {
 | |
|     FreePool (Resp);
 | |
|     ShellInfoObject.ConsoleInfo->Enabled = FALSE;
 | |
|     //
 | |
|     // When user wants to quit, the shell should stop running the command.
 | |
|     //
 | |
|     gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
 | |
|     return (EFI_DEVICE_ERROR);
 | |
|   } else {
 | |
|     ASSERT (FALSE);
 | |
|   }
 | |
| 
 | |
|   return (EFI_SUCCESS);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Worker function to handle printing the output with page breaks.
 | |
| 
 | |
|   @param[in] String               The string to output
 | |
|   @param[in] ConsoleInfo          The pointer to the instance of the console logger information.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The string was printed
 | |
|   @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
 | |
|                                   the text.
 | |
|   @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
 | |
|                                   defined text mode.
 | |
|   @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
 | |
|                                   characters in the Unicode string could not be
 | |
|                                   rendered and were skipped.
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerPrintWithPageBreak (
 | |
|   IN CONST CHAR16                 *String,
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   CONST CHAR16  *Walker;
 | |
|   CONST CHAR16  *LineStart;
 | |
|   CHAR16        *StringCopy;
 | |
|   CHAR16        TempChar;
 | |
| 
 | |
|   StringCopy = NULL;
 | |
|   StringCopy = StrnCatGrow (&StringCopy, NULL, String, 0);
 | |
|   if (StringCopy == NULL) {
 | |
|     return (EFI_OUT_OF_RESOURCES);
 | |
|   }
 | |
| 
 | |
|   for ( Walker = StringCopy,
 | |
|         LineStart = StringCopy
 | |
|         ; Walker != NULL && *Walker != CHAR_NULL
 | |
|         ; Walker++
 | |
|         )
 | |
|   {
 | |
|     switch (*Walker) {
 | |
|       case (CHAR_BACKSPACE):
 | |
|         if (ConsoleInfo->OurConOut.Mode->CursorColumn > 0) {
 | |
|           ConsoleInfo->OurConOut.Mode->CursorColumn--;
 | |
|         }
 | |
| 
 | |
|         break;
 | |
|       case (CHAR_LINEFEED):
 | |
|         //
 | |
|         // add a temp NULL terminator
 | |
|         //
 | |
|         TempChar                = *(Walker + 1);
 | |
|         *((CHAR16 *)(Walker+1)) = CHAR_NULL;
 | |
| 
 | |
|         //
 | |
|         // output the string
 | |
|         //
 | |
|         ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
 | |
| 
 | |
|         //
 | |
|         // restore the temp NULL terminator to its original character
 | |
|         //
 | |
|         *((CHAR16 *)(Walker+1)) = TempChar;
 | |
| 
 | |
|         //
 | |
|         // Update LineStart Variable
 | |
|         //
 | |
|         LineStart = Walker + 1;
 | |
| 
 | |
|         //
 | |
|         // increment row count
 | |
|         //
 | |
|         ShellInfoObject.ConsoleInfo->RowCounter++;
 | |
|         ConsoleInfo->OurConOut.Mode->CursorRow++;
 | |
| 
 | |
|         break;
 | |
|       case (CHAR_CARRIAGE_RETURN):
 | |
|         //
 | |
|         // Move the cursor to the beginning of the current row.
 | |
|         //
 | |
|         ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
 | |
|         break;
 | |
|       default:
 | |
|         //
 | |
|         // increment column count
 | |
|         //
 | |
|         ConsoleInfo->OurConOut.Mode->CursorColumn++;
 | |
|         //
 | |
|         // check if that is the last column
 | |
|         //
 | |
|         if ((INTN)ConsoleInfo->ColsPerScreen == ConsoleInfo->OurConOut.Mode->CursorColumn + 1) {
 | |
|           //
 | |
|           // output a line similar to the linefeed character.
 | |
|           //
 | |
| 
 | |
|           //
 | |
|           // add a temp NULL terminator
 | |
|           //
 | |
|           TempChar                = *(Walker + 1);
 | |
|           *((CHAR16 *)(Walker+1)) = CHAR_NULL;
 | |
| 
 | |
|           //
 | |
|           // output the string
 | |
|           //
 | |
|           ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
 | |
| 
 | |
|           //
 | |
|           // restore the temp NULL terminator to its original character
 | |
|           //
 | |
|           *((CHAR16 *)(Walker+1)) = TempChar;
 | |
| 
 | |
|           //
 | |
|           // Update LineStart Variable
 | |
|           //
 | |
|           LineStart = Walker + 1;
 | |
| 
 | |
|           //
 | |
|           // increment row count and zero the column
 | |
|           //
 | |
|           ShellInfoObject.ConsoleInfo->RowCounter++;
 | |
|           ConsoleInfo->OurConOut.Mode->CursorRow++;
 | |
|           ConsoleInfo->OurConOut.Mode->CursorColumn = 0;
 | |
|         } // last column on line
 | |
| 
 | |
|         break;
 | |
|     } // switch for character
 | |
| 
 | |
|     //
 | |
|     // check if that was the last printable row.  If yes handle PageBreak mode
 | |
|     //
 | |
|     if ((ConsoleInfo->RowsPerScreen) -1 == ShellInfoObject.ConsoleInfo->RowCounter) {
 | |
|       if (EFI_ERROR (ConsoleLoggerDoPageBreak ())) {
 | |
|         //
 | |
|         // We got an error which means 'break' and halt the printing
 | |
|         //
 | |
|         SHELL_FREE_NON_NULL (StringCopy);
 | |
|         return (EFI_DEVICE_ERROR);
 | |
|       }
 | |
|     }
 | |
|   } // for loop
 | |
| 
 | |
|   if ((LineStart != NULL) && (*LineStart != CHAR_NULL)) {
 | |
|     ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);
 | |
|   }
 | |
| 
 | |
|   SHELL_FREE_NON_NULL (StringCopy);
 | |
|   return (EFI_SUCCESS);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Write a Unicode string to the output device.
 | |
| 
 | |
|   @param[in] This                 Protocol instance pointer.
 | |
|   @param[in] WString              The NULL-terminated Unicode string to be displayed on the output
 | |
|                                   device(s). All output devices must also support the Unicode
 | |
|                                   drawing defined in this file.
 | |
|   @retval EFI_SUCCESS             The string was output to the device.
 | |
|   @retval EFI_DEVICE_ERROR        The device reported an error while attempting to output
 | |
|                                   the text.
 | |
|   @retval EFI_UNSUPPORTED         The output device's mode is not currently in a
 | |
|                                   defined text mode.
 | |
|   @retval EFI_WARN_UNKNOWN_GLYPH  This warning code indicates that some of the
 | |
|                                   characters in the Unicode string could not be
 | |
|                                   rendered and were skipped.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerOutputString (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  CHAR16                           *WString
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                         Status;
 | |
|   EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *TxtInEx;
 | |
|   EFI_KEY_DATA                       KeyData;
 | |
|   UINTN                              EventIndex;
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA        *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
|   if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
 | |
|     return (EFI_UNSUPPORTED);
 | |
|   }
 | |
| 
 | |
|   ASSERT (ShellInfoObject.ConsoleInfo == ConsoleInfo);
 | |
| 
 | |
|   Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **)&TxtInEx);
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     while (ShellInfoObject.HaltOutput) {
 | |
|       ShellInfoObject.HaltOutput = FALSE;
 | |
|       //
 | |
|       // just get some key
 | |
|       //
 | |
|       Status = gBS->WaitForEvent (1, &TxtInEx->WaitForKeyEx, &EventIndex);
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|       Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|       if ((KeyData.Key.UnicodeChar == L's') && (KeyData.Key.ScanCode == SCAN_NULL) &&
 | |
|           ((KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED)) ||
 | |
|            (KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED))
 | |
|           )
 | |
|           )
 | |
|       {
 | |
|         ShellInfoObject.HaltOutput = TRUE;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (!ShellInfoObject.ConsoleInfo->Enabled) {
 | |
|     return (EFI_DEVICE_ERROR);
 | |
|   } else if (ShellInfoObject.PageBreakEnabled) {
 | |
|     return (ConsoleLoggerPrintWithPageBreak (WString, ConsoleInfo));
 | |
|   } else {
 | |
|     return (ConsoleLoggerOutputStringSplit (WString, ConsoleInfo));
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Verifies that all characters in a Unicode string can be output to the
 | |
|   target device.
 | |
| 
 | |
|   @param[in] This     Protocol instance pointer.
 | |
|   @param[in] WString  The NULL-terminated Unicode string to be examined for the output
 | |
|                       device(s).
 | |
| 
 | |
|   @retval EFI_SUCCESS           The device(s) are capable of rendering the output string.
 | |
|   @retval EFI_UNSUPPORTED       Some of the characters in the Unicode string cannot be
 | |
|                                 rendered by one or more of the output devices mapped
 | |
|                                 by the EFI handle.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerTestString (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  CHAR16                           *WString
 | |
|   )
 | |
| {
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   return (ConsoleInfo->OldConOut->TestString (ConsoleInfo->OldConOut, WString));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Returns information for an available text mode that the output device(s)
 | |
|   supports.
 | |
| 
 | |
|   @param[in] This               Protocol instance pointer.
 | |
|   @param[in] ModeNumber         The mode number to return information on.
 | |
|   @param[out] Columns           Upon return, the number of columns in the selected geometry
 | |
|   @param[out] Rows              Upon return, the number of rows in the selected geometry
 | |
| 
 | |
|   @retval EFI_SUCCESS           The requested mode information was returned.
 | |
|   @retval EFI_DEVICE_ERROR      The device had an error and could not
 | |
|                                 complete the request.
 | |
|   @retval EFI_UNSUPPORTED       The mode number was not valid.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerQueryMode (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  UINTN                            ModeNumber,
 | |
|   OUT UINTN                            *Columns,
 | |
|   OUT UINTN                            *Rows
 | |
|   )
 | |
| {
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   return (ConsoleInfo->OldConOut->QueryMode (
 | |
|                                     ConsoleInfo->OldConOut,
 | |
|                                     ModeNumber,
 | |
|                                     Columns,
 | |
|                                     Rows
 | |
|                                     ));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Sets the output device(s) to a specified mode.
 | |
| 
 | |
|   @param[in] This               Protocol instance pointer.
 | |
|   @param[in] ModeNumber         The mode number to set.
 | |
| 
 | |
| 
 | |
|   @retval EFI_SUCCESS           The requested text mode was set.
 | |
|   @retval EFI_DEVICE_ERROR      The device had an error and
 | |
|                                 could not complete the request.
 | |
|   @retval EFI_UNSUPPORTED       The mode number was not valid.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerSetMode (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  UINTN                            ModeNumber
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
| 
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->SetMode (ConsoleInfo->OldConOut, ModeNumber);
 | |
| 
 | |
|   //
 | |
|   // Check that the buffers are still correct for logging
 | |
|   //
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     ConsoleInfo->OurConOut.Mode = ConsoleInfo->OldConOut->Mode;
 | |
|     ConsoleLoggerResetBuffers (ConsoleInfo);
 | |
|     ConsoleInfo->OriginalStartRow = 0;
 | |
|     ConsoleInfo->CurrentStartRow  = 0;
 | |
|     ConsoleInfo->OurConOut.ClearScreen (&ConsoleInfo->OurConOut);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Sets the background and foreground colors for the OutputString () and
 | |
|   ClearScreen () functions.
 | |
| 
 | |
|   @param[in] This               Protocol instance pointer.
 | |
|   @param[in] Attribute          The attribute to set. Bits 0..3 are the foreground color, and
 | |
|                                 bits 4..6 are the background color. All other bits are undefined
 | |
|                                 and must be zero. The valid Attributes are defined in this file.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The attribute was set.
 | |
|   @retval EFI_DEVICE_ERROR      The device had an error and
 | |
|                                 could not complete the request.
 | |
|   @retval EFI_UNSUPPORTED       The attribute requested is not defined.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerSetAttribute (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  UINTN                            Attribute
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
| 
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, Attribute);
 | |
| 
 | |
|   //
 | |
|   // Record console output history
 | |
|   //
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     ConsoleInfo->HistoryMode.Attribute = (INT32)Attribute;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Clears the output device(s) display to the currently selected background
 | |
|   color.
 | |
| 
 | |
|   @param[in] This               Protocol instance pointer.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation completed successfully.
 | |
|   @retval EFI_DEVICE_ERROR      The device had an error and
 | |
|                                 could not complete the request.
 | |
|   @retval EFI_UNSUPPORTED       The output device is not in a valid text mode.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerClearScreen (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                   Status;
 | |
|   CHAR16                       *Screen;
 | |
|   INT32                        *Attributes;
 | |
|   UINTN                        Row;
 | |
|   UINTN                        Column;
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
 | |
|     return (EFI_UNSUPPORTED);
 | |
|   }
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
| 
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);
 | |
| 
 | |
|   //
 | |
|   // Record console output history
 | |
|   //
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Screen     = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];
 | |
|     Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];
 | |
|     for ( Row = ConsoleInfo->OriginalStartRow
 | |
|           ; Row < (ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)
 | |
|           ; Row++
 | |
|           )
 | |
|     {
 | |
|       for ( Column = 0
 | |
|             ; Column < ConsoleInfo->ColsPerScreen
 | |
|             ; Column++,
 | |
|             Screen++,
 | |
|             Attributes++
 | |
|             )
 | |
|       {
 | |
|         *Screen     = L' ';
 | |
|         *Attributes = ConsoleInfo->OldConOut->Mode->Attribute;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Skip the NULL on each column end in text buffer only
 | |
|       //
 | |
|       Screen += 2;
 | |
|     }
 | |
| 
 | |
|     ConsoleInfo->HistoryMode.CursorColumn = 0;
 | |
|     ConsoleInfo->HistoryMode.CursorRow    = 0;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Sets the current coordinates of the cursor position
 | |
| 
 | |
|   @param[in] This               Protocol instance pointer.
 | |
|   @param[in] Column             Column to put the cursor in.  Must be between zero and Column returned from QueryMode
 | |
|   @param[in] Row                Row to put the cursor in.  Must be between zero and Row returned from QueryMode
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation completed successfully.
 | |
|   @retval EFI_DEVICE_ERROR      The device had an error and
 | |
|                                 could not complete the request.
 | |
|   @retval EFI_UNSUPPORTED       The output device is not in a valid text mode, or the
 | |
|                                 cursor position is invalid for the current mode.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerSetCursorPosition (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  UINTN                            Column,
 | |
|   IN  UINTN                            Row
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                   Status;
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
 | |
|     return (EFI_UNSUPPORTED);
 | |
|   }
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->SetCursorPosition (
 | |
|                                      ConsoleInfo->OldConOut,
 | |
|                                      Column,
 | |
|                                      Row
 | |
|                                      );
 | |
| 
 | |
|   //
 | |
|   // Record console output history
 | |
|   //
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     ConsoleInfo->HistoryMode.CursorColumn = (INT32)Column;
 | |
|     ConsoleInfo->HistoryMode.CursorRow    = (INT32)(ConsoleInfo->OriginalStartRow + Row);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Makes the cursor visible or invisible
 | |
| 
 | |
|   @param[in] This       Protocol instance pointer.
 | |
|   @param[in] Visible    If TRUE, the cursor is set to be visible. If FALSE, the cursor is
 | |
|                         set to be invisible.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation completed successfully.
 | |
|   @retval EFI_DEVICE_ERROR      The device had an error and could not complete the
 | |
|                                 request, or the device does not support changing
 | |
|                                 the cursor mode.
 | |
|   @retval EFI_UNSUPPORTED       The output device is not in a valid text mode.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| ConsoleLoggerEnableCursor (
 | |
|   IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
 | |
|   IN  BOOLEAN                          Visible
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo;
 | |
| 
 | |
|   ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS (This);
 | |
|   //
 | |
|   // Forward the request to the original ConOut
 | |
|   //
 | |
|   Status = ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, Visible);
 | |
| 
 | |
|   //
 | |
|   // Record console output history
 | |
|   //
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     ConsoleInfo->HistoryMode.CursorVisible = Visible;
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Function to update and verify that the current buffers are correct.
 | |
| 
 | |
|   @param[in] ConsoleInfo  The pointer to the instance of the console logger information.
 | |
| 
 | |
|   This will be used when a mode has changed or a reset occurred to verify all
 | |
|   history buffers.
 | |
| **/
 | |
| EFI_STATUS
 | |
| ConsoleLoggerResetBuffers (
 | |
|   IN CONSOLE_LOGGER_PRIVATE_DATA  *ConsoleInfo
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   if (ConsoleInfo->Buffer != NULL) {
 | |
|     FreePool (ConsoleInfo->Buffer);
 | |
|     ConsoleInfo->Buffer     = NULL;
 | |
|     ConsoleInfo->BufferSize = 0;
 | |
|   }
 | |
| 
 | |
|   if (ConsoleInfo->Attributes != NULL) {
 | |
|     FreePool (ConsoleInfo->Attributes);
 | |
|     ConsoleInfo->Attributes = NULL;
 | |
|     ConsoleInfo->AttribSize = 0;
 | |
|   }
 | |
| 
 | |
|   Status = gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &ConsoleInfo->ColsPerScreen, &ConsoleInfo->RowsPerScreen);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return (Status);
 | |
|   }
 | |
| 
 | |
|   ConsoleInfo->BufferSize = (ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof (ConsoleInfo->Buffer[0]);
 | |
|   ConsoleInfo->AttribSize = ConsoleInfo->ColsPerScreen * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof (ConsoleInfo->Attributes[0]);
 | |
| 
 | |
|   ConsoleInfo->Buffer = (CHAR16 *)AllocateZeroPool (ConsoleInfo->BufferSize);
 | |
| 
 | |
|   if (ConsoleInfo->Buffer == NULL) {
 | |
|     return (EFI_OUT_OF_RESOURCES);
 | |
|   }
 | |
| 
 | |
|   ConsoleInfo->Attributes = (INT32 *)AllocateZeroPool (ConsoleInfo->AttribSize);
 | |
|   if (ConsoleInfo->Attributes == NULL) {
 | |
|     FreePool (ConsoleInfo->Buffer);
 | |
|     ConsoleInfo->Buffer = NULL;
 | |
|     return (EFI_OUT_OF_RESOURCES);
 | |
|   }
 | |
| 
 | |
|   CopyMem (&ConsoleInfo->HistoryMode, ConsoleInfo->OldConOut->Mode, sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));
 | |
| 
 | |
|   return (EFI_SUCCESS);
 | |
| }
 |