/** @file
File IO routines inspired by Streams with an EFI flavor

Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<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.

Basic support for opening files on different device types. The device string
is in the form of DevType:Path. Current DevType is required as there is no
current mounted device concept of current working directory concept implement
by this library.

Device names are case insensitive and only check the leading characters for
unique matches. Thus the following are all the same:
LoadFile0:
l0:
L0:
Lo0:

Supported Device Names:
A0x1234:0x12 - A memory buffer starting at address 0x1234 for 0x12 bytes
l1:          - EFI LoadFile device one.
B0:          - EFI BlockIo zero.
fs3:         - EFI Simple File System device 3
Fv2:         - EFI Firmware VOlume device 2
10.0.1.102:  - TFTP service IP followed by the file name
**/

#include <PiDxe.h>
#include <Protocol/BlockIo.h>             
#include <Protocol/DiskIo.h>             
#include <Protocol/SimpleFileSystem.h>      
#include <Protocol/FirmwareVolume2.h>        
#include <Protocol/LoadFile.h>
#include <Protocol/FirmwareVolumeBlock.h>  
#include <Guid/FileInfo.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PrintLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiLib.h>   
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/EfiFileLib.h>
#include <Library/PcdLib.h>
#include <Library/EblNetworkLib.h>


CHAR8 *gCwd = NULL;

CONST EFI_GUID gZeroGuid  = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };

#define EFI_OPEN_FILE_GUARD_HEADER  0x4B4D4641
#define EFI_OPEN_FILE_GUARD_FOOTER  0x444D5A56

// Need to defend against this overflowing
#define MAX_CMD_LINE  0x200

typedef struct {
  UINT32            Header;
  EFI_OPEN_FILE     File;
  UINT32            Footer;
} EFI_OPEN_FILE_GUARD;


// globals to store current open device info
EFI_HANDLE            *mBlkIo = NULL;
UINTN                 mBlkIoCount = 0;

EFI_HANDLE            *mFs = NULL;
UINTN                 mFsCount = 0;
// mFsInfo[] array entries must match mFs[] handles
EFI_FILE_SYSTEM_INFO  **mFsInfo = NULL;

EFI_HANDLE            *mFv = NULL;
UINTN                 mFvCount = 0;
EFI_HANDLE            *mLoadFile = NULL;
UINTN                 mLoadFileCount = 0;



/**
Internal worker function to validate a File handle.

@param  File    Open File Handle

@return TRUE    File is valid
@return FALSE   File is not valid


**/
BOOLEAN
FileHandleValid (
  IN EFI_OPEN_FILE  *File
  )
{
  EFI_OPEN_FILE_GUARD  *GuardFile;

  // Look right before and after file structure for the correct signatures
  GuardFile = BASE_CR (File, EFI_OPEN_FILE_GUARD, File);
  if ((GuardFile->Header != EFI_OPEN_FILE_GUARD_HEADER) ||
    (GuardFile->Footer != EFI_OPEN_FILE_GUARD_FOOTER) ) {
      return FALSE;
    }

    return TRUE;
}

/**
Internal worker function. If Buffer is not NULL free it.

@param  Buffer    Buffer to FreePool()

**/
VOID
EblFreePool (
  IN  VOID  *Buffer
  )
{
  if (Buffer != NULL) {
    FreePool (Buffer);
  }
}

/**
Update Device List Global Variables

**/
VOID
EblUpdateDeviceLists (
  VOID
  )
{
  EFI_STATUS                        Status;
  UINTN                             Size;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Fs;
  EFI_FILE_HANDLE                   Root;
  UINTN                             Index;

  if (mBlkIo != NULL) {
    FreePool (mBlkIo);
  }
  gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &mBlkIoCount, &mBlkIo);



  if (mFv != NULL) {
    FreePool (mFv);
  }
  gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &mFvCount, &mFv);

  if (mLoadFile != NULL) {
    FreePool (mLoadFile);
  }
  gBS->LocateHandleBuffer (ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &mLoadFileCount, &mLoadFile);

  if (mFs != NULL) {
    FreePool (mFs);
  }

  if (&mFsInfo[0] != NULL) {
    // Need to Free the mFsInfo prior to recalculating mFsCount so don't move this code
    for (Index = 0; Index < mFsCount; Index++) {
      if (mFsInfo[Index] != NULL) {
        FreePool (mFsInfo[Index]);
      }
    }
    FreePool (mFsInfo);
  }

  gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs);


  mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *));
  if (mFsInfo == NULL) {
    // If we can't do this then we can't support file system entries
    mFsCount = 0;
  } else {
    // Loop through all the file system structures and cache the file system info data
    for (Index =0; Index < mFsCount; Index++) {
      Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
      if (!EFI_ERROR (Status)) {
        Status = Fs->OpenVolume (Fs, &Root);
        if (!EFI_ERROR (Status)) {
          // Get information about the volume
          Size = 0;
          Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
          if (Status == EFI_BUFFER_TOO_SMALL) {
            mFsInfo[Index] = AllocatePool (Size);
            Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
          }

          Root->Close (Root);
        }
      }
    }
  }
}


