/** @file
  This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware
  volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.

  It will expose a single directory, containing one file for each file in the firmware
  volume. If a file has a UI section, its contents will be used as a filename.
  Otherwise, a string representation of the GUID will be used.
  Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)
  will have ".efi" added to their filename.

  Its primary intended use is to be able to start EFI applications embedded in FVs
  from the UEFI shell. It is entirely read-only.

Copyright (c) 2014, ARM Limited. All rights reserved.
Copyright (c) 2014 - 2018, Intel Corporation. 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.

**/

#include "FvSimpleFileSystemInternal.h"

//
// Template for EFI_FILE_SYSTEM_INFO data structure.
//
EFI_FILE_SYSTEM_INFO mFsInfoTemplate = {
  0,    // Populate at runtime
  TRUE, // Read-only
  0,    // Don't know volume size
  0,    // No free space
  0,    // Don't know block size
  L""   // Populate at runtime
};

//
// Template for EFI_FILE_PROTOCOL data structure.
//
EFI_FILE_PROTOCOL mFileSystemTemplate = {
  EFI_FILE_PROTOCOL_REVISION,
  FvSimpleFileSystemOpen,
  FvSimpleFileSystemClose,
  FvSimpleFileSystemDelete,
  FvSimpleFileSystemRead,
  FvSimpleFileSystemWrite,
  FvSimpleFileSystemGetPosition,
  FvSimpleFileSystemSetPosition,
  FvSimpleFileSystemGetInfo,
  FvSimpleFileSystemSetInfo,
  FvSimpleFileSystemFlush
};

