/** @file
  EBL commands for EFI and PI Devices

  Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>

  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 "Ebl.h"


EFI_DXE_SERVICES  *gDS = NULL;


/**
  Print information about the File System device.

  @param  File  Open File for the device

**/
VOID
EblPrintFsInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  CHAR16 *Str;

  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: ", File->DeviceName);
  if (File->FsInfo != NULL) {
    for (Str = File->FsInfo->VolumeLabel; *Str != '\0'; Str++) {
      if (*Str == ' ') {
        // UI makes you enter _ for space, so make the printout match that
        *Str = '_';
      }
      AsciiPrint ("%c", *Str);
    }
    AsciiPrint (":");
    if (File->FsInfo->ReadOnly) {
      AsciiPrint ("ReadOnly");
    }
  }

  AsciiPrint ("\n");
  EfiClose (File);
}


/**
  Print information about the FV devices.

  @param  File  Open File for the device

**/
VOID
EblPrintFvbInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: 0x%08lx - 0x%08lx : 0x%08x\n", File->DeviceName, File->FvStart, File->FvStart + File->FvSize - 1, File->FvSize);
  EfiClose (File);
}


/**
  Print information about the Blk IO devices.
  If the device supports PXE dump out extra information

  @param  File  Open File for the device

**/
VOID
EblPrintBlkIoInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  UINT64                    DeviceSize;
  UINTN                     Index;
  UINTN                     Max;
  EFI_OPEN_FILE             *FsFile;

  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: ", File->DeviceName);

  // print out name of file system, if any, on this block device
  Max = EfiGetDeviceCounts (EfiOpenFileSystem);
  if (Max != 0) {
    for (Index = 0; Index < Max; Index++) {
      FsFile = EfiDeviceOpenByType (EfiOpenFileSystem, Index);
      if (FsFile != NULL) {
        if (FsFile->EfiHandle == File->EfiHandle) {
          AsciiPrint ("fs%d: ", Index);
          EfiClose (FsFile);
          break;
        }
        EfiClose (FsFile);
      }
    }
  }

  // Print out useful Block IO media properties
  if (File->FsBlockIoMedia->RemovableMedia) {
    AsciiPrint ("Removable ");
  }
  if (!File->FsBlockIoMedia->MediaPresent) {
    AsciiPrint ("No Media\n");
  } else {
    if (File->FsBlockIoMedia->LogicalPartition) {
      AsciiPrint ("Partition ");
    }
    DeviceSize = MultU64x32 (File->FsBlockIoMedia->LastBlock + 1, File->FsBlockIoMedia->BlockSize);
    AsciiPrint ("Size = 0x%lX\n", DeviceSize);
  }
  EfiClose (File);
}

 /**
  Print information about the Load File devices.
  If the device supports PXE dump out extra information

  @param  File  Open File for the device

**/
VOID
EblPrintLoadFileInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  EFI_DEVICE_PATH_PROTOCOL    *DevicePathNode;
  MAC_ADDR_DEVICE_PATH        *MacAddr;
  UINTN                       HwAddressSize;
  UINTN                       Index;

  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: %a ", File->DeviceName, EblLoadFileBootTypeString (File->EfiHandle));

  if (File->DevicePath != NULL) {
    // Try to print out the MAC address
    for (DevicePathNode = File->DevicePath;
        !IsDevicePathEnd (DevicePathNode);
        DevicePathNode = NextDevicePathNode (DevicePathNode)) {

      if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePathNode) == MSG_MAC_ADDR_DP)) {
        MacAddr = (MAC_ADDR_DEVICE_PATH *)DevicePathNode;

        HwAddressSize = sizeof (EFI_MAC_ADDRESS);
        if (MacAddr->IfType == 0x01 || MacAddr->IfType == 0x00) {
          HwAddressSize = 6;
        }

        AsciiPrint ("MAC ");
        for (Index = 0; Index < HwAddressSize; Index++) {
          AsciiPrint ("%02x", MacAddr->MacAddress.Addr[Index] & 0xff);
        }
      }
    }
  }

  AsciiPrint ("\n");
  EfiClose (File);
  return;
}



