/** @file
  Provides interface to shell functionality for shell commands and applications.

  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  Copyright 2016-2018 Dell Technologies.<BR>
  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
  Copyright (C) 2023, Apple Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "UefiShellLib.h"
#include <Library/SortLib.h>
#include <Library/BaseLib.h>

//
// globals...
//
SHELL_PARAM_ITEM                EmptyParamList[] = {
  { NULL, TypeMax }
};
SHELL_PARAM_ITEM                SfoParamList[] = {
  { L"-sfo", TypeFlag },
  { NULL,    TypeMax  }
};
EFI_SHELL_ENVIRONMENT2          *mEfiShellEnvironment2;
EFI_SHELL_INTERFACE             *mEfiShellInterface;
EFI_SHELL_PROTOCOL              *gEfiShellProtocol;
EFI_SHELL_PARAMETERS_PROTOCOL   *gEfiShellParametersProtocol;
EFI_HANDLE                      mEfiShellEnvironment2Handle;
FILE_HANDLE_FUNCTION_MAP        FileFunctionMap;
EFI_UNICODE_COLLATION_PROTOCOL  *mUnicodeCollationProtocol;

/**
  Return a clean, fully-qualified version of an input path.  If the return value
  is non-NULL the caller must free the memory when it is no longer needed.

  If asserts are disabled, and if the input parameter is NULL, NULL is returned.

  If there is not enough memory available to create the fully-qualified path or
  a copy of the input path, NULL is returned.

  If there is no working directory, a clean copy of Path is returned.

  Otherwise, the current file system or working directory (as appropriate) is
  prepended to Path and the resulting path is cleaned and returned.

  NOTE: If the input path is an empty string, then the current working directory
  (if it exists) is returned.  In other words, an empty input path is treated
  exactly the same as ".".

  @param[in] Path  A pointer to some file or directory path.

  @retval NULL          The input path is NULL or out of memory.

  @retval non-NULL      A pointer to a clean, fully-qualified version of Path.
                        If there is no working directory, then a pointer to a
                        clean, but not necessarily fully-qualified version of
                        Path.  The caller must free this memory when it is no
                        longer needed.
**/
CHAR16 *
EFIAPI
FullyQualifyPath (
  IN     CONST CHAR16  *Path
  )
{
  CONST CHAR16  *WorkingPath;
  CONST CHAR16  *InputPath;
  CHAR16        *CharPtr;
  CHAR16        *InputFileSystem;
  UINTN         FileSystemCharCount;
  CHAR16        *FullyQualifiedPath;
  UINTN         Size;

  FullyQualifiedPath = NULL;

  ASSERT (Path != NULL);
  //
  // Handle erroneous input when asserts are disabled.
  //
  if (Path == NULL) {
    return NULL;
  }

  //
  // In paths that contain ":", like fs0:dir/file.ext and fs2:\fqpath\file.ext,
  // we  have to consider the file system part separately from the "path" part.
  // If there is a file system in the path, we have to get the current working
  // directory for that file system. Then we need to use the part of the path
  // following the ":".  If a path does not contain ":", we use it as given.
  //
  InputPath = StrStr (Path, L":");
  if (InputPath != NULL) {
    InputPath++;
    FileSystemCharCount = ((UINTN)InputPath - (UINTN)Path + sizeof (CHAR16)) / sizeof (CHAR16);
    InputFileSystem     = AllocateCopyPool (FileSystemCharCount * sizeof (CHAR16), Path);
    if (InputFileSystem != NULL) {
      InputFileSystem[FileSystemCharCount - 1] = CHAR_NULL;
    }

    WorkingPath = ShellGetCurrentDir (InputFileSystem);
    SHELL_FREE_NON_NULL (InputFileSystem);
  } else {
    InputPath   = Path;
    WorkingPath = ShellGetEnvironmentVariable (L"cwd");
  }

  if (WorkingPath == NULL) {
    //
    // With no working directory, all we can do is copy and clean the input path.
    //
    FullyQualifiedPath = AllocateCopyPool (StrSize (Path), Path);
  } else {
    //
    // Allocate space for both strings plus one more character.
    //
    Size               = StrSize (WorkingPath) + StrSize (InputPath);
    FullyQualifiedPath = AllocateZeroPool (Size);
    if (FullyQualifiedPath == NULL) {
      //
      // Try to copy and clean just the input. No harm if not enough memory.
      //
      FullyQualifiedPath = AllocateCopyPool (StrSize (Path), Path);
    } else {
      if ((*InputPath == L'\\') || (*InputPath == L'/')) {
        //
        // Absolute path: start with the current working directory, then
        // truncate the new path after the file system part.
        //
        StrCpyS (FullyQualifiedPath, Size/sizeof (CHAR16), WorkingPath);
        CharPtr = StrStr (FullyQualifiedPath, L":");
        if (CharPtr != NULL) {
          *(CharPtr + 1) = CHAR_NULL;
        }
      } else {
        //
        // Relative path: start with the working directory and append "\".
        //
        StrCpyS (FullyQualifiedPath, Size/sizeof (CHAR16), WorkingPath);
        StrCatS (FullyQualifiedPath, Size/sizeof (CHAR16), L"\\");
      }

      //
      // Now append the absolute or relative path.
      //
      StrCatS (FullyQualifiedPath, Size/sizeof (CHAR16), InputPath);
    }
  }

  PathCleanUpDirectories (FullyQualifiedPath);

  return FullyQualifiedPath;
}

/**
  Check if a Unicode character is a hexadecimal character.

  This internal function checks if a Unicode character is a
  numeric character.  The valid hexadecimal characters are
  L'0' to L'9', L'a' to L'f', or L'A' to L'F'.

  @param  Char  The character to check against.

  @retval TRUE  If the Char is a hexadecmial character.
  @retval FALSE If the Char is not a hexadecmial character.

**/
BOOLEAN
EFIAPI
ShellIsHexaDecimalDigitCharacter (
  IN      CHAR16  Char
  )
{
  return (BOOLEAN)((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f'));
}

/**
  Check if a Unicode character is a decimal character.

  This internal function checks if a Unicode character is a
  decimal character.  The valid characters are
  L'0' to L'9'.


  @param  Char  The character to check against.

  @retval TRUE  If the Char is a hexadecmial character.
  @retval FALSE If the Char is not a hexadecmial character.

**/
BOOLEAN
EFIAPI
ShellIsDecimalDigitCharacter (
  IN      CHAR16  Char
  )
{
  return (BOOLEAN)(Char >= L'0' && Char <= L'9');
}

/**
  Helper function to find ShellEnvironment2 for constructor.

  @param[in] ImageHandle    A copy of the calling image's handle.

  @retval EFI_OUT_OF_RESOURCES    Memory allocation failed.
**/
EFI_STATUS
ShellFindSE2 (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  *Buffer;
  UINTN       BufferSize;
  UINTN       HandleIndex;

  BufferSize = 0;
  Buffer     = NULL;
  Status     = gBS->OpenProtocol (
                      ImageHandle,
                      &gEfiShellEnvironment2Guid,
                      (VOID **)&mEfiShellEnvironment2,
                      ImageHandle,
                      NULL,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
  //
  // look for the mEfiShellEnvironment2 protocol at a higher level
  //
  if (EFI_ERROR (Status) || !(CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid))) {
    //
    // figure out how big of a buffer we need.
    //
    Status = gBS->LocateHandle (
                    ByProtocol,
                    &gEfiShellEnvironment2Guid,
                    NULL,             // ignored for ByProtocol
                    &BufferSize,
                    Buffer
                    );
    //
    // maybe it's not there???
    //
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Buffer = (EFI_HANDLE *)AllocateZeroPool (BufferSize);
      if (Buffer == NULL) {
        return (EFI_OUT_OF_RESOURCES);
      }

      Status = gBS->LocateHandle (
                      ByProtocol,
                      &gEfiShellEnvironment2Guid,
                      NULL,             // ignored for ByProtocol
                      &BufferSize,
                      Buffer
                      );
    }

    if (!EFI_ERROR (Status) && (Buffer != NULL)) {
      //
      // now parse the list of returned handles
      //
      Status = EFI_NOT_FOUND;
      for (HandleIndex = 0; HandleIndex < (BufferSize/sizeof (Buffer[0])); HandleIndex++) {
        Status = gBS->OpenProtocol (
                        Buffer[HandleIndex],
                        &gEfiShellEnvironment2Guid,
                        (VOID **)&mEfiShellEnvironment2,
                        ImageHandle,
                        NULL,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );
        if (CompareGuid (&mEfiShellEnvironment2->SESGuid, &gEfiShellEnvironment2ExtGuid)) {
          mEfiShellEnvironment2Handle = Buffer[HandleIndex];
          Status                      = EFI_SUCCESS;
          break;
        }
      }
    }
  }

  if (Buffer != NULL) {
    FreePool (Buffer);
  }

  return (Status);
}

/**
  Function to do most of the work of the constructor.  Allows for calling
  multiple times without complete re-initialization.

  @param[in] ImageHandle  A copy of the ImageHandle.
  @param[in] SystemTable  A pointer to the SystemTable for the application.

  @retval EFI_SUCCESS   The operationw as successful.
**/
EFI_STATUS
ShellLibConstructorWorker (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  if (gEfiShellProtocol == NULL) {
    //
    // UEFI 2.0 shell interfaces (used preferentially)
    //
    Status = gBS->OpenProtocol (
                    ImageHandle,
                    &gEfiShellProtocolGuid,
                    (VOID **)&gEfiShellProtocol,
                    ImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      //
      // Search for the shell protocol
      //
      Status = gBS->LocateProtocol (
                      &gEfiShellProtocolGuid,
                      NULL,
                      (VOID **)&gEfiShellProtocol
                      );
      if (EFI_ERROR (Status)) {
        gEfiShellProtocol = NULL;
      }
    }
  }

  if (gEfiShellParametersProtocol == NULL) {
    Status = gBS->OpenProtocol (
                    ImageHandle,
                    &gEfiShellParametersProtocolGuid,
                    (VOID **)&gEfiShellParametersProtocol,
                    ImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      gEfiShellParametersProtocol = NULL;
    }
  }

  if (gEfiShellProtocol == NULL) {
    //
    // Moved to seperate function due to complexity
    //
    Status = ShellFindSE2 (ImageHandle);

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Status: 0x%08x\r\n", Status));
      mEfiShellEnvironment2 = NULL;
    }

    Status = gBS->OpenProtocol (
                    ImageHandle,
                    &gEfiShellInterfaceGuid,
                    (VOID **)&mEfiShellInterface,
                    ImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      mEfiShellInterface = NULL;
    }
  }

  //
  // Getting either EDK Shell's ShellEnvironment2 and ShellInterface protocol
  //  or UEFI Shell's Shell protocol.
  // When ShellLib is linked to a driver producing DynamicCommand protocol,
  //  ShellParameters protocol is set by DynamicCommand.Handler().
  //
  if (((mEfiShellEnvironment2 != NULL) && (mEfiShellInterface != NULL)) ||
      (gEfiShellProtocol     != NULL)
      )
  {
    if (gEfiShellProtocol != NULL) {
      FileFunctionMap.GetFileInfo     = gEfiShellProtocol->GetFileInfo;
      FileFunctionMap.SetFileInfo     = gEfiShellProtocol->SetFileInfo;
      FileFunctionMap.ReadFile        = gEfiShellProtocol->ReadFile;
      FileFunctionMap.WriteFile       = gEfiShellProtocol->WriteFile;
      FileFunctionMap.CloseFile       = gEfiShellProtocol->CloseFile;
      FileFunctionMap.DeleteFile      = gEfiShellProtocol->DeleteFile;
      FileFunctionMap.GetFilePosition = gEfiShellProtocol->GetFilePosition;
      FileFunctionMap.SetFilePosition = gEfiShellProtocol->SetFilePosition;
      FileFunctionMap.FlushFile       = gEfiShellProtocol->FlushFile;
      FileFunctionMap.GetFileSize     = gEfiShellProtocol->GetFileSize;
    } else {
      FileFunctionMap.GetFileInfo     = (EFI_SHELL_GET_FILE_INFO)FileHandleGetInfo;
      FileFunctionMap.SetFileInfo     = (EFI_SHELL_SET_FILE_INFO)FileHandleSetInfo;
      FileFunctionMap.ReadFile        = (EFI_SHELL_READ_FILE)FileHandleRead;
      FileFunctionMap.WriteFile       = (EFI_SHELL_WRITE_FILE)FileHandleWrite;
      FileFunctionMap.CloseFile       = (EFI_SHELL_CLOSE_FILE)FileHandleClose;
      FileFunctionMap.DeleteFile      = (EFI_SHELL_DELETE_FILE)FileHandleDelete;
      FileFunctionMap.GetFilePosition = (EFI_SHELL_GET_FILE_POSITION)FileHandleGetPosition;
      FileFunctionMap.SetFilePosition = (EFI_SHELL_SET_FILE_POSITION)FileHandleSetPosition;
      FileFunctionMap.FlushFile       = (EFI_SHELL_FLUSH_FILE)FileHandleFlush;
      FileFunctionMap.GetFileSize     = (EFI_SHELL_GET_FILE_SIZE)FileHandleGetSize;
    }

    return (EFI_SUCCESS);
  }

  return (EFI_NOT_FOUND);
}

/**
  Constructor for the Shell library.

  Initialize the library and determine if the underlying is a UEFI Shell 2.0 or an EFI shell.

  @param ImageHandle    the image handle of the process
  @param SystemTable    the EFI System Table pointer

  @retval EFI_SUCCESS   the initialization was complete successfully
  @return others        an error ocurred during initialization
**/
EFI_STATUS
EFIAPI
ShellLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  mEfiShellEnvironment2       = NULL;
  gEfiShellProtocol           = NULL;
  gEfiShellParametersProtocol = NULL;
  mEfiShellInterface          = NULL;
  mEfiShellEnvironment2Handle = NULL;
  mUnicodeCollationProtocol   = NULL;

  //
  // verify that auto initialize is not set false
  //
  if (PcdGetBool (PcdShellLibAutoInitialize) == 0) {
    return (EFI_SUCCESS);
  }

  return (ShellLibConstructorWorker (ImageHandle, SystemTable));
}

/**
  Destructor for the library.  free any resources.

  @param[in] ImageHandle  A copy of the ImageHandle.
  @param[in] SystemTable  A pointer to the SystemTable for the application.

  @retval EFI_SUCCESS   The operation was successful.
  @return               An error from the CloseProtocol function.
**/
EFI_STATUS
EFIAPI
ShellLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  if (mEfiShellEnvironment2 != NULL) {
    Status = gBS->CloseProtocol (
                    mEfiShellEnvironment2Handle == NULL ? ImageHandle : mEfiShellEnvironment2Handle,
                    &gEfiShellEnvironment2Guid,
                    ImageHandle,
                    NULL
                    );
    if (!EFI_ERROR (Status)) {
      mEfiShellEnvironment2       = NULL;
      mEfiShellEnvironment2Handle = NULL;
    }
  }

  if (mEfiShellInterface != NULL) {
    Status = gBS->CloseProtocol (
                    ImageHandle,
                    &gEfiShellInterfaceGuid,
                    ImageHandle,
                    NULL
                    );
    if (!EFI_ERROR (Status)) {
      mEfiShellInterface = NULL;
    }
  }

  if (gEfiShellProtocol != NULL) {
    Status = gBS->CloseProtocol (
                    ImageHandle,
                    &gEfiShellProtocolGuid,
                    ImageHandle,
                    NULL
                    );
    if (!EFI_ERROR (Status)) {
      gEfiShellProtocol = NULL;
    }
  }

  if (gEfiShellParametersProtocol != NULL) {
    Status = gBS->CloseProtocol (
                    ImageHandle,
                    &gEfiShellParametersProtocolGuid,
                    ImageHandle,
                    NULL
                    );
    if (!EFI_ERROR (Status)) {
      gEfiShellParametersProtocol = NULL;
    }
  }

  return (EFI_SUCCESS);
}

/**
  This function causes the shell library to initialize itself.  If the shell library
  is already initialized it will de-initialize all the current protocol pointers and
  re-populate them again.

  When the library is used with PcdShellLibAutoInitialize set to true this function
  will return EFI_SUCCESS and perform no actions.

  This function is intended for internal access for shell commands only.

  @retval EFI_SUCCESS   the initialization was complete successfully

**/
EFI_STATUS
EFIAPI
ShellInitialize (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // if auto initialize is not false then skip
  //
  if (PcdGetBool (PcdShellLibAutoInitialize) != 0) {
    return (EFI_SUCCESS);
  }

  //
  // deinit the current stuff
  //
  Status = ShellLibDestructor (gImageHandle, gST);
  ASSERT_EFI_ERROR (Status);

  //
  // init the new stuff
  //
  return (ShellLibConstructorWorker (gImageHandle, gST));
}

