/** @file
*
*  Copyright (c) 2012-2014, ARM Limited. All rights reserved.
*
*  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 "BootMonFsInternal.h"

EFIAPI
EFI_STATUS
OpenBootMonFsOpenVolume (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
  OUT EFI_FILE_PROTOCOL              **Root
  )
{
  BOOTMON_FS_INSTANCE *Instance;

  Instance = BOOTMON_FS_FROM_FS_THIS (This);
  if (Instance == NULL) {
    return EFI_DEVICE_ERROR;
  }

  Instance->RootFile->Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;

  *Root = &Instance->RootFile->File;

  return EFI_SUCCESS;
}

UINT32
BootMonFsGetImageLength (
  IN BOOTMON_FS_FILE      *File
  )
{
  UINT32                   Index;
  UINT32                   FileSize;
  LIST_ENTRY              *RegionToFlushLink;
  BOOTMON_FS_FILE_REGION  *Region;

  FileSize = 0;

  // Look at all Flash areas to determine file size
  for (Index = 0; Index < HW_IMAGE_DESCRIPTION_REGION_MAX; Index++) {
    FileSize += File->HwDescription.Region[Index].Size;
  }

  // Add the regions that have not been flushed yet
  for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
       !IsNull (&File->RegionToFlushLink, RegionToFlushLink);
       RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink)
       )
  {
    Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
    if (Region->Offset + Region->Size > FileSize) {
      FileSize += Region->Offset + Region->Size;
    }
  }

  return FileSize;
}

UINTN
BootMonFsGetPhysicalSize (
  IN BOOTMON_FS_FILE* File
  )
{
  // Return 0 for files that haven't yet been flushed to media
  if (File->HwDescription.RegionCount == 0) {
    return 0;
  }

  return ((File->HwDescription.BlockEnd - File->HwDescription.BlockStart) + 1 )
          * File->Instance->Media->BlockSize;
}

EFIAPI
EFI_STATUS
BootMonFsSetDirPosition (
  IN EFI_FILE_PROTOCOL  *This,
  IN UINT64             Position
  )
{
  BOOTMON_FS_FILE       *File;

  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  // UEFI Spec section 12.5:
  // "The seek request for nonzero is not valid on open directories."
  if (Position != 0) {
    return EFI_UNSUPPORTED;
  }
  File->Position = Position;

  return EFI_SUCCESS;
}

EFI_STATUS
BootMonFsOpenDirectory (
  OUT EFI_FILE_PROTOCOL **NewHandle,
  IN CHAR16             *FileName,
  IN BOOTMON_FS_INSTANCE *Volume
  )
{
  ASSERT(0);

  return EFI_UNSUPPORTED;
}

STATIC
EFI_STATUS
GetFileSystemVolumeLabelInfo (
  IN BOOTMON_FS_INSTANCE *Instance,
  IN OUT UINTN          *BufferSize,
  OUT VOID              *Buffer
  )
{
  UINTN                         Size;
  EFI_FILE_SYSTEM_VOLUME_LABEL *Label;
  EFI_STATUS                    Status;

  Label = Buffer;

  // Value returned by StrSize includes null terminator.
  Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
         + StrSize (Instance->FsInfo.VolumeLabel);

  if (*BufferSize >= Size) {
    CopyMem (&Label->VolumeLabel, &Instance->FsInfo.VolumeLabel, Size);
    Status = EFI_SUCCESS;
  } else {
    Status = EFI_BUFFER_TOO_SMALL;
  }
  *BufferSize = Size;
  return Status;
}

// Helper function that calculates a rough "free space" by:
// - Taking the media size
// - Subtracting the sum of all file sizes
// - Subtracting the block size times the number of files
//    (To account for the blocks containing the HW_IMAGE_INFO
STATIC
UINT64
ComputeFreeSpace (
  IN BOOTMON_FS_INSTANCE *Instance
  )
{
  LIST_ENTRY   *FileLink;
  UINT64        FileSizeSum;
  UINT64        MediaSize;
  UINTN         NumFiles;
  EFI_BLOCK_IO_MEDIA *Media;
  BOOTMON_FS_FILE *File;

  Media = Instance->BlockIo->Media;
  MediaSize = Media->BlockSize * (Media->LastBlock + 1);

  NumFiles = 0;
  FileSizeSum = 0;
  for (FileLink = GetFirstNode (&Instance->RootFile->Link);
         !IsNull (&Instance->RootFile->Link, FileLink);
         FileLink = GetNextNode (&Instance->RootFile->Link, FileLink)
         )
  {
    File = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);
    FileSizeSum += BootMonFsGetImageLength (File);

    NumFiles++;
  }

  return MediaSize - (FileSizeSum + (Media->BlockSize + NumFiles));
}

STATIC
EFI_STATUS
GetFilesystemInfo (
  IN BOOTMON_FS_INSTANCE *Instance,
  IN OUT UINTN          *BufferSize,
  OUT VOID              *Buffer
  )
{
  EFI_STATUS              Status;

  if (*BufferSize >= Instance->FsInfo.Size) {
    Instance->FsInfo.FreeSpace = ComputeFreeSpace (Instance);
    CopyMem (Buffer, &Instance->FsInfo, Instance->FsInfo.Size);
    Status = EFI_SUCCESS;
  } else {
    Status = EFI_BUFFER_TOO_SMALL;
  }

  *BufferSize = Instance->FsInfo.Size;
  return Status;
}

STATIC
EFI_STATUS
GetFileInfo (
  IN BOOTMON_FS_INSTANCE  *Instance,
  IN BOOTMON_FS_FILE      *File,
  IN OUT UINTN            *BufferSize,
  OUT VOID                *Buffer
  )
{
  EFI_FILE_INFO  *Info;
  UINTN          ResultSize;

  ResultSize = SIZE_OF_EFI_FILE_INFO + StrSize (File->Info->FileName);

  if (*BufferSize < ResultSize) {
    *BufferSize = ResultSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  Info = Buffer;

  CopyMem (Info, File->Info, ResultSize);
  // Size of the information
  Info->Size = ResultSize;

  *BufferSize = ResultSize;

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
GetBootMonFsFileInfo (
  IN BOOTMON_FS_INSTANCE *Instance,
  IN BOOTMON_FS_FILE     *File,
  IN OUT UINTN           *BufferSize,
  OUT VOID               *Buffer
  )
{
  EFI_STATUS             Status;
  BOOTMON_FS_FILE_INFO   *Info;
  UINTN                  ResultSize;
  UINTN                  Index;

  if (File == Instance->RootFile) {
    Status = EFI_UNSUPPORTED;
  } else {
    ResultSize = SIZE_OF_BOOTMON_FS_FILE_INFO;

    if (*BufferSize < ResultSize) {
      *BufferSize = ResultSize;
      Status = EFI_BUFFER_TOO_SMALL;
    } else {
      Info = Buffer;

      // Zero out the structure
      ZeroMem (Info, ResultSize);

      // Fill in the structure
      Info->Size = ResultSize;

      Info->EntryPoint  = File->HwDescription.EntryPoint;
      Info->RegionCount = File->HwDescription.RegionCount;
      for (Index = 0; Index < File->HwDescription.RegionCount; Index++) {
        Info->Region[Index].LoadAddress = File->HwDescription.Region[Index].LoadAddress;
        Info->Region[Index].Size        = File->HwDescription.Region[Index].Size;
        Info->Region[Index].Offset      = File->HwDescription.Region[Index].Offset;
        Info->Region[Index].Checksum    = File->HwDescription.Region[Index].Checksum;
      }
      *BufferSize = ResultSize;
      Status = EFI_SUCCESS;
    }
  }

  return Status;
}

/**
  Set the name of a file.

  This is a helper function for SetFileInfo().

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  FileName  A pointer to the new name of the file.

  @retval  EFI_SUCCESS        The name was set.
  @retval  EFI_ACCESS_DENIED  An attempt is made to change the name of a file
                              to a file that is already present.

**/
STATIC
EFI_STATUS
SetFileName (
  IN  BOOTMON_FS_INSTANCE  *Instance,
  IN  BOOTMON_FS_FILE      *File,
  IN  CONST CHAR16         *FileName
  )
{
  CHAR8            AsciiFileName[MAX_NAME_LENGTH];
  BOOTMON_FS_FILE  *SameFile;

  // If the file path start with a \ strip it. The EFI Shell may
  // insert a \ in front of the file name.
  if (FileName[0] == L'\\') {
    FileName++;
  }

  UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH);

  if (BootMonGetFileFromAsciiFileName (
        File->Instance,
        AsciiFileName,
        &SameFile
        ) != EFI_NOT_FOUND) {
    // A file with that name already exists.
    return EFI_ACCESS_DENIED;
  } else {
    // OK, change the filename.
    AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName,
      (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16));
    return EFI_SUCCESS;
  }
}

