[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 (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 (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
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 (pFcb->Flags & FCB_IS_DIRTY)
80 {
81 VfatUpdateEntry (pFcb);
82 }
83
84 if (pFcb->Flags & FCB_DELETE_PENDING &&
85 pFcb->OpenHandleCount == 0)
86 {
87 PFILE_OBJECT tmpFileObject;
88 tmpFileObject = pFcb->FileObject;
89 if (tmpFileObject != NULL)
90 {
91 pFcb->FileObject = NULL;
92 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
93 ObDereferenceObject(tmpFileObject);
94 }
95
96 pFcb->RFCB.ValidDataLength.QuadPart = 0;
97 pFcb->RFCB.FileSize.QuadPart = 0;
98 pFcb->RFCB.AllocationSize.QuadPart = 0;
99 }
100
101 /* Uninitialize the cache (should be done even if caching was never initialized) */
102 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
103
104 if (pFcb->Flags & FCB_DELETE_PENDING &&
105 pFcb->OpenHandleCount == 0)
106 {
107 VfatDelEntry(DeviceExt, pFcb, NULL);
108
109 FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
110 &(DeviceExt->NotifyList),
111 (PSTRING)&pFcb->PathNameU,
112 pFcb->PathNameU.Length - pFcb->LongNameU.Length,
113 NULL,
114 NULL,
115 ((*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
116 FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
117 FILE_ACTION_REMOVED,
118 NULL);
119 }
120
121 if (pFcb->OpenHandleCount != 0)
122 {
123 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
124 }
125
126 FileObject->Flags |= FO_CLEANUP_COMPLETE;
127
128 ExReleaseResourceLite(&pFcb->PagingIoResource);
129 ExReleaseResourceLite(&pFcb->MainResource);
130 }
131
132 #ifdef ENABLE_SWAPOUT
133 if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
134 {
135 VfatCheckForDismount(DeviceExt, FALSE);
136 }
137 #endif
138
139 return STATUS_SUCCESS;
140 }
141
142 /*
143 * FUNCTION: Cleans up after a file has been closed.
144 */
145 NTSTATUS
146 VfatCleanup(
147 PVFAT_IRP_CONTEXT IrpContext)
148 {
149 NTSTATUS Status;
150
151 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
152
153 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
154 {
155 IrpContext->Irp->IoStatus.Information = 0;
156 return STATUS_SUCCESS;
157 }
158
159 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
160 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
161 {
162 return VfatMarkIrpContextForQueue(IrpContext);
163 }
164
165 Status = VfatCleanupFile(IrpContext);
166
167 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
168
169 if (Status == STATUS_PENDING)
170 {
171 return VfatMarkIrpContextForQueue(IrpContext);
172 }
173
174 IrpContext->Irp->IoStatus.Information = 0;
175 return Status;
176 }
177
178 /* EOF */