/**
  Find and call ReadSection on the first section found of an executable type.

  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
                                      representing a file's info.
  @param  BufferSize                  Pointer to a caller-allocated UINTN. It indicates the size of
                                      the memory represented by *Buffer.
  @param  Buffer                      Pointer to a pointer to a data buffer to contain file content.

  @retval EFI_SUCCESS                 The call completed successfully.
  @retval EFI_WARN_BUFFER_TOO_SMALL   The buffer is too small to contain the requested output.
  @retval EFI_ACCESS_DENIED           The firmware volume is configured to disallow reads.
  @retval EFI_NOT_FOUND               The requested file was not found in the firmware volume.
  @retval EFI_DEVICE_ERROR            A hardware error occurred when attempting toaccess the firmware volume.

**/
EFI_STATUS
FvFsFindExecutableSection (
  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,
  IN     FV_FILESYSTEM_FILE_INFO           *FvFileInfo,
  IN OUT UINTN                             *BufferSize,
  IN OUT VOID                              **Buffer
  )
{
  EFI_SECTION_TYPE                    SectionType;
  UINT32                              AuthenticationStatus;
  EFI_STATUS                          Status;

  for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_TE; SectionType++) {
    Status = FvProtocol->ReadSection (
                           FvProtocol,
                           &FvFileInfo->NameGuid,
                           SectionType,
                           0,
                           Buffer,
                           BufferSize,
                           &AuthenticationStatus
                           );
    if (Status != EFI_NOT_FOUND) {
      return Status;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Get the size of the buffer that will be returned by FvFsReadFile.

  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
                                      representing a file's info.

  @retval EFI_SUCCESS                 The file size was gotten correctly.
  @retval Others                      The file size wasn't gotten correctly.

**/
EFI_STATUS
FvFsGetFileSize (
  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,
  IN OUT FV_FILESYSTEM_FILE_INFO           *FvFileInfo
  )
{
  UINT32                         AuthenticationStatus;
  EFI_FV_FILETYPE                FoundType;
  EFI_FV_FILE_ATTRIBUTES         Attributes;
  EFI_STATUS                     Status;
  UINT8                          IgnoredByte;
  VOID                           *IgnoredPtr;

  //
  // To get the size of a section, we pass 0 for BufferSize. But we can't pass
  // NULL for Buffer, as that will cause a return of INVALID_PARAMETER, and we
  // can't pass NULL for *Buffer, as that will cause the callee to allocate
  // a buffer of the sections size.
  //
  IgnoredPtr = &IgnoredByte;
  FvFileInfo->FileInfo.FileSize = 0;

  if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {
    //
    // Get the size of the first executable section out of the file.
    //
    Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, (UINTN*)&FvFileInfo->FileInfo.FileSize, &IgnoredPtr);
    if (Status == EFI_WARN_BUFFER_TOO_SMALL) {
      return EFI_SUCCESS;
    }
  } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {
    //
    // Try to get the size of a raw section out of the file
    //
    Status = FvProtocol->ReadSection (
                           FvProtocol,
                           &FvFileInfo->NameGuid,
                           EFI_SECTION_RAW,
                           0,
                           &IgnoredPtr,
                           (UINTN*)&FvFileInfo->FileInfo.FileSize,
                           &AuthenticationStatus
                           );
    if (Status == EFI_WARN_BUFFER_TOO_SMALL) {
      return EFI_SUCCESS;
    }
    if (EFI_ERROR (Status)) {
      //
      // Didn't find a raw section, just return the whole file's size.
      //
      return FvProtocol->ReadFile (
                           FvProtocol,
                           &FvFileInfo->NameGuid,
                           NULL,
                           (UINTN*)&FvFileInfo->FileInfo.FileSize,
                           &FoundType,
                           &Attributes,
                           &AuthenticationStatus
                           );
    }
  } else {
    //
    // Get the size of the entire file
    //
    return FvProtocol->ReadFile (
                         FvProtocol,
                         &FvFileInfo->NameGuid,
                         NULL,
                         (UINTN*)&FvFileInfo->FileInfo.FileSize,
                         &FoundType,
                         &Attributes,
                         &AuthenticationStatus
                         );
  }

  return Status;
}

/**
  Helper function to read a file.

  The data returned depends on the type of the underlying FV file:
  - For executable types, the first section found that contains executable code is returned.
  - For files of type FREEFORM, the driver attempts to return the first section of type RAW.
    If none is found, the entire contents of the FV file are returned.
  - On all other files the entire contents of the FV file is returned, as by
    EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadFile.

  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
                                      representing a file's info.
  @param  BufferSize                  Pointer to a caller-allocated UINTN. It indicates the size of
                                      the memory represented by *Buffer.
  @param  Buffer                      Pointer to a pointer to a data buffer to contain file content.

  @retval EFI_SUCCESS                 The call completed successfully.
  @retval EFI_WARN_BUFFER_TOO_SMALL   The buffer is too small to contain the requested output.
  @retval EFI_ACCESS_DENIED           The firmware volume is configured to disallow reads.
  @retval EFI_NOT_FOUND               The requested file was not found in the firmware volume.
  @retval EFI_DEVICE_ERROR            A hardware error occurred when attempting toaccess the firmware volume.

**/
EFI_STATUS
FvFsReadFile (
  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,
  IN     FV_FILESYSTEM_FILE_INFO           *FvFileInfo,
  IN OUT UINTN                             *BufferSize,
  IN OUT VOID                              **Buffer
  )
{
  UINT32                         AuthenticationStatus;
  EFI_FV_FILETYPE                FoundType;
  EFI_FV_FILE_ATTRIBUTES         Attributes;
  EFI_STATUS                     Status;

  if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {
    //
    // Read the first executable section out of the file.
    //
    Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, BufferSize, Buffer);
  } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {
    //
    // Try to read a raw section out of the file
    //
    Status = FvProtocol->ReadSection (
                           FvProtocol,
                           &FvFileInfo->NameGuid,
                           EFI_SECTION_RAW,
                           0,
                           Buffer,
                           BufferSize,
                           &AuthenticationStatus
                           );
    if (EFI_ERROR (Status)) {
      //
      // Didn't find a raw section, just return the whole file.
      //
      Status = FvProtocol->ReadFile (
                             FvProtocol,
                             &FvFileInfo->NameGuid,
                             Buffer,
                             BufferSize,
                             &FoundType,
                             &Attributes,
                             &AuthenticationStatus
                             );
    }
  } else {
    //
    // Read the entire file
    //
    Status = FvProtocol->ReadFile (
                           FvProtocol,
                           &FvFileInfo->NameGuid,
                           Buffer,
                           BufferSize,
                           &FoundType,
                           &Attributes,
                           &AuthenticationStatus
                           );
  }

  return Status;
}

