/** @file
  This is THE shell (application)

  Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright 2015-2018 Dell Technologies.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Shell.h"

//
// Initialize the global structure
//
SHELL_INFO  ShellInfoObject = {
  NULL,
  NULL,
  FALSE,
  FALSE,
  {
    {
      {
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0
      }
    },
    0,
    NULL,
    NULL
  },
  {
    { NULL,NULL   }, NULL
  },
  {
    {
      { NULL,NULL   }, NULL
    },
    0,
    0,
    TRUE
  },
  NULL,
  0,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  {
    { NULL,NULL   }, NULL, NULL
  },
  {
    { NULL,NULL   }, NULL, NULL
  },
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  FALSE
};

STATIC CONST CHAR16  mScriptExtension[]      = L".NSH";
STATIC CONST CHAR16  mExecutableExtensions[] = L".NSH;.EFI";
STATIC CONST CHAR16  mStartupScript[]        = L"startup.nsh";
CONST CHAR16         mNoNestingEnvVarName[]  = L"nonesting";
CONST CHAR16         mNoNestingTrue[]        = L"True";
CONST CHAR16         mNoNestingFalse[]       = L"False";

/**
  Cleans off leading and trailing spaces and tabs.

  @param[in] String pointer to the string to trim them off.
**/
EFI_STATUS
TrimSpaces (
  IN CHAR16  **String
  )
{
  ASSERT (String != NULL);
  ASSERT (*String != NULL);
  //
  // Remove any spaces and tabs at the beginning of the (*String).
  //
  while (((*String)[0] == L' ') || ((*String)[0] == L'\t')) {
    CopyMem ((*String), (*String)+1, StrSize ((*String)) - sizeof ((*String)[0]));
  }

  //
  // Remove any spaces and tabs at the end of the (*String).
  //
  while ((StrLen (*String) > 0) && (((*String)[StrLen ((*String))-1] == L' ') || ((*String)[StrLen ((*String))-1] == L'\t'))) {
    (*String)[StrLen ((*String))-1] = CHAR_NULL;
  }

  return (EFI_SUCCESS);
}

/**
  Parse for the next instance of one string within another string. Can optionally make sure that
  the string was not escaped (^ character) per the shell specification.

  @param[in] SourceString             The string to search within
  @param[in] FindString               The string to look for
  @param[in] CheckForEscapeCharacter  TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances
**/
CHAR16 *
FindNextInstance (
  IN CONST CHAR16   *SourceString,
  IN CONST CHAR16   *FindString,
  IN CONST BOOLEAN  CheckForEscapeCharacter
  )
{
  CHAR16  *Temp;

  if (SourceString == NULL) {
    return (NULL);
  }

  Temp = StrStr (SourceString, FindString);

  //
  // If nothing found, or we don't care about escape characters
  //
  if ((Temp == NULL) || !CheckForEscapeCharacter) {
    return (Temp);
  }

  //
  // If we found an escaped character, try again on the remainder of the string
  //
  if ((Temp > (SourceString)) && (*(Temp-1) == L'^')) {
    return FindNextInstance (Temp+1, FindString, CheckForEscapeCharacter);
  }

  //
  // we found the right character
  //
  return (Temp);
}

