/** @file
  Provides interface to shell functionality for shell commands and applications.

Copyright (c) 2006 - 2009, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <Uefi.h>
#include <Library/ShellLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/FileHandleLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>

#include <Protocol/EfiShellEnvironment2.h>
#include <Protocol/EfiShellInterface.h>
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/SimpleFileSystem.h>

#include "UefiShellLib.h"

#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)
#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)

//
// This is not static since it's extern in the .h file
//
SHELL_PARAM_ITEM EmptyParamList[] = {
  {NULL, TypeMax}
  };

//
// Static file globals for the shell library
//
STATIC EFI_SHELL_ENVIRONMENT2        *mEfiShellEnvironment2;
STATIC EFI_SHELL_INTERFACE           *mEfiShellInterface;
STATIC EFI_SHELL_PROTOCOL            *mEfiShellProtocol;
STATIC EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol;
STATIC EFI_HANDLE                    mEfiShellEnvironment2Handle;
STATIC FILE_HANDLE_FUNCTION_MAP      FileFunctionMap;

/**
  helper function to find ShellEnvironment2 for constructor
**/
EFI_STATUS
EFIAPI
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) != FALSE)){
    //
    // figure out how big of a buffer we need.
    //
    Status = gBS->LocateHandle (ByProtocol,
                                &gEfiShellEnvironment2Guid,
                                NULL, // ignored for ByProtocol
                                &BufferSize,
                                Buffer
                                );
    ASSERT(Status == EFI_BUFFER_TOO_SMALL);
    Buffer = (EFI_HANDLE*)AllocatePool(BufferSize);
    ASSERT(Buffer != NULL);
    Status = gBS->LocateHandle (ByProtocol,
                                &gEfiShellEnvironment2Guid,
                                NULL, // ignored for ByProtocol
                                &BufferSize,
                                Buffer
                                );
    if (!EFI_ERROR (Status)) {
      //
      // 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) != FALSE) {
          mEfiShellEnvironment2Handle = Buffer[HandleIndex];
          Status = EFI_SUCCESS;
          break;
        }
      }
    }
  }
  if (Buffer != NULL) {
    FreePool (Buffer);
  }
  return (Status);
}

