/** @file
  Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
  manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.

  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  Copyright (C) 2014, Red Hat, Inc.
  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Shell.h"

BOOLEAN AsciiRedirection = FALSE;

/**
  Return the next parameter's end from a command line string.

  @param[in] String        the string to parse
**/
CONST CHAR16*
FindEndOfParameter(
  IN CONST CHAR16 *String
  )
{
  CONST CHAR16 *First;
  CONST CHAR16 *CloseQuote;

  First = FindFirstCharacter(String, L" \"", L'^');

  //
  // nothing, all one parameter remaining
  //
  if (*First == CHAR_NULL) {
    return (First);
  }

  //
  // If space before a quote (or neither found, i.e. both CHAR_NULL),
  // then that's the end.
  //
  if (*First == L' ') {
    return (First);
  }

  CloseQuote = FindFirstCharacter (First+1, L"\"", L'^');

  //
  // We did not find a terminator...
  //
  if (*CloseQuote == CHAR_NULL) {
    return (NULL);
  }

  return (FindEndOfParameter (CloseQuote+1));
}

/**
  Return the next parameter from a command line string.

  This function moves the next parameter from Walker into TempParameter and moves
  Walker up past that parameter for recursive calling.  When the final parameter
  is moved *Walker will be set to NULL;

  Temp Parameter must be large enough to hold the parameter before calling this
  function.

  This will also remove all remaining ^ characters after processing.

  @param[in, out] Walker          pointer to string of command line.  Adjusted to
                                  remaining command line on return
  @param[in, out] TempParameter   pointer to string of command line item extracted.
  @param[in]      Length          buffer size of TempParameter.
  @param[in]      StripQuotation  if TRUE then strip the quotation marks surrounding
                                  the parameters.

  @return   EFI_INVALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string.
  @return   EFI_NOT_FOUND         A closing " could not be found on the specified string
**/
EFI_STATUS
GetNextParameter(
  IN OUT CHAR16   **Walker,
  IN OUT CHAR16   **TempParameter,
  IN CONST UINTN  Length,
  IN BOOLEAN      StripQuotation
  )
{
  CONST CHAR16 *NextDelim;

  if (Walker           == NULL
    ||*Walker          == NULL
    ||TempParameter    == NULL
    ||*TempParameter   == NULL
    ){
    return (EFI_INVALID_PARAMETER);
  }


  //
  // make sure we dont have any leading spaces
  //
  while ((*Walker)[0] == L' ') {
      (*Walker)++;
  }

  //
  // make sure we still have some params now...
  //
  if (StrLen(*Walker) == 0) {
DEBUG_CODE_BEGIN();
    *Walker        = NULL;
DEBUG_CODE_END();
    return (EFI_INVALID_PARAMETER);
  }

  NextDelim = FindEndOfParameter(*Walker);

  if (NextDelim == NULL){
DEBUG_CODE_BEGIN();
    *Walker        = NULL;
DEBUG_CODE_END();
    return (EFI_NOT_FOUND);
  }

  StrnCpyS(*TempParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker);

  //
  // Add a CHAR_NULL if we didn't get one via the copy
  //
  if (*NextDelim != CHAR_NULL) {
    (*TempParameter)[NextDelim - *Walker] = CHAR_NULL;
  }

  //
  // Update Walker for the next iteration through the function
  //
  *Walker = (CHAR16*)NextDelim;

  //
  // Remove any non-escaped quotes in the string
  // Remove any remaining escape characters in the string
  //
  for (NextDelim = FindFirstCharacter(*TempParameter, L"\"^", CHAR_NULL)
    ; *NextDelim != CHAR_NULL
    ; NextDelim = FindFirstCharacter(NextDelim, L"\"^", CHAR_NULL)
    ) {
    if (*NextDelim == L'^') {

      //
      // eliminate the escape ^
      //
      CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
      NextDelim++;
    } else if (*NextDelim == L'\"') {

      //
      // eliminate the unescaped quote
      //
      if (StripQuotation) {
        CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
    } else{
        NextDelim++;
    }
    }
  }

  return EFI_SUCCESS;
}

