/** @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, 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;

  //
  // 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 = 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
  //
  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) {
      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
    //
    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;
}

