ReactOS  0.4.13-dev-100-gc8611ae
flush.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  Flush.c
8 
9 Abstract:
10 
11  This module implements the File Flush buffers routine for Fat called by the
12  dispatch driver.
13 
14 
15 --*/
16 
17 #include "fatprocs.h"
18 
19 //
20 // The Bug check file id for this module
21 //
22 
23 #define BugCheckFileId (FAT_BUG_CHECK_FLUSH)
24 
25 //
26 // The local debug trace level
27 //
28 
29 #define Dbg (DEBUG_TRACE_FLUSH)
30 
31 #ifdef ALLOC_PRAGMA
32 #pragma alloc_text(PAGE, FatCommonFlushBuffers)
33 #pragma alloc_text(PAGE, FatFlushDirectory)
34 #pragma alloc_text(PAGE, FatFlushFat)
35 #pragma alloc_text(PAGE, FatFlushFile)
36 #pragma alloc_text(PAGE, FatFlushVolume)
37 #pragma alloc_text(PAGE, FatFsdFlushBuffers)
38 #pragma alloc_text(PAGE, FatFlushDirentForFile)
39 #pragma alloc_text(PAGE, FatFlushFatEntries)
40 #pragma alloc_text(PAGE, FatHijackIrpAndFlushDevice)
41 #endif
42 
43 //
44 // Local procedure prototypes
45 //
46 
47 IO_COMPLETION_ROUTINE FatFlushCompletionRoutine;
48 
50 NTAPI
53  _In_ PIRP Irp,
54  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
55  );
56 
57 IO_COMPLETION_ROUTINE FatHijackCompletionRoutine;
58 
60 NTAPI
63  _In_ PIRP Irp,
64  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
65  );
66 
67 
71 NTAPI
72 FatFsdFlushBuffers (
73  _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
75  )
76 
77 /*++
78 
79 Routine Description:
80 
81  This routine implements the FSD part of Flush buffers.
82 
83 Arguments:
84 
85  VolumeDeviceObject - Supplies the volume device object where the
86  file being flushed exists
87 
88  Irp - Supplies the Irp being processed
89 
90 Return Value:
91 
92  NTSTATUS - The FSD status for the IRP
93 
94 --*/
95 
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 }
146 
147 
148 _Requires_lock_held_(_Global_critical_region_)
149 NTSTATUS
150 FatCommonFlushBuffers (
151  IN PIRP_CONTEXT IrpContext,
152  IN PIRP Irp
153  )
154 
155 /*++
156 
157 Routine Description:
158 
159  This is the common routine for flushing a buffer.
160 
161 Arguments:
162 
163  Irp - Supplies the Irp to process
164 
165 Return Value:
166 
167  NTSTATUS - The return status for the operation
168 
169 --*/
170 
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 
260  case VirtualVolumeFile:
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 
368  case UserDirectoryOpen:
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 
467  if (!_SEH2_AbnormalTermination()) {
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 
488  ULongToPtr( Status ),
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 }
525 
526 
527 _Requires_lock_held_(_Global_critical_region_)
528 NTSTATUS
529 FatFlushDirectory (
530  IN PIRP_CONTEXT IrpContext,
531  IN PDCB Dcb,
533  )
534 
535 /*++
536 
537 Routine Description:
538 
539  This routine non-recursively flushes a dcb tree.
540 
541 Arguments:
542 
543  Dcb - Supplies the Dcb being flushed
544 
545  FlushType - Specifies the kind of flushing to perform
546 
547 Return Value:
548 
549  VOID
550 
551 --*/
552 
553 {
554  PFCB Fcb;
555  PVCB Vcb;
556  PFCB NextFcb;
557 
558  PDIRENT Dirent;
559  PBCB DirentBcb = NULL;
560 
562  NTSTATUS ReturnStatus = STATUS_SUCCESS;
563 
564  BOOLEAN ClearWriteThroughOnExit = FALSE;
565  BOOLEAN ClearWaitOnExit = FALSE;
566 
567  ULONG CorrectedFileSize = 0;
568 
569  PAGED_CODE();
570 
571  NT_ASSERT( FatVcbAcquiredExclusive(IrpContext, Dcb->Vcb) );
572 
573  DebugTrace(+1, Dbg, "FatFlushDirectory, Dcb = %p\n", Dcb);
574 
575  //
576  // First flush all the files, then the directories, to make sure all the
577  // file sizes and times get sets correctly on disk.
578  //
579  // We also have to check here if the "Ea Data. Sf" fcb really
580  // corressponds to an existing file.
581  //
582 
583  if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH)) {
584 
585  ClearWriteThroughOnExit = TRUE;
586  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
587  }
588 
589  if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
590 
591  ClearWaitOnExit = TRUE;
592  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
593  }
594 
595  Vcb = Dcb->Vcb;
596  Fcb = Dcb;
597 
598  while (Fcb != NULL) {
599 
600  NextFcb = FatGetNextFcbTopDown(IrpContext, Fcb, Dcb);
601 
602  if ( (NodeType( Fcb ) == FAT_NTC_FCB) &&
603  (Vcb->EaFcb != Fcb) &&
604  !IsFileDeleted(IrpContext, Fcb)) {
605 
606  (VOID)FatAcquireExclusiveFcb( IrpContext, Fcb );
607 
609 
610  //
611  // Exception handler to catch and commute errors encountered
612  // doing the flush dance. We may encounter corruption, and
613  // should continue flushing the volume as much as possible.
614  //
615 
616  _SEH2_TRY {
617 
618  //
619  // Standard handler to release resources, etc.
620  //
621 
622  _SEH2_TRY {
623 
624  //
625  // Make sure the Fcb is OK.
626  //
627 
628  _SEH2_TRY {
629 
630  FatVerifyFcb( IrpContext, Fcb );
631 
634 
635  FatResetExceptionState( IrpContext );
636  } _SEH2_END;
637 
638  //
639  // If this Fcb is not good skip it. Note that a 'continue'
640  // here would be very expensive as we inside a try{} body.
641  //
642 
643  if (Fcb->FcbCondition != FcbGood) {
644 
645  try_leave( NOTHING);
646  }
647 
648  //
649  // In case a handle was never closed and the FS and AS are more
650  // than a cluster different, do this truncate.
651  //
652 
654 
655 
656  FatTruncateFileAllocation( IrpContext,
657  Fcb,
658  Fcb->Header.FileSize.LowPart );
659 
660 
661  }
662 
663  //
664  // Also compare the file's dirent in the parent directory
665  // with the size information in the Fcb and update
666  // it if neccessary. Note that we don't mark the Bcb dirty
667  // because we will be flushing the file object presently, and
668  // Mm knows what's really dirty.
669  //
670 
671  FatGetDirentFromFcbOrDcb( IrpContext,
672  Fcb,
673  FALSE,
674  &Dirent,
675  &DirentBcb );
676 
677 
678  CorrectedFileSize = Fcb->Header.FileSize.LowPart;
679 
680 
681  if (Dirent->FileSize != CorrectedFileSize) {
682 
683  Dirent->FileSize = CorrectedFileSize;
684 
685 
686  }
687 
688  //
689  // We must unpin the Bcb before the flush since we recursively tear up
690  // the tree if Mm decides that the data section is no longer referenced
691  // and the final close comes in for this file. If this parent has no
692  // more children as a result, we will try to initiate teardown on it
693  // and Cc will deadlock against the active count of this Bcb.
694  //
695 
696  FatUnpinBcb( IrpContext, DirentBcb );
697 
698  //
699  // Now flush the file. Note that this may make the Fcb
700  // go away if Mm dereferences its file object.
701  //
702 
703  Status = FatFlushFile( IrpContext, Fcb, FlushType );
704 
705  if (!NT_SUCCESS(Status)) {
706 
707  ReturnStatus = Status;
708  }
709 
710  } _SEH2_FINALLY {
711 
712  FatUnpinBcb( IrpContext, DirentBcb );
713 
714  //
715  // Since we have the Vcb exclusive we know that if any closes
716  // come in it is because the CcPurgeCacheSection caused the
717  // Fcb to go away.
718  //
719 
720  if ( !FlagOn(Vcb->VcbState, VCB_STATE_FLAG_DELETED_FCB) ) {
721 
722  FatReleaseFcb( (IRPCONTEXT), Fcb );
723  }
724  } _SEH2_END;
725  } _SEH2_EXCEPT( (FsRtlIsNtstatusExpected( ReturnStatus = _SEH2_GetExceptionCode() ) != 0 ) ?
727  FatResetExceptionState( IrpContext );
728  } _SEH2_END;
729 
730  }
731 
732  Fcb = NextFcb;
733  }
734 
735  //
736  // OK, now flush the directories.
737  //
738 
739  Fcb = Dcb;
740 
741  while (Fcb != NULL) {
742 
743  NextFcb = FatGetNextFcbTopDown(IrpContext, Fcb, Dcb);
744 
745  if ( (NodeType( Fcb ) != FAT_NTC_FCB) &&
746  !IsFileDeleted(IrpContext, Fcb) ) {
747 
748  //
749  // Make sure the Fcb is OK.
750  //
751 
752  _SEH2_TRY {
753 
754  FatVerifyFcb( IrpContext, Fcb );
755 
758 
759  FatResetExceptionState( IrpContext );
760  } _SEH2_END;
761 
762  if (Fcb->FcbCondition == FcbGood) {
763 
764  Status = FatFlushFile( IrpContext, Fcb, FlushType );
765 
766  if (!NT_SUCCESS(Status)) {
767 
768  ReturnStatus = Status;
769  }
770  }
771  }
772 
773  Fcb = NextFcb;
774  }
775 
776  _SEH2_TRY {
777 
778  FatUnpinRepinnedBcbs( IrpContext );
779 
781 
782  ReturnStatus = IrpContext->ExceptionStatus;
783  } _SEH2_END;
784 
785  if (ClearWriteThroughOnExit) {
786 
787  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH);
788  }
789  if (ClearWaitOnExit) {
790 
791  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
792  }
793 
794  DebugTrace(-1, Dbg, "FatFlushDirectory -> 0x%08lx\n", ReturnStatus);
795 
796  return ReturnStatus;
797 }
798 
799 
800 NTSTATUS
802  IN PIRP_CONTEXT IrpContext,
803  IN PVCB Vcb
804  )
805 
806 /*++
807 
808 Routine Description:
809 
810  The function carefully flushes the entire FAT for a volume. It is
811  nessecary to dance around a bit because of complicated synchronization
812  reasons.
813 
814 Arguments:
815 
816  Vcb - Supplies the Vcb whose FAT is being flushed
817 
818 Return Value:
819 
820  VOID
821 
822 --*/
823 
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 }
960 
961 
962 _Requires_lock_held_(_Global_critical_region_)
963 NTSTATUS
964 FatFlushVolume (
965  IN PIRP_CONTEXT IrpContext,
966  IN PVCB Vcb,
968  )
969 
970 /*++
971 
972 Routine Description:
973 
974  The following routine is used to flush a volume to disk, including the
975  volume file, and ea file.
976 
977 Arguments:
978 
979  Vcb - Supplies the volume being flushed
980 
981  FlushType - Specifies the kind of flushing to perform
982 
983 Return Value:
984 
985  NTSTATUS - The Status from the flush.
986 
987 --*/
988 
989 {
991  NTSTATUS ReturnStatus = STATUS_SUCCESS;
992 
993  PAGED_CODE();
994 
995  //
996  // If this volume is write protected, no need to flush.
997  //
998 
999  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED)) {
1000 
1001  return STATUS_SUCCESS;
1002  }
1003 
1004  //
1005  // Flush all the files and directories.
1006  //
1007 
1008  Status = FatFlushDirectory( IrpContext, Vcb->RootDcb, FlushType );
1009 
1010  if (!NT_SUCCESS(Status)) {
1011 
1012  ReturnStatus = Status;
1013  }
1014 
1015  //
1016  // Now Flush the FAT
1017  //
1018 
1019  Status = FatFlushFat( IrpContext, Vcb );
1020 
1021  if (!NT_SUCCESS(Status)) {
1022 
1023  ReturnStatus = Status;
1024  }
1025 
1026  //
1027  // Unlock the volume if it is removable.
1028  //
1029 
1030  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA) &&
1032 
1033  FatToggleMediaEjectDisable( IrpContext, Vcb, FALSE );
1034  }
1035 
1036  return ReturnStatus;
1037 }
1038 
1039 
1040 _Requires_lock_held_(_Global_critical_region_)
1041 NTSTATUS
1042 FatFlushFile (
1043  IN PIRP_CONTEXT IrpContext,
1044  IN PFCB Fcb,
1046  )
1047 
1048 /*++
1049 
1050 Routine Description:
1051 
1052  This routine simply flushes the data section on a file.
1053 
1054 Arguments:
1055 
1056  Fcb - Supplies the file being flushed
1057 
1058  FlushType - Specifies the kind of flushing to perform
1059 
1060 Return Value:
1061 
1062  NTSTATUS - The Status from the flush.
1063 
1064 --*/
1065 
1066 {
1068  PVCB Vcb = Fcb->Vcb;
1069 
1070  PAGED_CODE();
1071 
1073 
1074 
1075  if ( !FlagOn( Vcb->VcbState, VCB_STATE_FLAG_DELETED_FCB )) {
1076 
1077  //
1078  // Grab and release PagingIo to serialize ourselves with the lazy writer.
1079  // This will work to ensure that all IO has completed on the cached
1080  // data.
1081  //
1082  // If we are to invalidate the file, now is the right time to do it. Do
1083  // it non-recursively so we don't thump children before their time.
1084  //
1085 
1086  ExAcquireResourceExclusiveLite( Fcb->Header.PagingIoResource, TRUE);
1087 
1088  if (FlushType == FlushAndInvalidate) {
1089 
1090  FatMarkFcbCondition( IrpContext, Fcb, FcbBad, FALSE );
1091  }
1092 
1093  ExReleaseResourceLite( Fcb->Header.PagingIoResource );
1094  }
1095 
1096  return Iosb.Status;
1097 }
1098 
1099 
1100 NTSTATUS
1102  IN PIRP_CONTEXT IrpContext,
1103  IN PIRP Irp,
1105  )
1106 
1107 /*++
1108 
1109 Routine Description:
1110 
1111  This routine is called when we need to send a flush to a device but
1112  we don't have a flush Irp. What this routine does is make a copy
1113  of its current Irp stack location, but changes the Irp Major code
1114  to a IRP_MJ_FLUSH_BUFFERS amd then send it down, but cut it off at
1115  the knees in the completion routine, fix it up and return to the
1116  user as if nothing had happened.
1117 
1118 Arguments:
1119 
1120  Irp - The Irp to hijack
1121 
1122  TargetDeviceObject - The device to send the request to.
1123 
1124 Return Value:
1125 
1126  NTSTATUS - The Status from the flush in case anybody cares.
1127 
1128 --*/
1129 
1130 {
1131  KEVENT Event;
1132  NTSTATUS Status;
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 );
1146  NextIrpSp->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
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 }
1188 
1189 
1190 VOID
1192  IN PIRP_CONTEXT IrpContext,
1193  IN PVCB Vcb,
1194  IN ULONG Cluster,
1195  IN ULONG Count
1196 )
1197 
1198 /*++
1199 
1200 Routine Description:
1201 
1202  This macro flushes the FAT page(s) containing the passed in run.
1203 
1204 Arguments:
1205 
1206  Vcb - Supplies the volume being flushed
1207 
1208  Cluster - The starting cluster
1209 
1210  Count - The number of FAT entries in the run
1211 
1212 Return Value:
1213 
1214  VOID
1215 
1216 --*/
1217 
1218 {
1219  ULONG ByteCount;
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 }
1261 
1262 
1263 VOID
1265  IN PIRP_CONTEXT IrpContext,
1266  IN PFCB Fcb
1267 )
1268 
1269 /*++
1270 
1271 Routine Description:
1272 
1273  This macro flushes the page containing a file's DIRENT in its parent.
1274 
1275 Arguments:
1276 
1277  Fcb - Supplies the file whose DIRENT is being flushed
1278 
1279 Return Value:
1280 
1281  VOID
1282 
1283 --*/
1284 
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 }
1308 
1309 
1310 //
1311 // Local support routine
1312 //
1313 
1314 NTSTATUS
1315 NTAPI
1318  IN PIRP Irp,
1319  IN PVOID Contxt
1320  )
1321 
1322 {
1323  NTSTATUS Status = (NTSTATUS) (ULONG_PTR) Contxt;
1324 
1325  if ( Irp->PendingReturned ) {
1326 
1327  IoMarkIrpPending( Irp );
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 }
1346 
1347 //
1348 // Local support routine
1349 //
1350 
1351 NTSTATUS
1352 NTAPI
1355  _In_ PIRP Irp,
1356  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
1357  )
1358 
1359 {
1360  //
1361  // Set the event so that our call will wake up.
1362  //
1363 
1364  KeSetEvent( (PKEVENT)Contxt, 0, FALSE );
1365 
1368 
1370 }
1371 
BOOLEAN NTAPI IoIsSystemThread(IN PETHREAD Thread)
Definition: util.c:115
IO_COMPLETION_ROUTINE FatHijackCompletionRoutine
Definition: flush.c:57
#define IN
Definition: typedefs.h:38
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define VCB_STATE_FLAG_VOLUME_DIRTY
Definition: fatstruc.h:557
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2983
#define FsRtlEnterFileSystem
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:402
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:558
#define IRP_MJ_FLUSH_BUFFERS
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
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
#define FsRtlExitFileSystem
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2621
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
NTSTATUS FatHijackIrpAndFlushDevice(IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT TargetDeviceObject)
Definition: flush.c:1101
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
Definition: cdstruc.h:1073
#define FCB_STATE_FLUSH_FAT
Definition: fatstruc.h:1193
LONG NTSTATUS
Definition: precomp.h:26
_Requires_lock_held_(_Global_critical_region_)
Definition: flush.c:148
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:877
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
Definition: cdstruc.h:504
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:566
#define PIN_WAIT
VOID FatVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:270
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: fatstruc.h:725
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
struct _FCB * ParentDcb
Definition: fatstruc.h:832
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2401
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1745
#define FatReservedBytes(B)
Definition: fat.h:414
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
PEPROCESS PsGetThreadProcess(_In_ PETHREAD Thread)
#define FatBytesPerFat(B)
Definition: fat.h:410
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:807
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:537
unsigned char BOOLEAN
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:959
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:556
NodeType
Definition: Node.h:5
#define FCB_STATE_TRUNCATE_ON_CLOSE
Definition: fatstruc.h:1190
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
IO_COMPLETION_ROUTINE FatFlushCompletionRoutine
Definition: flush.c:47
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2300
IN PFCB IN FAT_FLUSH_TYPE FlushType
Definition: fatprocs.h:1071
#define try_leave(S)
Definition: cdprocs.h:2190
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3515
#define DebugUnwind(X)
Definition: fatdata.h:315
#define Dbg
Definition: flush.c:29
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1635
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2971
VOID NTAPI CcUnpinRepinnedBcb(IN PVOID Bcb, IN BOOLEAN WriteThrough, OUT PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:343
return Iosb
Definition: create.c:4426
PDEVICE_OBJECT TargetDeviceObject
Definition: cdstruc.h:523
#define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE
Definition: fatstruc.h:563
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
enum _FAT_FLUSH_TYPE FAT_FLUSH_TYPE
#define Vcb
Definition: cdprocs.h:1425
#define _Inout_
Definition: no_sal2.h:244
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1954
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
#define CanFsdWait(I)
Definition: cdprocs.h:2011
VOID FatMarkFcbCondition(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN FCB_CONDITION FcbCondition, IN BOOLEAN Recursive)
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define NTSTATUS
Definition: precomp.h:20
#define VOID
Definition: acefi.h:82
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
VOID FatFlushFatEntries(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG Cluster, IN ULONG Count)
Definition: flush.c:1191
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
DRIVER_DISPATCH(nfs41_FsdDispatch)
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1060
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
_SEH2_END
Definition: create.c:4424
VBO DirentOffsetWithinDirectory
Definition: fatstruc.h:902
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned short USHORT
Definition: pedump.c:61
#define PIN_IF_BCB
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define FatAcquireExclusiveVcb(IC, V)
Definition: fatprocs.h:1451
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define VCB_STATE_FLAG_DELETED_FCB
Definition: fatstruc.h:561
VOID FatFlushDirentForFile(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: flush.c:1264
_SEH2_FINALLY
Definition: create.c:4395
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
_Function_class_(IRP_MJ_FLUSH_BUFFERS)
Definition: flush.c:68
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1631
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1486
#define _In_reads_opt_(size)
Definition: no_sal2.h:231
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
PVCB Vcb
Definition: cdstruc.h:939
VOID NTAPI CcRepinBcb(IN PVOID Bcb)
Definition: cachesub.c:331
NTSTATUS FatFlushFat(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: flush.c:801
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
_In_ PFCB Fcb
Definition: cdprocs.h:151
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1664
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4157
ULONG FcbState
Definition: cdstruc.h:977
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define NT_ASSERT
Definition: rtlfuncs.h:3312
PFCB FatGetNextFcbTopDown(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2626
FCB_CONDITION FcbCondition
Definition: fatstruc.h:846