2 * FFS File System Driver for Windows
8 * Lee Jae-Hong, http://www.pyrasis.com
19 extern PFFS_GLOBAL FFSGlobal
;
25 #pragma alloc_text(PAGE, FFSFlushFile)
26 #pragma alloc_text(PAGE, FFSFlushFiles)
27 #pragma alloc_text(PAGE, FFSFlushVolume)
28 #pragma alloc_text(PAGE, FFSFlush)
32 IO_COMPLETION_ROUTINE FFSFlushCompletionRoutine
;
36 FFSFlushCompletionRoutine(
37 IN PDEVICE_OBJECT DeviceObject
,
42 if (Irp
->PendingReturned
)
43 IoMarkIrpPending(Irp
);
46 if (Irp
->IoStatus
.Status
== STATUS_INVALID_DEVICE_REQUEST
)
47 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
49 return STATUS_SUCCESS
;
52 __drv_mustHoldCriticalRegion
58 IO_STATUS_BLOCK IoStatus
;
61 PLIST_ENTRY ListEntry
;
65 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
66 IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
))
68 return STATUS_SUCCESS
;
71 FFSPrint((DBG_INFO
, "Flushing Files ...\n"));
73 // Flush all Fcbs in Vcb list queue.
75 for (ListEntry
= Vcb
->FcbList
.Flink
;
76 ListEntry
!= &Vcb
->FcbList
;
77 ListEntry
= ListEntry
->Flink
)
79 Fcb
= CONTAINING_RECORD(ListEntry
, FFS_FCB
, Next
);
81 if (ExAcquireResourceExclusiveLite(
85 IoStatus
.Status
= FFSFlushFile(Fcb
);
89 IoStatus.Status = FFSPurgeFile(Fcb, TRUE);
91 IoStatus.Status = FFSFlushFile(Fcb);
94 ExReleaseResourceForThreadLite(
96 ExGetCurrentResourceThread());
101 return IoStatus
.Status
;
105 __drv_mustHoldCriticalRegion
111 IO_STATUS_BLOCK IoStatus
;
115 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
116 IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
))
118 return STATUS_SUCCESS
;
121 FFSPrint((DBG_INFO
, "FFSFlushVolume: Flushing Vcb ...\n"));
123 ExAcquireSharedStarveExclusive(&Vcb
->PagingIoResource
, TRUE
);
124 ExReleaseResourceLite(&Vcb
->PagingIoResource
);
126 CcFlushCache(&(Vcb
->SectionObject
), NULL
, 0, &IoStatus
);
128 return IoStatus
.Status
;
136 IO_STATUS_BLOCK IoStatus
;
142 ASSERT((Fcb
->Identifier
.Type
== FFSFCB
) &&
143 (Fcb
->Identifier
.Size
== sizeof(FFS_FCB
)));
145 if (IsDirectory(Fcb
))
146 return STATUS_SUCCESS
;
148 FFSPrint((DBG_INFO
, "FFSFlushFile: Flushing File Inode=%xh %S ...\n",
149 Fcb
->FFSMcb
->Inode
, Fcb
->FFSMcb
->ShortName
.Buffer
));
152 ULONG ResShCnt, ResExCnt;
153 ResShCnt = ExIsResourceAcquiredSharedLite(&Fcb->PagingIoResource);
154 ResExCnt = ExIsResourceAcquiredExclusiveLite(&Fcb->PagingIoResource);
156 FFSPrint((DBG_INFO, "FFSFlushFile: PagingIoRes: %xh:%xh\n", ResShCnt, ResExCnt));
159 CcFlushCache(&(Fcb
->SectionObject
), NULL
, 0, &IoStatus
);
161 ClearFlag(Fcb
->Flags
, FCB_FILE_MODIFIED
);
163 return IoStatus
.Status
;
167 __drv_mustHoldCriticalRegion
170 IN PFFS_IRP_CONTEXT IrpContext
)
175 PIO_STACK_LOCATION IrpSp
;
178 PFFS_FCBVCB FcbOrVcb
= 0;
179 PFILE_OBJECT FileObject
;
181 PDEVICE_OBJECT DeviceObject
;
183 BOOLEAN MainResourceAcquired
= FALSE
;
191 ASSERT((IrpContext
->Identifier
.Type
== FFSICX
) &&
192 (IrpContext
->Identifier
.Size
== sizeof(FFS_IRP_CONTEXT
)));
194 DeviceObject
= IrpContext
->DeviceObject
;
197 // This request is not allowed on the main device object
199 if (DeviceObject
== FFSGlobal
->DeviceObject
)
201 Status
= STATUS_INVALID_DEVICE_REQUEST
;
205 Vcb
= (PFFS_VCB
)DeviceObject
->DeviceExtension
;
209 ASSERT((Vcb
->Identifier
.Type
== FFSVCB
) &&
210 (Vcb
->Identifier
.Size
== sizeof(FFS_VCB
)));
212 ASSERT(IsMounted(Vcb
));
214 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
215 IsFlagOn(Vcb
->Flags
, VCB_WRITE_PROTECTED
))
217 Status
= STATUS_SUCCESS
;
221 Irp
= IrpContext
->Irp
;
223 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
225 FileObject
= IrpContext
->FileObject
;
227 FcbOrVcb
= (PFFS_FCBVCB
)FileObject
->FsContext
;
229 ASSERT(FcbOrVcb
!= NULL
);
231 #pragma prefast( suppress: 28137, "by design" )
233 if (!ExAcquireResourceExclusiveLite(
234 &FcbOrVcb
->MainResource
,
235 IrpContext
->IsSynchronous
))
237 Status
= STATUS_PENDING
;
241 MainResourceAcquired
= TRUE
;
243 if (FcbOrVcb
->Identifier
.Type
== FFSVCB
)
245 Status
= FFSFlushFiles((PFFS_VCB
)(FcbOrVcb
), FALSE
);
247 if (NT_SUCCESS(Status
))
252 Status
= FFSFlushVolume((PFFS_VCB
)(FcbOrVcb
), FALSE
);
254 if (NT_SUCCESS(Status
) && IsFlagOn(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
))
256 ClearFlag(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
);
259 else if (FcbOrVcb
->Identifier
.Type
== FFSFCB
)
261 Status
= FFSFlushFile((PFFS_FCB
)(FcbOrVcb
));
263 if (NT_SUCCESS(Status
) && IsFlagOn(FileObject
->Flags
, FO_FILE_MODIFIED
))
265 ClearFlag(FileObject
->Flags
, FO_FILE_MODIFIED
);
272 if (MainResourceAcquired
)
274 ExReleaseResourceForThreadLite(
275 &FcbOrVcb
->MainResource
,
276 ExGetCurrentResourceThread());
279 if (!IrpContext
->ExceptionInProgress
)
281 if (!IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
))
283 // Call the disk driver to flush the physial media.
284 NTSTATUS DriverStatus
;
285 PIO_STACK_LOCATION NextIrpSp
;
287 IrpSp
= IoGetCurrentIrpStackLocation(IrpContext
->Irp
);
288 NextIrpSp
= IoGetNextIrpStackLocation(IrpContext
->Irp
);
292 IoSetCompletionRoutine(IrpContext
->Irp
,
293 FFSFlushCompletionRoutine
,
299 DriverStatus
= IoCallDriver(Vcb
->TargetDeviceObject
, IrpContext
->Irp
);
301 Status
= (DriverStatus
== STATUS_INVALID_DEVICE_REQUEST
) ?
302 Status
: DriverStatus
;
304 IrpContext
->Irp
= NULL
;
307 FFSCompleteIrpContext(IrpContext
, Status
);