Merge the following revisions from kernel-fun branch:
[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 #ifdef ENABLE_SWAPOUT
114 if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
115 {
116 VfatCheckForDismount(DeviceExt, FALSE);
117 }
118 #endif
119
120 return STATUS_SUCCESS;
121 }
122
123 /*
124 * FUNCTION: Cleans up after a file has been closed.
125 */
126 NTSTATUS
127 VfatCleanup(
128 PVFAT_IRP_CONTEXT IrpContext)
129 {
130 NTSTATUS Status;
131
132 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
133
134 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
135 {
136 Status = STATUS_SUCCESS;
137 goto ByeBye;
138 }
139
140 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
141 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
142 {
143 return VfatQueueRequest(IrpContext);
144 }
145
146 Status = VfatCleanupFile(IrpContext);
147
148 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
149
150 if (Status == STATUS_PENDING)
151 {
152 return VfatQueueRequest(IrpContext);
153 }
154
155 ByeBye:
156 IrpContext->Irp->IoStatus.Status = Status;
157 IrpContext->Irp->IoStatus.Information = 0;
158
159 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
160 VfatFreeIrpContext(IrpContext);
161 return Status;
162 }
163
164 /* EOF */