/**
  Check whether the string between a pair of % is a valid environment variable name.

  @param[in] BeginPercent       pointer to the first percent.
  @param[in] EndPercent          pointer to the last percent.

  @retval TRUE                          is a valid environment variable name.
  @retval FALSE                         is NOT a valid environment variable name.
**/
BOOLEAN
IsValidEnvironmentVariableName (
  IN CONST CHAR16  *BeginPercent,
  IN CONST CHAR16  *EndPercent
  )
{
  CONST CHAR16  *Walker;

  Walker = NULL;

  ASSERT (BeginPercent != NULL);
  ASSERT (EndPercent != NULL);
  ASSERT (BeginPercent < EndPercent);

  if ((BeginPercent + 1) == EndPercent) {
    return FALSE;
  }

  for (Walker = BeginPercent + 1; Walker < EndPercent; Walker++) {
    if (
        ((*Walker >= L'0') && (*Walker <= L'9')) ||
        ((*Walker >= L'A') && (*Walker <= L'Z')) ||
        ((*Walker >= L'a') && (*Walker <= L'z')) ||
        (*Walker == L'_')
        )
    {
      if ((Walker == BeginPercent + 1) && ((*Walker >= L'0') && (*Walker <= L'9'))) {
        return FALSE;
      } else {
        continue;
      }
    } else {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Determine if a command line contains a split operation

  @param[in] CmdLine      The command line to parse.

  @retval TRUE            CmdLine has a valid split.
  @retval FALSE           CmdLine does not have a valid split.
**/
BOOLEAN
ContainsSplit (
  IN CONST CHAR16  *CmdLine
  )
{
  CONST CHAR16  *TempSpot;
  CONST CHAR16  *FirstQuote;
  CONST CHAR16  *SecondQuote;

  FirstQuote  = FindNextInstance (CmdLine, L"\"", TRUE);
  SecondQuote = NULL;
  TempSpot    = FindFirstCharacter (CmdLine, L"|", L'^');

  if ((FirstQuote == NULL) ||
      (TempSpot == NULL) ||
      (TempSpot == CHAR_NULL) ||
      (FirstQuote > TempSpot)
      )
  {
    return (BOOLEAN)((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
  }

  while ((TempSpot != NULL) && (*TempSpot != CHAR_NULL)) {
    if ((FirstQuote == NULL) || (FirstQuote > TempSpot)) {
      break;
    }

    SecondQuote = FindNextInstance (FirstQuote + 1, L"\"", TRUE);
    if (SecondQuote == NULL) {
      break;
    }

    if (SecondQuote < TempSpot) {
      FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
      continue;
    } else {
      FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
      TempSpot   = FindFirstCharacter (TempSpot + 1, L"|", L'^');
      continue;
    }
  }

  return (BOOLEAN)((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
}

/**
  Function to start monitoring for CTRL-S using SimpleTextInputEx.  This
  feature's enabled state was not known when the shell initially launched.

  @retval EFI_SUCCESS           The feature is enabled.
  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available.
**/
EFI_STATUS
InternalEfiShellStartCtrlSMonitor (
  VOID
  )
{
  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *SimpleEx;
  EFI_KEY_DATA                       KeyData;
  EFI_STATUS                         Status;

  Status = gBS->OpenProtocol (
                  gST->ConsoleInHandle,
                  &gEfiSimpleTextInputExProtocolGuid,
                  (VOID **)&SimpleEx,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_SHELL_NO_IN_EX),
      ShellInfoObject.HiiHandle
      );
    return (EFI_SUCCESS);
  }

  KeyData.KeyState.KeyToggleState = 0;
  KeyData.Key.ScanCode            = 0;
  KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
  KeyData.Key.UnicodeChar         = L's';

  Status = SimpleEx->RegisterKeyNotify (
                       SimpleEx,
                       &KeyData,
                       NotificationFunction,
                       &ShellInfoObject.CtrlSNotifyHandle1
                       );

  KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->RegisterKeyNotify (
                         SimpleEx,
                         &KeyData,
                         NotificationFunction,
                         &ShellInfoObject.CtrlSNotifyHandle2
                         );
  }

  KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
  KeyData.Key.UnicodeChar        = 19;

  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->RegisterKeyNotify (
                         SimpleEx,
                         &KeyData,
                         NotificationFunction,
                         &ShellInfoObject.CtrlSNotifyHandle3
                         );
  }

  KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
  if (!EFI_ERROR (Status)) {
    Status = SimpleEx->RegisterKeyNotify (
                         SimpleEx,
                         &KeyData,
                         NotificationFunction,
                         &ShellInfoObject.CtrlSNotifyHandle4
                         );
  }

  return (Status);
}

/**
  The entry point for the application.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                      Status;
  CHAR16                          *TempString;
  UINTN                           Size;
  EFI_HANDLE                      ConInHandle;
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *OldConIn;
  SPLIT_LIST                      *Split;

  if (PcdGet8 (PcdShellSupportLevel) > 3) {
    return (EFI_UNSUPPORTED);
  }

  //
  // Clear the screen
  //
  Status = gST->ConOut->ClearScreen (gST->ConOut);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  //
  // Populate the global structure from PCDs
  //
  ShellInfoObject.ImageDevPath               = NULL;
  ShellInfoObject.FileDevPath                = NULL;
  ShellInfoObject.PageBreakEnabled           = PcdGetBool (PcdShellPageBreakDefault);
  ShellInfoObject.ViewingSettings.InsertMode = PcdGetBool (PcdShellInsertModeDefault);
  ShellInfoObject.LogScreenCount             = PcdGet8 (PcdShellScreenLogCount);

  //
  // verify we dont allow for spec violation
  //
  ASSERT (ShellInfoObject.LogScreenCount >= 3);

  //
  // Initialize the LIST ENTRY objects...
  //
  InitializeListHead (&ShellInfoObject.BufferToFreeList.Link);
  InitializeListHead (&ShellInfoObject.ViewingSettings.CommandHistory.Link);
  InitializeListHead (&ShellInfoObject.SplitList.Link);

  //
  // Check PCDs for optional features that are not implemented yet.
  //
  if (  PcdGetBool (PcdShellSupportOldProtocols)
     || !FeaturePcdGet (PcdShellRequireHiiPlatform)
     || FeaturePcdGet (PcdShellSupportFrameworkHii)
        )
  {
    return (EFI_UNSUPPORTED);
  }

  //
  // turn off the watchdog timer
  //
  gBS->SetWatchdogTimer (0, 0, 0, NULL);

  //
  // install our console logger.  This will keep a log of the output for back-browsing
  //
  Status = ConsoleLoggerInstall (ShellInfoObject.LogScreenCount, &ShellInfoObject.ConsoleInfo);
  if (!EFI_ERROR (Status)) {
    //
    // Enable the cursor to be visible
    //
    gST->ConOut->EnableCursor (gST->ConOut, TRUE);

    //
    // If supporting EFI 1.1 we need to install HII protocol
    // only do this if PcdShellRequireHiiPlatform == FALSE
    //
    // remove EFI_UNSUPPORTED check above when complete.
    /// @todo add support for Framework HII

    //
    // install our (solitary) HII package
    //
    ShellInfoObject.HiiHandle = HiiAddPackages (&gEfiCallerIdGuid, gImageHandle, ShellStrings, NULL);
    if (ShellInfoObject.HiiHandle == NULL) {
      if (PcdGetBool (PcdShellSupportFrameworkHii)) {
        /// @todo Add our package into Framework HII
      }

      if (ShellInfoObject.HiiHandle == NULL) {
        Status = EFI_NOT_STARTED;
        goto FreeResources;
      }
    }

    //
    // create and install the EfiShellParametersProtocol
    //
    Status = CreatePopulateInstallShellParametersProtocol (&ShellInfoObject.NewShellParametersProtocol, &ShellInfoObject.RootShellInstance);
    ASSERT_EFI_ERROR (Status);
    ASSERT (ShellInfoObject.NewShellParametersProtocol != NULL);

    //
    // create and install the EfiShellProtocol
    //
    Status = CreatePopulateInstallShellProtocol (&ShellInfoObject.NewEfiShellProtocol);
    ASSERT_EFI_ERROR (Status);
    ASSERT (ShellInfoObject.NewEfiShellProtocol != NULL);

    //
    // Now initialize the shell library (it requires Shell Parameters protocol)
    //
    Status = ShellInitialize ();
    ASSERT_EFI_ERROR (Status);

    Status = CommandInit ();
    ASSERT_EFI_ERROR (Status);

    Status = ShellInitEnvVarList ();

    //
    // Check the command line
    //
    Status = ProcessCommandLine ();
    if (EFI_ERROR (Status)) {
      goto FreeResources;
    }

    //
    // If shell support level is >= 1 create the mappings and paths
    //
    if (PcdGet8 (PcdShellSupportLevel) >= 1) {
      Status = ShellCommandCreateInitialMappingsAndPaths ();
    }

    //
    // Set the environment variable for nesting support
    //
    Size       = 0;
    TempString = NULL;
    if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {
      //
      // No change.  require nesting in Shell Protocol Execute()
      //
      StrnCatGrow (
        &TempString,
        &Size,
        L"False",
        0
        );
    } else {
      StrnCatGrow (
        &TempString,
        &Size,
        mNoNestingTrue,
        0
        );
    }

    Status = InternalEfiShellSetEnv (mNoNestingEnvVarName, TempString, TRUE);
    SHELL_FREE_NON_NULL (TempString);
    Size = 0;

    //
    // save the device path for the loaded image and the device path for the filepath (under loaded image)
    // These are where to look for the startup.nsh file
    //
    Status = GetDevicePathsForImageAndFile (&ShellInfoObject.ImageDevPath, &ShellInfoObject.FileDevPath);
    ASSERT_EFI_ERROR (Status);

    //
    // Display the version
    //
    if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion) {
      ShellPrintHiiEx (
        0,
        gST->ConOut->Mode->CursorRow,
        NULL,
        STRING_TOKEN (STR_VER_OUTPUT_MAIN_SHELL),
        ShellInfoObject.HiiHandle,
        SupportLevel[PcdGet8 (PcdShellSupportLevel)],
        gEfiShellProtocol->MajorVersion,
        gEfiShellProtocol->MinorVersion
        );

      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_VER_OUTPUT_MAIN_SUPPLIER),
        ShellInfoObject.HiiHandle,
        (CHAR16 *)PcdGetPtr (PcdShellSupplier)
        );

      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_VER_OUTPUT_MAIN_UEFI),
        ShellInfoObject.HiiHandle,
        (gST->Hdr.Revision&0xffff0000)>>16,
        (gST->Hdr.Revision&0x0000ffff),
        gST->FirmwareVendor,
        gST->FirmwareRevision
        );
    }

    //
    // Display the mapping
    //
    if ((PcdGet8 (PcdShellSupportLevel) >= 2) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap) {
      Status = RunCommand (L"map");
      ASSERT_EFI_ERROR (Status);
    }

    //
    // init all the built in alias'
    //
    Status = SetBuiltInAlias ();
    ASSERT_EFI_ERROR (Status);

    //
    // Initialize environment variables
    //
    if (ShellCommandGetProfileList () != NULL) {
      Status = InternalEfiShellSetEnv (L"profiles", ShellCommandGetProfileList (), TRUE);
      ASSERT_EFI_ERROR (Status);
    }

    Size       = 100;
    TempString = AllocateZeroPool (Size);

    UnicodeSPrint (TempString, Size, L"%d", PcdGet8 (PcdShellSupportLevel));
    Status = InternalEfiShellSetEnv (L"uefishellsupport", TempString, TRUE);
    ASSERT_EFI_ERROR (Status);

    UnicodeSPrint (TempString, Size, L"%d.%d", ShellInfoObject.NewEfiShellProtocol->MajorVersion, ShellInfoObject.NewEfiShellProtocol->MinorVersion);
    Status = InternalEfiShellSetEnv (L"uefishellversion", TempString, TRUE);
    ASSERT_EFI_ERROR (Status);

    UnicodeSPrint (TempString, Size, L"%d.%d", (gST->Hdr.Revision & 0xFFFF0000) >> 16, gST->Hdr.Revision & 0x0000FFFF);
    Status = InternalEfiShellSetEnv (L"uefiversion", TempString, TRUE);
    ASSERT_EFI_ERROR (Status);

    FreePool (TempString);

    if (!EFI_ERROR (Status)) {
      if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt) {
        //
        // Set up the event for CTRL-C monitoring...
        //
        Status = InernalEfiShellStartMonitor ();
      }

      if (!EFI_ERROR (Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
        //
        // Set up the event for CTRL-S monitoring...
        //
        Status = InternalEfiShellStartCtrlSMonitor ();
      }

      if (!EFI_ERROR (Status) && ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
        //
        // close off the gST->ConIn
        //
        OldConIn    = gST->ConIn;
        ConInHandle = gST->ConsoleInHandle;
        gST->ConIn  = CreateSimpleTextInOnFile ((SHELL_FILE_HANDLE)&FileInterfaceNulFile, &gST->ConsoleInHandle);
      } else {
        OldConIn    = NULL;
        ConInHandle = NULL;
      }

      if (!EFI_ERROR (Status) && (PcdGet8 (PcdShellSupportLevel) >= 1)) {
        //
        // process the startup script or launch the called app.
        //
        Status = DoStartupScript (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
      }

      if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit && !ShellCommandGetExit () && ((PcdGet8 (PcdShellSupportLevel) >= 3) || PcdGetBool (PcdShellForceConsole)) && !EFI_ERROR (Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
        //
        // begin the UI waiting loop
        //
        do {
          //
          // clean out all the memory allocated for CONST <something> * return values
          // between each shell prompt presentation
          //
          if (!IsListEmpty (&ShellInfoObject.BufferToFreeList.Link)) {
            FreeBufferList (&ShellInfoObject.BufferToFreeList);
          }

          //
          // Reset page break back to default.
          //
          ShellInfoObject.PageBreakEnabled = PcdGetBool (PcdShellPageBreakDefault);
          ASSERT (ShellInfoObject.ConsoleInfo != NULL);
          ShellInfoObject.ConsoleInfo->Enabled    = TRUE;
          ShellInfoObject.ConsoleInfo->RowCounter = 0;

          //
          // Display Prompt
          //
          Status = DoShellPrompt ();
        } while (!ShellCommandGetExit ());
      }

      if ((OldConIn != NULL) && (ConInHandle != NULL)) {
        CloseSimpleTextInOnFile (gST->ConIn);
        gST->ConIn           = OldConIn;
        gST->ConsoleInHandle = ConInHandle;
      }
    }
  }

FreeResources:
  //
  // uninstall protocols / free memory / etc...
  //
  if (ShellInfoObject.UserBreakTimer != NULL) {
    gBS->CloseEvent (ShellInfoObject.UserBreakTimer);
    DEBUG_CODE (
      ShellInfoObject.UserBreakTimer = NULL;
      );
  }

  if (ShellInfoObject.ImageDevPath != NULL) {
    FreePool (ShellInfoObject.ImageDevPath);
    DEBUG_CODE (
      ShellInfoObject.ImageDevPath = NULL;
      );
  }

  if (ShellInfoObject.FileDevPath != NULL) {
    FreePool (ShellInfoObject.FileDevPath);
    DEBUG_CODE (
      ShellInfoObject.FileDevPath = NULL;
      );
  }

  if (ShellInfoObject.NewShellParametersProtocol != NULL) {
    CleanUpShellParametersProtocol (ShellInfoObject.NewShellParametersProtocol);
    DEBUG_CODE (
      ShellInfoObject.NewShellParametersProtocol = NULL;
      );
  }

  if (ShellInfoObject.NewEfiShellProtocol != NULL) {
    if (ShellInfoObject.NewEfiShellProtocol->IsRootShell ()) {
      InternalEfiShellSetEnv (L"cwd", NULL, TRUE);
    }

    CleanUpShellEnvironment (ShellInfoObject.NewEfiShellProtocol);
    DEBUG_CODE (
      ShellInfoObject.NewEfiShellProtocol = NULL;
      );
  }

  if (!IsListEmpty (&ShellInfoObject.BufferToFreeList.Link)) {
    FreeBufferList (&ShellInfoObject.BufferToFreeList);
  }

  if (!IsListEmpty (&ShellInfoObject.SplitList.Link)) {
    ASSERT (FALSE); /// @todo finish this de-allocation (free SplitStdIn/Out when needed).

    for ( Split = (SPLIT_LIST *)GetFirstNode (&ShellInfoObject.SplitList.Link)
          ; !IsNull (&ShellInfoObject.SplitList.Link, &Split->Link)
          ; Split = (SPLIT_LIST *)GetNextNode (&ShellInfoObject.SplitList.Link, &Split->Link)
          )
    {
      RemoveEntryList (&Split->Link);
      FreePool (Split);
    }

    DEBUG_CODE (
      InitializeListHead (&ShellInfoObject.SplitList.Link);
      );
  }

  if (ShellInfoObject.ShellInitSettings.FileName != NULL) {
    FreePool (ShellInfoObject.ShellInitSettings.FileName);
    DEBUG_CODE (
      ShellInfoObject.ShellInitSettings.FileName = NULL;
      );
  }

  if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
    FreePool (ShellInfoObject.ShellInitSettings.FileOptions);
    DEBUG_CODE (
      ShellInfoObject.ShellInitSettings.FileOptions = NULL;
      );
  }

  if (ShellInfoObject.HiiHandle != NULL) {
    HiiRemovePackages (ShellInfoObject.HiiHandle);
    DEBUG_CODE (
      ShellInfoObject.HiiHandle = NULL;
      );
  }

  if (!IsListEmpty (&ShellInfoObject.ViewingSettings.CommandHistory.Link)) {
    FreeBufferList (&ShellInfoObject.ViewingSettings.CommandHistory);
  }

  ASSERT (ShellInfoObject.ConsoleInfo != NULL);
  if (ShellInfoObject.ConsoleInfo != NULL) {
    ConsoleLoggerUninstall (ShellInfoObject.ConsoleInfo);
    FreePool (ShellInfoObject.ConsoleInfo);
    DEBUG_CODE (
      ShellInfoObject.ConsoleInfo = NULL;
      );
  }

  ShellFreeEnvVarList ();

  if (ShellCommandGetExit ()) {
    return ((EFI_STATUS)ShellCommandGetExitCode ());
  }

  return (Status);
}

/**
  Sets all the alias' that were registered with the ShellCommandLib library.

  @retval EFI_SUCCESS           all init commands were run successfully.
**/
EFI_STATUS
SetBuiltInAlias (
  VOID
  )
{
  EFI_STATUS        Status;
  CONST ALIAS_LIST  *List;
  ALIAS_LIST        *Node;

  //
  // Get all the commands we want to run
  //
  List = ShellCommandGetInitAliasList ();

  //
  // for each command in the List
  //
  for ( Node = (ALIAS_LIST *)GetFirstNode (&List->Link)
        ; !IsNull (&List->Link, &Node->Link)
        ; Node = (ALIAS_LIST *)GetNextNode (&List->Link, &Node->Link)
        )
  {
    //
    // install the alias'
    //
    Status = InternalSetAlias (Node->CommandString, Node->Alias, TRUE);
    ASSERT_EFI_ERROR (Status);
  }

  return (EFI_SUCCESS);
}

/**
  Internal function to determine if 2 command names are really the same.

  @param[in] Command1       The pointer to the first command name.
  @param[in] Command2       The pointer to the second command name.

  @retval TRUE              The 2 command names are the same.
  @retval FALSE             The 2 command names are not the same.
**/
BOOLEAN
IsCommand (
  IN CONST CHAR16  *Command1,
  IN CONST CHAR16  *Command2
  )
{
  if (StringNoCaseCompare (&Command1, &Command2) == 0) {
    return (TRUE);
  }

  return (FALSE);
}

/**
  Internal function to determine if a command is a script only command.

  @param[in] CommandName    The pointer to the command name.

  @retval TRUE              The command is a script only command.
  @retval FALSE             The command is not a script only command.
**/
BOOLEAN
IsScriptOnlyCommand (
  IN CONST CHAR16  *CommandName
  )
{
  if (  IsCommand (CommandName, L"for")
     || IsCommand (CommandName, L"endfor")
     || IsCommand (CommandName, L"if")
     || IsCommand (CommandName, L"else")
     || IsCommand (CommandName, L"endif")
     || IsCommand (CommandName, L"goto"))
  {
    return (TRUE);
  }

  return (FALSE);
}

/**
  This function will populate the 2 device path protocol parameters based on the
  global gImageHandle.  The DevPath will point to the device path for the handle that has
  loaded image protocol installed on it.  The FilePath will point to the device path
  for the file that was loaded.

  @param[in, out] DevPath       On a successful return the device path to the loaded image.
  @param[in, out] FilePath      On a successful return the device path to the file.

  @retval EFI_SUCCESS           The 2 device paths were successfully returned.
  @retval other                 A error from gBS->HandleProtocol.

  @sa HandleProtocol
**/
EFI_STATUS
GetDevicePathsForImageAndFile (
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevPath,
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **FilePath
  )
{
  EFI_STATUS                 Status;
  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL   *ImageDevicePath;

  ASSERT (DevPath  != NULL);
  ASSERT (FilePath != NULL);

  Status = gBS->OpenProtocol (
                  gImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&LoadedImage,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    LoadedImage->DeviceHandle,
                    &gEfiDevicePathProtocolGuid,
                    (VOID **)&ImageDevicePath,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      *DevPath  = DuplicateDevicePath (ImageDevicePath);
      *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
      gBS->CloseProtocol (
             LoadedImage->DeviceHandle,
             &gEfiDevicePathProtocolGuid,
             gImageHandle,
             NULL
             );
    }

    gBS->CloseProtocol (
           gImageHandle,
           &gEfiLoadedImageProtocolGuid,
           gImageHandle,
           NULL
           );
  }

  return (Status);
}

/**
  Process all Uefi Shell 2.0 command line options.

  see Uefi Shell 2.0 section 3.2 for full details.

  the command line must resemble the following:

  shell.efi [ShellOpt-options] [options] [file-name [file-name-options]]

  ShellOpt-options  Options which control the initialization behavior of the shell.
                    These options are read from the EFI global variable "ShellOpt"
                    and are processed before options or file-name.

  options           Options which control the initialization behavior of the shell.

  file-name         The name of a UEFI shell application or script to be executed
                    after initialization is complete. By default, if file-name is
                    specified, then -nostartup is implied. Scripts are not supported
                    by level 0.

  file-name-options The command-line options that are passed to file-name when it
                    is invoked.

  This will initialize the ShellInfoObject.ShellInitSettings global variable.

  @retval EFI_SUCCESS           The variable is initialized.
**/
EFI_STATUS
ProcessCommandLine (
  VOID
  )
{
  UINTN                           Size;
  UINTN                           LoopVar;
  CHAR16                          *CurrentArg;
  CHAR16                          *DelayValueStr;
  UINT64                          DelayValue;
  EFI_STATUS                      Status;
  EFI_UNICODE_COLLATION_PROTOCOL  *UnicodeCollation;

  // `file-name-options` will contain arguments to `file-name` that we don't
  // know about. This would cause ShellCommandLineParse to error, so we parse
  // arguments manually, ignoring those after the first thing that doesn't look
  // like a shell option (which is assumed to be `file-name`).

  Status = gBS->LocateProtocol (
                  &gEfiUnicodeCollation2ProtocolGuid,
                  NULL,
                  (VOID **)&UnicodeCollation
                  );
  if (EFI_ERROR (Status)) {
    Status = gBS->LocateProtocol (
                    &gEfiUnicodeCollationProtocolGuid,
                    NULL,
                    (VOID **)&UnicodeCollation
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  // Set default options
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup      = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup    = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn  = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt  = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap        = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion    = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay        = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit         = FALSE;
  ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest       = FALSE;
  ShellInfoObject.ShellInitSettings.Delay                      = 5;

  //
  // Start LoopVar at 0 to parse only optional arguments at Argv[0]
  // and parse other parameters from Argv[1].  This is for use case that
  // UEFI Shell boot option is created, and OptionalData is provided
  // that starts with shell command-line options.
  //
  for (LoopVar = 0; LoopVar < gEfiShellParametersProtocol->Argc; LoopVar++) {
    CurrentArg = gEfiShellParametersProtocol->Argv[LoopVar];
    if (UnicodeCollation->StriColl (
                            UnicodeCollation,
                            L"-startup",
                            CurrentArg
                            ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-nostartup",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-noconsoleout",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-noconsolein",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-nointerrupt",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-nomap",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-noversion",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-nonest",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest = TRUE;
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-delay",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = TRUE;
      // Check for optional delay value following "-delay"
      if ((LoopVar + 1) >= gEfiShellParametersProtocol->Argc) {
        DelayValueStr = NULL;
      } else {
        DelayValueStr = gEfiShellParametersProtocol->Argv[LoopVar + 1];
      }

      if (DelayValueStr != NULL) {
        if (*DelayValueStr == L':') {
          DelayValueStr++;
        }

        if (!EFI_ERROR (
               ShellConvertStringToUint64 (
                 DelayValueStr,
                 &DelayValue,
                 FALSE,
                 FALSE
                 )
               ))
        {
          ShellInfoObject.ShellInitSettings.Delay = (UINTN)DelayValue;
          LoopVar++;
        }
      }
    } else if (UnicodeCollation->StriColl (
                                   UnicodeCollation,
                                   L"-exit",
                                   CurrentArg
                                   ) == 0)
    {
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = TRUE;
    } else if (StrnCmp (L"-", CurrentArg, 1) == 0) {
      // Unrecognized option
      ShellPrintHiiEx (
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_GEN_PROBLEM),
        ShellInfoObject.HiiHandle,
        CurrentArg
        );
      return EFI_INVALID_PARAMETER;
    } else {
      //
      // First argument should be Shell.efi image name
      //
      if (LoopVar == 0) {
        continue;
      }

      ShellInfoObject.ShellInitSettings.FileName = NULL;
      Size                                       = 0;
      //
      // If first argument contains a space, then add double quotes before the argument
      //
      if (StrStr (CurrentArg, L" ") != NULL) {
        StrnCatGrow (&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);
        if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
          return (EFI_OUT_OF_RESOURCES);
        }
      }

      StrnCatGrow (&ShellInfoObject.ShellInitSettings.FileName, &Size, CurrentArg, 0);
      if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
        return (EFI_OUT_OF_RESOURCES);
      }

      //
      // If first argument contains a space, then add double quotes after the argument
      //
      if (StrStr (CurrentArg, L" ") != NULL) {
        StrnCatGrow (&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);
        if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
          return (EFI_OUT_OF_RESOURCES);
        }
      }

      //
      // We found `file-name`.
      //
      ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
      LoopVar++;

      // Add `file-name-options`
      for (Size = 0; LoopVar < gEfiShellParametersProtocol->Argc; LoopVar++) {
        ASSERT ((ShellInfoObject.ShellInitSettings.FileOptions == NULL && Size == 0) || (ShellInfoObject.ShellInitSettings.FileOptions != NULL));
        //
        // Add a space between arguments
        //
        if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
          StrnCatGrow (&ShellInfoObject.ShellInitSettings.FileOptions, &Size, L" ", 0);
          if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
            SHELL_FREE_NON_NULL (ShellInfoObject.ShellInitSettings.FileName);
            return (EFI_OUT_OF_RESOURCES);
          }
        }

        //
        // If an argument contains a space, then add double quotes before the argument
        //
        if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {
          StrnCatGrow (
            &ShellInfoObject.ShellInitSettings.FileOptions,
            &Size,
            L"\"",
            0
            );
          if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
            SHELL_FREE_NON_NULL (ShellInfoObject.ShellInitSettings.FileName);
            return (EFI_OUT_OF_RESOURCES);
          }
        }

        StrnCatGrow (
          &ShellInfoObject.ShellInitSettings.FileOptions,
          &Size,
          gEfiShellParametersProtocol->Argv[LoopVar],
          0
          );
        if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
          SHELL_FREE_NON_NULL (ShellInfoObject.ShellInitSettings.FileName);
          return (EFI_OUT_OF_RESOURCES);
        }

        //
        // If an argument contains a space, then add double quotes after the argument
        //
        if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {
          StrnCatGrow (
            &ShellInfoObject.ShellInitSettings.FileOptions,
            &Size,
            L"\"",
            0
            );
          if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
            SHELL_FREE_NON_NULL (ShellInfoObject.ShellInitSettings.FileName);
            return (EFI_OUT_OF_RESOURCES);
          }
        }
      }
    }
  }

  // "-nointerrupt" overrides "-delay"
  if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt) {
    ShellInfoObject.ShellInitSettings.Delay = 0;
  }

  return EFI_SUCCESS;
}

