]> git.proxmox.com Git - mirror_edk2.git/blob - FatPkg/EnhancedFatDxe/Delete.c
BaseTools: Library hashing fix and optimization for --hash feature
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / Delete.c
1 /** @file
2 Function that deletes a file.
3
4 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
8 **/
9
10 #include "Fat.h"
11
12 /**
13
14 Deletes the file & Closes the file handle.
15
16 @param FHand - Handle to the file to delete.
17
18 @retval EFI_SUCCESS - Delete the file successfully.
19 @retval EFI_WARN_DELETE_FAILURE - Fail to delete the file.
20
21 **/
22 EFI_STATUS
23 EFIAPI
24 FatDelete (
25 IN EFI_FILE_PROTOCOL *FHand
26 )
27 {
28 FAT_IFILE *IFile;
29 FAT_OFILE *OFile;
30 FAT_DIRENT *DirEnt;
31 EFI_STATUS Status;
32 UINTN Round;
33
34 IFile = IFILE_FROM_FHAND (FHand);
35 OFile = IFile->OFile;
36
37 FatWaitNonblockingTask (IFile);
38
39 //
40 // Lock the volume
41 //
42 FatAcquireLock ();
43
44 //
45 // If the file is read-only, then don't delete it
46 //
47 if (IFile->ReadOnly) {
48 Status = EFI_WRITE_PROTECTED;
49 goto Done;
50 }
51 //
52 // If the file is the root dir, then don't delete it
53 //
54 if (OFile->Parent == NULL) {
55 Status = EFI_ACCESS_DENIED;
56 goto Done;
57 }
58 //
59 // If the file has a permanant error, skip the delete
60 //
61 Status = OFile->Error;
62 if (!EFI_ERROR (Status)) {
63 //
64 // If this is a directory, make sure it's empty before
65 // allowing it to be deleted
66 //
67 if (OFile->ODir != NULL) {
68 //
69 // We do not allow to delete nonempty directory
70 //
71 FatResetODirCursor (OFile);
72 for (Round = 0; Round < 3; Round++) {
73 Status = FatGetNextDirEnt (OFile, &DirEnt);
74 if ((EFI_ERROR (Status)) ||
75 ((Round < 2) && (DirEnt == NULL || !FatIsDotDirEnt (DirEnt))) ||
76 ((Round == 2) && (DirEnt != NULL))
77 ) {
78 Status = EFI_ACCESS_DENIED;
79 goto Done;
80 }
81 }
82 }
83 //
84 // Return the file's space by setting its size to 0
85 //
86 FatTruncateOFile (OFile, 0);
87 //
88 // Free the directory entry for this file
89 //
90 Status = FatRemoveDirEnt (OFile->Parent, OFile->DirEnt);
91 if (EFI_ERROR (Status)) {
92 goto Done;
93 }
94 //
95 // Set a permanent error for this OFile in case there
96 // are still opened IFiles attached
97 //
98 OFile->Error = EFI_NOT_FOUND;
99 } else if (OFile->Error == EFI_NOT_FOUND) {
100 Status = EFI_SUCCESS;
101 }
102
103 Done:
104 //
105 // Always close the handle
106 //
107 FatIFileClose (IFile);
108 //
109 // Done
110 //
111 Status = FatCleanupVolume (OFile->Volume, NULL, Status, NULL);
112 FatReleaseLock ();
113
114 if (EFI_ERROR (Status)) {
115 Status = EFI_WARN_DELETE_FAILURE;
116 }
117
118 return Status;
119 }