/** @file
  EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables,
  StdIn, StdOut, StdErr, etc...).

  Copyright 2016 Dell Inc.
  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2013 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"
#include "FileHandleInternal.h"

#define MEM_WRITE_REALLOC_OVERHEAD 1024

/**
  File style interface for console (Open).  
  
  @param[in] This       Ignored.
  @param[out] NewHandle Ignored.
  @param[in] FileName   Ignored.
  @param[in] OpenMode   Ignored.
  @param[in] Attributes Ignored.
  
  @retval EFI_NOT_FOUND
**/
EFI_STATUS
EFIAPI
FileInterfaceOpenNotFound(
  IN EFI_FILE_PROTOCOL *This,
  OUT EFI_FILE_PROTOCOL **NewHandle,
  IN CHAR16 *FileName,
  IN UINT64 OpenMode,
  IN UINT64 Attributes
  )
{
  return (EFI_NOT_FOUND);
}

/**
  File style interface for console (Close, Delete, & Flush)
  
  @param[in] This       Ignored.
  
  @retval EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
FileInterfaceNopGeneric(
  IN EFI_FILE_PROTOCOL *This
  )
{
  return (EFI_SUCCESS);
}

/**
  File style interface for console (GetPosition).

  @param[in] This       Ignored.
  @param[out] Position  Ignored.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
FileInterfaceNopGetPosition(
  IN EFI_FILE_PROTOCOL *This,
  OUT UINT64 *Position
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for console (SetPosition).
  
  @param[in] This       Ignored.
  @param[in] Position   Ignored.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
FileInterfaceNopSetPosition(
  IN EFI_FILE_PROTOCOL *This,
  IN UINT64 Position
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for console (GetInfo).
  
  @param[in] This              Ignored.
  @param[in] InformationType   Ignored.
  @param[in, out] BufferSize   Ignored.
  @param[out] Buffer           Ignored.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
FileInterfaceNopGetInfo(
  IN EFI_FILE_PROTOCOL *This,
  IN EFI_GUID *InformationType,
  IN OUT UINTN *BufferSize,
  OUT VOID *Buffer
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for console (SetInfo).
  
  @param[in] This       Ignored.
  @param[in] InformationType   Ignored.
  @param[in] BufferSize Ignored.
  @param[in] Buffer     Ignored.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
FileInterfaceNopSetInfo(
  IN EFI_FILE_PROTOCOL *This,
  IN EFI_GUID *InformationType,
  IN UINTN BufferSize,
  IN VOID *Buffer
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for StdOut (Write).

  Writes data to the screen.
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to write.
  
  @retval EFI_UNSUPPORTED No output console is supported.
  @return A return value from gST->ConOut->OutputString.
**/
EFI_STATUS
EFIAPI
FileInterfaceStdOutWrite(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
    return (EFI_UNSUPPORTED);
  }
  if (*((CHAR16 *)Buffer) == gUnicodeFileTag) {
    return (gST->ConOut->OutputString(gST->ConOut, (CHAR16 *)Buffer + 1));
  }
  return (gST->ConOut->OutputString(gST->ConOut, Buffer));
}

/**
  File style interface for StdIn (Write).
  
  @param[in] This            Ignored.
  @param[in, out] BufferSize Ignored.
  @param[in] Buffer          Ignored.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
FileInterfaceStdInWrite(
  IN      EFI_FILE_PROTOCOL *This,
  IN OUT  UINTN             *BufferSize,
  IN      VOID              *Buffer
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for console StdErr (Write).

  Writes error to the error output.
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to write.
  
  @return A return value from gST->StdErr->OutputString.
**/
EFI_STATUS
EFIAPI
FileInterfaceStdErrWrite(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  return (gST->StdErr->OutputString(gST->StdErr, Buffer));
}

/**
  File style interface for console StdOut (Read).
  
  @param[in] This              Ignored.
  @param[in, out] BufferSize   Ignored.
  @param[out] Buffer           Ignored.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
FileInterfaceStdOutRead(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  OUT VOID *Buffer
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for console StdErr (Read).
  
  @param[in] This              Ignored.
  @param[in, out] BufferSize   Ignored.
  @param[out] Buffer           Ignored.
  
  @retval EFI_UNSUPPORTED Always.
**/
EFI_STATUS
EFIAPI
FileInterfaceStdErrRead(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  OUT VOID *Buffer
  )
{
  return (EFI_UNSUPPORTED);
}

/**
  File style interface for NUL file (Read).
  
  @param[in] This              Ignored.
  @param[in, out] BufferSize   Poiner to 0 upon return.
  @param[out] Buffer           Ignored.
  
  @retval EFI_SUCCESS Always.
**/
EFI_STATUS
EFIAPI
FileInterfaceNulRead(
  IN      EFI_FILE_PROTOCOL *This,
  IN OUT  UINTN             *BufferSize,
  OUT     VOID              *Buffer
  )
{
  *BufferSize = 0;
  return (EFI_SUCCESS);
}

