[FASTFAT]
[reactos.git] / reactos / 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 PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt;
29 PFILE_OBJECT FileObject = IrpContext->FileObject;
30
31 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
32 IrpContext->DeviceExt, FileObject);
33
34 /* FIXME: handle file/directory deletion here */
35 pFcb = (PVFATFCB)FileObject->FsContext;
36 if (!pFcb)
37 return STATUS_SUCCESS;
38
39 if (BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME))
40 {
41 pFcb->OpenHandleCount--;
42
43 if (pFcb->OpenHandleCount != 0)
44 {
45 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
46 }
47 }
48 else
49 {
50 if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
51 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
52 {
53 return STATUS_PENDING;
54 }
55 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
56 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
57 {
58 ExReleaseResourceLite(&pFcb->MainResource);
59 return STATUS_PENDING;
60 }
61
62 pCcb = FileObject->FsContext2;
63 if (BooleanFlagOn(pCcb->Flags, CCB_DELETE_ON_CLOSE))
64 {
65 pFcb->Flags |= FCB_DELETE_PENDING;
66 }
67
68 /* Notify about the cleanup */
69 FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync,
70 &(IrpContext->DeviceExt->NotifyList),
71 FileObject->FsContext2);
72
73 pFcb->OpenHandleCount--;
74 DeviceExt->OpenHandleCount--;
75
76 if (!vfatFCBIsDirectory(pFcb) &&
77 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
78 {
79 /* remove all locks this process have on this file */
80 FsRtlFastUnlockAll(&pFcb->FileLock,
81 FileObject,
82 IoGetRequestorProcess(IrpContext->Irp),
83 NULL);
84 }
85
86 if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY))
87 {
88 VfatUpdateEntry (pFcb, vfatVolumeIsFatX(DeviceExt));
89 }
90
91 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
92 pFcb->OpenHandleCount == 0)
93 {
94 if (vfatFCBIsDirectory(pFcb) &&
95 !VfatIsDirectoryEmpty(DeviceExt, pFcb))
96 {
97 pFcb->Flags &= ~FCB_DELETE_PENDING;
98 }
99 else
100 {
101 PFILE_OBJECT tmpFileObject;
102 tmpFileObject = pFcb->FileObject;
103 if (tmpFileObject != NULL)
104 {
105 pFcb->FileObject = NULL;
106 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
107 ObDereferenceObject(tmpFileObject);
108 }
109
110 pFcb->RFCB.ValidDataLength.QuadPart = 0;
111 pFcb->RFCB.FileSize.QuadPart = 0;
112 pFcb->RFCB.AllocationSize.QuadPart = 0;
113 }
114 }
115
116 /* Uninitialize the cache (should be done even if caching was never initialized) */
117 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
118
119 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
120 pFcb->OpenHandleCount == 0)
121 {
122 VfatDelEntry(DeviceExt, pFcb, NULL);
123
124 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
125 &(DeviceExt->NotifyList),
126 (PSTRING)&pFcb->PathNameU,
127 pFcb->PathNameU.Length - pFcb->LongNameU.Length,
128 NULL,
129 NULL,
130 vfatFCBIsDirectory(pFcb) ?
131 FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
132 FILE_ACTION_REMOVED,
133 NULL);
134 }
135
136 if (pFcb->OpenHandleCount != 0)
137 {
138 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
139 }
140
141 FileObject->Flags |= FO_CLEANUP_COMPLETE;
142
143 ExReleaseResourceLite(&pFcb->PagingIoResource);
144 ExReleaseResourceLite(&pFcb->MainResource);
145 }
146
147 #ifdef ENABLE_SWAPOUT
148 if (BooleanFlagOn(DeviceExt->Flags, VCB_DISMOUNT_PENDING))
149 {
150 VfatCheckForDismount(DeviceExt, FALSE);
151 }
152 #endif
153
154 return STATUS_SUCCESS;
155 }
156
157 /*
158 * FUNCTION: Cleans up after a file has been closed.
159 */
160 NTSTATUS
161 VfatCleanup(
162 PVFAT_IRP_CONTEXT IrpContext)
163 {
164 NTSTATUS Status;
165
166 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
167
168 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
169 {
170 IrpContext->Irp->IoStatus.Information = 0;
171 return STATUS_SUCCESS;
172 }
173
174 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
175 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
176 {
177 return VfatMarkIrpContextForQueue(IrpContext);
178 }
179
180 Status = VfatCleanupFile(IrpContext);
181
182 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
183
184 if (Status == STATUS_PENDING)
185 {
186 return VfatMarkIrpContextForQueue(IrpContext);
187 }
188
189 IrpContext->Irp->IoStatus.Information = 0;
190 return Status;
191 }
192
193 /* EOF */