/**
PathName is in the form <device name>:<path> for example fs1:\ or ROOT:\.
Return TRUE if the <devce name> prefix of PathName matches a file system
Volume Name. MatchIndex is the array  index in mFsInfo[] of the match, 
and it can be used with mFs[] to find the handle that needs to be opened

@param  PathName      PathName to check
@param  FileStart     Index of the first character of the <path>
@param  MatchIndex    Index in mFsInfo[] that matches

@return TRUE      PathName matches a Volume Label and MatchIndex is valid
@return FALSE     PathName does not match a Volume Label MatchIndex undefined

**/
BOOLEAN
EblMatchVolumeName (
  IN  CHAR8   *PathName,
  IN  UINTN   FileStart,
  OUT UINTN   *MatchIndex
  )
{
  UINTN   Index;
  UINTN   Compare;
  UINTN   VolStrLen;
  BOOLEAN Match;

  for (Index =0; Index < mFsCount; Index++) {
    if (mFsInfo[Index] == NULL) {
      // FsInfo is not valid so skip it
      continue;
    }
    VolStrLen = StrLen (mFsInfo[Index]->VolumeLabel);
    for (Compare = 0, Match = TRUE; Compare < (FileStart - 1); Compare++) {
      if (Compare > VolStrLen) {
        Match = FALSE;
        break;
      }
      if (PathName[Compare] != (CHAR8)mFsInfo[Index]->VolumeLabel[Compare]) {
        // If the VolumeLabel has a space allow a _ to match with it in addition to ' '
        if (!((PathName[Compare] == '_') && (mFsInfo[Index]->VolumeLabel[Compare] == L' '))) {
          Match = FALSE;
          break;
        }
      }
    }
    if (Match) {
      *MatchIndex = Index;
      return TRUE;
    }
  }

  return FALSE;
}


/**
Return the number of devices of the current type active in the system

@param  Type      Device type to check

@return 0         Invalid type

**/
UINTN
EfiGetDeviceCounts (
  IN  EFI_OPEN_FILE_TYPE     DeviceType
  )
{
  switch (DeviceType) {
  case EfiOpenLoadFile:
    return mLoadFileCount;
  case EfiOpenFirmwareVolume:
    return mFvCount;
  case EfiOpenFileSystem:
    return mFsCount;
  case EfiOpenBlockIo:
    return mBlkIoCount;
  default:
    return 0;
  }
}

EFI_STATUS
ConvertIpStringToEfiIp (
  IN  CHAR8           *PathName, 
  OUT EFI_IP_ADDRESS  *ServerIp
  )
{
  CHAR8     *Str;

  Str = PathName;
  ServerIp->v4.Addr[0] = (UINT8)AsciiStrDecimalToUintn (Str);

  Str = AsciiStrStr (Str, ".");
  if (Str == NULL) {
    return EFI_DEVICE_ERROR;
  }

  ServerIp->v4.Addr[1] = (UINT8)AsciiStrDecimalToUintn (++Str);

  Str = AsciiStrStr (Str, ".");
  if (Str == NULL) {
    return EFI_DEVICE_ERROR;
  }

  ServerIp->v4.Addr[2] = (UINT8)AsciiStrDecimalToUintn (++Str);

  Str = AsciiStrStr (Str, ".");
  if (Str == NULL) {
    return EFI_DEVICE_ERROR;
  }

  ServerIp->v4.Addr[3] = (UINT8)AsciiStrDecimalToUintn (++Str);

  return EFI_SUCCESS;
}


/**
Internal work function to extract a device number from a string skipping 
text. Easy way to extract numbers from strings like blk7:.

@param  Str   String to extract device number form

@return -1    Device string is not valid
@return       Device #

**/
UINTN
EblConvertDevStringToNumber (
  IN  CHAR8   *Str
  )
{
  UINTN   Max;
  UINTN   Index;


  // Find the first digit 
  Max = AsciiStrLen (Str);
  for  (Index = 0; !((*Str >= '0') && (*Str <= '9')) && (Index < Max); Index++) {
    Str++;
  }
  if (Index == Max) {
    return (UINTN)-1;
  }

  return AsciiStrDecimalToUintn (Str);
}


/**
Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo

@param  File        Open file handle
@param  FileName    Name of file after device stripped off


**/
EFI_STATUS
EblFileDevicePath (
  IN OUT EFI_OPEN_FILE  *File,
  IN  CHAR8             *FileName,
  IN  CONST UINT64      OpenMode
  )
{
  EFI_STATUS                        Status;
  UINTN                             Size;
  FILEPATH_DEVICE_PATH              *FilePath;
  EFI_DEVICE_PATH_PROTOCOL          *FileDevicePath;
  CHAR16                            UnicodeFileName[MAX_PATHNAME];
  EFI_BLOCK_IO_PROTOCOL             *BlkIo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Fs;
  EFI_FILE_HANDLE                   Root;


  if ( *FileName != 0 ) {
    AsciiStrToUnicodeStr (FileName, UnicodeFileName);
  } else {
    AsciiStrToUnicodeStr ("\\", UnicodeFileName);
  }

  Size = StrSize (UnicodeFileName);
  FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
  if (FileDevicePath != NULL) {
    FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
    FilePath->Header.Type    = MEDIA_DEVICE_PATH;
    FilePath->Header.SubType = MEDIA_FILEPATH_DP;
    CopyMem (&FilePath->PathName, UnicodeFileName, Size);
    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
    SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));

    if (File->EfiHandle != NULL) {
      File->DevicePath = DevicePathFromHandle (File->EfiHandle);
    }

    File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath);
    FreePool (FileDevicePath);
  }

  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
  if (!EFI_ERROR (Status)) {
    File->FsBlockIoMedia = BlkIo->Media;
    File->FsBlockIo = BlkIo;

    // If we are not opening the device this will get over written with file info
    File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize);
  }

  if (File->Type == EfiOpenFileSystem) {
    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
    if (!EFI_ERROR (Status)) {
      Status = Fs->OpenVolume (Fs, &Root);
      if (!EFI_ERROR (Status)) {
        // Get information about the volume
        Size = 0;
        Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          File->FsInfo = AllocatePool (Size);
          Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
        }

        // Get information about the file
        Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0);
        if (!EFI_ERROR (Status)) {
          Size = 0;
          Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL);
          if (Status == EFI_BUFFER_TOO_SMALL) {
            File->FsFileInfo = AllocatePool (Size);
            Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo);
            if (!EFI_ERROR (Status)) {
              File->Size = (UINTN)File->FsFileInfo->FileSize;
              File->MaxPosition = (UINT64)File->Size;
            }
          }
        }

        Root->Close (Root);
      }
    }
  } else if (File->Type == EfiOpenBlockIo) {
    File->Size = (UINTN)File->MaxPosition;
  }

  return Status;
}