/**
  File style interface for NUL file (Write).
  
  @param[in] This              Ignored.
  @param[in, out] BufferSize   Ignored.
  @param[in] Buffer            Ignored.
  
  @retval EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
FileInterfaceNulWrite(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  return (EFI_SUCCESS);
}

/**
  Create the TAB completion list.

  @param[in]  InputString       The command line to expand.
  @param[in]  StringLen         Length of the command line.
  @param[in]  BufferSize        Buffer size.
  @param[in, out] TabCompletionList Return the TAB completion list.
  @param[in, out] TabUpdatePos      Return the TAB update position.
**/
EFI_STATUS
CreateTabCompletionList (
  IN CONST CHAR16             *InputString,
  IN CONST UINTN              StringLen, 
  IN CONST UINTN              BufferSize,
  IN OUT EFI_SHELL_FILE_INFO  **TabCompletionList,
  IN OUT   UINTN              *TabUpdatePos
)
{
  BOOLEAN             InQuotation;
  UINTN               TabPos;
  UINTN               Index;
  CONST CHAR16        *Cwd;
  EFI_STATUS          Status;
  CHAR16              *TabStr;
  EFI_SHELL_FILE_INFO *FileList;
  EFI_SHELL_FILE_INFO *FileInfo;
  EFI_SHELL_FILE_INFO *TempFileInfo;

  //
  // Allocate buffers
  //
  TabStr = AllocateZeroPool (BufferSize);
  if (TabStr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // handle auto complete of file and directory names...
  // E.g.: cd fs0:\EFI\Bo<TAB>
  //          ^        ^
  //          TabPos   TabUpdatePos
  //
  TabPos        = 0;
  *TabUpdatePos = 0;
  FileList      = NULL;
  InQuotation   = FALSE;
  for (Index = 0; Index < StringLen; Index++) {
    switch (InputString[Index]) {
    case L'\"':
      InQuotation = (BOOLEAN) (!InQuotation);
      break;

    case L' ':
      if (!InQuotation) {
        TabPos = Index + 1;
        *TabUpdatePos = TabPos;
      }
      break;

    case L':':
      //
      // handle the case "fs0:<TAB>"
      // Update the TabUpdatePos as well.
      //
    case L'\\':
      *TabUpdatePos = Index + 1;
      break;

    default:
      break;
    }
  }

  if (StrStr (InputString + TabPos, L":") == NULL) {
    //
    // If file path doesn't contain ":", ...
    //
    Cwd = ShellInfoObject.NewEfiShellProtocol->GetCurDir (NULL);
    if (Cwd != NULL) {
      if (InputString[TabPos] != L'\\') {
        //
        // and it doesn't begin with "\\", it's a path relative to current directory.
        // TabStr = "<cwd>\\"
        //
        StrnCpyS (TabStr, BufferSize / sizeof (CHAR16), Cwd, (BufferSize) / sizeof (CHAR16) - 1);
        StrCatS (TabStr, (BufferSize) / sizeof (CHAR16), L"\\");
      } else {
        //
        // and it begins with "\\", it's a path pointing to root directory of current map.
        // TabStr = "fsx:"
        //
        Index = StrStr (Cwd, L":") - Cwd + 1;
        StrnCpyS (TabStr, BufferSize / sizeof (CHAR16), Cwd, Index);
      }
    }
  }
  StrnCatS (TabStr, (BufferSize) / sizeof (CHAR16), InputString + TabPos, StringLen - TabPos);
  StrnCatS (TabStr, (BufferSize) / sizeof (CHAR16), L"*", (BufferSize) / sizeof (CHAR16) - 1 - StrLen (TabStr));
  Status  = ShellInfoObject.NewEfiShellProtocol->FindFiles(TabStr, &FileList);

  //
  // Filter out the non-directory for "CD" command
  // Filter "." and ".." for all
  //
  if (!EFI_ERROR (Status) && FileList != NULL) {
    //
    // Skip the spaces in the beginning
    //
    while (*InputString == L' ') {
      InputString++;
    }

    for (FileInfo = (EFI_SHELL_FILE_INFO *) GetFirstNode (&FileList->Link); !IsNull (&FileList->Link, &FileInfo->Link); ) {
      if (((StrCmp (FileInfo->FileName, L".") == 0) || (StrCmp (FileInfo->FileName, L"..") == 0)) ||
          (((InputString[0] == L'c' || InputString[0] == L'C') && (InputString[1] == L'd' || InputString[1] == L'D')) &&
           (ShellIsDirectory (FileInfo->FullName) != EFI_SUCCESS))) {
        TempFileInfo = FileInfo;
        FileInfo = (EFI_SHELL_FILE_INFO *) RemoveEntryList (&FileInfo->Link);
        InternalFreeShellFileInfoNode (TempFileInfo);
      } else {
        FileInfo = (EFI_SHELL_FILE_INFO *) GetNextNode (&FileList->Link, &FileInfo->Link);
      }
    }
  }

  if (FileList != NULL && !IsListEmpty (&FileList->Link)) {
    Status = EFI_SUCCESS;
  } else {
    ShellInfoObject.NewEfiShellProtocol->FreeFileList (&FileList);
    Status = EFI_NOT_FOUND;
  }

  FreePool (TabStr);

  *TabCompletionList = FileList;
  return Status;
}

/**
  File style interface for console (Read).

  This will return a single line of input from the console.

  @param This           A pointer to the EFI_FILE_PROTOCOL instance that is the
                        file handle to read data from. Not used.
  @param BufferSize     On input, the size of the Buffer. On output, the amount
                        of data returned in Buffer. In both cases, the size is
                        measured in bytes.
  @param Buffer         The buffer into which the data is read.


  @retval EFI_SUCCESS           The data was read.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_DEVICE_ERROR      An attempt was made to read from a deleted file.
  @retval EFI_DEVICE_ERROR      On entry, the current file position is beyond the end of the file.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current directory
                                entry. BufferSize has been updated with the size
                                needed to complete the request.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
EFIAPI
FileInterfaceStdInRead(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  OUT VOID *Buffer
  )
{
  CHAR16              *CurrentString;
  BOOLEAN             Done;
  UINTN               TabUpdatePos;   // Start index of the string updated by TAB stroke
  UINTN               Column;         // Column of current cursor
  UINTN               Row;            // Row of current cursor
  UINTN               StartColumn;    // Column at the beginning of the line
  UINTN               Update;         // Line index for update
  UINTN               Delete;         // Num of chars to delete from console after update
  UINTN               StringLen;      // Total length of the line
  UINTN               StringCurPos;   // Line index corresponding to the cursor
  UINTN               MaxStr;         // Maximum possible line length
  UINTN               TotalColumn;     // Num of columns in the console
  UINTN               TotalRow;       // Num of rows in the console
  UINTN               SkipLength;
  UINTN               OutputLength;   // Length of the update string
  UINTN               TailRow;        // Row of end of line
  UINTN               TailColumn;     // Column of end of line
  EFI_INPUT_KEY       Key;

  BUFFER_LIST         *LinePos;
  BUFFER_LIST         *NewPos;
  BOOLEAN             InScrolling;
  EFI_STATUS          Status;
  BOOLEAN             InTabScrolling; // Whether in TAB-completion state
  EFI_SHELL_FILE_INFO *TabCompleteList;
  EFI_SHELL_FILE_INFO *TabCurrent;
  UINTN               EventIndex;
  CHAR16              *TabOutputStr;

  //
  // If buffer is not large enough to hold a CHAR16, return minimum buffer size
  //
  if (*BufferSize < sizeof (CHAR16) * 2) {
    *BufferSize = sizeof (CHAR16) * 2;
    return (EFI_BUFFER_TOO_SMALL);
  }

  Done              = FALSE;
  CurrentString     = Buffer;
  StringLen         = 0;
  StringCurPos      = 0;
  OutputLength      = 0;
  Update            = 0;
  Delete            = 0;
  LinePos           = NewPos = (BUFFER_LIST*)(&ShellInfoObject.ViewingSettings.CommandHistory);
  InScrolling       = FALSE;
  InTabScrolling    = FALSE;
  Status            = EFI_SUCCESS;
  TabOutputStr      = NULL;
  TabUpdatePos      = 0;
  TabCompleteList   = NULL;
  TabCurrent        = NULL;

  //
  // Get the screen setting and the current cursor location
  //
  Column      = StartColumn = gST->ConOut->Mode->CursorColumn;
  Row         = gST->ConOut->Mode->CursorRow;
  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &TotalColumn, &TotalRow);

  //
  // Limit the line length to the buffer size or the minimun size of the
  // screen. (The smaller takes effect)
  //
  MaxStr = TotalColumn * (TotalRow - 1) - StartColumn;
  if (MaxStr > *BufferSize / sizeof (CHAR16)) {
    MaxStr = *BufferSize / sizeof (CHAR16);
  }
  ZeroMem (CurrentString, MaxStr * sizeof (CHAR16));
  do {
    //
    // Read a key
    //
    gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    if (EFI_ERROR (Status)) {

      if (Status == EFI_NOT_READY)
        continue;

      ZeroMem (CurrentString, MaxStr * sizeof(CHAR16));
      StringLen = 0;
      break;
    }

    //
    // Press PageUp or PageDown to scroll the history screen up or down.
    // Press any other key to quit scrolling.
    //
    if (Key.UnicodeChar == 0 && (Key.ScanCode == SCAN_PAGE_UP || Key.ScanCode == SCAN_PAGE_DOWN)) {
      if (Key.ScanCode == SCAN_PAGE_UP) {
        ConsoleLoggerDisplayHistory(FALSE, 0, ShellInfoObject.ConsoleInfo);
      } else if (Key.ScanCode == SCAN_PAGE_DOWN) {
        ConsoleLoggerDisplayHistory(TRUE, 0, ShellInfoObject.ConsoleInfo);
      }

      InScrolling = TRUE;
    } else {
      if (InScrolling) {
        ConsoleLoggerStopHistory(ShellInfoObject.ConsoleInfo);
        InScrolling = FALSE;
      }
    }

    //
    // If we are quitting TAB scrolling...
    //
    if (InTabScrolling && Key.UnicodeChar != CHAR_TAB) {
      if (TabCompleteList != NULL) {
        ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteList);
        DEBUG_CODE(TabCompleteList = NULL;);
      }
      InTabScrolling = FALSE;
    }

    switch (Key.UnicodeChar) {
    case CHAR_CARRIAGE_RETURN:
      //
      // All done, print a newline at the end of the string
      //
      TailRow     = Row + (StringLen - StringCurPos + Column) / TotalColumn;
      TailColumn  = (StringLen - StringCurPos + Column) % TotalColumn;
      ShellPrintEx ((INT32)TailColumn, (INT32)TailRow, L"%N\n");
      Done = TRUE;
      break;

    case CHAR_BACKSPACE:
      if (StringCurPos != 0) {
        //
        // If not move back beyond string beginning, move all characters behind
        // the current position one character forward
        //
        StringCurPos--;
        Update  = StringCurPos;
        Delete  = 1;
        CopyMem (CurrentString + StringCurPos, CurrentString + StringCurPos + 1, sizeof (CHAR16) * (StringLen - StringCurPos));

        //
        // Adjust the current column and row
        //
        MoveCursorBackward (TotalColumn, &Column, &Row);
      }
      break;

    case CHAR_TAB:
      if (!InTabScrolling) {
        TabCurrent = NULL;
        //
        // Initialize a tab complete operation.
        //
        Status = CreateTabCompletionList (CurrentString, StringLen, *BufferSize, &TabCompleteList, &TabUpdatePos);
        if (!EFI_ERROR(Status)) {
          InTabScrolling = TRUE;
        }

        //
        // We do not set up the replacement.
        // The next section will do that.
        //
      }

      if (InTabScrolling) {
        //
        // We are in a tab complete operation.
        // set up the next replacement.
        //
        ASSERT(TabCompleteList != NULL);
        if (TabCurrent == NULL) {
          TabCurrent = (EFI_SHELL_FILE_INFO*) GetFirstNode (&TabCompleteList->Link);
        } else {
          TabCurrent = (EFI_SHELL_FILE_INFO*) GetNextNode (&TabCompleteList->Link, &TabCurrent->Link);
        }

        //
        // Skip over the empty list beginning node
        //
        if (IsNull(&TabCompleteList->Link, &TabCurrent->Link)) {
          TabCurrent = (EFI_SHELL_FILE_INFO*) GetNextNode (&TabCompleteList->Link, &TabCurrent->Link);
        }
      }
      break;

    default:
      if (Key.UnicodeChar >= ' ') {
        //
        // If we are at the buffer's end, drop the key
        //
        if (StringLen == MaxStr - 1 && (ShellInfoObject.ViewingSettings.InsertMode || StringCurPos == StringLen)) {
          break;
        }
        //
        // If in insert mode, make space by moving each other character 1
        // space higher in the array
        //
        if (ShellInfoObject.ViewingSettings.InsertMode) {
          CopyMem(CurrentString + StringCurPos + 1, CurrentString + StringCurPos, (StringLen - StringCurPos)*sizeof(CurrentString[0]));
        }

        CurrentString[StringCurPos] = Key.UnicodeChar;
        Update      = StringCurPos;

        StringCurPos += 1;
        OutputLength = 1;
      }
      break;

    case 0:
      switch (Key.ScanCode) {
      case SCAN_DELETE:
        //
        // Move characters behind current position one character forward
        //
        if (StringLen != 0) {
          Update  = StringCurPos;
          Delete  = 1;
          CopyMem (CurrentString + StringCurPos, CurrentString + StringCurPos + 1, sizeof (CHAR16) * (StringLen - StringCurPos));
        }
        break;

      case SCAN_UP:
        //
        // Prepare to print the previous command
        //
        NewPos = (BUFFER_LIST*)GetPreviousNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &LinePos->Link);
        if (IsNull(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &LinePos->Link)) {
          NewPos = (BUFFER_LIST*)GetPreviousNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &LinePos->Link);
        }
        break;

      case SCAN_DOWN:
        //
        // Prepare to print the next command
        //
        NewPos = (BUFFER_LIST*)GetNextNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &LinePos->Link);
        if (NewPos == (BUFFER_LIST*)(&ShellInfoObject.ViewingSettings.CommandHistory)) {
          NewPos = (BUFFER_LIST*)GetNextNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &LinePos->Link);
        }
        break;

      case SCAN_LEFT:
        //
        // Adjust current cursor position
        //
        if (StringCurPos != 0) {
          --StringCurPos;
          MoveCursorBackward (TotalColumn, &Column, &Row);
        }
        break;

      case SCAN_RIGHT:
        //
        // Adjust current cursor position
        //
        if (StringCurPos < StringLen) {
          ++StringCurPos;
          MoveCursorForward (TotalColumn, TotalRow, &Column, &Row);
        }
        break;

      case SCAN_HOME:
        //
        // Move current cursor position to the beginning of the command line
        //
        Row -= (StringCurPos + StartColumn) / TotalColumn;
        Column  = StartColumn;
        StringCurPos  = 0;
        break;

      case SCAN_END:
        //
        // Move current cursor position to the end of the command line
        //
        TailRow       = Row + (StringLen - StringCurPos + Column) / TotalColumn;
        TailColumn    = (StringLen - StringCurPos + Column) % TotalColumn;
        Row           = TailRow;
        Column        = TailColumn;
        StringCurPos  = StringLen;
        break;

      case SCAN_ESC:
        //
        // Prepare to clear the current command line
        //
        CurrentString[0]  = 0;
        Update  = 0;
        Delete  = StringLen;
        Row -= (StringCurPos + StartColumn) / TotalColumn;
        Column        = StartColumn;
        OutputLength  = 0;
        break;

      case SCAN_INSERT:
        //
        // Toggle the SEnvInsertMode flag
        //
        ShellInfoObject.ViewingSettings.InsertMode = (BOOLEAN)!ShellInfoObject.ViewingSettings.InsertMode;
        break;

      case SCAN_F7:
        //
        // Print command history
        //
        PrintCommandHistory (TotalColumn, TotalRow, 4);
        *CurrentString  = CHAR_NULL;
        Done  = TRUE;
        break;
      }
    }

    if (Done) {
      break;
    }

    //
    // If we are in auto-complete mode, we are preparing to print
    // the next file or directory name
    //
    if (InTabScrolling) {
      TabOutputStr = AllocateZeroPool (*BufferSize);
      if (TabOutputStr == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
      }
    }

    if (InTabScrolling && TabOutputStr != NULL) {

      //
      // Adjust the column and row to the start of TAB-completion string.
      //
      Column = (StartColumn + TabUpdatePos) % TotalColumn;
      Row -= (StartColumn + StringCurPos) / TotalColumn - (StartColumn + TabUpdatePos) / TotalColumn;
      OutputLength = StrLen (TabCurrent->FileName);
      //
      // if the output string contains  blank space, quotation marks L'\"'
      // should be added to the output.
      //
      if (StrStr(TabCurrent->FileName, L" ") != NULL){
        TabOutputStr[0] = L'\"';
        CopyMem (TabOutputStr + 1, TabCurrent->FileName, OutputLength * sizeof (CHAR16));
        TabOutputStr[OutputLength + 1] = L'\"';
        TabOutputStr[OutputLength + 2] = CHAR_NULL;
      } else {
        CopyMem (TabOutputStr, TabCurrent->FileName, OutputLength * sizeof (CHAR16));
        TabOutputStr[OutputLength] = CHAR_NULL;
      }
      OutputLength = StrLen (TabOutputStr) < MaxStr - 1 ? StrLen (TabOutputStr) : MaxStr - 1;
      CopyMem (CurrentString + TabUpdatePos, TabOutputStr, OutputLength * sizeof (CHAR16));
      CurrentString[TabUpdatePos + OutputLength] = CHAR_NULL;
      StringCurPos = TabUpdatePos + OutputLength;
      Update = TabUpdatePos;
      if (StringLen > TabUpdatePos + OutputLength) {
        Delete = StringLen - TabUpdatePos - OutputLength;
      }

      FreePool(TabOutputStr);
    }

    //
    // If we have a new position, we are preparing to print a previous or
    // next command.
    //
    if (NewPos != (BUFFER_LIST*)(&ShellInfoObject.ViewingSettings.CommandHistory)) {
      Column = StartColumn;
      Row -= (StringCurPos + StartColumn) / TotalColumn;

      LinePos       = NewPos;
      NewPos        = (BUFFER_LIST*)(&ShellInfoObject.ViewingSettings.CommandHistory);

      OutputLength  = StrLen (LinePos->Buffer) < MaxStr - 1 ? StrLen (LinePos->Buffer) : MaxStr - 1;
      CopyMem (CurrentString, LinePos->Buffer, OutputLength * sizeof (CHAR16));
      CurrentString[OutputLength] = CHAR_NULL;

      StringCurPos            = OutputLength;

      //
      // Draw new input string
      //
      Update = 0;
      if (StringLen > OutputLength) {
        //
        // If old string was longer, blank its tail
        //
        Delete = StringLen - OutputLength;
      }
    }
    //
    // If we need to update the output do so now
    //
    if (Update != (UINTN) -1) {
      ShellPrintEx ((INT32)Column, (INT32)Row, L"%s%.*s", CurrentString + Update, Delete, L"");
      StringLen = StrLen (CurrentString);

      if (Delete != 0) {
        SetMem (CurrentString + StringLen, Delete * sizeof (CHAR16), CHAR_NULL);
      }

      if (StringCurPos > StringLen) {
        StringCurPos = StringLen;
      }

      Update = (UINTN) -1;

      //
      // After using print to reflect newly updates, if we're not using
      // BACKSPACE and DELETE, we need to move the cursor position forward,
      // so adjust row and column here.
      //
      if (Key.UnicodeChar != CHAR_BACKSPACE && !(Key.UnicodeChar == 0 && Key.ScanCode == SCAN_DELETE)) {
        //
        // Calulate row and column of the tail of current string
        //
        TailRow     = Row + (StringLen - StringCurPos + Column + OutputLength) / TotalColumn;
        TailColumn  = (StringLen - StringCurPos + Column + OutputLength) % TotalColumn;

        //
        // If the tail of string reaches screen end, screen rolls up, so if
        // Row does not equal TailRow, Row should be decremented
        //
        // (if we are recalling commands using UPPER and DOWN key, and if the
        // old command is too long to fit the screen, TailColumn must be 79.
        //
        if (TailColumn == 0 && TailRow >= TotalRow && Row != TailRow) {
          Row--;
        }
        //
        // Calculate the cursor position after current operation. If cursor
        // reaches line end, update both row and column, otherwise, only
        // column will be changed.
        //
        if (Column + OutputLength >= TotalColumn) {
          SkipLength = OutputLength - (TotalColumn - Column);

          Row += SkipLength / TotalColumn + 1;
          if (Row > TotalRow - 1) {
            Row = TotalRow - 1;
          }

          Column = SkipLength % TotalColumn;
        } else {
          Column += OutputLength;
        }
      }

      Delete = 0;
    }
    //
    // Set the cursor position for this key
    //
    gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row);
  } while (!Done);

  if (CurrentString != NULL && StrLen(CurrentString) > 0) {
    //
    // add the line to the history buffer
    //
    AddLineToCommandHistory(CurrentString);
  }

  //
  // Return the data to the caller
  //
  *BufferSize = StringLen * sizeof (CHAR16);

  //
  // if this was used it should be deallocated by now...
  // prevent memory leaks...
  //
  if (TabCompleteList != NULL) {
    ShellInfoObject.NewEfiShellProtocol->FreeFileList (&TabCompleteList);
  }
  ASSERT(TabCompleteList == NULL);

  return Status;
}

//
// FILE sytle interfaces for StdIn/StdOut/StdErr
//
EFI_FILE_PROTOCOL FileInterfaceStdIn = {
  EFI_FILE_REVISION,
  FileInterfaceOpenNotFound,
  FileInterfaceNopGeneric,
  FileInterfaceNopGeneric,
  FileInterfaceStdInRead,
  FileInterfaceStdInWrite,
  FileInterfaceNopGetPosition,
  FileInterfaceNopSetPosition,
  FileInterfaceNopGetInfo,
  FileInterfaceNopSetInfo,
  FileInterfaceNopGeneric
};

EFI_FILE_PROTOCOL FileInterfaceStdOut = {
  EFI_FILE_REVISION,
  FileInterfaceOpenNotFound,
  FileInterfaceNopGeneric,
  FileInterfaceNopGeneric,
  FileInterfaceStdOutRead,
  FileInterfaceStdOutWrite,
  FileInterfaceNopGetPosition,
  FileInterfaceNopSetPosition,
  FileInterfaceNopGetInfo,
  FileInterfaceNopSetInfo,
  FileInterfaceNopGeneric
};

EFI_FILE_PROTOCOL FileInterfaceStdErr = {
  EFI_FILE_REVISION,
  FileInterfaceOpenNotFound,
  FileInterfaceNopGeneric,
  FileInterfaceNopGeneric,
  FileInterfaceStdErrRead,
  FileInterfaceStdErrWrite,
  FileInterfaceNopGetPosition,
  FileInterfaceNopSetPosition,
  FileInterfaceNopGetInfo,
  FileInterfaceNopSetInfo,
  FileInterfaceNopGeneric
};

EFI_FILE_PROTOCOL FileInterfaceNulFile = {
  EFI_FILE_REVISION,
  FileInterfaceOpenNotFound,
  FileInterfaceNopGeneric,
  FileInterfaceNopGeneric,
  FileInterfaceNulRead,
  FileInterfaceNulWrite,
  FileInterfaceNopGetPosition,
  FileInterfaceNopSetPosition,
  FileInterfaceNopGetInfo,
  FileInterfaceNopSetInfo,
  FileInterfaceNopGeneric
};




//
// This is identical to EFI_FILE_PROTOCOL except for the additional member
// for the name.
//

typedef struct {
  UINT64                Revision;
  EFI_FILE_OPEN         Open;
  EFI_FILE_CLOSE        Close;
  EFI_FILE_DELETE       Delete;
  EFI_FILE_READ         Read;
  EFI_FILE_WRITE        Write;
  EFI_FILE_GET_POSITION GetPosition;
  EFI_FILE_SET_POSITION SetPosition;
  EFI_FILE_GET_INFO     GetInfo;
  EFI_FILE_SET_INFO     SetInfo;
  EFI_FILE_FLUSH        Flush;
  CHAR16                Name[1];
} EFI_FILE_PROTOCOL_ENVIRONMENT;
//ANSI compliance helper to get size of the struct.
#define SIZE_OF_EFI_FILE_PROTOCOL_ENVIRONMENT EFI_FIELD_OFFSET (EFI_FILE_PROTOCOL_ENVIRONMENT, Name)

/**
  File style interface for Environment Variable (Close).

  Frees the memory for this object.
  
  @param[in] This       The pointer to the EFI_FILE_PROTOCOL object.
  
  @retval EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
FileInterfaceEnvClose(
  IN EFI_FILE_PROTOCOL *This
  )
{
  VOID*       NewBuffer;
  UINTN       NewSize;
  EFI_STATUS  Status;
  BOOLEAN     Volatile;
  UINTN       TotalSize;

  //
  // Most if not all UEFI commands will have an '\r\n' at the end of any output. 
  // Since the output was redirected to a variable, it does not make sense to 
  // keep this.  So, before closing, strip the trailing '\r\n' from the variable
  // if it exists.
  //
  NewBuffer   = NULL;
  NewSize     = 0;
  TotalSize   = 0;

  Status = IsVolatileEnv (((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &Volatile);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    TotalSize = NewSize + sizeof (CHAR16);
    NewBuffer = AllocateZeroPool (TotalSize);
    if (NewBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }  
    Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
  }
  
  if (!EFI_ERROR(Status) && NewBuffer != NULL) {
    
    if (TotalSize / sizeof (CHAR16) >= 3) {
      if ( (((CHAR16*)NewBuffer)[TotalSize / sizeof (CHAR16) - 2] == CHAR_LINEFEED) &&
           (((CHAR16*)NewBuffer)[TotalSize / sizeof (CHAR16) - 3] == CHAR_CARRIAGE_RETURN)
         ) {
        ((CHAR16*)NewBuffer)[TotalSize / sizeof (CHAR16) - 3] = CHAR_NULL;
        //
        // If the NewBuffer end with \r\n\0, We will repace '\r' by '\0' and then update TotalSize.
        //
        TotalSize -= sizeof(CHAR16) * 2;
      }

      if (Volatile) {
        Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (
                   ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
                   TotalSize - sizeof (CHAR16),
                   NewBuffer
                   );

        if (!EFI_ERROR(Status)) {
          Status = ShellAddEnvVarToList (
                     ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
                     NewBuffer,
                     TotalSize,
                     EFI_VARIABLE_BOOTSERVICE_ACCESS
                     );
        }
      } else {
        Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (
                   ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
                   TotalSize - sizeof (CHAR16),
                   NewBuffer
                   );

        if (!EFI_ERROR(Status)) {
          Status = ShellAddEnvVarToList (
                     ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
                     NewBuffer,
                     TotalSize,
                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS
                     );
        }
      }
    }
  } 
  
  SHELL_FREE_NON_NULL(NewBuffer);
  FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT*)This);
  return (Status);
}

/**
  File style interface for Environment Variable (Delete).
  
  @param[in] This       The pointer to the EFI_FILE_PROTOCOL object.
  
  @retval The return value from FileInterfaceEnvClose().
**/
EFI_STATUS
EFIAPI
FileInterfaceEnvDelete(
  IN EFI_FILE_PROTOCOL *This
  )
{
  SHELL_DELETE_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name);
  return (FileInterfaceEnvClose(This));
}