/**
  Function try to find location of the Startup.nsh file.

  The buffer is callee allocated and should be freed by the caller.

  @param    ImageDevicePath       The path to the image for shell.  first place to look for the startup script
  @param    FileDevicePath        The path to the file for shell.  second place to look for the startup script.

  @retval   NULL                  No Startup.nsh file was found.
  @return   !=NULL                Pointer to NULL-terminated path.
**/
CHAR16 *
LocateStartupScript (
  IN EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath,
  IN EFI_DEVICE_PATH_PROTOCOL  *FileDevicePath
  )
{
  CHAR16        *StartupScriptPath;
  CHAR16        *TempSpot;
  CONST CHAR16  *MapName;
  UINTN         Size;

  StartupScriptPath = NULL;
  Size              = 0;

  //
  // Try to find 'Startup.nsh' in the directory where the shell itself was launched.
  //
  MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath (&ImageDevicePath);
  if (MapName != NULL) {
    StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, MapName, 0);
    if (StartupScriptPath == NULL) {
      //
      // Do not locate the startup script in sys path when out of resource.
      //
      return NULL;
    }

    TempSpot = StrStr (StartupScriptPath, L";");
    if (TempSpot != NULL) {
      *TempSpot = CHAR_NULL;
    }

    InternalEfiShellSetEnv (L"homefilesystem", StartupScriptPath, TRUE);

    StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, ((FILEPATH_DEVICE_PATH *)FileDevicePath)->PathName, 0);
    PathRemoveLastItem (StartupScriptPath);
    StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, mStartupScript, 0);
  }

  //
  // Try to find 'Startup.nsh' in the execution path defined by the environment variable PATH.
  //
  if ((StartupScriptPath == NULL) || EFI_ERROR (ShellIsFile (StartupScriptPath))) {
    SHELL_FREE_NON_NULL (StartupScriptPath);
    StartupScriptPath = ShellFindFilePath (mStartupScript);
  }

  return StartupScriptPath;
}

/**
  Handles all interaction with the default startup script.

  this will check that the correct command line parameters were passed, handle the delay, and then start running the script.

  @param ImagePath              the path to the image for shell.  first place to look for the startup script
  @param FilePath               the path to the file for shell.  second place to look for the startup script.

  @retval EFI_SUCCESS           the variable is initialized.
**/
EFI_STATUS
DoStartupScript (
  IN EFI_DEVICE_PATH_PROTOCOL  *ImagePath,
  IN EFI_DEVICE_PATH_PROTOCOL  *FilePath
  )
{
  EFI_STATUS     Status;
  EFI_STATUS     CalleeStatus;
  UINTN          Delay;
  EFI_INPUT_KEY  Key;
  CHAR16         *FileStringPath;
  CHAR16         *FullFileStringPath;
  UINTN          NewSize;

  Key.UnicodeChar = CHAR_NULL;
  Key.ScanCode    = 0;

  if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup && (ShellInfoObject.ShellInitSettings.FileName != NULL)) {
    //
    // launch something else instead
    //
    NewSize = StrSize (ShellInfoObject.ShellInitSettings.FileName);
    if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
      NewSize += StrSize (ShellInfoObject.ShellInitSettings.FileOptions) + sizeof (CHAR16);
    }

    FileStringPath = AllocateZeroPool (NewSize);
    if (FileStringPath == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }

    StrCpyS (FileStringPath, NewSize/sizeof (CHAR16), ShellInfoObject.ShellInitSettings.FileName);
    if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
      StrnCatS (FileStringPath, NewSize/sizeof (CHAR16), L" ", NewSize/sizeof (CHAR16) - StrLen (FileStringPath) -1);
      StrnCatS (FileStringPath, NewSize/sizeof (CHAR16), ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof (CHAR16) - StrLen (FileStringPath) -1);
    }

    Status = RunShellCommand (FileStringPath, &CalleeStatus);
    if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit == TRUE) {
      ShellCommandRegisterExit (gEfiShellProtocol->BatchIsActive (), (UINT64)CalleeStatus);
    }

    FreePool (FileStringPath);
    return (Status);
  }

  //
  // for shell level 0 we do no scripts
  // Without the Startup bit overriding we allow for nostartup to prevent scripts
  //
  if (  (PcdGet8 (PcdShellSupportLevel) < 1)
     || (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup)
        )
  {
    return (EFI_SUCCESS);
  }

  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
  //
  // print out our warning and see if they press a key
  //
  for ( Status = EFI_UNSUPPORTED, Delay = ShellInfoObject.ShellInitSettings.Delay
        ; Delay != 0 && EFI_ERROR (Status)
        ; Delay--
        )
  {
    ShellPrintHiiEx (0, gST->ConOut->Mode->CursorRow, NULL, STRING_TOKEN (STR_SHELL_STARTUP_QUESTION), ShellInfoObject.HiiHandle, Delay);
    gBS->Stall (1000000);
    if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    }
  }

  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_CRLF), ShellInfoObject.HiiHandle);
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  //
  // ESC was pressed
  //
  if ((Status == EFI_SUCCESS) && (Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_ESC)) {
    return (EFI_SUCCESS);
  }

  FileStringPath = LocateStartupScript (ImagePath, FilePath);
  if (FileStringPath != NULL) {
    FullFileStringPath = FullyQualifyPath (FileStringPath);
    if (FullFileStringPath == NULL) {
      Status = RunScriptFile (FileStringPath, NULL, FileStringPath, ShellInfoObject.NewShellParametersProtocol);
    } else {
      Status = RunScriptFile (FullFileStringPath, NULL, FullFileStringPath, ShellInfoObject.NewShellParametersProtocol);
      FreePool (FullFileStringPath);
    }

    FreePool (FileStringPath);
  } else {
    //
    // we return success since startup script is not mandatory.
    //
    Status = EFI_SUCCESS;
  }

  return (Status);
}