#define ToUpper(a)  ((((a) >= 'a') && ((a) <= 'z')) ? ((a) - 'a' + 'A') : (a))

EFI_STATUS
CompareGuidToString (
  IN  EFI_GUID    *Guid,
  IN  CHAR8       *String
  )
{
  CHAR8       AsciiGuid[64];
  CHAR8       *StringPtr;
  CHAR8       *GuidPtr;

  AsciiSPrint (AsciiGuid, sizeof(AsciiGuid), "%g", Guid);

  StringPtr = String;
  GuidPtr   = AsciiGuid;

  while ((*StringPtr != '\0') && (*GuidPtr != '\0')) {
    // Skip dashes
    if (*StringPtr == '-') {
      StringPtr++;
      continue;
    }

    if (*GuidPtr == '-') {
      GuidPtr++;
      continue;
    }

    if (ToUpper(*StringPtr) != ToUpper(*GuidPtr)) {
      return EFI_NOT_FOUND;
    }

    StringPtr++;
    GuidPtr++;
  }

  return EFI_SUCCESS;
}


/**
Internal work function to fill in EFI_OPEN_FILE information for the FV

@param  File        Open file handle
@param  FileName    Name of file after device stripped off


**/
EFI_STATUS
EblFvFileDevicePath (
  IN OUT EFI_OPEN_FILE  *File,
  IN  CHAR8             *FileName,
  IN  CONST UINT64      OpenMode
  )
{
  EFI_STATUS                          Status;
  EFI_STATUS                          GetNextFileStatus;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  UINTN                               Key;
  UINT32                              AuthenticationStatus;
  CHAR8                               AsciiSection[MAX_PATHNAME];
  VOID                                *Section;
  UINTN                               SectionSize;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;
  EFI_LBA                             Lba;
  UINTN                               BlockSize;
  UINTN                               NumberOfBlocks;
  EFI_FIRMWARE_VOLUME_HEADER          *FvHeader = NULL;
  UINTN                               Index;


  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Get FVB Info about the handle
  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
  if (!EFI_ERROR (Status)) {
    Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
    if (!EFI_ERROR (Status)) {
      FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart;
      File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
      for (Index = 0; FvHeader->BlockMap[Index].Length !=0; Index++) {
        File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
      }

      for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
        Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
        if (EFI_ERROR (Status)) {
          break;
        }
      }
    }
  }


  DevicePath = DevicePathFromHandle (File->EfiHandle);

  if (*FileName == '\0') {
    File->DevicePath = DuplicateDevicePath (DevicePath);
    File->Size = File->FvSize;
    File->MaxPosition = File->Size;
  } else {
    Key = 0;
    do {
      File->FvType = EFI_FV_FILETYPE_ALL;
      GetNextFileStatus = File->Fv->GetNextFile (
        File->Fv, 
        &Key,
        &File->FvType,  
        &File->FvNameGuid, 
        &File->FvAttributes, 
        &File->Size
        );
      if (!EFI_ERROR (GetNextFileStatus)) {
        // Compare GUID first
        Status = CompareGuidToString (&File->FvNameGuid, FileName);
        if (!EFI_ERROR(Status)) {
          break;
        }

        Section = NULL;
        Status = File->Fv->ReadSection (
          File->Fv,
          &File->FvNameGuid,
          EFI_SECTION_USER_INTERFACE,
          0,
          &Section,
          &SectionSize,
          &AuthenticationStatus
          );
        if (!EFI_ERROR (Status)) {
          UnicodeStrToAsciiStr (Section, AsciiSection);
          if (AsciiStriCmp (FileName, AsciiSection) == 0) {
            FreePool (Section);
            break;
          }
          FreePool (Section);
        }
      }
    } while (!EFI_ERROR (GetNextFileStatus));

    if (EFI_ERROR (GetNextFileStatus)) {
      return GetNextFileStatus;
    }

    if (OpenMode != EFI_SECTION_ALL) {
      // Calculate the size of the section we are targeting
      Section = NULL;
      File->Size = 0;
      Status = File->Fv->ReadSection (
        File->Fv,
        &File->FvNameGuid,
        (EFI_SECTION_TYPE)OpenMode,
        0,
        &Section,
        &File->Size,
        &AuthenticationStatus
        );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    File->MaxPosition = File->Size;
    EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid);
    File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
  }


  // FVB not required if FV was soft loaded...
  return EFI_SUCCESS;
}




