/** @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 - 2015, 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 = AllocateCopyPool (NewFileNameLength * 2, 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;
}