/**
  Function to populate Argc and Argv.

  This function parses the CommandLine and divides it into standard C style Argc/Argv
  parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL.  this supports space
  delimited and quote surrounded parameter definition.

  All special character processing (alias, environment variable, redirection,
  etc... must be complete before calling this API.

  @param[in] CommandLine          String of command line to parse
  @param[in] StripQuotation       if TRUE then strip the quotation marks surrounding
                                  the parameters.
  @param[in, out] Argv            pointer to array of strings; one for each parameter
  @param[in, out] Argc            pointer to number of strings in Argv array

  @return EFI_SUCCESS           the operation was successful
  @return EFI_INVALID_PARAMETER some parameters are invalid
  @return EFI_OUT_OF_RESOURCES  a memory allocation failed.
**/
EFI_STATUS
ParseCommandLineToArgs(
  IN CONST CHAR16 *CommandLine,
  IN BOOLEAN      StripQuotation,
  IN OUT CHAR16   ***Argv,
  IN OUT UINTN    *Argc
  )
{
  UINTN       Count;
  CHAR16      *TempParameter;
  CHAR16      *Walker;
  CHAR16      *NewParam;
  CHAR16      *NewCommandLine;
  UINTN       Size;
  EFI_STATUS  Status;

  ASSERT(Argc != NULL);
  ASSERT(Argv != NULL);

  if (CommandLine == NULL || StrLen(CommandLine)==0) {
    (*Argc) = 0;
    (*Argv) = NULL;
    return (EFI_SUCCESS);
  }

  NewCommandLine = AllocateCopyPool(StrSize(CommandLine), CommandLine);
  if (NewCommandLine == NULL){
    return (EFI_OUT_OF_RESOURCES);
  }

  TrimSpaces(&NewCommandLine);
  Size = StrSize(NewCommandLine);
  TempParameter = AllocateZeroPool(Size);
  if (TempParameter == NULL) {
    SHELL_FREE_NON_NULL(NewCommandLine);
    return (EFI_OUT_OF_RESOURCES);
  }

  for ( Count = 0
      , Walker = (CHAR16*)NewCommandLine
      ; Walker != NULL && *Walker != CHAR_NULL
      ; Count++
      ) {
    if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, TRUE))) {
      break;
    }
  }

  //
  // lets allocate the pointer array
  //
  (*Argv) = AllocateZeroPool((Count)*sizeof(CHAR16*));
  if (*Argv == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  *Argc = 0;
  Walker = (CHAR16*)NewCommandLine;
  while(Walker != NULL && *Walker != CHAR_NULL) {
    SetMem16(TempParameter, Size, CHAR_NULL);
    if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, StripQuotation))) {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    NewParam = AllocateCopyPool(StrSize(TempParameter), TempParameter);
    if (NewParam == NULL){
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }
    ((CHAR16**)(*Argv))[(*Argc)] = NewParam;
    (*Argc)++;
  }
  ASSERT(Count >= (*Argc));
  Status = EFI_SUCCESS;

Done:
  SHELL_FREE_NON_NULL(TempParameter);
  SHELL_FREE_NON_NULL(NewCommandLine);
  return (Status);
}

/**
  creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
  installs it on our handle and if there is an existing version of the protocol
  that one is cached for removal later.

  @param[in, out] NewShellParameters on a successful return, a pointer to pointer
                                     to the newly installed interface.
  @param[in, out] RootShellInstance  on a successful return, pointer to boolean.
                                     TRUE if this is the root shell instance.

  @retval EFI_SUCCESS               the operation completed successfully.
  @return other                     the operation failed.
  @sa ReinstallProtocolInterface
  @sa InstallProtocolInterface
  @sa ParseCommandLineToArgs
**/
EFI_STATUS
CreatePopulateInstallShellParametersProtocol (
  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  **NewShellParameters,
  IN OUT BOOLEAN                        *RootShellInstance
  )
{
  EFI_STATUS Status;
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  CHAR16                    *FullCommandLine;
  UINTN                     Size;

  Size = 0;
  FullCommandLine = NULL;
  LoadedImage = NULL;

  //
  // Assert for valid parameters
  //
  ASSERT(NewShellParameters != NULL);
  ASSERT(RootShellInstance  != NULL);

  //
  // See if we have a shell parameters placed on us
  //
  Status = gBS->OpenProtocol (
                gImageHandle,
                &gEfiShellParametersProtocolGuid,
                (VOID **) &ShellInfoObject.OldShellParameters,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
               );
  //
  // if we don't then we must be the root shell (error is expected)
  //
  if (EFI_ERROR (Status)) {
    *RootShellInstance = TRUE;
  }

  //
  // Allocate the new structure
  //
  *NewShellParameters = AllocateZeroPool(sizeof(EFI_SHELL_PARAMETERS_PROTOCOL));
  if ((*NewShellParameters) == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // get loaded image protocol
  //
  Status = gBS->OpenProtocol (
                gImageHandle,
                &gEfiLoadedImageProtocolGuid,
                (VOID **) &LoadedImage,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
               );
  ASSERT_EFI_ERROR(Status);
  //
  // Build the full command line
  //
  Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, FullCommandLine);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    FullCommandLine = AllocateZeroPool(Size + LoadedImage->LoadOptionsSize);
    Status = SHELL_GET_ENVIRONMENT_VARIABLE(L"ShellOpt", &Size, FullCommandLine);
  }
  if (Status == EFI_NOT_FOUND) {
    //
    // no parameters via environment... ok
    //
  } else {
    if (EFI_ERROR(Status)) {
      return (Status);
    }
  }
  if (Size == 0 && LoadedImage->LoadOptionsSize != 0) {
    ASSERT(FullCommandLine == NULL);
    //
    // Now we need to include a NULL terminator in the size.
    //
    Size = LoadedImage->LoadOptionsSize + sizeof(FullCommandLine[0]);
    FullCommandLine = AllocateZeroPool(Size);
  }
  if (FullCommandLine != NULL) {
    CopyMem (FullCommandLine, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize);
    //
    // Populate Argc and Argv
    //
    Status = ParseCommandLineToArgs(FullCommandLine,
                                    TRUE,
                                    &(*NewShellParameters)->Argv,
                                    &(*NewShellParameters)->Argc);

    FreePool(FullCommandLine);

    ASSERT_EFI_ERROR(Status);
  } else {
    (*NewShellParameters)->Argv = NULL;
    (*NewShellParameters)->Argc = 0;
  }

  //
  // Populate the 3 faked file systems...
  //
  if (*RootShellInstance) {
    (*NewShellParameters)->StdIn  = &FileInterfaceStdIn;
    (*NewShellParameters)->StdOut = &FileInterfaceStdOut;
    (*NewShellParameters)->StdErr = &FileInterfaceStdErr;
    Status = gBS->InstallProtocolInterface(&gImageHandle,
                                           &gEfiShellParametersProtocolGuid,
                                           EFI_NATIVE_INTERFACE,
                                           (VOID*)(*NewShellParameters));
  } else {
    //
    // copy from the existing ones
    //
    (*NewShellParameters)->StdIn  = ShellInfoObject.OldShellParameters->StdIn;
    (*NewShellParameters)->StdOut = ShellInfoObject.OldShellParameters->StdOut;
    (*NewShellParameters)->StdErr = ShellInfoObject.OldShellParameters->StdErr;
    Status = gBS->ReinstallProtocolInterface(gImageHandle,
                                             &gEfiShellParametersProtocolGuid,
                                             (VOID*)ShellInfoObject.OldShellParameters,
                                             (VOID*)(*NewShellParameters));
  }

  return (Status);
}