/**
  This function will retrieve the information about the file for the handle
  specified and store it in allocated pool memory.

  This function allocates a buffer to store the file's information. It is the
  caller's responsibility to free the buffer

  @param  FileHandle  The file handle of the file for which information is
  being requested.

  @retval NULL information could not be retrieved.

  @return the information about the file
**/
EFI_FILE_INFO *
EFIAPI
ShellGetFileInfo (
  IN SHELL_FILE_HANDLE  FileHandle
  )
{
  return (FileFunctionMap.GetFileInfo (FileHandle));
}

/**
  This function sets the information about the file for the opened handle
  specified.

  @param[in]  FileHandle        The file handle of the file for which information
                                is being set.

  @param[in]  FileInfo          The information to set.

  @retval EFI_SUCCESS           The information was set.
  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.
  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
  @retval EFI_ACCESS_DENIED     The file was opened read only.
  @retval EFI_VOLUME_FULL       The volume is full.
**/
EFI_STATUS
EFIAPI
ShellSetFileInfo (
  IN SHELL_FILE_HANDLE  FileHandle,
  IN EFI_FILE_INFO      *FileInfo
  )
{
  return (FileFunctionMap.SetFileInfo (FileHandle, FileInfo));
}

/**
This function will open a file or directory referenced by DevicePath.

This function opens a file with the open mode according to the file path. The
Attributes is valid only for EFI_FILE_MODE_CREATE.

@param  FilePath        on input the device path to the file.  On output
                        the remaining device path.
@param  FileHandle      pointer to the file handle.
@param  OpenMode        the mode to open the file with.
@param  Attributes      the file's file attributes.

@retval EFI_SUCCESS           The information was set.
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
@retval EFI_UNSUPPORTED       Could not open the file path.
@retval EFI_NOT_FOUND         The specified file could not be found on the
                              device or the file system could not be found on
                              the device.
@retval EFI_NO_MEDIA          The device has no medium.
@retval EFI_MEDIA_CHANGED     The device has a different medium in it or the
                              medium is no longer supported.
@retval EFI_DEVICE_ERROR      The device reported an error.
@retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
@retval EFI_WRITE_PROTECTED   The file or medium is write protected.
@retval EFI_ACCESS_DENIED     The file was opened read only.
@retval EFI_OUT_OF_RESOURCES  Not enough resources were available to open the
                              file.
@retval EFI_VOLUME_FULL       The volume is full.
**/
EFI_STATUS
EFIAPI
ShellOpenFileByDevicePath (
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **FilePath,
  OUT SHELL_FILE_HANDLE            *FileHandle,
  IN UINT64                        OpenMode,
  IN UINT64                        Attributes
  )
{
  CHAR16             *FileName;
  EFI_STATUS         Status;
  EFI_FILE_PROTOCOL  *File;

  if ((FilePath == NULL) || (FileHandle == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // which shell interface should we use
  //
  if (gEfiShellProtocol != NULL) {
    //
    // use UEFI Shell 2.0 method.
    //
    FileName = gEfiShellProtocol->GetFilePathFromDevicePath (*FilePath);
    if (FileName == NULL) {
      return (EFI_INVALID_PARAMETER);
    }

    Status = ShellOpenFileByName (FileName, FileHandle, OpenMode, Attributes);
    FreePool (FileName);
    return (Status);
  }

  //
  // use old shell method.
  //
  Status = EfiOpenFileByDevicePath (FilePath, &File, OpenMode, Attributes);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
  //
  *FileHandle = (VOID *)File;
  return (EFI_SUCCESS);
}

/**
  This function will open a file or directory referenced by filename.

  If return is EFI_SUCCESS, the Filehandle is the opened file's handle;
  otherwise, the Filehandle is NULL. The Attributes is valid only for
  EFI_FILE_MODE_CREATE.

  if FileName is NULL then ASSERT()

  @param  FileName      pointer to file name
  @param  FileHandle    pointer to the file handle.
  @param  OpenMode      the mode to open the file with.
  @param  Attributes    the file's file attributes.

  @retval EFI_SUCCESS           The information was set.
  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
  @retval EFI_UNSUPPORTED       Could not open the file path.
  @retval EFI_NOT_FOUND         The specified file could not be found on the
                                device or the file system could not be found
                                on the device.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_MEDIA_CHANGED     The device has a different medium in it or the
                                medium is no longer supported.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
  @retval EFI_ACCESS_DENIED     The file was opened read only.
  @retval EFI_OUT_OF_RESOURCES  Not enough resources were available to open the
                                file.
  @retval EFI_VOLUME_FULL       The volume is full.
**/
EFI_STATUS
EFIAPI
ShellOpenFileByName (
  IN CONST CHAR16        *FileName,
  OUT SHELL_FILE_HANDLE  *FileHandle,
  IN UINT64              OpenMode,
  IN UINT64              Attributes
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
  EFI_STATUS                Status;
  EFI_FILE_INFO             *FileInfo;
  CHAR16                    *FileNameCopy;
  EFI_STATUS                Status2;

  //
  // ASSERT if FileName is NULL
  //
  ASSERT (FileName != NULL);

  if (FileName == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  if (gEfiShellProtocol != NULL) {
    if ((OpenMode & EFI_FILE_MODE_CREATE) == EFI_FILE_MODE_CREATE) {
      //
      // Create only a directory
      //
      if ((Attributes & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {
        return ShellCreateDirectory (FileName, FileHandle);
      }

      //
      // Create the directory to create the file in
      //
      FileNameCopy = AllocateCopyPool (StrSize (FileName), FileName);
      if (FileNameCopy == NULL) {
        return (EFI_OUT_OF_RESOURCES);
      }

      PathCleanUpDirectories (FileNameCopy);
      if (PathRemoveLastItem (FileNameCopy)) {
        if (!EFI_ERROR (ShellCreateDirectory (FileNameCopy, FileHandle))) {
          ShellCloseFile (FileHandle);
        }
      }

      SHELL_FREE_NON_NULL (FileNameCopy);
    }

    //
    // Use UEFI Shell 2.0 method to create the file
    //
    Status = gEfiShellProtocol->OpenFileByName (
                                  FileName,
                                  FileHandle,
                                  OpenMode
                                  );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (mUnicodeCollationProtocol == NULL) {
      Status = gBS->LocateProtocol (&gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID **)&mUnicodeCollationProtocol);
      if (EFI_ERROR (Status)) {
        gEfiShellProtocol->CloseFile (*FileHandle);
        return Status;
      }
    }

    if ((mUnicodeCollationProtocol->StriColl (mUnicodeCollationProtocol, (CHAR16 *)FileName, L"NUL") != 0) &&
        (mUnicodeCollationProtocol->StriColl (mUnicodeCollationProtocol, (CHAR16 *)FileName, L"NULL") != 0) &&
        !EFI_ERROR (Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0))
    {
      FileInfo = FileFunctionMap.GetFileInfo (*FileHandle);
      ASSERT (FileInfo != NULL);
      FileInfo->Attribute = Attributes;
      Status2             = FileFunctionMap.SetFileInfo (*FileHandle, FileInfo);
      FreePool (FileInfo);
      if (EFI_ERROR (Status2)) {
        gEfiShellProtocol->CloseFile (*FileHandle);
      }

      Status = Status2;
    }

    return (Status);
  }

  //
  // Using EFI Shell version
  // this means convert name to path and call that function
  // since this will use EFI method again that will open it.
  //
  ASSERT (mEfiShellEnvironment2 != NULL);
  FilePath = mEfiShellEnvironment2->NameToPath ((CHAR16 *)FileName);
  if (FilePath != NULL) {
    return (ShellOpenFileByDevicePath (
              &FilePath,
              FileHandle,
              OpenMode,
              Attributes
              ));
  }

  return (EFI_DEVICE_ERROR);
}

/**
  This function create a directory

  If return is EFI_SUCCESS, the Filehandle is the opened directory's handle;
  otherwise, the Filehandle is NULL. If the directory already existed, this
  function opens the existing directory.

  @param  DirectoryName   pointer to directory name
  @param  FileHandle      pointer to the file handle.

  @retval EFI_SUCCESS           The information was set.
  @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
  @retval EFI_UNSUPPORTED       Could not open the file path.
  @retval EFI_NOT_FOUND         The specified file could not be found on the
                                device or the file system could not be found
                                on the device.
  @retval EFI_NO_MEDIA          The device has no medium.
  @retval EFI_MEDIA_CHANGED     The device has a different medium in it or the
                                medium is no longer supported.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
  @retval EFI_ACCESS_DENIED     The file was opened read only.
  @retval EFI_OUT_OF_RESOURCES  Not enough resources were available to open the
                                file.
  @retval EFI_VOLUME_FULL       The volume is full.
  @sa ShellOpenFileByName
**/
EFI_STATUS
EFIAPI
ShellCreateDirectory (
  IN CONST CHAR16        *DirectoryName,
  OUT SHELL_FILE_HANDLE  *FileHandle
  )
{
  if (gEfiShellProtocol != NULL) {
    //
    // Use UEFI Shell 2.0 method
    //
    return (gEfiShellProtocol->CreateFile (
                                 DirectoryName,
                                 EFI_FILE_DIRECTORY,
                                 FileHandle
                                 ));
  } else {
    return (ShellOpenFileByName (
              DirectoryName,
              FileHandle,
              EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
              EFI_FILE_DIRECTORY
              ));
  }
}

/**
  This function reads information from an opened file.

  If FileHandle is not a directory, the function reads the requested number of
  bytes from the file at the file's current position and returns them in Buffer.
  If the read goes beyond the end of the file, the read length is truncated to the
  end of the file. The file's current position is increased by the number of bytes
  returned.  If FileHandle is a directory, the function reads the directory entry
  at the file's current position and returns the entry in Buffer. If the Buffer
  is not large enough to hold the current directory entry, then
  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.
  BufferSize is set to be the size of the buffer needed to read the entry. On
  success, the current position is updated to the next directory entry. If there
  are no more directory entries, the read returns a zero-length buffer.
  EFI_FILE_INFO is the structure returned as the directory entry.

  @param FileHandle             the opened file handle
  @param BufferSize             on input the size of buffer in bytes.  on return
                                the number of bytes written.
  @param Buffer                 the buffer to put read data into.

  @retval EFI_SUCCESS           Data was read.
  @retval EFI_NO_MEDIA          The device has no media.
  @retval EFI_DEVICE_ERROR  The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_BUFFER_TO_SMALL Buffer is too small. ReadSize contains required
                                size.

**/
EFI_STATUS
EFIAPI
ShellReadFile (
  IN SHELL_FILE_HANDLE  FileHandle,
  IN OUT UINTN          *BufferSize,
  OUT VOID              *Buffer
  )
{
  return (FileFunctionMap.ReadFile (FileHandle, BufferSize, Buffer));
}

/**
  Write data to a file.

  This function writes the specified number of bytes to the file at the current
  file position. The current file position is advanced the actual number of bytes
  written, which is returned in BufferSize. Partial writes only occur when there
  has been a data error during the write attempt (such as "volume space full").
  The file is automatically grown to hold the data if required. Direct writes to
  opened directories are not supported.

  @param FileHandle           The opened file for writing
  @param BufferSize           on input the number of bytes in Buffer.  On output
                              the number of bytes written.
  @param Buffer               the buffer containing data to write is stored.

 @retval EFI_SUCCESS          Data was written.
 @retval EFI_UNSUPPORTED      Writes to an open directory are not supported.
 @retval EFI_NO_MEDIA         The device has no media.
 @retval EFI_DEVICE_ERROR     The device reported an error.
 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
 @retval EFI_WRITE_PROTECTED  The device is write-protected.
 @retval EFI_ACCESS_DENIED    The file was open for read only.
 @retval EFI_VOLUME_FULL      The volume is full.
**/
EFI_STATUS
EFIAPI
ShellWriteFile (
  IN SHELL_FILE_HANDLE  FileHandle,
  IN OUT UINTN          *BufferSize,
  IN VOID               *Buffer
  )
{
  return (FileFunctionMap.WriteFile (FileHandle, BufferSize, Buffer));
}

/**
  Close an open file handle.

  This function closes a specified file handle. All "dirty" cached file data is
  flushed to the device, and the file is closed. In all cases the handle is
  closed.

@param FileHandle               the file handle to close.

@retval EFI_SUCCESS             the file handle was closed successfully.
**/
EFI_STATUS
EFIAPI
ShellCloseFile (
  IN SHELL_FILE_HANDLE  *FileHandle
  )
{
  return (FileFunctionMap.CloseFile (*FileHandle));
}

/**
  Delete a file and close the handle

  This function closes and deletes a file. In all cases the file handle is closed.
  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is
  returned, but the handle is still closed.

  @param FileHandle             the file handle to delete

  @retval EFI_SUCCESS           the file was closed successfully
  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not
                                deleted
  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
**/
EFI_STATUS
EFIAPI
ShellDeleteFile (
  IN SHELL_FILE_HANDLE  *FileHandle
  )
{
  return (FileFunctionMap.DeleteFile (*FileHandle));
}

/**
  Set the current position in a file.

  This function sets the current file position for the handle to the position
  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only
  absolute positioning is supported, and seeking past the end of the file is
  allowed (a subsequent write would grow the file). Seeking to position
  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.
  If FileHandle is a directory, the only position that may be set is zero. This
  has the effect of starting the read process of the directory entries over.

  @param FileHandle             The file handle on which the position is being set
  @param Position               Byte position from beginning of file

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on
                                directories.
  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
**/
EFI_STATUS
EFIAPI
ShellSetFilePosition (
  IN SHELL_FILE_HANDLE  FileHandle,
  IN UINT64             Position
  )
{
  return (FileFunctionMap.SetFilePosition (FileHandle, Position));
}

/**
  Gets a file's current position

  This function retrieves the current file position for the file handle. For
  directories, the current file position has no meaning outside of the file
  system driver and as such the operation is not supported. An error is returned
  if FileHandle is a directory.

  @param FileHandle             The open file handle on which to get the position.
  @param Position               Byte position from beginning of file.

  @retval EFI_SUCCESS           the operation completed successfully.
  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
  @retval EFI_UNSUPPORTED       the request is not valid on directories.
**/
EFI_STATUS
EFIAPI
ShellGetFilePosition (
  IN SHELL_FILE_HANDLE  FileHandle,
  OUT UINT64            *Position
  )
{
  return (FileFunctionMap.GetFilePosition (FileHandle, Position));
}

/**
  Flushes data on a file

  This function flushes all modified data associated with a file to a device.

  @param FileHandle             The file handle on which to flush data

  @retval EFI_SUCCESS           The data was flushed.
  @retval EFI_NO_MEDIA          The device has no media.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
  @retval EFI_ACCESS_DENIED     The file was opened for read only.
**/
EFI_STATUS
EFIAPI
ShellFlushFile (
  IN SHELL_FILE_HANDLE  FileHandle
  )
{
  return (FileFunctionMap.FlushFile (FileHandle));
}

/** Retrieve first entry from a directory.

  This function takes an open directory handle and gets information from the
  first entry in the directory.  A buffer is allocated to contain
  the information and a pointer to the buffer is returned in *Buffer.  The
  caller can use ShellFindNextFile() to get subsequent directory entries.

  The buffer will be freed by ShellFindNextFile() when the last directory
  entry is read.  Otherwise, the caller must free the buffer, using FreePool,
  when finished with it.

  @param[in]  DirHandle         The file handle of the directory to search.
  @param[out] Buffer            The pointer to the buffer for the file's information.

  @retval EFI_SUCCESS           Found the first file.
  @retval EFI_NOT_FOUND         Cannot find the directory.
  @retval EFI_NO_MEDIA          The device has no media.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @return Others                status of ShellGetFileInfo, ShellSetFilePosition,
                                or ShellReadFile
**/
EFI_STATUS
EFIAPI
ShellFindFirstFile (
  IN SHELL_FILE_HANDLE  DirHandle,
  OUT EFI_FILE_INFO     **Buffer
  )
{
  //
  // pass to file handle lib
  //
  return (FileHandleFindFirstFile (DirHandle, Buffer));
}

/** Retrieve next entries from a directory.

  To use this function, the caller must first call the ShellFindFirstFile()
  function to get the first directory entry.  Subsequent directory entries are
  retrieved by using the ShellFindNextFile() function.  This function can
  be called several times to get each entry from the directory.  If the call of
  ShellFindNextFile() retrieved the last directory entry, the next call of
  this function will set *NoFile to TRUE and free the buffer.

  @param[in]  DirHandle         The file handle of the directory.
  @param[out] Buffer            The pointer to buffer for file's information.
  @param[out] NoFile            The pointer to boolean when last file is found.

  @retval EFI_SUCCESS           Found the next file, or reached last file
  @retval EFI_NO_MEDIA          The device has no media.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
**/
EFI_STATUS
EFIAPI
ShellFindNextFile (
  IN SHELL_FILE_HANDLE  DirHandle,
  OUT EFI_FILE_INFO     *Buffer,
  OUT BOOLEAN           *NoFile
  )
{
  //
  // pass to file handle lib
  //
  return (FileHandleFindNextFile (DirHandle, Buffer, NoFile));
}

/**
  Retrieve the size of a file.

  if FileHandle is NULL then ASSERT()
  if Size is NULL then ASSERT()

  This function extracts the file size info from the FileHandle's EFI_FILE_INFO
  data.

  @param FileHandle             file handle from which size is retrieved
  @param Size                   pointer to size

  @retval EFI_SUCCESS           operation was completed successfully
  @retval EFI_DEVICE_ERROR      cannot access the file
**/
EFI_STATUS
EFIAPI
ShellGetFileSize (
  IN SHELL_FILE_HANDLE  FileHandle,
  OUT UINT64            *Size
  )
{
  return (FileFunctionMap.GetFileSize (FileHandle, Size));
}

/**
  Retrieves the status of the break execution flag

  this function is useful to check whether the application is being asked to halt by the shell.

  @retval TRUE                  the execution break is enabled
  @retval FALSE                 the execution break is not enabled
**/
BOOLEAN
EFIAPI
ShellGetExecutionBreakFlag (
  VOID
  )
{
  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    //
    // We are using UEFI Shell 2.0; see if the event has been triggered
    //
    if (gBS->CheckEvent (gEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) {
      return (FALSE);
    }

    return (TRUE);
  }

  //
  // using EFI Shell; call the function to check
  //
  if (mEfiShellEnvironment2 != NULL) {
    return (mEfiShellEnvironment2->GetExecutionBreak ());
  }

  return (FALSE);
}

/**
  return the value of an environment variable

  this function gets the value of the environment variable set by the
  ShellSetEnvironmentVariable function

  @param EnvKey                 The key name of the environment variable.

  @retval NULL                  the named environment variable does not exist.
  @return != NULL               pointer to the value of the environment variable
**/
CONST CHAR16 *
EFIAPI
ShellGetEnvironmentVariable (
  IN CONST CHAR16  *EnvKey
  )
{
  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    return (gEfiShellProtocol->GetEnv (EnvKey));
  }

  //
  // Check for EFI shell
  //
  if (mEfiShellEnvironment2 != NULL) {
    return (mEfiShellEnvironment2->GetEnv ((CHAR16 *)EnvKey));
  }

  return NULL;
}

/**
  set the value of an environment variable

This function changes the current value of the specified environment variable. If the
environment variable exists and the Value is an empty string, then the environment
variable is deleted. If the environment variable exists and the Value is not an empty
string, then the value of the environment variable is changed. If the environment
variable does not exist and the Value is an empty string, there is no action. If the
environment variable does not exist and the Value is a non-empty string, then the
environment variable is created and assigned the specified value.

  This is not supported pre-UEFI Shell 2.0.

  @param EnvKey                 The key name of the environment variable.
  @param EnvVal                 The Value of the environment variable
  @param Volatile               Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).

  @retval EFI_SUCCESS           the operation was completed successfully
  @retval EFI_UNSUPPORTED       This operation is not allowed in pre UEFI 2.0 Shell environments
**/
EFI_STATUS
EFIAPI
ShellSetEnvironmentVariable (
  IN CONST CHAR16  *EnvKey,
  IN CONST CHAR16  *EnvVal,
  IN BOOLEAN       Volatile
  )
{
  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    return (gEfiShellProtocol->SetEnv (EnvKey, EnvVal, Volatile));
  }

  //
  // This feature does not exist under EFI shell
  //
  return (EFI_UNSUPPORTED);
}

/**
  Cause the shell to parse and execute a command line.

  This function creates a nested instance of the shell and executes the specified
  command (CommandLine) with the specified environment (Environment). Upon return,
  the status code returned by the specified command is placed in StatusCode.
  If Environment is NULL, then the current environment is used and all changes made
  by the commands executed will be reflected in the current environment. If the
  Environment is non-NULL, then the changes made will be discarded.
  The CommandLine is executed from the current working directory on the current
  device.

  The EnvironmentVariables pararemeter is ignored in a pre-UEFI Shell 2.0
  environment.  The values pointed to by the parameters will be unchanged by the
  ShellExecute() function.  The Output parameter has no effect in a
  UEFI Shell 2.0 environment.

  @param[in] ParentHandle         The parent image starting the operation.
  @param[in] CommandLine          The pointer to a NULL terminated command line.
  @param[in] Output               True to display debug output.  False to hide it.
  @param[in] EnvironmentVariables Optional pointer to array of environment variables
                                  in the form "x=y".  If NULL, the current set is used.
  @param[out] Status              The status of the run command line.

  @retval EFI_SUCCESS             The operation completed successfully.  Status
                                  contains the status code returned.
  @retval EFI_INVALID_PARAMETER   A parameter contains an invalid value.
  @retval EFI_OUT_OF_RESOURCES    Out of resources.
  @retval EFI_UNSUPPORTED         The operation is not allowed.
**/
EFI_STATUS
EFIAPI
ShellExecute (
  IN EFI_HANDLE   *ParentHandle,
  IN CHAR16       *CommandLine OPTIONAL,
  IN BOOLEAN      Output OPTIONAL,
  IN CHAR16       **EnvironmentVariables OPTIONAL,
  OUT EFI_STATUS  *Status OPTIONAL
  )
{
  EFI_STATUS  CmdStatus;

  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    //
    // Call UEFI Shell 2.0 version (not using Output parameter)
    //
    return (gEfiShellProtocol->Execute (
                                 ParentHandle,
                                 CommandLine,
                                 EnvironmentVariables,
                                 Status
                                 ));
  }

  //
  // Check for EFI shell
  //
  if (mEfiShellEnvironment2 != NULL) {
    //
    // Call EFI Shell version.
    //
    // Due to an unfixable bug in the EdkShell implementation, we must
    // dereference "ParentHandle" here:
    //
    // 1. The EFI shell installs the EFI_SHELL_ENVIRONMENT2 protocol,
    //    identified by gEfiShellEnvironment2Guid.
    // 2. The Execute() member function takes "ParentImageHandle" as first
    //    parameter, with type (EFI_HANDLE*).
    // 3. In the EdkShell implementation, SEnvExecute() implements the
    //    Execute() member function. It passes "ParentImageHandle" correctly to
    //    SEnvDoExecute().
    // 4. SEnvDoExecute() takes the (EFI_HANDLE*), and passes it directly --
    //    without de-referencing -- to the HandleProtocol() boot service.
    // 5. But HandleProtocol() takes an EFI_HANDLE.
    //
    // Therefore we must
    // - de-reference "ParentHandle" here, to mask the bug in
    //   SEnvDoExecute(), and
    // - pass the resultant EFI_HANDLE as an (EFI_HANDLE*).
    //
    CmdStatus = (mEfiShellEnvironment2->Execute (
                                          (EFI_HANDLE *)*ParentHandle,
                                          CommandLine,
                                          Output
                                          ));
    //
    // No Status output parameter so just use the returned status
    //
    if (Status != NULL) {
      *Status = CmdStatus;
    }

    //
    // If there was an error, we can't tell if it was from the command or from
    // the Execute() function, so we'll just assume the shell ran successfully
    // and the error came from the command.
    //
    return EFI_SUCCESS;
  }

  return (EFI_UNSUPPORTED);
}

/**
  Retreives the current directory path

  If the DeviceName is NULL, it returns the current device's current directory
  name. If the DeviceName is not NULL, it returns the current directory name
  on specified drive.

  Note that the current directory string should exclude the tailing backslash character.

  @param DeviceName             the name of the drive to get directory on

  @retval NULL                  the directory does not exist
  @return != NULL               the directory
**/
CONST CHAR16 *
EFIAPI
ShellGetCurrentDir (
  IN CHAR16                     *CONST  DeviceName OPTIONAL
  )
{
  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    return (gEfiShellProtocol->GetCurDir (DeviceName));
  }

  //
  // Check for EFI shell
  //
  if (mEfiShellEnvironment2 != NULL) {
    return (mEfiShellEnvironment2->CurDir (DeviceName));
  }

  return (NULL);
}