/**
Open a device named by PathName. The PathName includes a device name and 
path separated by a :. See file header for more details on the PathName
syntax. There is no checking to prevent a file from being opened more than
one type. 

SectionType is only used to open an FV. Each file in an FV contains multiple
sections and only the SectionType section is opened.

For any file that is opened with EfiOpen() must be closed with EfiClose().

@param  PathName    Path to parse to open 
@param  OpenMode    Same as EFI_FILE.Open()
@param  SectionType Section in FV to open.

@return NULL  Open failed
@return Valid EFI_OPEN_FILE handle

**/
EFI_OPEN_FILE *
EfiOpen (
  IN        CHAR8               *PathName,
  IN  CONST UINT64              OpenMode,
  IN  CONST EFI_SECTION_TYPE    SectionType
  )
{
  EFI_STATUS                Status;
  EFI_OPEN_FILE             *File;
  EFI_OPEN_FILE             FileData;
  UINTN                     StrLen;
  UINTN                     FileStart;
  UINTN                     DevNumber = 0;
  EFI_OPEN_FILE_GUARD       *GuardFile;
  BOOLEAN                   VolumeNameMatch;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     Size;
  EFI_IP_ADDRESS            Ip;
  CHAR8                     *CwdPlusPathName;
  UINTN                     Index;
  EFI_SECTION_TYPE          ModifiedSectionType;

  EblUpdateDeviceLists ();

  File = &FileData;
  ZeroMem (File, sizeof (EFI_OPEN_FILE));

  StrLen = AsciiStrSize (PathName);
  if (StrLen <= 1) {
    // Smallest valid path is 1 char and a null
    return NULL;
  }

  for (FileStart = 0; FileStart < StrLen; FileStart++) {
    if (PathName[FileStart] == ':') {
      FileStart++;
      break;
    }
  }

  //
  // Matching volume name has precedence over handle based names
  //
  VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
  if (!VolumeNameMatch) {
    if (FileStart == StrLen) {
      // No Volume name or device name, so try Current Working Directory
      if (gCwd == NULL) {
        // No CWD
        return NULL;
      }

      // We could add a current working directory concept
      CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
      if (CwdPlusPathName == NULL) {
        return NULL;
      }

      if ((PathName[0] == '/') || (PathName[0] == '\\')) {
        // PathName starts in / so this means we go to the root of the device in the CWD. 
        CwdPlusPathName[0] = '\0';
        for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
          CwdPlusPathName[FileStart] = gCwd[FileStart];
          if (gCwd[FileStart] == ':') {
            FileStart++;
            CwdPlusPathName[FileStart] = '\0';
            break;
          }
        }
      } else {
        AsciiStrCpy (CwdPlusPathName, gCwd);
        StrLen = AsciiStrLen (gCwd);
        if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
          AsciiStrCat (CwdPlusPathName, "\\");
        }
      }

      AsciiStrCat (CwdPlusPathName, PathName);
      if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
        // Extra error check to make sure we don't recurse and blow stack
        return NULL;
      }

      File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
      FreePool (CwdPlusPathName);
      return File;
    }

    DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName); 
  }

  File->DeviceName = AllocatePool (StrLen);
  AsciiStrCpy (File->DeviceName, PathName);
  File->DeviceName[FileStart - 1] = '\0';
  File->FileName = &File->DeviceName[FileStart];
  if (File->FileName[0] == '\0') {
    // if it is just a file name use / as root
    File->FileName = "\\";
  } 

  //
  // Use best match algorithm on the dev names so we only need to look at the
  // first few charters to match the full device name. Short name forms are 
  // legal from the caller.
  //
  Status = EFI_SUCCESS;
  if (*PathName == 'f' || *PathName == 'F' || VolumeNameMatch) {
    if (PathName[1] == 's' || PathName[1] == 'S' || VolumeNameMatch) {
      if (DevNumber >= mFsCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFileSystem;
      File->EfiHandle = mFs[DevNumber];
      Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);

    } else if (PathName[1] == 'v' || PathName[1] == 'V') { 
      if (DevNumber >= mFvCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFirmwareVolume;
      File->EfiHandle = mFv[DevNumber];

      if ((PathName[FileStart] == '/') || (PathName[FileStart] == '\\')) {
        // Skip leading / as its not really needed for the FV since no directories are supported
        FileStart++;
      }

      // Check for 2nd :
      ModifiedSectionType = SectionType;
      for (Index = FileStart; PathName[Index] != '\0'; Index++) {
        if (PathName[Index] == ':') {
          // Support fv0:\DxeCore:0x10
          // This means open the PE32 Section of the file 
          ModifiedSectionType = (EFI_SECTION_TYPE)AsciiStrHexToUintn (&PathName[Index + 1]);
          PathName[Index] = '\0';
        }
      }
      File->FvSectionType = ModifiedSectionType;
      Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
    }
  } else if ((*PathName == 'A') || (*PathName == 'a')) {
    // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE
    File->Type = EfiOpenMemoryBuffer;
    // 1st colon is at PathName[FileStart - 1]
    File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      File->Size = 0;
    } else {
      File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if there's no number after the second colon, default
    // the end of memory
    if (File->Size == 0) {
      File->Size =  (UINTN)(0 - (UINTN)File->Buffer);
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = (UINTN)File->Buffer;

  } else if (*PathName== 'l' || *PathName == 'L') {
    if (DevNumber >= mLoadFileCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenLoadFile;
    File->EfiHandle = mLoadFile[DevNumber];

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
    File->DevicePath = DuplicateDevicePath (DevicePath);

  } else if (*PathName == 'b' || *PathName == 'B') {
    // Handle b#:0x10000000:0x1234 address form b#:ADDRESS:SIZE
    if (DevNumber >= mBlkIoCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenBlockIo;
    File->EfiHandle = mBlkIo[DevNumber];
    EblFileDevicePath (File, "", OpenMode);

    // 1st colon is at PathName[FileStart - 1]
    File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      Size = 0;
    } else {
      Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if a zero size is passed in (or the size is left out entirely),
    // go to the end of the device.
    if (Size == 0) {
      File->Size = File->Size - File->DiskOffset;
    } else {
      File->Size = Size;
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = File->DiskOffset;
  } else if ((*PathName) >= '0' && (*PathName <= '9')) {

    // Get current IP address
    Status = EblGetCurrentIpAddress (&Ip);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Device IP Address is not configured.\n");
      goto ErrorExit;
    }


    // Parse X.X.X.X:Filename, only support IPv4 TFTP for now...
    File->Type = EfiOpenTftp;
    File->IsDirty = FALSE;
    File->IsBufferValid = FALSE;

    Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
  }

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  GuardFile = (EFI_OPEN_FILE_GUARD *)AllocateZeroPool (sizeof (EFI_OPEN_FILE_GUARD));
  if (GuardFile == NULL) {
    goto ErrorExit;
  }

  GuardFile->Header = EFI_OPEN_FILE_GUARD_HEADER;
  CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
  GuardFile->Footer = EFI_OPEN_FILE_GUARD_FOOTER;

  return &(GuardFile->File);

ErrorExit:
  FreePool (File->DeviceName);
  return NULL;
}

#define FILE_COPY_CHUNK 0x01000000

EFI_STATUS
EfiCopyFile (
  IN        CHAR8               *DestinationFile,
  IN        CHAR8               *SourceFile
  )
{
  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;

  Source = EfiOpen (SourceFile, EFI_FILE_MODE_READ, 0);
  if (Source == NULL) {
    AsciiPrint("Source file open error.\n");
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  Destination = EfiOpen (DestinationFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
  if (Destination == NULL) {
    AsciiPrint("Destination file open error.\n");
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  Buffer = AllocatePool(FILE_COPY_CHUNK);
  if (Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    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\n");
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error\n");
      goto Exit;
    }    
  }

Exit:
  if (Source != NULL) {
    Status = EfiClose(Source);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Source close error");
    }
  }

  if (Destination != NULL) {
    Status = EfiClose(Destination);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Destination close error");
    }
  }

  if (Buffer != NULL) {
    FreePool(Buffer);
  }

  return Status;
}

/**
Use DeviceType and Index to form a valid PathName and try and open it.

@param  DeviceType  Device type to open
@param  Index       Device Index to use. Zero relative.

@return NULL  Open failed
@return Valid EFI_OPEN_FILE handle

**/
EFI_OPEN_FILE  *
EfiDeviceOpenByType (
  IN  EFI_OPEN_FILE_TYPE    DeviceType,
  IN  UINTN                 Index
  )
{
  CHAR8   *DevStr;
  CHAR8   Path[MAX_CMD_LINE];

  switch (DeviceType) {
  case EfiOpenLoadFile:
    DevStr = "loadfile%d:";
    break;
  case EfiOpenFirmwareVolume:
    DevStr = "fv%d:";    
    break;
  case EfiOpenFileSystem:
    DevStr = "fs%d:";    
    break;
  case EfiOpenBlockIo:
    DevStr = "blk%d:";    
    break;
  case EfiOpenMemoryBuffer:
    DevStr = "a%d:";    
    break;
  default:
    return NULL;
  }

  AsciiSPrint (Path, MAX_PATHNAME, DevStr, Index);

  return EfiOpen (Path, EFI_FILE_MODE_READ, 0);
}


/**
Close a file handle opened by EfiOpen() and free all resources allocated by
EfiOpen().

@param  Stream    Open File Handle

@return EFI_INVALID_PARAMETER  Stream is not an Open File
@return EFI_SUCCESS            Steam closed

**/
EFI_STATUS
EfiClose (
  IN  EFI_OPEN_FILE     *File
  )
{
  EFI_STATUS          Status;
  UINT64              TftpBufferSize;

  if (!FileHandleValid (File)) {
    return EFI_INVALID_PARAMETER;
  }

  //Write the buffer contents to TFTP file.
  if ((File->Type == EfiOpenTftp) && (File->IsDirty)) {

    TftpBufferSize = File->Size;
    Status = EblMtftp (
      EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, 
      File->Buffer, 
      TRUE, 
      &TftpBufferSize, 
      NULL, 
      &File->ServerIp, 
      (UINT8 *)File->FileName, 
      NULL, 
      FALSE
      );
    if (EFI_ERROR(Status)) {
      AsciiPrint("TFTP error during APPLE_NSP_TFTP_WRITE_FILE: %r\n", Status);
      return Status;
    }
  }

  if ((File->Type == EfiOpenLoadFile) || 
    ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE)) ||
    ((File->Type == EfiOpenFirmwareVolume) && (File->IsBufferValid == TRUE))) {
    EblFreePool(File->Buffer);
  }

  EblFreePool (File->DevicePath);
  EblFreePool (File->DeviceName);
  EblFreePool (File->FsFileInfo);
  EblFreePool (File->FsInfo);

  if (File->FsFileHandle != NULL) {
    File->FsFileHandle->Close (File->FsFileHandle);
  }

  // Need to free File and it's Guard structures
  EblFreePool (BASE_CR (File, EFI_OPEN_FILE_GUARD, File));
  return EFI_SUCCESS;
}


/**
Return the size of the file represented by Stream. Also return the current 
Seek position. Opening a file will enable a valid file size to be returned.
LoadFile is an exception as a load file size is set to zero. 

@param  Stream    Open File Handle

@return 0         Stream is not an Open File or a valid LoadFile handle

**/
UINTN
EfiTell (
  IN  EFI_OPEN_FILE     *File,
  OUT EFI_LBA           *CurrentPosition    OPTIONAL
  )
{
  EFI_STATUS Status;
  UINT64     BufferSize = 0;

  if (!FileHandleValid (File)) {
    return 0;
  }

  if (CurrentPosition != NULL) {
    *CurrentPosition = File->CurrentPosition;
  }

  if (File->Type == EfiOpenLoadFile) {
    // Figure out the File->Size
    File->Buffer = NULL;
    File->Size   = 0;
    Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, &File->Size, File->Buffer);
    if (Status != EFI_BUFFER_TOO_SMALL) {
      return 0;
    }

    File->MaxPosition = (UINT64)File->Size;
  } else if (File->Type == EfiOpenTftp) {

    Status = EblMtftp (
      EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
      NULL,
      FALSE,
      &BufferSize,
      NULL,
      &File->ServerIp,
      (UINT8 *)File->FileName,
      NULL,
      TRUE
      );
    if (EFI_ERROR(Status)) {
      AsciiPrint("TFTP error during APPLE_NSP_TFTP_GET_FILE_SIZE: %r\n", Status);
      return 0;
    }

    File->Size        = (UINTN)BufferSize;
    File->MaxPosition = File->Size;
  }

  return File->Size;
}