/**
  File style interface for Environment Variable (Read).
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[out] Buffer           The pointer to the buffer to fill.
  
  @retval EFI_SUCCESS   The data was read.
**/
EFI_STATUS
EFIAPI
FileInterfaceEnvRead(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  OUT VOID *Buffer
  )
{
  return (SHELL_GET_ENVIRONMENT_VARIABLE(
    ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
    BufferSize,
    Buffer));
}

/**
  File style interface for Volatile Environment Variable (Write).
  This function also caches the environment variable into gShellEnvVarList.
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to write.
  
  @retval EFI_SUCCESS             The data was successfully write to variable.
  @retval SHELL_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
EFIAPI
FileInterfaceEnvVolWrite(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  VOID*       NewBuffer;
  UINTN       NewSize;
  EFI_STATUS  Status;
  UINTN       TotalSize;

  NewBuffer   = NULL;
  NewSize     = 0;
  TotalSize   = 0;

  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    TotalSize = NewSize + *BufferSize + sizeof (CHAR16);
  } else if (Status == EFI_NOT_FOUND) {
    TotalSize = *BufferSize + sizeof(CHAR16);
  } else {
    return Status;
  }

  NewBuffer = AllocateZeroPool (TotalSize);
  if (NewBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Status == EFI_BUFFER_TOO_SMALL) {
    Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
  }

  if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
    FreePool (NewBuffer);
    return Status;
  }

  CopyMem ((UINT8*)NewBuffer + NewSize, Buffer, *BufferSize);
  Status = ShellAddEnvVarToList (
             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
             NewBuffer,
             TotalSize,
             EFI_VARIABLE_BOOTSERVICE_ACCESS
             );
  if (EFI_ERROR(Status)) {
    FreePool (NewBuffer);
    return Status;
  }

  Status = SHELL_SET_ENVIRONMENT_VARIABLE_V (
             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
             TotalSize - sizeof (CHAR16),
             NewBuffer
             );
  if (EFI_ERROR(Status)) {
    ShellRemvoeEnvVarFromList (((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name);
  }

  FreePool (NewBuffer);
  return Status;
}


/**
  File style interface for Non Volatile Environment Variable (Write).
  This function also caches the environment variable into gShellEnvVarList.
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to write.
  
  @retval EFI_SUCCESS             The data was successfully write to variable.
  @retval SHELL_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
EFIAPI
FileInterfaceEnvNonVolWrite(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  VOID*       NewBuffer;
  UINTN       NewSize;
  EFI_STATUS  Status;
  UINTN       TotalSize;

  NewBuffer   = NULL;
  NewSize     = 0;
  TotalSize   = 0;

  Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    TotalSize = NewSize + *BufferSize + sizeof (CHAR16);
  } else if (Status == EFI_NOT_FOUND) {
    TotalSize = *BufferSize + sizeof (CHAR16);
  } else {
    return Status;
  }

  NewBuffer = AllocateZeroPool (TotalSize);
  if (NewBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Status == EFI_BUFFER_TOO_SMALL) {
    Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
  }

  if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
    FreePool (NewBuffer);
    return Status;
  }

  CopyMem ((UINT8*) NewBuffer + NewSize, Buffer, *BufferSize);
  Status = ShellAddEnvVarToList (
             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
             NewBuffer,
             TotalSize,
             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS
             );
  if (EFI_ERROR (Status)) {
    FreePool (NewBuffer);
    return Status;
  }

  Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV (
             ((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name,
             TotalSize - sizeof (CHAR16),
             NewBuffer
             );
  if (EFI_ERROR (Status)) {
    ShellRemvoeEnvVarFromList (((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name);
  }

  FreePool (NewBuffer);
  return Status;
}

/**
  Creates a EFI_FILE_PROTOCOL (almost) object for using to access
  environment variables through file operations.

  @param EnvName    The name of the Environment Variable to be operated on.

  @retval NULL      Memory could not be allocated.
  @return other     a pointer to an EFI_FILE_PROTOCOL structure
**/
EFI_FILE_PROTOCOL*
CreateFileInterfaceEnv(
  IN CONST CHAR16 *EnvName
  )
{
  EFI_STATUS                     Status;
  EFI_FILE_PROTOCOL_ENVIRONMENT  *EnvFileInterface;
  UINTN                          EnvNameSize;
  BOOLEAN                        Volatile;

  if (EnvName == NULL) {
    return (NULL);
  }

  Status = IsVolatileEnv (EnvName, &Volatile);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Get some memory
  //
  EnvNameSize = StrSize(EnvName);
  EnvFileInterface = AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_ENVIRONMENT)+EnvNameSize);
  if (EnvFileInterface == NULL){
    return (NULL);
  }

  //
  // Assign the generic members
  //
  EnvFileInterface->Revision    = EFI_FILE_REVISION;
  EnvFileInterface->Open        = FileInterfaceOpenNotFound;
  EnvFileInterface->Close       = FileInterfaceEnvClose;
  EnvFileInterface->GetPosition = FileInterfaceNopGetPosition;
  EnvFileInterface->SetPosition = FileInterfaceNopSetPosition;
  EnvFileInterface->GetInfo     = FileInterfaceNopGetInfo;
  EnvFileInterface->SetInfo     = FileInterfaceNopSetInfo;
  EnvFileInterface->Flush       = FileInterfaceNopGeneric;
  EnvFileInterface->Delete      = FileInterfaceEnvDelete;
  EnvFileInterface->Read        = FileInterfaceEnvRead;
  
  CopyMem(EnvFileInterface->Name, EnvName, EnvNameSize);

  //
  // Assign the different members for Volatile and Non-Volatile variables
  //
  if (Volatile) {
    EnvFileInterface->Write       = FileInterfaceEnvVolWrite;
  } else {
    EnvFileInterface->Write       = FileInterfaceEnvNonVolWrite;
  }
  return ((EFI_FILE_PROTOCOL *)EnvFileInterface);
}