/**
  Function to perform the shell prompt looping.  It will do a single prompt,
  dispatch the result, and then return.  It is expected that the caller will
  call this function in a loop many times.

  @retval EFI_SUCCESS
  @retval RETURN_ABORTED
**/
EFI_STATUS
DoShellPrompt (
  VOID
  )
{
  UINTN         Column;
  UINTN         Row;
  CHAR16        *CmdLine;
  CONST CHAR16  *CurDir;
  UINTN         BufferSize;
  EFI_STATUS    Status;
  LIST_ENTRY    OldBufferList;

  CurDir = NULL;

  //
  // Get screen setting to decide size of the command line buffer
  //
  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Column, &Row);
  BufferSize = Column * Row * sizeof (CHAR16);
  CmdLine    = AllocateZeroPool (BufferSize);
  if (CmdLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  SaveBufferList (&OldBufferList);
  CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv (L"cwd");

  //
  // Prompt for input
  //
  gST->ConOut->SetCursorPosition (gST->ConOut, 0, gST->ConOut->Mode->CursorRow);

  if ((CurDir != NULL) && (StrLen (CurDir) > 1)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);
  } else {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);
  }

  //
  // Read a line from the console
  //
  Status = ShellInfoObject.NewEfiShellProtocol->ReadFile (ShellInfoObject.NewShellParametersProtocol->StdIn, &BufferSize, CmdLine);

  //
  // Null terminate the string and parse it
  //
  if (!EFI_ERROR (Status)) {
    //
    // Reset the CTRL-C event just before running the command (yes we ignore the return values)
    //
    Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);

    CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
    Status                                = RunCommand (CmdLine);
  }

  //
  // Done with this command
  //
  RestoreBufferList (&OldBufferList);
  FreePool (CmdLine);
  return Status;
}

/**
  Add a buffer to the Buffer To Free List for safely returning buffers to other
  places without risking letting them modify internal shell information.

  @param Buffer   Something to pass to FreePool when the shell is exiting.
**/
VOID *
AddBufferToFreeList (
  VOID  *Buffer
  )
{
  BUFFER_LIST  *BufferListEntry;

  if (Buffer == NULL) {
    return (NULL);
  }

  BufferListEntry = AllocateZeroPool (sizeof (BUFFER_LIST));
  if (BufferListEntry == NULL) {
    return NULL;
  }

  BufferListEntry->Buffer = Buffer;
  InsertTailList (&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);
  return (Buffer);
}

/**
  Create a new buffer list and stores the old one to OldBufferList

  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
**/
VOID
SaveBufferList (
  OUT LIST_ENTRY  *OldBufferList
  )
{
  CopyMem (OldBufferList, &ShellInfoObject.BufferToFreeList.Link, sizeof (LIST_ENTRY));
  InitializeListHead (&ShellInfoObject.BufferToFreeList.Link);
}

/**
  Restore previous nodes into BufferToFreeList .

  @param OldBufferList   The temporary list head used to store the nodes in BufferToFreeList.
**/
VOID
RestoreBufferList (
  IN OUT LIST_ENTRY  *OldBufferList
  )
{
  FreeBufferList (&ShellInfoObject.BufferToFreeList);
  CopyMem (&ShellInfoObject.BufferToFreeList.Link, OldBufferList, sizeof (LIST_ENTRY));
}

