ReactOS 0.4.15-dev-7958-gcd0bb1a
flush.c File Reference
#include "fatprocs.h"
Include dependency graph for flush.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_FLUSH)
 
#define Dbg   (DEBUG_TRACE_FLUSH)
 

Functions

NTSTATUS NTAPI FatFlushCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
NTSTATUS NTAPI FatHijackCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
 _Function_class_ (IRP_MJ_FLUSH_BUFFERS)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
NTSTATUS FatFlushFat (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
NTSTATUS FatHijackIrpAndFlushDevice (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT TargetDeviceObject)
 
VOID FatFlushFatEntries (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG Cluster, IN ULONG Count)
 
VOID FatFlushDirentForFile (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
 
NTSTATUS NTAPI FatFlushCompletionRoutine (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Contxt)
 

Variables

IO_COMPLETION_ROUTINE FatFlushCompletionRoutine
 
IO_COMPLETION_ROUTINE FatHijackCompletionRoutine
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_FLUSH)

Definition at line 23 of file flush.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_FLUSH)

Definition at line 29 of file flush.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( IRP_MJ_FLUSH_BUFFERS  )

Definition at line 68 of file flush.c.

96{
98 PIRP_CONTEXT IrpContext = NULL;
99
101
102 PAGED_CODE();
103
104 DebugTrace(+1, Dbg, "FatFsdFlushBuffers\n", 0);
105
106 //
107 // Call the common Cleanup routine, with blocking allowed if synchronous
108 //
109
111
113
114 _SEH2_TRY {
115
116 IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
117
118 Status = FatCommonFlushBuffers( IrpContext, Irp );
119
121
122 //
123 // We had some trouble trying to perform the requested
124 // operation, so we'll abort the I/O request with
125 // the error status that we get back from the
126 // execption code
127 //
128
129 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
130 } _SEH2_END;
131
132 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
133
135
136 //
137 // And return to our caller
138 //
139
140 DebugTrace(-1, Dbg, "FatFsdFlushBuffers -> %08lx\n", Status);
141
142 UNREFERENCED_PARAMETER( VolumeDeviceObject );
143
144 return Status;
145}
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define CanFsdWait(I)
Definition: cdprocs.h:2001
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define Dbg
Definition: flush.c:29
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 148 of file flush.c.

