/** @file
*
*  Copyright (c) 2012-2015, 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"

// Clear a file's image description on storage media:
// UEFI allows you to seek past the end of a file, a subsequent write will grow
// the file. It does not specify how space between the former end of the file
// and the beginning of the write should be filled. It's therefore possible that
// BootMonFs metadata, that comes after the end of a file, could be left there
// and wrongly detected by BootMonFsImageInBlock.
STATIC
EFI_STATUS
InvalidateImageDescription (
  IN  BOOTMON_FS_FILE  *File
  )
{
  EFI_DISK_IO_PROTOCOL   *DiskIo;
  EFI_BLOCK_IO_PROTOCOL  *BlockIo;
  UINT32                  MediaId;
  VOID                   *Buffer;
  EFI_STATUS              Status;

  DiskIo = File->Instance->DiskIo;
  BlockIo = File->Instance->BlockIo;
  MediaId = BlockIo->Media->MediaId;

  Buffer = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION));

  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = DiskIo->WriteDisk (DiskIo,
                    MediaId,
                    File->HwDescAddress,
                    sizeof (HW_IMAGE_DESCRIPTION),
                    Buffer
                    );

  FreePool(Buffer);

  return Status;
}

/**
  Write the description of a file to storage media.

  This function uses DiskIo to write to the media, so call BlockIo->FlushBlocks()
  after calling it to ensure the data are written on the media.

  @param[in]  File       Description of the file whose description on the
                         storage media has to be updated.
  @param[in]  FileName   Name of the file. Its length is assumed to be
                         lower than MAX_NAME_LENGTH.
  @param[in]  DataSize   Number of data bytes of the file.
  @param[in]  FileStart  File's starting position on media. FileStart must
                         be aligned to the media's block size.

  @retval  EFI_WRITE_PROTECTED  The device cannot be written to.
  @retval  EFI_DEVICE_ERROR     The device reported an error while performing
                                the write operation.

**/
STATIC
EFI_STATUS
WriteFileDescription (
  IN  BOOTMON_FS_FILE  *File,
  IN  CHAR8            *FileName,
  IN  UINT32            DataSize,
  IN  UINT64            FileStart
  )
{
  EFI_STATUS            Status;
  EFI_DISK_IO_PROTOCOL  *DiskIo;
  UINTN                 BlockSize;
  UINT32                FileSize;
  HW_IMAGE_DESCRIPTION  *Description;

  DiskIo    = File->Instance->DiskIo;
  BlockSize = File->Instance->BlockIo->Media->BlockSize;
  ASSERT (FileStart % BlockSize == 0);

  //
  // Construct the file description
  //

  FileSize = DataSize + sizeof (HW_IMAGE_DESCRIPTION);
  Description = &File->HwDescription;
  Description->Attributes = 1;
  Description->BlockStart = FileStart / BlockSize;
  Description->BlockEnd   = Description->BlockStart + (FileSize / BlockSize);
  AsciiStrCpyS (Description->Footer.Filename,
    sizeof Description->Footer.Filename, FileName);

#ifdef MDE_CPU_ARM
  Description->Footer.Offset  = HW_IMAGE_FOOTER_OFFSET;
  Description->Footer.Version = HW_IMAGE_FOOTER_VERSION;
#else
  Description->Footer.Offset  = HW_IMAGE_FOOTER_OFFSET2;
  Description->Footer.Version = HW_IMAGE_FOOTER_VERSION2;
#endif
  Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1;
  Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2;
  Description->RegionCount = 1;
  Description->Region[0].Checksum = 0;
  Description->Region[0].Offset = Description->BlockStart * BlockSize;
  Description->Region[0].Size = DataSize;

  Status = BootMonFsComputeFooterChecksum (Description);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  File->HwDescAddress = ((Description->BlockEnd + 1) * BlockSize) - sizeof (HW_IMAGE_DESCRIPTION);

  // Update the file description on the media
  Status = DiskIo->WriteDisk (
                    DiskIo,
                    File->Instance->Media->MediaId,
                    File->HwDescAddress,
                    sizeof (HW_IMAGE_DESCRIPTION),
                    Description
                    );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

// Find a space on media for a file that has not yet been flushed to disk.
// Just returns the first space that's big enough.
// This function could easily be adapted to:
// - Find space for moving an existing file that has outgrown its space
//   (We do not currently move files, just return EFI_VOLUME_FULL)
// - Find space for a fragment of a file that has outgrown its space
//   (We do not currently fragment files - it's not clear whether fragmentation
//    is actually part of BootMonFs as there is no spec)
// - Be more clever about finding space (choosing the largest or smallest
//   suitable space)
// Parameters:
// File - the new (not yet flushed) file for which we need to find space.
// FileStart - the position on media of the file (in bytes).
STATIC
EFI_STATUS
BootMonFsFindSpaceForNewFile (
  IN  BOOTMON_FS_FILE     *File,
  IN  UINT64              FileSize,
  OUT UINT64              *FileStart
  )
{
  LIST_ENTRY              *FileLink;
  BOOTMON_FS_FILE         *RootFile;
  BOOTMON_FS_FILE         *FileEntry;
  UINTN                    BlockSize;
  EFI_BLOCK_IO_MEDIA      *Media;

  Media = File->Instance->BlockIo->Media;
  BlockSize = Media->BlockSize;
  RootFile = File->Instance->RootFile;

  // This function must only be called for file which has not been flushed into
  // Flash yet
  ASSERT (File->HwDescription.RegionCount == 0);

  *FileStart = 0;
  // Go through all the files in the list
  for (FileLink = GetFirstNode (&RootFile->Link);
         !IsNull (&RootFile->Link, FileLink);
         FileLink = GetNextNode (&RootFile->Link, FileLink)
         )
  {
    FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);
    // Skip files that aren't on disk yet
    if (FileEntry->HwDescription.RegionCount == 0) {
      continue;
    }

    // If the free space preceding the file is big enough to contain the new
    // file then use it!
    if (((FileEntry->HwDescription.BlockStart * BlockSize) - *FileStart)
        >= FileSize) {
      // The file list must be in disk-order
      RemoveEntryList (&File->Link);
      File->Link.BackLink = FileLink->BackLink;
      File->Link.ForwardLink = FileLink;
      FileLink->BackLink->ForwardLink = &File->Link;
      FileLink->BackLink = &File->Link;

      return EFI_SUCCESS;
    } else {
      *FileStart = (FileEntry->HwDescription.BlockEnd + 1) * BlockSize;
    }
  }
  // See if there's space after the last file
  if ((((Media->LastBlock + 1) * BlockSize) - *FileStart) >= FileSize) {
    return EFI_SUCCESS;
  } else {
    return EFI_VOLUME_FULL;
  }
}