/**
  Add a buffer to the Line History List

  @param Buffer     The line buffer to add.
**/
VOID
AddLineToCommandHistory (
  IN CONST CHAR16  *Buffer
  )
{
  BUFFER_LIST  *Node;
  BUFFER_LIST  *Walker;
  UINT16       MaxHistoryCmdCount;
  UINT16       Count;

  Count              = 0;
  MaxHistoryCmdCount = PcdGet16 (PcdShellMaxHistoryCommandCount);

  if (MaxHistoryCmdCount == 0) {
    return;
  }

  Node = AllocateZeroPool (sizeof (BUFFER_LIST));
  if (Node == NULL) {
    return;
  }

  Node->Buffer = AllocateCopyPool (StrSize (Buffer), Buffer);
  if (Node->Buffer == NULL) {
    FreePool (Node);
    return;
  }

  for ( Walker = (BUFFER_LIST *)GetFirstNode (&ShellInfoObject.ViewingSettings.CommandHistory.Link)
        ; !IsNull (&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)
        ; Walker = (BUFFER_LIST *)GetNextNode (&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)
        )
  {
    Count++;
  }

  if (Count < MaxHistoryCmdCount) {
    InsertTailList (&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
  } else {
    Walker = (BUFFER_LIST *)GetFirstNode (&ShellInfoObject.ViewingSettings.CommandHistory.Link);
    RemoveEntryList (&Walker->Link);
    if (Walker->Buffer != NULL) {
      FreePool (Walker->Buffer);
    }

    FreePool (Walker);
    InsertTailList (&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
  }
}

/**
  Checks if a string is an alias for another command.  If yes, then it replaces the alias name
  with the correct command name.

  @param[in, out] CommandString    Upon entry the potential alias.  Upon return the
                                   command name if it was an alias.  If it was not
                                   an alias it will be unchanged.  This function may
                                   change the buffer to fit the command name.

  @retval EFI_SUCCESS             The name was changed.
  @retval EFI_SUCCESS             The name was not an alias.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
ShellConvertAlias (
  IN OUT CHAR16  **CommandString
  )
{
  CONST CHAR16  *NewString;

  NewString = ShellInfoObject.NewEfiShellProtocol->GetAlias (*CommandString, NULL);
  if (NewString == NULL) {
    return (EFI_SUCCESS);
  }

  FreePool (*CommandString);
  *CommandString = AllocateCopyPool (StrSize (NewString), NewString);
  if (*CommandString == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  return (EFI_SUCCESS);
}

/**
  This function will eliminate unreplaced (and therefore non-found) environment variables.

  @param[in,out] CmdLine   The command line to update.
**/
EFI_STATUS
StripUnreplacedEnvironmentVariables (
  IN OUT CHAR16  *CmdLine
  )
{
  CHAR16  *FirstPercent;
  CHAR16  *FirstQuote;
  CHAR16  *SecondPercent;
  CHAR16  *SecondQuote;
  CHAR16  *CurrentLocator;

  for (CurrentLocator = CmdLine; CurrentLocator != NULL; ) {
    FirstQuote    = FindNextInstance (CurrentLocator, L"\"", TRUE);
    FirstPercent  = FindNextInstance (CurrentLocator, L"%", TRUE);
    SecondPercent = FirstPercent != NULL ? FindNextInstance (FirstPercent+1, L"%", TRUE) : NULL;
    if ((FirstPercent == NULL) || (SecondPercent == NULL)) {
      //
      // If we ever don't have 2 % we are done.
      //
      break;
    }

    if ((FirstQuote != NULL) && (FirstQuote < FirstPercent)) {
      SecondQuote = FindNextInstance (FirstQuote+1, L"\"", TRUE);
      //
      // Quote is first found
      //

      if (SecondQuote < FirstPercent) {
        //
        // restart after the pair of "
        //
        CurrentLocator = SecondQuote + 1;
      } else {
        /* FirstPercent < SecondQuote */
        //
        // Restart on the first percent
        //
        CurrentLocator = FirstPercent;
      }

      continue;
    }

    if ((FirstQuote == NULL) || (SecondPercent < FirstQuote)) {
      if (IsValidEnvironmentVariableName (FirstPercent, SecondPercent)) {
        //
        // We need to remove from FirstPercent to SecondPercent
        //
        CopyMem (FirstPercent, SecondPercent + 1, StrSize (SecondPercent + 1));
        //
        // don't need to update the locator.  both % characters are gone.
        //
      } else {
        CurrentLocator = SecondPercent + 1;
      }

      continue;
    }

    CurrentLocator = FirstQuote;
  }

  return (EFI_SUCCESS);
}

/**
  Function allocates a new command line and replaces all instances of environment
  variable names that are correctly preset to their values.

  If the return value is not NULL the memory must be caller freed.

  @param[in] OriginalCommandLine    The original command line

  @retval NULL                      An error occurred.
  @return                           The new command line with no environment variables present.
**/
CHAR16 *
ShellConvertVariables (
  IN CONST CHAR16  *OriginalCommandLine
  )
{
  CONST CHAR16  *MasterEnvList;
  UINTN         NewSize;
  CHAR16        *NewCommandLine1;
  CHAR16        *NewCommandLine2;
  CHAR16        *Temp;
  UINTN         ItemSize;
  CHAR16        *ItemTemp;
  SCRIPT_FILE   *CurrentScriptFile;
  ALIAS_LIST    *AliasListNode;

  ASSERT (OriginalCommandLine != NULL);

  ItemSize          = 0;
  NewSize           = StrSize (OriginalCommandLine);
  CurrentScriptFile = ShellCommandGetCurrentScriptFile ();
  Temp              = NULL;

  /// @todo update this to handle the %0 - %9 for scripting only (borrow from line 1256 area) ? ? ?

  //
  // calculate the size required for the post-conversion string...
  //
  if (CurrentScriptFile != NULL) {
    for (AliasListNode = (ALIAS_LIST *)GetFirstNode (&CurrentScriptFile->SubstList)
         ; !IsNull (&CurrentScriptFile->SubstList, &AliasListNode->Link)
         ; AliasListNode = (ALIAS_LIST *)GetNextNode (&CurrentScriptFile->SubstList, &AliasListNode->Link)
         )
    {
      for (Temp = StrStr (OriginalCommandLine, AliasListNode->Alias)
           ; Temp != NULL
           ; Temp = StrStr (Temp+1, AliasListNode->Alias)
           )
      {
        //
        // we need a preceding and if there is space no ^ preceding (if no space ignore)
        //
        if ((((Temp-OriginalCommandLine) > 2) && (*(Temp-2) != L'^')) || ((Temp-OriginalCommandLine) <= 2)) {
          NewSize += StrSize (AliasListNode->CommandString);
        }
      }
    }
  }

  for (MasterEnvList = EfiShellGetEnv (NULL)
       ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL // && *(MasterEnvList+1) != CHAR_NULL
       ; MasterEnvList += StrLen (MasterEnvList) + 1
       )
  {
    if (StrSize (MasterEnvList) > ItemSize) {
      ItemSize = StrSize (MasterEnvList);
    }

    for (Temp = StrStr (OriginalCommandLine, MasterEnvList)
         ; Temp != NULL
         ; Temp = StrStr (Temp+1, MasterEnvList)
         )
    {
      //
      // we need a preceding and following % and if there is space no ^ preceding (if no space ignore)
      //
      if ((*(Temp-1) == L'%') && (*(Temp+StrLen (MasterEnvList)) == L'%') &&
          ((((Temp-OriginalCommandLine) > 2) && (*(Temp-2) != L'^')) || ((Temp-OriginalCommandLine) <= 2)))
      {
        NewSize += StrSize (EfiShellGetEnv (MasterEnvList));
      }
    }
  }

  //
  // now do the replacements...
  //
  NewCommandLine1 = AllocateZeroPool (NewSize);
  NewCommandLine2 = AllocateZeroPool (NewSize);
  ItemTemp        = AllocateZeroPool (ItemSize+(2*sizeof (CHAR16)));
  if ((NewCommandLine1 == NULL) || (NewCommandLine2 == NULL) || (ItemTemp == NULL)) {
    SHELL_FREE_NON_NULL (NewCommandLine1);
    SHELL_FREE_NON_NULL (NewCommandLine2);
    SHELL_FREE_NON_NULL (ItemTemp);
    return (NULL);
  }

  CopyMem (NewCommandLine1, OriginalCommandLine, StrSize (OriginalCommandLine));

  for (MasterEnvList = EfiShellGetEnv (NULL)
       ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL
       ; MasterEnvList += StrLen (MasterEnvList) + 1
       )
  {
    StrCpyS (
      ItemTemp,
      ((ItemSize+(2*sizeof (CHAR16)))/sizeof (CHAR16)),
      L"%"
      );
    StrCatS (
      ItemTemp,
      ((ItemSize+(2*sizeof (CHAR16)))/sizeof (CHAR16)),
      MasterEnvList
      );
    StrCatS (
      ItemTemp,
      ((ItemSize+(2*sizeof (CHAR16)))/sizeof (CHAR16)),
      L"%"
      );
    ShellCopySearchAndReplace (NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv (MasterEnvList), TRUE, FALSE);
    StrCpyS (NewCommandLine1, NewSize/sizeof (CHAR16), NewCommandLine2);
  }

  if (CurrentScriptFile != NULL) {
    for (AliasListNode = (ALIAS_LIST *)GetFirstNode (&CurrentScriptFile->SubstList)
         ; !IsNull (&CurrentScriptFile->SubstList, &AliasListNode->Link)
         ; AliasListNode = (ALIAS_LIST *)GetNextNode (&CurrentScriptFile->SubstList, &AliasListNode->Link)
         )
    {
      ShellCopySearchAndReplace (NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);
      StrCpyS (NewCommandLine1, NewSize/sizeof (CHAR16), NewCommandLine2);
    }
  }

  //
  // Remove non-existent environment variables
  //
  StripUnreplacedEnvironmentVariables (NewCommandLine1);

  //
  // Now cleanup any straggler intentionally ignored "%" characters
  //
  ShellCopySearchAndReplace (NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);
  StrCpyS (NewCommandLine1, NewSize/sizeof (CHAR16), NewCommandLine2);

  FreePool (NewCommandLine2);
  FreePool (ItemTemp);

  return (NewCommandLine1);
}

/**
  Internal function to run a command line with pipe usage.

  @param[in] CmdLine        The pointer to the command line.
  @param[in] StdIn          The pointer to the Standard input.
  @param[in] StdOut         The pointer to the Standard output.

  @retval EFI_SUCCESS       The split command is executed successfully.
  @retval other             Some error occurs when executing the split command.
**/
EFI_STATUS
RunSplitCommand (
  IN CONST CHAR16             *CmdLine,
  IN       SHELL_FILE_HANDLE  StdIn,
  IN       SHELL_FILE_HANDLE  StdOut
  )
{
  EFI_STATUS         Status;
  CHAR16             *NextCommandLine;
  CHAR16             *OurCommandLine;
  UINTN              Size1;
  UINTN              Size2;
  SPLIT_LIST         *Split;
  SHELL_FILE_HANDLE  TempFileHandle;
  BOOLEAN            Unicode;

  ASSERT (StdOut == NULL);

  ASSERT (StrStr (CmdLine, L"|") != NULL);

  Status          = EFI_SUCCESS;
  NextCommandLine = NULL;
  OurCommandLine  = NULL;
  Size1           = 0;
  Size2           = 0;

  NextCommandLine = StrnCatGrow (&NextCommandLine, &Size1, StrStr (CmdLine, L"|")+1, 0);
  OurCommandLine  = StrnCatGrow (&OurCommandLine, &Size2, CmdLine, StrStr (CmdLine, L"|") - CmdLine);

  if ((NextCommandLine == NULL) || (OurCommandLine == NULL)) {
    SHELL_FREE_NON_NULL (OurCommandLine);
    SHELL_FREE_NON_NULL (NextCommandLine);
    return (EFI_OUT_OF_RESOURCES);
  } else if ((StrStr (OurCommandLine, L"|") != NULL) || (Size1 == 0) || (Size2 == 0)) {
    SHELL_FREE_NON_NULL (OurCommandLine);
    SHELL_FREE_NON_NULL (NextCommandLine);
    return (EFI_INVALID_PARAMETER);
  } else if ((NextCommandLine[0] == L'a') &&
             ((NextCommandLine[1] == L' ') || (NextCommandLine[1] == CHAR_NULL))
             )
  {
    CopyMem (NextCommandLine, NextCommandLine+1, StrSize (NextCommandLine) - sizeof (NextCommandLine[0]));
    while (NextCommandLine[0] == L' ') {
      CopyMem (NextCommandLine, NextCommandLine+1, StrSize (NextCommandLine) - sizeof (NextCommandLine[0]));
    }

    if (NextCommandLine[0] == CHAR_NULL) {
      SHELL_FREE_NON_NULL (OurCommandLine);
      SHELL_FREE_NON_NULL (NextCommandLine);
      return (EFI_INVALID_PARAMETER);
    }

    Unicode = FALSE;
  } else {
    Unicode = TRUE;
  }

  //
  // make a SPLIT_LIST item and add to list
  //
  Split = AllocateZeroPool (sizeof (SPLIT_LIST));
  if (Split == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Split->SplitStdIn  = StdIn;
  Split->SplitStdOut = ConvertEfiFileProtocolToShellHandle (CreateFileInterfaceMem (Unicode), NULL);
  ASSERT (Split->SplitStdOut != NULL);
  InsertHeadList (&ShellInfoObject.SplitList.Link, &Split->Link);

  Status = RunCommand (OurCommandLine);

  //
  // move the output from the first to the in to the second.
  //
  TempFileHandle = Split->SplitStdOut;
  if (Split->SplitStdIn == StdIn) {
    Split->SplitStdOut = NULL;
  } else {
    Split->SplitStdOut = Split->SplitStdIn;
  }

  Split->SplitStdIn = TempFileHandle;
  ShellInfoObject.NewEfiShellProtocol->SetFilePosition (Split->SplitStdIn, 0);

  if (!EFI_ERROR (Status)) {
    Status = RunCommand (NextCommandLine);
  }

  //
  // remove the top level from the ScriptList
  //
  ASSERT ((SPLIT_LIST *)GetFirstNode (&ShellInfoObject.SplitList.Link) == Split);
  RemoveEntryList (&Split->Link);

  //
  // Note that the original StdIn is now the StdOut...
  //
  if (Split->SplitStdOut != NULL) {
    ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);
  }

  if (Split->SplitStdIn != NULL) {
    ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);
  }

  FreePool (Split);
  FreePool (NextCommandLine);
  FreePool (OurCommandLine);

  return (Status);
}

/**
  Take the original command line, substitute any variables, free
  the original string, return the modified copy.

  @param[in] CmdLine  pointer to the command line to update.

  @retval EFI_SUCCESS           the function was successful.
  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
**/
EFI_STATUS
ShellSubstituteVariables (
  IN CHAR16  **CmdLine
  )
{
  CHAR16  *NewCmdLine;

  NewCmdLine = ShellConvertVariables (*CmdLine);
  SHELL_FREE_NON_NULL (*CmdLine);
  if (NewCmdLine == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  *CmdLine = NewCmdLine;
  return (EFI_SUCCESS);
}

/**
  Take the original command line, substitute any alias in the first group of space delimited characters, free
  the original string, return the modified copy.

  @param[in] CmdLine  pointer to the command line to update.

  @retval EFI_SUCCESS           the function was successful.
  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
**/
EFI_STATUS
ShellSubstituteAliases (
  IN CHAR16  **CmdLine
  )
{
  CHAR16      *NewCmdLine;
  CHAR16      *CommandName;
  EFI_STATUS  Status;
  UINTN       PostAliasSize;

  ASSERT (CmdLine != NULL);
  ASSERT (*CmdLine != NULL);

  CommandName = NULL;
  if (StrStr ((*CmdLine), L" ") == NULL) {
    StrnCatGrow (&CommandName, NULL, (*CmdLine), 0);
  } else {
    StrnCatGrow (&CommandName, NULL, (*CmdLine), StrStr ((*CmdLine), L" ") - (*CmdLine));
  }

  //
  // This cannot happen 'inline' since the CmdLine can need extra space.
  //
  NewCmdLine = NULL;
  if (!ShellCommandIsCommandOnList (CommandName)) {
    //
    // Convert via alias
    //
    Status = ShellConvertAlias (&CommandName);
    if (EFI_ERROR (Status)) {
      return (Status);
    }

    PostAliasSize = 0;
    NewCmdLine    = StrnCatGrow (&NewCmdLine, &PostAliasSize, CommandName, 0);
    if (NewCmdLine == NULL) {
      SHELL_FREE_NON_NULL (CommandName);
      SHELL_FREE_NON_NULL (*CmdLine);
      return (EFI_OUT_OF_RESOURCES);
    }

    NewCmdLine = StrnCatGrow (&NewCmdLine, &PostAliasSize, StrStr ((*CmdLine), L" "), 0);
    if (NewCmdLine == NULL) {
      SHELL_FREE_NON_NULL (CommandName);
      SHELL_FREE_NON_NULL (*CmdLine);
      return (EFI_OUT_OF_RESOURCES);
    }
  } else {
    NewCmdLine = StrnCatGrow (&NewCmdLine, NULL, (*CmdLine), 0);
  }

  SHELL_FREE_NON_NULL (*CmdLine);
  SHELL_FREE_NON_NULL (CommandName);

  //
  // re-assign the passed in double pointer to point to our newly allocated buffer
  //
  *CmdLine = NewCmdLine;

  return (EFI_SUCCESS);
}

/**
  Takes the Argv[0] part of the command line and determine the meaning of it.

  @param[in] CmdName  pointer to the command line to update.

  @retval Internal_Command    The name is an internal command.
  @retval File_Sys_Change     the name is a file system change.
  @retval Script_File_Name    the name is a NSH script file.
  @retval Unknown_Invalid     the name is unknown.
  @retval Efi_Application     the name is an application (.EFI).
**/
SHELL_OPERATION_TYPES
GetOperationType (
  IN CONST CHAR16  *CmdName
  )
{
  CHAR16        *FileWithPath;
  CONST CHAR16  *TempLocation;
  CONST CHAR16  *TempLocation2;

  FileWithPath = NULL;
  //
  // test for an internal command.
  //
  if (ShellCommandIsCommandOnList (CmdName)) {
    return (Internal_Command);
  }

  //
  // Test for file system change request.  anything ending with first : and cant have spaces.
  //
  if (CmdName[(StrLen (CmdName)-1)] == L':') {
    if (  (StrStr (CmdName, L" ") != NULL)
       || (StrLen (StrStr (CmdName, L":")) > 1)
          )
    {
      return (Unknown_Invalid);
    }

    return (File_Sys_Change);
  }

  //
  // Test for a file
  //
  if ((FileWithPath = ShellFindFilePathEx (CmdName, mExecutableExtensions)) != NULL) {
    //
    // See if that file has a script file extension
    //
    if (StrLen (FileWithPath) > 4) {
      TempLocation  = FileWithPath+StrLen (FileWithPath)-4;
      TempLocation2 = mScriptExtension;
      if (StringNoCaseCompare ((VOID *)(&TempLocation), (VOID *)(&TempLocation2)) == 0) {
        SHELL_FREE_NON_NULL (FileWithPath);
        return (Script_File_Name);
      }
    }

    //
    // Was a file, but not a script.  we treat this as an application.
    //
    SHELL_FREE_NON_NULL (FileWithPath);
    return (Efi_Application);
  }

  SHELL_FREE_NON_NULL (FileWithPath);
  //
  // No clue what this is... return invalid flag...
  //
  return (Unknown_Invalid);
}

/**
  Determine if the first item in a command line is valid.

  @param[in] CmdLine            The command line to parse.

  @retval EFI_SUCCESS           The item is valid.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_NOT_FOUND         The operation type is unknown or invalid.
**/
EFI_STATUS
IsValidSplit (
  IN CONST CHAR16  *CmdLine
  )
{
  CHAR16      *Temp;
  CHAR16      *FirstParameter;
  CHAR16      *TempWalker;
  EFI_STATUS  Status;

  Temp = NULL;

  Temp = StrnCatGrow (&Temp, NULL, CmdLine, 0);
  if (Temp == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  FirstParameter = StrStr (Temp, L"|");
  if (FirstParameter != NULL) {
    *FirstParameter = CHAR_NULL;
  }

  FirstParameter = NULL;

  //
  // Process the command line
  //
  Status = ProcessCommandLineToFinal (&Temp);

  if (!EFI_ERROR (Status)) {
    FirstParameter = AllocateZeroPool (StrSize (CmdLine));
    if (FirstParameter == NULL) {
      SHELL_FREE_NON_NULL (Temp);
      return (EFI_OUT_OF_RESOURCES);
    }

    TempWalker = (CHAR16 *)Temp;
    if (!EFI_ERROR (GetNextParameter (&TempWalker, &FirstParameter, StrSize (CmdLine), TRUE))) {
      if (GetOperationType (FirstParameter) == Unknown_Invalid) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
        SetLastError (SHELL_NOT_FOUND);
        Status = EFI_NOT_FOUND;
      }
    }
  }

  SHELL_FREE_NON_NULL (Temp);
  SHELL_FREE_NON_NULL (FirstParameter);
  return Status;
}

/**
  Determine if a command line contains with a split contains only valid commands.

  @param[in] CmdLine      The command line to parse.

  @retval EFI_SUCCESS     CmdLine has only valid commands, application, or has no split.
  @retval EFI_ABORTED     CmdLine has at least one invalid command or application.
**/
EFI_STATUS
VerifySplit (
  IN CONST CHAR16  *CmdLine
  )
{
  CONST CHAR16  *TempSpot;
  EFI_STATUS    Status;

  //
  // If this was the only item, then get out
  //
  if (!ContainsSplit (CmdLine)) {
    return (EFI_SUCCESS);
  }

  //
  // Verify up to the pipe or end character
  //
  Status = IsValidSplit (CmdLine);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  //
  // recurse to verify the next item
  //
  TempSpot = FindFirstCharacter (CmdLine, L"|", L'^') + 1;
  if ((*TempSpot == L'a') &&
      ((*(TempSpot + 1) == L' ') || (*(TempSpot + 1) == CHAR_NULL))
      )
  {
    // If it's an ASCII pipe '|a'
    TempSpot += 1;
  }

  return (VerifySplit (TempSpot));
}

/**
  Process a split based operation.

  @param[in] CmdLine    pointer to the command line to process

  @retval EFI_SUCCESS   The operation was successful
  @return               an error occurred.
**/
EFI_STATUS
ProcessNewSplitCommandLine (
  IN CONST CHAR16  *CmdLine
  )
{
  SPLIT_LIST  *Split;
  EFI_STATUS  Status;

  Status = VerifySplit (CmdLine);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  Split = NULL;

  //
  // are we in an existing split???
  //
  if (!IsListEmpty (&ShellInfoObject.SplitList.Link)) {
    Split = (SPLIT_LIST *)GetFirstNode (&ShellInfoObject.SplitList.Link);
  }

  if (Split == NULL) {
    Status = RunSplitCommand (CmdLine, NULL, NULL);
  } else {
    Status = RunSplitCommand (CmdLine, Split->SplitStdIn, Split->SplitStdOut);
  }

  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);
  }

  return (Status);
}

