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