EFI_STATUS
EFIAPI
ShellLibConstructorWorker (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
){
  EFI_STATUS Status;

  //
  // UEFI 2.0 shell interfaces (used preferentially)
  //
  Status = gBS->OpenProtocol(ImageHandle, 
                             &gEfiShellProtocolGuid,
                             (VOID **)&mEfiShellProtocol,
                             ImageHandle,
                             NULL,
                             EFI_OPEN_PROTOCOL_GET_PROTOCOL
                             );
  if (EFI_ERROR(Status)) {
    mEfiShellProtocol = NULL;
  }
  Status = gBS->OpenProtocol(ImageHandle, 
                             &gEfiShellParametersProtocolGuid,
                             (VOID **)&mEfiShellParametersProtocol,
                             ImageHandle,
                             NULL,
                             EFI_OPEN_PROTOCOL_GET_PROTOCOL
                             );
  if (EFI_ERROR(Status)) {
    mEfiShellParametersProtocol = NULL;
  }

  if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == 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;
    }
  }
  //
  // only success getting 2 of either the old or new, but no 1/2 and 1/2
  //
  if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface          != NULL) || 
      (mEfiShellProtocol     != NULL && mEfiShellParametersProtocol != NULL)    ) {
    if (mEfiShellProtocol != NULL) {
      FileFunctionMap.GetFileInfo     = mEfiShellProtocol->GetFileInfo;
      FileFunctionMap.SetFileInfo     = mEfiShellProtocol->SetFileInfo;
      FileFunctionMap.ReadFile        = mEfiShellProtocol->ReadFile;
      FileFunctionMap.WriteFile       = mEfiShellProtocol->WriteFile;
      FileFunctionMap.CloseFile       = mEfiShellProtocol->CloseFile;
      FileFunctionMap.DeleteFile      = mEfiShellProtocol->DeleteFile;
      FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition;
      FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition;
      FileFunctionMap.FlushFile       = mEfiShellProtocol->FlushFile;
      FileFunctionMap.GetFileSize     = mEfiShellProtocol->GetFileSize;
    } else {
      FileFunctionMap.GetFileInfo     = FileHandleGetInfo;
      FileFunctionMap.SetFileInfo     = FileHandleSetInfo;
      FileFunctionMap.ReadFile        = FileHandleRead;
      FileFunctionMap.WriteFile       = FileHandleWrite;
      FileFunctionMap.CloseFile       = FileHandleClose;
      FileFunctionMap.DeleteFile      = FileHandleDelete;
      FileFunctionMap.GetFilePosition = FileHandleGetPosition;
      FileFunctionMap.SetFilePosition = FileHandleSetPosition;
      FileFunctionMap.FlushFile       = FileHandleFlush;
      FileFunctionMap.GetFileSize     = 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;
  mEfiShellProtocol           = NULL;
  mEfiShellParametersProtocol = NULL;
  mEfiShellInterface          = NULL;
  mEfiShellEnvironment2Handle = NULL;

  //
  // verify that auto initialize is not set false
  // 
  if (PcdGetBool(PcdShellLibAutoInitialize) == 0) {
    return (EFI_SUCCESS);
  }
  
  return (ShellLibConstructorWorker(ImageHandle, SystemTable));
}

/**
  Destructory for the library.  free any resources.
**/
EFI_STATUS
EFIAPI
ShellLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  ){
  if (mEfiShellEnvironment2 != NULL) {
    gBS->CloseProtocol(mEfiShellEnvironment2Handle==NULL?ImageHandle:mEfiShellEnvironment2Handle,
                       &gEfiShellEnvironment2Guid,
                       ImageHandle,
                       NULL);
    mEfiShellEnvironment2 = NULL;
  }
  if (mEfiShellInterface != NULL) {
    gBS->CloseProtocol(ImageHandle,
                       &gEfiShellInterfaceGuid,
                       ImageHandle,
                       NULL);  
    mEfiShellInterface = NULL;
  }
  if (mEfiShellProtocol != NULL) {
    gBS->CloseProtocol(ImageHandle,
                       &gEfiShellProtocolGuid,
                       ImageHandle,
                       NULL);  
    mEfiShellProtocol = NULL;
  }
  if (mEfiShellParametersProtocol != NULL) {
    gBS->CloseProtocol(ImageHandle,
                       &gEfiShellParametersProtocolGuid,
                       ImageHandle,
                       NULL);    
    mEfiShellParametersProtocol = NULL;
  }
  mEfiShellEnvironment2Handle = 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 (
  ) {
  //
  // if auto initialize is not false then skip
  //
  if (PcdGetBool(PcdShellLibAutoInitialize) != 0) {
    return (EFI_SUCCESS);
  }

  //
  // deinit the current stuff
  //
  ASSERT_EFI_ERROR(ShellLibDestructor(gImageHandle, gST));

  //
  // 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 EFI_FILE_HANDLE            FileHandle
  )
{
  return (FileFunctionMap.GetFileInfo(FileHandle));
}

/**
  This function will set the information about the file for the opened handle 
  specified.

  @param  FileHandle            The file handle of the file for which information 
  is being set

  @param  FileInfo              The infotmation to set.

  @retval EFI_SUCCESS		The information was set.
  @retval EFI_UNSUPPORTED The InformationType is not known.
  @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 EFI_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  DeviceHandle  	pointer to the system device handle.
  @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 EFI_HANDLE                    	*DeviceHandle,
  OUT EFI_FILE_HANDLE               	*FileHandle,
  IN UINT64                          	OpenMode,
  IN UINT64                          	Attributes
  )
{
  CHAR16      *FileName;
  EFI_STATUS  Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
  EFI_FILE_HANDLE LastHandle;

  //
  // ASERT for FileHandle, FilePath, and DeviceHandle being NULL
  //
  ASSERT(FilePath != NULL);
  ASSERT(FileHandle != NULL);
  ASSERT(DeviceHandle != NULL);
  // 
  // which shell interface should we use
  //
  if (mEfiShellProtocol != NULL) {
    //
    // use UEFI Shell 2.0 method.
    //
    FileName = mEfiShellProtocol->GetFilePathFromDevicePath(*FilePath);
    if (FileName == NULL) {
      return (EFI_INVALID_PARAMETER);
    }
    Status = ShellOpenFileByName(FileName, FileHandle, OpenMode, Attributes);
    FreePool(FileName);
    return (Status);
  } 


  //
  // use old shell method.
  //
  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, 
                                  FilePath, 
                                  DeviceHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = gBS->OpenProtocol(*DeviceHandle,
                             &gEfiSimpleFileSystemProtocolGuid,
                             (VOID**)&EfiSimpleFileSystemProtocol,
                             gImageHandle,
                             NULL,
                             EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, FileHandle);
  if (EFI_ERROR (Status)) {
    FileHandle = NULL;
    return Status;
  }

  //
  // go down directories one node at a time.
  //
  while (!IsDevicePathEnd (*FilePath)) {
    //
    // For file system access each node should be a file path component
    //
    if (DevicePathType    (*FilePath) != MEDIA_DEVICE_PATH ||
        DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
        ) {
      FileHandle = NULL;
      return (EFI_INVALID_PARAMETER);
    }
    //
    // Open this file path node
    //
    LastHandle  = *FileHandle;
    *FileHandle = NULL;

    //
    // Try to test opening an existing file
    //
    Status = LastHandle->Open (
                          LastHandle,
                          FileHandle,
                          ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
                          OpenMode &~EFI_FILE_MODE_CREATE,
                          0
                          );

    //
    // see if the error was that it needs to be created
    //
    if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
      Status = LastHandle->Open (
                            LastHandle,
                            FileHandle,
                            ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
                            OpenMode,
                            Attributes
                            );
    }
    //
    // Close the last node
    //
    LastHandle->Close (LastHandle);

    if (EFI_ERROR(Status)) {
      return (Status);
    }

    //
    // Get the next node
    //
    *FilePath = NextDevicePathNode (*FilePath);
  }
  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 EFI_FILE_HANDLE           *FileHandle,
  IN UINT64                     OpenMode,
  IN UINT64                    	Attributes
  )
{
  EFI_HANDLE                    DeviceHandle;
  EFI_DEVICE_PATH_PROTOCOL      *FilePath;
  EFI_STATUS                    Status;
  EFI_FILE_INFO                 *FileInfo;

  //
  // ASSERT if FileName is NULL
  //
  ASSERT(FileName != NULL);

  if (mEfiShellProtocol != NULL) {
    //
    // Use UEFI Shell 2.0 method
    //
    Status = mEfiShellProtocol->OpenFileByName(FileName,
                                               FileHandle,
                                               OpenMode);
    if (!EFI_ERROR(Status)){
      FileInfo = FileHandleGetInfo(*FileHandle);
      ASSERT(FileInfo != NULL);
      FileInfo->Attribute = Attributes;
      Status = FileHandleSetInfo(*FileHandle, FileInfo);
    }
    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 (FileDevicePath != NULL) {
    return (ShellOpenFileByDevicePath(&FilePath,
                                      &DeviceHandle,
                                      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 EFI_FILE_HANDLE         *FileHandle
  )
{
  //
  // this is a pass thru to the open file function with sepcific open mode and attributes
  //
  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 EFI_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 EFI_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 EFI_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 EFI_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 EFI_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 EFI_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 EFI_FILE_HANDLE            FileHandle
  )
{
  return (FileFunctionMap.FlushFile(FileHandle));
}

/**
  Retrieves the first file from a directory

  This function opens a directory and gets the first file's info in the 
  directory. Caller can use ShellFindNextFile() to get other files.  When 
  complete the caller is responsible for calling FreePool() on Buffer.

  @param DirHandle              The file handle of the directory to search
  @param Buffer                 Pointer to buffer for 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 EFI_FILE_HANDLE            DirHandle,
  OUT EFI_FILE_INFO             **Buffer
  )
{
  //
  // pass to file handle lib
  //
  return (FileHandleFindFirstFile(DirHandle, Buffer));
}
/**
  Retrieves the next file in a directory.

  To use this function, caller must call the LibFindFirstFile() to get the 
  first file, and then use this function get other files. This function can be 
  called for several times to get each file's information in the directory. If 
  the call of ShellFindNextFile() got the last file in the directory, the next 
  call of this function has no file to get. *NoFile will be set to TRUE and the 
  Buffer memory will be automatically freed. 

  @param DirHandle              the file handle of the directory
  @param Buffer			            pointer to buffer for file's information
  @param NoFile			            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 EFI_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 EFI_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 (mEfiShellProtocol != NULL) {

    //
    // We are using UEFI Shell 2.0; see if the event has been triggered
    //
    if (gBS->CheckEvent(mEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) {
      return (FALSE);
    }
    return (TRUE);
  } 

  //
  // using EFI Shell; call the function to check
  //
  ASSERT(mEfiShellEnvironment2 != NULL);
  return (mEfiShellEnvironment2->GetExecutionBreak());
}
/**
  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 (mEfiShellProtocol != NULL) {
    return (mEfiShellProtocol->GetEnv(EnvKey));
  }

  //
  // ASSERT that we must have EFI shell
  //
  ASSERT(mEfiShellEnvironment2 != NULL);

  //
  // using EFI Shell
  //
  return (mEfiShellEnvironment2->GetEnv((CHAR16*)EnvKey));
}
/**
  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 (mEfiShellProtocol != NULL) {
    return (mEfiShellProtocol->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.

EnvironmentVariables and Status are only supported for UEFI Shell 2.0.
Output is only supported for pre-UEFI Shell 2.0

  @param ImageHandle            Parent image that is starting the operation
  @param CommandLine            pointer to null terminated command line.
  @param Output                 true to display debug output.  false to hide it.
  @param EnvironmentVariables   optional pointer to array of environment variables
                                in the form "x=y".  if NULL current set is used.
  @param 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
  )
{
  // 
  // Check for UEFI Shell 2.0 protocols
  //
  if (mEfiShellProtocol != NULL) {
    //
    // Call UEFI Shell 2.0 version (not using Output parameter)
    //
    return (mEfiShellProtocol->Execute(ParentHandle,
                                      CommandLine,
                                      EnvironmentVariables,
                                      Status));
  } 
  //
  // ASSERT that we must have EFI shell
  //
  ASSERT(mEfiShellEnvironment2 != NULL);
  //
  // Call EFI Shell version (not using EnvironmentVariables or Status parameters)
  // Due to oddity in the EFI shell we want to dereference the ParentHandle here
  //
  return (mEfiShellEnvironment2->Execute(*ParentHandle, 
                                        CommandLine, 
                                        Output));
}
/**
  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.

  @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                     *DeviceName OPTIONAL
  )
{
  // 
  // Check for UEFI Shell 2.0 protocols
  //
  if (mEfiShellProtocol != NULL) {
    return (mEfiShellProtocol->GetCurDir(DeviceName));
  } 
  //
  // ASSERT that we must have EFI shell
  //
  ASSERT(mEfiShellEnvironment2 != NULL);
  return (mEfiShellEnvironment2->CurDir(DeviceName));
}
/**
  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 (mEfiShellProtocol != NULL) {
      //
      // Enable with UEFI 2.0 Shell
      //
      mEfiShellProtocol->EnablePageBreak();
      return;
    } else {
      // 
      // ASSERT that must have EFI Shell
      //
      ASSERT(mEfiShellEnvironment2 != NULL);
      //
      // Enable with EFI Shell
      //
      mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
      return;
    }
  } else {
    // 
    // check for UEFI Shell 2.0
    //
    if (mEfiShellProtocol != NULL) {
      //
      // Disable with UEFI 2.0 Shell
      //
      mEfiShellProtocol->DisablePageBreak();
      return;
    } else {
      // 
      // ASSERT that must have EFI Shell
      //
      ASSERT(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;
  EFI_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*
EFIAPI
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);

    //
    // make sure the old list was valid
    //
    ASSERT(OldInfo           != NULL); 
    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));
    
    // 
    // 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     = AllocateZeroPool(StrSize(OldInfo->FullName));
    NewInfo->FileName     = AllocateZeroPool(StrSize(OldInfo->FileName));
    NewInfo->Info         = AllocateZeroPool((UINTN)OldInfo->Info->Size);
    
    //
    // make sure all the memory allocations were sucessful
    //
    ASSERT(NewInfo->FullName != NULL);
    ASSERT(NewInfo->FileName != NULL);
    ASSERT(NewInfo->Info     != NULL);

    //
    // Copt the strings and structure
    //
    StrCpy(NewInfo->FullName, OldInfo->FullName);
    StrCpy(NewInfo->FileName, OldInfo->FileName);
    gBS->CopyMem (NewInfo->Info, OldInfo->Info, (UINTN)OldInfo->Info->Size);

    //
    // 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_ARG structure to record the file information. These 
  structures are placed on the list ListHead. Users can get the SHELL_FILE_ARG 
  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
  #retval EFI_UNSUPPORTED       a previous ShellOpenFileMetaArg must be closed first.
                                *ListHead is set to NULL.
  @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;
  
  //
  // ASSERT that Arg and ListHead are not NULL
  //
  ASSERT(Arg      != NULL);
  ASSERT(ListHead != NULL);

  // 
  // Check for UEFI Shell 2.0 protocols
  //
  if (mEfiShellProtocol != NULL) {
    if (*ListHead == NULL) {
      *ListHead = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
      if (*ListHead == NULL) {
        return (EFI_OUT_OF_RESOURCES);
      }
      InitializeListHead(&((*ListHead)->Link));
    }    
    return (mEfiShellProtocol->OpenFileList(Arg, 
                                           OpenMode, 
                                           ListHead));
  } 

  //
  // ASSERT that we must have EFI shell
  //
  ASSERT(mEfiShellEnvironment2 != NULL);

  //
  // make sure the list head is initialized
  //
  InitializeListHead(&mOldStyleFileList);

  //
  // Get the EFI Shell list of files
  //
  Status = mEfiShellEnvironment2->FileMetaArg(Arg, &mOldStyleFileList);
  if (EFI_ERROR(Status)) {
    *ListHead = NULL;
    return (Status);
  }

  if (*ListHead == NULL) {
    *ListHead = (EFI_SHELL_FILE_INFO    *)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
    if (*ListHead == NULL) {
      return (EFI_OUT_OF_RESOURCES);
    }
  }

  //
  // 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);

  return (Status);
}
/**
  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 (mEfiShellProtocol != NULL) {
    return (mEfiShellProtocol->FreeFileList(ListHead));
  } else {
    //
    // Since this is EFI Shell version we need to free our internally made copy 
    // of the list
    //
    for ( Node = GetFirstNode(&(*ListHead)->Link) 
        ; IsListEmpty(&(*ListHead)->Link) == FALSE 
        ; Node = GetFirstNode(&(*ListHead)->Link)) {
      RemoveEntryList(Node);
      ((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);
    }
    return EFI_SUCCESS;
  }
}

typedef struct {
  LIST_ENTRY     Link;
  CHAR16         *Name;
  ParamType      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 Type                   pointer to type of parameter if it was found
  @param Name                   pointer to Name of parameter found
  @param CheckList              List to check against

  @retval TRUE                  the Parameter was found.  Type is valid.
  @retval FALSE                 the Parameter was not found.  Type is not valid.
**/
BOOLEAN
EFIAPI
InternalIsOnCheckList (
  IN CONST CHAR16               *Name,
  IN CONST SHELL_PARAM_ITEM     *CheckList,
  OUT ParamType                 *Type
  )
{
  SHELL_PARAM_ITEM              *TempListItem;

  //
  // 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)
      ) {
     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 && StrnCmp(Name, TempListItem->Name, StrLen(TempListItem->Name)) == 0) {
      *Type = TempListItem->Type;
      return (TRUE);
    } else if (StrCmp(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 Name                   pointer to Name of parameter found

  @retval TRUE                  the Parameter is a flag.
  @retval FALSE                 the Parameter not a flag
**/
BOOLEAN
EFIAPI
InternalIsFlag (
  IN CONST CHAR16               *Name
  )
{
  //
  // ASSERT that Name isn't NULL
  //
  ASSERT(Name != NULL);

  //
  // 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 CheckList              pointer to list of parameters to check
  @param CheckPackage           pointer to pointer to list checked values
  @param 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 AutoPageBreak          will automatically set PageBreakEnabled for "b" parameter
  @param Argc                   Count of parameters in Argv
  @param Argv                   pointer to array of parameters

  @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
EFIAPI
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
  )
{
  UINTN                         LoopCounter;
  UINTN                         Count;
  ParamType                     CurrentItemType;
  SHELL_PARAM_PACKAGE           *CurrentItemPackage;
  BOOLEAN                       GetItemValue;

  CurrentItemPackage = NULL;

  //
  // ASSERTs
  //
  ASSERT(CheckList  != NULL);
  ASSERT(Argv       != NULL);

  Count = 0;
  GetItemValue = FALSE;

  //
  // If there is only 1 item we dont need to do anything
  //
  if (Argc <= 1) {
    *CheckPackage = NULL;
    return (EFI_SUCCESS);
  }

  //
  // initialize the linked list
  //
  *CheckPackage = (LIST_ENTRY*)AllocateZeroPool(sizeof(LIST_ENTRY));
  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) == TRUE) {
      //
      // this is a flag
      //
      CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));
      ASSERT(CurrentItemPackage != NULL);
      CurrentItemPackage->Name  = AllocatePool(StrSize(Argv[LoopCounter]));
      ASSERT(CurrentItemPackage->Name != NULL);
      StrCpy(CurrentItemPackage->Name,  Argv[LoopCounter]);
      CurrentItemPackage->Type  = CurrentItemType;
      CurrentItemPackage->OriginalPosition = (UINTN)(-1);
      CurrentItemPackage->Value = NULL;

      //
      // Does this flag require a value
      //
      if (CurrentItemPackage->Type == TypeValue) {
        //
        // trigger the next loop to populate the value of this item
        //
        GetItemValue = TRUE; 
      } else {
        //
        // this item has no value expected; we are done
        //
        InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);
      }
    } else if (GetItemValue == TRUE && InternalIsFlag(Argv[LoopCounter]) == FALSE) {
      ASSERT(CurrentItemPackage != NULL);
      //
      // get the item VALUE for the previous flag
      //
      GetItemValue = FALSE;
      CurrentItemPackage->Value = AllocateZeroPool(StrSize(Argv[LoopCounter]));
      ASSERT(CurrentItemPackage->Value != NULL);
      StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);
      InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);
    } else if (InternalIsFlag(Argv[LoopCounter]) == FALSE) {
      //
      // add this one as a non-flag
      //
      CurrentItemPackage = AllocatePool(sizeof(SHELL_PARAM_PACKAGE));
      ASSERT(CurrentItemPackage != NULL);
      CurrentItemPackage->Name  = NULL;
      CurrentItemPackage->Type  = TypePosition;
      CurrentItemPackage->Value = AllocatePool(StrSize(Argv[LoopCounter]));
      ASSERT(CurrentItemPackage->Value != NULL);
      StrCpy(CurrentItemPackage->Value, Argv[LoopCounter]);
      CurrentItemPackage->OriginalPosition = Count++;
      InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);
    } else if (ProblemParam) {
      //
      // this was a non-recognised flag... error!
      //
      *ProblemParam = AllocatePool(StrSize(Argv[LoopCounter]));
      ASSERT(*ProblemParam != NULL);
      StrCpy(*ProblemParam, Argv[LoopCounter]);
      ShellCommandLineFreeVarList(*CheckPackage);
      *CheckPackage = NULL;
      return (EFI_VOLUME_CORRUPTED);
    } else {
      ShellCommandLineFreeVarList(*CheckPackage);
      *CheckPackage = NULL;
      return (EFI_VOLUME_CORRUPTED);
    }
  }
  //
  // 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 CheckList              pointer to list of parameters to check
  @param CheckPackage           pointer to pointer to list checked values
  @param ProblemParam           optional pointer to pointer to unicode string for 
                                the paramater that caused failure.
  @param AutoPageBreak          will automatically set PageBreakEnabled for "b" parameter

  @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_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
