]> git.proxmox.com Git - mirror_edk2.git/blob - FatPkg/EnhancedFatDxe/Delete.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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 //
53 // If the file is the root dir, then don't delete it
54 //
55 if (OFile->Parent == NULL) {
56 Status = EFI_ACCESS_DENIED;
57 goto Done;
58 }
59
60 //
61 // If the file has a permanent error, skip the delete
62 //
63 Status = OFile->Error;
64 if (!EFI_ERROR (Status)) {
65 //
66 // If this is a directory, make sure it's empty before
67 // allowing it to be deleted
68 //
69 if (OFile->ODir != NULL) {
70 //
71 // We do not allow to delete nonempty directory
72 //
73 FatResetODirCursor (OFile);
74 for (Round = 0; Round < 3; Round++) {
75 Status = FatGetNextDirEnt (OFile, &DirEnt);
76 if ((EFI_ERROR (Status)) ||
77 ((Round < 2) && ((DirEnt == NULL) || !FatIsDotDirEnt (DirEnt))) ||
78 ((Round == 2) && (DirEnt != NULL))
79 )
80 {
81 Status = EFI_ACCESS_DENIED;
82 goto Done;
83 }
84 }
85 }
86
87 //
88 // Return the file's space by setting its size to 0
89 //
90 FatTruncateOFile (OFile, 0);
91 //
92 // Free the directory entry for this file
93 //
94 Status = FatRemoveDirEnt (OFile->Parent, OFile->DirEnt);
95 if (EFI_ERROR (Status)) {
96 goto Done;
97 }
98
99 //
100 // Set a permanent error for this OFile in case there
101 // are still opened IFiles attached
102 //
103 OFile->Error = EFI_NOT_FOUND;
104 } else if (OFile->Error == EFI_NOT_FOUND) {
105 Status = EFI_SUCCESS;
106 }
107
108 Done:
109 //
110 // Always close the handle
111 //
112 FatIFileClose (IFile);
113 //
114 // Done
115 //
116 Status = FatCleanupVolume (OFile->Volume, NULL, Status, NULL);
117 FatReleaseLock ();
118
119 if (EFI_ERROR (Status)) {
120 Status = EFI_WARN_DELETE_FAILURE;
121 }
122
123 return Status;
124 }