/**
  sets (enabled or disabled) the page break mode

  when page break mode is enabled the screen will stop scrolling
  and wait for operator input before scrolling a subsequent screen.

  @param CurrentState           TRUE to enable and FALSE to disable
**/
VOID
EFIAPI
ShellSetPageBreakMode (
  IN BOOLEAN  CurrentState
  )
{
  //
  // check for enabling
  //
  if (CurrentState != 0x00) {
    //
    // check for UEFI Shell 2.0
    //
    if (gEfiShellProtocol != NULL) {
      //
      // Enable with UEFI 2.0 Shell
      //
      gEfiShellProtocol->EnablePageBreak ();
      return;
    } else {
      //
      // Check for EFI shell
      //
      if (mEfiShellEnvironment2 != NULL) {
        //
        // Enable with EFI Shell
        //
        mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
        return;
      }
    }
  } else {
    //
    // check for UEFI Shell 2.0
    //
    if (gEfiShellProtocol != NULL) {
      //
      // Disable with UEFI 2.0 Shell
      //
      gEfiShellProtocol->DisablePageBreak ();
      return;
    } else {
      //
      // Check for EFI shell
      //
      if (mEfiShellEnvironment2 != NULL) {
        //
        // Disable with EFI Shell
        //
        mEfiShellEnvironment2->DisablePageBreak ();
        return;
      }
    }
  }
}

///
/// version of EFI_SHELL_FILE_INFO struct, except has no CONST pointers.
/// This allows for the struct to be populated.
///
typedef struct {
  LIST_ENTRY           Link;
  EFI_STATUS           Status;
  CHAR16               *FullName;
  CHAR16               *FileName;
  SHELL_FILE_HANDLE    Handle;
  EFI_FILE_INFO        *Info;
} EFI_SHELL_FILE_INFO_NO_CONST;

/**
  Converts a EFI shell list of structures to the coresponding UEFI Shell 2.0 type of list.

  if OldStyleFileList is NULL then ASSERT()

  this function will convert a SHELL_FILE_ARG based list into a callee allocated
  EFI_SHELL_FILE_INFO based list.  it is up to the caller to free the memory via
  the ShellCloseFileMetaArg function.

  @param[in] FileList           the EFI shell list type
  @param[in, out] ListHead      the list to add to

  @retval the resultant head of the double linked new format list;
**/
LIST_ENTRY *
InternalShellConvertFileListType (
  IN LIST_ENTRY      *FileList,
  IN OUT LIST_ENTRY  *ListHead
  )
{
  SHELL_FILE_ARG                *OldInfo;
  LIST_ENTRY                    *Link;
  EFI_SHELL_FILE_INFO_NO_CONST  *NewInfo;

  //
  // ASSERTs
  //
  ASSERT (FileList  != NULL);
  ASSERT (ListHead  != NULL);

  //
  // enumerate through each member of the old list and copy
  //
  for (Link = FileList->ForwardLink; Link != FileList; Link = Link->ForwardLink) {
    OldInfo = CR (Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
    ASSERT (OldInfo           != NULL);

    //
    // Skip ones that failed to open...
    //
    if (OldInfo->Status != EFI_SUCCESS) {
      continue;
    }

    //
    // make sure the old list was valid
    //
    ASSERT (OldInfo->Info     != NULL);
    ASSERT (OldInfo->FullName != NULL);
    ASSERT (OldInfo->FileName != NULL);

    //
    // allocate a new EFI_SHELL_FILE_INFO object
    //
    NewInfo = AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
    if (NewInfo == NULL) {
      ShellCloseFileMetaArg ((EFI_SHELL_FILE_INFO **)(&ListHead));
      ListHead = NULL;
      break;
    }

    //
    // copy the simple items
    //
    NewInfo->Handle = OldInfo->Handle;
    NewInfo->Status = OldInfo->Status;

    // old shell checks for 0 not NULL
    OldInfo->Handle = 0;

    //
    // allocate new space to copy strings and structure
    //
    NewInfo->FullName = AllocateCopyPool (StrSize (OldInfo->FullName), OldInfo->FullName);
    NewInfo->FileName = AllocateCopyPool (StrSize (OldInfo->FileName), OldInfo->FileName);
    NewInfo->Info     = AllocateCopyPool ((UINTN)OldInfo->Info->Size, OldInfo->Info);

    //
    // make sure all the memory allocations were successful
    //
    if ((NULL == NewInfo->FullName) || (NewInfo->FileName == NULL) || (NewInfo->Info == NULL)) {
      //
      // Free the partially allocated new node
      //
      SHELL_FREE_NON_NULL (NewInfo->FullName);
      SHELL_FREE_NON_NULL (NewInfo->FileName);
      SHELL_FREE_NON_NULL (NewInfo->Info);
      SHELL_FREE_NON_NULL (NewInfo);

      //
      // Free the previously converted stuff
      //
      ShellCloseFileMetaArg ((EFI_SHELL_FILE_INFO **)(&ListHead));
      ListHead = NULL;
      break;
    }

    //
    // add that to the list
    //
    InsertTailList (ListHead, &NewInfo->Link);
  }

  return (ListHead);
}

/**
  Opens a group of files based on a path.

  This function uses the Arg to open all the matching files. Each matched
  file has a SHELL_FILE_INFO structure to record the file information. These
  structures are placed on the list ListHead. Users can get the SHELL_FILE_INFO
  structures from ListHead to access each file. This function supports wildcards
  and will process '?' and '*' as such.  the list must be freed with a call to
  ShellCloseFileMetaArg().

  If you are NOT appending to an existing list *ListHead must be NULL.  If
  *ListHead is NULL then it must be callee freed.

  @param Arg                    pointer to path string
  @param OpenMode               mode to open files with
  @param ListHead               head of linked list of results

  @retval EFI_SUCCESS           the operation was successful and the list head
                                contains the list of opened files
  @return != EFI_SUCCESS        the operation failed

  @sa InternalShellConvertFileListType
**/
EFI_STATUS
EFIAPI
ShellOpenFileMetaArg (
  IN CHAR16                   *Arg,
  IN UINT64                   OpenMode,
  IN OUT EFI_SHELL_FILE_INFO  **ListHead
  )
{
  EFI_STATUS  Status;
  LIST_ENTRY  mOldStyleFileList;
  CHAR16      *CleanFilePathStr;

  //
  // ASSERT that Arg and ListHead are not NULL
  //
  ASSERT (Arg      != NULL);
  ASSERT (ListHead != NULL);

  CleanFilePathStr = NULL;

  Status = InternalShellStripQuotes (Arg, &CleanFilePathStr);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    if (*ListHead == NULL) {
      *ListHead = (EFI_SHELL_FILE_INFO *)AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
      if (*ListHead == NULL) {
        FreePool (CleanFilePathStr);
        return (EFI_OUT_OF_RESOURCES);
      }

      InitializeListHead (&((*ListHead)->Link));
    }

    Status = gEfiShellProtocol->OpenFileList (
                                  CleanFilePathStr,
                                  OpenMode,
                                  ListHead
                                  );
    if (EFI_ERROR (Status)) {
      gEfiShellProtocol->RemoveDupInFileList (ListHead);
    } else {
      Status = gEfiShellProtocol->RemoveDupInFileList (ListHead);
    }

    if ((*ListHead != NULL) && IsListEmpty (&(*ListHead)->Link)) {
      FreePool (*ListHead);
      FreePool (CleanFilePathStr);
      *ListHead = NULL;
      return (EFI_NOT_FOUND);
    }

    FreePool (CleanFilePathStr);
    return (Status);
  }

  //
  // Check for EFI shell
  //
  if (mEfiShellEnvironment2 != NULL) {
    //
    // make sure the list head is initialized
    //
    InitializeListHead (&mOldStyleFileList);

    //
    // Get the EFI Shell list of files
    //
    Status = mEfiShellEnvironment2->FileMetaArg (CleanFilePathStr, &mOldStyleFileList);
    if (EFI_ERROR (Status)) {
      *ListHead = NULL;
      FreePool (CleanFilePathStr);
      return (Status);
    }

    if (*ListHead == NULL) {
      *ListHead = (EFI_SHELL_FILE_INFO    *)AllocateZeroPool (sizeof (EFI_SHELL_FILE_INFO));
      if (*ListHead == NULL) {
        FreePool (CleanFilePathStr);
        return (EFI_OUT_OF_RESOURCES);
      }

      InitializeListHead (&((*ListHead)->Link));
    }

    //
    // Convert that to equivalent of UEFI Shell 2.0 structure
    //
    InternalShellConvertFileListType (&mOldStyleFileList, &(*ListHead)->Link);

    //
    // Free the EFI Shell version that was converted.
    //
    mEfiShellEnvironment2->FreeFileList (&mOldStyleFileList);

    if (((*ListHead)->Link.ForwardLink == (*ListHead)->Link.BackLink) && ((*ListHead)->Link.BackLink == &((*ListHead)->Link))) {
      FreePool (*ListHead);
      *ListHead = NULL;
      Status    = EFI_NOT_FOUND;
    }

    FreePool (CleanFilePathStr);
    return (Status);
  }

  FreePool (CleanFilePathStr);
  return (EFI_UNSUPPORTED);
}