/**
  Handle a request to change the current file system.

  @param[in] CmdLine  The passed in command line.

  @retval EFI_SUCCESS The operation was successful.
**/
EFI_STATUS
ChangeMappedDrive (
  IN CONST CHAR16  *CmdLine
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  //
  // make sure we are the right operation
  //
  ASSERT (CmdLine[(StrLen (CmdLine)-1)] == L':' && StrStr (CmdLine, L" ") == NULL);

  //
  // Call the protocol API to do the work
  //
  Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir (NULL, CmdLine);

  //
  // Report any errors
  //
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, CmdLine);
  }

  return (Status);
}

/**
  Reprocess the command line to direct all -? to the help command.

  if found, will add "help" as argv[0], and move the rest later.

  @param[in,out] CmdLine        pointer to the command line to update
**/
EFI_STATUS
DoHelpUpdate (
  IN OUT CHAR16  **CmdLine
  )
{
  CHAR16      *CurrentParameter;
  CHAR16      *Walker;
  CHAR16      *NewCommandLine;
  EFI_STATUS  Status;
  UINTN       NewCmdLineSize;

  Status = EFI_SUCCESS;

  CurrentParameter = AllocateZeroPool (StrSize (*CmdLine));
  if (CurrentParameter == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  Walker = *CmdLine;
  while (Walker != NULL && *Walker != CHAR_NULL) {
    if (!EFI_ERROR (GetNextParameter (&Walker, &CurrentParameter, StrSize (*CmdLine), TRUE))) {
      if (StrStr (CurrentParameter, L"-?") == CurrentParameter) {
        CurrentParameter[0] = L' ';
        CurrentParameter[1] = L' ';
        NewCmdLineSize      = StrSize (L"help ") + StrSize (*CmdLine);
        NewCommandLine      = AllocateZeroPool (NewCmdLineSize);
        if (NewCommandLine == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }

        //
        // We know the space is sufficient since we just calculated it.
        //
        StrnCpyS (NewCommandLine, NewCmdLineSize/sizeof (CHAR16), L"help ", 5);
        StrnCatS (NewCommandLine, NewCmdLineSize/sizeof (CHAR16), *CmdLine, StrLen (*CmdLine));
        SHELL_FREE_NON_NULL (*CmdLine);
        *CmdLine = NewCommandLine;
        break;
      }
    }
  }

  SHELL_FREE_NON_NULL (CurrentParameter);

  return (Status);
}

/**
  Function to update the shell variable "lasterror".

  @param[in] ErrorCode      the error code to put into lasterror.
**/
EFI_STATUS
SetLastError (
  IN CONST SHELL_STATUS  ErrorCode
  )
{
  CHAR16  LeString[19];

  if (sizeof (EFI_STATUS) == sizeof (UINT64)) {
    UnicodeSPrint (LeString, sizeof (LeString), L"0x%Lx", ErrorCode);
  } else {
    UnicodeSPrint (LeString, sizeof (LeString), L"0x%x", ErrorCode);
  }

  DEBUG_CODE (
    InternalEfiShellSetEnv (L"debuglasterror", LeString, TRUE);
    );
  InternalEfiShellSetEnv (L"lasterror", LeString, TRUE);

  return (EFI_SUCCESS);
}

/**
  Converts the command line to its post-processed form.  this replaces variables and alias' per UEFI Shell spec.

  @param[in,out] CmdLine        pointer to the command line to update

  @retval EFI_SUCCESS           The operation was successful
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @return                       some other error occurred
**/
EFI_STATUS
ProcessCommandLineToFinal (
  IN OUT CHAR16  **CmdLine
  )
{
  EFI_STATUS  Status;

  TrimSpaces (CmdLine);

  Status = ShellSubstituteAliases (CmdLine);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  TrimSpaces (CmdLine);

  Status = ShellSubstituteVariables (CmdLine);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  ASSERT (*CmdLine != NULL);

  TrimSpaces (CmdLine);

  //
  // update for help parsing
  //
  if (StrStr (*CmdLine, L"?") != NULL) {
    //
    // This may do nothing if the ? does not indicate help.
    // Save all the details for in the API below.
    //
    Status = DoHelpUpdate (CmdLine);
  }

  TrimSpaces (CmdLine);

  return (EFI_SUCCESS);
}

/**
  Run an internal shell command.

  This API will update the shell's environment since these commands are libraries.

  @param[in] CmdLine          the command line to run.
  @param[in] FirstParameter   the first parameter on the command line
  @param[in] ParamProtocol    the shell parameters protocol pointer
  @param[out] CommandStatus   the status from the command line.

  @retval EFI_SUCCESS     The command was completed.
  @retval EFI_ABORTED     The command's operation was aborted.
**/
EFI_STATUS
RunInternalCommand (
  IN CONST CHAR16                   *CmdLine,
  IN       CHAR16                   *FirstParameter,
  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,
  OUT EFI_STATUS                    *CommandStatus
  )
{
  EFI_STATUS    Status;
  UINTN         Argc;
  CHAR16        **Argv;
  SHELL_STATUS  CommandReturnedStatus;
  BOOLEAN       LastError;
  CHAR16        *Walker;
  CHAR16        *NewCmdLine;

  NewCmdLine = AllocateCopyPool (StrSize (CmdLine), CmdLine);
  if (NewCmdLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
    if ((*Walker == L'^') && (*(Walker+1) == L'#')) {
      CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0]));
    }
  }

  //
  // get the argc and argv updated for internal commands
  //
  Status = UpdateArgcArgv (ParamProtocol, NewCmdLine, Internal_Command, &Argv, &Argc);
  if (!EFI_ERROR (Status)) {
    //
    // Run the internal command.
    //
    Status = ShellCommandRunCommandHandler (FirstParameter, &CommandReturnedStatus, &LastError);

    if (!EFI_ERROR (Status)) {
      if (CommandStatus != NULL) {
        if (CommandReturnedStatus != SHELL_SUCCESS) {
          *CommandStatus = (EFI_STATUS)(CommandReturnedStatus | MAX_BIT);
        } else {
          *CommandStatus = EFI_SUCCESS;
        }
      }

      //
      // Update last error status.
      // some commands do not update last error.
      //
      if (LastError) {
        SetLastError (CommandReturnedStatus);
      }

      //
      // Pass thru the exitcode from the app.
      //
      if (ShellCommandGetExit ()) {
        //
        // An Exit was requested ("exit" command), pass its value up.
        //
        Status = CommandReturnedStatus;
      } else if ((CommandReturnedStatus != SHELL_SUCCESS) && IsScriptOnlyCommand (FirstParameter)) {
        //
        // Always abort when a script only command fails for any reason
        //
        Status = EFI_ABORTED;
      } else if ((ShellCommandGetCurrentScriptFile () != NULL) && (CommandReturnedStatus == SHELL_ABORTED)) {
        //
        // Abort when in a script and a command aborted
        //
        Status = EFI_ABORTED;
      }
    }
  }

  //
  // This is guaranteed to be called after UpdateArgcArgv no matter what else happened.
  // This is safe even if the update API failed.  In this case, it may be a no-op.
  //
  RestoreArgcArgv (ParamProtocol, &Argv, &Argc);

  //
  // If a script is running and the command is not a script only command, then
  // change return value to success so the script won't halt (unless aborted).
  //
  // Script only commands have to be able halt the script since the script will
  // not operate if they are failing.
  //
  if (  (ShellCommandGetCurrentScriptFile () != NULL)
     && !IsScriptOnlyCommand (FirstParameter)
     && (Status != EFI_ABORTED)
        )
  {
    Status = EFI_SUCCESS;
  }

  FreePool (NewCmdLine);
  return (Status);
}