/**
  frees all memory used by creation and installation of shell parameters protocol
  and if there was an old version installed it will restore that one.

  @param NewShellParameters the interface of EFI_SHELL_PARAMETERS_PROTOCOL that is
  being cleaned up.

  @retval EFI_SUCCESS     the cleanup was successful
  @return other           the cleanup failed
  @sa ReinstallProtocolInterface
  @sa UninstallProtocolInterface
**/
EFI_STATUS
CleanUpShellParametersProtocol (
  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *NewShellParameters
  )
{
  EFI_STATUS Status;
  UINTN LoopCounter;

  //
  // If the old exists we need to restore it
  //
  if (ShellInfoObject.OldShellParameters != NULL) {
    Status = gBS->ReinstallProtocolInterface(gImageHandle,
                                             &gEfiShellParametersProtocolGuid,
                                             (VOID*)NewShellParameters,
                                             (VOID*)ShellInfoObject.OldShellParameters);
    DEBUG_CODE(ShellInfoObject.OldShellParameters = NULL;);
  } else {
    //
    // No old one, just uninstall us...
    //
    Status = gBS->UninstallProtocolInterface(gImageHandle,
                                             &gEfiShellParametersProtocolGuid,
                                             (VOID*)NewShellParameters);
  }
  if (NewShellParameters->Argv != NULL) {
    for ( LoopCounter = 0
        ; LoopCounter < NewShellParameters->Argc
        ; LoopCounter++
       ){
      FreePool(NewShellParameters->Argv[LoopCounter]);
    }
    FreePool(NewShellParameters->Argv);
  }
  FreePool(NewShellParameters);
  return (Status);
}

/**
  Determine if a file name represents a unicode file.

  @param[in] FileName     Pointer to the filename to open.

  @retval EFI_SUCCESS     The file is a unicode file.
  @return An error upon failure.
**/
EFI_STATUS
IsUnicodeFile(
  IN CONST CHAR16 *FileName
  )
{
  SHELL_FILE_HANDLE Handle;
  EFI_STATUS        Status;
  UINT64            OriginalFilePosition;
  UINTN             CharSize;
  CHAR16            CharBuffer;

  Status = gEfiShellProtocol->OpenFileByName(FileName, &Handle, EFI_FILE_MODE_READ);
  if (EFI_ERROR(Status)) {
    return (Status);
  }
  gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition);
  gEfiShellProtocol->SetFilePosition(Handle, 0);
  CharSize = sizeof(CHAR16);
  Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer);
  if (EFI_ERROR(Status) || CharBuffer != gUnicodeFileTag) {
    Status = EFI_BUFFER_TOO_SMALL;
  }
  gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition);
  gEfiShellProtocol->CloseFile(Handle);
  return (Status);
}

/**
  Strips out quotes sections of a string.

  All of the characters between quotes is replaced with spaces.

  @param[in, out] TheString  A pointer to the string to update.
**/
VOID
StripQuotes (
  IN OUT CHAR16 *TheString
  )
{
  BOOLEAN RemoveNow;

  for (RemoveNow = FALSE ; TheString != NULL && *TheString != CHAR_NULL ; TheString++) {
    if (*TheString == L'^' && *(TheString + 1) == L'\"') {
      TheString++;
    } else if (*TheString == L'\"') {
      RemoveNow = (BOOLEAN)!RemoveNow;
    } else if (RemoveNow) {
      *TheString = L' ';
    }
  }
}

/**
  Calculate the 32-bit CRC in a EFI table using the service provided by the
  gRuntime service.

  @param  Hdr                    Pointer to an EFI standard header

**/
VOID
CalculateEfiHdrCrc (
  IN  OUT EFI_TABLE_HEADER    *Hdr
  )
{
  UINT32 Crc;

  Hdr->CRC32 = 0;

  //
  // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
  //  Crc will come back as zero if we set it to zero here
  //
  Crc = 0;
  gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
  Hdr->CRC32 = Crc;
}