/**
Seek to the Offset location in the file. LoadFile and FV device types do
not support EfiSeek(). It is not possible to grow the file size using 
EfiSeek().

SeekType defines how use Offset to calculate the new file position:
EfiSeekStart  : Position = Offset
EfiSeekCurrent: Position is Offset bytes from the current position
EfiSeekEnd    : Only supported if Offset is zero to seek to end of file.

@param  Stream    Open File Handle
@param  Offset    Offset to seek too. 
@param  SeekType  Type of seek to perform


@return EFI_INVALID_PARAMETER  Stream is not an Open File
@return EFI_UNSUPPORTED        LoadFile and FV do not support Seek
@return EFI_NOT_FOUND          Seek past the end of the file.
@return EFI_SUCCESS            Steam closed

**/
EFI_STATUS
EfiSeek (
  IN  EFI_OPEN_FILE     *File,
  IN  EFI_LBA           Offset,
  IN  EFI_SEEK_TYPE     SeekType
  )
{
  EFI_STATUS    Status;
  UINT64        CurrentPosition;

  if (!FileHandleValid (File)) {
    return EFI_INVALID_PARAMETER;
  }

  if (File->Type == EfiOpenLoadFile) {
    // LoadFile does not support Seek
    return EFI_UNSUPPORTED;
  }

  CurrentPosition = File->CurrentPosition;
  switch (SeekType) {
  case EfiSeekStart:
    if (Offset > File->MaxPosition) {
      return EFI_NOT_FOUND;
    }
    CurrentPosition = Offset;
    break;

  case EfiSeekCurrent:
    if ((File->CurrentPosition + Offset) > File->MaxPosition) {
      return EFI_NOT_FOUND;
    }
    CurrentPosition += Offset;
    break;

  case EfiSeekEnd:
    if (Offset != 0) {
      // We don't support growing file size via seeking past end of file
      return EFI_UNSUPPORTED;
    }
    CurrentPosition = File->MaxPosition;
    break;

  default:
    return EFI_NOT_FOUND;
  }

  Status = EFI_SUCCESS;
  if (File->FsFileHandle != NULL) {
    Status = File->FsFileHandle->SetPosition (File->FsFileHandle, CurrentPosition);
  }

  if (!EFI_ERROR (Status)) {
    File->CurrentPosition = CurrentPosition;
  }

  return Status;
}