/**
  Move the cursor position one character backward.

  @param[in] LineLength       Length of a line. Get it by calling QueryMode
  @param[in, out] Column      Current column of the cursor position
  @param[in, out] Row         Current row of the cursor position
**/
VOID
MoveCursorBackward (
  IN     UINTN                   LineLength,
  IN OUT UINTN                   *Column,
  IN OUT UINTN                   *Row
  )
{
  //
  // If current column is 0, move to the last column of the previous line,
  // otherwise, just decrement column.
  //
  if (*Column == 0) {
    *Column = LineLength - 1;
    if (*Row > 0) {
      (*Row)--;
    }
    return;
  }
  (*Column)--;
}

/**
  Move the cursor position one character forward.

  @param[in] LineLength       Length of a line.
  @param[in] TotalRow         Total row of a screen
  @param[in, out] Column      Current column of the cursor position
  @param[in, out] Row         Current row of the cursor position
**/
VOID
MoveCursorForward (
  IN     UINTN                   LineLength,
  IN     UINTN                   TotalRow,
  IN OUT UINTN                   *Column,
  IN OUT UINTN                   *Row
  )
{
  //
  // Increment Column.
  // If this puts column past the end of the line, move to first column
  // of the next row.
  //
  (*Column)++;
  if (*Column >= LineLength) {
    (*Column) = 0;
    if ((*Row) < TotalRow - 1) {
      (*Row)++;
    }
  }
}

