/** @file
  Provides interface to shell console logger.

  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2016 Hewlett-Packard Development Company, L.P.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/

#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 arrribute and make that temporarily NULL
        // so we can do fewer printout statements.  (later) restore that one and we will
        // start at that collumn 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 optionaly 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 it's 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 it's 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 ocurred 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);
}
