d19fa94703e618b595d95281bfa98da207d7db3e
[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 DeviceExt->OpenHandleCount--;
45
46 if (pFcb->OpenHandleCount != 0)
47 {
48 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
49 }
50 }
51 else
52 {
53 ExAcquireResourceExclusiveLite(&pFcb->MainResource, TRUE);
54 ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource, TRUE);
55
56 pCcb = FileObject->FsContext2;
57 if (BooleanFlagOn(pCcb->Flags, CCB_DELETE_ON_CLOSE))
58 {
59 pFcb->Flags |= FCB_DELETE_PENDING;
60 }
61
62 /* Notify about the cleanup */
63 FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync,
64 &(IrpContext->DeviceExt->NotifyList),
65 FileObject->FsContext2);
66
67 pFcb->OpenHandleCount--;
68 DeviceExt->OpenHandleCount--;
69
70 if (!vfatFCBIsDirectory(pFcb) &&
71 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
72 {
73 /* remove all locks this process have on this file */
74 FsRtlFastUnlockAll(&pFcb->FileLock,
75 FileObject,
76 IoGetRequestorProcess(IrpContext->Irp),
77 NULL);
78 }
79
80 if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY))
81 {
82 VfatUpdateEntry (DeviceExt, pFcb);
83 }
84
85 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
86 pFcb->OpenHandleCount == 0)
87 {
88 if (vfatFCBIsDirectory(pFcb) &&
89 !VfatIsDirectoryEmpty(DeviceExt, pFcb))
90 {
91 pFcb->Flags &= ~FCB_DELETE_PENDING;
92 }
93 else
94 {
95 PFILE_OBJECT tmpFileObject;
96 tmpFileObject = pFcb->FileObject;
97 if (tmpFileObject != NULL)
98 {
99 pFcb->FileObject = NULL;
100 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
101 ClearFlag(pFcb->Flags, FCB_CACHE_INITIALIZED);
102 ObDereferenceObject(tmpFileObject);
103 }
104
105 pFcb->RFCB.ValidDataLength.QuadPart = 0;
106 pFcb->RFCB.FileSize.QuadPart = 0;
107 pFcb->RFCB.AllocationSize.QuadPart = 0;
108 }
109 }
110
111 /* Uninitialize the cache (should be done even if caching was never initialized) */
112 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
113
114 if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&
115 pFcb->OpenHandleCount == 0)
116 {
117 VfatDelEntry(DeviceExt, pFcb, NULL);
118
119 vfatReportChange(DeviceExt,
120 pFcb,
121 (vfatFCBIsDirectory(pFcb) ?
122 FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
123 FILE_ACTION_REMOVED);
124 }
125
126 if (pFcb->OpenHandleCount != 0)
127 {
128 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
129 }
130
131 FileObject->Flags |= FO_CLEANUP_COMPLETE;
132 #ifdef KDBG
133 pFcb->Flags |= FCB_CLEANED_UP;
134 #endif
135
136 ExReleaseResourceLite(&pFcb->PagingIoResource);
137 ExReleaseResourceLite(&pFcb->MainResource);
138 }
139
140 #ifdef ENABLE_SWAPOUT
141 if (IsVolume && 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 ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
168 Status = VfatCleanupFile(IrpContext);
169 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
170
171 IrpContext->Irp->IoStatus.Information = 0;
172 return Status;
173 }
174
175 /* EOF */