EFI_STATUS
CacheTftpFile (
  IN OUT  EFI_OPEN_FILE *File
  )
{
  EFI_STATUS          Status;
  UINT64              TftpBufferSize;

  if (File->IsBufferValid) {
    return EFI_SUCCESS;
  }

  // Make sure the file size is set.
  EfiTell (File, NULL);

  //Allocate a buffer to hold the whole file.
  File->Buffer = AllocatePool(File->Size);
  if (File->Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TftpBufferSize = File->Size;

  Status = EblMtftp (
    EFI_PXE_BASE_CODE_TFTP_READ_FILE, 
    File->Buffer, 
    FALSE, 
    &TftpBufferSize, 
    NULL, 
    &File->ServerIp, 
    (UINT8 *)File->FileName, 
    NULL, 
    FALSE);
  if (EFI_ERROR(Status)) {
    AsciiPrint("TFTP error during APPLE_NSP_TFTP_READ_FILE: %r\n", Status);
    FreePool(File->Buffer);
    return Status;
  }

  // Set the buffer valid flag.
  File->IsBufferValid = TRUE;

  return Status;
}

/**
Read BufferSize bytes from the current location in the file. For load file,
FV, and TFTP case you must read the entire file. 

@param  Stream      Open File Handle
@param  Buffer      Caller allocated buffer. 
@param  BufferSize  Size of buffer in bytes.


@return EFI_SUCCESS           Stream is not an Open File
@return EFI_END_OF_FILE Tried to read past the end of the file
@return EFI_INVALID_PARAMETER Stream is not an open file handle
@return EFI_BUFFER_TOO_SMALL  Buffer is not big enough to do the read
@return "other"               Error returned from device read

**/
EFI_STATUS
EfiRead (
  IN  EFI_OPEN_FILE       *File,
  OUT VOID                *Buffer,
  OUT UINTN               *BufferSize
  )
{
  EFI_STATUS            Status;
  UINT32                AuthenticationStatus;
  EFI_DISK_IO_PROTOCOL  *DiskIo;

  if (!FileHandleValid (File)) {
    return EFI_INVALID_PARAMETER;
  }

  // Don't read past the end of the file.
  if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
    return EFI_END_OF_FILE;
  }

  switch (File->Type) {
  case EfiOpenLoadFile:
    // Figure out the File->Size
    EfiTell (File, NULL);

    Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, BufferSize, Buffer);
    break;

  case EfiOpenFirmwareVolume:
    if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
      // This is the entire FV device, so treat like a memory buffer 
      CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
      File->CurrentPosition += *BufferSize;
      Status = EFI_SUCCESS;
    } else {
      if (File->Buffer == NULL) {
        if (File->FvSectionType == EFI_SECTION_ALL) {
          Status = File->Fv->ReadFile (
            File->Fv,
            &File->FvNameGuid,
            (VOID **)&File->Buffer,
            &File->Size,
            &File->FvType,
            &File->FvAttributes,
            &AuthenticationStatus
            );
        } else {
          Status = File->Fv->ReadSection (
            File->Fv,
            &File->FvNameGuid,
            File->FvSectionType,
            0,
            (VOID **)&File->Buffer,
            &File->Size,
            &AuthenticationStatus
            );
        }
        if (EFI_ERROR (Status)) {
          return Status;
        }
        File->IsBufferValid = TRUE;
      }
      // Operate on the cached buffer so Seek will work
      CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
      File->CurrentPosition += *BufferSize;
      Status = EFI_SUCCESS;
    }
    break;

  case EfiOpenMemoryBuffer:
    CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
    File->CurrentPosition += *BufferSize;
    Status = EFI_SUCCESS;
    break;

  case EfiOpenFileSystem:
    Status = File->FsFileHandle->Read (File->FsFileHandle, BufferSize, Buffer);
    File->CurrentPosition += *BufferSize;
    break;

  case EfiOpenBlockIo:
    Status = gBS->HandleProtocol(File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
    if (!EFI_ERROR(Status)) {
      Status = DiskIo->ReadDisk(DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
    }
    File->CurrentPosition += *BufferSize;
    break;

  case EfiOpenTftp:
    // Cache the file if it hasn't been cached yet.
    if (File->IsBufferValid == FALSE) {
      Status = CacheTftpFile (File);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    }

    // Copy out the requested data
    CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
    File->CurrentPosition += *BufferSize;

    Status = EFI_SUCCESS;
    break;

  default:
    return EFI_INVALID_PARAMETER;
  };

  return Status;
}


