/** @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>
  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 sucessfully
  @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 poitners 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 sucessfully

**/
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 sucessfully.
**/
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 sucessfully
  @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 begining of file

  @retval EFI_SUCCESS           Operation completed sucessfully.
  @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 begining of file.

  @retval EFI_SUCCESS           the operation completed sucessfully.
  @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 sucessfully
  @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 sucessfully
  @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 sucessfully.  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 sucessful
    //
    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 sucessful 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 sucessful.
**/
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 sucessfully.
  @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 sucessfully.
  @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 sucessful.
  @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 (PcdGet16 (PcdShellPrintBufferSize));
  mPostReplaceFormat2 = AllocateZeroPool (PcdGet16 (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, PcdGet16 (PcdShellPrintBufferSize), L"%N", L"%%N", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat, mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), L"%E", L"%%E", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat2, mPostReplaceFormat, PcdGet16 (PcdShellPrintBufferSize), L"%H", L"%%H", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat, mPostReplaceFormat2, PcdGet16 (PcdShellPrintBufferSize), L"%B", L"%%B", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);
  Status = ShellCopySearchAndReplace (mPostReplaceFormat2, mPostReplaceFormat, PcdGet16 (PcdShellPrintBufferSize), L"%V", L"%%V", FALSE, FALSE);
  ASSERT_EFI_ERROR (Status);

  //
  // Use the last buffer from replacing to print from...
  //
  UnicodeVSPrint (mPostReplaceFormat2, PcdGet16 (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 sucessful.
  @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) {
        ShellPrintEx (-1, -1, 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;
      }

      ShellPrintEx (-1, -1, L"%c", Key.UnicodeChar);
      if ((Key.UnicodeChar == L'Q') || (Key.UnicodeChar == L'q')) {
        *Resp = ShellPromptResponseQuit;
      } else {
        *Resp = ShellPromptResponseContinue;
      }

      break;
    case ShellPromptResponseTypeYesNoCancel:
      if (Prompt != NULL) {
        ShellPrintEx (-1, -1, 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;
        }

        ShellPrintEx (-1, -1, 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) {
        ShellPrintEx (-1, -1, 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)) {
          ShellPrintEx (-1, -1, 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) {
        ShellPrintEx (-1, -1, 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;
          }

          ShellPrintEx (-1, -1, 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) {
        ShellPrintEx (-1, -1, 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;
        }

        ShellPrintEx (-1, -1, 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) {
        ShellPrintEx (-1, -1, 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;
        }

        ShellPrintEx (-1, -1, 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);
    }
  }

  ShellPrintEx (-1, -1, 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 sucessful.
  @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);
  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;
  }

  //
  // 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;

  if ((String == NULL) || (StrSize (String) == 0) || (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++;
  }

  if (CharToUpper (*String) == L'X') {
    if (*(String - 1) != L'0') {
      return 0;
    }

    //
    // Skip the 'X'
    //
    String++;
  }

  Result = 0;

  //
  // there is a space where there should't be
  //
  if (*String == L' ') {
    return (EFI_INVALID_PARAMETER);
  }

  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) || (StrSize (String) == 0) || (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 ((Value == NULL) && !EFI_ERROR (Status)) {
    return (EFI_NOT_FOUND);
  }

  if (Value != NULL) {
    *Value = RetVal;
  }

  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.

  @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       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);
  }

  while (Buffer[StrLen (Buffer)-1] == L'\r') {
    Buffer[StrLen (Buffer)-1] = 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) {
    ShellPrintEx (-1, -1, L"%H%-14s%N- %s\r\n", CommandToGetHelpOn, OutText);
  } else {
    ShellPrintEx (-1, -1, 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;
}