ShellCommandLineParse (
  IN CONST SHELL_PARAM_ITEM     *CheckList,
  OUT LIST_ENTRY                **CheckPackage,
  OUT CHAR16                    **ProblemParam OPTIONAL,
  IN BOOLEAN                    AutoPageBreak
  )
{
  // 
  // ASSERT that CheckList and CheckPackage aren't NULL
  //
  ASSERT(CheckList    != NULL);
  ASSERT(CheckPackage != NULL);

  // 
  // Check for UEFI Shell 2.0 protocols
  //
  if (mEfiShellParametersProtocol != NULL) {
    return (InternalCommandLineParse(CheckList, 
                                     CheckPackage, 
                                     ProblemParam, 
                                     AutoPageBreak, 
                                     (CONST CHAR16**) mEfiShellParametersProtocol->Argv,
                                     mEfiShellParametersProtocol->Argc ));
  }

  // 
  // ASSERT That EFI Shell is not required
  //
  ASSERT (mEfiShellInterface != NULL);
  return (InternalCommandLineParse(CheckList, 
                                   CheckPackage, 
                                   ProblemParam, 
                                   AutoPageBreak, 
                                   (CONST CHAR16**) mEfiShellInterface->Argv,
                                   mEfiShellInterface->Argc ));
}

/**
  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)
      ; Node != 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           *CheckPackage,
  IN CHAR16                     *KeyString
  )
{
  LIST_ENTRY                    *Node;

  //
  // ASSERT that both CheckPackage and KeyString aren't NULL
  //
  ASSERT(KeyString != NULL);

  //
  // return FALSE for no package
  //
  if (CheckPackage == 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 
        && StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0
        ){
        return (TRUE);
      } else if (StrCmp(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 CheckPackage           The package of parsed command line arguments
  @param KeyString              the Key of the command line argument to check for

  @retval NULL                  the flag is not on the command line
  @return !=NULL                pointer to unicode string of the value
  **/