/**
  Prints out each previously typed command in the command list history log.

  When each screen is full it will pause for a key before continuing.

  @param[in] TotalCols    How many columns are on the screen
  @param[in] TotalRows    How many rows are on the screen
  @param[in] StartColumn  which column to start at
**/
VOID
PrintCommandHistory (
  IN CONST UINTN TotalCols,
  IN CONST UINTN TotalRows,
  IN CONST UINTN StartColumn
  )
{
  BUFFER_LIST     *Node;
  UINTN           Index;
  UINTN           LineNumber;
  UINTN           LineCount;

  ShellPrintEx (-1, -1, L"\n");
  Index       = 0;
  LineNumber  = 0;
  //
  // go through history list...
  //
  for ( Node = (BUFFER_LIST*)GetFirstNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link)
      ; !IsNull(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link)
      ; Node = (BUFFER_LIST*)GetNextNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link)
   ){
    Index++;
    LineCount = ((StrLen (Node->Buffer) + StartColumn + 1) / TotalCols) + 1;

    if (LineNumber + LineCount >= TotalRows) {
      ShellPromptForResponseHii(
        ShellPromptResponseTypeEnterContinue,
        STRING_TOKEN (STR_SHELL_ENTER_TO_CONT),
        ShellInfoObject.HiiHandle,
        NULL
       );
      LineNumber = 0;
    }
    ShellPrintEx (-1, -1, L"%2d. %s\n", Index, Node->Buffer);
    LineNumber += LineCount;
  }
}






