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)
9 /* INCLUDES *****************************************************************/
16 /* FUNCTIONS ****************************************************************/
19 * FUNCTION: Cleans up after a file has been closed.
24 PVFAT_IRP_CONTEXT IrpContext
)
28 PDEVICE_EXTENSION DeviceExt
= IrpContext
->DeviceExt
;
29 PFILE_OBJECT FileObject
= IrpContext
->FileObject
;
31 DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
32 IrpContext
->DeviceExt
, FileObject
);
34 /* FIXME: handle file/directory deletion here */
35 pFcb
= (PVFATFCB
)FileObject
->FsContext
;
37 return STATUS_SUCCESS
;
39 if (BooleanFlagOn(pFcb
->Flags
, FCB_IS_VOLUME
))
41 pFcb
->OpenHandleCount
--;
43 if (pFcb
->OpenHandleCount
!= 0)
45 IoRemoveShareAccess(FileObject
, &pFcb
->FCBShareAccess
);
50 if(!ExAcquireResourceExclusiveLite(&pFcb
->MainResource
,
51 BooleanFlagOn(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
)))
53 return STATUS_PENDING
;
55 if(!ExAcquireResourceExclusiveLite(&pFcb
->PagingIoResource
,
56 BooleanFlagOn(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
)))
58 ExReleaseResourceLite(&pFcb
->MainResource
);
59 return STATUS_PENDING
;
62 pCcb
= FileObject
->FsContext2
;
63 if (BooleanFlagOn(pCcb
->Flags
, CCB_DELETE_ON_CLOSE
))
65 pFcb
->Flags
|= FCB_DELETE_PENDING
;
68 /* Notify about the cleanup */
69 FsRtlNotifyCleanup(IrpContext
->DeviceExt
->NotifySync
,
70 &(IrpContext
->DeviceExt
->NotifyList
),
71 FileObject
->FsContext2
);
73 pFcb
->OpenHandleCount
--;
74 DeviceExt
->OpenHandleCount
--;
76 if (!vfatFCBIsDirectory(pFcb
) &&
77 FsRtlAreThereCurrentFileLocks(&pFcb
->FileLock
))
79 /* remove all locks this process have on this file */
80 FsRtlFastUnlockAll(&pFcb
->FileLock
,
82 IoGetRequestorProcess(IrpContext
->Irp
),
86 if (BooleanFlagOn(pFcb
->Flags
, FCB_IS_DIRTY
))
88 VfatUpdateEntry (pFcb
, vfatVolumeIsFatX(DeviceExt
));
91 if (BooleanFlagOn(pFcb
->Flags
, FCB_DELETE_PENDING
) &&
92 pFcb
->OpenHandleCount
== 0)
94 if (vfatFCBIsDirectory(pFcb
) &&
95 !VfatIsDirectoryEmpty(DeviceExt
, pFcb
))
97 pFcb
->Flags
&= ~FCB_DELETE_PENDING
;
101 PFILE_OBJECT tmpFileObject
;
102 tmpFileObject
= pFcb
->FileObject
;
103 if (tmpFileObject
!= NULL
)
105 pFcb
->FileObject
= NULL
;
106 CcUninitializeCacheMap(tmpFileObject
, NULL
, NULL
);
107 ObDereferenceObject(tmpFileObject
);
110 pFcb
->RFCB
.ValidDataLength
.QuadPart
= 0;
111 pFcb
->RFCB
.FileSize
.QuadPart
= 0;
112 pFcb
->RFCB
.AllocationSize
.QuadPart
= 0;
116 /* Uninitialize the cache (should be done even if caching was never initialized) */
117 CcUninitializeCacheMap(FileObject
, &pFcb
->RFCB
.FileSize
, NULL
);
119 if (BooleanFlagOn(pFcb
->Flags
, FCB_DELETE_PENDING
) &&
120 pFcb
->OpenHandleCount
== 0)
122 VfatDelEntry(DeviceExt
, pFcb
, NULL
);
124 FsRtlNotifyFullReportChange(DeviceExt
->NotifySync
,
125 &(DeviceExt
->NotifyList
),
126 (PSTRING
)&pFcb
->PathNameU
,
127 pFcb
->PathNameU
.Length
- pFcb
->LongNameU
.Length
,
130 vfatFCBIsDirectory(pFcb
) ?
131 FILE_NOTIFY_CHANGE_DIR_NAME
: FILE_NOTIFY_CHANGE_FILE_NAME
,
136 if (pFcb
->OpenHandleCount
!= 0)
138 IoRemoveShareAccess(FileObject
, &pFcb
->FCBShareAccess
);
141 FileObject
->Flags
|= FO_CLEANUP_COMPLETE
;
143 ExReleaseResourceLite(&pFcb
->PagingIoResource
);
144 ExReleaseResourceLite(&pFcb
->MainResource
);
147 #ifdef ENABLE_SWAPOUT
148 if (BooleanFlagOn(DeviceExt
->Flags
, VCB_DISMOUNT_PENDING
))
150 VfatCheckForDismount(DeviceExt
, FALSE
);
154 return STATUS_SUCCESS
;
158 * FUNCTION: Cleans up after a file has been closed.
162 PVFAT_IRP_CONTEXT IrpContext
)
166 DPRINT("VfatCleanup(DeviceObject %p, Irp %p)\n", IrpContext
->DeviceObject
, IrpContext
->Irp
);
168 if (IrpContext
->DeviceObject
== VfatGlobalData
->DeviceObject
)
170 IrpContext
->Irp
->IoStatus
.Information
= 0;
171 return STATUS_SUCCESS
;
174 if (!ExAcquireResourceExclusiveLite(&IrpContext
->DeviceExt
->DirResource
,
175 BooleanFlagOn(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
)))
177 return VfatMarkIrpContextForQueue(IrpContext
);
180 Status
= VfatCleanupFile(IrpContext
);
182 ExReleaseResourceLite(&IrpContext
->DeviceExt
->DirResource
);
184 if (Status
== STATUS_PENDING
)
186 return VfatMarkIrpContextForQueue(IrpContext
);
189 IrpContext
->Irp
->IoStatus
.Information
= 0;