/**
  Function to run the command or file.

  @param[in] Type             the type of operation being run.
  @param[in] CmdLine          the command line to run.
  @param[in] FirstParameter   the first parameter on the command line
  @param[in] ParamProtocol    the shell parameters protocol pointer
  @param[out] CommandStatus   the status from the command line.

  @retval EFI_SUCCESS     The command was completed.
  @retval EFI_ABORTED     The command's operation was aborted.
**/
EFI_STATUS
RunCommandOrFile (
  IN       SHELL_OPERATION_TYPES    Type,
  IN CONST CHAR16                   *CmdLine,
  IN       CHAR16                   *FirstParameter,
  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,
  OUT EFI_STATUS                    *CommandStatus
  )
{
  EFI_STATUS                Status;
  EFI_STATUS                StartStatus;
  CHAR16                    *CommandWithPath;
  CHAR16                    *FullCommandWithPath;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  SHELL_STATUS              CalleeExitStatus;

  Status           = EFI_SUCCESS;
  CommandWithPath  = NULL;
  DevPath          = NULL;
  CalleeExitStatus = SHELL_INVALID_PARAMETER;

  switch (Type) {
    case Internal_Command:
      Status = RunInternalCommand (CmdLine, FirstParameter, ParamProtocol, CommandStatus);
      break;
    case Script_File_Name:
    case Efi_Application:
      //
      // Process a fully qualified path
      //
      if (StrStr (FirstParameter, L":") != NULL) {
        ASSERT (CommandWithPath == NULL);
        if (ShellIsFile (FirstParameter) == EFI_SUCCESS) {
          CommandWithPath = StrnCatGrow (&CommandWithPath, NULL, FirstParameter, 0);
        }
      }

      //
      // Process a relative path and also check in the path environment variable
      //
      if (CommandWithPath == NULL) {
        CommandWithPath = ShellFindFilePathEx (FirstParameter, mExecutableExtensions);
      }

      //
      // This should be impossible now.
      //
      ASSERT (CommandWithPath != NULL);

      //
      // Make sure that path is not just a directory (or not found)
      //
      if (!EFI_ERROR (ShellIsDirectory (CommandWithPath))) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
        SetLastError (SHELL_NOT_FOUND);
      }

      switch (Type) {
        case Script_File_Name:
          FullCommandWithPath = FullyQualifyPath (CommandWithPath);
          if (FullCommandWithPath == NULL) {
            Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);
          } else {
            Status = RunScriptFile (FullCommandWithPath, NULL, CmdLine, ParamProtocol);
            FreePool (FullCommandWithPath);
          }

          break;
        case Efi_Application:
          //
          // Get the device path of the application image
          //
          DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath (CommandWithPath);
          if (DevPath == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            break;
          }

          //
          // Execute the device path
          //
          Status = InternalShellExecuteDevicePath (
                     &gImageHandle,
                     DevPath,
                     CmdLine,
                     NULL,
                     &StartStatus
                     );

          SHELL_FREE_NON_NULL (DevPath);

          if (EFI_ERROR (Status)) {
            CalleeExitStatus = (SHELL_STATUS)(Status & (~MAX_BIT));
          } else {
            CalleeExitStatus = (SHELL_STATUS)StartStatus;
          }

          if (CommandStatus != NULL) {
            *CommandStatus = CalleeExitStatus;
          }

          //
          // Update last error status.
          //
          // Status is an EFI_STATUS. Clear top bit to convert to SHELL_STATUS
          SetLastError (CalleeExitStatus);
          break;
        default:
          //
          // Do nothing.
          //
          break;
      }

      break;
    default:
      //
      // Do nothing.
      //
      break;
  }

  SHELL_FREE_NON_NULL (CommandWithPath);

  return (Status);
}

/**
  Function to setup StdIn, StdErr, StdOut, and then run the command or file.

  @param[in] Type             the type of operation being run.
  @param[in] CmdLine          the command line to run.
  @param[in] FirstParameter   the first parameter on the command line.
  @param[in] ParamProtocol    the shell parameters protocol pointer
  @param[out] CommandStatus   the status from the command line.

  @retval EFI_SUCCESS     The command was completed.
  @retval EFI_ABORTED     The command's operation was aborted.
**/
EFI_STATUS
SetupAndRunCommandOrFile (
  IN   SHELL_OPERATION_TYPES          Type,
  IN   CHAR16                         *CmdLine,
  IN   CHAR16                         *FirstParameter,
  IN   EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol,
  OUT EFI_STATUS                      *CommandStatus
  )
{
  EFI_STATUS         Status;
  SHELL_FILE_HANDLE  OriginalStdIn;
  SHELL_FILE_HANDLE  OriginalStdOut;
  SHELL_FILE_HANDLE  OriginalStdErr;
  SYSTEM_TABLE_INFO  OriginalSystemTableInfo;
  CONST SCRIPT_FILE  *ConstScriptFile;

  //
  // Update the StdIn, StdOut, and StdErr for redirection to environment variables, files, etc... unicode and ASCII
  //
  Status = UpdateStdInStdOutStdErr (ParamProtocol, CmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);

  //
  // The StdIn, StdOut, and StdErr are set up.
  // Now run the command, script, or application
  //
  if (!EFI_ERROR (Status)) {
    TrimSpaces (&CmdLine);
    Status = RunCommandOrFile (Type, CmdLine, FirstParameter, ParamProtocol, CommandStatus);
  }

  //
  // Now print errors
  //
  if (EFI_ERROR (Status)) {
    ConstScriptFile = ShellCommandGetCurrentScriptFile ();
    if ((ConstScriptFile == NULL) || (ConstScriptFile->CurrentCommand == NULL)) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID *)(Status));
    } else {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR_SCRIPT), ShellInfoObject.HiiHandle, (VOID *)(Status), ConstScriptFile->CurrentCommand->Line);
    }
  }

  //
  // put back the original StdIn, StdOut, and StdErr
  //
  RestoreStdInStdOutStdErr (ParamProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);

  return (Status);
}