//
// This is identical to EFI_FILE_PROTOCOL except for the additional members
// for the buffer, size, and position.
//

typedef struct {
  UINT64                Revision;
  EFI_FILE_OPEN         Open;
  EFI_FILE_CLOSE        Close;
  EFI_FILE_DELETE       Delete;
  EFI_FILE_READ         Read;
  EFI_FILE_WRITE        Write;
  EFI_FILE_GET_POSITION GetPosition;
  EFI_FILE_SET_POSITION SetPosition;
  EFI_FILE_GET_INFO     GetInfo;
  EFI_FILE_SET_INFO     SetInfo;
  EFI_FILE_FLUSH        Flush;
  VOID                  *Buffer;
  UINT64                Position;
  UINT64                BufferSize;
  BOOLEAN               Unicode;
  UINT64                FileSize;
} EFI_FILE_PROTOCOL_MEM;

/**
  File style interface for Mem (SetPosition).
  
  @param[in] This       The pointer to the EFI_FILE_PROTOCOL object.
  @param[out] Position  The position to set.
  
  @retval EFI_SUCCESS             The position was successfully changed.
  @retval EFI_INVALID_PARAMETER   The Position was invalid.
**/
EFI_STATUS
EFIAPI
FileInterfaceMemSetPosition(
  IN EFI_FILE_PROTOCOL *This,
  OUT UINT64 Position
  )
{
  if (Position <= ((EFI_FILE_PROTOCOL_MEM*)This)->FileSize) {
    ((EFI_FILE_PROTOCOL_MEM*)This)->Position = Position;
    return (EFI_SUCCESS);
  } else {
    return (EFI_INVALID_PARAMETER);
  }
}

/**
  File style interface for Mem (GetPosition).
  
  @param[in] This       The pointer to the EFI_FILE_PROTOCOL object.
  @param[out] Position  The pointer to the position.
  
  @retval EFI_SUCCESS   The position was retrieved.
**/ 
EFI_STATUS
EFIAPI
FileInterfaceMemGetPosition(
  IN EFI_FILE_PROTOCOL *This,
  OUT UINT64 *Position
  )
{
  *Position = ((EFI_FILE_PROTOCOL_MEM*)This)->Position;
  return (EFI_SUCCESS);
}

/**
  File style interface for Mem (Write).
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to write.
  
  @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
  @retval EFI_SUCCESS          The data was written.
**/
EFI_STATUS
EFIAPI
FileInterfaceMemWrite(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  CHAR8                  *AsciiBuffer;
  EFI_FILE_PROTOCOL_MEM  *MemFile;

  MemFile = (EFI_FILE_PROTOCOL_MEM *) This;
  if (MemFile->Unicode) {
    //
    // Unicode
    //
    if ((UINTN)(MemFile->Position + (*BufferSize)) > (UINTN)(MemFile->BufferSize)) {
      MemFile->Buffer = ReallocatePool((UINTN)(MemFile->BufferSize), (UINTN)(MemFile->BufferSize) + (*BufferSize) + MEM_WRITE_REALLOC_OVERHEAD, MemFile->Buffer);
      MemFile->BufferSize += (*BufferSize) + MEM_WRITE_REALLOC_OVERHEAD;
    }
    CopyMem(((UINT8*)MemFile->Buffer) + MemFile->Position, Buffer, *BufferSize);
    MemFile->Position += (*BufferSize);
    MemFile->FileSize = MemFile->Position;
    return (EFI_SUCCESS);
  } else {
    //
    // Ascii
    //
    AsciiBuffer = AllocateZeroPool(*BufferSize);
    if (AsciiBuffer == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }
    AsciiSPrint(AsciiBuffer, *BufferSize, "%S", Buffer);
    if ((UINTN)(MemFile->Position + AsciiStrSize(AsciiBuffer)) > (UINTN)(MemFile->BufferSize)) {
      MemFile->Buffer = ReallocatePool((UINTN)(MemFile->BufferSize), (UINTN)(MemFile->BufferSize) + AsciiStrSize(AsciiBuffer) + MEM_WRITE_REALLOC_OVERHEAD, MemFile->Buffer);
      MemFile->BufferSize += AsciiStrSize(AsciiBuffer) + MEM_WRITE_REALLOC_OVERHEAD;
    }
    CopyMem(((UINT8*)MemFile->Buffer) + MemFile->Position, AsciiBuffer, AsciiStrSize(AsciiBuffer));
    MemFile->Position += (*BufferSize / sizeof(CHAR16));
    MemFile->FileSize = MemFile->Position;
    FreePool(AsciiBuffer);
    return (EFI_SUCCESS);
  }
}