171{
173
175
177
179 PVCB Vcb;
180 PFCB Fcb;
181 PFCB NextFcb;
182 PCCB Ccb;
183
184 BOOLEAN VcbAcquired = FALSE;
185 BOOLEAN FcbAcquired = FALSE;
186 BOOLEAN FatFlushRequired = FALSE;
187
188 PAGED_CODE();
189
191
192 DebugTrace(+1, Dbg, "FatCommonFlushBuffers\n", 0);
193 DebugTrace( 0, Dbg, "Irp = %p\n", Irp);
194 DebugTrace( 0, Dbg, "->FileObject = %p\n", IrpSp->FileObject);
195
196 //
197 // Extract and decode the file object
198 //
199
202
203 //
204 // CcFlushCache is always synchronous, so if we can't wait enqueue
205 // the irp to the Fsp.
206 //
207
208 if ( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ) {
209
210 Status = FatFsdPostRequest( IrpContext, Irp );
211
212 DebugTrace(-1, Dbg, "FatCommonFlushBuffers -> %08lx\n", Status );
213 return Status;
214 }
215
217
218 _SEH2_TRY {
219
220#if (NTDDI_VERSION >= NTDDI_WIN8)
221
223
224 PETHREAD OriginatingThread = NULL;
225
226 //
227 // Charge the flush to the originating thread.
228 // Try the Thread in Irp's tail first, if that is NULL, then charge
229 // the flush to current thread.
230 //
231
232 if ((Irp->Tail.Overlay.Thread != NULL) &&
233 !IoIsSystemThread( Irp->Tail.Overlay.Thread )) {
234
235 OriginatingThread = Irp->Tail.Overlay.Thread;
236
237 } else {
238
239 OriginatingThread = PsGetCurrentThread();
240 }
241
242 NT_ASSERT( OriginatingThread != NULL );
243
244 PsUpdateDiskCounters( PsGetThreadProcess( OriginatingThread ),
245 0,
246 0,
247 0,
248 0,
249 1 );
250 }
251
252#endif
253
254 //
255 // Case on the type of open that we are trying to flush
256 //
257
258 switch (TypeOfOpen) {
259
261 case EaFile:
262 case DirectoryFile:
263 DebugTrace(0, Dbg, "Flush that does nothing\n", 0);
264 break;
265
266 case UserFileOpen:
267
268 DebugTrace(0, Dbg, "Flush User File Open\n", 0);
269
270 (VOID)FatAcquireExclusiveFcb( IrpContext, Fcb );
271
272 FcbAcquired = TRUE;
273
274 FatVerifyFcb( IrpContext, Fcb );
275
276 //
277 // If the file is cached then flush its cache
278 //
279
280 Status = FatFlushFile( IrpContext, Fcb, Flush );
281
282 //
283 // Also flush the file's dirent in the parent directory if the file
284 // flush worked.
285 //
286
287 if (NT_SUCCESS( Status )) {
288
289 //
290 // Insure that we get the filesize to disk correctly. This is
291 // benign if it was already good.
292 //
293
295
296
297 FatUpdateDirentFromFcb( IrpContext, FileObject, Fcb, Ccb );
298
300
301 FatFlushRequired = TRUE;
302 }
303
304 //
305 // Flush the parent Dcb's to get any dirent updates to disk.
306 //
307
308 NextFcb = Fcb->ParentDcb;
309
310 while (NextFcb != NULL) {
311
312 //
313 // Make sure the Fcb is OK.
314 //
315
316 _SEH2_TRY {
317
318 FatVerifyFcb( IrpContext, NextFcb );
319
322
323 FatResetExceptionState( IrpContext );
324 } _SEH2_END;
325
326 if (NextFcb->FcbCondition == FcbGood) {
327
328 NTSTATUS LocalStatus;
329
330 LocalStatus = FatFlushFile( IrpContext, NextFcb, Flush );
331
332 if (!NT_SUCCESS(LocalStatus)) {
333
334 Status = LocalStatus;
335 }
336
337 if (FlagOn(NextFcb->FcbState, FCB_STATE_FLUSH_FAT)) {
338
339 FatFlushRequired = TRUE;
340 }
341 }
342
343 NextFcb = NextFcb->ParentDcb;
344 }
345
346 //
347 // Flush the volume file to get any allocation information
348 // updates to disk.
349 //
350
351 if (FatFlushRequired) {
352
353 Status = FatFlushFat( IrpContext, Vcb );
354
356 }
357
358 //
359 // Set the write through bit so that these modifications
360 // will be completed with the request.
361 //
362
363 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
364 }
365
366 break;
367
369
370 //
371 // If the user had opened the root directory then we'll
372 // oblige by flushing the volume.
373 //
374
375 if (NodeType(Fcb) != FAT_NTC_ROOT_DCB) {
376
377 DebugTrace(0, Dbg, "Flush a directory does nothing\n", 0);
378 break;
379 }
380
381 case UserVolumeOpen:
382
383 DebugTrace(0, Dbg, "Flush User Volume Open, or root dcb\n", 0);
384
385 //
386 // Acquire exclusive access to the Vcb.
387 //
388
389 {
390 BOOLEAN Finished;
391#ifdef _MSC_VER
392#pragma prefast( suppress:28931, "needed for debug build" )
393#endif
394 Finished = FatAcquireExclusiveVcb( IrpContext, Vcb );
395 NT_ASSERT( Finished );
396 }
397
398 VcbAcquired = TRUE;
399
400 //
401 // Mark the volume clean and then flush the volume file,
402 // and then all directories
403 //
404
405 Status = FatFlushVolume( IrpContext, Vcb, Flush );
406
407 //
408 // If the volume was dirty, do the processing that the delayed
409 // callback would have done.
410 //
411
412 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY)) {
413
414 //
415 // Cancel any pending clean volumes.
416 //
417
418 (VOID)KeCancelTimer( &Vcb->CleanVolumeTimer );
419 (VOID)KeRemoveQueueDpc( &Vcb->CleanVolumeDpc );
420
421 //
422 // The volume is now clean, note it.
423 //
424
425 if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
426
427 FatMarkVolume( IrpContext, Vcb, VolumeClean );
429 }
430
431 //
432 // Unlock the volume if it is removable.
433 //
434
435 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA) &&
437
438 FatToggleMediaEjectDisable( IrpContext, Vcb, FALSE );
439 }
440 }
441
442 break;
443
444 default:
445
446#ifdef _MSC_VER
447#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
448#endif
449 FatBugCheck( TypeOfOpen, 0, 0 );
450 }
451
452 FatUnpinRepinnedBcbs( IrpContext );
453
454 } _SEH2_FINALLY {
455
456 DebugUnwind( FatCommonFlushBuffers );
457
458 if (VcbAcquired) { FatReleaseVcb( IrpContext, Vcb ); }
459
460 if (FcbAcquired) { FatReleaseFcb( IrpContext, Fcb ); }
461
462 //
463 // If this is a normal termination then pass the request on
464 // to the target device object.
465 //
466
468
469#if (NTDDI_VERSION >= NTDDI_WIN8)
470 if ((IrpSp->MinorFunction != IRP_MN_FLUSH_DATA_ONLY) &&
471 (IrpSp->MinorFunction != IRP_MN_FLUSH_NO_SYNC)) {
472#endif
473
474 NTSTATUS DriverStatus;
475
476 //
477 // Get the next stack location, and copy over the stack location
478 //
479
481
482 //
483 // Set up the completion routine
484 //
485
489 TRUE,
490 TRUE,
491 TRUE );
492
493 //
494 // Send the request.
495 //
496
497 DriverStatus = IoCallDriver(Vcb->TargetDeviceObject, Irp);
498
499 if ((DriverStatus == STATUS_PENDING) ||
500 (!NT_SUCCESS(DriverStatus) &&
501 (DriverStatus != STATUS_INVALID_DEVICE_REQUEST))) {
502
503 Status = DriverStatus;
504 }
505
506 Irp = NULL;
507
508#if (NTDDI_VERSION >= NTDDI_WIN8)
509 }
510#endif
511
512 //
513 // Complete the Irp if necessary and return to the caller.
514 //
515
516 FatCompleteRequest( IrpContext, Irp, Status );
517
518 }
519
520 DebugTrace(-1, Dbg, "FatCommonFlushBuffers -> %08lx\n", Status);
521 } _SEH2_END;
522
523 return Status;
524}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define VOID
Definition: acefi.h:82
#define ULongToPtr(ul)
Definition: basetsd.h:92
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
@ UserDirectoryOpen
Definition: cdprocs.h:576
@ UserFileOpen
Definition: cdprocs.h:577
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
@ FcbGood
Definition: cdstruc.h:779
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:878
#define NodeType(P)
Definition: nodetype.h:51
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1088
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3495
NTSTATUS FatFlushFat(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: flush.c:801
IO_COMPLETION_ROUTINE FatFlushCompletionRoutine
Definition: flush.c:47
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
#define DebugUnwind(X)
Definition: fatdata.h:315
@ VolumeClean
Definition: fatprocs.h:1954
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
@ DirectoryFile
Definition: fatprocs.h:1046
@ VirtualVolumeFile
Definition: fatprocs.h:1045
@ EaFile
Definition: fatprocs.h:1047
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2983
#define FatAcquireExclusiveVcb(IC, V)
Definition: fatprocs.h:1460
@ Flush
Definition: fatprocs.h:1054
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1640
#define VCB_STATE_FLAG_VOLUME_DIRTY
Definition: fatstruc.h:561
#define FCB_STATE_FLUSH_FAT
Definition: fatstruc.h:1197
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:560
#define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE
Definition: fatstruc.h:567
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
#define _SEH2_FINALLY
Definition: filesup.c:21
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define IoCallDriver
Definition: irp.c:1225
BOOLEAN NTAPI IoIsSystemThread(IN PETHREAD Thread)
Definition: util.c:115
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
struct _FCB * ParentDcb
Definition: fatstruc.h:836
FCB_CONDITION FcbCondition
Definition: fatstruc.h:850
ULONG FcbState
Definition: cdstruc.h:971
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
Definition: cdstruc.h:498
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ FatFlushCompletionRoutine() [1/2]

NTSTATUS NTAPI FatFlushCompletionRoutine ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  Contxt 
)

