Home | History | Annotate | Download | only in EnhancedFatDxe
      1 /** @file
      2   Function that deletes a file.
      3 
      4 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials are licensed and made available
      6 under the terms and conditions of the BSD License which accompanies this
      7 distribution. The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 
     14 **/
     15 
     16 #include "Fat.h"
     17 
     18 /**
     19 
     20   Deletes the file & Closes the file handle.
     21 
     22   @param  FHand                    - Handle to the file to delete.
     23 
     24   @retval EFI_SUCCESS              - Delete the file successfully.
     25   @retval EFI_WARN_DELETE_FAILURE  - Fail to delete the file.
     26 
     27 **/
     28 EFI_STATUS
     29 EFIAPI
     30 FatDelete (
     31   IN EFI_FILE_PROTOCOL  *FHand
     32   )
     33 {
     34   FAT_IFILE   *IFile;
     35   FAT_OFILE   *OFile;
     36   FAT_DIRENT  *DirEnt;
     37   EFI_STATUS  Status;
     38   UINTN       Round;
     39 
     40   IFile = IFILE_FROM_FHAND (FHand);
     41   OFile = IFile->OFile;
     42 
     43   FatWaitNonblockingTask (IFile);
     44 
     45   //
     46   // Lock the volume
     47   //
     48   FatAcquireLock ();
     49 
     50   //
     51   // If the file is read-only, then don't delete it
     52   //
     53   if (IFile->ReadOnly) {
     54     Status = EFI_WRITE_PROTECTED;
     55     goto Done;
     56   }
     57   //
     58   // If the file is the root dir, then don't delete it
     59   //
     60   if (OFile->Parent == NULL) {
     61     Status = EFI_ACCESS_DENIED;
     62     goto Done;
     63   }
     64   //
     65   // If the file has a permanant error, skip the delete
     66   //
     67   Status = OFile->Error;
     68   if (!EFI_ERROR (Status)) {
     69     //
     70     // If this is a directory, make sure it's empty before
     71     // allowing it to be deleted
     72     //
     73     if (OFile->ODir != NULL) {
     74       //
     75       // We do not allow to delete nonempty directory
     76       //
     77       FatResetODirCursor (OFile);
     78       for (Round = 0; Round < 3; Round++) {
     79         Status = FatGetNextDirEnt (OFile, &DirEnt);
     80         if ((EFI_ERROR (Status)) ||
     81             ((Round < 2) && (DirEnt == NULL || !FatIsDotDirEnt (DirEnt))) ||
     82             ((Round == 2) && (DirEnt != NULL))
     83             ) {
     84           Status = EFI_ACCESS_DENIED;
     85           goto Done;
     86         }
     87       }
     88     }
     89     //
     90     // Return the file's space by setting its size to 0
     91     //
     92     FatTruncateOFile (OFile, 0);
     93     //
     94     // Free the directory entry for this file
     95     //
     96     Status = FatRemoveDirEnt (OFile->Parent, OFile->DirEnt);
     97     if (EFI_ERROR (Status)) {
     98       goto Done;
     99     }
    100     //
    101     // Set a permanent error for this OFile in case there
    102     // are still opened IFiles attached
    103     //
    104     OFile->Error = EFI_NOT_FOUND;
    105   } else if (OFile->Error == EFI_NOT_FOUND) {
    106     Status = EFI_SUCCESS;
    107   }
    108 
    109 Done:
    110   //
    111   // Always close the handle
    112   //
    113   FatIFileClose (IFile);
    114   //
    115   // Done
    116   //
    117   Status = FatCleanupVolume (OFile->Volume, NULL, Status, NULL);
    118   FatReleaseLock ();
    119 
    120   if (EFI_ERROR (Status)) {
    121     Status = EFI_WARN_DELETE_FAILURE;
    122   }
    123 
    124   return Status;
    125 }
    126