// Free the resources in the file's Region list.
STATIC
VOID
FreeFileRegions (
  IN  BOOTMON_FS_FILE *File
  )
{
  LIST_ENTRY              *RegionToFlushLink;
  BOOTMON_FS_FILE_REGION  *Region;

  RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
  while (!IsNull (&File->RegionToFlushLink, RegionToFlushLink)) {
    // Repeatedly remove the first node from the list and free its resources.
    Region = (BOOTMON_FS_FILE_REGION *) RegionToFlushLink;
    RemoveEntryList (RegionToFlushLink);
    FreePool (Region->Buffer);
    FreePool (Region);

    RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
  }
}

/**
  Flush all modified data associated with a file to a device.

  @param[in]  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_ACCESS_DENIED      The file was opened read-only.
  @retval  EFI_DEVICE_ERROR       The device reported an error.
  @retval  EFI_VOLUME_FULL        The volume is full.
  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to flush the data.
  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

**/
EFIAPI
EFI_STATUS
BootMonFsFlushFile (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  EFI_STATUS               Status;
  BOOTMON_FS_INSTANCE     *Instance;
  EFI_FILE_INFO           *Info;
  EFI_BLOCK_IO_PROTOCOL   *BlockIo;
  EFI_BLOCK_IO_MEDIA      *Media;
  EFI_DISK_IO_PROTOCOL    *DiskIo;
  UINTN                    BlockSize;
  CHAR8                    AsciiFileName[MAX_NAME_LENGTH];
  LIST_ENTRY              *RegionToFlushLink;
  BOOTMON_FS_FILE         *File;
  BOOTMON_FS_FILE         *NextFile;
  BOOTMON_FS_FILE_REGION  *Region;
  LIST_ENTRY              *FileLink;
  UINTN                    CurrentPhysicalSize;
  UINT64                   FileStart;
  UINT64                   FileEnd;
  UINT64                   RegionStart;
  UINT64                   RegionEnd;
  UINT64                   NewDataSize;
  UINT64                   NewFileSize;
  UINT64                   EndOfAppendSpace;
  BOOLEAN                  HasSpace;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (File->Info == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (File->OpenMode == EFI_FILE_MODE_READ) {
    return EFI_ACCESS_DENIED;
  }

  Instance  = File->Instance;
  Info      = File->Info;
  BlockIo   = Instance->BlockIo;
  Media     = BlockIo->Media;
  DiskIo    = Instance->DiskIo;
  BlockSize = Media->BlockSize;

  UnicodeStrToAsciiStrS (Info->FileName, AsciiFileName, MAX_NAME_LENGTH);

  // If the file doesn't exist then find a space for it
  if (File->HwDescription.RegionCount == 0) {
    Status = BootMonFsFindSpaceForNewFile (
               File,
               Info->FileSize + sizeof (HW_IMAGE_DESCRIPTION),
               &FileStart
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    FileStart = File->HwDescription.BlockStart * BlockSize;
  }
  // FileEnd is the current NOR address of the end of the file's data
  FileEnd = FileStart + File->HwDescription.Region[0].Size;

  for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
       !IsNull (&File->RegionToFlushLink, RegionToFlushLink);
       RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink)
       )
  {
    Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
    if (Region->Size == 0) {
      continue;
    }

    // RegionStart and RegionEnd are the the intended NOR address of the
    // start and end of the region
    RegionStart = FileStart   + Region->Offset;
    RegionEnd   = RegionStart + Region->Size;

    if (RegionEnd < FileEnd) {
      // Handle regions representing edits to existing portions of the file
      // Write the region data straight into the file
      Status = DiskIo->WriteDisk (DiskIo,
                        Media->MediaId,
                        RegionStart,
                        Region->Size,
                        Region->Buffer
                        );
      if (EFI_ERROR (Status)) {
        return Status;
      }
    } else {
      // Handle regions representing appends to the file
      //
      // Note: Since seeking past the end of the file with SetPosition() is
      //  valid, it's possible there will be a gap between the current end of
      //  the file and the beginning of the new region. Since the UEFI spec
      //  says nothing about this case (except "a subsequent write would grow
      //  the file"), we just leave garbage in the gap.

      // Check if there is space to append the new region
      HasSpace = FALSE;
      NewDataSize = RegionEnd - FileStart;
      NewFileSize = NewDataSize + sizeof (HW_IMAGE_DESCRIPTION);
      CurrentPhysicalSize = BootMonFsGetPhysicalSize (File);
      if (NewFileSize <= CurrentPhysicalSize) {
        HasSpace = TRUE;
      } else {
        // Get the File Description for the next file
        FileLink = GetNextNode (&Instance->RootFile->Link, &File->Link);
        if (!IsNull (&Instance->RootFile->Link, FileLink)) {
          NextFile = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);

          // If there is space between the beginning of the current file and the
          // beginning of the next file then use it
          EndOfAppendSpace = NextFile->HwDescription.BlockStart * BlockSize;
        } else {
          // We are flushing the last file.
          EndOfAppendSpace = (Media->LastBlock + 1) * BlockSize;
        }
        if (EndOfAppendSpace - FileStart >= NewFileSize) {
          HasSpace = TRUE;
        }
      }

      if (HasSpace == TRUE) {
        // Invalidate the current image description of the file if any.
        if (File->HwDescAddress != 0) {
          Status = InvalidateImageDescription (File);
          if (EFI_ERROR (Status)) {
            return Status;
          }
        }

        // Write the new file data
        Status = DiskIo->WriteDisk (
                    DiskIo,
                    Media->MediaId,
                    RegionStart,
                    Region->Size,
                    Region->Buffer
                    );
        if (EFI_ERROR (Status)) {
          return Status;
        }

        Status = WriteFileDescription (File, AsciiFileName, NewDataSize, FileStart);
        if (EFI_ERROR (Status)) {
          return Status;
        }

      } else {
        // There isn't a space for the file.
        // Options here are to move the file or fragment it. However as files
        // may represent boot images at fixed positions, these options will
        // break booting if the bootloader doesn't use BootMonFs to find the
        // image.

        return EFI_VOLUME_FULL;
      }
    }
  }

  FreeFileRegions (File);
  Info->PhysicalSize = BootMonFsGetPhysicalSize (File);

  if ((AsciiStrCmp (AsciiFileName, File->HwDescription.Footer.Filename) != 0) ||
      (Info->FileSize != File->HwDescription.Region[0].Size)               ) {
    Status = WriteFileDescription (File, AsciiFileName, Info->FileSize, FileStart);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  // Flush DiskIo Buffers (see UEFI Spec 12.7 - DiskIo buffers are flushed by
  // calling FlushBlocks on the same device's BlockIo).
  BlockIo->FlushBlocks (BlockIo);

  return EFI_SUCCESS;
}

