/** @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                      = PcdGet32 (PcdShellDefaultDelay);

  //
  // 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;

  CalleeStatus    = EFI_SUCCESS;
  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));
}