◆ FatFlushCompletionRoutine() [2/2]

NTSTATUS NTAPI FatFlushCompletionRoutine ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Contxt 
)

Definition at line 1316 of file flush.c.

1322{
1323 NTSTATUS Status = (NTSTATUS) (ULONG_PTR) Contxt;
1324
1325 if ( Irp->PendingReturned ) {
1326
1328 }
1329
1330 //
1331 // If the Irp got STATUS_INVALID_DEVICE_REQUEST, normalize it
1332 // to STATUS_SUCCESS.
1333 //
1334
1335 if (NT_SUCCESS(Irp->IoStatus.Status) ||
1336 (Irp->IoStatus.Status == STATUS_INVALID_DEVICE_REQUEST)) {
1337
1338 Irp->IoStatus.Status = Status;
1339 }
1340
1342 UNREFERENCED_PARAMETER( Contxt );
1343
1344 return STATUS_SUCCESS;
1345}
#define NTSTATUS
Definition: precomp.h:21
IoMarkIrpPending(Irp)
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ FatFlushDirentForFile()

VOID FatFlushDirentForFile ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb 
)

Definition at line 1264 of file flush.c.

1285{
1288
1289 PAGED_CODE();
1290
1292
1293 CcFlushCache( &Fcb->ParentDcb->NonPaged->SectionObjectPointers,
1294 &FileOffset,
1295 sizeof( DIRENT ),
1296 &Iosb );
1297
1298 if (NT_SUCCESS(Iosb.Status)) {
1299 Iosb.Status = FatHijackIrpAndFlushDevice( IrpContext,
1300 IrpContext->OriginatingIrp,
1302 }
1303
1304 if (!NT_SUCCESS(Iosb.Status)) {
1305 FatNormalizeAndRaiseStatus(IrpContext, Iosb.Status);
1306 }
1307}
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
return Iosb
Definition: create.c:4402
NTSTATUS FatHijackIrpAndFlushDevice(IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT TargetDeviceObject)
Definition: flush.c:1101
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2995
PVCB Vcb
Definition: cdstruc.h:933
VBO DirentOffsetWithinDirectory
Definition: fatstruc.h:906
PDEVICE_OBJECT TargetDeviceObject
Definition: cdstruc.h:517

◆ FatFlushFat()

NTSTATUS FatFlushFat ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 801 of file flush.c.

824{
825 PBCB Bcb;
826 PVOID DontCare;
829
830 NTSTATUS ReturnStatus = STATUS_SUCCESS;
831
832 PAGED_CODE();
833
834 //
835 // If this volume is write protected, no need to flush.
836 //
837
838 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED)) {
839
840 return STATUS_SUCCESS;
841 }
842
843 //
844 // Make sure the Vcb is OK.
845 //
846
847 _SEH2_TRY {
848
849 FatVerifyVcb( IrpContext, Vcb );
850
853
854 FatResetExceptionState( IrpContext );
855 } _SEH2_END;
856
857 if (Vcb->VcbCondition != VcbGood) {
858
859 return STATUS_FILE_INVALID;
860 }
861
862 //
863 // The only way we have to correctly synchronize things is to
864 // repin stuff, and then unpin repin it.
865 //
866 // With NT 5.0, we can use some new cache manager support to make
867 // this a lot more efficient (important for FAT32). Since we're
868 // only worried about ranges that are dirty - and since we're a
869 // modified-no-write stream - we can assume that if there is no
870 // BCB, there is no work to do in the range. I.e., the lazy writer
871 // beat us to it.
872 //
873 // This is much better than reading the entire FAT in and trying
874 // to punch it out (see the test in the write path to blow
875 // off writes that don't correspond to dirty ranges of the FAT).
876 // For FAT32, this would be a *lot* of reading.
877 //
878
879 if (Vcb->AllocationSupport.FatIndexBitSize != 12) {
880
881 //
882 // Walk through the Fat, one page at a time.
883 //
884
885 ULONG NumberOfPages;
886 ULONG Page;
887
888 NumberOfPages = ( FatReservedBytes(&Vcb->Bpb) +
889 FatBytesPerFat(&Vcb->Bpb) +
890 (PAGE_SIZE - 1) ) / PAGE_SIZE;
891
892
893 for ( Page = 0, Offset.QuadPart = 0;
894 Page < NumberOfPages;
895 Page++, Offset.LowPart += PAGE_SIZE ) {
896
897 _SEH2_TRY {
898
899 if (CcPinRead( Vcb->VirtualVolumeFile,
900 &Offset,
901 PAGE_SIZE,
903 &Bcb,
904 &DontCare )) {
905
907 CcRepinBcb( Bcb );
908 CcUnpinData( Bcb );
910
911 if (!NT_SUCCESS(Iosb.Status)) {
912
913 ReturnStatus = Iosb.Status;
914 }
915 }
916
918
919 ReturnStatus = IrpContext->ExceptionStatus;
920 continue;
921 } _SEH2_END;
922 }
923
924 } else {
925
926 //
927 // We read in the entire fat in the 12 bit case.
928 //
929
930 Offset.QuadPart = FatReservedBytes( &Vcb->Bpb );
931
932 _SEH2_TRY {
933
934 if (CcPinRead( Vcb->VirtualVolumeFile,
935 &Offset,
936 FatBytesPerFat( &Vcb->Bpb ),
938 &Bcb,
939 &DontCare )) {
940
942 CcRepinBcb( Bcb );
943 CcUnpinData( Bcb );
945
946 if (!NT_SUCCESS(Iosb.Status)) {
947
948 ReturnStatus = Iosb.Status;
949 }
950 }
951
953
954 ReturnStatus = IrpContext->ExceptionStatus;
955 } _SEH2_END;
956 }
957
958 return ReturnStatus;
959}
VOID NTAPI CcUnpinRepinnedBcb(IN PVOID Bcb, IN BOOLEAN WriteThrough, OUT PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:343
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
VOID NTAPI CcRepinBcb(IN PVOID Bcb)
Definition: cachesub.c:331
#define FatReservedBytes(B)
Definition: fat.h:414
#define FatBytesPerFat(B)
Definition: fat.h:410
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:414
VOID FatVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:270
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
@ VcbGood
Definition: fatstruc.h:223
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PIN_IF_BCB
#define PIN_WAIT
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
uint32_t ULONG
Definition: typedefs.h:59

Referenced by _Requires_lock_held_().

◆ FatFlushFatEntries()

VOID FatFlushFatEntries ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN ULONG  Cluster,
IN ULONG  Count 
)