/**
  Helper function for populating an EFI_FILE_INFO for a file.

  Note the CreateTime, LastAccessTime and ModificationTime fields in EFI_FILE_INFO
  are full zero as FV2 protocol has no corresponding info to fill.

  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
                                      representing a file's info.
  @param  BufferSize                  Pointer to a caller-allocated UINTN. It indicates the size of
                                      the memory represented by FileInfo.
  @param  FileInfo                    A pointer to EFI_FILE_INFO to contain the returned file info.

  @retval EFI_SUCCESS                 The call completed successfully.
  @retval EFI_BUFFER_TOO_SMALL        The buffer is too small to contain the requested output.

**/
EFI_STATUS
FvFsGetFileInfo (
  IN     FV_FILESYSTEM_FILE_INFO           *FvFileInfo,
  IN OUT UINTN                             *BufferSize,
     OUT EFI_FILE_INFO                     *FileInfo
  )
{
  UINTN                      InfoSize;

  InfoSize = (UINTN)FvFileInfo->FileInfo.Size;
  if (*BufferSize < InfoSize) {
    *BufferSize = InfoSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Initialize FileInfo
  //
  CopyMem (FileInfo, &FvFileInfo->FileInfo, InfoSize);

  *BufferSize = InfoSize;
  return EFI_SUCCESS;
}

/**
  Removes the last directory or file entry in a path by changing the last
  L'\' to a CHAR_NULL.

  @param  Path      The pointer to the path to modify.

  @retval FALSE     Nothing was found to remove.
  @retval TRUE      A directory or file was removed.

**/
BOOLEAN
EFIAPI
RemoveLastItemFromPath (
  IN OUT CHAR16 *Path
  )
{
  CHAR16        *Walker;
  CHAR16        *LastSlash;
  //
  // get directory name from path... ('chop' off extra)
  //
  for ( Walker = Path, LastSlash = NULL
      ; Walker != NULL && *Walker != CHAR_NULL
      ; Walker++
     ){
    if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {
      LastSlash = Walker + 1;
    }
  }

  if (LastSlash != NULL) {
    *LastSlash = CHAR_NULL;
    return (TRUE);
  }

  return (FALSE);
}

/**
  Function to clean up paths.

  - Single periods in the path are removed.
  - Double periods in the path are removed along with a single parent directory.
  - Forward slashes L'/' are converted to backward slashes L'\'.

  This will be done inline and the existing buffer may be larger than required
  upon completion.

  @param  Path          The pointer to the string containing the path.

  @retval NULL          An error occured.
  @return Path in all other instances.

**/
CHAR16*
EFIAPI
TrimFilePathToAbsolutePath (
  IN CHAR16 *Path
  )
{
  CHAR16  *TempString;
  UINTN   TempSize;

  if (Path == NULL) {
    return NULL;
  }

  //
  // Fix up the '/' vs '\'
  //
  for (TempString = Path ; (TempString != NULL) && (*TempString != CHAR_NULL); TempString++) {
    if (*TempString == L'/') {
      *TempString = L'\\';
    }
  }

  //
  // Fix up the ..
  //
  while ((TempString = StrStr (Path, L"\\..\\")) != NULL) {
    *TempString  = CHAR_NULL;
    TempString  += 4;
    RemoveLastItemFromPath (Path);
    TempSize     = StrSize (TempString);
    CopyMem (Path + StrLen (Path), TempString, TempSize);
  }

  if (((TempString = StrStr (Path, L"\\..")) != NULL) && (*(TempString + 3) == CHAR_NULL)) {
    *TempString  = CHAR_NULL;
    RemoveLastItemFromPath (Path);
  }

  //
  // Fix up the .
  //
  while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
    *TempString  = CHAR_NULL;
    TempString  += 2;
    TempSize     = StrSize (TempString);
    CopyMem(Path + StrLen (Path), TempString, TempSize);
  }

  if (((TempString = StrStr (Path, L"\\.")) != NULL) && (*(TempString + 2) == CHAR_NULL)) {
    *(TempString + 1) = CHAR_NULL;
  }

  while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
    *TempString  = CHAR_NULL;
    TempString  += 1;
    TempSize     = StrSize(TempString);
    CopyMem(Path + StrLen(Path), TempString, TempSize);
  }

  if (((TempString = StrStr(Path, L"\\\\")) != NULL) && (*(TempString + 1) == CHAR_NULL)) {
    *(TempString) = CHAR_NULL;
  }

  return Path;
}