/**
  Free the linked list returned from ShellOpenFileMetaArg.

  if ListHead is NULL then ASSERT().

  @param ListHead               the pointer to free.

  @retval EFI_SUCCESS           the operation was successful.
**/
EFI_STATUS
EFIAPI
ShellCloseFileMetaArg (
  IN OUT EFI_SHELL_FILE_INFO  **ListHead
  )
{
  LIST_ENTRY  *Node;

  //
  // ASSERT that ListHead is not NULL
  //
  ASSERT (ListHead != NULL);

  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    return (gEfiShellProtocol->FreeFileList (ListHead));
  } else if (mEfiShellEnvironment2 != NULL) {
    //
    // Since this is EFI Shell version we need to free our internally made copy
    // of the list
    //
    for ( Node = GetFirstNode (&(*ListHead)->Link)
          ; *ListHead != NULL && !IsListEmpty (&(*ListHead)->Link)
          ; Node = GetFirstNode (&(*ListHead)->Link))
    {
      RemoveEntryList (Node);
      ((EFI_FILE_PROTOCOL *)((EFI_SHELL_FILE_INFO_NO_CONST *)Node)->Handle)->Close (((EFI_SHELL_FILE_INFO_NO_CONST *)Node)->Handle);
      FreePool (((EFI_SHELL_FILE_INFO_NO_CONST *)Node)->FullName);
      FreePool (((EFI_SHELL_FILE_INFO_NO_CONST *)Node)->FileName);
      FreePool (((EFI_SHELL_FILE_INFO_NO_CONST *)Node)->Info);
      FreePool ((EFI_SHELL_FILE_INFO_NO_CONST *)Node);
    }

    SHELL_FREE_NON_NULL (*ListHead);
    return EFI_SUCCESS;
  }

  return (EFI_UNSUPPORTED);
}

/**
  Find a file by searching the CWD and then the path.

  If FileName is NULL then ASSERT.

  If the return value is not NULL then the memory must be caller freed.

  @param FileName               Filename string.

  @retval NULL                  the file was not found
  @return !NULL                 the full path to the file.
**/
CHAR16 *
EFIAPI
ShellFindFilePath (
  IN CONST CHAR16  *FileName
  )
{
  CONST CHAR16       *Path;
  SHELL_FILE_HANDLE  Handle;
  EFI_STATUS         Status;
  CHAR16             *RetVal;
  CHAR16             *TestPath;
  CONST CHAR16       *Walker;
  UINTN              Size;
  CHAR16             *TempChar;

  RetVal = NULL;

  //
  // First make sure its not an absolute path.
  //
  Status = ShellOpenFileByName (FileName, &Handle, EFI_FILE_MODE_READ, 0);
  if (!EFI_ERROR (Status)) {
    if (FileHandleIsDirectory (Handle) != EFI_SUCCESS) {
      ASSERT (RetVal == NULL);
      RetVal = StrnCatGrow (&RetVal, NULL, FileName, 0);
      ShellCloseFile (&Handle);
      return (RetVal);
    } else {
      ShellCloseFile (&Handle);
    }
  }

  Path = ShellGetEnvironmentVariable (L"cwd");
  if (Path != NULL) {
    Size     = StrSize (Path) + sizeof (CHAR16);
    Size    += StrSize (FileName);
    TestPath = AllocateZeroPool (Size);
    if (TestPath == NULL) {
      return (NULL);
    }

    StrCpyS (TestPath, Size/sizeof (CHAR16), Path);
    StrCatS (TestPath, Size/sizeof (CHAR16), L"\\");
    StrCatS (TestPath, Size/sizeof (CHAR16), FileName);
    Status = ShellOpenFileByName (TestPath, &Handle, EFI_FILE_MODE_READ, 0);
    if (!EFI_ERROR (Status)) {
      if (FileHandleIsDirectory (Handle) != EFI_SUCCESS) {
        ASSERT (RetVal == NULL);
        RetVal = StrnCatGrow (&RetVal, NULL, TestPath, 0);
        ShellCloseFile (&Handle);
        FreePool (TestPath);
        return (RetVal);
      } else {
        ShellCloseFile (&Handle);
      }
    }

    FreePool (TestPath);
  }

  Path = ShellGetEnvironmentVariable (L"path");
  if (Path != NULL) {
    Size     = StrSize (Path)+sizeof (CHAR16);
    Size    += StrSize (FileName);
    TestPath = AllocateZeroPool (Size);
    if (TestPath == NULL) {
      return (NULL);
    }

    Walker = (CHAR16 *)Path;
    do {
      CopyMem (TestPath, Walker, StrSize (Walker));
      if (TestPath != NULL) {
        TempChar = StrStr (TestPath, L";");
        if (TempChar != NULL) {
          *TempChar = CHAR_NULL;
        }

        if (TestPath[StrLen (TestPath)-1] != L'\\') {
          StrCatS (TestPath, Size/sizeof (CHAR16), L"\\");
        }

        if (FileName[0] == L'\\') {
          FileName++;
        }

        StrCatS (TestPath, Size/sizeof (CHAR16), FileName);
        if (StrStr (Walker, L";") != NULL) {
          Walker = StrStr (Walker, L";") + 1;
        } else {
          Walker = NULL;
        }

        Status = ShellOpenFileByName (TestPath, &Handle, EFI_FILE_MODE_READ, 0);
        if (!EFI_ERROR (Status)) {
          if (FileHandleIsDirectory (Handle) != EFI_SUCCESS) {
            ASSERT (RetVal == NULL);
            RetVal = StrnCatGrow (&RetVal, NULL, TestPath, 0);
            ShellCloseFile (&Handle);
            break;
          } else {
            ShellCloseFile (&Handle);
          }
        }
      }
    } while (Walker != NULL && Walker[0] != CHAR_NULL);

    FreePool (TestPath);
  }

  return (RetVal);
}

/**
  Find a file by searching the CWD and then the path with a variable set of file
  extensions.  If the file is not found it will append each extension in the list
  in the order provided and return the first one that is successful.

  If FileName is NULL, then ASSERT.
  If FileExtension is NULL, then behavior is identical to ShellFindFilePath.

  If the return value is not NULL then the memory must be caller freed.

  @param[in] FileName           Filename string.
  @param[in] FileExtension      Semi-colon delimeted list of possible extensions.

  @retval NULL                  The file was not found.
  @retval !NULL                 The path to the file.
**/
CHAR16 *
EFIAPI
ShellFindFilePathEx (
  IN CONST CHAR16  *FileName,
  IN CONST CHAR16  *FileExtension
  )
{
  CHAR16        *TestPath;
  CHAR16        *RetVal;
  CONST CHAR16  *ExtensionWalker;
  UINTN         Size;
  CHAR16        *TempChar;
  CHAR16        *TempChar2;

  ASSERT (FileName != NULL);
  if (FileExtension == NULL) {
    return (ShellFindFilePath (FileName));
  }

  RetVal = ShellFindFilePath (FileName);
  if (RetVal != NULL) {
    return (RetVal);
  }

  Size     =  StrSize (FileName);
  Size    += StrSize (FileExtension);
  TestPath = AllocateZeroPool (Size);
  if (TestPath == NULL) {
    return (NULL);
  }

  for (ExtensionWalker = FileExtension, TempChar2 = (CHAR16 *)FileExtension; TempChar2 != NULL; ExtensionWalker = TempChar2 + 1) {
    StrCpyS (TestPath, Size/sizeof (CHAR16), FileName);
    if (ExtensionWalker != NULL) {
      StrCatS (TestPath, Size/sizeof (CHAR16), ExtensionWalker);
    }

    TempChar = StrStr (TestPath, L";");
    if (TempChar != NULL) {
      *TempChar = CHAR_NULL;
    }

    RetVal = ShellFindFilePath (TestPath);
    if (RetVal != NULL) {
      break;
    }

    ASSERT (ExtensionWalker != NULL);
    TempChar2 = StrStr (ExtensionWalker, L";");
  }

  FreePool (TestPath);
  return (RetVal);
}

typedef struct {
  LIST_ENTRY          Link;
  CHAR16              *Name;
  SHELL_PARAM_TYPE    Type;
  CHAR16              *Value;
  UINTN               OriginalPosition;
} SHELL_PARAM_PACKAGE;

/**
  Checks the list of valid arguments and returns TRUE if the item was found.  If the
  return value is TRUE then the type parameter is set also.

  if CheckList is NULL then ASSERT();
  if Name is NULL then ASSERT();
  if Type is NULL then ASSERT();

  @param Name                   pointer to Name of parameter found
  @param CheckList              List to check against
  @param Type                   pointer to type of parameter if it was found

  @retval TRUE                  the Parameter was found.  Type is valid.
  @retval FALSE                 the Parameter was not found.  Type is not valid.
**/
BOOLEAN
InternalIsOnCheckList (
  IN CONST CHAR16            *Name,
  IN CONST SHELL_PARAM_ITEM  *CheckList,
  OUT SHELL_PARAM_TYPE       *Type
  )
{
  SHELL_PARAM_ITEM  *TempListItem;
  CHAR16            *TempString;

  //
  // ASSERT that all 3 pointer parameters aren't NULL
  //
  ASSERT (CheckList  != NULL);
  ASSERT (Type       != NULL);
  ASSERT (Name       != NULL);

  //
  // question mark and page break mode are always supported
  //
  if ((StrCmp (Name, L"-?") == 0) ||
      (StrCmp (Name, L"-b") == 0)
      )
  {
    *Type = TypeFlag;
    return (TRUE);
  }

  //
  // Enumerate through the list
  //
  for (TempListItem = (SHELL_PARAM_ITEM *)CheckList; TempListItem->Name != NULL; TempListItem++) {
    //
    // If the Type is TypeStart only check the first characters of the passed in param
    // If it matches set the type and return TRUE
    //
    if (TempListItem->Type == TypeStart) {
      if (StrnCmp (Name, TempListItem->Name, StrLen (TempListItem->Name)) == 0) {
        *Type = TempListItem->Type;
        return (TRUE);
      }

      TempString = NULL;
      TempString = StrnCatGrow (&TempString, NULL, Name, StrLen (TempListItem->Name));
      if (TempString != NULL) {
        if (StringNoCaseCompare (&TempString, &TempListItem->Name) == 0) {
          *Type = TempListItem->Type;
          FreePool (TempString);
          return (TRUE);
        }

        FreePool (TempString);
      }
    } else if (StringNoCaseCompare (&Name, &TempListItem->Name) == 0) {
      *Type = TempListItem->Type;
      return (TRUE);
    }
  }

  return (FALSE);
}

/**
  Checks the string for indicators of "flag" status.  this is a leading '/', '-', or '+'

  @param[in] Name               pointer to Name of parameter found
  @param[in] AlwaysAllowNumbers TRUE to allow numbers, FALSE to not.
  @param[in] TimeNumbers        TRUE to allow numbers with ":", FALSE otherwise.

  @retval TRUE                  the Parameter is a flag.
  @retval FALSE                 the Parameter not a flag.
**/
BOOLEAN
InternalIsFlag (
  IN CONST CHAR16   *Name,
  IN CONST BOOLEAN  AlwaysAllowNumbers,
  IN CONST BOOLEAN  TimeNumbers
  )
{
  //
  // ASSERT that Name isn't NULL
  //
  ASSERT (Name != NULL);

  //
  // If we accept numbers then dont return TRUE. (they will be values)
  //
  if ((((Name[0] == L'-') || (Name[0] == L'+')) && InternalShellIsHexOrDecimalNumber (Name+1, FALSE, FALSE, TimeNumbers)) && AlwaysAllowNumbers) {
    return (FALSE);
  }

  //
  // If the Name has a /, +, or - as the first character return TRUE
  //
  if ((Name[0] == L'/') ||
      (Name[0] == L'-') ||
      (Name[0] == L'+')
      )
  {
    return (TRUE);
  }

  return (FALSE);
}