CONST CHAR16*
EFIAPI
ShellCommandLineGetValue (
  IN CONST LIST_ENTRY           *CheckPackage,
  IN CHAR16                     *KeyString
  )
{
  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 Name matches, return the value (name can be NULL)
    //
    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 
        && StrnCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name, StrLen(KeyString)) == 0
        ){
        //
        // return the string part after the flag
        //
        return (((SHELL_PARAM_PACKAGE*)Node)->Name + StrLen(KeyString));
      } else if (StrCmp(KeyString, ((SHELL_PARAM_PACKAGE*)Node)->Name) == 0) {
        //
        // return the value
        //
        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 CheckPackage           The package of parsed command line arguments
  @param Position               the position of the value 

  @retval NULL                  the flag is not on the command line
  @return !=NULL                pointer to unicode string of the value
  **/
CONST CHAR16*
EFIAPI
ShellCommandLineGetRawValue (
  IN CONST LIST_ENTRY           *CheckPackage,
  IN UINT32                     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);
}
/**
  This is a find and replace function.  it will return the NewString as a copy of 
  SourceString with each instance of FindTarget replaced with ReplaceWith.

  If the string would grow bigger than NewSize it will halt and return error.

  @param[in] SourceString             String with source buffer
  @param[in,out] NewString           String with resultant buffer
  @param[in] NewSize                  Size in bytes of NewString
  @param[in] FindTarget               String to look for
  @param[in[ ReplaceWith              String to replace FindTarget with

  @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 sucessfully copied with replacement
**/