/**
Read the entire file into a buffer. This routine allocates the buffer and
returns it to the user full of the read data. 

This is very useful for load file where it's hard to know how big the buffer
must be.

@param  Stream      Open File Handle
@param  Buffer      Pointer to buffer to return. 
@param  BufferSize  Pointer to Size of buffer return..


@return EFI_SUCCESS           Stream is not an Open File
@return EFI_END_OF_FILE       Tried to read past the end of the file
@return EFI_INVALID_PARAMETER Stream is not an open file handle
@return EFI_BUFFER_TOO_SMALL  Buffer is not big enough to do the read
@return "other"               Error returned from device read

**/
EFI_STATUS
EfiReadAllocatePool (
  IN  EFI_OPEN_FILE     *File,
  OUT VOID              **Buffer,
  OUT UINTN             *BufferSize
  )
{
  if (!FileHandleValid (File)) {
    return EFI_INVALID_PARAMETER;
  }

  // Loadfile defers file size determination on Open so use tell to find it
  EfiTell (File, NULL);

  *BufferSize = File->Size;
  *Buffer = AllocatePool (*BufferSize);
  if (*Buffer == NULL) {
    return EFI_NOT_FOUND;
  }

  return EfiRead (File, *Buffer, BufferSize);
}


/**
Write data back to the file. For TFTP case you must write the entire file. 

@param  Stream      Open File Handle
@param  Buffer      Pointer to buffer to return. 
@param  BufferSize  Pointer to Size of buffer return..


@return EFI_SUCCESS           Stream is not an Open File
@return EFI_END_OF_FILE       Tried to read past the end of the file
@return EFI_INVALID_PARAMETER Stream is not an open file handle
@return EFI_BUFFER_TOO_SMALL  Buffer is not big enough to do the read
@return "other"               Error returned from device write

**/
EFI_STATUS
EfiWrite (
  IN  EFI_OPEN_FILE   *File,
  OUT VOID            *Buffer,
  OUT UINTN           *BufferSize
  )
{
  EFI_STATUS              Status;
  EFI_FV_WRITE_FILE_DATA  FileData;
  EFI_DISK_IO_PROTOCOL    *DiskIo;  

  if (!FileHandleValid (File)) {
    return EFI_INVALID_PARAMETER;
  }

  switch (File->Type) {
  case EfiOpenMemoryBuffer:
    if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
      return EFI_END_OF_FILE;
    }

    CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
    File->CurrentPosition += *BufferSize;
    Status = EFI_SUCCESS;

  case EfiOpenLoadFile:
    // LoadFile device is read only be definition
    Status = EFI_UNSUPPORTED;

  case EfiOpenFirmwareVolume:
    if (File->FvSectionType != EFI_SECTION_ALL) {
      // Writes not support to a specific section. You have to update entire file
      return EFI_UNSUPPORTED;
    }

    FileData.NameGuid       = &(File->FvNameGuid);
    FileData.Type           = File->FvType;
    FileData.FileAttributes = File->FvAttributes;
    FileData.Buffer         = Buffer;
    FileData.BufferSize     = (UINT32)*BufferSize;
    Status = File->Fv->WriteFile (File->Fv, 1, EFI_FV_UNRELIABLE_WRITE, &FileData);
    break;

  case EfiOpenFileSystem:
    Status = File->FsFileHandle->Write (File->FsFileHandle, BufferSize, Buffer);
    File->CurrentPosition += *BufferSize;
    break;

  case EfiOpenBlockIo:
    if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
      return EFI_END_OF_FILE;
    }

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
    if (!EFI_ERROR(Status)) {
      Status = DiskIo->WriteDisk (DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
    }
    File->CurrentPosition += *BufferSize;
    break;

  case EfiOpenTftp:
    // Cache the file if it hasn't been cached yet.
    if (File->IsBufferValid == FALSE) {
      Status = CacheTftpFile(File);
      if (EFI_ERROR(Status)) {
        return Status;
      }
    }

    // Don't overwrite the buffer
    if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
      UINT8 *TempBuffer;

      TempBuffer = File->Buffer;

      File->Buffer = AllocatePool ((UINTN)(File->CurrentPosition + *BufferSize));
      if (File->Buffer == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (File->Buffer, TempBuffer, File->Size);

      FreePool (TempBuffer);

      File->Size = (UINTN)(File->CurrentPosition + *BufferSize);
      File->MaxPosition = (UINT64)File->Size;
    }

    // Copy in the requested data
    CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
    File->CurrentPosition += *BufferSize;

    // Mark the file dirty
    File->IsDirty = TRUE;

    Status = EFI_SUCCESS;
    break;

  default:
    Status = EFI_INVALID_PARAMETER;
  };

  return Status;
}