/**
  Checks the command line arguments passed against the list of valid ones.

  If no initialization is required, then return RETURN_SUCCESS.

  @param[in] CheckList          pointer to list of parameters to check
  @param[out] CheckPackage      pointer to pointer to list checked values
  @param[out] ProblemParam      optional pointer to pointer to unicode string for
                                the paramater that caused failure.  If used then the
                                caller is responsible for freeing the memory.
  @param[in] AutoPageBreak      will automatically set PageBreakEnabled for "b" parameter
  @param[in] Argv               pointer to array of parameters
  @param[in] Argc               Count of parameters in Argv
  @param[in] AlwaysAllowNumbers TRUE to allow numbers always, FALSE otherwise.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed
  @retval EFI_INVALID_PARAMETER A parameter was invalid
  @retval EFI_VOLUME_CORRUPTED  the command line was corrupt.  an argument was
                                duplicated.  the duplicated command line argument
                                was returned in ProblemParam if provided.
  @retval EFI_NOT_FOUND         a argument required a value that was missing.
                                the invalid command line argument was returned in
                                ProblemParam if provided.
**/
EFI_STATUS
InternalCommandLineParse (
  IN CONST SHELL_PARAM_ITEM  *CheckList,
  OUT LIST_ENTRY             **CheckPackage,
  OUT CHAR16                 **ProblemParam OPTIONAL,
  IN BOOLEAN                 AutoPageBreak,
  IN CONST CHAR16            **Argv,
  IN UINTN                   Argc,
  IN BOOLEAN                 AlwaysAllowNumbers
  )
{
  UINTN                LoopCounter;
  SHELL_PARAM_TYPE     CurrentItemType;
  SHELL_PARAM_PACKAGE  *CurrentItemPackage;
  UINTN                GetItemValue;
  UINTN                ValueSize;
  UINTN                Count;
  CONST CHAR16         *TempPointer;
  UINTN                CurrentValueSize;
  CHAR16               *NewValue;

  CurrentItemPackage = NULL;
  GetItemValue       = 0;
  ValueSize          = 0;
  Count              = 0;

  //
  // If there is only 1 item we dont need to do anything
  //
  if (Argc < 1) {
    *CheckPackage = NULL;
    return (EFI_SUCCESS);
  }

  //
  // ASSERTs
  //
  ASSERT (CheckList  != NULL);
  ASSERT (Argv       != NULL);

  //
  // initialize the linked list
  //
  *CheckPackage = (LIST_ENTRY *)AllocateZeroPool (sizeof (LIST_ENTRY));
  if (*CheckPackage == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  InitializeListHead (*CheckPackage);

  //
  // loop through each of the arguments
  //
  for (LoopCounter = 0; LoopCounter < Argc; ++LoopCounter) {
    if (Argv[LoopCounter] == NULL) {
      //
      // do nothing for NULL argv
      //
    } else if (InternalIsOnCheckList (Argv[LoopCounter], CheckList, &CurrentItemType)) {
      //
      // We might have leftover if last parameter didnt have optional value
      //
      if (GetItemValue != 0) {
        GetItemValue = 0;
        InsertHeadList (*CheckPackage, &CurrentItemPackage->Link);
      }

      //
      // this is a flag
      //
      CurrentItemPackage = AllocateZeroPool (sizeof (SHELL_PARAM_PACKAGE));
      if (CurrentItemPackage == NULL) {
        ShellCommandLineFreeVarList (*CheckPackage);
        *CheckPackage = NULL;
        return (EFI_OUT_OF_RESOURCES);
      }

      CurrentItemPackage->Name = AllocateCopyPool (StrSize (Argv[LoopCounter]), Argv[LoopCounter]);
      if (CurrentItemPackage->Name == NULL) {
        ShellCommandLineFreeVarList (*CheckPackage);
        *CheckPackage = NULL;
        return (EFI_OUT_OF_RESOURCES);
      }

      CurrentItemPackage->Type             = CurrentItemType;
      CurrentItemPackage->OriginalPosition = (UINTN)(-1);
      CurrentItemPackage->Value            = NULL;

      //
      // Does this flag require a value
      //
      switch (CurrentItemPackage->Type) {
        //
        // possibly trigger the next loop(s) to populate the value of this item
        //
        case TypeValue:
        case TypeTimeValue:
          GetItemValue = 1;
          ValueSize    = 0;
          break;
        case TypeDoubleValue:
          GetItemValue = 2;
          ValueSize    = 0;
          break;
        case TypeMaxValue:
          GetItemValue = (UINTN)(-1);
          ValueSize    = 0;
          break;
        default:
          //
          // this item has no value expected; we are done
          //
          InsertHeadList (*CheckPackage, &CurrentItemPackage->Link);
          ASSERT (GetItemValue == 0);
          break;
      }
    } else if ((GetItemValue != 0) && (CurrentItemPackage != NULL) && !InternalIsFlag (Argv[LoopCounter], AlwaysAllowNumbers, (BOOLEAN)(CurrentItemPackage->Type == TypeTimeValue))) {
      //
      // get the item VALUE for a previous flag
      //
      CurrentValueSize = ValueSize + StrSize (Argv[LoopCounter]) + sizeof (CHAR16);
      NewValue         = ReallocatePool (ValueSize, CurrentValueSize, CurrentItemPackage->Value);
      if (NewValue == NULL) {
        SHELL_FREE_NON_NULL (CurrentItemPackage->Value);
        SHELL_FREE_NON_NULL (CurrentItemPackage);
        ShellCommandLineFreeVarList (*CheckPackage);
        *CheckPackage = NULL;
        return EFI_OUT_OF_RESOURCES;
      }

      CurrentItemPackage->Value = NewValue;
      if (ValueSize == 0) {
        StrCpyS (
          CurrentItemPackage->Value,
          CurrentValueSize/sizeof (CHAR16),
          Argv[LoopCounter]
          );
      } else {
        StrCatS (
          CurrentItemPackage->Value,
          CurrentValueSize/sizeof (CHAR16),
          L" "
          );
        StrCatS (
          CurrentItemPackage->Value,
          CurrentValueSize/sizeof (CHAR16),
          Argv[LoopCounter]
          );
      }

      ValueSize += StrSize (Argv[LoopCounter]) + sizeof (CHAR16);

      GetItemValue--;
      if (GetItemValue == 0) {
        InsertHeadList (*CheckPackage, &CurrentItemPackage->Link);
      }
    } else if (!InternalIsFlag (Argv[LoopCounter], AlwaysAllowNumbers, FALSE)) {
      //
      // add this one as a non-flag
      //

      TempPointer = Argv[LoopCounter];
      if (  ((*TempPointer == L'^') && (*(TempPointer+1) == L'-'))
         || ((*TempPointer == L'^') && (*(TempPointer+1) == L'/'))
         || ((*TempPointer == L'^') && (*(TempPointer+1) == L'+'))
            )
      {
        TempPointer++;
      }

      CurrentItemPackage = AllocateZeroPool (sizeof (SHELL_PARAM_PACKAGE));
      if (CurrentItemPackage == NULL) {
        ShellCommandLineFreeVarList (*CheckPackage);
        *CheckPackage = NULL;
        return (EFI_OUT_OF_RESOURCES);
      }

      CurrentItemPackage->Name  = NULL;
      CurrentItemPackage->Type  = TypePosition;
      CurrentItemPackage->Value = AllocateCopyPool (StrSize (TempPointer), TempPointer);
      if (CurrentItemPackage->Value == NULL) {
        ShellCommandLineFreeVarList (*CheckPackage);
        *CheckPackage = NULL;
        return (EFI_OUT_OF_RESOURCES);
      }

      CurrentItemPackage->OriginalPosition = Count++;
      InsertHeadList (*CheckPackage, &CurrentItemPackage->Link);
    } else {
      //
      // this was a non-recognised flag... error!
      //
      if (ProblemParam != NULL) {
        *ProblemParam = AllocateCopyPool (StrSize (Argv[LoopCounter]), Argv[LoopCounter]);
      }

      ShellCommandLineFreeVarList (*CheckPackage);
      *CheckPackage = NULL;
      return (EFI_VOLUME_CORRUPTED);
    }
  }

  if (GetItemValue != 0) {
    GetItemValue = 0;
    InsertHeadList (*CheckPackage, &CurrentItemPackage->Link);
  }

  //
  // support for AutoPageBreak
  //
  if (AutoPageBreak && ShellCommandLineGetFlag (*CheckPackage, L"-b")) {
    ShellSetPageBreakMode (TRUE);
  }

  return (EFI_SUCCESS);
}

/**
  Checks the command line arguments passed against the list of valid ones.
  Optionally removes NULL values first.

  If no initialization is required, then return RETURN_SUCCESS.

  @param[in] CheckList          The pointer to list of parameters to check.
  @param[out] CheckPackage      The package of checked values.
  @param[out] ProblemParam      Optional pointer to pointer to unicode string for
                                the paramater that caused failure.
  @param[in] AutoPageBreak      Will automatically set PageBreakEnabled.
  @param[in] AlwaysAllowNumbers Will never fail for number based flags.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_INVALID_PARAMETER A parameter was invalid.
  @retval EFI_VOLUME_CORRUPTED  The command line was corrupt.
  @retval EFI_DEVICE_ERROR      The commands contained 2 opposing arguments.  One
                                of the command line arguments was returned in
                                ProblemParam if provided.
  @retval EFI_NOT_FOUND         A argument required a value that was missing.
                                The invalid command line argument was returned in
                                ProblemParam if provided.
**/
EFI_STATUS
EFIAPI
ShellCommandLineParseEx (
  IN CONST SHELL_PARAM_ITEM  *CheckList,
  OUT LIST_ENTRY             **CheckPackage,
  OUT CHAR16                 **ProblemParam OPTIONAL,
  IN BOOLEAN                 AutoPageBreak,
  IN BOOLEAN                 AlwaysAllowNumbers
  )
{
  //
  // ASSERT that CheckList and CheckPackage aren't NULL
  //
  ASSERT (CheckList    != NULL);
  ASSERT (CheckPackage != NULL);

  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellParametersProtocol != NULL) {
    return (InternalCommandLineParse (
              CheckList,
              CheckPackage,
              ProblemParam,
              AutoPageBreak,
              (CONST CHAR16 **)gEfiShellParametersProtocol->Argv,
              gEfiShellParametersProtocol->Argc,
              AlwaysAllowNumbers
              ));
  }

  //
  // ASSERT That EFI Shell is not required
  //
  ASSERT (mEfiShellInterface != NULL);
  return (InternalCommandLineParse (
            CheckList,
            CheckPackage,
            ProblemParam,
            AutoPageBreak,
            (CONST CHAR16 **)mEfiShellInterface->Argv,
            mEfiShellInterface->Argc,
            AlwaysAllowNumbers
            ));
}

/**
  Frees shell variable list that was returned from ShellCommandLineParse.

  This function will free all the memory that was used for the CheckPackage
  list of postprocessed shell arguments.

  this function has no return value.

  if CheckPackage is NULL, then return

  @param CheckPackage           the list to de-allocate
  **/
VOID
EFIAPI
ShellCommandLineFreeVarList (
  IN LIST_ENTRY  *CheckPackage
  )
{
  LIST_ENTRY  *Node;

  //
  // check for CheckPackage == NULL
  //
  if (CheckPackage == NULL) {
    return;
  }

  //
  // for each node in the list
  //
  for ( Node = GetFirstNode (CheckPackage)
        ; !IsListEmpty (CheckPackage)
        ; Node = GetFirstNode (CheckPackage)
        )
  {
    //
    // Remove it from the list
    //
    RemoveEntryList (Node);

    //
    // if it has a name free the name
    //
    if (((SHELL_PARAM_PACKAGE *)Node)->Name != NULL) {
      FreePool (((SHELL_PARAM_PACKAGE *)Node)->Name);
    }

    //
    // if it has a value free the value
    //
    if (((SHELL_PARAM_PACKAGE *)Node)->Value != NULL) {
      FreePool (((SHELL_PARAM_PACKAGE *)Node)->Value);
    }

    //
    // free the node structure
    //
    FreePool ((SHELL_PARAM_PACKAGE *)Node);
  }

  //
  // free the list head node
  //
  FreePool (CheckPackage);
}

/**
  Checks for presence of a flag parameter

  flag arguments are in the form of "-<Key>" or "/<Key>", but do not have a value following the key

  if CheckPackage is NULL then return FALSE.
  if KeyString is NULL then ASSERT()

  @param CheckPackage           The package of parsed command line arguments
  @param KeyString              the Key of the command line argument to check for

  @retval TRUE                  the flag is on the command line
  @retval FALSE                 the flag is not on the command line
  **/
BOOLEAN
EFIAPI
ShellCommandLineGetFlag (
  IN CONST LIST_ENTRY         *CONST  CheckPackage,
  IN CONST CHAR16             *CONST  KeyString
  )
{
  LIST_ENTRY  *Node;
  CHAR16      *TempString;

  //
  // return FALSE for no package or KeyString is NULL
  //
  if ((CheckPackage == NULL) || (KeyString == NULL)) {
    return (FALSE);
  }

  //
  // enumerate through the list of parametrs
  //
  for ( Node = GetFirstNode (CheckPackage)
        ; !IsNull (CheckPackage, Node)
        ; Node = GetNextNode (CheckPackage, Node)
        )
  {
    //
    // If the Name matches, return TRUE (and there may be NULL name)
    //
    if (((SHELL_PARAM_PACKAGE *)Node)->Name != NULL) {
      //
      // If Type is TypeStart then only compare the begining of the strings
      //
      if (((SHELL_PARAM_PACKAGE *)Node)->Type == TypeStart) {
        if (StrnCmp (KeyString, ((SHELL_PARAM_PACKAGE *)Node)->Name, StrLen (KeyString)) == 0) {
          return (TRUE);
        }

        TempString = NULL;
        TempString = StrnCatGrow (&TempString, NULL, KeyString, StrLen (((SHELL_PARAM_PACKAGE *)Node)->Name));
        if (TempString != NULL) {
          if (StringNoCaseCompare (&KeyString, &((SHELL_PARAM_PACKAGE *)Node)->Name) == 0) {
            FreePool (TempString);
            return (TRUE);
          }

          FreePool (TempString);
        }
      } else if (StringNoCaseCompare (&KeyString, &((SHELL_PARAM_PACKAGE *)Node)->Name) == 0) {
        return (TRUE);
      }
    }
  }

  return (FALSE);
}

/**
  Returns value from command line argument.

  Value parameters are in the form of "-<Key> value" or "/<Key> value".

  If CheckPackage is NULL, then return NULL.

  @param[in] CheckPackage       The package of parsed command line arguments.
  @param[in] KeyString          The Key of the command line argument to check for.

  @retval NULL                  The flag is not on the command line.
  @retval !=NULL                The pointer to unicode string of the value.
**/
CONST CHAR16 *
EFIAPI
ShellCommandLineGetValue (
  IN CONST LIST_ENTRY  *CheckPackage,
  IN CHAR16            *KeyString
  )
{
  LIST_ENTRY  *Node;
  CHAR16      *TempString;

  //
  // return NULL for no package or KeyString is NULL
  //
  if ((CheckPackage == NULL) || (KeyString == NULL)) {
    return (NULL);
  }

  //
  // enumerate through the list of parametrs
  //
  for ( Node = GetFirstNode (CheckPackage)
        ; !IsNull (CheckPackage, Node)
        ; Node = GetNextNode (CheckPackage, Node)
        )
  {
    //
    // If the Name matches, return TRUE (and there may be NULL name)
    //
    if (((SHELL_PARAM_PACKAGE *)Node)->Name != NULL) {
      //
      // If Type is TypeStart then only compare the begining of the strings
      //
      if (((SHELL_PARAM_PACKAGE *)Node)->Type == TypeStart) {
        if (StrnCmp (KeyString, ((SHELL_PARAM_PACKAGE *)Node)->Name, StrLen (KeyString)) == 0) {
          return (((SHELL_PARAM_PACKAGE *)Node)->Name + StrLen (KeyString));
        }

        TempString = NULL;
        TempString = StrnCatGrow (&TempString, NULL, KeyString, StrLen (((SHELL_PARAM_PACKAGE *)Node)->Name));
        if (TempString != NULL) {
          if (StringNoCaseCompare (&KeyString, &((SHELL_PARAM_PACKAGE *)Node)->Name) == 0) {
            FreePool (TempString);
            return (((SHELL_PARAM_PACKAGE *)Node)->Name + StrLen (KeyString));
          }

          FreePool (TempString);
        }
      } else if (StringNoCaseCompare (&KeyString, &((SHELL_PARAM_PACKAGE *)Node)->Name) == 0) {
        return (((SHELL_PARAM_PACKAGE *)Node)->Value);
      }
    }
  }

  return (NULL);
}

/**
  Returns raw value from command line argument.

  Raw value parameters are in the form of "value" in a specific position in the list.

  If CheckPackage is NULL, then return NULL.

  @param[in] CheckPackage       The package of parsed command line arguments.
  @param[in] Position           The position of the value.

  @retval NULL                  The flag is not on the command line.
  @retval !=NULL                The pointer to unicode string of the value.
  **/
CONST CHAR16 *
EFIAPI
ShellCommandLineGetRawValue (
  IN CONST LIST_ENTRY           *CONST  CheckPackage,
  IN UINTN                              Position
  )
{
  LIST_ENTRY  *Node;

  //
  // check for CheckPackage == NULL
  //
  if (CheckPackage == NULL) {
    return (NULL);
  }

  //
  // enumerate through the list of parametrs
  //
  for ( Node = GetFirstNode (CheckPackage)
        ; !IsNull (CheckPackage, Node)
        ; Node = GetNextNode (CheckPackage, Node)
        )
  {
    //
    // If the position matches, return the value
    //
    if (((SHELL_PARAM_PACKAGE *)Node)->OriginalPosition == Position) {
      return (((SHELL_PARAM_PACKAGE *)Node)->Value);
    }
  }

  return (NULL);
}

/**
  returns the number of command line value parameters that were parsed.

  this will not include flags.

  @param[in] CheckPackage       The package of parsed command line arguments.

  @retval (UINTN)-1     No parsing has ocurred
  @return other         The number of value parameters found
**/
UINTN
EFIAPI
ShellCommandLineGetCount (
  IN CONST LIST_ENTRY  *CheckPackage
  )
{
  LIST_ENTRY  *Node1;
  UINTN       Count;

  if (CheckPackage == NULL) {
    return (0);
  }

  for ( Node1 = GetFirstNode (CheckPackage), Count = 0
        ; !IsNull (CheckPackage, Node1)
        ; Node1 = GetNextNode (CheckPackage, Node1)
        )
  {
    if (((SHELL_PARAM_PACKAGE *)Node1)->Name == NULL) {
      Count++;
    }
  }

  return (Count);
}

/**
  Determines if a parameter is duplicated.

  If Param is not NULL then it will point to a callee allocated string buffer
  with the parameter value if a duplicate is found.

  If CheckPackage is NULL, then ASSERT.

  @param[in] CheckPackage       The package of parsed command line arguments.
  @param[out] Param             Upon finding one, a pointer to the duplicated parameter.

  @retval EFI_SUCCESS           No parameters were duplicated.
  @retval EFI_DEVICE_ERROR      A duplicate was found.
  **/
EFI_STATUS
EFIAPI
ShellCommandLineCheckDuplicate (
  IN CONST LIST_ENTRY  *CheckPackage,
  OUT CHAR16           **Param
  )
{
  LIST_ENTRY  *Node1;
  LIST_ENTRY  *Node2;

  ASSERT (CheckPackage != NULL);

  for ( Node1 = GetFirstNode (CheckPackage)
        ; !IsNull (CheckPackage, Node1)
        ; Node1 = GetNextNode (CheckPackage, Node1)
        )
  {
    for ( Node2 = GetNextNode (CheckPackage, Node1)
          ; !IsNull (CheckPackage, Node2)
          ; Node2 = GetNextNode (CheckPackage, Node2)
          )
    {
      if ((((SHELL_PARAM_PACKAGE *)Node1)->Name != NULL) && (((SHELL_PARAM_PACKAGE *)Node2)->Name != NULL) && (StrCmp (((SHELL_PARAM_PACKAGE *)Node1)->Name, ((SHELL_PARAM_PACKAGE *)Node2)->Name) == 0)) {
        if (Param != NULL) {
          *Param = NULL;
          *Param = StrnCatGrow (Param, NULL, ((SHELL_PARAM_PACKAGE *)Node1)->Name, 0);
        }

        return (EFI_DEVICE_ERROR);
      }
    }
  }

  return (EFI_SUCCESS);
}