/**
  Function will process and run a command line.

  This will determine if the command line represents an internal shell
  command or dispatch an external application.

  @param[in] CmdLine      The command line to parse.
  @param[out] CommandStatus   The status from the command line.

  @retval EFI_SUCCESS     The command was completed.
  @retval EFI_ABORTED     The command's operation was aborted.
**/
EFI_STATUS
RunShellCommand (
  IN CONST CHAR16  *CmdLine,
  OUT EFI_STATUS   *CommandStatus
  )
{
  EFI_STATUS             Status;
  CHAR16                 *CleanOriginal;
  CHAR16                 *FirstParameter;
  CHAR16                 *TempWalker;
  SHELL_OPERATION_TYPES  Type;
  CONST CHAR16           *CurDir;

  ASSERT (CmdLine != NULL);
  if (StrLen (CmdLine) == 0) {
    return (EFI_SUCCESS);
  }

  Status        = EFI_SUCCESS;
  CleanOriginal = NULL;

  CleanOriginal = StrnCatGrow (&CleanOriginal, NULL, CmdLine, 0);
  if (CleanOriginal == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  TrimSpaces (&CleanOriginal);

  //
  // NULL out comments (leveraged from RunScriptFileHandle() ).
  // The # character on a line is used to denote that all characters on the same line
  // and to the right of the # are to be ignored by the shell.
  // Afterwards, again remove spaces, in case any were between the last command-parameter and '#'.
  //
  for (TempWalker = CleanOriginal; TempWalker != NULL && *TempWalker != CHAR_NULL; TempWalker++) {
    if (*TempWalker == L'^') {
      if (*(TempWalker + 1) == L'#') {
        TempWalker++;
      }
    } else if (*TempWalker == L'#') {
      *TempWalker = CHAR_NULL;
    }
  }

  TrimSpaces (&CleanOriginal);

  //
  // Handle case that passed in command line is just 1 or more " " characters.
  //
  if (StrLen (CleanOriginal) == 0) {
    SHELL_FREE_NON_NULL (CleanOriginal);
    return (EFI_SUCCESS);
  }

  Status = ProcessCommandLineToFinal (&CleanOriginal);
  if (EFI_ERROR (Status)) {
    SHELL_FREE_NON_NULL (CleanOriginal);
    return (Status);
  }

  //
  // We don't do normal processing with a split command line (output from one command input to another)
  //
  if (ContainsSplit (CleanOriginal)) {
    Status = ProcessNewSplitCommandLine (CleanOriginal);
    SHELL_FREE_NON_NULL (CleanOriginal);
    return (Status);
  }

  //
  // We need the first parameter information so we can determine the operation type
  //
  FirstParameter = AllocateZeroPool (StrSize (CleanOriginal));
  if (FirstParameter == NULL) {
    SHELL_FREE_NON_NULL (CleanOriginal);
    return (EFI_OUT_OF_RESOURCES);
  }

  TempWalker = CleanOriginal;
  if (!EFI_ERROR (GetNextParameter (&TempWalker, &FirstParameter, StrSize (CleanOriginal), TRUE))) {
    //
    // Depending on the first parameter we change the behavior
    //
    switch (Type = GetOperationType (FirstParameter)) {
      case File_Sys_Change:
        Status = ChangeMappedDrive (FirstParameter);
        break;
      case Internal_Command:
      case Script_File_Name:
      case Efi_Application:
        Status = SetupAndRunCommandOrFile (Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol, CommandStatus);
        break;
      default:
        //
        // Whatever was typed, it was invalid.
        //
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
        SetLastError (SHELL_NOT_FOUND);
        break;
    }
  } else {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
    SetLastError (SHELL_NOT_FOUND);
  }

  //
  // Check whether the current file system still exists. If not exist, we need update "cwd" and gShellCurMapping.
  //
  CurDir = EfiShellGetCurDir (NULL);
  if (CurDir != NULL) {
    if (EFI_ERROR (ShellFileExists (CurDir))) {
      //
      // EfiShellSetCurDir() cannot set current directory to NULL.
      // EfiShellSetEnv() is not allowed to set the "cwd" variable.
      // Only InternalEfiShellSetEnv () is allowed setting the "cwd" variable.
      //
      InternalEfiShellSetEnv (L"cwd", NULL, TRUE);
      gShellCurMapping = NULL;
    }
  }

  SHELL_FREE_NON_NULL (CleanOriginal);
  SHELL_FREE_NON_NULL (FirstParameter);

  return (Status);
}

/**
  Function will process and run a command line.

  This will determine if the command line represents an internal shell
  command or dispatch an external application.

  @param[in] CmdLine      The command line to parse.

  @retval EFI_SUCCESS     The command was completed.
  @retval EFI_ABORTED     The command's operation was aborted.
**/
EFI_STATUS
RunCommand (
  IN CONST CHAR16  *CmdLine
  )
{
  return (RunShellCommand (CmdLine, NULL));
}

/**
  Function to process a NSH script file via SHELL_FILE_HANDLE.

  @param[in] Handle             The handle to the already opened file.
  @param[in] Name               The name of the script file.

  @retval EFI_SUCCESS           the script completed successfully
**/
EFI_STATUS
RunScriptFileHandle (
  IN SHELL_FILE_HANDLE  Handle,
  IN CONST CHAR16       *Name
  )
{
  EFI_STATUS           Status;
  SCRIPT_FILE          *NewScriptFile;
  UINTN                LoopVar;
  UINTN                PrintBuffSize;
  CHAR16               *CommandLine;
  CHAR16               *CommandLine2;
  CHAR16               *CommandLine3;
  SCRIPT_COMMAND_LIST  *LastCommand;
  BOOLEAN              Ascii;
  BOOLEAN              PreScriptEchoState;
  BOOLEAN              PreCommandEchoState;
  CONST CHAR16         *CurDir;
  UINTN                LineCount;
  CHAR16               LeString[50];
  LIST_ENTRY           OldBufferList;

  ASSERT (!ShellCommandGetScriptExit ());

  PreScriptEchoState = ShellCommandGetEchoState ();
  PrintBuffSize      = PcdGet16 (PcdShellPrintBufferSize);

  NewScriptFile = (SCRIPT_FILE *)AllocateZeroPool (sizeof (SCRIPT_FILE));
  if (NewScriptFile == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // Set up the name
  //
  ASSERT (NewScriptFile->ScriptName == NULL);
  NewScriptFile->ScriptName = StrnCatGrow (&NewScriptFile->ScriptName, NULL, Name, 0);
  if (NewScriptFile->ScriptName == NULL) {
    DeleteScriptFileStruct (NewScriptFile);
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // Save the parameters (used to replace %0 to %9 later on)
  //
  NewScriptFile->Argc = ShellInfoObject.NewShellParametersProtocol->Argc;
  if (NewScriptFile->Argc != 0) {
    NewScriptFile->Argv = (CHAR16 **)AllocateZeroPool (NewScriptFile->Argc * sizeof (CHAR16 *));
    if (NewScriptFile->Argv == NULL) {
      DeleteScriptFileStruct (NewScriptFile);
      return (EFI_OUT_OF_RESOURCES);
    }

    //
    // Put the full path of the script file into Argv[0] as required by section
    // 3.6.2 of version 2.2 of the shell specification.
    //
    NewScriptFile->Argv[0] = StrnCatGrow (&NewScriptFile->Argv[0], NULL, NewScriptFile->ScriptName, 0);
    for (LoopVar = 1; LoopVar < 10 && LoopVar < NewScriptFile->Argc; LoopVar++) {
      ASSERT (NewScriptFile->Argv[LoopVar] == NULL);
      NewScriptFile->Argv[LoopVar] = StrnCatGrow (&NewScriptFile->Argv[LoopVar], NULL, ShellInfoObject.NewShellParametersProtocol->Argv[LoopVar], 0);
      if (NewScriptFile->Argv[LoopVar] == NULL) {
        DeleteScriptFileStruct (NewScriptFile);
        return (EFI_OUT_OF_RESOURCES);
      }
    }
  } else {
    NewScriptFile->Argv = NULL;
  }

  InitializeListHead (&NewScriptFile->CommandList);
  InitializeListHead (&NewScriptFile->SubstList);

  //
  // Now build the list of all script commands.
  //
  LineCount = 0;
  while (!ShellFileHandleEof (Handle)) {
    CommandLine = ShellFileHandleReturnLine (Handle, &Ascii);
    LineCount++;
    if ((CommandLine == NULL) || (StrLen (CommandLine) == 0) || (CommandLine[0] == '#')) {
      SHELL_FREE_NON_NULL (CommandLine);
      continue;
    }

    NewScriptFile->CurrentCommand = AllocateZeroPool (sizeof (SCRIPT_COMMAND_LIST));
    if (NewScriptFile->CurrentCommand == NULL) {
      SHELL_FREE_NON_NULL (CommandLine);
      DeleteScriptFileStruct (NewScriptFile);
      return (EFI_OUT_OF_RESOURCES);
    }

    NewScriptFile->CurrentCommand->Cl   = CommandLine;
    NewScriptFile->CurrentCommand->Data = NULL;
    NewScriptFile->CurrentCommand->Line = LineCount;

    InsertTailList (&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link);
  }

  //
  // Add this as the topmost script file
  //
  ShellCommandSetNewScript (NewScriptFile);

  //
  // Now enumerate through the commands and run each one.
  //
  CommandLine = AllocateZeroPool (PrintBuffSize);
  if (CommandLine == NULL) {
    DeleteScriptFileStruct (NewScriptFile);
    return (EFI_OUT_OF_RESOURCES);
  }

  CommandLine2 = AllocateZeroPool (PrintBuffSize);
  if (CommandLine2 == NULL) {
    FreePool (CommandLine);
    DeleteScriptFileStruct (NewScriptFile);
    return (EFI_OUT_OF_RESOURCES);
  }

  for ( NewScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetFirstNode (&NewScriptFile->CommandList)
        ; !IsNull (&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link)
        ; // conditional increment in the body of the loop
        )
  {
    ASSERT (CommandLine2 != NULL);
    StrnCpyS (
      CommandLine2,
      PrintBuffSize/sizeof (CHAR16),
      NewScriptFile->CurrentCommand->Cl,
      PrintBuffSize/sizeof (CHAR16) - 1
      );

    SaveBufferList (&OldBufferList);

    //
    // NULL out comments
    //
    for (CommandLine3 = CommandLine2; CommandLine3 != NULL && *CommandLine3 != CHAR_NULL; CommandLine3++) {
      if (*CommandLine3 == L'^') {
        if ( *(CommandLine3+1) == L':') {
          CopyMem (CommandLine3, CommandLine3+1, StrSize (CommandLine3) - sizeof (CommandLine3[0]));
        } else if (*(CommandLine3+1) == L'#') {
          CommandLine3++;
        }
      } else if (*CommandLine3 == L'#') {
        *CommandLine3 = CHAR_NULL;
      }
    }

    if ((CommandLine2 != NULL) && (StrLen (CommandLine2) >= 1)) {
      //
      // Due to variability in starting the find and replace action we need to have both buffers the same.
      //
      StrnCpyS (
        CommandLine,
        PrintBuffSize/sizeof (CHAR16),
        CommandLine2,
        PrintBuffSize/sizeof (CHAR16) - 1
        );

      //
      // Remove the %0 to %9 from the command line (if we have some arguments)
      //
      if (NewScriptFile->Argv != NULL) {
        switch (NewScriptFile->Argc) {
          default:
            Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%9", NewScriptFile->Argv[9], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 9:
            Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%8", NewScriptFile->Argv[8], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 8:
            Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%7", NewScriptFile->Argv[7], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 7:
            Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%6", NewScriptFile->Argv[6], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 6:
            Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%5", NewScriptFile->Argv[5], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 5:
            Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%4", NewScriptFile->Argv[4], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 4:
            Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%3", NewScriptFile->Argv[3], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 3:
            Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%2", NewScriptFile->Argv[2], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 2:
            Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%1", NewScriptFile->Argv[1], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
          case 1:
            Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%0", NewScriptFile->Argv[0], FALSE, FALSE);
            ASSERT_EFI_ERROR (Status);
            break;
          case 0:
            break;
        }
      }

      Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%1", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%2", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%3", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%4", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%5", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%6", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%7", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine, CommandLine2, PrintBuffSize, L"%8", L"\"\"", FALSE, FALSE);
      Status = ShellCopySearchAndReplace (CommandLine2, CommandLine, PrintBuffSize, L"%9", L"\"\"", FALSE, FALSE);

      StrnCpyS (
        CommandLine2,
        PrintBuffSize/sizeof (CHAR16),
        CommandLine,
        PrintBuffSize/sizeof (CHAR16) - 1
        );

      LastCommand = NewScriptFile->CurrentCommand;

      for (CommandLine3 = CommandLine2; CommandLine3[0] == L' '; CommandLine3++) {
      }

      if ((CommandLine3 != NULL) && (CommandLine3[0] == L':')) {
        //
        // This line is a goto target / label
        //
      } else {
        if ((CommandLine3 != NULL) && (StrLen (CommandLine3) > 0)) {
          if (CommandLine3[0] == L'@') {
            //
            // We need to save the current echo state
            // and disable echo for just this command.
            //
            PreCommandEchoState = ShellCommandGetEchoState ();
            ShellCommandSetEchoState (FALSE);
            Status = RunCommand (CommandLine3+1);

            //
            // If command was "@echo -off" or "@echo -on" then don't restore echo state
            //
            if ((StrCmp (L"@echo -off", CommandLine3) != 0) &&
                (StrCmp (L"@echo -on", CommandLine3) != 0))
            {
              //
              // Now restore the pre-'@' echo state.
              //
              ShellCommandSetEchoState (PreCommandEchoState);
            }
          } else {
            if (ShellCommandGetEchoState ()) {
              CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv (L"cwd");
              if ((CurDir != NULL) && (StrLen (CurDir) > 1)) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);
              } else {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);
              }

              ShellPrintEx (-1, -1, L"%s\r\n", CommandLine2);
            }

            Status = RunCommand (CommandLine3);
          }
        }

        if (ShellCommandGetScriptExit ()) {
          //
          // ShellCommandGetExitCode() always returns a UINT64
          //
          UnicodeSPrint (LeString, sizeof (LeString), L"0x%Lx", ShellCommandGetExitCode ());
          DEBUG_CODE (
            InternalEfiShellSetEnv (L"debuglasterror", LeString, TRUE);
            );
          InternalEfiShellSetEnv (L"lasterror", LeString, TRUE);

          ShellCommandRegisterExit (FALSE, 0);
          Status = EFI_SUCCESS;
          RestoreBufferList (&OldBufferList);
          break;
        }

        if (ShellGetExecutionBreakFlag ()) {
          RestoreBufferList (&OldBufferList);
          break;
        }

        if (EFI_ERROR (Status)) {
          RestoreBufferList (&OldBufferList);
          break;
        }

        if (ShellCommandGetExit ()) {
          RestoreBufferList (&OldBufferList);
          break;
        }
      }

      //
      // If that commend did not update the CurrentCommand then we need to advance it...
      //
      if (LastCommand == NewScriptFile->CurrentCommand) {
        NewScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode (&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link);
        if (!IsNull (&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link)) {
          NewScriptFile->CurrentCommand->Reset = TRUE;
        }
      }
    } else {
      NewScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode (&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link);
      if (!IsNull (&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link)) {
        NewScriptFile->CurrentCommand->Reset = TRUE;
      }
    }

    RestoreBufferList (&OldBufferList);
  }

  FreePool (CommandLine);
  FreePool (CommandLine2);
  ShellCommandSetNewScript (NULL);

  //
  // Only if this was the last script reset the state.
  //
  if (ShellCommandGetCurrentScriptFile () == NULL) {
    ShellCommandSetEchoState (PreScriptEchoState);
  }

  return (EFI_SUCCESS);
}

/**
  Function to process a NSH script file.

  @param[in] ScriptPath         Pointer to the script file name (including file system path).
  @param[in] Handle             the handle of the script file already opened.
  @param[in] CmdLine            the command line to run.
  @param[in] ParamProtocol      the shell parameters protocol pointer

  @retval EFI_SUCCESS           the script completed successfully
**/
EFI_STATUS
RunScriptFile (
  IN CONST CHAR16                   *ScriptPath,
  IN SHELL_FILE_HANDLE              Handle OPTIONAL,
  IN CONST CHAR16                   *CmdLine,
  IN EFI_SHELL_PARAMETERS_PROTOCOL  *ParamProtocol
  )
{
  EFI_STATUS         Status;
  SHELL_FILE_HANDLE  FileHandle;
  UINTN              Argc;
  CHAR16             **Argv;

  if (ShellIsFile (ScriptPath) != EFI_SUCCESS) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // get the argc and argv updated for scripts
  //
  Status = UpdateArgcArgv (ParamProtocol, CmdLine, Script_File_Name, &Argv, &Argc);
  if (!EFI_ERROR (Status)) {
    if (Handle == NULL) {
      //
      // open the file
      //
      Status = ShellOpenFileByName (ScriptPath, &FileHandle, EFI_FILE_MODE_READ, 0);
      if (!EFI_ERROR (Status)) {
        //
        // run it
        //
        Status = RunScriptFileHandle (FileHandle, ScriptPath);

        //
        // now close the file
        //
        ShellCloseFile (&FileHandle);
      }
    } else {
      Status = RunScriptFileHandle (Handle, ScriptPath);
    }
  }

  //
  // This is guaranteed to be called after UpdateArgcArgv no matter what else happened.
  // This is safe even if the update API failed.  In this case, it may be a no-op.
  //
  RestoreArgcArgv (ParamProtocol, &Argv, &Argc);

  return (Status);
}

/**
  Return the pointer to the first occurrence of any character from a list of characters.

  @param[in] String           the string to parse
  @param[in] CharacterList    the list of character to look for
  @param[in] EscapeCharacter  An escape character to skip

  @return the location of the first character in the string
  @retval CHAR_NULL no instance of any character in CharacterList was found in String
**/
CONST CHAR16 *
FindFirstCharacter (
  IN CONST CHAR16  *String,
  IN CONST CHAR16  *CharacterList,
  IN CONST CHAR16  EscapeCharacter
  )
{
  UINT32  WalkChar;
  UINT32  WalkStr;

  for (WalkStr = 0; WalkStr < StrLen (String); WalkStr++) {
    if (String[WalkStr] == EscapeCharacter) {
      WalkStr++;
      continue;
    }

    for (WalkChar = 0; WalkChar < StrLen (CharacterList); WalkChar++) {
      if (String[WalkStr] == CharacterList[WalkChar]) {
        return (&String[WalkStr]);
      }
    }
  }

  return (String + StrLen (String));
}