/**
  Fix a string to only have the file name, removing starting at the first space of whatever is quoted.

  @param[in]  FileName    The filename to start with.

  @retval NULL  FileName was invalid.
  @return       The modified FileName.
**/
CHAR16*
FixFileName (
  IN CHAR16 *FileName
  )
{
  CHAR16  *Copy;
  CHAR16  *TempLocation;

  if (FileName == NULL) {
    return (NULL);
  }

  if (FileName[0] == L'\"') {
    Copy = FileName+1;
    if ((TempLocation = StrStr(Copy , L"\"")) != NULL) {
      TempLocation[0] = CHAR_NULL;
    }
  } else {
    Copy = FileName;
    while(Copy[0] == L' ') {
      Copy++;
    }
    if ((TempLocation = StrStr(Copy , L" ")) != NULL) {
      TempLocation[0] = CHAR_NULL;
    }
  }

  if (Copy[0] == CHAR_NULL) {
    return (NULL);
  }

  return (Copy);
}

/**
  Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.

  @param[in]  FileName    The filename to start with.

  @retval NULL  FileName was invalid.
  @return       The modified FileName.
**/
CHAR16*
FixVarName (
  IN CHAR16 *FileName
  )
{
  CHAR16  *Copy;
  CHAR16  *TempLocation;

  Copy = FileName;

  if (FileName[0] == L'%') {
    Copy = FileName+1;
    if ((TempLocation = StrStr(Copy , L"%")) != NULL) {
      TempLocation[0] = CHAR_NULL;
    }
  }

  return (FixFileName(Copy));
}


/**
  Write the unicode file tag to the specified file.

  It is the caller's responsibility to ensure that
  ShellInfoObject.NewEfiShellProtocol has been initialized before calling this
  function.

  @param[in] FileHandle  The file to write the unicode file tag to.

  @return  Status code from ShellInfoObject.NewEfiShellProtocol->WriteFile.
**/
EFI_STATUS
WriteFileTag (
  IN SHELL_FILE_HANDLE FileHandle
  )
{
  CHAR16     FileTag;
  UINTN      Size;
  EFI_STATUS Status;

  FileTag = gUnicodeFileTag;
  Size = sizeof FileTag;
  Status = ShellInfoObject.NewEfiShellProtocol->WriteFile (FileHandle, &Size,
                                                  &FileTag);
  ASSERT (EFI_ERROR (Status) || Size == sizeof FileTag);
  return Status;
}