/**
  Close a specified file handle.

  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
                    handle to close.

  @retval  EFI_SUCCESS            The file was closed.
  @retval  EFI_INVALID_PARAMETER  The parameter "This" is NULL or is not an open
                                  file handle.

**/
EFIAPI
EFI_STATUS
BootMonFsCloseFile (
  IN EFI_FILE_PROTOCOL  *This
  )
{
  BOOTMON_FS_FILE  *File;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (File->Info == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  // In the case of a file and not the root directory
  if (This != &File->Instance->RootFile->File) {
    This->Flush (This);
    FreePool (File->Info);
    File->Info = NULL;
  }

  return EFI_SUCCESS;
}

/**
  Open a file on the boot monitor file system.

  The boot monitor file system does not allow for sub-directories. There is only
  one directory, the root one. On any attempt to create a directory, the function
  returns in error with the EFI_WRITE_PROTECTED error code.

  @param[in]   This        A pointer to the EFI_FILE_PROTOCOL instance that is
                           the file handle to source location.
  @param[out]  NewHandle   A pointer to the location to return the opened
                           handle for the new file.
  @param[in]   FileName    The Null-terminated string of the name of the file
                           to be opened.
  @param[in]   OpenMode    The mode to open the file : Read or Read/Write or
                           Read/Write/Create
  @param[in]   Attributes  Attributes of the file in case of a file creation

  @retval  EFI_SUCCESS            The file was open.
  @retval  EFI_NOT_FOUND          The specified file could not be found or the specified
                                  directory in which to create a file could not be found.
  @retval  EFI_DEVICE_ERROR       The device reported an error.
  @retval  EFI_WRITE_PROTECTED    Attempt to create a directory. This is not possible
                                  with the Boot Monitor file system.
  @retval  EFI_OUT_OF_RESOURCES   Not enough resources were available to open the file.
  @retval  EFI_INVALID_PARAMETER  At least one of the parameters is invalid.

**/
EFIAPI
EFI_STATUS
BootMonFsOpenFile (
  IN EFI_FILE_PROTOCOL   *This,
  OUT EFI_FILE_PROTOCOL  **NewHandle,
  IN CHAR16              *FileName,
  IN UINT64              OpenMode,
  IN UINT64              Attributes
  )
{
  EFI_STATUS           Status;
  BOOTMON_FS_FILE      *Directory;
  BOOTMON_FS_FILE      *File;
  BOOTMON_FS_INSTANCE  *Instance;
  CHAR8                *Buf;
  CHAR16               *Path;
  CHAR16               *Separator;
  CHAR8                *AsciiFileName;
  EFI_FILE_INFO        *Info;
  UINTN                AsciiFileNameSize;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (Directory->Info == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if ((FileName == NULL) || (NewHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The only valid modes are read, read/write, and read/write/create
  //
  if ( (OpenMode != EFI_FILE_MODE_READ) &&
       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
       (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = Directory->Instance;

  //
  // If the instance has not been initialized yet then do it ...
  //
  if (!Instance->Initialized) {
    Status = BootMonFsInitialize (Instance);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Copy the file path to be able to work on it. We do not want to
  // modify the input file name string "FileName".
  //
  Buf = AllocateCopyPool (StrSize (FileName), FileName);
  if (Buf == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  Path = (CHAR16*)Buf;
  AsciiFileName = NULL;
  Info = NULL;

  //
  // Handle single periods, double periods and convert forward slashes '/'
  // to backward '\' ones. Does not handle a '.' at the beginning of the
  // path for the time being.
  //
  if (PathCleanUpDirectories (Path) == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Error;
  }

  //
  // Detect if the first component of the path refers to a directory.
  // This is done to return the correct error code when trying to
  // access or create a directory other than the root directory.
  //

  //
  // Search for the '\\' sequence and if found return in error
  // with the EFI_INVALID_PARAMETER error code. ere in the path.
  //
  if (StrStr (Path, L"\\\\") != NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Error;
  }
  //
  // Get rid of the leading '\' if any.
  //
  Path += (Path[0] == L'\\');

  //
  // Look for a '\' in the file path. If one is found then
  // the first component of the path refers to a directory
  // that is not the root directory.
  //
  Separator = StrStr (Path, L"\\");
  if (Separator != NULL) {
    //
    // In the case '<dir name>\' and a creation, return
    // EFI_WRITE_PROTECTED if this is for a directory
    // creation, EFI_INVALID_PARAMETER otherwise.
    //
    if ((*(Separator + 1) == '\0') && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {
      if (Attributes & EFI_FILE_DIRECTORY) {
        Status = EFI_WRITE_PROTECTED;
      } else {
        Status = EFI_INVALID_PARAMETER;
      }
    } else {
      //
      // Attempt to open a file or a directory that is not in the
      // root directory or to open without creation a directory
      // located in the root directory, returns EFI_NOT_FOUND.
      //
      Status = EFI_NOT_FOUND;
    }
    goto Error;
  }

  //
  // BootMonFs interface requires ASCII filenames
  //
  AsciiFileNameSize = StrLen (Path) + 1;
  if (AsciiFileNameSize > MAX_NAME_LENGTH) {
    AsciiFileNameSize = MAX_NAME_LENGTH;
  }
  AsciiFileName = AllocatePool (AsciiFileNameSize);
  if (AsciiFileName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  UnicodeStrToAsciiStrS (Path, AsciiFileName, AsciiFileNameSize);

  if ((AsciiFileName[0] == '\0') ||
      (AsciiFileName[0] == '.' )    ) {
    //
    // Opening the root directory
    //

    *NewHandle = &Instance->RootFile->File;
    Instance->RootFile->Position = 0;
    Status = EFI_SUCCESS;
  } else {

    if ((OpenMode & EFI_FILE_MODE_CREATE) &&
        (Attributes & EFI_FILE_DIRECTORY)    ) {
      Status = EFI_WRITE_PROTECTED;
      goto Error;
    }

    //
    // Allocate a buffer to store the characteristics of the file while the
    // file is open. We allocate the maximum size to not have to reallocate
    // if the file name is changed.
    //
    Info = AllocateZeroPool (
             SIZE_OF_EFI_FILE_INFO + (sizeof (CHAR16) * MAX_NAME_LENGTH));
    if (Info == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    //
    // Open or create a file in the root directory.
    //

    Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File);
    if (Status == EFI_NOT_FOUND) {
      if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
        goto Error;
      }

      Status = BootMonFsCreateFile (Instance, &File);
      if (EFI_ERROR (Status)) {
        goto Error;
      }
      InsertHeadList (&Instance->RootFile->Link, &File->Link);
      Info->Attribute = Attributes;
    } else {
      //
      // File already open, not supported yet.
      //
      if (File->Info != NULL) {
        Status = EFI_UNSUPPORTED;
        goto Error;
      }
    }

    Info->FileSize     = BootMonFsGetImageLength (File);
    Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
    AsciiStrToUnicodeStrS (AsciiFileName, Info->FileName, MAX_NAME_LENGTH);

    File->Info = Info;
    Info = NULL;
    File->Position = 0;
    File->OpenMode = OpenMode;

    *NewHandle = &File->File;
  }

Error:

  FreePool (Buf);
  if (AsciiFileName != NULL) {
    FreePool (AsciiFileName);
  }
  if (Info != NULL) {
    FreePool (Info);
  }

  return Status;
}

// Delete() for the root directory's EFI_FILE_PROTOCOL instance
EFIAPI
EFI_STATUS
BootMonFsDeleteFail (
  IN EFI_FILE_PROTOCOL *This
  )
{
  This->Close(This);
  // You can't delete the root directory
  return EFI_WARN_DELETE_FAILURE;
}

/**
  Close and delete a file from the boot monitor file system.

  @param[in]  This  A pointer to the EFI_FILE_PROTOCOL instance that is the file
                    handle to delete.

  @retval  EFI_SUCCESS              The file was closed and deleted.
  @retval  EFI_INVALID_PARAMETER    The parameter "This" is NULL or is not an open
                                    file handle.
  @retval  EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.

**/
EFIAPI
EFI_STATUS
BootMonFsDelete (
  IN EFI_FILE_PROTOCOL *This
  )
{
  EFI_STATUS               Status;
  BOOTMON_FS_FILE         *File;
  LIST_ENTRY              *RegionToFlushLink;
  BOOTMON_FS_FILE_REGION  *Region;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
  if (File->Info == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsListEmpty (&File->RegionToFlushLink)) {
    // Free the entries from the Buffer List
    RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
    do {
      Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;

      //
      // Get next element of the list before deleting the region description
      // that contain the LIST_ENTRY structure.
      //
      RegionToFlushLink = RemoveEntryList (RegionToFlushLink);

      // Free the buffers
      FreePool (Region->Buffer);
      FreePool (Region);
    } while (!IsListEmpty (&File->RegionToFlushLink));
  }

  // If (RegionCount is greater than 0) then the file already exists
  if (File->HwDescription.RegionCount > 0) {
    // Invalidate the last Block
    Status = InvalidateImageDescription (File);
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      return  EFI_WARN_DELETE_FAILURE;
    }
  }

  // Remove the entry from the list
  RemoveEntryList (&File->Link);
  FreePool (File->Info);
  FreePool (File);

  return EFI_SUCCESS;
}
