2 * FFS File System Driver for Windows
8 * Lee Jae-Hong, http://www.pyrasis.com
19 extern PFFS_GLOBAL FFSGlobal
;
24 #pragma alloc_text(PAGE, FFSCleanup)
28 __drv_mustHoldCriticalRegion
31 IN PFFS_IRP_CONTEXT IrpContext
)
33 PDEVICE_OBJECT DeviceObject
;
34 NTSTATUS Status
= STATUS_SUCCESS
;
36 BOOLEAN VcbResourceAcquired
= FALSE
;
37 PFILE_OBJECT FileObject
;
39 BOOLEAN FcbResourceAcquired
= FALSE
;
40 BOOLEAN FcbPagingIoAcquired
= FALSE
;
48 ASSERT(IrpContext
!= NULL
);
50 ASSERT((IrpContext
->Identifier
.Type
== FFSICX
) &&
51 (IrpContext
->Identifier
.Size
== sizeof(FFS_IRP_CONTEXT
)));
53 DeviceObject
= IrpContext
->DeviceObject
;
55 if (DeviceObject
== FFSGlobal
->DeviceObject
)
57 Status
= STATUS_SUCCESS
;
61 Vcb
= (PFFS_VCB
)DeviceObject
->DeviceExtension
;
65 ASSERT((Vcb
->Identifier
.Type
== FFSVCB
) &&
66 (Vcb
->Identifier
.Size
== sizeof(FFS_VCB
)));
68 if (!IsFlagOn(Vcb
->Flags
, VCB_INITIALIZED
))
70 Status
= STATUS_SUCCESS
;
75 #pragma prefast( suppress: 28137, "by design" )
77 if (!ExAcquireResourceExclusiveLite(
79 IrpContext
->IsSynchronous
))
81 Status
= STATUS_PENDING
;
85 VcbResourceAcquired
= TRUE
;
87 FileObject
= IrpContext
->FileObject
;
89 Fcb
= (PFFS_FCB
)FileObject
->FsContext
;
93 Status
= STATUS_SUCCESS
;
97 if (Fcb
->Identifier
.Type
== FFSVCB
)
99 if (IsFlagOn(Vcb
->Flags
, VCB_VOLUME_LOCKED
) &&
100 (Vcb
->LockFile
== FileObject
))
102 ClearFlag(Vcb
->Flags
, VCB_VOLUME_LOCKED
);
103 Vcb
->LockFile
= NULL
;
105 FFSClearVpbFlag(Vcb
->Vpb
, VPB_LOCKED
);
108 Vcb
->OpenHandleCount
--;
110 if (!Vcb
->OpenHandleCount
)
112 IoRemoveShareAccess(FileObject
, &Vcb
->ShareAccess
);
115 Status
= STATUS_SUCCESS
;
119 ASSERT((Fcb
->Identifier
.Type
== FFSFCB
) &&
120 (Fcb
->Identifier
.Size
== sizeof(FFS_FCB
)));
123 if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) &&
124 !IsFlagOn(Fcb->Flags, FCB_PAGE_FILE))
128 #pragma prefast( suppress: 28137, "by design" )
130 if (!ExAcquireResourceExclusiveLite(
132 IrpContext
->IsSynchronous
))
134 Status
= STATUS_PENDING
;
138 FcbResourceAcquired
= TRUE
;
141 Ccb
= (PFFS_CCB
)FileObject
->FsContext2
;
145 Status
= STATUS_SUCCESS
;
149 if (IsFlagOn(FileObject
->Flags
, FO_CLEANUP_COMPLETE
))
151 if (IsFlagOn(FileObject
->Flags
, FO_FILE_MODIFIED
) &&
152 IsFlagOn(Vcb
->Flags
, VCB_FLOPPY_DISK
) &&
153 !IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
))
155 Status
= FFSFlushFile(Fcb
);
161 ASSERT((Ccb
->Identifier
.Type
== FFSCCB
) &&
162 (Ccb
->Identifier
.Size
== sizeof(FFS_CCB
)));
163 Irp
= IrpContext
->Irp
;
165 Fcb
->OpenHandleCount
--;
167 if (!IsFlagOn(FileObject
->Flags
, FO_CACHE_SUPPORTED
))
169 Fcb
->NonCachedOpenCount
--;
172 Vcb
->OpenFileHandleCount
--;
174 if (IsFlagOn(Fcb
->Flags
, FCB_DELETE_ON_CLOSE
))
176 SetFlag(Fcb
->Flags
, FCB_DELETE_PENDING
);
178 if (IsDirectory(Fcb
))
180 FsRtlNotifyFullChangeDirectory(
194 if (IsDirectory(Fcb
))
204 // Drop any byte range locks this process may have on the file.
207 &Fcb
->FileLockAnchor
,
209 IoGetRequestorProcess(Irp
),
213 // If there are no byte range locks owned by other processes on the
214 // file the fast I/O read/write functions doesn't have to check for
215 // locks so we set IsFastIoPossible to FastIoIsPossible again.
217 if (!FsRtlGetNextFileLock(&Fcb
->FileLockAnchor
, TRUE
))
219 if (Fcb
->Header
.IsFastIoPossible
!= FastIoIsPossible
)
222 DBG_INFO
, ": %-16.16s %-31s %s\n",
223 FFSGetCurrentProcessName(),
225 Fcb
->AnsiFileName
.Buffer
));
227 Fcb
->Header
.IsFastIoPossible
= FastIoIsPossible
;
232 if (IsFlagOn(FileObject
->Flags
, FO_CACHE_SUPPORTED
) &&
233 (Fcb
->NonCachedOpenCount
!= 0) &&
234 (Fcb
->NonCachedOpenCount
== Fcb
->ReferenceCount
) &&
235 (Fcb
->SectionObject
.DataSectionObject
!= NULL
))
238 if(!IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) &&
239 !IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
))
241 CcFlushCache(&Fcb
->SectionObject
, NULL
, 0, NULL
);
244 ExAcquireResourceExclusiveLite(&(Fcb
->PagingIoResource
), TRUE
);
245 ExReleaseResourceLite(&(Fcb
->PagingIoResource
));
247 CcPurgeCacheSection(&Fcb
->SectionObject
,
254 if (Fcb
->OpenHandleCount
== 0)
256 if (IsFlagOn(Fcb
->Flags
, FCB_DELETE_PENDING
))
258 BOOLEAN bDeleted
= FALSE
;
261 // Have to delete this file...
264 #pragma prefast( suppress: 28137, "by design" )
266 if (!ExAcquireResourceExclusiveLite(
267 &Fcb
->PagingIoResource
,
268 IrpContext
->IsSynchronous
))
270 Status
= STATUS_PENDING
;
274 FcbPagingIoAcquired
= TRUE
;
276 bDeleted
= FFSDeleteFile(IrpContext
, Vcb
, Fcb
);
280 if (IsDirectory(Fcb
))
282 FFSNotifyReportChange(IrpContext
, Vcb
, Fcb
,
283 FILE_NOTIFY_CHANGE_DIR_NAME
,
284 FILE_ACTION_REMOVED
);
288 FFSNotifyReportChange(IrpContext
, Vcb
, Fcb
,
289 FILE_NOTIFY_CHANGE_FILE_NAME
,
290 FILE_ACTION_REMOVED
);
294 if (FcbPagingIoAcquired
)
296 ExReleaseResourceForThreadLite(
297 &Fcb
->PagingIoResource
,
298 ExGetCurrentResourceThread());
300 FcbPagingIoAcquired
= FALSE
;
306 FFSPurgeFile(Fcb, FALSE);
311 #endif // !FFS_READ_ONLY
313 if (!IsDirectory(Fcb
) && FileObject
->PrivateCacheMap
)
315 FFSPrint((DBG_INFO
, "FFSCleanup: CcUninitializeCacheMap is called for %s.\n",
316 Fcb
->AnsiFileName
.Buffer
));
318 CcUninitializeCacheMap(
320 (PLARGE_INTEGER
)(&(Fcb
->Header
.FileSize
)),
324 if (!Fcb
->OpenHandleCount
)
326 IoRemoveShareAccess(FileObject
, &Fcb
->ShareAccess
);
329 FFSPrint((DBG_INFO
, "FFSCleanup: OpenCount: %u ReferCount: %u %s\n",
330 Fcb
->OpenHandleCount
, Fcb
->ReferenceCount
, Fcb
->AnsiFileName
.Buffer
));
332 Status
= STATUS_SUCCESS
;
336 SetFlag(FileObject
->Flags
, FO_CLEANUP_COMPLETE
);
343 if (FcbPagingIoAcquired
)
345 ExReleaseResourceForThreadLite(
346 &Fcb
->PagingIoResource
,
347 ExGetCurrentResourceThread());
350 if (FcbResourceAcquired
)
352 ExReleaseResourceForThreadLite(
354 ExGetCurrentResourceThread());
357 if (VcbResourceAcquired
)
359 ExReleaseResourceForThreadLite(
361 ExGetCurrentResourceThread());
364 if (!IrpContext
->ExceptionInProgress
)
366 if (Status
== STATUS_PENDING
)
368 FFSQueueRequest(IrpContext
);
372 IrpContext
->Irp
->IoStatus
.Status
= Status
;
374 FFSCompleteIrpContext(IrpContext
, Status
);