/**
  Set the size of a file.

  This is a helper function for SetFileInfo().

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  NewSize   The requested new size for the file.

  @retval  EFI_SUCCESS           The size was set.
  @retval  EFI_OUT_OF_RESOURCES  An allocation needed to process the request failed.

**/
STATIC
EFI_STATUS
SetFileSize (
  IN BOOTMON_FS_INSTANCE  *Instance,
  IN BOOTMON_FS_FILE      *BootMonFsFile,
  IN UINTN                 NewSize
  )
{
  EFI_STATUS              Status;
  UINT32                  OldSize;
  LIST_ENTRY              *RegionToFlushLink;
  LIST_ENTRY              *NextRegionToFlushLink;
  BOOTMON_FS_FILE_REGION  *Region;
  EFI_FILE_PROTOCOL       *File;
  CHAR8                   *Buffer;
  UINTN                   BufferSize;
  UINT64                  StoredPosition;

  OldSize = BootMonFsFile->Info->FileSize;

  //
  // In case of file truncation, force the regions waiting for writing to
  // not overflow the new size of the file.
  //
  if (NewSize < OldSize) {
    for (RegionToFlushLink = GetFirstNode (&BootMonFsFile->RegionToFlushLink);
         !IsNull (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);
         )
    {
      NextRegionToFlushLink = GetNextNode (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);
      Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
      if (Region->Offset > NewSize) {
        RemoveEntryList (RegionToFlushLink);
        FreePool (Region->Buffer);
        FreePool (Region);
      } else {
        Region->Size = MIN (Region->Size, NewSize - Region->Offset);
      }
      RegionToFlushLink = NextRegionToFlushLink;
    }

  } else if (NewSize > OldSize) {
    // Increasing a file's size is potentially complicated as it may require
    // moving the image description on media. The simplest way to do it is to
    // seek past the end of the file (which is valid in UEFI) and perform a
    // Write.
    File = &BootMonFsFile->File;

    // Save position
    Status = File->GetPosition (File, &StoredPosition);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    // Set position at the end of the file
    Status = File->SetPosition (File, OldSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    BufferSize = NewSize - OldSize;
    Buffer = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = File->Write (File, &BufferSize, Buffer);
    FreePool (Buffer);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    // Restore saved position
    Status = File->SetPosition (File, StoredPosition);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  BootMonFsFile->Info->FileSize = NewSize;

  return EFI_SUCCESS;
}

/**
  Set information about a file.

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  Info      A pointer to the file information to write.

  @retval  EFI_SUCCESS           The information was set.
  @retval  EFI_ACCESS_DENIED     An attempt is being made to change the
                                 EFI_FILE_DIRECTORY Attribute.
  @retval  EFI_ACCESS_DENIED     The file was opened in read-only mode and an
                                 attempt is being made to modify a field other
                                 than Attribute.
  @retval  EFI_ACCESS_DENIED     An attempt is made to change the name of a file
                                 to a file that is already present.
  @retval  EFI_WRITE_PROTECTED   An attempt is being made to modify a read-only
                                 attribute.
  @retval  EFI_OUT_OF_RESOURCES  An allocation needed to process the request
                                 failed.

**/
STATIC
EFI_STATUS
SetFileInfo (
  IN BOOTMON_FS_INSTANCE  *Instance,
  IN BOOTMON_FS_FILE      *File,
  IN EFI_FILE_INFO        *Info
  )
{
  EFI_STATUS  Status;
  BOOLEAN     FileSizeIsDifferent;
  BOOLEAN     FileNameIsDifferent;
  BOOLEAN     TimeIsDifferent;

  //
  // A directory can not be changed to a file and a file can
  // not be changed to a directory.
  //
  if ((Info->Attribute & EFI_FILE_DIRECTORY)      !=
      (File->Info->Attribute & EFI_FILE_DIRECTORY)  ) {
    return EFI_ACCESS_DENIED;
  }

  FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize);
  FileNameIsDifferent = (StrnCmp (
                           Info->FileName,
                           File->Info->FileName,
                           MAX_NAME_LENGTH - 1
                           ) != 0);
  //
  // Check if the CreateTime, LastAccess or ModificationTime
  // have been changed. The file system does not support file
  // timestamps thus the three times in "File->Info" are
  // always equal to zero. The following comparison actually
  // checks if all three times are still equal to 0 or not.
  //
  TimeIsDifferent = CompareMem (
                      &Info->CreateTime,
                      &File->Info->CreateTime,
                      3 * sizeof (EFI_TIME)
                      ) != 0;

  //
  // For a file opened in read-only mode, only the Attribute field can be
  // modified. The root directory open mode is forced to read-only at opening
  // thus the following test protects the root directory to be somehow modified.
  //
  if (File->OpenMode == EFI_FILE_MODE_READ) {
    if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) {
      return EFI_ACCESS_DENIED;
    }
  }

  if (TimeIsDifferent) {
    return EFI_WRITE_PROTECTED;
  }

  if (FileSizeIsDifferent) {
    Status = SetFileSize (Instance, File, Info->FileSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Note down in RAM the Attribute field but we can not
  // ask to store it in flash for the time being.
  //
  File->Info->Attribute = Info->Attribute;

  if (FileNameIsDifferent) {
    Status = SetFileName (Instance, File, Info->FileName);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

EFIAPI
EFI_STATUS
BootMonFsGetInfo (
  IN EFI_FILE_PROTOCOL  *This,
  IN EFI_GUID           *InformationType,
  IN OUT UINTN          *BufferSize,
  OUT VOID              *Buffer
  )
{
  EFI_STATUS           Status;
  BOOTMON_FS_FILE     *File;
  BOOTMON_FS_INSTANCE *Instance;

  if ((This == NULL)                         ||
      (InformationType == NULL)              ||
      (BufferSize == NULL)                   ||
      ((Buffer == NULL) && (*BufferSize > 0))  ) {
    return EFI_INVALID_PARAMETER;
  }

  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (File->Info == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  Instance = File->Instance;

  // If the instance has not been initialized yet then do it ...
  if (!Instance->Initialized) {
    Status = BootMonFsInitialize (Instance);
  } else {
    Status = EFI_SUCCESS;
  }

  if (!EFI_ERROR (Status)) {
    if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)
        != 0) {
      Status = GetFileSystemVolumeLabelInfo (Instance, BufferSize, Buffer);
    } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
      Status = GetFilesystemInfo (Instance, BufferSize, Buffer);
    } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
      Status = GetFileInfo (Instance, File, BufferSize, Buffer);
    } else if (CompareGuid (InformationType, &gArmBootMonFsFileInfoGuid) != 0) {
      Status = GetBootMonFsFileInfo (Instance, File, BufferSize, Buffer);
    } else {
      Status = EFI_UNSUPPORTED;
    }
  }

  return Status;
}

/**
  Set information about a file or a volume.

  @param[in]  This             A pointer to the EFI_FILE_PROTOCOL instance that
                               is the file handle the information is for.
  @param[in]  InformationType  The type identifier for the information being set :
                               EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
                               EFI_FILE_SYSTEM_VOLUME_LABEL_ID
  @param[in]  BufferSize       The size, in bytes, of Buffer.
  @param[in]  Buffer           A pointer to the data buffer to write. The type of the
                               data inside the buffer is indicated by InformationType.

  @retval  EFI_SUCCESS            The information was set.
  @retval  EFI_UNSUPPORTED        The InformationType is not known.
  @retval  EFI_DEVICE_ERROR       The last issued semi-hosting operation failed.
  @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      InformationType is EFI_FILE_INFO_ID and
                                  the file was opened in read-only mode and an
                                  attempt is being made to modify a field other
                                  than Attribute.
  @retval  EFI_WRITE_PROTECTED    An attempt is being made to modify a read-only
                                  attribute.
  @retval  EFI_BAD_BUFFER_SIZE    The size of the buffer is lower than that indicated by
                                  the data inside the buffer.
  @retval  EFI_OUT_OF_RESOURCES   A allocation needed to process the request failed.
  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

**/
EFIAPI
EFI_STATUS
BootMonFsSetInfo (
  IN EFI_FILE_PROTOCOL  *This,
  IN EFI_GUID           *InformationType,
  IN UINTN              BufferSize,
  IN VOID               *Buffer
  )
{
  BOOTMON_FS_FILE       *File;
  EFI_FILE_INFO         *Info;
  EFI_FILE_SYSTEM_INFO  *SystemInfo;

  if ((This == NULL)            ||
      (InformationType == NULL) ||
      (Buffer == NULL)             ) {
    return EFI_INVALID_PARAMETER;
  }

  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (File->Info == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    Info = Buffer;
    if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {
      return EFI_INVALID_PARAMETER;
    }
    if (BufferSize < Info->Size) {
      return EFI_BAD_BUFFER_SIZE;
    }
    return (SetFileInfo (File->Instance, File, Info));
  }

  //
  // The only writable field in the other two information types
  // (i.e. EFI_FILE_SYSTEM_INFO and EFI_FILE_SYSTEM_VOLUME_LABEL) is the
  // filesystem volume label. This can be retrieved with GetInfo, but it is
  // hard-coded into this driver, not stored on media.
  //

  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    SystemInfo = Buffer;
    if (SystemInfo->Size <
        (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {
      return EFI_INVALID_PARAMETER;
    }
    if (BufferSize < SystemInfo->Size) {
      return EFI_BAD_BUFFER_SIZE;
    }
    return EFI_WRITE_PROTECTED;
  }

  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    return EFI_WRITE_PROTECTED;
  }

  return EFI_UNSUPPORTED;
}

EFIAPI
EFI_STATUS
BootMonFsReadDirectory (
  IN EFI_FILE_PROTOCOL    *This,
  IN OUT UINTN            *BufferSize,
  OUT VOID                *Buffer
  )
{
  BOOTMON_FS_INSTANCE *Instance;
  BOOTMON_FS_FILE     *RootFile;
  BOOTMON_FS_FILE     *File;
  EFI_FILE_INFO       *Info;
  UINTN               NameSize;
  UINTN               ResultSize;
  EFI_STATUS          Status;
  UINTN               Index;

  RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (RootFile == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = RootFile->Instance;
  Status = BootMonGetFileFromPosition (Instance, RootFile->Position, &File);
  if (EFI_ERROR (Status)) {
    // No more file
    *BufferSize = 0;
    return EFI_SUCCESS;
  }

  NameSize   = AsciiStrLen (File->HwDescription.Footer.Filename) + 1;
  ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16));
  if (*BufferSize < ResultSize) {
    *BufferSize = ResultSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  // Zero out the structure
  Info = Buffer;
  ZeroMem (Info, ResultSize);

  // Fill in the structure
  Info->Size         = ResultSize;
  Info->FileSize     = BootMonFsGetImageLength (File);
  Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
  for (Index = 0; Index < NameSize; Index++) {
    Info->FileName[Index] = File->HwDescription.Footer.Filename[Index];
  }

  *BufferSize = ResultSize;
  RootFile->Position++;

  return EFI_SUCCESS;
}

EFIAPI
EFI_STATUS
BootMonFsFlushDirectory (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  BOOTMON_FS_FILE *RootFile;
  LIST_ENTRY      *ListFiles;
  LIST_ENTRY      *Link;
  BOOTMON_FS_FILE *File;

  RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (RootFile == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ListFiles = &RootFile->Link;

  if (IsListEmpty (ListFiles)) {
    return EFI_SUCCESS;
  }

  //
  // Flush all the files that need to be flushed
  //

  // Go through all the list of files to flush them
  for (Link = GetFirstNode (ListFiles);
       !IsNull (ListFiles, Link);
       Link = GetNextNode (ListFiles, Link)
       )
  {
    File = BOOTMON_FS_FILE_FROM_LINK_THIS (Link);
    File->File.Flush (&File->File);
  }

  return EFI_SUCCESS;
}