/**
  This is a find and replace function.  Upon successful return the NewString is a copy of
  SourceString with each instance of FindTarget replaced with ReplaceWith.

  If SourceString and NewString overlap the behavior is undefined.

  If the string would grow bigger than NewSize it will halt and return error.

  @param[in] SourceString              The string with source buffer.
  @param[in, out] NewString            The string with resultant buffer.
  @param[in] NewSize                   The size in bytes of NewString.
  @param[in] FindTarget                The string to look for.
  @param[in] ReplaceWith               The string to replace FindTarget with.
  @param[in] SkipPreCarrot             If TRUE will skip a FindTarget that has a '^'
                                       immediately before it.
  @param[in] ParameterReplacing        If TRUE will add "" around items with spaces.

  @retval EFI_INVALID_PARAMETER       SourceString was NULL.
  @retval EFI_INVALID_PARAMETER       NewString was NULL.
  @retval EFI_INVALID_PARAMETER       FindTarget was NULL.
  @retval EFI_INVALID_PARAMETER       ReplaceWith was NULL.
  @retval EFI_INVALID_PARAMETER       FindTarget had length < 1.
  @retval EFI_INVALID_PARAMETER       SourceString had length < 1.
  @retval EFI_BUFFER_TOO_SMALL        NewSize was less than the minimum size to hold
                                      the new string (truncation occurred).
  @retval EFI_SUCCESS                 The string was successfully copied with replacement.
**/
EFI_STATUS
EFIAPI
ShellCopySearchAndReplace (
  IN CHAR16 CONST   *SourceString,
  IN OUT CHAR16     *NewString,
  IN UINTN          NewSize,
  IN CONST CHAR16   *FindTarget,
  IN CONST CHAR16   *ReplaceWith,
  IN CONST BOOLEAN  SkipPreCarrot,
  IN CONST BOOLEAN  ParameterReplacing
  )
{
  UINTN   Size;
  CHAR16  *Replace;

  if (  (SourceString == NULL)
     || (NewString    == NULL)
     || (FindTarget   == NULL)
     || (ReplaceWith  == NULL)
     || (StrLen (FindTarget) < 1)
     || (StrLen (SourceString) < 1)
        )
  {
    return (EFI_INVALID_PARAMETER);
  }

  Replace = NULL;
  if ((StrStr (ReplaceWith, L" ") == NULL) || !ParameterReplacing) {
    Replace = StrnCatGrow (&Replace, NULL, ReplaceWith, 0);
  } else {
    Replace = AllocateZeroPool (StrSize (ReplaceWith) + 2*sizeof (CHAR16));
    if (Replace != NULL) {
      UnicodeSPrint (Replace, StrSize (ReplaceWith) + 2*sizeof (CHAR16), L"\"%s\"", ReplaceWith);
    }
  }

  if (Replace == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  NewString = ZeroMem (NewString, NewSize);
  while (*SourceString != CHAR_NULL) {
    //
    // if we find the FindTarget and either Skip == FALSE or Skip  and we
    // dont have a carrot do a replace...
    //
    if (  (StrnCmp (SourceString, FindTarget, StrLen (FindTarget)) == 0)
       && ((SkipPreCarrot && (*(SourceString-1) != L'^')) || !SkipPreCarrot)
          )
    {
      SourceString += StrLen (FindTarget);
      Size          = StrSize (NewString);
      if ((Size + (StrLen (Replace)*sizeof (CHAR16))) > NewSize) {
        FreePool (Replace);
        return (EFI_BUFFER_TOO_SMALL);
      }

      StrCatS (NewString, NewSize/sizeof (CHAR16), Replace);
    } else {
      Size = StrSize (NewString);
      if (Size + sizeof (CHAR16) > NewSize) {
        FreePool (Replace);
        return (EFI_BUFFER_TOO_SMALL);
      }

      StrnCatS (NewString, NewSize/sizeof (CHAR16), SourceString, 1);
      SourceString++;
    }
  }

  FreePool (Replace);
  return (EFI_SUCCESS);
}

/**
  Internal worker function to output a string.

  This function will output a string to the correct StdOut.

  @param[in] String       The string to print out.

  @retval EFI_SUCCESS     The operation was successful.
  @retval !EFI_SUCCESS    The operation failed.
**/
EFI_STATUS
InternalPrintTo (
  IN CONST CHAR16  *String
  )
{
  UINTN  Size;

  Size = StrSize (String) - sizeof (CHAR16);
  if (Size == 0) {
    return (EFI_SUCCESS);
  }

  if (gEfiShellParametersProtocol != NULL) {
    return (gEfiShellProtocol->WriteFile (gEfiShellParametersProtocol->StdOut, &Size, (VOID *)String));
  }

  if (mEfiShellInterface          != NULL) {
    if (mEfiShellInterface->RedirArgc == 0) {
      //
      // Divide in half for old shell.  Must be string length not size.
      //
      Size /= 2;  // Divide in half only when no redirection.
    }

    return (mEfiShellInterface->StdOut->Write (mEfiShellInterface->StdOut, &Size, (VOID *)String));
  }

  ASSERT (FALSE);
  return (EFI_UNSUPPORTED);
}

/**
  Print at a specific location on the screen.

  This function will move the cursor to a given screen location and print the specified string

  If -1 is specified for either the Row or Col the current screen location for BOTH
  will be used.

  if either Row or Col is out of range for the current console, then ASSERT
  if Format is NULL, then ASSERT

  In addition to the standard %-based flags as supported by UefiLib Print() this supports
  the following additional flags:
    %N       -   Set output attribute to normal
    %H       -   Set output attribute to highlight
    %E       -   Set output attribute to error
    %B       -   Set output attribute to blue color
    %V       -   Set output attribute to green color

  Note: The background color is controlled by the shell command cls.

  @param[in] Col        the column to print at
  @param[in] Row        the row to print at
  @param[in] Format     the format string
  @param[in] Marker     the marker for the variable argument list

  @return EFI_SUCCESS           The operation was successful.
  @return EFI_DEVICE_ERROR      The console device reported an error.
**/
EFI_STATUS
InternalShellPrintWorker (
  IN INT32         Col OPTIONAL,
  IN INT32         Row OPTIONAL,
  IN CONST CHAR16  *Format,
  IN VA_LIST       Marker
  )
{
  EFI_STATUS  Status;
  CHAR16      *ResumeLocation;
  CHAR16      *FormatWalker;
  UINTN       OriginalAttribute;
  CHAR16      *mPostReplaceFormat;
  CHAR16      *mPostReplaceFormat2;

  mPostReplaceFormat  = AllocateZeroPool (PcdGet32 (PcdShellPrintBufferSize));
  mPostReplaceFormat2 = AllocateZeroPool (PcdGet32 (PcdShellPrintBufferSize));

  if ((mPostReplaceFormat == NULL) || (mPostReplaceFormat2 == NULL)) {
    SHELL_FREE_NON_NULL (mPostReplaceFormat);
    SHELL_FREE_NON_NULL (mPostReplaceFormat2);
    return (EFI_OUT_OF_RESOURCES);
  }

  Status            = EFI_SUCCESS;
  OriginalAttribute = gST->ConOut->Mode->Attribute;

  //
  // Back and forth each time fixing up 1 of our flags...
  //
  Status = ShellCopySearchAndReplace (Format, mPostReplaceFormat, PcdGet32 (PcdShellPrintBufferSize), L"%N", L"%%N", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat, mPostReplaceFormat2, PcdGet32 (PcdShellPrintBufferSize), L"%E", L"%%E", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat2, mPostReplaceFormat, PcdGet32 (PcdShellPrintBufferSize), L"%H", L"%%H", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat, mPostReplaceFormat2, PcdGet32 (PcdShellPrintBufferSize), L"%B", L"%%B", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat2, mPostReplaceFormat, PcdGet32 (PcdShellPrintBufferSize), L"%V", L"%%V", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);

  //
  // Use the last buffer from replacing to print from...
  //
  UnicodeVSPrint (mPostReplaceFormat2, PcdGet32 (PcdShellPrintBufferSize), mPostReplaceFormat, Marker);

  if ((Col != -1) && (Row != -1)) {
    Status = gST->ConOut->SetCursorPosition (gST->ConOut, Col, Row);
  }

  FormatWalker = mPostReplaceFormat2;
  while (*FormatWalker != CHAR_NULL) {
    //
    // Find the next attribute change request
    //
    ResumeLocation = StrStr (FormatWalker, L"%");
    if (ResumeLocation != NULL) {
      *ResumeLocation = CHAR_NULL;
    }

    //
    // print the current FormatWalker string
    //
    if (StrLen (FormatWalker) > 0) {
      Status = InternalPrintTo (FormatWalker);
      if (EFI_ERROR (Status)) {
        break;
      }
    }

    //
    // update the attribute
    //
    if (ResumeLocation != NULL) {
      if ((ResumeLocation != mPostReplaceFormat2) && (*(ResumeLocation-1) == L'^')) {
        //
        // Move cursor back 1 position to overwrite the ^
        //
        gST->ConOut->SetCursorPosition (gST->ConOut, gST->ConOut->Mode->CursorColumn - 1, gST->ConOut->Mode->CursorRow);

        //
        // Print a simple '%' symbol
        //
        Status         = InternalPrintTo (L"%");
        ResumeLocation = ResumeLocation - 1;
      } else {
        switch (*(ResumeLocation+1)) {
          case (L'N'):
            gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
            break;
          case (L'E'):
            gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          case (L'H'):
            gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          case (L'B'):
            gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTBLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          case (L'V'):
            gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)));
            break;
          default:
            //
            // Print a simple '%' symbol
            //
            Status = InternalPrintTo (L"%");
            if (EFI_ERROR (Status)) {
              break;
            }

            ResumeLocation = ResumeLocation - 1;
            break;
        }
      }
    } else {
      //
      // reset to normal now...
      //
      break;
    }

    //
    // update FormatWalker to Resume + 2 (skip the % and the indicator)
    //
    FormatWalker = ResumeLocation + 2;
  }

  gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);

  SHELL_FREE_NON_NULL (mPostReplaceFormat);
  SHELL_FREE_NON_NULL (mPostReplaceFormat2);
  return (Status);
}