/**
Given Cwd expand Path to remove .. and replace them with real 
directory names.

@param  Cwd     Current Working Directory
@param  Path    Path to expand

@return NULL     Cwd or Path are not valid
@return 'other'  Path with .. expanded

**/
CHAR8 *
ExpandPath (
  IN CHAR8    *Cwd,
  IN CHAR8    *Path
  )
{
  CHAR8   *NewPath;
  CHAR8   *Work, *Start, *End;
  UINTN   StrLen;
  INTN    i;

  if (Cwd == NULL || Path == NULL) {
    return NULL;
  }

  StrLen = AsciiStrSize (Cwd);
  if (StrLen <= 2) {
    // Smallest valid path is 1 char and a null
    return NULL;
  }

  StrLen = AsciiStrSize (Path);
  NewPath = AllocatePool (AsciiStrSize (Cwd) + StrLen + 1);
  if (NewPath == NULL) {
    return NULL;
  }
  AsciiStrCpy (NewPath, Cwd);

  End = Path + StrLen;
  for (Start = Path ;;) {
    Work = AsciiStrStr (Start, "..") ;
    if (Work == NULL) {
      // Remaining part of Path contains no more ..
      break;
    } 

    // append path prior to .. 
    AsciiStrnCat (NewPath, Start, Work - Start);
    StrLen = AsciiStrLen (NewPath);
    for (i = StrLen; i >= 0; i--) {
      if (NewPath[i] == ':') {
        // too many ..
        return NULL;
      }
      if (NewPath[i] == '/' || NewPath[i] == '\\') {
        if ((i > 0) && (NewPath[i-1] == ':')) {
          // leave the / before a :
          NewPath[i+1] = '\0';
        } else {
          // replace / will Null to remove trailing file/dir reference
          NewPath[i] = '\0';
        }
        break;
      }
    }

    Start = Work + 3;
  } 

  // Handle the path that remains after the ..
  AsciiStrnCat (NewPath, Start, End - Start);

  return NewPath;
}


/**
Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
the path does not contain a device name, The CWD is prepended to the path.

@param  Cwd     Current Working Directory to set


@return EFI_SUCCESS           CWD is set
@return EFI_INVALID_PARAMETER Cwd is not a valid device:path

**/
EFI_STATUS
EfiSetCwd (
  IN  CHAR8   *Cwd
  ) 
{
  EFI_OPEN_FILE *File;
  UINTN         Len;
  CHAR8         *Path;

  if (Cwd == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (AsciiStrCmp (Cwd, ".") == 0) {
    // cd . is a no-op
    return EFI_SUCCESS;
  }

  Path = Cwd;
  if (AsciiStrStr (Cwd, "..") != NULL) {
    if (gCwd == NULL) {
      // no parent 
      return EFI_SUCCESS;
    }

    Len = AsciiStrLen (gCwd);
    if ((gCwd[Len-2] == ':') && ((gCwd[Len-1] == '/') || (gCwd[Len-1] == '\\'))) {
      // parent is device so nothing to do
      return EFI_SUCCESS;
    }

    // Expand .. in Cwd, given we know current working directory
    Path = ExpandPath (gCwd, Cwd);
    if (Path == NULL) {
      return EFI_NOT_FOUND;
    }
  }

  File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (gCwd != NULL) {
    FreePool (gCwd);
  }

  // Use the info returned from EfiOpen as it can add in CWD if needed. So Cwd could be
  // relative to the current gCwd or not.
  gCwd = AllocatePool (AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 10);
  if (gCwd == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  AsciiStrCpy (gCwd, File->DeviceName);
  if (File->FileName == NULL) {
    AsciiStrCat (gCwd, ":\\");
  } else {
    AsciiStrCat (gCwd, ":");
    AsciiStrCat (gCwd, File->FileName);
  }


  EfiClose (File);
  if (Path != Cwd) {
    FreePool (Path);
  }
  return EFI_SUCCESS;
}


/**
Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
the path does not contain a device name, The CWD is prepended to the path.
The CWD buffer is only valid until a new call is made to EfiSetCwd(). After
a call to EfiSetCwd() it is not legal to use the pointer returned by 
this function.

@param  Cwd     Current Working Directory 


@return ""      No CWD set
@return 'other' Returns buffer that contains CWD.

**/
CHAR8 *
EfiGetCwd (
  VOID
  )
{
  if (gCwd == NULL) {
    return "";
  }
  return gCwd;
}