EFI_STATUS
EFIAPI
CopyReplace(
  IN CHAR16 CONST                     *SourceString,
  IN CHAR16                           *NewString,
  IN UINTN                            NewSize,
  IN CONST CHAR16                     *FindTarget,
  IN CONST CHAR16                     *ReplaceWith
  ){
  UINTN Size;
  if ( (SourceString == NULL)
    || (NewString    == NULL)
    || (FindTarget   == NULL)
    || (ReplaceWith  == NULL)
    || (StrLen(FindTarget) < 1)
    || (StrLen(SourceString) < 1)
    ){
    return (EFI_INVALID_PARAMETER);
  }
  NewString = SetMem16(NewString, NewSize, L'\0');
  while (*SourceString != L'\0') {
    if (StrnCmp(SourceString, FindTarget, StrLen(FindTarget)) == 0) {
      SourceString += StrLen(FindTarget);
      Size = StrSize(NewString);
      if ((Size + (StrLen(ReplaceWith)*sizeof(CHAR16))) > NewSize) {
        return (EFI_BUFFER_TOO_SMALL);
      }
      StrCat(NewString, ReplaceWith);
    } else {
      Size = StrSize(NewString);
      if (Size + sizeof(CHAR16) > NewSize) {
        return (EFI_BUFFER_TOO_SMALL);
      }
      StrnCat(NewString, SourceString, 1);
      SourceString++;
    }
  }
  return (EFI_SUCCESS);
}

