Create a branch for network fixes.
[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 #define NDEBUG
12 #include "vfat.h"
13
14 /* FUNCTIONS ****************************************************************/
15
16 /*
17 * FUNCTION: Cleans up after a file has been closed.
18 */
19 static NTSTATUS
20 VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
21 {
22 PVFATFCB pFcb;
23 PFILE_OBJECT FileObject = IrpContext->FileObject;
24
25 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
26 IrpContext->DeviceExt, FileObject);
27
28 /* FIXME: handle file/directory deletion here */
29 pFcb = (PVFATFCB) FileObject->FsContext;
30 if (!pFcb)
31 return STATUS_SUCCESS;
32
33 if (pFcb->Flags & FCB_IS_VOLUME)
34 {
35 pFcb->OpenHandleCount--;
36
37 if (pFcb->OpenHandleCount != 0)
38 {
39 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
40 }
41 }
42 else
43 {
44 if(!ExAcquireResourceExclusiveLite (&pFcb->MainResource,
45 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
46 {
47 return STATUS_PENDING;
48 }
49 if(!ExAcquireResourceExclusiveLite (&pFcb->PagingIoResource,
50 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
51 {
52 ExReleaseResourceLite (&pFcb->MainResource);
53 return STATUS_PENDING;
54 }
55
56 pFcb->OpenHandleCount--;
57
58 if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
59 FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
60 {
61 /* remove all locks this process have on this file */
62 FsRtlFastUnlockAll(&pFcb->FileLock,
63 FileObject,
64 IoGetRequestorProcess(IrpContext->Irp),
65 NULL);
66 }
67
68 if (pFcb->Flags & FCB_IS_DIRTY)
69 {
70 VfatUpdateEntry (pFcb);
71 }
72
73 if (pFcb->Flags & FCB_DELETE_PENDING &&
74 pFcb->OpenHandleCount == 0)
75 {
76 PFILE_OBJECT tmpFileObject;
77 tmpFileObject = pFcb->FileObject;
78 if (tmpFileObject != NULL)
79 {
80 pFcb->FileObject = NULL;
81 CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
82 ObDereferenceObject(tmpFileObject);
83 }
84
85 #if 0
86 /* FIXME:
87 * CcPurgeCacheSection is unimplemented.
88 */
89 CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE);
90 #endif
91 }
92 /* Uninitialize file cache if. */
93 if (FileObject->SectionObjectPointer->SharedCacheMap)
94 {
95 CcUninitializeCacheMap (FileObject, &pFcb->RFCB.FileSize, NULL);
96 }
97 if (pFcb->OpenHandleCount != 0)
98 {
99 IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess);
100 }
101
102 FileObject->Flags |= FO_CLEANUP_COMPLETE;
103
104 ExReleaseResourceLite (&pFcb->PagingIoResource);
105 ExReleaseResourceLite (&pFcb->MainResource);
106 }
107
108 return STATUS_SUCCESS;
109 }
110
111 /*
112 * FUNCTION: Cleans up after a file has been closed.
113 */
114 NTSTATUS VfatCleanup(PVFAT_IRP_CONTEXT IrpContext)
115 {
116 NTSTATUS Status;
117
118 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext->DeviceObject, IrpContext->Irp);
119
120 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
121 {
122 Status = STATUS_SUCCESS;
123 goto ByeBye;
124 }
125
126 if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource,
127 (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
128 {
129 return VfatQueueRequest (IrpContext);
130 }
131
132 Status = VfatCleanupFile(IrpContext);
133
134 ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
135
136 if (Status == STATUS_PENDING)
137 {
138 return VfatQueueRequest(IrpContext);
139 }
140
141 ByeBye:
142 IrpContext->Irp->IoStatus.Status = Status;
143 IrpContext->Irp->IoStatus.Information = 0;
144
145 IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
146 VfatFreeIrpContext(IrpContext);
147 return (Status);
148 }
149
150 /* EOF */