/**
  File style interface for Mem (Read).
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to fill.
  
  @retval EFI_SUCCESS   The data was read.
**/
EFI_STATUS
EFIAPI
FileInterfaceMemRead(
  IN EFI_FILE_PROTOCOL *This,
  IN OUT UINTN *BufferSize,
  IN VOID *Buffer
  )
{
  EFI_FILE_PROTOCOL_MEM  *MemFile;

  MemFile = (EFI_FILE_PROTOCOL_MEM *) This;
  if (*BufferSize > (UINTN)((MemFile->FileSize) - (UINTN)(MemFile->Position))) {
    (*BufferSize) = (UINTN)((MemFile->FileSize) - (UINTN)(MemFile->Position));
  }
  CopyMem(Buffer, ((UINT8*)MemFile->Buffer) + MemFile->Position, (*BufferSize));
  MemFile->Position = MemFile->Position + (*BufferSize);
  return (EFI_SUCCESS);
}

/**
  File style interface for Mem (Close).

  Frees all memory associated with this object.
  
  @param[in] This       The pointer to the EFI_FILE_PROTOCOL object.
  
  @retval EFI_SUCCESS   The 'file' was closed.
**/ 
EFI_STATUS
EFIAPI
FileInterfaceMemClose(
  IN EFI_FILE_PROTOCOL *This
  )
{
  SHELL_FREE_NON_NULL(((EFI_FILE_PROTOCOL_MEM*)This)->Buffer);
  SHELL_FREE_NON_NULL(This);
  return (EFI_SUCCESS);
}

/**
  Creates a EFI_FILE_PROTOCOL (almost) object for using to access
  a file entirely in memory through file operations.

  @param[in] Unicode Boolean value with TRUE for Unicode and FALSE for Ascii.

  @retval NULL      Memory could not be allocated.
  @return other     A pointer to an EFI_FILE_PROTOCOL structure.
**/
EFI_FILE_PROTOCOL*
CreateFileInterfaceMem(
  IN CONST BOOLEAN Unicode
  )
{
  EFI_FILE_PROTOCOL_MEM  *FileInterface;

  //
  // Get some memory
  //
  FileInterface = AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_MEM));
  if (FileInterface == NULL){
    return (NULL);
  }

  //
  // Assign the generic members
  //
  FileInterface->Revision    = EFI_FILE_REVISION;
  FileInterface->Open        = FileInterfaceOpenNotFound;
  FileInterface->Close       = FileInterfaceMemClose;
  FileInterface->GetPosition = FileInterfaceMemGetPosition;
  FileInterface->SetPosition = FileInterfaceMemSetPosition;
  FileInterface->GetInfo     = FileInterfaceNopGetInfo;
  FileInterface->SetInfo     = FileInterfaceNopSetInfo;
  FileInterface->Flush       = FileInterfaceNopGeneric;
  FileInterface->Delete      = FileInterfaceNopGeneric;
  FileInterface->Read        = FileInterfaceMemRead;
  FileInterface->Write       = FileInterfaceMemWrite;
  FileInterface->Unicode     = Unicode;

  ASSERT(FileInterface->Buffer      == NULL);
  ASSERT(FileInterface->BufferSize  == 0);
  ASSERT(FileInterface->Position    == 0);

  if (Unicode) {
    FileInterface->Buffer = AllocateZeroPool(sizeof(gUnicodeFileTag));
    if (FileInterface->Buffer == NULL) {
      FreePool (FileInterface);
      return NULL;
    }
    *((CHAR16 *) (FileInterface->Buffer)) = EFI_UNICODE_BYTE_ORDER_MARK;
    FileInterface->BufferSize = 2;
    FileInterface->Position = 2;
  }

  return ((EFI_FILE_PROTOCOL *)FileInterface);
}

typedef struct {
  UINT64                Revision;
  EFI_FILE_OPEN         Open;
  EFI_FILE_CLOSE        Close;
  EFI_FILE_DELETE       Delete;
  EFI_FILE_READ         Read;
  EFI_FILE_WRITE        Write;
  EFI_FILE_GET_POSITION GetPosition;
  EFI_FILE_SET_POSITION SetPosition;
  EFI_FILE_GET_INFO     GetInfo;
  EFI_FILE_SET_INFO     SetInfo;
  EFI_FILE_FLUSH        Flush;
  BOOLEAN               Unicode;
  EFI_FILE_PROTOCOL     *Orig;
} EFI_FILE_PROTOCOL_FILE;

/**
  Set a files current position

  @param  This            Protocol instance pointer.
  @param  Position        Byte position from the start of the file.
                          
  @retval EFI_SUCCESS     Data was written.
  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.

**/
EFI_STATUS
EFIAPI
FileInterfaceFileSetPosition(
  IN EFI_FILE_PROTOCOL        *This,
  IN UINT64                   Position
  )
{
  return ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->SetPosition(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, Position);
}

/**
  Get a file's current position

  @param  This            Protocol instance pointer.
  @param  Position        Byte position from the start of the file.
                          
  @retval EFI_SUCCESS     Data was written.
  @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..

**/
EFI_STATUS
EFIAPI
FileInterfaceFileGetPosition(
  IN EFI_FILE_PROTOCOL        *This,
  OUT UINT64                  *Position
  )
{
  return ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->GetPosition(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, Position);
}

/**
  Get information about a file.

  @param  This            Protocol instance pointer.
  @param  InformationType Type of information to return in Buffer.
  @param  BufferSize      On input size of buffer, on output amount of data in buffer.
  @param  Buffer          The buffer to return data.

  @retval EFI_SUCCESS          Data was returned.
  @retval EFI_UNSUPPORT        InformationType is not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  The device is write protected.
  @retval EFI_ACCESS_DENIED    The file was open for read only.
  @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.

**/
EFI_STATUS
EFIAPI
FileInterfaceFileGetInfo(
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN OUT UINTN                *BufferSize,
  OUT VOID                    *Buffer
  )
{
  return ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->GetInfo(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, InformationType, BufferSize, Buffer);
}

/**
  Set information about a file

  @param  This            Protocol instance pointer.
  @param  InformationType Type of information in Buffer.
  @param  BufferSize      Size of buffer.
  @param  Buffer          The data to write.

  @retval EFI_SUCCESS          Data was returned.
  @retval EFI_UNSUPPORT        InformationType is not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  The device is write protected.
  @retval EFI_ACCESS_DENIED    The file was open for read only.

**/
EFI_STATUS
EFIAPI
FileInterfaceFileSetInfo(
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN UINTN                    BufferSize,
  IN VOID                     *Buffer
  )
{
  return ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->SetInfo(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, InformationType, BufferSize, Buffer);
}

/**
  Flush data back for the file handle.

  @param  This Protocol instance pointer.

  @retval EFI_SUCCESS          Data was written.
  @retval EFI_UNSUPPORT        Writes to Open directory are not supported.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  The device is write protected.
  @retval EFI_ACCESS_DENIED    The file was open for read only.
  @retval EFI_VOLUME_FULL      The volume is full.

**/
EFI_STATUS
EFIAPI
FileInterfaceFileFlush(
  IN EFI_FILE_PROTOCOL  *This
  )
{
  return ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Flush(((EFI_FILE_PROTOCOL_FILE*)This)->Orig);
}

