ReactOS  0.4.14-dev-552-g2fad488
verfysup.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  VerfySup.c
8 
9 Abstract:
10 
11  This module implements the Fat Verify volume and fcb/dcb support
12  routines
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_VERFYSUP)
24 
25 //
26 // The Debug trace level for this module
27 //
28 
29 #define Dbg (DEBUG_TRACE_VERFYSUP)
30 
31 //
32 // Local procedure prototypes
33 //
34 
35 VOID
37  IN PIRP_CONTEXT IrpContext,
38  IN PFCB Fcb
39  );
40 
41 BOOLEAN
43  __in PIRP_CONTEXT IrpContext,
45  __in PFCB Fcb
46  );
47 
48 _Requires_lock_held_(_Global_critical_region_)
49 VOID
50 FatDetermineAndMarkFcbCondition (
51  IN PIRP_CONTEXT IrpContext,
52  IN PFCB Fcb
53  );
54 
55 WORKER_THREAD_ROUTINE FatDeferredCleanVolume;
56 
57 VOID
58 NTAPI
61  );
62 
63 IO_COMPLETION_ROUTINE FatMarkVolumeCompletionRoutine;
64 
66 NTAPI
69  _In_ PIRP Irp,
70  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
71  );
72 
73 #ifdef ALLOC_PRAGMA
74 #pragma alloc_text(PAGE, FatCheckDirtyBit)
75 #pragma alloc_text(PAGE, FatVerifyOperationIsLegal)
76 #pragma alloc_text(PAGE, FatDeferredCleanVolume)
77 #pragma alloc_text(PAGE, FatMatchFileSize)
78 #pragma alloc_text(PAGE, FatDetermineAndMarkFcbCondition)
79 #pragma alloc_text(PAGE, FatQuickVerifyVcb)
80 #pragma alloc_text(PAGE, FatPerformVerify)
81 #pragma alloc_text(PAGE, FatMarkFcbCondition)
82 #pragma alloc_text(PAGE, FatResetFcb)
83 #pragma alloc_text(PAGE, FatVerifyVcb)
84 #pragma alloc_text(PAGE, FatVerifyFcb)
85 #endif
86 
87 
88 VOID
90  IN PIRP_CONTEXT IrpContext,
91  IN PFCB Fcb,
92  IN FCB_CONDITION FcbCondition,
93  IN BOOLEAN Recursive
94  )
95 
96 /*++
97 
98 Routine Description:
99 
100  This routines marks the entire Fcb/Dcb structure from Fcb down with
101  FcbCondition.
102 
103 Arguments:
104 
105  Fcb - Supplies the Fcb/Dcb being marked
106 
107  FcbCondition - Supplies the setting to use for the Fcb Condition
108 
109  Recursive - Specifies whether this condition should be applied to
110  all children (see the case where we are invalidating a live volume
111  for a case where this is now desireable).
112 
113 Return Value:
114 
115  None.
116 
117 --*/
118 
119 {
120  PAGED_CODE();
121 
122  DebugTrace(+1, Dbg, "FatMarkFcbCondition, Fcb = %p\n", Fcb );
123 
124  //
125  // If we are marking this Fcb something other than Good, we will need
126  // to have the Vcb exclusive.
127  //
128 
129  NT_ASSERT( FcbCondition != FcbNeedsToBeVerified ? TRUE :
130  FatVcbAcquiredExclusive(IrpContext, Fcb->Vcb) );
131 
132  //
133  // If this is a PagingFile it has to be good unless media underneath is
134  // removable. The "removable" check was added specifically for ReadyBoost,
135  // which opens its cache file on a removable device as a paging file and
136  // relies on the file system to validate its mapping information after a
137  // power transition.
138  //
139 
142 
144  return;
145  }
146 
147  //
148  // Update the condition of the Fcb.
149  //
150 
151  Fcb->FcbCondition = FcbCondition;
152 
153  DebugTrace(0, Dbg, "MarkFcb: %wZ\n", &Fcb->FullFileName);
154 
155  //
156  // This FastIo flag is based on FcbCondition, so update it now. This only
157  // applies to regular FCBs, of course.
158  //
159 
160  if (Fcb->Header.NodeTypeCode == FAT_NTC_FCB) {
161 
162  Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
163  }
164 
165  if (FcbCondition == FcbNeedsToBeVerified) {
166  FatResetFcb( IrpContext, Fcb );
167  }
168 
169  //
170  // Now if we marked NeedsVerify or Bad a directory then we also need to
171  // go and mark all of our children with the same condition.
172  //
173 
174  if ( ((FcbCondition == FcbNeedsToBeVerified) ||
175  (FcbCondition == FcbBad)) &&
176  Recursive &&
177  ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) ||
178  (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) ) {
179 
180  PFCB OriginalFcb = Fcb;
181 
182  while ( (Fcb = FatGetNextFcbTopDown(IrpContext, Fcb, OriginalFcb)) != NULL ) {
183 
184  DebugTrace(0, Dbg, "MarkFcb: %wZ\n", &Fcb->FullFileName);
185 
186  Fcb->FcbCondition = FcbCondition;
187 
188  //
189  // We already know that FastIo is not possible since we are propagating
190  // a parent's bad/verify flag down the tree - IO to the children must
191  // take the long route for now.
192  //
193 
194  Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
195 
196  //
197  // Leave all the Fcbs in a condition to be verified.
198  //
199 
200  if (FcbCondition == FcbNeedsToBeVerified) {
201  FatResetFcb( IrpContext, Fcb );
202  }
203 
204  }
205  }
206 
207  DebugTrace(-1, Dbg, "FatMarkFcbCondition -> VOID\n", 0);
208 
209  return;
210 }
211 
212 BOOLEAN
214  IN PVCB Vcb
215  )
216 
217 /*++
218 
219 Routine Description:
220 
221  This routine checks to see if the specified Vcb is currently mounted on
222  the device or not. If it is, it sets the verify flag on the device, if
223  not then the state is noted in the Vcb.
224 
225 Arguments:
226 
227  Vcb - This is the volume to check.
228 
229 Return Value:
230 
231  TRUE if the device has been marked for verify here, FALSE otherwise.
232 
233 --*/
234 {
235  BOOLEAN Marked = FALSE;
236  KIRQL SavedIrql;
237 
238  IoAcquireVpbSpinLock( &SavedIrql );
239 
240 #ifdef _MSC_VER
241 #pragma prefast( push )
242 #pragma prefast( disable: 28175, "touching Vpb is ok for a filesystem" )
243 #endif
244 
245  if (Vcb->Vpb->RealDevice->Vpb == Vcb->Vpb) {
246 
247  SetFlag( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
248  Marked = TRUE;
249  }
250  else {
251 
252  //
253  // Flag this to avoid the VPB spinlock in future passes.
254  //
255 
257  }
258 
259 #ifdef _MSC_VER
260 #pragma prefast( pop )
261 #endif
262 
263  IoReleaseVpbSpinLock( SavedIrql );
264 
265  return Marked;
266 }
267 
268 
269 VOID
271  IN PIRP_CONTEXT IrpContext,
272  IN PVCB Vcb
273  )
274 
275 /*++
276 
277 Routine Description:
278 
279  This routines verifies that the Vcb still denotes a valid Volume
280  If the Vcb is bad it raises an error condition.
281 
282 Arguments:
283 
284  Vcb - Supplies the Vcb being verified
285 
286 Return Value:
287 
288  None.
289 
290 --*/
291 
292 {
293  BOOLEAN DevMarkedForVerify;
294 
295  PAGED_CODE();
296 
297  DebugTrace(+1, Dbg, "FatVerifyVcb, Vcb = %p\n", Vcb );
298 
299  //
300  // If the verify volume flag in the device object is set
301  // this means the media has potentially changed.
302  //
303  // Note that we only force this ping for create operations.
304  // For others we take a sporting chance. If in the end we
305  // have to physically access the disk, the right thing will happen.
306  //
307 
308  DevMarkedForVerify = BooleanFlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
309 
310  //
311  // We ALWAYS force CREATE requests on unmounted volumes through the
312  // verify path. These requests could have been in limbo between
313  // IoCheckMountedVpb and us, when a verify/mount took place and caused
314  // a completely different fs/volume to be mounted. In this case the
315  // checks above may not have caught the condition, since we may already
316  // have verified (wrong volume) and decided that we have nothing to do.
317  // We want the requests to be re routed to the currently mounted volume,
318  // since they were directed at the 'drive', not our volume. So we take
319  // the verify path for synchronisation, and the request will eventually
320  // be bounced back to IO with STATUS_REPARSE by our verify handler.
321  //
322 
323  if (!DevMarkedForVerify &&
324  (IrpContext->MajorFunction == IRP_MJ_CREATE) &&
325  (IrpContext->OriginatingIrp != NULL)) {
326 
327  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp);
328 
329  if ((IrpSp->FileObject->RelatedFileObject == NULL) &&
330  (Vcb->VcbCondition == VcbNotMounted)) {
331 
332  DevMarkedForVerify = TRUE;
333  }
334  }
335 
336  //
337  // Raise any error condition otherwise.
338  //
339 
340  if (DevMarkedForVerify) {
341 
342  DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
343 
344  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
345  Vcb->Vpb->RealDevice );
346 
348  }
349 
350  //
351  // Check the operation is legal for current Vcb state.
352  //
353 
354  FatQuickVerifyVcb( IrpContext, Vcb );
355 
356  DebugTrace(-1, Dbg, "FatVerifyVcb -> VOID\n", 0);
357 }
358 
359 
360 _Requires_lock_held_(_Global_critical_region_)
361 VOID
362 FatVerifyFcb (
363  IN PIRP_CONTEXT IrpContext,
364  IN PFCB Fcb
365  )
366 
367 /*++
368 
369 Routine Description:
370 
371  This routines verifies that the Fcb still denotes the same file.
372  If the Fcb is bad it raises a error condition.
373 
374 Arguments:
375 
376  Fcb - Supplies the Fcb being verified
377 
378 Return Value:
379 
380  None.
381 
382 --*/
383 
384 {
386 
387  PAGED_CODE();
388 
389  DebugTrace(+1, Dbg, "FatVerifyFcb, Vcb = %p\n", Fcb );
390 
391  //
392  // Always refuse operations on dismounted volumes.
393  //
394 
396 
398  }
399 
400  //
401  // If this is the Fcb of a deleted dirent or our parent is deleted,
402  // no-op this call with the hope that the caller will do the right thing.
403  // The only caller we really have to worry about is the AdvanceOnly
404  // callback for setting valid data length from Cc, this will happen after
405  // cleanup (and file deletion), just before the SCM is ripped down.
406  //
407 
408  if (IsFileDeleted( IrpContext, Fcb ) ||
409  ((NodeType(Fcb) != FAT_NTC_ROOT_DCB) &&
410  IsFileDeleted( IrpContext, Fcb->ParentDcb ))) {
411 
412  return;
413  }
414 
415  //
416  // If we are not in the process of doing a verify,
417  // first do a quick spot check on the Vcb.
418  //
419 
420  if ( Fcb->Vcb->VerifyThread != KeGetCurrentThread() ) {
421 
422  FatQuickVerifyVcb( IrpContext, Fcb->Vcb );
423  }
424 
425  //
426  // Now based on the condition of the Fcb we'll either return
427  // immediately to the caller, raise a condition, or do some work
428  // to verify the Fcb.
429  //
430 
431  switch (Fcb->FcbCondition) {
432 
433  case FcbGood:
434 
435  DebugTrace(0, Dbg, "The Fcb is good\n", 0);
436  break;
437 
438  case FcbBad:
439 
440  FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
441  break;
442 
444 
445  //
446  // We loop here checking our ancestors until we hit an Fcb which
447  // is either good or bad.
448  //
449 
450  CurrentFcb = Fcb;
451 
453 
454  FatDetermineAndMarkFcbCondition(IrpContext, CurrentFcb);
455 
456  //
457  // If this Fcb didn't make it, or it was the Root Dcb, exit
458  // the loop now, else continue with out parent.
459  //
460 
461  if ( (CurrentFcb->FcbCondition != FcbGood) ||
463 
464  break;
465  }
466 
468  }
469 
470  //
471  // Now we can just look at ourselves to see how we did.
472  //
473 
474  if (Fcb->FcbCondition != FcbGood) {
475 
476  FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
477  }
478 
479  break;
480 
481  default:
482 
483  DebugDump("Invalid FcbCondition\n", 0, Fcb);
484 
485 #ifdef _MSC_VER
486 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
487 #endif
488  FatBugCheck( Fcb->FcbCondition, 0, 0 );
489  }
490 
491  DebugTrace(-1, Dbg, "FatVerifyFcb -> VOID\n", 0);
492 
493  return;
494 }
495 
496 
497 VOID
498 NTAPI
501  )
502 
503 /*++
504 
505 Routine Description:
506 
507  This is the routine that performs the actual FatMarkVolumeClean call.
508  It assures that the target volume still exists as there ia a race
509  condition between queueing the ExWorker item and volumes going away.
510 
511 Arguments:
512 
513  Parameter - Points to a clean volume packet that was allocated from pool
514 
515 Return Value:
516 
517  None.
518 
519 --*/
520 
521 {
523  PLIST_ENTRY Links;
524  PVCB Vcb;
525  IRP_CONTEXT IrpContext;
526  BOOLEAN VcbExists = FALSE;
527 
528  PAGED_CODE();
529 
530  DebugTrace(+1, Dbg, "FatDeferredCleanVolume\n", 0);
531 
533 
534  Vcb = Packet->Vcb;
535 
536  //
537  // Make us appear as a top level FSP request so that we will
538  // receive any errors from the operation.
539  //
540 
542 
543  //
544  // Dummy up and Irp Context so we can call our worker routines
545  //
546 
547  RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));
548 
549  SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
550 
551  //
552  // Acquire shared access to the global lock and make sure this volume
553  // still exists.
554  //
555 
556 #ifdef _MSC_VER
557 #pragma prefast( push )
558 #pragma prefast( disable: 28193, "this will always wait" )
559 #endif
560  FatAcquireSharedGlobal( &IrpContext );
561 #ifdef _MSC_VER
562 #pragma prefast( pop )
563 #endif
564 
565  for (Links = FatData.VcbQueue.Flink;
566  Links != &FatData.VcbQueue;
567  Links = Links->Flink) {
568 
569  PVCB ExistingVcb;
570 
571  ExistingVcb = CONTAINING_RECORD(Links, VCB, VcbLinks);
572 
573  if ( Vcb == ExistingVcb ) {
574 
575  VcbExists = TRUE;
576  break;
577  }
578  }
579 
580  //
581  // If the vcb is good then mark it clean. Ignore any problems.
582  //
583 
584  if ( VcbExists &&
585  (Vcb->VcbCondition == VcbGood) &&
586  !FlagOn(Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN) ) {
587 
588  _SEH2_TRY {
589 
590  if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
591 
592  FatMarkVolume( &IrpContext, Vcb, VolumeClean );
593  }
594 
595  //
596  // Check for a pathological race condition, and fix it.
597  //
598 
599  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY)) {
600 
601  FatMarkVolume( &IrpContext, Vcb, VolumeDirty );
602 
603  } else {
604 
605  //
606  // Unlock the volume if it is removable.
607  //
608 
609  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA) &&
611 
612  FatToggleMediaEjectDisable( &IrpContext, Vcb, FALSE );
613  }
614  }
615 
618 
619  NOTHING;
620  } _SEH2_END;
621  }
622 
623  //
624  // Release the global resource, unpin and repinned Bcbs and return.
625  //
626 
627  FatReleaseGlobal( &IrpContext );
628 
629  _SEH2_TRY {
630 
631  FatUnpinRepinnedBcbs( &IrpContext );
632 
635 
636  NOTHING;
637  } _SEH2_END;
638 
640 
641  //
642  // and finally free the packet.
643  //
644 
645  ExFreePool( Packet );
646 
647  return;
648 }
649 
650 
651 
652 VOID
653 NTAPI
655  _In_ PKDPC Dpc,
659  )
660 
661 /*++
662 
663 Routine Description:
664 
665  This routine is dispatched 5 seconds after the last disk structure was
666  modified in a specific volume, and exqueues an execuative worker thread
667  to perform the actual task of marking the volume dirty.
668 
669 Arguments:
670 
671  DefferedContext - Contains the Vcb to process.
672 
673 Return Value:
674 
675  None.
676 
677 --*/
678 
679 {
680  PVCB Vcb;
682 
686 
688 
689 
690  //
691  // If there is still dirty data (highly unlikely), set the timer for a
692  // second in the future.
693  //
694 
695  if (CcIsThereDirtyData(Vcb->Vpb)) {
696 
697  LARGE_INTEGER TwoSecondsFromNow;
698 
699  TwoSecondsFromNow.QuadPart = (LONG)-2*1000*1000*10;
700 
701  KeSetTimer( &Vcb->CleanVolumeTimer,
702  TwoSecondsFromNow,
703  &Vcb->CleanVolumeDpc );
704 
705  return;
706  }
707 
708  //
709  // If we couldn't get pool, oh well....
710  //
711 
712 #ifndef __REACTOS__
713  Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
714 #else
716 #endif
717 
718  if ( Packet ) {
719 
720  Packet->Vcb = Vcb;
721  Packet->Irp = NULL;
722 
723  //
724  // Clear the dirty flag now since we cannot synchronize after this point.
725  //
726 
727  ClearFlag( Packet->Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY );
728 
730 
731 #ifdef _MSC_VER
732 #pragma prefast( suppress:28159, "prefast indicates this is an obsolete API, but it is ok for fastfat to keep using it" )
733 #endif
735  }
736 
737  return;
738 }
739 
740 
741 _Requires_lock_held_(_Global_critical_region_)
742 VOID
743 FatMarkVolume (
744  IN PIRP_CONTEXT IrpContext,
745  IN PVCB Vcb,
747  )
748 
749 /*++
750 
751 Routine Description:
752 
753  This routine moves the physically marked volume state between the clean
754  and dirty states. For compatibility with Win9x, we manipulate both the
755  historical DOS (on==clean in index 1 of the FAT) and NT (on==dirty in
756  the CurrentHead field of the BPB) dirty bits.
757 
758 Arguments:
759 
760  Vcb - Supplies the Vcb being modified
761 
762  VolumeState - Supplies the state the volume is transitioning to
763 
764 Return Value:
765 
766  None.
767 
768 --*/
769 
770 {
771  PCHAR Sector;
772  PBCB Bcb = NULL;
773  KEVENT Event;
774  PIRP Irp = NULL;
776  BOOLEAN FsInfoUpdate = FALSE;
777  ULONG FsInfoOffset = 0;
778  ULONG ThisPass;
780  BOOLEAN abort = FALSE;
781 
782  DebugTrace(+1, Dbg, "FatMarkVolume, Vcb = %p\n", Vcb);
783 
784  //
785  // We had best not be trying to scribble dirty/clean bits if the
786  // volume is write protected. The responsibility lies with the
787  // callers to make sure that operations that could cause a state
788  // change cannot happen. There are a few, though, that show it
789  // just doesn't make sense to force everyone to do the dinky
790  // check.
791  //
792 
793  //
794  // If we were called for FAT12 or readonly media, return immediately.
795  //
796 
797  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) ||
798  FatIsFat12( Vcb )) {
799 
800  return;
801  }
802 
803  //
804  // We have two possible additional tasks to do to mark a volume
805  //
806  // Pass 0) Flip the dirty bit in the Bpb
807  // Pass 1) Rewrite the FsInfo sector for FAT32 if needed
808  //
809  // In most cases we can collapse these two either because the volume
810  // is either not FAT32 or the FsInfo sector is adjacent to the boot sector.
811  //
812 
813  for (ThisPass = 0; ThisPass < 2; ThisPass++) {
814 
815  //
816  // If this volume is being dirtied, or isn't FAT32, or if it is and
817  // we were able to perform the fast update, or the bpb lied to us
818  // about where the FsInfo went, we're done - no FsInfo to update in
819  // a seperate write.
820  //
821 
822  if (ThisPass == 1 && (!FatIsFat32( Vcb ) ||
824  FsInfoUpdate ||
825  Vcb->Bpb.FsInfoSector == 0)) {
826 
827  break;
828  }
829 
830  //
831  // Bail if we get an IO error.
832  //
833 
834  _SEH2_TRY {
835 
836  ULONG PinLength;
837  ULONG WriteLength;
838 
839  //
840  // If the FAT table is 12-bit then our strategy is to pin the entire
841  // thing when any of it is modified. Here we're going to pin the
842  // first page, so in the 12-bit case we also want to pin the rest
843  // of the FAT table.
844  //
845 
846  Offset.QuadPart = 0;
847 
848  if (Vcb->AllocationSupport.FatIndexBitSize == 12) {
849 
850  //
851  // But we only write back the first sector.
852  //
853 
854  PinLength = FatReservedBytes(&Vcb->Bpb) + FatBytesPerFat(&Vcb->Bpb);
855  WriteLength = Vcb->Bpb.BytesPerSector;
856 
857  } else {
858 
859  WriteLength = PinLength = Vcb->Bpb.BytesPerSector;
860 
861  //
862  // If this is a FAT32 volume going into the clean state,
863  // see about doing the FsInfo sector.
864  //
865 
866  if (FatIsFat32( Vcb ) && VolumeState == VolumeClean) {
867 
868  //
869  // If the FsInfo sector immediately follows the boot sector,
870  // we can do this in a single operation by rewriting both
871  // sectors at once.
872  //
873 
874  if (Vcb->Bpb.FsInfoSector == 1) {
875 
876  NT_ASSERT( ThisPass == 0 );
877 
878  FsInfoUpdate = TRUE;
879  FsInfoOffset = Vcb->Bpb.BytesPerSector;
880  WriteLength = PinLength = Vcb->Bpb.BytesPerSector * 2;
881 
882  } else if (ThisPass == 1) {
883 
884  //
885  // We are doing an explicit write to the FsInfo sector.
886  //
887 
888  FsInfoUpdate = TRUE;
889  FsInfoOffset = 0;
890 
891  Offset.QuadPart = Vcb->Bpb.BytesPerSector * Vcb->Bpb.FsInfoSector;
892  }
893  }
894  }
895 
896  //
897  // Call Cc directly here so that we can avoid overhead and push this
898  // right down to the disk.
899  //
900 
901  CcPinRead( Vcb->VirtualVolumeFile,
902  &Offset,
903  PinLength,
904  TRUE,
905  &Bcb,
906  (PVOID *)&Sector );
907 
908  DbgDoit( IrpContext->PinCount += 1 )
909 
910  //
911  // Set the Bpb on Pass 0 always
912  //
913 
914  if (ThisPass == 0) {
915 
916  PCHAR CurrentHead;
917 
918  //
919  // Before we do anything, doublecheck that this still looks like a
920  // FAT bootsector. If it doesn't, something remarkable happened
921  // and we should avoid touching the volume.
922  //
923  // THIS IS TEMPORARY (but may last a while)
924  //
925 
926  if (!FatIsBootSectorFat( (PPACKED_BOOT_SECTOR) Sector )) {
927  abort = TRUE;
928  _SEH2_LEAVE;
929  }
930 
931  if (FatIsFat32( Vcb )) {
932 
933  CurrentHead = (PCHAR)&((PPACKED_BOOT_SECTOR_EX) Sector)->CurrentHead;
934 
935  } else {
936 
937  CurrentHead = (PCHAR)&((PPACKED_BOOT_SECTOR) Sector)->CurrentHead;
938  }
939 
940  if (VolumeState == VolumeClean) {
941 
942  ClearFlag( *CurrentHead, FAT_BOOT_SECTOR_DIRTY );
943 
944  } else {
945 
946  SetFlag( *CurrentHead, FAT_BOOT_SECTOR_DIRTY );
947 
948  //
949  // In addition, if this request received an error that may indicate
950  // media corruption, have autochk perform a surface test.
951  //
952 
954 
955  SetFlag( *CurrentHead, FAT_BOOT_SECTOR_TEST_SURFACE );
956  }
957  }
958  }
959 
960  //
961  // Update the FsInfo as appropriate.
962  //
963 
964  if (FsInfoUpdate) {
965 
966  PFSINFO_SECTOR FsInfoSector = (PFSINFO_SECTOR) ((PCHAR)Sector + FsInfoOffset);
967 
968  //
969  // We just rewrite all of the spec'd fields. Note that we don't
970  // care to synchronize with the allocation package - this will be
971  // quickly taken care of by a re-dirtying of the volume if a change
972  // is racing with us. Remember that this is all a compatibility
973  // deference for Win9x FAT32 - NT will never look at this information.
974  //
975 
977  FsInfoSector->FsInfoSignature = FSINFO_SIGNATURE;
978  FsInfoSector->FreeClusterCount = Vcb->AllocationSupport.NumberOfFreeClusters;
979  FsInfoSector->NextFreeCluster = Vcb->ClusterHint;
981  }
982 
983  //
984  // Initialize the event we're going to use
985  //
986 
988 
989  //
990  // Build the irp for the operation and also set the override flag.
991  // Note that we may be at APC level, so do this asyncrhonously and
992  // use an event for synchronization as normal request completion
993  // cannot occur at APC level.
994  //
995 
997  Vcb->TargetDeviceObject,
998  (PVOID)Sector,
999  WriteLength,
1000  &Offset,
1001  NULL );
1002 
1003  if ( Irp == NULL ) {
1004 
1006  }
1007 
1008  //
1009  // Make this operation write-through. It never hurts to try to be
1010  // safer about this, even though we aren't logged.
1011  //
1012 
1014 
1015  //
1016  // Set up the completion routine
1017  //
1018 
1021  &Event,
1022  TRUE,
1023  TRUE,
1024  TRUE );
1025 
1026  //
1027  // Call the device to do the write and wait for it to finish.
1028  // Igmore any return status.
1029  //
1030 
1031  Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
1032 
1033  if (Status == STATUS_PENDING) {
1034 
1036  }
1037 
1038  try_exit: NOTHING;
1039  } _SEH2_FINALLY {
1040 
1041  //
1042  // Clean up the Irp and Mdl
1043  //
1044 
1045 
1046  if (Irp) {
1047 
1048  //
1049  // If there is an MDL (or MDLs) associated with this I/O
1050  // request, Free it (them) here. This is accomplished by
1051  // walking the MDL list hanging off of the IRP and deallocating
1052  // each MDL encountered.
1053  //
1054 
1055  while (Irp->MdlAddress != NULL) {
1056 
1057  PMDL NextMdl;
1058 
1059  NextMdl = Irp->MdlAddress->Next;
1060 
1061  MmUnlockPages( Irp->MdlAddress );
1062 
1063  IoFreeMdl( Irp->MdlAddress );
1064 
1065  Irp->MdlAddress = NextMdl;
1066  }
1067 
1068  IoFreeIrp( Irp );
1069  }
1070 
1071  if (Bcb != NULL) {
1072 
1073  FatUnpinBcb( IrpContext, Bcb );
1074  }
1075  } _SEH2_END;
1076  }
1077 
1078  if (!abort) {
1079 
1080  //
1081  // Flip the dirty bit in the FAT
1082  //
1083 
1084  if (VolumeState == VolumeDirty) {
1085 
1086  FatSetFatEntry( IrpContext, Vcb, FAT_DIRTY_BIT_INDEX, FAT_DIRTY_VOLUME);
1087 
1088  } else {
1089 
1090  FatSetFatEntry( IrpContext, Vcb, FAT_DIRTY_BIT_INDEX, FAT_CLEAN_VOLUME);
1091  }
1092  }
1093 
1094  DebugTrace(-1, Dbg, "FatMarkVolume -> VOID\n", 0);
1095 
1096  return;
1097 }
1098 
1099 
1100 VOID
1101 NTAPI
1104  )
1105 
1106 /*++
1107 
1108 Routine Description:
1109 
1110  This is the routine that performs the actual FatMarkVolume Dirty call
1111  on a paging file Io that encounters a media error. It is responsible
1112  for completing the PagingIo Irp as soon as this is done.
1113 
1114  Note: this routine (and thus FatMarkVolume()) must be resident as
1115  the paging file might be damaged at this point.
1116 
1117 Arguments:
1118 
1119  Parameter - Points to a dirty volume packet that was allocated from pool
1120 
1121 Return Value:
1122 
1123  None.
1124 
1125 --*/
1126 
1127 {
1129  PVCB Vcb;
1130  IRP_CONTEXT IrpContext;
1131  PIRP Irp;
1132 
1133  DebugTrace(+1, Dbg, "FatFspMarkVolumeDirtyWithRecover\n", 0);
1134 
1136 
1137  Vcb = Packet->Vcb;
1138  Irp = Packet->Irp;
1139 
1140  //
1141  // Dummy up the IrpContext so we can call our worker routines
1142  //
1143 
1144  RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));
1145 
1146  SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1147  IrpContext.OriginatingIrp = Irp;
1148 
1149  //
1150  // Make us appear as a top level FSP request so that we will
1151  // receive any errors from the operation.
1152  //
1153 
1155 
1156  //
1157  // Try to write out the dirty bit. If something goes wrong, we
1158  // tried.
1159  //
1160 
1161  _SEH2_TRY {
1162 
1164 
1165  FatMarkVolume( &IrpContext, Vcb, VolumeDirtyWithSurfaceTest );
1166 
1168 
1169  NOTHING;
1170  } _SEH2_END;
1171 
1173 
1174  //
1175  // Now complete the originating Irp or set the synchronous event.
1176  //
1177 
1178  if (Packet->Event) {
1179  KeSetEvent( Packet->Event, 0, FALSE );
1180  } else {
1182  }
1183 
1184  DebugTrace(-1, Dbg, "FatFspMarkVolumeDirtyWithRecover -> VOID\n", 0);
1185 }
1186 
1187 
1188 VOID
1190  IN PIRP_CONTEXT IrpContext,
1191  IN PVCB Vcb
1192  )
1193 
1194 /*++
1195 
1196 Routine Description:
1197 
1198  This routine looks at the volume dirty bit, and depending on the state of
1199  VCB_STATE_FLAG_MOUNTED_DIRTY, the appropriate action is taken.
1200 
1201 Arguments:
1202 
1203  Vcb - Supplies the Vcb being queried.
1204 
1205 Return Value:
1206 
1207  None.
1208 
1209 --*/
1210 
1211 {
1212  BOOLEAN Dirty;
1213 
1215  PBCB BootSectorBcb;
1216 
1217  UNICODE_STRING VolumeLabel;
1218 
1219  PAGED_CODE();
1220 
1221  //
1222  // Look in the boot sector
1223  //
1224 
1225  FatReadVolumeFile( IrpContext,
1226  Vcb,
1227  0,
1228  sizeof(PACKED_BOOT_SECTOR),
1229  &BootSectorBcb,
1230  (PVOID *)&BootSector );
1231 
1232  _SEH2_TRY {
1233 
1234  //
1235  // Check if the magic bit is set
1236  //
1237 
1238  if (IsBpbFat32(&BootSector->PackedBpb)) {
1239  Dirty = BooleanFlagOn( ((PPACKED_BOOT_SECTOR_EX)BootSector)->CurrentHead,
1241  } else {
1242  Dirty = BooleanFlagOn( BootSector->CurrentHead, FAT_BOOT_SECTOR_DIRTY );
1243  }
1244 
1245  //
1246  // Setup the VolumeLabel string
1247  //
1248 
1249  VolumeLabel.Length = Vcb->Vpb->VolumeLabelLength;
1251  VolumeLabel.Buffer = &Vcb->Vpb->VolumeLabel[0];
1252 
1253  if ( Dirty ) {
1254 
1255  //
1256  // Do not trigger the mounted dirty bit if this is a verify
1257  // and the volume is a boot or paging device. We know that
1258  // a boot or paging device cannot leave the system, and thus
1259  // that on its mount we will have figured this out correctly.
1260  //
1261  // This logic is a reasonable change. Why?
1262  // 'cause setup cracked a non-exclusive DASD handle near the
1263  // end of setup, wrote some data, closed the handle and we
1264  // set the verify bit ... came back around and saw that other
1265  // arbitrary activity had left the volume in a temporarily dirty
1266  // state.
1267  //
1268  // Of course, the real problem is that we don't have a journal.
1269  //
1270 
1271  if (!(IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1272  IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME &&
1274 
1277  "FASTFAT: WARNING! Mounting Dirty Volume %Z\n",
1278  &VolumeLabel));
1279 
1281  }
1282 
1283  } else {
1284 
1285  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
1286 
1289  "FASTFAT: Volume %Z has been cleaned.\n",
1290  &VolumeLabel));
1291 
1293 
1294  } else {
1295 
1296  (VOID)FsRtlBalanceReads( Vcb->TargetDeviceObject );
1297  }
1298  }
1299 
1300  } _SEH2_FINALLY {
1301 
1302  FatUnpinBcb( IrpContext, BootSectorBcb );
1303  } _SEH2_END;
1304 }
1305 
1306 
1307 VOID
1309  IN PIRP_CONTEXT IrpContext
1310  )
1311 
1312 /*++
1313 
1314 Routine Description:
1315 
1316  This routine determines is the requested operation should be allowed to
1317  continue. It either returns to the user if the request is Okay, or
1318  raises an appropriate status.
1319 
1320 Arguments:
1321 
1322  Irp - Supplies the Irp to check
1323 
1324 Return Value:
1325 
1326  None.
1327 
1328 --*/
1329 
1330 {
1331  PIRP Irp;
1333 
1334  PAGED_CODE();
1335 
1336  Irp = IrpContext->OriginatingIrp;
1337 
1338  //
1339  // If the Irp is not present, then we got here via close.
1340  //
1341  //
1342 
1343  if ( Irp == NULL ) {
1344 
1345  return;
1346  }
1347 
1349 
1350  //
1351  // If there is not a file object, we cannot continue.
1352  //
1353 
1354  if ( FileObject == NULL ) {
1355 
1356  return;
1357  }
1358 
1359  //
1360  // If the file object has already been cleaned up, and
1361  //
1362  // A) This request is a paging io read or write, or
1363  // B) This request is a close operation, or
1364  // C) This request is a set or query info call (for Lou)
1365  // D) This is an MDL complete
1366  //
1367  // let it pass, otherwise return STATUS_FILE_CLOSED.
1368  //
1369 
1370  if ( FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE) ) {
1371 
1373 
1374  if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) ||
1375  (IrpSp->MajorFunction == IRP_MJ_CLOSE ) ||
1378  ( ( (IrpSp->MajorFunction == IRP_MJ_READ) ||
1379  (IrpSp->MajorFunction == IRP_MJ_WRITE) ) &&
1381 
1382  NOTHING;
1383 
1384  } else {
1385 
1386  FatRaiseStatus( IrpContext, STATUS_FILE_CLOSED );
1387  }
1388  }
1389 
1390  return;
1391 }
1392 
1393 
1394 
1395 //
1396 // Internal support routine
1397 //
1398 
1399 VOID
1401  IN PIRP_CONTEXT IrpContext,
1402  IN PFCB Fcb
1403  )
1404 
1405 /*++
1406 
1407 Routine Description:
1408 
1409  This routine is called when an Fcb has been marked as needs to be verified.
1410 
1411  It does the following tasks:
1412 
1413  - Reset Mcb mapping information
1414  - For directories, reset dirent hints
1415  - Set allocation size to unknown
1416 
1417 Arguments:
1418 
1419  Fcb - Supplies the Fcb to reset
1420 
1421 Return Value:
1422 
1423  None.
1424 
1425 --*/
1426 
1427 {
1428  LOGICAL IsRealPagingFile;
1429 
1430  PAGED_CODE();
1431  UNREFERENCED_PARAMETER( IrpContext );
1432 
1433  //
1434  // Don't do the two following operations for the Root Dcb
1435  // of a non FAT32 volume or paging files. Paging files!?
1436  // Yes, if someone diddles a volume we try to reverify all
1437  // of the Fcbs just in case; however, there is no safe way
1438  // to chuck and retrieve the mapping pair information for
1439  // a real paging file. Lose it and die.
1440  //
1441  // An exception is made for ReadyBoost cache files, which
1442  // are created as paging files on removable devices and
1443  // require validation after a power transition.
1444  //
1445 
1448 
1449  IsRealPagingFile = TRUE;
1450 
1451  } else {
1452 
1453  IsRealPagingFile = FALSE;
1454  }
1455 
1456  if ( (NodeType(Fcb) != FAT_NTC_ROOT_DCB ||
1457  FatIsFat32( Fcb->Vcb )) &&
1458  !IsRealPagingFile ) {
1459 
1460  //
1461  // Reset the mcb mapping.
1462  //
1463 
1464  FsRtlRemoveLargeMcbEntry( &Fcb->Mcb, 0, 0xFFFFFFFF );
1465 
1466  //
1467  // Reset the allocation size to 0 or unknown
1468  //
1469 
1470  if ( Fcb->FirstClusterOfFile == 0 ) {
1471 
1472  Fcb->Header.AllocationSize.QuadPart = 0;
1473 
1474  } else {
1475 
1476  Fcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1477  }
1478  }
1479 
1480  //
1481  // If this is a directory, reset the hints.
1482  //
1483 
1484  if ( (NodeType(Fcb) == FAT_NTC_DCB) ||
1485  (NodeType(Fcb) == FAT_NTC_ROOT_DCB) ) {
1486 
1487  //
1488  // Force a rescan of the directory
1489  //
1490 
1491  Fcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
1492  Fcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
1493  }
1494 }
1495 
1496 
1497 
1498 BOOLEAN
1500  __in PIRP_CONTEXT IrpContext,
1502  __in PFCB Fcb
1503  )
1504 {
1505 
1506  UNREFERENCED_PARAMETER(IrpContext);
1507 
1508  if (NodeType(Fcb) != FAT_NTC_FCB) {
1509  return TRUE;
1510  }
1511 
1512 
1513  if (Fcb->Header.FileSize.LowPart != Dirent->FileSize) {
1514  return FALSE;
1515  }
1516 
1517 
1518  return TRUE;
1519 }
1520 
1521 //
1522 // Internal support routine
1523 //
1524 
1525 _Requires_lock_held_(_Global_critical_region_)
1526 VOID
1527 FatDetermineAndMarkFcbCondition (
1528  IN PIRP_CONTEXT IrpContext,
1529  IN PFCB Fcb
1530  )
1531 
1532 /*++
1533 
1534 Routine Description:
1535 
1536  This routine checks a specific Fcb to see if it is different from what's
1537  on the disk. The following things are checked:
1538 
1539  - File Name
1540  - File Size (if not directory)
1541  - First Cluster Of File
1542  - Dirent Attributes
1543 
1544 Arguments:
1545 
1546  Fcb - Supplies the Fcb to examine
1547 
1548 Return Value:
1549 
1550  None.
1551 
1552 --*/
1553 
1554 {
1555  PDIRENT Dirent;
1556  PBCB DirentBcb;
1557  ULONG FirstClusterOfFile;
1558 
1559  OEM_STRING Name;
1560  CHAR Buffer[16];
1561 
1562  PAGED_CODE();
1563 
1564  //
1565  // If this is the Root Dcb, special case it. That is, we know
1566  // by definition that it is good since it is fixed in the volume
1567  // structure.
1568  //
1569 
1570  if ( NodeType(Fcb) == FAT_NTC_ROOT_DCB ) {
1571 
1572  FatMarkFcbCondition( IrpContext, Fcb, FcbGood, FALSE );
1573 
1574  return;
1575  }
1576 
1577  // The first thing we need to do to verify ourselves is
1578  // locate the dirent on the disk.
1579  //
1580 
1581  FatGetDirentFromFcbOrDcb( IrpContext,
1582  Fcb,
1583  TRUE,
1584  &Dirent,
1585  &DirentBcb );
1586  //
1587  // If we couldn't get the dirent, this fcb must be bad (case of
1588  // enclosing directory shrinking during the time it was ejected).
1589  //
1590 
1591  if (DirentBcb == NULL) {
1592 
1593  FatMarkFcbCondition( IrpContext, Fcb, FcbBad, FALSE );
1594 
1595  return;
1596  }
1597 
1598  //
1599  // We located the dirent for ourselves now make sure it
1600  // is really ours by comparing the Name and FatFlags.
1601  // Then for a file we also check the file size.
1602  //
1603  // Note that we have to unpin the Bcb before calling FatResetFcb
1604  // in order to avoid a deadlock in CcUninitializeCacheMap.
1605  //
1606 
1607  _SEH2_TRY {
1608 
1609  Name.MaximumLength = 16;
1610  Name.Buffer = &Buffer[0];
1611 
1612  Fat8dot3ToString( IrpContext, Dirent, FALSE, &Name );
1613 
1614  //
1615  // We need to calculate the first cluster 'cause FAT32 splits
1616  // this field across the dirent.
1617  //
1618 
1619  FirstClusterOfFile = Dirent->FirstClusterOfFile;
1620 
1621  if (FatIsFat32( Fcb->Vcb )) {
1622 
1623  FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
1624  }
1625 
1627 
1628  ||
1629 
1630  !FatMatchFileSize(IrpContext, Dirent, Fcb )
1631 
1632  ||
1633 
1634  (FirstClusterOfFile != Fcb->FirstClusterOfFile)
1635 
1636  ||
1637 
1638  (Dirent->Attributes != Fcb->DirentFatFlags) ) {
1639 
1640  FatMarkFcbCondition( IrpContext, Fcb, FcbBad, FALSE );
1641 
1642  } else {
1643 
1644  //
1645  // We passed. Get the Fcb ready to use again.
1646  //
1647 
1648  FatMarkFcbCondition( IrpContext, Fcb, FcbGood, FALSE );
1649  }
1650 
1651  } _SEH2_FINALLY {
1652 
1653  FatUnpinBcb( IrpContext, DirentBcb );
1654  } _SEH2_END;
1655 
1656  return;
1657 }
1658 
1659 
1660 
1661 //
1662 // Internal support routine
1663 //
1664 
1665 VOID
1667  IN PIRP_CONTEXT IrpContext,
1668  IN PVCB Vcb
1669  )
1670 
1671 /*++
1672 
1673 Routine Description:
1674 
1675  This routines just checks the verify bit in the real device and the
1676  Vcb condition and raises an appropriate exception if so warented.
1677  It is called when verifying both Fcbs and Vcbs.
1678 
1679 Arguments:
1680 
1681  Vcb - Supplies the Vcb to check the condition of.
1682 
1683 Return Value:
1684 
1685  None.
1686 
1687 --*/
1688 
1689 {
1690  PAGED_CODE();
1691 
1692  //
1693  // If the real device needs to be verified we'll set the
1694  // DeviceToVerify to be our real device and raise VerifyRequired.
1695  //
1696 
1697  if (FlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME)) {
1698 
1699  DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
1700 
1701  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1702  Vcb->Vpb->RealDevice );
1703 
1704  FatRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED );
1705  }
1706 
1707  //
1708  // Based on the condition of the Vcb we'll either return to our
1709  // caller or raise an error condition
1710  //
1711 
1712  switch (Vcb->VcbCondition) {
1713 
1714  case VcbGood:
1715 
1716  DebugTrace(0, Dbg, "The Vcb is good\n", 0);
1717 
1718  //
1719  // Do a check here of an operation that would try to modify a
1720  // write protected media.
1721  //
1722 
1723  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) &&
1724  ((IrpContext->MajorFunction == IRP_MJ_WRITE) ||
1725  (IrpContext->MajorFunction == IRP_MJ_SET_INFORMATION) ||
1726  (IrpContext->MajorFunction == IRP_MJ_SET_EA) ||
1727  (IrpContext->MajorFunction == IRP_MJ_FLUSH_BUFFERS) ||
1728  (IrpContext->MajorFunction == IRP_MJ_SET_VOLUME_INFORMATION) ||
1729  (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1730  IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST &&
1731  IoGetCurrentIrpStackLocation(IrpContext->OriginatingIrp)->Parameters.FileSystemControl.FsControlCode ==
1733 
1734  //
1735  // Set the real device for the pop-up info, and set the verify
1736  // bit in the device object, so that we will force a verify
1737  // in case the user put the correct media back in.
1738  //
1739 
1740 
1741  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1742  Vcb->Vpb->RealDevice );
1743 
1745 
1747  }
1748 
1749  break;
1750 
1751  case VcbNotMounted:
1752 
1753  DebugTrace(0, Dbg, "The Vcb is not mounted\n", 0);
1754 
1755  //
1756  // Set the real device for the pop-up info, and set the verify
1757  // bit in the device object, so that we will force a verify
1758  // in case the user put the correct media back in.
1759  //
1760 
1761  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1762  Vcb->Vpb->RealDevice );
1763 
1764  FatRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
1765 
1766  break;
1767 
1768  case VcbBad:
1769 
1770  DebugTrace(0, Dbg, "The Vcb is bad\n", 0);
1771 
1772  if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DISMOUNTED )) {
1773 
1775 
1776  } else {
1777 
1778  FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
1779  }
1780  break;
1781 
1782  default:
1783 
1784  DebugDump("Invalid VcbCondition\n", 0, Vcb);
1785 #ifdef _MSC_VER
1786 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1787 #endif
1788  FatBugCheck( Vcb->VcbCondition, 0, 0 );
1789  }
1790 }
1791 
1792 _Requires_lock_held_(_Global_critical_region_)
1793 NTSTATUS
1794 FatPerformVerify (
1795  _In_ PIRP_CONTEXT IrpContext,
1796  _In_ PIRP Irp,
1798  )
1799 
1800 /*++
1801 
1802 Routine Description:
1803 
1804  This routines performs an IoVerifyVolume operation and takes the
1805  appropriate action. After the Verify is complete the originating
1806  Irp is sent off to an Ex Worker Thread. This routine is called
1807  from the exception handler.
1808 
1809 Arguments:
1810 
1811  Irp - The irp to send off after all is well and done.
1812 
1813  Device - The real device needing verification.
1814 
1815 Return Value:
1816 
1817  None.
1818 
1819 --*/
1820 
1821 {
1822  PVCB Vcb;
1826  BOOLEAN AllowRawMount = FALSE;
1827  BOOLEAN VcbDeleted = FALSE;
1828 
1829  PAGED_CODE();
1830 
1831  //
1832  // Check if this Irp has a status of Verify required and if it does
1833  // then call the I/O system to do a verify.
1834  //
1835  // Skip the IoVerifyVolume if this is a mount or verify request
1836  // itself. Trying a recursive mount will cause a deadlock with
1837  // the DeviceObject->DeviceLock.
1838  //
1839 
1840  if ( (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
1841  ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
1842  (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME)) ) {
1843 
1844  return FatFsdPostRequest( IrpContext, Irp );
1845  }
1846 
1847  DebugTrace(0, Dbg, "Verify Required, DeviceObject = %p\n", Device);
1848 
1849  //
1850  // Extract a pointer to the Vcb from the VolumeDeviceObject.
1851  // Note that since we have specifically excluded mount,
1852  // requests, we know that IrpSp->DeviceObject is indeed a
1853  // volume device object.
1854  //
1855 
1857 
1860  DeviceObject )->Vcb;
1861 
1862  //
1863  // Check if the volume still thinks it needs to be verified,
1864  // if it doesn't then we can skip doing a verify because someone
1865  // else beat us to it.
1866  //
1867 
1868  _SEH2_TRY {
1869 
1870  //
1871  // We will allow Raw to mount this volume if we were doing a
1872  // a DASD open.
1873  //
1874 
1875  if ( (IrpContext->MajorFunction == IRP_MJ_CREATE) &&
1876  (IrpSp->FileObject->FileName.Length == 0) &&
1877  (IrpSp->FileObject->RelatedFileObject == NULL) ) {
1878 
1879  AllowRawMount = TRUE;
1880  }
1881 
1882  //
1883  // Send down the verify. This could be going to a different
1884  // filesystem.
1885  //
1886 
1887  Status = IoVerifyVolume( Device, AllowRawMount );
1888 
1889  //
1890  // If the verify operation completed it will return
1891  // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
1892  //
1893  // If FatVerifyVolume encountered an error during
1894  // processing, it will return that error. If we got
1895  // STATUS_WRONG_VOLUME from the verfy, and our volume
1896  // is now mounted, commute the status to STATUS_SUCCESS.
1897  //
1898  // Acquire the Vcb so we're working with a stable Vcb condition.
1899  //
1900 
1901  FatAcquireSharedVcb(IrpContext, Vcb);
1902 
1903  if ( (Status == STATUS_WRONG_VOLUME) &&
1904  (Vcb->VcbCondition == VcbGood) ) {
1905 
1907  }
1908  else if ((STATUS_SUCCESS == Status) && (Vcb->VcbCondition != VcbGood)) {
1909 
1911  }
1912 
1913  //
1914  // Do a quick unprotected check here. The routine will do
1915  // a safe check. After here we can release the resource.
1916  // Note that if the volume really went away, we will be taking
1917  // the Reparse path.
1918  //
1919 
1920  if ((VcbGood != Vcb->VcbCondition) &&
1921  (0 == Vcb->OpenFileCount) ) {
1922 
1923  FatReleaseVcb( IrpContext, Vcb);
1924 
1925 #ifdef _MSC_VER
1926 #pragma prefast( push )
1927 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
1928 #pragma prefast( disable: 28193 )
1929 #endif
1930  FatAcquireExclusiveGlobal( IrpContext );
1931 #ifdef _MSC_VER
1932 #pragma prefast( pop )
1933 #endif
1934 
1935  FatAcquireExclusiveVcb( IrpContext,
1936  Vcb );
1937 
1938  VcbDeleted = FatCheckForDismount( IrpContext,
1939  Vcb,
1940  FALSE );
1941 
1942  if (!VcbDeleted) {
1943 
1944  FatReleaseVcb( IrpContext,
1945  Vcb );
1946  }
1947 
1948  FatReleaseGlobal( IrpContext );
1949  }
1950  else {
1951 
1952  FatReleaseVcb( IrpContext, Vcb);
1953  }
1954 
1955  //
1956  // If the IopMount in IoVerifyVolume did something, and
1957  // this is an absolute open, force a reparse.
1958  //
1959 
1960  if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
1961  (FileObject->RelatedFileObject == NULL) &&
1963 
1964  Irp->IoStatus.Information = IO_REMOUNT;
1965 
1966  FatCompleteRequest( IrpContext, Irp, STATUS_REPARSE );
1968  Irp = NULL;
1969  }
1970 
1971  if ( (Irp != NULL) && !NT_SUCCESS(Status) ) {
1972 
1973  //
1974  // Fill in the device object if required.
1975  //
1976 
1977  if ( IoIsErrorUserInduced( Status ) ) {
1978 
1980  }
1981 
1983 
1984  FatNormalizeAndRaiseStatus( IrpContext, Status );
1985  }
1986 
1987  //
1988  // If there is still an Irp, send it off to an Ex Worker thread.
1989  //
1990 
1991  if ( Irp != NULL ) {
1992 
1993  Status = FatFsdPostRequest( IrpContext, Irp );
1994  }
1995 
1996  }
1998 
1999  //
2000  // We had some trouble trying to perform the verify or raised
2001  // an error ourselves. So we'll abort the I/O request with
2002  // the error status that we get back from the execption code.
2003  //
2004 
2005  Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
2006  } _SEH2_END;
2007 
2008  return Status;
2009 }
2010 
2011 //
2012 // Local support routine
2013 //
2014 
2015 NTSTATUS
2016 NTAPI
2019  _In_ PIRP Irp,
2020  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
2021  )
2022 
2023 {
2024  //
2025  // Set the event so that our call will wake up.
2026  //
2027 
2028  KeSetEvent( (PKEVENT)Contxt, 0, FALSE );
2029 
2032 
2034 }
2035 
2036 
struct _FCB::@708::@710 Dcb
signed char * PCHAR
Definition: retypes.h:7
ULONG SectorBeginSignature
Definition: fat.h:195
#define DbgDoit(X)
Definition: fatdata.h:336
ULONG FreeClusterCount
Definition: fat.h:198
#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:560
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1987
#define TRUE
Definition: types.h:120
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1627
#define IsBpbFat32(bpb)
Definition: fat.h:101
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2983
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
_Inout_ PFCB * CurrentFcb
Definition: cdprocs.h:806
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:402
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:561
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1240
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
#define IRP_MJ_FLUSH_BUFFERS
PKTHREAD VerifyThread
Definition: fatstruc.h:484
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2621
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FAT_BOOT_SECTOR_DIRTY
Definition: fat.h:213
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
BOOLEAN NTAPI CcIsThereDirtyData(IN PVPB Vpb)
Definition: logsup.c:55
VOID NTAPI FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
Definition: largemcb.c:862
char CHAR
Definition: xmlstorage.h:175
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
#define FatIsFat12(VCB)
Definition: fatprocs.h:1439
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
VOID FatReadVolumeFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer)
Definition: cachesup.c:102
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define IRP_MJ_SET_VOLUME_INFORMATION
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
#define FAT_DIRTY_VOLUME
Definition: fat.h:235
Definition: cdstruc.h:504
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:569
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
NTSTATUS NTAPI FatMarkVolumeCompletionRoutine(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
Definition: verfysup.c:2017
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
STRING OEM_STRING
Definition: umtypes.h:203
_In_ PVOID Parameter
Definition: ldrtypes.h:241
ULONG VcbState
Definition: cdstruc.h:546
#define VCB_STATE_FLAG_VOLUME_DISMOUNTED
Definition: fatstruc.h:571
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
NTSYSAPI BOOLEAN NTAPI RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
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:835
#define FSCTL_MARK_VOLUME_DIRTY
Definition: nt_native.h:838
#define PAGED_CODE()
Definition: video.h:57
#define _In_opt_
Definition: no_sal2.h:213
#define Dbg
Definition: verfysup.c:29
#define Marked(f)
Definition: render.c:146
_SEH2_TRY
Definition: create.c:4250
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
VOID FatQuickVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1666
#define IRP_MN_COMPLETE
Definition: iotypes.h:4064
struct _BootSector BootSector
Definition: vfat.h:108
#define FatReservedBytes(B)
Definition: fat.h:414
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4049
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
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 FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1194
long LONG
Definition: pedump.c:60
BOOLEAN FatMatchFileSize(__in PIRP_CONTEXT IrpContext, __in PDIRENT Dirent, __in PFCB Fcb)
Definition: verfysup.c:1499
#define IRP_MJ_SET_EA
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define FatBytesPerFat(B)
Definition: fat.h:410
UCHAR DirentFatFlags
Definition: fatstruc.h:1132
struct NameRec_ * Name
Definition: cdprocs.h:464
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
BOOLEAN FatIsBootSectorFat(IN PPACKED_BOOT_SECTOR BootSector)
Definition: fsctrl.c:2526
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#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 FAT_CLEAN_VOLUME
Definition: fat.h:234
enum _FCB_CONDITION FCB_CONDITION
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: iotypes.h:154
Definition: bufpool.h:45
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:559
NodeType
Definition: Node.h:5
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
OEM_STRING Oem
Definition: fatstruc.h:692
#define PCHAR
Definition: match.c:90
struct _CLEAN_AND_DIRTY_VOLUME_PACKET * PCLEAN_AND_DIRTY_VOLUME_PACKET
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4048
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
VOID FatCheckDirtyBit(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1189
VOID FatVerifyOperationIsLegal(IN PIRP_CONTEXT IrpContext)
Definition: verfysup.c:1308
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3515
VOID NTAPI FatCleanVolumeDpc(_In_ PKDPC Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
Definition: verfysup.c:654
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4047
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
FAT_DATA FatData
Definition: fatdata.c:56
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define FatAcquireSharedGlobal(IRPCONTEXT)
Definition: fatprocs.h:1382
#define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE
Definition: fatstruc.h:566
VOID NTAPI FatDeferredCleanVolume(_In_ PVOID Parameter)
Definition: verfysup.c:499
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2189
NTSTATUS NTAPI FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice)
Definition: faulttol.c:35
#define IRP_MJ_FILE_SYSTEM_CONTROL
BOOLEAN FatMarkDevForVerifyIfVcbMounted(IN PVCB Vcb)
Definition: verfysup.c:213
#define Vcb
Definition: cdprocs.h:1425
union _FCB::@708 Specific
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
VOID FatVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:270
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
VOID FatResetFcb(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: verfysup.c:1400
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
* PFILE_OBJECT
Definition: iotypes.h:1955
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
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
UNICODE_STRING FullFileName
Definition: fatstruc.h:1121
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
CD_MCB Mcb
Definition: cdstruc.h:1022
VOID FatMarkFcbCondition(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN FCB_CONDITION FcbCondition, IN BOOLEAN Recursive)
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
Definition: ketypes.h:687
#define VOID
Definition: acefi.h:82
union _FILE_NAME_NODE::@707 Name
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
Definition: typedefs.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ULONG NextFreeCluster
Definition: fat.h:199
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define FatIsFat32(VCB)
Definition: fatprocs.h:1437
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define FSINFO_SECTOR_BEGIN_SIGNATURE
Definition: fat.h:204
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
ULONG FsInfoSignature
Definition: fat.h:197
LIST_ENTRY VcbQueue
Definition: fatstruc.h:48
#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 VCB_STATE_FLAG_SHUTDOWN
Definition: fatstruc.h:562
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define FAT_BOOT_SECTOR_TEST_SURFACE
Definition: fat.h:214
_SEH2_END
Definition: create.c:4424
#define FAT_DIRTY_BIT_INDEX
Definition: fat.h:237
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
enum _FAT_VOLUME_STATE FAT_VOLUME_STATE
#define FatAcquireExclusiveVcb(IC, V)
Definition: fatprocs.h:1451
#define FatIsFastIoPossible(FCB)
Definition: fatprocs.h:2801
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1747
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define abort()
Definition: i386-dis.c:35
_SEH2_FINALLY
Definition: create.c:4395
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define FSINFO_SECTOR_END_SIGNATURE
Definition: fat.h:205
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1631
#define IRP_PAGING_IO
#define SL_WRITE_THROUGH
Definition: iotypes.h:1781
#define FAT_NTC_DCB
Definition: nodetype.h:30
ULONG FirstClusterOfFile
Definition: fatstruc.h:817
#define IRP_MJ_READ
Definition: rdpdr.c:46
#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
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:733
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID NTAPI FatFspMarkVolumeDirtyWithRecover(PVOID Parameter)
Definition: verfysup.c:1102
PVCB Vcb
Definition: cdstruc.h:939
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define VCB_STATE_VPB_NOT_ON_DEVICE
Definition: cdstruc.h:720
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
_Requires_lock_held_(_Global_critical_region_)
Definition: verfysup.c:29
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define IO_REMOUNT
Definition: iotypes.h:512
#define _SEH2_LEAVE
Definition: filesup.c:20
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
struct _FSINFO_SECTOR * PFSINFO_SECTOR
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define __in
Definition: dbghelp.h:35
#define FSINFO_SIGNATURE
Definition: fat.h:207
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1114
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:882
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
ULONG SectorEndSignature
Definition: fat.h:201
ULONG FcbState
Definition: cdstruc.h:977
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:112
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
Definition: fatprocs.h:1378
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
#define NT_ASSERT
Definition: rtlfuncs.h:3312
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:518
PFCB FatGetNextFcbTopDown(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2626
FCB_CONDITION FcbCondition
Definition: fatstruc.h:849
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675