/**
  Print at a specific location on the screen.

  This function will move the cursor to a given screen location and print the specified string.

  If -1 is specified for either the Row or Col the current screen location for BOTH
  will be used.

  If either Row or Col is out of range for the current console, then ASSERT.
  If Format is NULL, then ASSERT.

  In addition to the standard %-based flags as supported by UefiLib Print() this supports
  the following additional flags:
    %N       -   Set output attribute to normal
    %H       -   Set output attribute to highlight
    %E       -   Set output attribute to error
    %B       -   Set output attribute to blue color
    %V       -   Set output attribute to green color

  Note: The background color is controlled by the shell command cls.

  @param[in] Col        the column to print at
  @param[in] Row        the row to print at
  @param[in] Format     the format string
  @param[in] ...        The variable argument list.

  @return EFI_SUCCESS           The printing was successful.
  @return EFI_DEVICE_ERROR      The console device reported an error.
**/
EFI_STATUS
EFIAPI
ShellPrintEx (
  IN INT32         Col OPTIONAL,
  IN INT32         Row OPTIONAL,
  IN CONST CHAR16  *Format,
  ...
  )
{
  VA_LIST     Marker;
  EFI_STATUS  RetVal;

  if (Format == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  VA_START (Marker, Format);
  RetVal = InternalShellPrintWorker (Col, Row, Format, Marker);
  VA_END (Marker);
  return (RetVal);
}

/**
  Print at a specific location on the screen.

  This function will move the cursor to a given screen location and print the specified string.

  If -1 is specified for either the Row or Col the current screen location for BOTH
  will be used.

  If either Row or Col is out of range for the current console, then ASSERT.
  If Format is NULL, then ASSERT.

  In addition to the standard %-based flags as supported by UefiLib Print() this supports
  the following additional flags:
    %N       -   Set output attribute to normal.
    %H       -   Set output attribute to highlight.
    %E       -   Set output attribute to error.
    %B       -   Set output attribute to blue color.
    %V       -   Set output attribute to green color.

  Note: The background color is controlled by the shell command cls.

  @param[in] Col                The column to print at.
  @param[in] Row                The row to print at.
  @param[in] Language           The language of the string to retrieve.  If this parameter
                                is NULL, then the current platform language is used.
  @param[in] HiiFormatStringId  The format string Id for getting from Hii.
  @param[in] HiiFormatHandle    The format string Handle for getting from Hii.
  @param[in] ...                The variable argument list.

  @return EFI_SUCCESS           The printing was successful.
  @return EFI_DEVICE_ERROR      The console device reported an error.
**/
EFI_STATUS
EFIAPI
ShellPrintHiiEx (
  IN INT32                 Col OPTIONAL,
  IN INT32                 Row OPTIONAL,
  IN CONST CHAR8           *Language OPTIONAL,
  IN CONST EFI_STRING_ID   HiiFormatStringId,
  IN CONST EFI_HII_HANDLE  HiiFormatHandle,
  ...
  )
{
  VA_LIST     Marker;
  CHAR16      *HiiFormatString;
  EFI_STATUS  RetVal;

  RetVal = EFI_DEVICE_ERROR;

  VA_START (Marker, HiiFormatHandle);
  HiiFormatString = HiiGetString (HiiFormatHandle, HiiFormatStringId, Language);
  if (HiiFormatString != NULL) {
    RetVal = InternalShellPrintWorker (Col, Row, HiiFormatString, Marker);
    SHELL_FREE_NON_NULL (HiiFormatString);
  }

  VA_END (Marker);

  return (RetVal);
}

/**
  Function to determine if a given filename represents a file or a directory.

  @param[in] DirName      Path to directory to test.

  @retval EFI_SUCCESS             The Path represents a directory
  @retval EFI_NOT_FOUND           The Path does not represent a directory
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @return                         The path failed to open
**/
EFI_STATUS
EFIAPI
ShellIsDirectory (
  IN CONST CHAR16  *DirName
  )
{
  EFI_STATUS         Status;
  SHELL_FILE_HANDLE  Handle;
  CHAR16             *TempLocation;
  CHAR16             *TempLocation2;

  ASSERT (DirName != NULL);

  Handle       = NULL;
  TempLocation = NULL;

  Status = ShellOpenFileByName (DirName, &Handle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    //
    // try good logic first.
    //
    if (gEfiShellProtocol != NULL) {
      TempLocation = StrnCatGrow (&TempLocation, NULL, DirName, 0);
      if (TempLocation == NULL) {
        ShellCloseFile (&Handle);
        return (EFI_OUT_OF_RESOURCES);
      }

      TempLocation2 = StrStr (TempLocation, L":");
      if ((TempLocation2 != NULL) && (StrLen (StrStr (TempLocation, L":")) == 2)) {
        *(TempLocation2+1) = CHAR_NULL;
      }

      if (gEfiShellProtocol->GetDevicePathFromMap (TempLocation) != NULL) {
        FreePool (TempLocation);
        return (EFI_SUCCESS);
      }

      FreePool (TempLocation);
    } else {
      //
      // probably a map name?!?!!?
      //
      TempLocation = StrStr (DirName, L"\\");
      if ((TempLocation != NULL) && (*(TempLocation+1) == CHAR_NULL)) {
        return (EFI_SUCCESS);
      }
    }

    return (Status);
  }

  if (FileHandleIsDirectory (Handle) == EFI_SUCCESS) {
    ShellCloseFile (&Handle);
    return (EFI_SUCCESS);
  }

  ShellCloseFile (&Handle);
  return (EFI_NOT_FOUND);
}

/**
  Function to determine if a given filename represents a file.

  @param[in] Name         Path to file to test.

  @retval EFI_SUCCESS     The Path represents a file.
  @retval EFI_NOT_FOUND   The Path does not represent a file.
  @retval other           The path failed to open.
**/
EFI_STATUS
EFIAPI
ShellIsFile (
  IN CONST CHAR16  *Name
  )
{
  EFI_STATUS         Status;
  SHELL_FILE_HANDLE  Handle;

  ASSERT (Name != NULL);

  Handle = NULL;

  Status = ShellOpenFileByName (Name, &Handle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  if (FileHandleIsDirectory (Handle) != EFI_SUCCESS) {
    ShellCloseFile (&Handle);
    return (EFI_SUCCESS);
  }

  ShellCloseFile (&Handle);
  return (EFI_NOT_FOUND);
}

/**
  Function to determine if a given filename represents a file.

  This will search the CWD and then the Path.

  If Name is NULL, then ASSERT.

  @param[in] Name         Path to file to test.

  @retval EFI_SUCCESS     The Path represents a file.
  @retval EFI_NOT_FOUND   The Path does not represent a file.
  @retval other           The path failed to open.
**/
EFI_STATUS
EFIAPI
ShellIsFileInPath (
  IN CONST CHAR16  *Name
  )
{
  CHAR16      *NewName;
  EFI_STATUS  Status;

  if (!EFI_ERROR (ShellIsFile (Name))) {
    return (EFI_SUCCESS);
  }

  NewName = ShellFindFilePath (Name);
  if (NewName == NULL) {
    return (EFI_NOT_FOUND);
  }

  Status = ShellIsFile (NewName);
  FreePool (NewName);
  return (Status);
}

/**
  Function return the number converted from a hex representation of a number.

  Note: this function cannot be used when (UINTN)(-1), (0xFFFFFFFF) may be a valid
  result.  Use ShellConvertStringToUint64 instead.

  @param[in] String   String representation of a number.

  @return             The unsigned integer result of the conversion.
  @retval (UINTN)(-1) An error occurred.
**/
UINTN
EFIAPI
ShellHexStrToUintn (
  IN CONST CHAR16  *String
  )
{
  UINT64  RetVal;

  if (!EFI_ERROR (ShellConvertStringToUint64 (String, &RetVal, TRUE, TRUE))) {
    return ((UINTN)RetVal);
  }

  return ((UINTN)(-1));
}

/**
  Function to determine whether a string is decimal or hex representation of a number
  and return the number converted from the string.  Spaces are always skipped.

  @param[in] String   String representation of a number

  @return             the number
  @retval (UINTN)(-1) An error ocurred.
**/
UINTN
EFIAPI
ShellStrToUintn (
  IN CONST CHAR16  *String
  )
{
  UINT64   RetVal;
  BOOLEAN  Hex;

  Hex = FALSE;

  if (!InternalShellIsHexOrDecimalNumber (String, Hex, TRUE, FALSE)) {
    Hex = TRUE;
  }

  if (!EFI_ERROR (ShellConvertStringToUint64 (String, &RetVal, Hex, TRUE))) {
    return ((UINTN)RetVal);
  }

  return ((UINTN)(-1));
}

/**
  Safely append with automatic string resizing given length of Destination and
  desired length of copy from Source.

  append the first D characters of Source to the end of Destination, where D is
  the lesser of Count and the StrLen() of Source. If appending those D characters
  will fit within Destination (whose Size is given as CurrentSize) and
  still leave room for a NULL terminator, then those characters are appended,
  starting at the original terminating NULL of Destination, and a new terminating
  NULL is appended.

  If appending D characters onto Destination will result in a overflow of the size
  given in CurrentSize the string will be grown such that the copy can be performed
  and CurrentSize will be updated to the new size.

  If Source is NULL, there is nothing to append, just return the current buffer in
  Destination.

  if Destination is NULL, then ASSERT()
  if Destination's current length (including NULL terminator) is already more then
  CurrentSize, then ASSERT()

  @param[in, out] Destination   The String to append onto
  @param[in, out] CurrentSize   on call the number of bytes in Destination.  On
                                return possibly the new size (still in bytes).  if NULL
                                then allocate whatever is needed.
  @param[in]      Source        The String to append from
  @param[in]      Count         Maximum number of characters to append.  if 0 then
                                all are appended.

  @return Destination           return the resultant string.
**/
CHAR16 *
EFIAPI
StrnCatGrow (
  IN OUT CHAR16        **Destination,
  IN OUT UINTN         *CurrentSize,
  IN     CONST CHAR16  *Source,
  IN     UINTN         Count
  )
{
  UINTN  DestinationStartSize;
  UINTN  NewSize;

  //
  // ASSERTs
  //
  ASSERT (Destination != NULL);

  //
  // If there's nothing to do then just return Destination
  //
  if (Source == NULL) {
    return (*Destination);
  }

  //
  // allow for un-initialized pointers, based on size being 0
  //
  if ((CurrentSize != NULL) && (*CurrentSize == 0)) {
    *Destination = NULL;
  }

  //
  // allow for NULL pointers address as Destination
  //
  if (*Destination != NULL) {
    ASSERT (CurrentSize != 0);
    DestinationStartSize = StrSize (*Destination);
    ASSERT (DestinationStartSize <= *CurrentSize);
  } else {
    DestinationStartSize = 0;
    //    ASSERT(*CurrentSize == 0);
  }

  //
  // Append all of Source?
  //
  if (Count == 0) {
    Count = StrLen (Source);
  }

  //
  // Test and grow if required
  //
  if (CurrentSize != NULL) {
    NewSize = *CurrentSize;
    if (NewSize < DestinationStartSize + (Count * sizeof (CHAR16))) {
      while (NewSize < (DestinationStartSize + (Count*sizeof (CHAR16)))) {
        NewSize += 2 * Count * sizeof (CHAR16);
      }

      *Destination = ReallocatePool (*CurrentSize, NewSize, *Destination);
      *CurrentSize = NewSize;
    }
  } else {
    NewSize      = (Count+1)*sizeof (CHAR16);
    *Destination = AllocateZeroPool (NewSize);
  }

  //
  // Now use standard StrnCat on a big enough buffer
  //
  if (*Destination == NULL) {
    return (NULL);
  }

  StrnCatS (*Destination, NewSize/sizeof (CHAR16), Source, Count);
  return *Destination;
}

/**
  Prompt the user and return the resultant answer to the requestor.

  This function will display the requested question on the shell prompt and then
  wait for an appropriate answer to be input from the console.

  if the SHELL_PROMPT_REQUEST_TYPE is SHELL_PROMPT_REQUEST_TYPE_YESNO, ShellPromptResponseTypeQuitContinue
  or SHELL_PROMPT_REQUEST_TYPE_YESNOCANCEL then *Response is of type SHELL_PROMPT_RESPONSE.

  if the SHELL_PROMPT_REQUEST_TYPE is ShellPromptResponseTypeFreeform then *Response is of type
  CHAR16*.

  In either case *Response must be callee freed if Response was not NULL;

  @param Type                     What type of question is asked.  This is used to filter the input
                                  to prevent invalid answers to question.
  @param Prompt                   Pointer to string prompt to use to request input.
  @param Response                 Pointer to Response which will be populated upon return.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_UNSUPPORTED         The operation is not supported as requested.
  @retval EFI_INVALID_PARAMETER   A parameter was invalid.
  @return other                   The operation failed.
**/
EFI_STATUS
EFIAPI
ShellPromptForResponse (
  IN SHELL_PROMPT_REQUEST_TYPE  Type,
  IN CHAR16                     *Prompt OPTIONAL,
  IN OUT VOID                   **Response OPTIONAL
  )
{
  EFI_STATUS             Status;
  EFI_INPUT_KEY          Key;
  UINTN                  EventIndex;
  SHELL_PROMPT_RESPONSE  *Resp;
  UINTN                  Size;
  CHAR16                 *Buffer;

  Status = EFI_UNSUPPORTED;
  Resp   = NULL;
  Buffer = NULL;
  Size   = 0;
  if (Type != ShellPromptResponseTypeFreeform) {
    Resp = (SHELL_PROMPT_RESPONSE *)AllocateZeroPool (sizeof (SHELL_PROMPT_RESPONSE));
    if (Resp == NULL) {
      if (Response != NULL) {
        *Response = NULL;
      }

      return (EFI_OUT_OF_RESOURCES);
    }
  }

  switch (Type) {
    case ShellPromptResponseTypeQuitContinue:
      if (Prompt != NULL) {
        ShellPrintDefaultEx (L"%s", Prompt);
      }

      //
      // wait for valid response
      //
      gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
      if (EFI_ERROR (Status)) {
        break;
      }

      ShellPrintDefaultEx (L"%c", Key.UnicodeChar);
      if ((Key.UnicodeChar == L'Q') || (Key.UnicodeChar == L'q')) {
        *Resp = ShellPromptResponseQuit;
      } else {
        *Resp = ShellPromptResponseContinue;
      }

      break;
    case ShellPromptResponseTypeYesNoCancel:
      if (Prompt != NULL) {
        ShellPrintDefaultEx (L"%s", Prompt);
      }

      //
      // wait for valid response
      //
      *Resp = ShellPromptResponseMax;
      while (*Resp == ShellPromptResponseMax) {
        if (ShellGetExecutionBreakFlag ()) {
          Status = EFI_ABORTED;
          break;
        }

        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
        if (EFI_ERROR (Status)) {
          break;
        }

        ShellPrintDefaultEx (L"%c", Key.UnicodeChar);
        switch (Key.UnicodeChar) {
          case L'Y':
          case L'y':
            *Resp = ShellPromptResponseYes;
            break;
          case L'N':
          case L'n':
            *Resp = ShellPromptResponseNo;
            break;
          case L'C':
          case L'c':
            *Resp = ShellPromptResponseCancel;
            break;
        }
      }

      break;
    case ShellPromptResponseTypeYesNoAllCancel:
      if (Prompt != NULL) {
        ShellPrintDefaultEx (L"%s", Prompt);
      }

      //
      // wait for valid response
      //
      *Resp = ShellPromptResponseMax;
      while (*Resp == ShellPromptResponseMax) {
        if (ShellGetExecutionBreakFlag ()) {
          Status = EFI_ABORTED;
          break;
        }

        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
        if (EFI_ERROR (Status)) {
          break;
        }

        if ((Key.UnicodeChar <= 127) && (Key.UnicodeChar >= 32)) {
          ShellPrintDefaultEx (L"%c", Key.UnicodeChar);
        }

        switch (Key.UnicodeChar) {
          case L'Y':
          case L'y':
            *Resp = ShellPromptResponseYes;
            break;
          case L'N':
          case L'n':
            *Resp = ShellPromptResponseNo;
            break;
          case L'A':
          case L'a':
            *Resp = ShellPromptResponseAll;
            break;
          case L'C':
          case L'c':
            *Resp = ShellPromptResponseCancel;
            break;
        }
      }

      break;
    case ShellPromptResponseTypeEnterContinue:
    case ShellPromptResponseTypeAnyKeyContinue:
      if (Prompt != NULL) {
        ShellPrintDefaultEx (L"%s", Prompt);
      }

      //
      // wait for valid response
      //
      *Resp = ShellPromptResponseMax;
      while (*Resp == ShellPromptResponseMax) {
        if (ShellGetExecutionBreakFlag ()) {
          Status = EFI_ABORTED;
          break;
        }

        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
        if (Type == ShellPromptResponseTypeEnterContinue) {
          Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
          if (EFI_ERROR (Status)) {
            break;
          }

          ShellPrintDefaultEx (L"%c", Key.UnicodeChar);
          if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
            *Resp = ShellPromptResponseContinue;
            break;
          }
        }

        if (Type == ShellPromptResponseTypeAnyKeyContinue) {
          Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
          ASSERT_EFI_ERROR (Status);
          *Resp = ShellPromptResponseContinue;
          break;
        }
      }

      break;
    case ShellPromptResponseTypeYesNo:
      if (Prompt != NULL) {
        ShellPrintDefaultEx (L"%s", Prompt);
      }

      //
      // wait for valid response
      //
      *Resp = ShellPromptResponseMax;
      while (*Resp == ShellPromptResponseMax) {
        if (ShellGetExecutionBreakFlag ()) {
          Status = EFI_ABORTED;
          break;
        }

        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
        if (EFI_ERROR (Status)) {
          break;
        }

        ShellPrintDefaultEx (L"%c", Key.UnicodeChar);
        switch (Key.UnicodeChar) {
          case L'Y':
          case L'y':
            *Resp = ShellPromptResponseYes;
            break;
          case L'N':
          case L'n':
            *Resp = ShellPromptResponseNo;
            break;
        }
      }

      break;
    case ShellPromptResponseTypeFreeform:
      if (Prompt != NULL) {
        ShellPrintDefaultEx (L"%s", Prompt);
      }

      while (1) {
        if (ShellGetExecutionBreakFlag ()) {
          Status = EFI_ABORTED;
          break;
        }

        gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
        if (EFI_ERROR (Status)) {
          break;
        }

        ShellPrintDefaultEx (L"%c", Key.UnicodeChar);
        if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
          break;
        }

        ASSERT ((Buffer == NULL && Size == 0) || (Buffer != NULL));
        StrnCatGrow (&Buffer, &Size, &Key.UnicodeChar, 1);
      }

      break;
    //
    // This is the location to add new prompt types.
    // If your new type loops remember to add ExecutionBreak support.
    //
    default:
      ASSERT (FALSE);
  }

  if (Response != NULL) {
    if (Resp != NULL) {
      *Response = Resp;
    } else if (Buffer != NULL) {
      *Response = Buffer;
    } else {
      *Response = NULL;
    }
  } else {
    if (Resp != NULL) {
      FreePool (Resp);
    }

    if (Buffer != NULL) {
      FreePool (Buffer);
    }
  }

  ShellPrintDefaultEx (L"\r\n");
  return (Status);
}

/**
  Prompt the user and return the resultant answer to the requestor.

  This function is the same as ShellPromptForResponse, except that the prompt is
  automatically pulled from HII.

  @param Type     What type of question is asked.  This is used to filter the input
                  to prevent invalid answers to question.
  @param[in] HiiFormatStringId  The format string Id for getting from Hii.
  @param[in] HiiFormatHandle    The format string Handle for getting from Hii.
  @param Response               Pointer to Response which will be populated upon return.

  @retval EFI_SUCCESS the operation was successful.
  @return other       the operation failed.

  @sa ShellPromptForResponse
**/
EFI_STATUS
EFIAPI
ShellPromptForResponseHii (
  IN SHELL_PROMPT_REQUEST_TYPE  Type,
  IN CONST EFI_STRING_ID        HiiFormatStringId,
  IN CONST EFI_HII_HANDLE       HiiFormatHandle,
  IN OUT VOID                   **Response
  )
{
  CHAR16      *Prompt;
  EFI_STATUS  Status;

  Prompt = HiiGetString (HiiFormatHandle, HiiFormatStringId, NULL);
  Status = ShellPromptForResponse (Type, Prompt, Response);
  if (Prompt != NULL) {
    FreePool (Prompt);
  }

  return (Status);
}

/**
  Function to determin if an entire string is a valid number.

  If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.

  @param[in] String       The string to evaluate.
  @param[in] ForceHex     TRUE - always assume hex.
  @param[in] StopAtSpace  TRUE to halt upon finding a space, FALSE to keep going.
  @param[in] TimeNumbers        TRUE to allow numbers with ":", FALSE otherwise.

  @retval TRUE        It is all numeric (dec/hex) characters.
  @retval FALSE       There is a non-numeric character.
**/
BOOLEAN
InternalShellIsHexOrDecimalNumber (
  IN CONST CHAR16   *String,
  IN CONST BOOLEAN  ForceHex,
  IN CONST BOOLEAN  StopAtSpace,
  IN CONST BOOLEAN  TimeNumbers
  )
{
  BOOLEAN  Hex;
  BOOLEAN  LeadingZero;

  if (String == NULL) {
    return FALSE;
  }

  //
  // chop off a single negative sign
  //
  if (*String == L'-') {
    String++;
  }

  if (*String == CHAR_NULL) {
    return FALSE;
  }

  //
  // chop leading zeroes
  //
  LeadingZero = FALSE;
  while (*String == L'0') {
    String++;
    LeadingZero = TRUE;
  }

  //
  // allow '0x' or '0X', but not 'x' or 'X'
  //
  if ((*String == L'x') || (*String == L'X')) {
    if (!LeadingZero) {
      //
      // we got an x without a preceeding 0
      //
      return (FALSE);
    }

    String++;
    Hex = TRUE;
  } else if (ForceHex) {
    Hex = TRUE;
  } else {
    Hex = FALSE;
  }

  if ((*String == CHAR_NULL) && LeadingZero) {
    return (TRUE);
  }

  //
  // loop through the remaining characters and use the lib function
  //
  for ( ; *String != CHAR_NULL && !(StopAtSpace && *String == L' '); String++) {
    if (TimeNumbers && (String[0] == L':')) {
      continue;
    }

    if (Hex) {
      if (!ShellIsHexaDecimalDigitCharacter (*String)) {
        return (FALSE);
      }
    } else {
      if (!ShellIsDecimalDigitCharacter (*String)) {
        return (FALSE);
      }
    }
  }

  return (TRUE);
}

/**
  Function to determine if a given filename exists.

  @param[in] Name         Path to test.

  @retval EFI_SUCCESS     The Path represents a file.
  @retval EFI_NOT_FOUND   The Path does not represent a file.
  @retval other           The path failed to open.
**/
EFI_STATUS
EFIAPI
ShellFileExists (
  IN CONST CHAR16  *Name
  )
{
  EFI_STATUS           Status;
  EFI_SHELL_FILE_INFO  *List;

  ASSERT (Name != NULL);

  List   = NULL;
  Status = ShellOpenFileMetaArg ((CHAR16 *)Name, EFI_FILE_MODE_READ, &List);
  if (EFI_ERROR (Status)) {
    return (Status);
  }

  ShellCloseFileMetaArg (&List);

  return (EFI_SUCCESS);
}

/**
  Convert a Unicode character to numerical value.

  This internal function only deal with Unicode character
  which maps to a valid hexadecimal ASII character, i.e.
  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
  Unicode character, the value returned does not make sense.

  @param  Char  The character to convert.

  @return The numerical value converted.

**/
UINTN
InternalShellHexCharToUintn (
  IN      CHAR16  Char
  )
{
  if (ShellIsDecimalDigitCharacter (Char)) {
    return Char - L'0';
  }

  return (10 + CharToUpper (Char) - L'A');
}

/**
  Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.

  This function returns a value of type UINT64 by interpreting the contents
  of the Unicode string specified by String as a hexadecimal number.
  The format of the input Unicode string String is:

                  [spaces][zeros][x][hexadecimal digits].

  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
  If "x" appears in the input string, it must be prefixed with at least one 0.
  The function will ignore the pad space, which includes spaces or tab characters,
  before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
  [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
  first valid hexadecimal digit. Then, the function stops at the first character that is
  a not a valid hexadecimal character or NULL, whichever one comes first.

  If String has only pad spaces, then zero is returned.
  If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
  then zero is returned.

  @param[in]  String      A pointer to a Null-terminated Unicode string.
  @param[out] Value       Upon a successful return the value of the conversion.
  @param[in] StopAtSpace  FALSE to skip spaces.

  @retval EFI_SUCCESS             The conversion was successful.
  @retval EFI_INVALID_PARAMETER   A parameter was NULL or invalid.
  @retval EFI_DEVICE_ERROR        An overflow occurred.
**/
EFI_STATUS
InternalShellStrHexToUint64 (
  IN CONST CHAR16   *String,
  OUT   UINT64      *Value,
  IN CONST BOOLEAN  StopAtSpace
  )
{
  UINT64   Result;
  BOOLEAN  LeadingZero;

  if ((String == NULL) || (*String == CHAR_NULL) || (Value == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Ignore the pad spaces (space or tab)
  //
  while ((*String == L' ') || (*String == L'\t')) {
    String++;
  }

  //
  // Ignore leading Zeros after the spaces
  //
  LeadingZero = FALSE;
  while (*String == L'0') {
    String++;
    LeadingZero = TRUE;
  }

  if (CharToUpper (*String) == L'X') {
    if (!LeadingZero) {
      return 0;
    }

    //
    // Skip the 'X'
    //
    String++;

    //
    // there is a space where there should't be
    //
    if (*String == L' ') {
      return (EFI_INVALID_PARAMETER);
    }
  }

  Result = 0;

  while (ShellIsHexaDecimalDigitCharacter (*String)) {
    //
    // If the Hex Number represented by String overflows according
    // to the range defined by UINT64, then return EFI_DEVICE_ERROR.
    //
    if (!(Result <= (RShiftU64 ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)), 4)))) {
      //    if (!(Result <= ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)) >> 4))) {
      return (EFI_DEVICE_ERROR);
    }

    Result  = (LShiftU64 (Result, 4));
    Result += InternalShellHexCharToUintn (*String);
    String++;

    //
    // stop at spaces if requested
    //
    if (StopAtSpace && (*String == L' ')) {
      break;
    }
  }

  *Value = Result;
  return (EFI_SUCCESS);
}