/**
  Read data from the file.

  @param  This       Protocol instance pointer.
  @param  BufferSize On input size of buffer, on output amount of data in buffer.
  @param  Buffer     The buffer in which data is read.

  @retval EFI_SUCCESS          Data was read.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_BUFFER_TO_SMALL  BufferSize is too small. BufferSize contains required size.

**/
EFI_STATUS
EFIAPI
FileInterfaceFileRead(
  IN EFI_FILE_PROTOCOL        *This,
  IN OUT UINTN                *BufferSize,
  OUT VOID                    *Buffer
  )
{
  CHAR8       *AsciiStrBuffer;
  CHAR16      *UscStrBuffer;
  UINTN       Size;
  UINTN       CharNum;
  EFI_STATUS  Status;
  if (((EFI_FILE_PROTOCOL_FILE*)This)->Unicode) {
    //
    // Unicode
    //
    return (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, BufferSize, Buffer));
  } else {
    //
    // Ascii
    //
    Size  = (*BufferSize) / sizeof(CHAR16);
    AsciiStrBuffer = AllocateZeroPool(Size + sizeof(CHAR8));
    if (AsciiStrBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    UscStrBuffer = AllocateZeroPool(*BufferSize + sizeof(CHAR16));
    if (UscStrBuffer== NULL) {
      SHELL_FREE_NON_NULL(AsciiStrBuffer);
      return EFI_OUT_OF_RESOURCES;
    }
    Status = (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Read(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Size, AsciiStrBuffer));
    if (!EFI_ERROR(Status)) {
      CharNum = UnicodeSPrint(UscStrBuffer, *BufferSize + sizeof(CHAR16), L"%a", AsciiStrBuffer);
      if (CharNum == Size) {
        CopyMem (Buffer, UscStrBuffer, *BufferSize);
      } else {
        Status = EFI_UNSUPPORTED;
      }
    }
    SHELL_FREE_NON_NULL(AsciiStrBuffer);
    SHELL_FREE_NON_NULL(UscStrBuffer);
    return (Status);
  }
}

/**
  Opens a new file relative to the source file's location.

  @param[in]  This       The protocol instance pointer.
  @param[out]  NewHandle Returns File Handle for FileName.
  @param[in]  FileName   Null terminated string. "\", ".", and ".." are supported.
  @param[in]  OpenMode   Open mode for file.
  @param[in]  Attributes Only used for EFI_FILE_MODE_CREATE.

  @retval EFI_SUCCESS          The device was opened.
  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_MEDIA_CHANGED    The media has changed.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
  @retval EFI_VOLUME_FULL      The volume is full.
**/
EFI_STATUS
EFIAPI
FileInterfaceFileOpen (
  IN EFI_FILE_PROTOCOL        *This,
  OUT EFI_FILE_PROTOCOL       **NewHandle,
  IN CHAR16                   *FileName,
  IN UINT64                   OpenMode,
  IN UINT64                   Attributes
  )
{
  return ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Open(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, NewHandle, FileName, OpenMode, Attributes);
}

/**
  Close and delete the file handle.

  @param  This                     Protocol instance pointer.
                                   
  @retval EFI_SUCCESS              The device was opened.
  @retval EFI_WARN_DELETE_FAILURE  The handle was closed but the file was not deleted.

**/
EFI_STATUS
EFIAPI
FileInterfaceFileDelete(
  IN EFI_FILE_PROTOCOL  *This
  )
{
  EFI_STATUS Status;
  Status = ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Delete(((EFI_FILE_PROTOCOL_FILE*)This)->Orig);
  FreePool(This);
  return (Status);
}

/**
  File style interface for File (Close).
  
  @param[in] This       The pointer to the EFI_FILE_PROTOCOL object.
  
  @retval EFI_SUCCESS   The file was closed.
**/
EFI_STATUS
EFIAPI
FileInterfaceFileClose(
  IN EFI_FILE_PROTOCOL *This
  )
{
  EFI_STATUS Status;
  Status = ((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Close(((EFI_FILE_PROTOCOL_FILE*)This)->Orig);
  FreePool(This);
  return (Status);
}

/**
  File style interface for File (Write).

  If the file was opened with ASCII mode the data will be processed through 
  AsciiSPrint before writing.
  
  @param[in] This              The pointer to the EFI_FILE_PROTOCOL object.
  @param[in, out] BufferSize   Size in bytes of Buffer.
  @param[in] Buffer            The pointer to the buffer to write.
  
  @retval EFI_SUCCESS   The data was written.
**/
EFI_STATUS
EFIAPI
FileInterfaceFileWrite(
  IN     EFI_FILE_PROTOCOL  *This,
  IN OUT UINTN              *BufferSize,
  IN     VOID               *Buffer
  )
{
  CHAR8       *AsciiBuffer;
  UINTN       Size;
  EFI_STATUS  Status;
  if (((EFI_FILE_PROTOCOL_FILE*)This)->Unicode) {
    //
    // Unicode
    //
    return (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Write(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, BufferSize, Buffer));
  } else {
    //
    // Ascii
    //
    AsciiBuffer = AllocateZeroPool(*BufferSize);
    AsciiSPrint(AsciiBuffer, *BufferSize, "%S", Buffer);
    Size = AsciiStrSize(AsciiBuffer) - 1; // (we dont need the null terminator)
    Status = (((EFI_FILE_PROTOCOL_FILE*)This)->Orig->Write(((EFI_FILE_PROTOCOL_FILE*)This)->Orig, &Size, AsciiBuffer));
    FreePool(AsciiBuffer);
    return (Status);
  }
}

/**
  Create a file interface with unicode information.

  This will create a new EFI_FILE_PROTOCOL identical to the Templace
  except that the new one has Unicode and Ascii knowledge.
  
  @param[in] Template   A pointer to the EFI_FILE_PROTOCOL object.
  @param[in] Unicode    TRUE for UCS-2, FALSE for ASCII.
  
  @return a new EFI_FILE_PROTOCOL object to be used instead of the template.
**/
EFI_FILE_PROTOCOL*
CreateFileInterfaceFile(
  IN CONST EFI_FILE_PROTOCOL  *Template,
  IN CONST BOOLEAN            Unicode
  )
{
  EFI_FILE_PROTOCOL_FILE *NewOne;

  NewOne = AllocateZeroPool(sizeof(EFI_FILE_PROTOCOL_FILE));
  if (NewOne == NULL) {
    return (NULL);
  }
  CopyMem(NewOne, Template, sizeof(EFI_FILE_PROTOCOL_FILE));
  NewOne->Orig        = (EFI_FILE_PROTOCOL *)Template;
  NewOne->Unicode     = Unicode;
  NewOne->Open        = FileInterfaceFileOpen;
  NewOne->Close       = FileInterfaceFileClose;
  NewOne->Delete      = FileInterfaceFileDelete;
  NewOne->Read        = FileInterfaceFileRead;
  NewOne->Write       = FileInterfaceFileWrite;
  NewOne->GetPosition = FileInterfaceFileGetPosition;
  NewOne->SetPosition = FileInterfaceFileSetPosition;
  NewOne->GetInfo     = FileInterfaceFileGetInfo;
  NewOne->SetInfo     = FileInterfaceFileSetInfo;
  NewOne->Flush       = FileInterfaceFileFlush;

  return ((EFI_FILE_PROTOCOL *)NewOne);
}