/**
  Opens a new file relative to the source file's location.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to the source location. This would typically be an open
                     handle to a directory.
  @param  NewHandle  A pointer to the location to return the opened handle for the new
                     file.
  @param  FileName   The Null-terminated string of the name of the file to be opened.
                     The file name may contain the following path modifiers: "\", ".",
                     and "..".
  @param  OpenMode   The mode to open the file. The only valid combinations that the
                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
                     attribute bits for the newly created file.

  @retval EFI_SUCCESS          The file was opened.
  @retval EFI_NOT_FOUND        The specified file 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  An attempt was made to create a file, or open a file for write
                               when the media is write-protected.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @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
FvSimpleFileSystemOpen (
  IN     EFI_FILE_PROTOCOL    *This,
     OUT EFI_FILE_PROTOCOL    **NewHandle,
  IN     CHAR16               *FileName,
  IN     UINT64               OpenMode,
  IN     UINT64               Attributes
  )
{
  FV_FILESYSTEM_INSTANCE      *Instance;
  FV_FILESYSTEM_FILE          *File;
  FV_FILESYSTEM_FILE          *NewFile;
  FV_FILESYSTEM_FILE_INFO     *FvFileInfo;
  LIST_ENTRY                  *FvFileInfoLink;
  EFI_STATUS                  Status;
  UINTN                       FileNameLength;
  UINTN                       NewFileNameLength;
  CHAR16                      *FileNameWithExtension;

  //
  // Check for a valid mode
  //
  switch (OpenMode) {
  case EFI_FILE_MODE_READ:
    break;

  default:
    return EFI_WRITE_PROTECTED;
  }

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  FileName = TrimFilePathToAbsolutePath (FileName);
  if (FileName == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (FileName[0] == L'\\') {
    FileName++;
  }

  //
  // Check for opening root
  //
  if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) {
    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (NewFile == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    NewFile->Signature = FVFS_FILE_SIGNATURE;
    NewFile->Instance  = Instance;
    NewFile->FvFileInfo = File->FvFileInfo;
    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    InitializeListHead (&NewFile->Link);
    InsertHeadList (&Instance->FileHead, &NewFile->Link);

    NewFile->DirReadNext = NULL;
    if (!IsListEmpty (&Instance->FileInfoHead)) {
      NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
    }

    *NewHandle = &NewFile->FileProtocol;
    return EFI_SUCCESS;
  }

  //
  // Do a linear search for a file in the FV with a matching filename
  //
  Status     = EFI_NOT_FOUND;
  FvFileInfo = NULL;
  for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
      !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
       FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
    FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
    if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {
      Status = EFI_SUCCESS;
      break;
    }
  }

  // If the file has not been found check if the filename exists with an extension
  // in case there was no extension present.
  // FvFileSystem adds a 'virtual' extension '.EFI' to EFI applications and drivers
  // present in the Firmware Volume
  if (Status == EFI_NOT_FOUND) {
    FileNameLength = StrLen (FileName);

    // Does the filename already contain the '.EFI' extension?
    if (mUnicodeCollation->StriColl (mUnicodeCollation, FileName + FileNameLength - 4, L".efi") != 0) {
      // No, there was no extension. So add one and search again for the file
      // NewFileNameLength = FileNameLength + 1 + 4 = (Number of non-null character) + (file extension) + (a null character)
      NewFileNameLength = FileNameLength + 1 + 4;
      FileNameWithExtension = AllocatePool (NewFileNameLength * 2);
      StrCpyS (FileNameWithExtension, NewFileNameLength, FileName);
      StrCatS (FileNameWithExtension, NewFileNameLength, L".EFI");

      for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
          !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
           FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
        FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
        if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileNameWithExtension) == 0) {
          Status = EFI_SUCCESS;
          break;
        }
      }
    }
  }

  if (!EFI_ERROR (Status)) {
    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (NewFile == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    NewFile->Signature = FVFS_FILE_SIGNATURE;
    NewFile->Instance  = Instance;
    NewFile->FvFileInfo = FvFileInfo;
    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    InitializeListHead (&NewFile->Link);
    InsertHeadList (&Instance->FileHead, &NewFile->Link);

    *NewHandle = &NewFile->FileProtocol;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Closes a specified file handle.

  @param  This          A pointer to the EFI_FILE_PROTOCOL instance that is the file
                        handle to close.

  @retval EFI_SUCCESS   The file was closed.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemClose (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  FV_FILESYSTEM_INSTANCE      *Instance;
  FV_FILESYSTEM_FILE          *File;

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  if (File != Instance->Root) {
    RemoveEntryList (&File->Link);
    FreePool (File);
  }
  return EFI_SUCCESS;
}

/**
  Reads data from a file.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to read data from.
  @param  BufferSize On input, the size of the Buffer. On output, the amount of data
                     returned in Buffer. In both cases, the size is measured in bytes.
  @param  Buffer     The buffer into which the data is read.

  @retval EFI_SUCCESS          Data was read.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_DEVICE_ERROR     An attempt was made to read from a deleted file.
  @retval EFI_DEVICE_ERROR     On entry, the current file position is beyond the end of the file.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
                               entry. BufferSize has been updated with the size
                               needed to complete the request.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemRead (
  IN     EFI_FILE_PROTOCOL      *This,
  IN OUT UINTN                  *BufferSize,
     OUT VOID                   *Buffer
  )
{
  FV_FILESYSTEM_INSTANCE        *Instance;
  FV_FILESYSTEM_FILE            *File;
  EFI_STATUS                    Status;
  LIST_ENTRY                    *FvFileInfoLink;
  VOID                          *FileBuffer;
  UINTN                         FileSize;

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  if (File->FvFileInfo == Instance->Root->FvFileInfo) {
    if (File->DirReadNext) {
      //
      // Directory read: populate Buffer with an EFI_FILE_INFO
      //
      Status = FvFsGetFileInfo (File->DirReadNext, BufferSize, Buffer);
      if (!EFI_ERROR (Status)) {
        //
        // Successfully read a directory entry, now update the pointer to the
        // next file, which will be read on the next call to this function
        //
        FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, &File->DirReadNext->Link);
        if (IsNull (&Instance->FileInfoHead, FvFileInfoLink)) {
          //
          // No more files left
          //
          File->DirReadNext = NULL;
        } else {
          File->DirReadNext = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
        }
      }
      return Status;
    } else {
      //
      // Directory read. All entries have been read, so return a zero-size
      // buffer.
      //
      *BufferSize = 0;
      return EFI_SUCCESS;
    }
  } else {
    FileSize = (UINTN)File->FvFileInfo->FileInfo.FileSize;

    FileBuffer = AllocateZeroPool (FileSize);
    if (FileBuffer == NULL) {
      return EFI_DEVICE_ERROR;
    }

    Status = FvFsReadFile (File->Instance->FvProtocol, File->FvFileInfo, &FileSize, &FileBuffer);
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    if (*BufferSize + File->Position > FileSize) {
      *BufferSize = (UINTN)(FileSize - File->Position);
    }

    CopyMem (Buffer, (UINT8*)FileBuffer + File->Position, *BufferSize);
    File->Position += *BufferSize;

    return EFI_SUCCESS;
  }
}

/**
  Writes data to a file.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to write data to.
  @param  BufferSize On input, the size of the Buffer. On output, the amount of data
                     actually written. In both cases, the size is measured in bytes.
  @param  Buffer     The buffer of data to write.

  @retval EFI_SUCCESS          Data was written.
  @retval EFI_UNSUPPORTED      Writes to open directory files are not supported.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.
  @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
FvSimpleFileSystemWrite (
  IN     EFI_FILE_PROTOCOL    *This,
  IN OUT UINTN                *BufferSize,
  IN     VOID                 *Buffer
  )
{
  FV_FILESYSTEM_INSTANCE        *Instance;
  FV_FILESYSTEM_FILE            *File;

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  if (File->FvFileInfo == Instance->Root->FvFileInfo) {
    return EFI_UNSUPPORTED;
  } else {
    return EFI_WRITE_PROTECTED;
  }
}

/**
  Returns a file's current position.

  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file
                          handle to get the current position on.
  @param  Position        The address to return the file's current position value.

  @retval EFI_SUCCESS      The position was returned.
  @retval EFI_UNSUPPORTED  The request is not valid on open directories.
  @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemGetPosition (
  IN     EFI_FILE_PROTOCOL    *This,
     OUT UINT64               *Position
  )
{
  FV_FILESYSTEM_INSTANCE        *Instance;
  FV_FILESYSTEM_FILE            *File;

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  if (File->FvFileInfo == Instance->Root->FvFileInfo) {
    return EFI_UNSUPPORTED;
  } else {
    *Position = File->Position;
    return EFI_SUCCESS;
  }
}

/**
  Sets a file's current position.

  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the
                          file handle to set the requested position on.
  @param  Position        The byte position from the start of the file to set.

  @retval EFI_SUCCESS      The position was set.
  @retval EFI_UNSUPPORTED  The seek request for nonzero is not valid on open
                           directories.
  @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemSetPosition (
  IN EFI_FILE_PROTOCOL        *This,
  IN UINT64                   Position
  )
{
  FV_FILESYSTEM_INSTANCE      *Instance;
  FV_FILESYSTEM_FILE          *File;

  File = FVFS_FILE_FROM_FILE_THIS (This);
  Instance = File->Instance;

  if (File->FvFileInfo == Instance->Root->FvFileInfo) {
    if (Position != 0) {
      return EFI_UNSUPPORTED;
    }
    //
    // Reset directory position to first entry
    //
    if (File->DirReadNext) {
      File->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
    }
  } else if (Position == 0xFFFFFFFFFFFFFFFFull) {
    File->Position = File->FvFileInfo->FileInfo.FileSize;
  } else {
    File->Position = Position;
  }

  return EFI_SUCCESS;
}

/**
  Flushes all modified data associated with a file to a device.

  @param  This A pointer to the EFI_FILE_PROTOCOL instance that is the file
               handle to flush.

  @retval EFI_SUCCESS          The data was flushed.
  @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
FvSimpleFileSystemFlush (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  return EFI_WRITE_PROTECTED;
}

/**
  Close and delete the file handle.

  @param  This                     A pointer to the EFI_FILE_PROTOCOL instance that is the
                                   handle to the file to delete.

  @retval EFI_SUCCESS              The file was closed and deleted, and the handle was closed.
  @retval EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemDelete (
  IN EFI_FILE_PROTOCOL *This
  )
{
  EFI_STATUS       Status;

  Status = FvSimpleFileSystemClose (This);
  ASSERT_EFI_ERROR (Status);

  return EFI_WARN_DELETE_FAILURE;
}

/**
  Returns information about a file.

  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file
                          handle the requested information is for.
  @param  InformationType The type identifier for the information being requested.
  @param  BufferSize      On input, the size of Buffer. On output, the amount of data
                          returned in Buffer. In both cases, the size is measured in bytes.
  @param  Buffer          A pointer to the data buffer to return. The buffer's type is
                          indicated by InformationType.

  @retval EFI_SUCCESS          The information was returned.
  @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_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
                               BufferSize has been updated with the size needed to complete
                               the request.
**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemGetInfo (
  IN     EFI_FILE_PROTOCOL    *This,
  IN     EFI_GUID             *InformationType,
  IN OUT UINTN                *BufferSize,
     OUT VOID                 *Buffer
  )
{
  FV_FILESYSTEM_FILE           *File;
  EFI_FILE_SYSTEM_INFO         *FsInfoOut;
  EFI_FILE_SYSTEM_VOLUME_LABEL *FsVolumeLabel;
  FV_FILESYSTEM_INSTANCE       *Instance;
  UINTN                        Size;
  EFI_STATUS                   Status;

  File = FVFS_FILE_FROM_FILE_THIS (This);

  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    //
    // Return filesystem info
    //
    Instance = File->Instance;

    Size = sizeof (EFI_FILE_SYSTEM_INFO) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);

    if (*BufferSize < Size) {
      *BufferSize = Size;
      return EFI_BUFFER_TOO_SMALL;
    }

    //
    // Cast output buffer for convenience
    //
    FsInfoOut = (EFI_FILE_SYSTEM_INFO *) Buffer;

    CopyMem (FsInfoOut, &mFsInfoTemplate, sizeof (EFI_FILE_SYSTEM_INFO));
    Status = StrnCpyS ( FsInfoOut->VolumeLabel,
                        (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16),
                        Instance->VolumeLabel,
                        StrLen (Instance->VolumeLabel)
                        );
    ASSERT_EFI_ERROR (Status);
    FsInfoOut->Size = Size;
    return Status;
  } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    //
    // Return file info
    //
    return FvFsGetFileInfo (File->FvFileInfo, BufferSize, (EFI_FILE_INFO *) Buffer);
  } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    //
    // Return Volume Label
    //
    Instance = File->Instance;
    Size     = sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);;
    if (*BufferSize < Size) {
      *BufferSize = Size;
      return EFI_BUFFER_TOO_SMALL;
    }

    FsVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL*) Buffer;
    Status        = StrnCpyS (FsVolumeLabel->VolumeLabel,
                              (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel)) / sizeof (CHAR16),
                              Instance->VolumeLabel,
                              StrLen (Instance->VolumeLabel)
                              );
    ASSERT_EFI_ERROR (Status);
    return Status;
  } else {
    return EFI_UNSUPPORTED;
  }
}

/**
  Sets information about a file.

  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file
                          handle the information is for.
  @param  InformationType The type identifier for the information being set.
  @param  BufferSize      The size, in bytes, of Buffer.
  @param  Buffer          A pointer to the data buffer to write. The buffer's type is
                          indicated by InformationType.

  @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  InformationType is EFI_FILE_INFO_ID and the media is
                               read-only.
  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID
                               and the media is read only.
  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID
                               and the media is read-only.
  @retval EFI_ACCESS_DENIED    An attempt is made to change the name of a file to a
                               file that is already present.
  @retval EFI_ACCESS_DENIED    An attempt is being made to change the EFI_FILE_DIRECTORY
                               Attribute.
  @retval EFI_ACCESS_DENIED    An attempt is being made to change the size of a directory.
  @retval EFI_ACCESS_DENIED    InformationType is EFI_FILE_INFO_ID and the file was opened
                               read-only and an attempt is being made to modify a field
                               other than Attribute.
  @retval EFI_VOLUME_FULL      The volume is full.
  @retval EFI_BAD_BUFFER_SIZE  BufferSize is smaller than the size of the type indicated
                               by InformationType.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemSetInfo (
  IN EFI_FILE_PROTOCOL        *This,
  IN EFI_GUID                 *InformationType,
  IN UINTN                    BufferSize,
  IN VOID                     *Buffer
  )
{
  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) ||
      CompareGuid (InformationType, &gEfiFileInfoGuid) ||
      CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    return EFI_WRITE_PROTECTED;
  }

  return EFI_UNSUPPORTED;
}