/**
  Convert a Null-terminated Unicode decimal string to a value of
  type UINT64.

  This function returns a value of type UINT64 by interpreting the contents
  of the Unicode string specified by String as a decimal number. The format
  of the input Unicode string String is:

                  [spaces] [decimal digits].

  The valid decimal digit character is in the range [0-9]. The
  function will ignore the pad space, which includes spaces or
  tab characters, before [decimal digits]. The running zero in the
  beginning of [decimal digits] will be ignored. Then, the function
  stops at the first character that is a not a valid decimal character
  or a Null-terminator, whichever one comes first.

  If String has only pad spaces, then 0 is returned.
  If String has no pad spaces or valid decimal digits,
  then 0 is returned.

  @param[in]  String      A pointer to a Null-terminated Unicode string.
  @param[out] Value       Upon a successful return the value of the conversion.
  @param[in] StopAtSpace  FALSE to skip spaces.

  @retval EFI_SUCCESS             The conversion was successful.
  @retval EFI_INVALID_PARAMETER   A parameter was NULL or invalid.
  @retval EFI_DEVICE_ERROR        An overflow occurred.
**/
EFI_STATUS
InternalShellStrDecimalToUint64 (
  IN CONST CHAR16   *String,
  OUT   UINT64      *Value,
  IN CONST BOOLEAN  StopAtSpace
  )
{
  UINT64  Result;

  if ((String == NULL) || (*String == CHAR_NULL) || (Value == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Ignore the pad spaces (space or tab)
  //
  while ((*String == L' ') || (*String == L'\t')) {
    String++;
  }

  //
  // Ignore leading Zeros after the spaces
  //
  while (*String == L'0') {
    String++;
  }

  Result = 0;

  //
  // Stop upon space if requested
  // (if the whole value was 0)
  //
  if (StopAtSpace && (*String == L' ')) {
    *Value = Result;
    return (EFI_SUCCESS);
  }

  while (ShellIsDecimalDigitCharacter (*String)) {
    //
    // If the number represented by String overflows according
    // to the range defined by UINT64, then return EFI_DEVICE_ERROR.
    //

    if (!(Result <= (DivU64x32 ((((UINT64) ~0) - (*String - L'0')), 10)))) {
      return (EFI_DEVICE_ERROR);
    }

    Result = MultU64x32 (Result, 10) + (*String - L'0');
    String++;

    //
    // Stop at spaces if requested
    //
    if (StopAtSpace && (*String == L' ')) {
      break;
    }
  }

  *Value = Result;

  return (EFI_SUCCESS);
}

/**
  Function to verify and convert a string to its numerical value.

  If Hex it must be preceeded with a 0x, 0X, or has ForceHex set TRUE.

  @param[in] String       The string to evaluate.
  @param[out] Value       Upon a successful return the value of the conversion.
  @param[in] ForceHex     TRUE - always assume hex.
  @param[in] StopAtSpace  FALSE to skip spaces.

  @retval EFI_SUCCESS             The conversion was successful.
  @retval EFI_INVALID_PARAMETER   String contained an invalid character.
  @retval EFI_NOT_FOUND           String was a number, but Value was NULL.
**/
EFI_STATUS
EFIAPI
ShellConvertStringToUint64 (
  IN CONST CHAR16   *String,
  OUT   UINT64      *Value,
  IN CONST BOOLEAN  ForceHex,
  IN CONST BOOLEAN  StopAtSpace
  )
{
  UINT64        RetVal;
  CONST CHAR16  *Walker;
  EFI_STATUS    Status;
  BOOLEAN       Hex;

  Hex = ForceHex;

  if (!InternalShellIsHexOrDecimalNumber (String, Hex, StopAtSpace, FALSE)) {
    if (!Hex) {
      Hex = TRUE;
      if (!InternalShellIsHexOrDecimalNumber (String, Hex, StopAtSpace, FALSE)) {
        return (EFI_INVALID_PARAMETER);
      }
    } else {
      return (EFI_INVALID_PARAMETER);
    }
  }

  //
  // Chop off leading spaces
  //
  for (Walker = String; Walker != NULL && *Walker != CHAR_NULL && *Walker == L' '; Walker++) {
  }

  //
  // make sure we have something left that is numeric.
  //
  if ((Walker == NULL) || (*Walker == CHAR_NULL) || !InternalShellIsHexOrDecimalNumber (Walker, Hex, StopAtSpace, FALSE)) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // do the conversion.
  //
  if (Hex || (StrnCmp (Walker, L"0x", 2) == 0) || (StrnCmp (Walker, L"0X", 2) == 0)) {
    Status = InternalShellStrHexToUint64 (Walker, &RetVal, StopAtSpace);
  } else {
    Status = InternalShellStrDecimalToUint64 (Walker, &RetVal, StopAtSpace);
  }

  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Value == NULL) {
    return EFI_NOT_FOUND;
  }

  *Value = RetVal;

  return EFI_SUCCESS;
}

/**
  Function to determin if an entire string is a valid number.

  If Hex it must be preceeded with a 0x or has ForceHex, set TRUE.

  @param[in] String       The string to evaluate.
  @param[in] ForceHex     TRUE - always assume hex.
  @param[in] StopAtSpace  TRUE to halt upon finding a space, FALSE to keep going.

  @retval TRUE        It is all numeric (dec/hex) characters.
  @retval FALSE       There is a non-numeric character.
**/
BOOLEAN
EFIAPI
ShellIsHexOrDecimalNumber (
  IN CONST CHAR16   *String,
  IN CONST BOOLEAN  ForceHex,
  IN CONST BOOLEAN  StopAtSpace
  )
{
  if (ShellConvertStringToUint64 (String, NULL, ForceHex, StopAtSpace) == EFI_NOT_FOUND) {
    return (TRUE);
  }

  return (FALSE);
}

/**
  Function to read a single line from a SHELL_FILE_HANDLE. The \n is not included in the returned
  buffer.  The returned buffer must be callee freed.

  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
  maintained and not changed for all operations with the same file.

  @param[in]       Handle        SHELL_FILE_HANDLE to read from.
  @param[in, out]  Ascii         Boolean value for indicating whether the file is
                                 Ascii (TRUE) or UCS2 (FALSE).

  @return                        The line of text from the file.
  @retval NULL                   There was not enough memory available.

  @sa ShellFileHandleReadLine
**/
CHAR16 *
EFIAPI
ShellFileHandleReturnLine (
  IN SHELL_FILE_HANDLE  Handle,
  IN OUT BOOLEAN        *Ascii
  )
{
  CHAR16      *RetVal;
  UINTN       Size;
  EFI_STATUS  Status;

  Size   = 0;
  RetVal = NULL;

  Status = ShellFileHandleReadLine (Handle, RetVal, &Size, FALSE, Ascii);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    RetVal = AllocateZeroPool (Size);
    if (RetVal == NULL) {
      return (NULL);
    }

    Status = ShellFileHandleReadLine (Handle, RetVal, &Size, FALSE, Ascii);
  }

  if ((Status == EFI_END_OF_FILE) && (RetVal != NULL) && (*RetVal != CHAR_NULL)) {
    Status = EFI_SUCCESS;
  }

  if (EFI_ERROR (Status) && (RetVal != NULL)) {
    FreePool (RetVal);
    RetVal = NULL;
  }

  return (RetVal);
}

/**
  Function to read a single line (up to but not including the \n) from a SHELL_FILE_HANDLE.

  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
  maintained and not changed for all operations with the same file.

  NOTE: LINES THAT ARE RETURNED BY THIS FUNCTION ARE UCS2, EVEN IF THE FILE BEING READ
        IS IN ASCII FORMAT.

  @param[in]       Handle        SHELL_FILE_HANDLE to read from.
  @param[in, out]  Buffer        The pointer to buffer to read into. If this function
                                 returns EFI_SUCCESS, then on output Buffer will
                                 contain a UCS2 string, even if the file being
                                 read is ASCII.
  @param[in, out]  Size          On input, pointer to number of bytes in Buffer.
                                 On output, unchanged unless Buffer is too small
                                 to contain the next line of the file. In that
                                 case Size is set to the number of bytes needed
                                 to hold the next line of the file (as a UCS2
                                 string, even if it is an ASCII file).
  @param[in]       Truncate      If the buffer is large enough, this has no effect.
                                 If the buffer is is too small and Truncate is TRUE,
                                 the line will be truncated.
                                 If the buffer is is too small and Truncate is FALSE,
                                 then no read will occur.

  @param[in, out]  Ascii         Boolean value for indicating whether the file is
                                 Ascii (TRUE) or UCS2 (FALSE).

  @retval EFI_SUCCESS           The operation was successful.  The line is stored in
                                Buffer.
  @retval EFI_END_OF_FILE       There are no more lines in the file.
  @retval EFI_INVALID_PARAMETER Handle was NULL.
  @retval EFI_INVALID_PARAMETER Size was NULL.
  @retval EFI_BUFFER_TOO_SMALL  Size was not large enough to store the line.
                                Size was updated to the minimum space required.
**/
EFI_STATUS
EFIAPI
ShellFileHandleReadLine (
  IN SHELL_FILE_HANDLE  Handle,
  IN OUT CHAR16         *Buffer,
  IN OUT UINTN          *Size,
  IN BOOLEAN            Truncate,
  IN OUT BOOLEAN        *Ascii
  )
{
  EFI_STATUS  Status;
  CHAR16      CharBuffer;
  UINTN       BufferLength;
  UINTN       CharSize;
  UINTN       CountSoFar;
  UINT64      OriginalFilePosition;

  if (  (Handle == NULL)
     || (Size   == NULL)
        )
  {
    return (EFI_INVALID_PARAMETER);
  }

  if (Buffer == NULL) {
    ASSERT (*Size == 0);
  } else {
    *Buffer = CHAR_NULL;
  }

  gEfiShellProtocol->GetFilePosition (Handle, &OriginalFilePosition);
  if (OriginalFilePosition == 0) {
    CharSize = sizeof (CHAR16);
    Status   = gEfiShellProtocol->ReadFile (Handle, &CharSize, &CharBuffer);
    ASSERT_EFI_ERROR (Status);
    if (CharBuffer == gUnicodeFileTag) {
      *Ascii = FALSE;
    } else {
      *Ascii = TRUE;
      gEfiShellProtocol->SetFilePosition (Handle, OriginalFilePosition);
    }
  }

  if (*Ascii) {
    CharSize = sizeof (CHAR8);
  } else {
    CharSize = sizeof (CHAR16);
  }

  for (CountSoFar = 0; ; CountSoFar++) {
    CharBuffer = 0;
    Status     = gEfiShellProtocol->ReadFile (Handle, &CharSize, &CharBuffer);
    if (  EFI_ERROR (Status)
       || (CharSize == 0)
       || ((CharBuffer == L'\n') && !(*Ascii))
       || ((CharBuffer ==  '\n') && *Ascii)
          )
    {
      if (CharSize == 0) {
        Status = EFI_END_OF_FILE;
      }

      break;
    }

    //
    // if we have space save it...
    //
    if ((CountSoFar+1)*sizeof (CHAR16) < *Size) {
      ASSERT (Buffer != NULL);
      ((CHAR16 *)Buffer)[CountSoFar]   = CharBuffer;
      ((CHAR16 *)Buffer)[CountSoFar+1] = CHAR_NULL;
    }
  }

  //
  // if we ran out of space tell when...
  //
  if ((CountSoFar+1)*sizeof (CHAR16) > *Size) {
    *Size = (CountSoFar+1)*sizeof (CHAR16);
    if (!Truncate) {
      gEfiShellProtocol->SetFilePosition (Handle, OriginalFilePosition);
    } else {
      DEBUG ((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine"));
    }

    return (EFI_BUFFER_TOO_SMALL);
  }

  BufferLength = StrLen (Buffer);
  while ((BufferLength != 0) && (Buffer[--BufferLength] == L'\r')) {
    Buffer[BufferLength] = CHAR_NULL;
  }

  return (Status);
}

/**
  Function to print help file / man page content in the spec from the UEFI Shell protocol GetHelpText function.

  @param[in] CommandToGetHelpOn  Pointer to a string containing the command name of help file to be printed.
  @param[in] SectionToGetHelpOn  Pointer to the section specifier(s).
  @param[in] PrintCommandText    If TRUE, prints the command followed by the help content, otherwise prints
                                 the help content only.
  @retval EFI_DEVICE_ERROR       The help data format was incorrect.
  @retval EFI_NOT_FOUND          The help data could not be found.
  @retval EFI_SUCCESS            The operation was successful.
**/
EFI_STATUS
EFIAPI
ShellPrintHelp (
  IN CONST CHAR16  *CommandToGetHelpOn,
  IN CONST CHAR16  *SectionToGetHelpOn,
  IN BOOLEAN       PrintCommandText
  )
{
  EFI_STATUS  Status;
  CHAR16      *OutText;

  OutText = NULL;

  //
  // Get the string to print based
  //
  Status = gEfiShellProtocol->GetHelpText (CommandToGetHelpOn, SectionToGetHelpOn, &OutText);

  //
  // make sure we got a valid string
  //
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((OutText == NULL) || (StrLen (OutText) == 0)) {
    return EFI_NOT_FOUND;
  }

  //
  // Chop off trailing stuff we dont need
  //
  while (OutText[StrLen (OutText)-1] == L'\r' || OutText[StrLen (OutText)-1] == L'\n' || OutText[StrLen (OutText)-1] == L' ') {
    OutText[StrLen (OutText)-1] = CHAR_NULL;
  }

  //
  // Print this out to the console
  //
  if (PrintCommandText) {
    ShellPrintDefaultEx (L"%H%-14s%N- %s\r\n", CommandToGetHelpOn, OutText);
  } else {
    ShellPrintDefaultEx (L"%N%s\r\n", OutText);
  }

  SHELL_FREE_NON_NULL (OutText);

  return EFI_SUCCESS;
}

/**
  Function to delete a file by name

  @param[in]       FileName       Pointer to file name to delete.

  @retval EFI_SUCCESS             the file was deleted sucessfully
  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not
                                  deleted
  @retval EFI_INVALID_PARAMETER   One of the parameters has an invalid value.
  @retval EFI_NOT_FOUND           The specified file could not be found on the
                                  device or the file system could not be found
                                  on the device.
  @retval EFI_NO_MEDIA            The device has no medium.
  @retval EFI_MEDIA_CHANGED       The device has a different medium in it or the
                                  medium is no longer supported.
  @retval EFI_DEVICE_ERROR        The device reported an error.
  @retval EFI_VOLUME_CORRUPTED    The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED     The file or medium is write protected.
  @retval EFI_ACCESS_DENIED       The file was opened read only.
  @retval EFI_OUT_OF_RESOURCES    Not enough resources were available to open the
                                  file.
  @retval other                   The file failed to open
**/
EFI_STATUS
EFIAPI
ShellDeleteFileByName (
  IN CONST CHAR16  *FileName
  )
{
  EFI_STATUS         Status;
  SHELL_FILE_HANDLE  FileHandle;

  Status = ShellFileExists (FileName);

  if (Status == EFI_SUCCESS) {
    Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0x0);
    if (Status == EFI_SUCCESS) {
      Status = ShellDeleteFile (&FileHandle);
    }
  }

  return (Status);
}

/**
  Cleans off all the quotes in the string.

  @param[in]     OriginalString   pointer to the string to be cleaned.
  @param[out]   CleanString      The new string with all quotes removed.
                                                  Memory allocated in the function and free
                                                  by caller.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
InternalShellStripQuotes (
  IN  CONST CHAR16  *OriginalString,
  OUT CHAR16        **CleanString
  )
{
  CHAR16  *Walker;

  if ((OriginalString == NULL) || (CleanString == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString);
  if (*CleanString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL; Walker++) {
    if (*Walker == L'\"') {
      CopyMem (Walker, Walker+1, StrSize (Walker) - sizeof (Walker[0]));
    }
  }

  return EFI_SUCCESS;
}
