/** @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>
  Copyright (C) 2023, Apple Inc. All rights reserved.<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)) {
    ShellPrintHiiDefaultEx (
      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 (!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
        );

      ShellPrintHiiDefaultEx (
        STRING_TOKEN (STR_VER_OUTPUT_MAIN_SUPPLIER),
        ShellInfoObject.HiiHandle,
        (CHAR16 *)PcdGetPtr (PcdShellSupplier)
        );

      ShellPrintHiiDefaultEx (
        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);
    if (TempString == NULL) {
      ASSERT (TempString != NULL);
      Status = EFI_OUT_OF_RESOURCES;
      goto FreeResources;
    }

    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)) {
    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
      ShellPrintHiiDefaultEx (
        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);

    if ((DevicePathType (FileDevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType (FileDevicePath) == MEDIA_FILEPATH_DP)) {
      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);
    }
  }

  ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);
  } else {
    ShellPrintHiiDefaultEx (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) {
        ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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)) {
    ShellPrintHiiDefaultEx (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
  )
{
  EFI_STATUS  Status;
  CHAR16      *CurrentParameter;
  CHAR16      *Walker;
  CHAR16      *NewCommandLine;
  CHAR16      *CmdName;
  UINTN       CmdNameSize;
  UINTN       NewCmdLineSize;
  BOOLEAN     HasHelpFlag;

  if ((CmdLine == NULL) || (*CmdLine == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  CurrentParameter = AllocateZeroPool (StrSize (*CmdLine));
  if (CurrentParameter == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  HasHelpFlag = FALSE;
  Walker      = *CmdLine;
  CmdName     = NULL;
  CmdNameSize = 0;
  while ((Walker != NULL) && (*Walker != CHAR_NULL) &&
         (!EFI_ERROR (GetNextParameter (&Walker, &CurrentParameter, StrSize (*CmdLine), TRUE))))
  {
    if (StrStr (CurrentParameter, L"-?") == CurrentParameter) {
      HasHelpFlag = TRUE;
    } else if (CmdName == NULL) {
      //
      // A command line can start with "-? CmdName".
      // In such case CmdName is the second parameter.
      //
      CmdNameSize = StrSize (CurrentParameter);
      CmdName     = AllocateCopyPool (CmdNameSize, CurrentParameter);
      if (CmdName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto exit_handler;
      }
    }
  }

  //
  // Nothing to do.
  //
  if (!HasHelpFlag) {
    Status = EFI_SUCCESS;
    goto exit_handler;
  }

  //
  // Allocate space for "help [CmdName]"
  //
  NewCmdLineSize = sizeof (L"help ") + CmdNameSize;
  NewCommandLine = AllocateZeroPool (NewCmdLineSize);
  if (NewCommandLine == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto exit_handler;
  }

  StrnCpyS (NewCommandLine, NewCmdLineSize/sizeof (CHAR16), L"help ", StrLen (L"help "));
  if (CmdName != NULL) {
    StrnCatS (NewCommandLine, NewCmdLineSize/sizeof (CHAR16), CmdName, CmdNameSize/sizeof (CHAR16));
  }

  FreePool (*CmdLine);
  *CmdLine = NewCommandLine;
  Status   = EFI_SUCCESS;

exit_handler:
  SHELL_FREE_NON_NULL (CurrentParameter);
  SHELL_FREE_NON_NULL (CmdName);
  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);
      }

      if (CommandWithPath == NULL) {
        //
        // This should be impossible now.
        //
        ASSERT (CommandWithPath != NULL);
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
        SetLastError (SHELL_NOT_FOUND);
        return EFI_NOT_FOUND;
      }

      //
      // Make sure that path is not just a directory (or not found)
      //
      if (!EFI_ERROR (ShellIsDirectory (CommandWithPath))) {
        ShellPrintHiiDefaultEx (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)) {
      ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID *)(Status));
    } else {
      ShellPrintHiiDefaultEx (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.
        //
        ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
        SetLastError (SHELL_NOT_FOUND);
        break;
    }
  } else {
    ShellPrintHiiDefaultEx (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      = PcdGet32 (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)) {
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);
              } else {
                ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);
              }

              ShellPrintDefaultEx (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
  )
{
  UINTN  WalkChar;
  UINTN  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));
}