Definition at line 1191 of file flush.c.

1218{
1221
1223
1224 PAGED_CODE();
1225
1226 FileOffset.HighPart = 0;
1227 FileOffset.LowPart = FatReservedBytes( &Vcb->Bpb );
1228
1229 if (Vcb->AllocationSupport.FatIndexBitSize == 12) {
1230
1231 FileOffset.LowPart += Cluster * 3 / 2;
1232 ByteCount = (Count * 3 / 2) + 1;
1233
1234 } else if (Vcb->AllocationSupport.FatIndexBitSize == 32) {
1235
1236 FileOffset.LowPart += Cluster * sizeof(ULONG);
1237 ByteCount = Count * sizeof(ULONG);
1238
1239 } else {
1240
1241 FileOffset.LowPart += Cluster * sizeof( USHORT );
1242 ByteCount = Count * sizeof( USHORT );
1243
1244 }
1245
1246 CcFlushCache( &Vcb->SectionObjectPointers,
1247 &FileOffset,
1248 ByteCount,
1249 &Iosb );
1250
1251 if (NT_SUCCESS(Iosb.Status)) {
1252 Iosb.Status = FatHijackIrpAndFlushDevice( IrpContext,
1253 IrpContext->OriginatingIrp,
1254 Vcb->TargetDeviceObject );
1255 }
1256
1257 if (!NT_SUCCESS(Iosb.Status)) {
1258 FatNormalizeAndRaiseStatus(IrpContext, Iosb.Status);
1259 }
1260}
int Count
Definition: noreturn.cpp:7
unsigned short USHORT
Definition: pedump.c:61
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099

