/** @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;
}