/**
  Dump information about devices in the system.

  fv:       PI Firmware Volume
  fs:       EFI Simple File System
  blk:      EFI Block IO
  LoadFile: EFI Load File Protocol (commonly PXE network boot)

  Argv[0] - "device"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblDeviceCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN         Index;
  UINTN         CurrentRow;
  UINTN         Max;

  CurrentRow = 0;

  // Need to call here to make sure Device Counts are valid
  EblUpdateDeviceLists ();

  // Now we can print out the info...
  Max = EfiGetDeviceCounts (EfiOpenFirmwareVolume);
  if (Max != 0) {
    AsciiPrint ("Firmware Volume Devices:\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintFvbInfo (EfiDeviceOpenByType (EfiOpenFirmwareVolume, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  Max = EfiGetDeviceCounts (EfiOpenFileSystem);
  if (Max != 0) {
    AsciiPrint ("File System Devices:\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintFsInfo (EfiDeviceOpenByType (EfiOpenFileSystem, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  Max = EfiGetDeviceCounts (EfiOpenBlockIo);
  if (Max != 0) {
    AsciiPrint ("Block IO Devices:\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintBlkIoInfo (EfiDeviceOpenByType (EfiOpenBlockIo, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  Max = EfiGetDeviceCounts (EfiOpenLoadFile);
  if (Max != 0) {
    AsciiPrint ("LoadFile Devices: (usually network)\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintLoadFileInfo (EfiDeviceOpenByType (EfiOpenLoadFile, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  return EFI_SUCCESS;
}


/**
  Start an EFI image (PE32+ with EFI defined entry point).

  Argv[0] - "start"
  Argv[1] - device name and path
  Argv[2] - "" string to pass into image being started

  start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the
                                      ; ascii string arg to pass to the image
  start fv0:\FV                       ; load an FV from an FV (not common)
  start LoadFile0:                    ; load an FV via a PXE boot

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblStartCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                  Status;
  EFI_OPEN_FILE               *File;
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
  EFI_HANDLE                  ImageHandle;
  UINTN                       ExitDataSize;
  CHAR16                      *ExitData;
  VOID                        *Buffer;
  UINTN                       BufferSize;
  EFI_LOADED_IMAGE_PROTOCOL   *ImageInfo;

  ImageHandle = NULL;

  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DevicePath = File->DevicePath;
  if (DevicePath != NULL) {
    // check for device path form: blk, fv, fs, and loadfile
    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
  } else {
    // Check for buffer form: A0x12345678:0x1234 syntax.
    // Means load using buffer starting at 0x12345678 of size 0x1234.

    Status = EfiReadAllocatePool (File, &Buffer, &BufferSize);
    if (EFI_ERROR (Status)) {
      EfiClose (File);
      return Status;
    }
    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, Buffer, BufferSize, &ImageHandle);

    FreePool (Buffer);
  }

  EfiClose (File);

  if (!EFI_ERROR (Status)) {
    if (Argc >= 3) {
      // Argv[2] is a "" string that we pass directly to the EFI application without the ""
      // We don't pass Argv[0] to the EFI Application (it's name) just the args
      Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo);
      ASSERT_EFI_ERROR (Status);

      ImageInfo->LoadOptionsSize = (UINT32)AsciiStrSize (Argv[2]);
      ImageInfo->LoadOptions     = AllocatePool (ImageInfo->LoadOptionsSize);
      AsciiStrCpyS (ImageInfo->LoadOptions, ImageInfo->LoadOptionsSize, Argv[2]);
    }

    // Transfer control to the EFI image we loaded with LoadImage()
    Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
  }

  return Status;
}


/**
  Load a Firmware Volume (FV) into memory from a device. This causes drivers in
  the FV to be dispatched if the dependencies of the drivers are met.

  Argv[0] - "loadfv"
  Argv[1] - device name and path

  loadfv fs1:\Temp\Fv.Fv ; load an FV from the disk
  loadfv fv0:\FV         ; load an FV from an FV (not common)
  loadfv LoadFile0:      ; load an FV via a PXE boot

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblLoadFvCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                        Status;
  EFI_OPEN_FILE                     *File;
  VOID                              *FvStart;
  UINTN                             FvSize;
  EFI_HANDLE                        FvHandle;


  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (File->Type == EfiOpenMemoryBuffer) {
    // If it is a address just use it.
    Status = gDS->ProcessFirmwareVolume (File->Buffer, File->Size, &FvHandle);
  } else {
    // If it is a file read it into memory and use it
    Status = EfiReadAllocatePool (File, &FvStart, &FvSize);
    EfiClose (File);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle);
    if (EFI_ERROR (Status)) {
      FreePool (FvStart);
    }
  }
  return Status;
}


/**
  Perform an EFI connect to connect devices that follow the EFI driver model.
  If it is a PI system also call the dispatcher in case a new FV was made
  available by one of the connect EFI drivers (this is not a common case).

  Argv[0] - "connect"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblConnectCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS    Status;
  UINTN         HandleCount;
  EFI_HANDLE    *HandleBuffer;
  UINTN         Index;
  BOOLEAN       Dispatch;
  EFI_OPEN_FILE *File;


  if (Argc > 1) {
    if ((*Argv[1] == 'd') || (*Argv[1] == 'D')) {
      Status = gBS->LocateHandleBuffer (
                      AllHandles,
                      NULL,
                      NULL,
                      &HandleCount,
                      &HandleBuffer
                      );
      if (EFI_ERROR (Status)) {
        return Status;
      }

      for (Index = 0; Index < HandleCount; Index++) {
        gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
      }

      //
      // Given we disconnect our console we should go and do a connect now
      //
    } else {
      File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
      if (File != NULL) {
        AsciiPrint ("Connecting %a\n", Argv[1]);
        gBS->ConnectController (File->EfiHandle, NULL, NULL, TRUE);
        EfiClose (File);
        return EFI_SUCCESS;
      }
    }
  }

  Dispatch = FALSE;
  do {
    Status = gBS->LocateHandleBuffer (
                    AllHandles,
                    NULL,
                    NULL,
                    &HandleCount,
                    &HandleBuffer
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    for (Index = 0; Index < HandleCount; Index++) {
      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
    }

    FreePool (HandleBuffer);

    //
    // Check to see if it's possible to dispatch an more DXE drivers.
    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
    // If anything is Dispatched Status == EFI_SUCCESS and we will try
    // the connect again.
    //
    if (gDS == NULL) {
      Status = EFI_NOT_FOUND;
    } else {
      Status = gDS->Dispatch ();
      if (!EFI_ERROR (Status)) {
        Dispatch = TRUE;
      }
    }

  } while (!EFI_ERROR (Status));

  if (Dispatch) {
    AsciiPrint ("Connected and dispatched\n");
  } else {
    AsciiPrint ("Connect\n");
  }

  return EFI_SUCCESS;
}



CHAR8 *gMemMapType[] = {
  "reserved  ",
  "LoaderCode",
  "LoaderData",
  "BS_code   ",
  "BS_data   ",
  "RT_code   ",
  "RT_data   ",
  "available ",
  "Unusable  ",
  "ACPI_recl ",
  "ACPI_NVS  ",
  "MemMapIO  ",
  "MemPortIO ",
  "PAL_code  "
};


/**
  Dump out the EFI memory map

  Argv[0] - "memmap"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblMemMapCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS            Status;
  EFI_MEMORY_DESCRIPTOR *MemMap;
  EFI_MEMORY_DESCRIPTOR *OrigMemMap;
  UINTN                 MemMapSize;
  UINTN                 MapKey;
  UINTN                 DescriptorSize;
  UINT32                DescriptorVersion;
  UINT64                PageCount[EfiMaxMemoryType];
  UINTN                 Index;
  UINT64                EntrySize;
  UINTN                 CurrentRow;
  UINT64                TotalMemory;

  ZeroMem (PageCount, sizeof (PageCount));

  AsciiPrint ("EFI Memory Map\n");

  // First call is to figure out how big the buffer needs to be
  MemMapSize = 0;
  MemMap     = NULL;
  Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    // In case the AllocatPool changes the memory map we added in some extra descriptors
    MemMapSize += (DescriptorSize * 0x100);
    OrigMemMap = MemMap = AllocatePool (MemMapSize);
    if (OrigMemMap != NULL) {
      // 2nd time we get the data
      Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);
      if (!EFI_ERROR (Status)) {
        for (Index = 0, CurrentRow = 0; Index < MemMapSize/DescriptorSize; Index++) {
          EntrySize = LShiftU64 (MemMap->NumberOfPages, 12);
          AsciiPrint ("\n%a %016lx - %016lx: # %08lx %016lx", gMemMapType[MemMap->Type % EfiMaxMemoryType], MemMap->PhysicalStart, MemMap->PhysicalStart + EntrySize -1, MemMap->NumberOfPages, MemMap->Attribute);
          if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
            break;
          }

          PageCount[MemMap->Type % EfiMaxMemoryType] += MemMap->NumberOfPages;
          MemMap = NEXT_MEMORY_DESCRIPTOR (MemMap, DescriptorSize);
        }
      }

      for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++) {
        if (PageCount[Index] != 0) {
          AsciiPrint ("\n  %a %,7ld Pages (%,14ld)", gMemMapType[Index], PageCount[Index], LShiftU64 (PageCount[Index], 12));
          if (Index == EfiLoaderCode ||
              Index == EfiLoaderData ||
              Index == EfiBootServicesCode ||
              Index == EfiBootServicesData ||
              Index == EfiRuntimeServicesCode ||
              Index == EfiRuntimeServicesData ||
              Index == EfiConventionalMemory ||
              Index == EfiACPIReclaimMemory ||
              Index == EfiACPIMemoryNVS ||
              Index == EfiPalCode
          ) {
            // Count total memory
            TotalMemory += PageCount[Index];
          }
        }
      }

      AsciiPrint ("\nTotal Memory: %,ld MB (%,ld bytes)\n", RShiftU64 (TotalMemory, 8), LShiftU64 (TotalMemory, 12));

      FreePool (OrigMemMap);

    }
  }

  return EFI_SUCCESS;
}




/**
  Load a file into memory and optionally jump to it. A load address can be
  specified or automatically allocated. A quoted command line can optionally
  be passed into the image.

  Argv[0] - "go"
  Argv[1] - Device Name:path for the file to load
  Argv[2] - Address to load to or '*' if the load address will be allocated
  Argv[3] - Optional Entry point to the image. Image will be called if present
  Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs
            to include the command name

  go fv1:\EblCmdX  0x10000  0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX
    from FV1 to location 0x10000 and call the entry point at 0x10010 passing
    in "EblCmdX Arg2 Arg3 Arg4" as the arguments.

  go fv0:\EblCmdX  *  0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0
    to location allocated by this command and call the entry point at offset 0x10
    passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.

  go fv1:\EblCmdX  0x10000; Load EblCmdX to address 0x10000 and return

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblGoCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                    Status;
  EFI_OPEN_FILE                 *File;
  VOID                          *Address;
  UINTN                         Size;
  EBL_COMMMAND                  EntryPoint;
  UINTN                         EntryPointArgc;
  CHAR8                         *EntryPointArgv[MAX_ARGS];


  if (Argc <= 2) {
    // device name and laod address are required
    return EFI_SUCCESS;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    AsciiPrint ("  %a is not a valid path\n", Argv[1]);
    return EFI_SUCCESS;
  }

  EntryPoint  = (EBL_COMMMAND)((Argc > 3) ? (UINTN)AsciiStrHexToUintn (Argv[3]) : (UINTN)NULL);
  if (Argv[2][0] == '*') {
    // * Means allocate the buffer
    Status = EfiReadAllocatePool (File, &Address, &Size);

    // EntryPoint is relative to the start of the image
    EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address);

  } else {
    Address = (VOID *)AsciiStrHexToUintn (Argv[2]);
    Size = File->Size;

    // File->Size for LoadFile is lazy so we need to use the tell to figure it out
    EfiTell (File, NULL);
    Status = EfiRead (File, Address, &Size);
  }

  if (!EFI_ERROR (Status)) {
    AsciiPrint ("Loaded %,d bytes to 0x%08x\n", Size, Address);

    if (Argc > 3) {
      if (Argc > 4) {
        ParseArguments (Argv[4], &EntryPointArgc, EntryPointArgv);
      } else {
        EntryPointArgc = 1;
        EntryPointArgv[0] = File->FileName;
      }

      Status = EntryPoint (EntryPointArgc, EntryPointArgv);
    }
  }

  EfiClose (File);
  return Status;
}

#define FILE_COPY_CHUNK 0x20000

EFI_STATUS
EFIAPI
EblFileCopyCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_OPEN_FILE *Source      = NULL;
  EFI_OPEN_FILE *Destination = NULL;
  EFI_STATUS    Status       = EFI_SUCCESS;
  VOID          *Buffer      = NULL;
  UINTN         Size;
  UINTN         Offset;
  UINTN         Chunk        = FILE_COPY_CHUNK;
  UINTN         FileNameLen, DestFileNameLen;
  CHAR8*        DestFileName;
  CHAR8*        SrcFileName;
  CHAR8*        SrcPtr;

  if (Argc < 3) {
    return EFI_INVALID_PARAMETER;
  }

  DestFileName = Argv[2];
  FileNameLen = AsciiStrLen (DestFileName);

  // Check if the destination file name looks like a directory
  if ((DestFileName[FileNameLen-1] == '\\') || (DestFileName[FileNameLen-1] == ':')) {
    // Set the pointer after the source drive (eg: after fs1:)
    SrcPtr = AsciiStrStr (Argv[1], ":");
    if (SrcPtr == NULL) {
      SrcPtr = Argv[1];
    } else {
      SrcPtr++;
      if (*SrcPtr == '\\') {
        SrcPtr++;
      }
    }

    if (*SrcPtr == '\0') {
      AsciiPrint("Source file incorrect.\n");
    }

    // Skip the Source Directories
    while (1) {
      SrcFileName = SrcPtr;
      SrcPtr = AsciiStrStr (SrcPtr,"\\");
      if (SrcPtr != NULL) {
        SrcPtr++;
      } else {
        break;
      }
    }

    if (*SrcFileName == '\0') {
      AsciiPrint("Source file incorrect (Error 2).\n");
    }

    // Construct the destination filepath
    DestFileNameLen = FileNameLen + AsciiStrLen (SrcFileName) + 1;
    DestFileName = (CHAR8*)AllocatePool (DestFileNameLen);
    AsciiStrCpyS (DestFileName, DestFileNameLen, Argv[2]);
    AsciiStrCatS (DestFileName, DestFileNameLen, SrcFileName);
  }

  Source = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);
  if (Source == NULL) {
    AsciiPrint("Source file open error.\n");
    return EFI_NOT_FOUND;
  }

  Destination = EfiOpen(DestFileName, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
  if (Destination == NULL) {
    AsciiPrint("Destination file open error.\n");
    return EFI_NOT_FOUND;
  }

  Buffer = AllocatePool(FILE_COPY_CHUNK);
  if (Buffer == NULL) {
    goto Exit;
  }

  Size = EfiTell(Source, NULL);

  for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {
    Chunk = FILE_COPY_CHUNK;

    Status = EfiRead(Source, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Read file error %r\n", Status);
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error %r\n", Status);
      goto Exit;
    }
  }

  // Any left over?
  if (Offset < Size) {
    Chunk = Size - Offset;

    Status = EfiRead(Source, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Read file error %r\n", Status);
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error %r\n", Status);
      goto Exit;
    }
  }


Exit:
  if (Source != NULL) {
    Status = EfiClose(Source);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Source close error %r\n", Status);
    }
  }
  if (Destination != NULL) {
    Status = EfiClose(Destination);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Destination close error %r\n", Status);
    }

    // Case when we have concated the filename to the destination directory
    if (DestFileName != Argv[2]) {
      FreePool (DestFileName);
    }
  }

  if (Buffer != NULL) {
    FreePool(Buffer);
  }

  return Status;
}

EFI_STATUS
EFIAPI
EblFileDiffCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_OPEN_FILE *File1   = NULL;
  EFI_OPEN_FILE *File2   = NULL;
  EFI_STATUS    Status   = EFI_SUCCESS;
  VOID          *Buffer1 = NULL;
  VOID          *Buffer2 = NULL;
  UINTN         Size1;
  UINTN         Size2;
  UINTN         Offset;
  UINTN         Chunk   = FILE_COPY_CHUNK;

  if (Argc != 3) {
    return EFI_INVALID_PARAMETER;
  }

  File1 = EfiOpen(Argv[1], EFI_FILE_MODE_READ, 0);
  if (File1 == NULL) {
    AsciiPrint("File 1 open error.\n");
    return EFI_NOT_FOUND;
  }

  File2 = EfiOpen(Argv[2], EFI_FILE_MODE_READ, 0);
  if (File2 == NULL) {
    AsciiPrint("File 2 open error.\n");
    return EFI_NOT_FOUND;
  }

  Size1 = EfiTell(File1, NULL);
  Size2 = EfiTell(File2, NULL);

  if (Size1 != Size2) {
    AsciiPrint("Files differ.\n");
    goto Exit;
  }

  Buffer1 = AllocatePool(FILE_COPY_CHUNK);
  if (Buffer1 == NULL) {
    goto Exit;
  }

  Buffer2 = AllocatePool(FILE_COPY_CHUNK);
  if (Buffer2 == NULL) {
    goto Exit;
  }

  for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size1; Offset += Chunk) {
    Chunk = FILE_COPY_CHUNK;

    Status = EfiRead(File1, Buffer1, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("File 1 read error\n");
      goto Exit;
    }

    Status = EfiRead(File2, Buffer2, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("File 2 read error\n");
      goto Exit;
    }

    if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {
      AsciiPrint("Files differ.\n");
      goto Exit;
    };
  }

  // Any left over?
  if (Offset < Size1) {
    Chunk = Size1 - Offset;

    Status = EfiRead(File1, Buffer1, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("File 1 read error\n");
      goto Exit;
    }

    Status = EfiRead(File2, Buffer2, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("File 2 read error\n");
      goto Exit;
    }
  }

  if (CompareMem(Buffer1, Buffer2, Chunk) != 0) {
    AsciiPrint("Files differ.\n");
  } else {
    AsciiPrint("Files are identical.\n");
  }

Exit:
  if (File1 != NULL) {
    Status = EfiClose(File1);
    if (EFI_ERROR(Status)) {
      AsciiPrint("File 1 close error %r\n", Status);
    }
  }

  if (File2 != NULL) {
    Status = EfiClose(File2);
    if (EFI_ERROR(Status)) {
      AsciiPrint("File 2 close error %r\n", Status);
    }
  }

  if (Buffer1 != NULL) {
    FreePool(Buffer1);
  }

  if (Buffer2 != NULL) {
    FreePool(Buffer2);
  }

  return Status;
}

GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDeviceTemplate[] =
{
  {
    "connect",
    "[d]; Connect all EFI devices. d means disconnect",
    NULL,
    EblConnectCmd
  },
  {
    "device",
    "; Show information about boot devices",
    NULL,
    EblDeviceCmd
  },
  {
    "go",
    " dev:path loadaddress entrypoint args; load to given address and jump in",
    NULL,
    EblGoCmd
  },
  {
    "loadfv",
    " devname; Load PI FV from device",
    NULL,
    EblLoadFvCmd
  },
  {
    "start",
    " path; EFI Boot Device:filepath. fs1:\\EFI\\BOOT.EFI",
    NULL,
    EblStartCmd
  },
  {
    "memmap",
    "; dump EFI memory map",
    NULL,
    EblMemMapCmd
  },
  {
    "cp",
    " file1 file2; copy file only.",
    NULL,
    EblFileCopyCmd
  },
  {
    "diff",
    " file1 file2; compare files",
    NULL,
    EblFileDiffCmd
  }
};


/**
  Initialize the commands in this in this file
**/

VOID
EblInitializeDeviceCmd (
  VOID
  )
{
  EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
  EblAddCommands (mCmdDeviceTemplate, sizeof (mCmdDeviceTemplate)/sizeof (EBL_COMMAND_TABLE));
}

