[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 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
51 {
52 return STATUS_PENDING;
53 }
54 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
55 (BOOLEAN)(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 CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
97 }
98
99 /* Uninitialize the cache (should be done even if caching was never initialized) */
100 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
101
102 if (pFcb->OpenHandleCount != 0)
103 {
104 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
105 }
106
107 FileObject->Flags |= FO_CLEANUP_COMPLETE;
108
109 ExReleaseResourceLite(&pFcb->PagingIoResource);
110 ExReleaseResourceLite(&pFcb->MainResource);
111 }
112
113 if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
114 {
115 VfatCheckForDismount(DeviceExt, FALSE);
116 }
117
118 return STATUS_SUCCESS;
119 }
120
121 /*
122 * FUNCTION: Cleans up after a file has been closed.
123 */
124 NTSTATUS
125 VfatCleanup(
126 PVFAT_IRP_CONTEXT IrpContext)
127 {
128 NTSTATUS Status;
129
130 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
131
132 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
133 {
134 Status = STATUS_SUCCESS;
135 goto ByeBye;
136 }
137
138 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
139 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
140 {
141 return VfatQueueRequest(IrpContext);
142 }
143
144 Status = VfatCleanupFile(IrpContext);
145
146 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
147
148 if (Status == STATUS_PENDING)
149 {
150 return VfatQueueRequest(IrpContext);
151 }
152
153 ByeBye:
154 IrpContext->Irp->IoStatus.Status = Status;
155 IrpContext->Irp->IoStatus.Information = 0;
156
157 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
158 VfatFreeIrpContext(IrpContext);
159 return Status;
160 }
161
162 /* EOF */