◆ FatHijackCompletionRoutine()

NTSTATUS NTAPI FatHijackCompletionRoutine ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  Contxt 
)

Definition at line 1353 of file flush.c.

1359{
1360 //
1361 // Set the event so that our call will wake up.
1362 //
1363
1364 KeSetEvent( (PKEVENT)Contxt, 0, FALSE );
1365
1368
1370}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68

◆ FatHijackIrpAndFlushDevice()

NTSTATUS FatHijackIrpAndFlushDevice ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN PDEVICE_OBJECT  TargetDeviceObject 
)

Definition at line 1101 of file flush.c.

1130{
1131 KEVENT Event;
1133 PIO_STACK_LOCATION NextIrpSp;
1134
1135 PAGED_CODE();
1136
1137 UNREFERENCED_PARAMETER( IrpContext );
1138
1139 //
1140 // Get the next stack location, and copy over the stack location
1141 //
1142
1144
1145 NextIrpSp = IoGetNextIrpStackLocation( Irp );
1147 NextIrpSp->MinorFunction = 0;
1148
1149 //
1150 // Set up the completion routine
1151 //
1152
1154
1157 &Event,
1158 TRUE,
1159 TRUE,
1160 TRUE );
1161
1162 //
1163 // Send the request.
1164 //
1165
1167
1168 if (Status == STATUS_PENDING) {
1169
1171
1172 Status = Irp->IoStatus.Status;
1173 }
1174
1175 //
1176 // If the driver doesn't support flushes, return SUCCESS.
1177 //
1178
1181 }
1182
1183 Irp->IoStatus.Status = 0;
1184 Irp->IoStatus.Information = 0;
1185
1186 return Status;
1187}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
IO_COMPLETION_ROUTINE FatHijackCompletionRoutine
Definition: flush.c:57
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_MJ_FLUSH_BUFFERS
@ Executive
Definition: ketypes.h:415

Referenced by _Requires_lock_held_(), FatFlushDirentForFile(), and FatFlushFatEntries().

Variable Documentation

◆ FatFlushCompletionRoutine

IO_COMPLETION_ROUTINE FatFlushCompletionRoutine

Definition at line 47 of file flush.c.

Referenced by _Requires_lock_held_().

◆ FatHijackCompletionRoutine

NTSTATUS NTAPI FatHijackCompletionRoutine

Definition at line 57 of file flush.c.

Referenced by FatHijackIrpAndFlushDevice().