* Sync up to trunk head (r65120).
[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 PFILE_OBJECT FileObject = IrpContext->FileObject;
28
29 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
30 IrpContext->DeviceExt, FileObject);
31
32 /* FIXME: handle file/directory deletion here */
33 pFcb = (PVFATFCB)FileObject->FsContext;
34 if (!pFcb)
35 return STATUS_SUCCESS;
36
37 if (pFcb->Flags & FCB_IS_VOLUME)
38 {
39 pFcb->OpenHandleCount--;
40
41 if (pFcb->OpenHandleCount != 0)
42 {
43 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
44 }
45 }
46 else
47 {
48 if(!ExAcquireResourceExclusiveLite(&pFcb->MainResource,
49 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
50 {
51 return STATUS_PENDING;
52 }
53 if(!ExAcquireResourceExclusiveLite(&pFcb->PagingIoResource,
54 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
55 {
56 ExReleaseResourceLite(&pFcb->MainResource);
57 return STATUS_PENDING;
58 }
59
60 /* Notify about the cleanup */
61 FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync,
62 &(IrpContext->DeviceExt->NotifyList),
63 FileObject->FsContext2);
64
65 pFcb->OpenHandleCount--;
66
67 if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
68 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
69 {
70 /* remove all locks this process have on this file */
71 FsRtlFastUnlockAll(&pFcb->FileLock,
72 FileObject,
73 IoGetRequestorProcess(IrpContext->Irp),
74 NULL);
75 }
76
77 if (pFcb->Flags & FCB_IS_DIRTY)
78 {
79 VfatUpdateEntry (pFcb);
80 }
81
82 if (pFcb->Flags & FCB_DELETE_PENDING &&
83 pFcb->OpenHandleCount == 0)
84 {
85 PFILE_OBJECT tmpFileObject;
86 tmpFileObject = pFcb->FileObject;
87 if (tmpFileObject != NULL)
88 {
89 pFcb->FileObject = NULL;
90 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
91 ObDereferenceObject(tmpFileObject);
92 }
93
94 CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
95 }
96
97 /* Uninitialize the cache (should be done even if caching was never initialized) */
98 CcUninitializeCacheMap(FileObject, &pFcb->RFCB.FileSize, NULL);
99
100 if (pFcb->OpenHandleCount != 0)
101 {
102 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
103 }
104
105 FileObject->Flags |= FO_CLEANUP_COMPLETE;
106
107 ExReleaseResourceLite(&pFcb->PagingIoResource);
108 ExReleaseResourceLite(&pFcb->MainResource);
109 }
110
111 return STATUS_SUCCESS;
112 }
113
114 /*
115 * FUNCTION: Cleans up after a file has been closed.
116 */
117 NTSTATUS
118 VfatCleanup(
119 PVFAT_IRP_CONTEXT IrpContext)
120 {
121 NTSTATUS Status;
122
123 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
124
125 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
126 {
127 Status = STATUS_SUCCESS;
128 goto ByeBye;
129 }
130
131 if (!ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource,
132 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
133 {
134 return VfatQueueRequest(IrpContext);
135 }
136
137 Status = VfatCleanupFile(IrpContext);
138
139 ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
140
141 if (Status == STATUS_PENDING)
142 {
143 return VfatQueueRequest(IrpContext);
144 }
145
146 ByeBye:
147 IrpContext->Irp->IoStatus.Status = Status;
148 IrpContext->Irp->IoStatus.Information = 0;
149
150 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
151 VfatFreeIrpContext(IrpContext);
152 return Status;
153 }
154
155 /* EOF */