/**
  Function will replace the current StdIn and StdOut in the ShellParameters protocol
  structure by parsing NewCommandLine.  The current values are returned to the
  user.

  This will also update the system table.

  @param[in, out] ShellParameters        Pointer to parameter structure to modify.
  @param[in] NewCommandLine              The new command line to parse and use.
  @param[out] OldStdIn                   Pointer to old StdIn.
  @param[out] OldStdOut                  Pointer to old StdOut.
  @param[out] OldStdErr                  Pointer to old StdErr.
  @param[out] SystemTableInfo            Pointer to old system table information.

  @retval   EFI_SUCCESS                 Operation was successful, Argv and Argc are valid.
  @retval   EFI_OUT_OF_RESOURCES        A memory allocation failed.
**/
EFI_STATUS
UpdateStdInStdOutStdErr(
  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
  IN CHAR16                             *NewCommandLine,
  OUT SHELL_FILE_HANDLE                 *OldStdIn,
  OUT SHELL_FILE_HANDLE                 *OldStdOut,
  OUT SHELL_FILE_HANDLE                 *OldStdErr,
  OUT SYSTEM_TABLE_INFO                 *SystemTableInfo
  )
{
  CHAR16            *CommandLineCopy;
  CHAR16            *CommandLineWalker;
  CHAR16            *StdErrFileName;
  CHAR16            *StdOutFileName;
  CHAR16            *StdInFileName;
  CHAR16            *StdInVarName;
  CHAR16            *StdOutVarName;
  CHAR16            *StdErrVarName;
  EFI_STATUS        Status;
  SHELL_FILE_HANDLE TempHandle;
  UINT64            FileSize;
  BOOLEAN           OutUnicode;
  BOOLEAN           InUnicode;
  BOOLEAN           ErrUnicode;
  BOOLEAN           OutAppend;
  BOOLEAN           ErrAppend;
  UINTN             Size;
  SPLIT_LIST        *Split;
  CHAR16            *FirstLocation;
  BOOLEAN           Volatile;

  OutUnicode      = TRUE;
  InUnicode       = TRUE;
  AsciiRedirection = FALSE;
  ErrUnicode      = TRUE;
  StdInVarName    = NULL;
  StdOutVarName   = NULL;
  StdErrVarName   = NULL;
  StdErrFileName  = NULL;
  StdInFileName   = NULL;
  StdOutFileName  = NULL;
  ErrAppend       = FALSE;
  OutAppend       = FALSE;
  CommandLineCopy = NULL;
  FirstLocation   = NULL;

  if (ShellParameters == NULL || SystemTableInfo == NULL || OldStdIn == NULL || OldStdOut == NULL || OldStdErr == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  SystemTableInfo->ConIn          = gST->ConIn;
  SystemTableInfo->ConInHandle    = gST->ConsoleInHandle;
  SystemTableInfo->ConOut         = gST->ConOut;
  SystemTableInfo->ConOutHandle   = gST->ConsoleOutHandle;
  SystemTableInfo->ErrOut         = gST->StdErr;
  SystemTableInfo->ErrOutHandle   = gST->StandardErrorHandle;
  *OldStdIn                       = ShellParameters->StdIn;
  *OldStdOut                      = ShellParameters->StdOut;
  *OldStdErr                      = ShellParameters->StdErr;

  if (NewCommandLine == NULL) {
    return (EFI_SUCCESS);
  }

  CommandLineCopy = StrnCatGrow(&CommandLineCopy, NULL, NewCommandLine, 0);
  if (CommandLineCopy == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }
  Status          = EFI_SUCCESS;
  Split           = NULL;
  FirstLocation   = CommandLineCopy + StrLen(CommandLineCopy);

  StripQuotes(CommandLineCopy);

  if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
    Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
    if (Split != NULL && Split->SplitStdIn != NULL) {
      ShellParameters->StdIn  = Split->SplitStdIn;
    }
    if (Split != NULL && Split->SplitStdOut != NULL) {
      ShellParameters->StdOut = Split->SplitStdOut;
    }
  }

  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>>v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 12, L' ');
    StdErrVarName   = CommandLineWalker += 6;
    ErrAppend       = TRUE;
    if (StrStr(CommandLineWalker, L" 2>>v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 12, L' ');
    StdOutVarName   = CommandLineWalker += 6;
    OutAppend       = TRUE;
    if (StrStr(CommandLineWalker, L" 1>>v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    StdOutVarName   = CommandLineWalker += 5;
    OutAppend       = TRUE;
    if (StrStr(CommandLineWalker, L" >>v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  } else if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    StdOutVarName   = CommandLineWalker += 4;
    OutAppend       = FALSE;
    if (StrStr(CommandLineWalker, L" >v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>>a ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 12, L' ');
    StdOutFileName  = CommandLineWalker += 6;
    OutAppend       = TRUE;
    OutUnicode      = FALSE;
    if (StrStr(CommandLineWalker, L" 1>>a ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>> ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 5;
      OutAppend       = TRUE;
    }
    if (StrStr(CommandLineWalker, L" 1>> ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >> ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 4;
      OutAppend       = TRUE;
    }
    if (StrStr(CommandLineWalker, L" >> ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >>a ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 5;
      OutAppend       = TRUE;
      OutUnicode      = FALSE;
    }
    if (StrStr(CommandLineWalker, L" >>a ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>a ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 5;
      OutAppend       = FALSE;
      OutUnicode      = FALSE;
    }
    if (StrStr(CommandLineWalker, L" 1>a ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" >a ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 4;
      OutAppend       = FALSE;
      OutUnicode      = FALSE;
    }
    if (StrStr(CommandLineWalker, L" >a ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>> ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdErrFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdErrFileName  = CommandLineWalker += 5;
      ErrAppend       = TRUE;
    }
    if (StrStr(CommandLineWalker, L" 2>> ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }

  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdErrVarName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdErrVarName   = CommandLineWalker += 5;
      ErrAppend       = FALSE;
    }
    if (StrStr(CommandLineWalker, L" 2>v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1>v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdOutVarName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutVarName   = CommandLineWalker += 5;
      OutAppend       = FALSE;
    }
    if (StrStr(CommandLineWalker, L" 1>v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2>a ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 10, L' ');
    if (StdErrFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdErrFileName  = CommandLineWalker += 5;
      ErrAppend       = FALSE;
      ErrUnicode      = FALSE;
    }
    if (StrStr(CommandLineWalker, L" 2>a ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 2> ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    if (StdErrFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdErrFileName  = CommandLineWalker += 4;
      ErrAppend       = FALSE;
    }
    if (StrStr(CommandLineWalker, L" 2> ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }

  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" 1> ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 4;
      OutAppend       = FALSE;
    }
    if (StrStr(CommandLineWalker, L" 1> ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }

  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" > ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 6, L' ');
    if (StdOutFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdOutFileName  = CommandLineWalker += 3;
      OutAppend       = FALSE;
    }
    if (StrStr(CommandLineWalker, L" > ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }

  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" < ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 6, L' ');
    if (StdInFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdInFileName  = CommandLineWalker += 3;
    }
    if (StrStr(CommandLineWalker, L" < ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <a ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    if (StdInFileName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdInFileName   = CommandLineWalker += 4;
      InUnicode       = FALSE;
      AsciiRedirection = TRUE;
    }
    if (StrStr(CommandLineWalker, L" <a ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }
  if (!EFI_ERROR(Status) && (CommandLineWalker = StrStr(CommandLineCopy, L" <v ")) != NULL) {
    FirstLocation = MIN(CommandLineWalker, FirstLocation);
    SetMem16(CommandLineWalker, 8, L' ');
    if (StdInVarName != NULL) {
      Status = EFI_INVALID_PARAMETER;
    } else {
      StdInVarName  = CommandLineWalker += 4;
    }
    if (StrStr(CommandLineWalker, L" <v ") != NULL) {
      Status = EFI_NOT_FOUND;
    }
  }

  //
  // re-populate the string to support any filenames that were in quotes.
  //
  StrnCpyS(CommandLineCopy, StrSize(CommandLineCopy)/sizeof(CHAR16), NewCommandLine, StrLen(NewCommandLine));

  if (FirstLocation != CommandLineCopy + StrLen(CommandLineCopy)
    && (((UINTN)FirstLocation - (UINTN)CommandLineCopy)/sizeof(CHAR16) < StrLen(NewCommandLine))
    ){
    *(NewCommandLine + ((UINTN)FirstLocation - (UINTN)CommandLineCopy)/sizeof(CHAR16)) = CHAR_NULL;
  }

  if (!EFI_ERROR(Status)) {

    if (StdErrFileName != NULL) {
      if ((StdErrFileName    = FixFileName(StdErrFileName)) == NULL) {
        Status = EFI_INVALID_PARAMETER;
      }
    }
    if (StdOutFileName != NULL) {
      if ((StdOutFileName    = FixFileName(StdOutFileName)) == NULL) {
        Status = EFI_INVALID_PARAMETER;
      }
    }
    if (StdInFileName  != NULL) {
      if ((StdInFileName     = FixFileName(StdInFileName)) == NULL) {
        Status = EFI_INVALID_PARAMETER;
      }
    }
    if (StdErrVarName  != NULL) {
      if ((StdErrVarName     = FixVarName(StdErrVarName)) == NULL) {
        Status = EFI_INVALID_PARAMETER;
      }
    }
    if (StdOutVarName  != NULL) {
      if ((StdOutVarName     = FixVarName(StdOutVarName)) == NULL) {
        Status = EFI_INVALID_PARAMETER;
      }
    }
    if (StdInVarName   != NULL) {
      if ((StdInVarName      = FixVarName(StdInVarName)) == NULL) {
        Status = EFI_INVALID_PARAMETER;
      }
    }

    //
    // Verify not the same and not duplicating something from a split
    //
    if (
      //
      // Check that no 2 filenames are the same
      //
      (StdErrFileName != NULL && StdOutFileName!= NULL && StringNoCaseCompare(&StdErrFileName, &StdOutFileName) == 0)
      ||(StdErrFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdErrFileName, &StdInFileName ) == 0)
      ||(StdOutFileName != NULL && StdInFileName != NULL && StringNoCaseCompare(&StdOutFileName, &StdInFileName ) == 0)
      //
      // Check that no 2 variable names are the same
      //
      ||(StdErrVarName  != NULL && StdInVarName  != NULL && StringNoCaseCompare(&StdErrVarName , &StdInVarName  ) == 0)
      ||(StdOutVarName  != NULL && StdInVarName != NULL && StringNoCaseCompare(&StdOutVarName , &StdInVarName  ) == 0)
      ||(StdErrVarName  != NULL && StdOutVarName != NULL && StringNoCaseCompare(&StdErrVarName , &StdOutVarName ) == 0)
      //
      // When a split (using | operator) is in place some are not allowed
      //
      ||(Split != NULL && Split->SplitStdIn  != NULL && (StdInVarName  != NULL || StdInFileName  != NULL))
      ||(Split != NULL && Split->SplitStdOut != NULL && (StdOutVarName != NULL || StdOutFileName != NULL))
      //
      // Check that nothing is trying to be output to 2 locations.
      //
      ||(StdErrFileName != NULL && StdErrVarName != NULL)
      ||(StdOutFileName != NULL && StdOutVarName != NULL)
      ||(StdInFileName  != NULL && StdInVarName  != NULL)
      //
      // Check for no volatile environment variables
      //
      ||(StdErrVarName  != NULL && !EFI_ERROR (IsVolatileEnv (StdErrVarName, &Volatile)) && !Volatile)
      ||(StdOutVarName  != NULL && !EFI_ERROR (IsVolatileEnv (StdOutVarName, &Volatile)) && !Volatile)
      //
      // Cant redirect during a reconnect operation.
      //
      ||(StrStr(NewCommandLine, L"connect -r") != NULL
         && (StdOutVarName != NULL || StdOutFileName != NULL || StdErrFileName != NULL || StdErrVarName != NULL))
      //
      // Check that filetypes (Unicode/Ascii) do not change during an append
      //
      ||(StdOutFileName != NULL && OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && EFI_ERROR(IsUnicodeFile(StdOutFileName))))
      ||(StdErrFileName != NULL && ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && EFI_ERROR(IsUnicodeFile(StdErrFileName))))
      ||(StdOutFileName != NULL && !OutUnicode && OutAppend && (!EFI_ERROR(ShellFileExists(StdOutFileName)) && !EFI_ERROR(IsUnicodeFile(StdOutFileName))))
      ||(StdErrFileName != NULL && !ErrUnicode && ErrAppend && (!EFI_ERROR(ShellFileExists(StdErrFileName)) && !EFI_ERROR(IsUnicodeFile(StdErrFileName))))
      ){
      Status = EFI_INVALID_PARAMETER;
      ShellParameters->StdIn  = *OldStdIn;
      ShellParameters->StdOut = *OldStdOut;
      ShellParameters->StdErr = *OldStdErr;
    } else if (!EFI_ERROR(Status)){
      //
      // Open the Std<Whatever> and we should not have conflicts here...
      //

      //
      // StdErr to a file
      //
      if (StdErrFileName != NULL) {
        if (!ErrAppend) {
          //
          // delete existing file.
          //
          ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdErrFileName);
        }
        Status = ShellOpenFileByName(StdErrFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
        if (!ErrAppend && ErrUnicode && !EFI_ERROR(Status)) {
          Status = WriteFileTag (TempHandle);
        }
        if (!ErrUnicode && !EFI_ERROR(Status)) {
          TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
          ASSERT(TempHandle != NULL);
        }
        if (!EFI_ERROR(Status)) {
          ShellParameters->StdErr = TempHandle;
          gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
        }
      }

      //
      // StdOut to a file
      //
      if (!EFI_ERROR(Status) && StdOutFileName != NULL) {
        if (!OutAppend) {
          //
          // delete existing file.
          //
          ShellInfoObject.NewEfiShellProtocol->DeleteFileByName(StdOutFileName);
        }
        Status = ShellOpenFileByName(StdOutFileName, &TempHandle, EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ|EFI_FILE_MODE_CREATE,0);
        if (TempHandle == NULL) {
          Status = EFI_INVALID_PARAMETER;
        } else {
          if (gUnicodeCollation->MetaiMatch (gUnicodeCollation, StdOutFileName, L"NUL")) {
            //no-op
          } else if (!OutAppend && OutUnicode && !EFI_ERROR(Status)) {
            Status = WriteFileTag (TempHandle);
          } else if (OutAppend) {
            Status = ShellInfoObject.NewEfiShellProtocol->GetFileSize(TempHandle, &FileSize);
            if (!EFI_ERROR(Status)) {
              //
              // When appending to a new unicode file, write the file tag.
              // Otherwise (ie. when appending to a new ASCII file, or an
              // existent file with any encoding), just seek to the end.
              //
              Status = (FileSize == 0 && OutUnicode) ?
                         WriteFileTag (TempHandle) :
                         ShellInfoObject.NewEfiShellProtocol->SetFilePosition (
                                                                TempHandle,
                                                                FileSize);
            }
          }
          if (!OutUnicode && !EFI_ERROR(Status)) {
            TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
            ASSERT(TempHandle != NULL);
          }
          if (!EFI_ERROR(Status)) {
            ShellParameters->StdOut = TempHandle;
            gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
          }
        }
      }

      //
      // StdOut to a var
      //
      if (!EFI_ERROR(Status) && StdOutVarName != NULL) {
        if (!OutAppend) {
          //
          // delete existing variable.
          //
          SHELL_SET_ENVIRONMENT_VARIABLE_V(StdOutVarName, 0, L"");
        }
        TempHandle = CreateFileInterfaceEnv(StdOutVarName);
        ASSERT(TempHandle != NULL);
        ShellParameters->StdOut = TempHandle;
        gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
      }

      //
      // StdErr to a var
      //
      if (!EFI_ERROR(Status) && StdErrVarName != NULL) {
        if (!ErrAppend) {
          //
          // delete existing variable.
          //
          SHELL_SET_ENVIRONMENT_VARIABLE_V(StdErrVarName, 0, L"");
        }
        TempHandle = CreateFileInterfaceEnv(StdErrVarName);
        ASSERT(TempHandle != NULL);
        ShellParameters->StdErr = TempHandle;
        gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
      }

      //
      // StdIn from a var
      //
      if (!EFI_ERROR(Status) && StdInVarName != NULL) {
        TempHandle = CreateFileInterfaceEnv(StdInVarName);
        if (TempHandle == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
        } else {
          if (!InUnicode) {
            TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
          }
          Size = 0;
          if (TempHandle == NULL || ((EFI_FILE_PROTOCOL*)TempHandle)->Read(TempHandle, &Size, NULL) != EFI_BUFFER_TOO_SMALL) {
            Status = EFI_INVALID_PARAMETER;
          } else {
            ShellParameters->StdIn = TempHandle;
            gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
          }
        }
      }

      //
      // StdIn from a file
      //
      if (!EFI_ERROR(Status) && StdInFileName != NULL) {
        Status = ShellOpenFileByName(
          StdInFileName,
          &TempHandle,
          EFI_FILE_MODE_READ,
          0);
        if (!EFI_ERROR(Status)) {
          if (!InUnicode) {
            //
            // Create the ASCII->Unicode conversion layer
            //
            TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
          }
          ShellParameters->StdIn = TempHandle;
          gST->ConIn = CreateSimpleTextInOnFile(TempHandle, &gST->ConsoleInHandle);
        }
      }
    }
  }
  FreePool(CommandLineCopy);

  CalculateEfiHdrCrc(&gST->Hdr);

  if (gST->ConIn == NULL ||gST->ConOut == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  }

  if (Status == EFI_NOT_FOUND) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
  } else if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
  }

  return (Status);
}

/**
  Function will replace the current StdIn and StdOut in the ShellParameters protocol
  structure with StdIn and StdOut.  The current values are de-allocated.

  @param[in, out] ShellParameters      Pointer to parameter structure to modify.
  @param[in] OldStdIn                  Pointer to old StdIn.
  @param[in] OldStdOut                 Pointer to old StdOut.
  @param[in] OldStdErr                 Pointer to old StdErr.
  @param[in] SystemTableInfo           Pointer to old system table information.
**/
EFI_STATUS
RestoreStdInStdOutStdErr (
  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
  IN  SHELL_FILE_HANDLE                 *OldStdIn,
  IN  SHELL_FILE_HANDLE                 *OldStdOut,
  IN  SHELL_FILE_HANDLE                 *OldStdErr,
  IN  SYSTEM_TABLE_INFO                 *SystemTableInfo
  )
{
  SPLIT_LIST        *Split;

  if (ShellParameters == NULL
    ||OldStdIn        == NULL
    ||OldStdOut       == NULL
    ||OldStdErr       == NULL
    ||SystemTableInfo == NULL) {
    return (EFI_INVALID_PARAMETER);
  }
  if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
    Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
  } else {
    Split = NULL;
  }
  if (ShellParameters->StdIn  != *OldStdIn) {
    if ((Split != NULL && Split->SplitStdIn != ShellParameters->StdIn) || Split == NULL) {
      gEfiShellProtocol->CloseFile(ShellParameters->StdIn);
    }
    ShellParameters->StdIn = *OldStdIn;
  }
  if (ShellParameters->StdOut != *OldStdOut) {
    if ((Split != NULL && Split->SplitStdOut != ShellParameters->StdOut) || Split == NULL) {
      gEfiShellProtocol->CloseFile(ShellParameters->StdOut);
    }
    ShellParameters->StdOut = *OldStdOut;
  }
  if (ShellParameters->StdErr != *OldStdErr) {
    gEfiShellProtocol->CloseFile(ShellParameters->StdErr);
    ShellParameters->StdErr = *OldStdErr;
  }

  if (gST->ConIn != SystemTableInfo->ConIn) {
    CloseSimpleTextInOnFile(gST->ConIn);
    gST->ConIn                = SystemTableInfo->ConIn;
    gST->ConsoleInHandle      = SystemTableInfo->ConInHandle;
  }
  if (gST->ConOut != SystemTableInfo->ConOut) {
    CloseSimpleTextOutOnFile(gST->ConOut);
    gST->ConOut               = SystemTableInfo->ConOut;
    gST->ConsoleOutHandle     = SystemTableInfo->ConOutHandle;
  }
  if (gST->StdErr != SystemTableInfo->ErrOut) {
    CloseSimpleTextOutOnFile(gST->StdErr);
    gST->StdErr               = SystemTableInfo->ErrOut;
    gST->StandardErrorHandle  = SystemTableInfo->ErrOutHandle;
  }

  CalculateEfiHdrCrc(&gST->Hdr);

  return (EFI_SUCCESS);
}
/**
  Function will replace the current Argc and Argv in the ShellParameters protocol
  structure by parsing NewCommandLine.  The current values are returned to the
  user.

  If OldArgv or OldArgc is NULL then that value is not returned.

  @param[in, out] ShellParameters        Pointer to parameter structure to modify.
  @param[in] NewCommandLine              The new command line to parse and use.
  @param[in] Type                        The type of operation.
  @param[out] OldArgv                    Pointer to old list of parameters.
  @param[out] OldArgc                    Pointer to old number of items in Argv list.


  @retval   EFI_SUCCESS                 Operation was successful, Argv and Argc are valid.
  @return   EFI_INVALID_PARAMETER       Some parameters are invalid.
  @retval   EFI_OUT_OF_RESOURCES        A memory allocation failed.
**/
EFI_STATUS
UpdateArgcArgv(
  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
  IN CONST CHAR16                       *NewCommandLine,
  IN SHELL_OPERATION_TYPES              Type,
  OUT CHAR16                            ***OldArgv OPTIONAL,
  OUT UINTN                             *OldArgc OPTIONAL
  )
{
  BOOLEAN                 StripParamQuotation;

  ASSERT(ShellParameters != NULL);
  StripParamQuotation = TRUE;

  if (OldArgc != NULL) {
    *OldArgc = ShellParameters->Argc;
  }
  if (OldArgc != NULL) {
    *OldArgv = ShellParameters->Argv;
  }

  if (Type == Script_File_Name) {
    StripParamQuotation = FALSE;
  }

  return ParseCommandLineToArgs( NewCommandLine,
                                 StripParamQuotation,
                                 &(ShellParameters->Argv),
                                 &(ShellParameters->Argc)
                                );
}

/**
  Function will replace the current Argc and Argv in the ShellParameters protocol
  structure with Argv and Argc.  The current values are de-allocated and the
  OldArgv must not be deallocated by the caller.

  @param[in, out] ShellParameters       pointer to parameter structure to modify
  @param[in] OldArgv                    pointer to old list of parameters
  @param[in] OldArgc                    pointer to old number of items in Argv list
**/
VOID
RestoreArgcArgv(
  IN OUT EFI_SHELL_PARAMETERS_PROTOCOL  *ShellParameters,
  IN CHAR16                             ***OldArgv,
  IN UINTN                              *OldArgc
  )
{
  UINTN LoopCounter;
  ASSERT(ShellParameters != NULL);
  ASSERT(OldArgv         != NULL);
  ASSERT(OldArgc         != NULL);

  if (ShellParameters->Argv != NULL) {
    for ( LoopCounter = 0
        ; LoopCounter < ShellParameters->Argc
        ; LoopCounter++
       ){
      FreePool(ShellParameters->Argv[LoopCounter]);
    }
    FreePool(ShellParameters->Argv);
  }
  ShellParameters->Argv = *OldArgv;
  *OldArgv = NULL;
  ShellParameters->Argc = *OldArgc;
  *OldArgc = 0;
}