/**
  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] Row        the row to print at
  @param[in] Col        the column to print at
  @param[in] Format     the format string

  @return the number of characters printed to the screen
**/

UINTN
EFIAPI
ShellPrintEx(
  IN INT32                Col OPTIONAL,
  IN INT32                Row OPTIONAL,
  IN CONST CHAR16         *Format,
  ...
  ){
  VA_LIST           Marker;
  UINTN             BufferSize;
  CHAR16            *PostReplaceFormat;
  CHAR16            *PostReplaceFormat2;
  UINTN             Return;

  EFI_STATUS        Status;
  UINTN             NormalAttribute;
  CHAR16            *ResumeLocation;
  CHAR16            *FormatWalker;

  VA_START (Marker, Format);
  
  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);
  PostReplaceFormat = AllocateZeroPool (BufferSize);
  ASSERT (PostReplaceFormat != NULL);
  PostReplaceFormat2 = AllocateZeroPool (BufferSize);
  ASSERT (PostReplaceFormat2 != NULL);

  //
  // Back and forth each time fixing up 1 of our flags...
  //
  Status = CopyReplace(Format,             PostReplaceFormat,  BufferSize, L"%N", L"%%N");
  ASSERT_EFI_ERROR(Status);
  Status = CopyReplace(PostReplaceFormat,  PostReplaceFormat2, BufferSize, L"%E", L"%%E");
  ASSERT_EFI_ERROR(Status);
  Status = CopyReplace(PostReplaceFormat2, PostReplaceFormat,  BufferSize, L"%H", L"%%H");
  ASSERT_EFI_ERROR(Status);
  Status = CopyReplace(PostReplaceFormat,  PostReplaceFormat2, BufferSize, L"%B", L"%%B");
  ASSERT_EFI_ERROR(Status);
  Status = CopyReplace(PostReplaceFormat2, PostReplaceFormat,  BufferSize, L"%V", L"%%V");
  ASSERT_EFI_ERROR(Status);

  //
  // Use the last buffer from replacing to print from...
  //
  Return = UnicodeVSPrint (PostReplaceFormat2, BufferSize, PostReplaceFormat, Marker);

  FreePool(PostReplaceFormat);

  if (Col != -1 && Row != -1) {
    Status = gST->ConOut->SetCursorPosition(gST->ConOut, Col, Row);
    ASSERT_EFI_ERROR(Status);
  }

  NormalAttribute = gST->ConOut->Mode->Attribute;
  FormatWalker = PostReplaceFormat2;
  while (*FormatWalker != L'\0') {
    //
    // Find the next attribute change request
    //
    ResumeLocation = StrStr(FormatWalker, L"%");
    if (ResumeLocation != NULL) {
      *ResumeLocation = L'\0';
    }
    //
    // print the current FormatWalker string
    //
    Status = gST->ConOut->OutputString(gST->ConOut, FormatWalker);
    ASSERT_EFI_ERROR(Status);
    //
    // update the attribute
    //
    if (ResumeLocation != NULL) {
      switch (*(ResumeLocation+1)) {
        case (L'N'):
          gST->ConOut->SetAttribute(gST->ConOut, NormalAttribute);
          break;
        case (L'E'):
          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));
          break;
        case (L'H'):
          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));
          break;
        case (L'B'):
          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));
          break;
        case (L'V'):
          gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((NormalAttribute&(BIT4|BIT5|BIT6))>>4)));
          break;
        default:
          ASSERT(FALSE);
          break;
      }
    } else {
      //
      // reset to normal now...
      //
      gST->ConOut->SetAttribute(gST->ConOut, NormalAttribute);
      break;
    }

    //
    // update FormatWalker to Resume + 2 (skip the % and the indicator)
    //
    FormatWalker = ResumeLocation + 2;
  }

  FreePool(PostReplaceFormat2);

  return (Return);
}
