Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / drivers / filesystems / fastfat / cleanup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/fs/vfat/cleanup.c
5 * PURPOSE: VFAT Filesystem
6 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include "vfat.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ****************************************************************/
17
18 /*
19 * FUNCTION: Cleans up after a file has been closed.
20 */
21 static
22 NTSTATUS
23 VfatCleanupFile(
24 PVFAT_IRP_CONTEXT IrpContext)
25 {
26 PVFATFCB pFcb;
27 PVFATCCB pCcb;
28 BOOLEAN IsVolume;
29 PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt;
30 PFILE_OBJECT FileObject = IrpContext->FileObject;
31
32 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
33 IrpContext->DeviceExt, FileObject);
34
35 /* FIXME: handle file/directory deletion here */
36 pFcb = (PVFATFCB)FileObject->FsContext;
37 if (!pFcb)
38 return STATUS_SUCCESS;
39
40 IsVolume = BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME);
41 if (IsVolume)
42 {
43 pFcb->OpenHandleCount--;
44
45 if (pFcb->OpenHandleCount != 0)
46 {
47 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
48 }
49 }
50 else
51 {
52 if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
53 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
54 {
55 return STATUS_PENDING;
56 }
57 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
58 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
59 {
60 ExReleaseResourceLite(&pFcb->MainResource);
61 return STATUS_PENDING;
62 }
63
64 pCcb = FileObject->FsContext2;
65 if (BooleanFlagOn(pCcb->Flags, CCB_DELETE_ON_CLOSE))
66 {
67 pFcb->Flags |= FCB_DELETE_PENDING;
68 }
69
70 /* Notify about the cleanup */
71 FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync,
72 &(IrpContext->DeviceExt->NotifyList),
73 FileObject->FsContext2);
74
75 pFcb->OpenHandleCount--;
76 DeviceExt->OpenHandleCount--;
77
78 if (!vfatFCBIsDirectory(pFcb) &&
79 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
80 {
81 /* remove all locks this process have on this file */
82 FsRtlFastUnlockAll(&pFcb->FileLock,
83 FileObject,
84 IoGetRequestorProcess(IrpContext->Irp),
85 NULL);
86 }
87
88 if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY))
89 {
90 VfatUpdateEntry (pFcb, vfatVolumeIsFatX(DeviceExt));
91 }
92
93 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
94 pFcb->OpenHandleCount == 0)
95 {
96 if (vfatFCBIsDirectory(pFcb) &&
97 !VfatIsDirectoryEmpty(DeviceExt, pFcb))
98 {
99 pFcb->Flags &= ~FCB_DELETE_PENDING;
100 }
101 else
102 {
103 PFILE_OBJECT tmpFileObject;
104 tmpFileObject = pFcb->FileObject;
105 if (tmpFileObject != NULL)
106 {
107 pFcb->FileObject = NULL;
108 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
109 ObDereferenceObject(tmpFileObject);
110 }
111
112 pFcb->RFCB.ValidDataLength.QuadPart = 0;
113 pFcb->RFCB.FileSize.QuadPart = 0;
114 pFcb->RFCB.AllocationSize.QuadPart = 0;
115 }
116 }
117
118 /* Uninitialize the cache (should be done even if caching was never initialized) */
119 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
120
121 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
122 pFcb->OpenHandleCount == 0)
123 {
124 VfatDelEntry(DeviceExt, pFcb, NULL);
125
126 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
127 &(DeviceExt->NotifyList),
128 (PSTRING)&pFcb->PathNameU,
129 pFcb->PathNameU.Length - pFcb->LongNameU.Length,
130 NULL,
131 NULL,
132 vfatFCBIsDirectory(pFcb) ?
133 FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
134 FILE_ACTION_REMOVED,
135 NULL);
136 }
137
138 if (pFcb->OpenHandleCount != 0)
139 {
140 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
141 }
142
143 FileObject->Flags |= FO_CLEANUP_COMPLETE;
144
145 ExReleaseResourceLite(&pFcb->PagingIoResource);
146 ExReleaseResourceLite(&pFcb->MainResource);
147 }
148
149 #ifdef ENABLE_SWAPOUT
150 if (IsVolume && BooleanFlagOn(DeviceExt->Flags, VCB_DISMOUNT_PENDING))
151 {
152 VfatCheckForDismount(DeviceExt, FALSE);
153 }
154 #endif
155
156 return STATUS_SUCCESS;
157 }
158
159 /*
160 * FUNCTION: Cleans up after a file has been closed.
161 */
162 NTSTATUS
163 VfatCleanup(
164 PVFAT_IRP_CONTEXT IrpContext)
165 {
166 NTSTATUS Status;
167
168 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
169
170 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
171 {
172 IrpContext->Irp->IoStatus.Information = 0;
173 return STATUS_SUCCESS;
174 }
175
176 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
177 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
178 {
179 return VfatMarkIrpContextForQueue(IrpContext);
180 }
181
182 Status = VfatCleanupFile(IrpContext);
183
184 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
185
186 if (Status == STATUS_PENDING)
187 {
188 return VfatMarkIrpContextForQueue(IrpContext);
189 }
190
191 IrpContext->Irp->IoStatus.Information = 0;
192 return Status;
193 }
194
195 /* EOF */