ReactOS  0.4.15-dev-492-ga1108f6
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  Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
713 
714  if ( Packet ) {
715 
716  Packet->Vcb = Vcb;
717  Packet->Irp = NULL;
718 
719  //
720  // Clear the dirty flag now since we cannot synchronize after this point.
721  //
722 
723  ClearFlag( Packet->Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY );
724 
726 
727 #ifdef _MSC_VER
728 #pragma prefast( suppress:28159, "prefast indicates this is an obsolete API, but it is ok for fastfat to keep using it" )
729 #endif
731  }
732 
733  return;
734 }
735 
736 
737 _Requires_lock_held_(_Global_critical_region_)
738 VOID
739 FatMarkVolume (
740  IN PIRP_CONTEXT IrpContext,
741  IN PVCB Vcb,
743  )
744 
745 /*++
746 
747 Routine Description:
748 
749  This routine moves the physically marked volume state between the clean
750  and dirty states. For compatibility with Win9x, we manipulate both the
751  historical DOS (on==clean in index 1 of the FAT) and NT (on==dirty in
752  the CurrentHead field of the BPB) dirty bits.
753 
754 Arguments:
755 
756  Vcb - Supplies the Vcb being modified
757 
758  VolumeState - Supplies the state the volume is transitioning to
759 
760 Return Value:
761 
762  None.
763 
764 --*/
765 
766 {
767  PCHAR Sector;
768  PBCB Bcb = NULL;
769  KEVENT Event;
770  PIRP Irp = NULL;
772  BOOLEAN FsInfoUpdate = FALSE;
773  ULONG FsInfoOffset = 0;
774  ULONG ThisPass;
776  BOOLEAN abort = FALSE;
777 
778  DebugTrace(+1, Dbg, "FatMarkVolume, Vcb = %p\n", Vcb);
779 
780  //
781  // We had best not be trying to scribble dirty/clean bits if the
782  // volume is write protected. The responsibility lies with the
783  // callers to make sure that operations that could cause a state
784  // change cannot happen. There are a few, though, that show it
785  // just doesn't make sense to force everyone to do the dinky
786  // check.
787  //
788 
789  //
790  // If we were called for FAT12 or readonly media, return immediately.
791  //
792 
793  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) ||
794  FatIsFat12( Vcb )) {
795 
796  return;
797  }
798 
799  //
800  // We have two possible additional tasks to do to mark a volume
801  //
802  // Pass 0) Flip the dirty bit in the Bpb
803  // Pass 1) Rewrite the FsInfo sector for FAT32 if needed
804  //
805  // In most cases we can collapse these two either because the volume
806  // is either not FAT32 or the FsInfo sector is adjacent to the boot sector.
807  //
808 
809  for (ThisPass = 0; ThisPass < 2; ThisPass++) {
810 
811  //
812  // If this volume is being dirtied, or isn't FAT32, or if it is and
813  // we were able to perform the fast update, or the bpb lied to us
814  // about where the FsInfo went, we're done - no FsInfo to update in
815  // a seperate write.
816  //
817 
818  if (ThisPass == 1 && (!FatIsFat32( Vcb ) ||
820  FsInfoUpdate ||
821  Vcb->Bpb.FsInfoSector == 0)) {
822 
823  break;
824  }
825 
826  //
827  // Bail if we get an IO error.
828  //
829 
830  _SEH2_TRY {
831 
832  ULONG PinLength;
833  ULONG WriteLength;
834 
835  //
836  // If the FAT table is 12-bit then our strategy is to pin the entire
837  // thing when any of it is modified. Here we're going to pin the
838  // first page, so in the 12-bit case we also want to pin the rest
839  // of the FAT table.
840  //
841 
842  Offset.QuadPart = 0;
843 
844  if (Vcb->AllocationSupport.FatIndexBitSize == 12) {
845 
846  //
847  // But we only write back the first sector.
848  //
849 
850  PinLength = FatReservedBytes(&Vcb->Bpb) + FatBytesPerFat(&Vcb->Bpb);
851  WriteLength = Vcb->Bpb.BytesPerSector;
852 
853  } else {
854 
855  WriteLength = PinLength = Vcb->Bpb.BytesPerSector;
856 
857  //
858  // If this is a FAT32 volume going into the clean state,
859  // see about doing the FsInfo sector.
860  //
861 
862  if (FatIsFat32( Vcb ) && VolumeState == VolumeClean) {
863 
864  //
865  // If the FsInfo sector immediately follows the boot sector,
866  // we can do this in a single operation by rewriting both
867  // sectors at once.
868  //
869 
870  if (Vcb->Bpb.FsInfoSector == 1) {
871 
872  NT_ASSERT( ThisPass == 0 );
873 
874  FsInfoUpdate = TRUE;
875  FsInfoOffset = Vcb->Bpb.BytesPerSector;
876  WriteLength = PinLength = Vcb->Bpb.BytesPerSector * 2;
877 
878  } else if (ThisPass == 1) {
879 
880  //
881  // We are doing an explicit write to the FsInfo sector.
882  //
883 
884  FsInfoUpdate = TRUE;
885  FsInfoOffset = 0;
886 
887  Offset.QuadPart = Vcb->Bpb.BytesPerSector * Vcb->Bpb.FsInfoSector;
888  }
889  }
890  }
891 
892  //
893  // Call Cc directly here so that we can avoid overhead and push this
894  // right down to the disk.
895  //
896 
897  CcPinRead( Vcb->VirtualVolumeFile,
898  &Offset,
899  PinLength,
900  TRUE,
901  &Bcb,
902  (PVOID *)&Sector );
903 
904  DbgDoit( IrpContext->PinCount += 1 )
905 
906  //
907  // Set the Bpb on Pass 0 always
908  //
909 
910  if (ThisPass == 0) {
911 
912  PCHAR CurrentHead;
913 
914  //
915  // Before we do anything, doublecheck that this still looks like a
916  // FAT bootsector. If it doesn't, something remarkable happened
917  // and we should avoid touching the volume.
918  //
919  // THIS IS TEMPORARY (but may last a while)
920  //
921 
922  if (!FatIsBootSectorFat( (PPACKED_BOOT_SECTOR) Sector )) {
923  abort = TRUE;
924  _SEH2_LEAVE;
925  }
926 
927  if (FatIsFat32( Vcb )) {
928 
929  CurrentHead = (PCHAR)&((PPACKED_BOOT_SECTOR_EX) Sector)->CurrentHead;
930 
931  } else {
932 
933  CurrentHead = (PCHAR)&((PPACKED_BOOT_SECTOR) Sector)->CurrentHead;
934  }
935 
936  if (VolumeState == VolumeClean) {
937 
938  ClearFlag( *CurrentHead, FAT_BOOT_SECTOR_DIRTY );
939 
940  } else {
941 
942  SetFlag( *CurrentHead, FAT_BOOT_SECTOR_DIRTY );
943 
944  //
945  // In addition, if this request received an error that may indicate
946  // media corruption, have autochk perform a surface test.
947  //
948 
950 
951  SetFlag( *CurrentHead, FAT_BOOT_SECTOR_TEST_SURFACE );
952  }
953  }
954  }
955 
956  //
957  // Update the FsInfo as appropriate.
958  //
959 
960  if (FsInfoUpdate) {
961 
962  PFSINFO_SECTOR FsInfoSector = (PFSINFO_SECTOR) ((PCHAR)Sector + FsInfoOffset);
963 
964  //
965  // We just rewrite all of the spec'd fields. Note that we don't
966  // care to synchronize with the allocation package - this will be
967  // quickly taken care of by a re-dirtying of the volume if a change
968  // is racing with us. Remember that this is all a compatibility
969  // deference for Win9x FAT32 - NT will never look at this information.
970  //
971 
973  FsInfoSector->FsInfoSignature = FSINFO_SIGNATURE;
974  FsInfoSector->FreeClusterCount = Vcb->AllocationSupport.NumberOfFreeClusters;
975  FsInfoSector->NextFreeCluster = Vcb->ClusterHint;
977  }
978 
979  //
980  // Initialize the event we're going to use
981  //
982 
984 
985  //
986  // Build the irp for the operation and also set the override flag.
987  // Note that we may be at APC level, so do this asyncrhonously and
988  // use an event for synchronization as normal request completion
989  // cannot occur at APC level.
990  //
991 
993  Vcb->TargetDeviceObject,
994  (PVOID)Sector,
995  WriteLength,
996  &Offset,
997  NULL );
998 
999  if ( Irp == NULL ) {
1000 
1002  }
1003 
1004  //
1005  // Make this operation write-through. It never hurts to try to be
1006  // safer about this, even though we aren't logged.
1007  //
1008 
1010 
1011  //
1012  // Set up the completion routine
1013  //
1014 
1017  &Event,
1018  TRUE,
1019  TRUE,
1020  TRUE );
1021 
1022  //
1023  // Call the device to do the write and wait for it to finish.
1024  // Igmore any return status.
1025  //
1026 
1027  Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
1028 
1029  if (Status == STATUS_PENDING) {
1030 
1032  }
1033 
1034  try_exit: NOTHING;
1035  } _SEH2_FINALLY {
1036 
1037  //
1038  // Clean up the Irp and Mdl
1039  //
1040 
1041 
1042  if (Irp) {
1043 
1044  //
1045  // If there is an MDL (or MDLs) associated with this I/O
1046  // request, Free it (them) here. This is accomplished by
1047  // walking the MDL list hanging off of the IRP and deallocating
1048  // each MDL encountered.
1049  //
1050 
1051  while (Irp->MdlAddress != NULL) {
1052 
1053  PMDL NextMdl;
1054 
1055  NextMdl = Irp->MdlAddress->Next;
1056 
1057  MmUnlockPages( Irp->MdlAddress );
1058 
1059  IoFreeMdl( Irp->MdlAddress );
1060 
1061  Irp->MdlAddress = NextMdl;
1062  }
1063 
1064  IoFreeIrp( Irp );
1065  }
1066 
1067  if (Bcb != NULL) {
1068 
1069  FatUnpinBcb( IrpContext, Bcb );
1070  }
1071  } _SEH2_END;
1072  }
1073 
1074  if (!abort) {
1075 
1076  //
1077  // Flip the dirty bit in the FAT
1078  //
1079 
1080  if (VolumeState == VolumeDirty) {
1081 
1082  FatSetFatEntry( IrpContext, Vcb, FAT_DIRTY_BIT_INDEX, FAT_DIRTY_VOLUME);
1083 
1084  } else {
1085 
1086  FatSetFatEntry( IrpContext, Vcb, FAT_DIRTY_BIT_INDEX, FAT_CLEAN_VOLUME);
1087  }
1088  }
1089 
1090  DebugTrace(-1, Dbg, "FatMarkVolume -> VOID\n", 0);
1091 
1092  return;
1093 }
1094 
1095 
1096 VOID
1097 NTAPI
1100  )
1101 
1102 /*++
1103 
1104 Routine Description:
1105 
1106  This is the routine that performs the actual FatMarkVolume Dirty call
1107  on a paging file Io that encounters a media error. It is responsible
1108  for completing the PagingIo Irp as soon as this is done.
1109 
1110  Note: this routine (and thus FatMarkVolume()) must be resident as
1111  the paging file might be damaged at this point.
1112 
1113 Arguments:
1114 
1115  Parameter - Points to a dirty volume packet that was allocated from pool
1116 
1117 Return Value:
1118 
1119  None.
1120 
1121 --*/
1122 
1123 {
1125  PVCB Vcb;
1126  IRP_CONTEXT IrpContext;
1127  PIRP Irp;
1128 
1129  DebugTrace(+1, Dbg, "FatFspMarkVolumeDirtyWithRecover\n", 0);
1130 
1132 
1133  Vcb = Packet->Vcb;
1134  Irp = Packet->Irp;
1135 
1136  //
1137  // Dummy up the IrpContext so we can call our worker routines
1138  //
1139 
1140  RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));
1141 
1142  SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1143  IrpContext.OriginatingIrp = Irp;
1144 
1145  //
1146  // Make us appear as a top level FSP request so that we will
1147  // receive any errors from the operation.
1148  //
1149 
1151 
1152  //
1153  // Try to write out the dirty bit. If something goes wrong, we
1154  // tried.
1155  //
1156 
1157  _SEH2_TRY {
1158 
1160 
1161  FatMarkVolume( &IrpContext, Vcb, VolumeDirtyWithSurfaceTest );
1162 
1164 
1165  NOTHING;
1166  } _SEH2_END;
1167 
1169 
1170  //
1171  // Now complete the originating Irp or set the synchronous event.
1172  //
1173 
1174  if (Packet->Event) {
1175  KeSetEvent( Packet->Event, 0, FALSE );
1176  } else {
1178  }
1179 
1180  DebugTrace(-1, Dbg, "FatFspMarkVolumeDirtyWithRecover -> VOID\n", 0);
1181 }
1182 
1183 
1184 VOID
1186  IN PIRP_CONTEXT IrpContext,
1187  IN PVCB Vcb
1188  )
1189 
1190 /*++
1191 
1192 Routine Description:
1193 
1194  This routine looks at the volume dirty bit, and depending on the state of
1195  VCB_STATE_FLAG_MOUNTED_DIRTY, the appropriate action is taken.
1196 
1197 Arguments:
1198 
1199  Vcb - Supplies the Vcb being queried.
1200 
1201 Return Value:
1202 
1203  None.
1204 
1205 --*/
1206 
1207 {
1208  BOOLEAN Dirty;
1209 
1211  PBCB BootSectorBcb;
1212 
1213  UNICODE_STRING VolumeLabel;
1214 
1215  PAGED_CODE();
1216 
1217  //
1218  // Look in the boot sector
1219  //
1220 
1221  FatReadVolumeFile( IrpContext,
1222  Vcb,
1223  0,
1224  sizeof(PACKED_BOOT_SECTOR),
1225  &BootSectorBcb,
1226  (PVOID *)&BootSector );
1227 
1228  _SEH2_TRY {
1229 
1230  //
1231  // Check if the magic bit is set
1232  //
1233 
1234  if (IsBpbFat32(&BootSector->PackedBpb)) {
1235  Dirty = BooleanFlagOn( ((PPACKED_BOOT_SECTOR_EX)BootSector)->CurrentHead,
1237  } else {
1238  Dirty = BooleanFlagOn( BootSector->CurrentHead, FAT_BOOT_SECTOR_DIRTY );
1239  }
1240 
1241  //
1242  // Setup the VolumeLabel string
1243  //
1244 
1245  VolumeLabel.Length = Vcb->Vpb->VolumeLabelLength;
1247  VolumeLabel.Buffer = &Vcb->Vpb->VolumeLabel[0];
1248 
1249  if ( Dirty ) {
1250 
1251  //
1252  // Do not trigger the mounted dirty bit if this is a verify
1253  // and the volume is a boot or paging device. We know that
1254  // a boot or paging device cannot leave the system, and thus
1255  // that on its mount we will have figured this out correctly.
1256  //
1257  // This logic is a reasonable change. Why?
1258  // 'cause setup cracked a non-exclusive DASD handle near the
1259  // end of setup, wrote some data, closed the handle and we
1260  // set the verify bit ... came back around and saw that other
1261  // arbitrary activity had left the volume in a temporarily dirty
1262  // state.
1263  //
1264  // Of course, the real problem is that we don't have a journal.
1265  //
1266 
1267  if (!(IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1268  IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME &&
1270 
1273  "FASTFAT: WARNING! Mounting Dirty Volume %Z\n",
1274  &VolumeLabel));
1275 
1277  }
1278 
1279  } else {
1280 
1281  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
1282 
1285  "FASTFAT: Volume %Z has been cleaned.\n",
1286  &VolumeLabel));
1287 
1289 
1290  } else {
1291 
1292  (VOID)FsRtlBalanceReads( Vcb->TargetDeviceObject );
1293  }
1294  }
1295 
1296  } _SEH2_FINALLY {
1297 
1298  FatUnpinBcb( IrpContext, BootSectorBcb );
1299  } _SEH2_END;
1300 }
1301 
1302 
1303 VOID
1305  IN PIRP_CONTEXT IrpContext
1306  )
1307 
1308 /*++
1309 
1310 Routine Description:
1311 
1312  This routine determines is the requested operation should be allowed to
1313  continue. It either returns to the user if the request is Okay, or
1314  raises an appropriate status.
1315 
1316 Arguments:
1317 
1318  Irp - Supplies the Irp to check
1319 
1320 Return Value:
1321 
1322  None.
1323 
1324 --*/
1325 
1326 {
1327  PIRP Irp;
1329 
1330  PAGED_CODE();
1331 
1332  Irp = IrpContext->OriginatingIrp;
1333 
1334  //
1335  // If the Irp is not present, then we got here via close.
1336  //
1337  //
1338 
1339  if ( Irp == NULL ) {
1340 
1341  return;
1342  }
1343 
1345 
1346  //
1347  // If there is not a file object, we cannot continue.
1348  //
1349 
1350  if ( FileObject == NULL ) {
1351 
1352  return;
1353  }
1354 
1355  //
1356  // If the file object has already been cleaned up, and
1357  //
1358  // A) This request is a paging io read or write, or
1359  // B) This request is a close operation, or
1360  // C) This request is a set or query info call (for Lou)
1361  // D) This is an MDL complete
1362  //
1363  // let it pass, otherwise return STATUS_FILE_CLOSED.
1364  //
1365 
1366  if ( FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE) ) {
1367 
1369 
1370  if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) ||
1371  (IrpSp->MajorFunction == IRP_MJ_CLOSE ) ||
1374  ( ( (IrpSp->MajorFunction == IRP_MJ_READ) ||
1375  (IrpSp->MajorFunction == IRP_MJ_WRITE) ) &&
1377 
1378  NOTHING;
1379 
1380  } else {
1381 
1382  FatRaiseStatus( IrpContext, STATUS_FILE_CLOSED );
1383  }
1384  }
1385 
1386  return;
1387 }
1388 
1389 
1390 
1391 //
1392 // Internal support routine
1393 //
1394 
1395 VOID
1397  IN PIRP_CONTEXT IrpContext,
1398  IN PFCB Fcb
1399  )
1400 
1401 /*++
1402 
1403 Routine Description:
1404 
1405  This routine is called when an Fcb has been marked as needs to be verified.
1406 
1407  It does the following tasks:
1408 
1409  - Reset Mcb mapping information
1410  - For directories, reset dirent hints
1411  - Set allocation size to unknown
1412 
1413 Arguments:
1414 
1415  Fcb - Supplies the Fcb to reset
1416 
1417 Return Value:
1418 
1419  None.
1420 
1421 --*/
1422 
1423 {
1424  LOGICAL IsRealPagingFile;
1425 
1426  PAGED_CODE();
1427  UNREFERENCED_PARAMETER( IrpContext );
1428 
1429  //
1430  // Don't do the two following operations for the Root Dcb
1431  // of a non FAT32 volume or paging files. Paging files!?
1432  // Yes, if someone diddles a volume we try to reverify all
1433  // of the Fcbs just in case; however, there is no safe way
1434  // to chuck and retrieve the mapping pair information for
1435  // a real paging file. Lose it and die.
1436  //
1437  // An exception is made for ReadyBoost cache files, which
1438  // are created as paging files on removable devices and
1439  // require validation after a power transition.
1440  //
1441 
1444 
1445  IsRealPagingFile = TRUE;
1446 
1447  } else {
1448 
1449  IsRealPagingFile = FALSE;
1450  }
1451 
1452  if ( (NodeType(Fcb) != FAT_NTC_ROOT_DCB ||
1453  FatIsFat32( Fcb->Vcb )) &&
1454  !IsRealPagingFile ) {
1455 
1456  //
1457  // Reset the mcb mapping.
1458  //
1459 
1460  FsRtlRemoveLargeMcbEntry( &Fcb->Mcb, 0, 0xFFFFFFFF );
1461 
1462  //
1463  // Reset the allocation size to 0 or unknown
1464  //
1465 
1466  if ( Fcb->FirstClusterOfFile == 0 ) {
1467 
1468  Fcb->Header.AllocationSize.QuadPart = 0;
1469 
1470  } else {
1471 
1472  Fcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1473  }
1474  }
1475 
1476  //
1477  // If this is a directory, reset the hints.
1478  //
1479 
1480  if ( (NodeType(Fcb) == FAT_NTC_DCB) ||
1481  (NodeType(Fcb) == FAT_NTC_ROOT_DCB) ) {
1482 
1483  //
1484  // Force a rescan of the directory
1485  //
1486 
1487  Fcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
1488  Fcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
1489  }
1490 }
1491 
1492 
1493 
1494 BOOLEAN
1496  __in PIRP_CONTEXT IrpContext,
1498  __in PFCB Fcb
1499  )
1500 {
1501 
1502  UNREFERENCED_PARAMETER(IrpContext);
1503 
1504  if (NodeType(Fcb) != FAT_NTC_FCB) {
1505  return TRUE;
1506  }
1507 
1508 
1509  if (Fcb->Header.FileSize.LowPart != Dirent->FileSize) {
1510  return FALSE;
1511  }
1512 
1513 
1514  return TRUE;
1515 }
1516 
1517 //
1518 // Internal support routine
1519 //
1520 
1521 _Requires_lock_held_(_Global_critical_region_)
1522 VOID
1523 FatDetermineAndMarkFcbCondition (
1524  IN PIRP_CONTEXT IrpContext,
1525  IN PFCB Fcb
1526  )
1527 
1528 /*++
1529 
1530 Routine Description:
1531 
1532  This routine checks a specific Fcb to see if it is different from what's
1533  on the disk. The following things are checked:
1534 
1535  - File Name
1536  - File Size (if not directory)
1537  - First Cluster Of File
1538  - Dirent Attributes
1539 
1540 Arguments:
1541 
1542  Fcb - Supplies the Fcb to examine
1543 
1544 Return Value:
1545 
1546  None.
1547 
1548 --*/
1549 
1550 {
1551  PDIRENT Dirent;
1552  PBCB DirentBcb;
1553  ULONG FirstClusterOfFile;
1554 
1555  OEM_STRING Name;
1556  CHAR Buffer[16];
1557 
1558  PAGED_CODE();
1559 
1560  //
1561  // If this is the Root Dcb, special case it. That is, we know
1562  // by definition that it is good since it is fixed in the volume
1563  // structure.
1564  //
1565 
1566  if ( NodeType(Fcb) == FAT_NTC_ROOT_DCB ) {
1567 
1568  FatMarkFcbCondition( IrpContext, Fcb, FcbGood, FALSE );
1569 
1570  return;
1571  }
1572 
1573  // The first thing we need to do to verify ourselves is
1574  // locate the dirent on the disk.
1575  //
1576 
1577  FatGetDirentFromFcbOrDcb( IrpContext,
1578  Fcb,
1579  TRUE,
1580  &Dirent,
1581  &DirentBcb );
1582  //
1583  // If we couldn't get the dirent, this fcb must be bad (case of
1584  // enclosing directory shrinking during the time it was ejected).
1585  //
1586 
1587  if (DirentBcb == NULL) {
1588 
1589  FatMarkFcbCondition( IrpContext, Fcb, FcbBad, FALSE );
1590 
1591  return;
1592  }
1593 
1594  //
1595  // We located the dirent for ourselves now make sure it
1596  // is really ours by comparing the Name and FatFlags.
1597  // Then for a file we also check the file size.
1598  //
1599  // Note that we have to unpin the Bcb before calling FatResetFcb
1600  // in order to avoid a deadlock in CcUninitializeCacheMap.
1601  //
1602 
1603  _SEH2_TRY {
1604 
1605  Name.MaximumLength = 16;
1606  Name.Buffer = &Buffer[0];
1607 
1608  Fat8dot3ToString( IrpContext, Dirent, FALSE, &Name );
1609 
1610  //
1611  // We need to calculate the first cluster 'cause FAT32 splits
1612  // this field across the dirent.
1613  //
1614 
1615  FirstClusterOfFile = Dirent->FirstClusterOfFile;
1616 
1617  if (FatIsFat32( Fcb->Vcb )) {
1618 
1619  FirstClusterOfFile += Dirent->FirstClusterOfFileHi << 16;
1620  }
1621 
1623 
1624  ||
1625 
1626  !FatMatchFileSize(IrpContext, Dirent, Fcb )
1627 
1628  ||
1629 
1630  (FirstClusterOfFile != Fcb->FirstClusterOfFile)
1631 
1632  ||
1633 
1634  (Dirent->Attributes != Fcb->DirentFatFlags) ) {
1635 
1636  FatMarkFcbCondition( IrpContext, Fcb, FcbBad, FALSE );
1637 
1638  } else {
1639 
1640  //
1641  // We passed. Get the Fcb ready to use again.
1642  //
1643 
1644  FatMarkFcbCondition( IrpContext, Fcb, FcbGood, FALSE );
1645  }
1646 
1647  } _SEH2_FINALLY {
1648 
1649  FatUnpinBcb( IrpContext, DirentBcb );
1650  } _SEH2_END;
1651 
1652  return;
1653 }
1654 
1655 
1656 
1657 //
1658 // Internal support routine
1659 //
1660 
1661 VOID
1663  IN PIRP_CONTEXT IrpContext,
1664  IN PVCB Vcb
1665  )
1666 
1667 /*++
1668 
1669 Routine Description:
1670 
1671  This routines just checks the verify bit in the real device and the
1672  Vcb condition and raises an appropriate exception if so warented.
1673  It is called when verifying both Fcbs and Vcbs.
1674 
1675 Arguments:
1676 
1677  Vcb - Supplies the Vcb to check the condition of.
1678 
1679 Return Value:
1680 
1681  None.
1682 
1683 --*/
1684 
1685 {
1686  PAGED_CODE();
1687 
1688  //
1689  // If the real device needs to be verified we'll set the
1690  // DeviceToVerify to be our real device and raise VerifyRequired.
1691  //
1692 
1693  if (FlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME)) {
1694 
1695  DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
1696 
1697  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1698  Vcb->Vpb->RealDevice );
1699 
1700  FatRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED );
1701  }
1702 
1703  //
1704  // Based on the condition of the Vcb we'll either return to our
1705  // caller or raise an error condition
1706  //
1707 
1708  switch (Vcb->VcbCondition) {
1709 
1710  case VcbGood:
1711 
1712  DebugTrace(0, Dbg, "The Vcb is good\n", 0);
1713 
1714  //
1715  // Do a check here of an operation that would try to modify a
1716  // write protected media.
1717  //
1718 
1719  if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) &&
1720  ((IrpContext->MajorFunction == IRP_MJ_WRITE) ||
1721  (IrpContext->MajorFunction == IRP_MJ_SET_INFORMATION) ||
1722  (IrpContext->MajorFunction == IRP_MJ_SET_EA) ||
1723  (IrpContext->MajorFunction == IRP_MJ_FLUSH_BUFFERS) ||
1724  (IrpContext->MajorFunction == IRP_MJ_SET_VOLUME_INFORMATION) ||
1725  (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1726  IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST &&
1727  IoGetCurrentIrpStackLocation(IrpContext->OriginatingIrp)->Parameters.FileSystemControl.FsControlCode ==
1729 
1730  //
1731  // Set the real device for the pop-up info, and set the verify
1732  // bit in the device object, so that we will force a verify
1733  // in case the user put the correct media back in.
1734  //
1735 
1736 
1737  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1738  Vcb->Vpb->RealDevice );
1739 
1741 
1743  }
1744 
1745  break;
1746 
1747  case VcbNotMounted:
1748 
1749  DebugTrace(0, Dbg, "The Vcb is not mounted\n", 0);
1750 
1751  //
1752  // Set the real device for the pop-up info, and set the verify
1753  // bit in the device object, so that we will force a verify
1754  // in case the user put the correct media back in.
1755  //
1756 
1757  IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1758  Vcb->Vpb->RealDevice );
1759 
1760  FatRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
1761 
1762  break;
1763 
1764  case VcbBad:
1765 
1766  DebugTrace(0, Dbg, "The Vcb is bad\n", 0);
1767 
1768  if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DISMOUNTED )) {
1769 
1771 
1772  } else {
1773 
1774  FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
1775  }
1776  break;
1777 
1778  default:
1779 
1780  DebugDump("Invalid VcbCondition\n", 0, Vcb);
1781 #ifdef _MSC_VER
1782 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1783 #endif
1784  FatBugCheck( Vcb->VcbCondition, 0, 0 );
1785  }
1786 }
1787 
1788 _Requires_lock_held_(_Global_critical_region_)
1789 NTSTATUS
1790 FatPerformVerify (
1791  _In_ PIRP_CONTEXT IrpContext,
1792  _In_ PIRP Irp,
1794  )
1795 
1796 /*++
1797 
1798 Routine Description:
1799 
1800  This routines performs an IoVerifyVolume operation and takes the
1801  appropriate action. After the Verify is complete the originating
1802  Irp is sent off to an Ex Worker Thread. This routine is called
1803  from the exception handler.
1804 
1805 Arguments:
1806 
1807  Irp - The irp to send off after all is well and done.
1808 
1809  Device - The real device needing verification.
1810 
1811 Return Value:
1812 
1813  None.
1814 
1815 --*/
1816 
1817 {
1818  PVCB Vcb;
1822  BOOLEAN AllowRawMount = FALSE;
1823  BOOLEAN VcbDeleted = FALSE;
1824 
1825  PAGED_CODE();
1826 
1827  //
1828  // Check if this Irp has a status of Verify required and if it does
1829  // then call the I/O system to do a verify.
1830  //
1831  // Skip the IoVerifyVolume if this is a mount or verify request
1832  // itself. Trying a recursive mount will cause a deadlock with
1833  // the DeviceObject->DeviceLock.
1834  //
1835 
1836  if ( (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
1837  ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
1838  (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME)) ) {
1839 
1840  return FatFsdPostRequest( IrpContext, Irp );
1841  }
1842 
1843  DebugTrace(0, Dbg, "Verify Required, DeviceObject = %p\n", Device);
1844 
1845  //
1846  // Extract a pointer to the Vcb from the VolumeDeviceObject.
1847  // Note that since we have specifically excluded mount,
1848  // requests, we know that IrpSp->DeviceObject is indeed a
1849  // volume device object.
1850  //
1851 
1853 
1856  DeviceObject )->Vcb;
1857 
1858  //
1859  // Check if the volume still thinks it needs to be verified,
1860  // if it doesn't then we can skip doing a verify because someone
1861  // else beat us to it.
1862  //
1863 
1864  _SEH2_TRY {
1865 
1866  //
1867  // We will allow Raw to mount this volume if we were doing a
1868  // a DASD open.
1869  //
1870 
1871  if ( (IrpContext->MajorFunction == IRP_MJ_CREATE) &&
1872  (IrpSp->FileObject->FileName.Length == 0) &&
1873  (IrpSp->FileObject->RelatedFileObject == NULL) ) {
1874 
1875  AllowRawMount = TRUE;
1876  }
1877 
1878  //
1879  // Send down the verify. This could be going to a different
1880  // filesystem.
1881  //
1882 
1883  Status = IoVerifyVolume( Device, AllowRawMount );
1884 
1885  //
1886  // If the verify operation completed it will return
1887  // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
1888  //
1889  // If FatVerifyVolume encountered an error during
1890  // processing, it will return that error. If we got
1891  // STATUS_WRONG_VOLUME from the verfy, and our volume
1892  // is now mounted, commute the status to STATUS_SUCCESS.
1893  //
1894  // Acquire the Vcb so we're working with a stable Vcb condition.
1895  //
1896 
1897  FatAcquireSharedVcb(IrpContext, Vcb);
1898 
1899  if ( (Status == STATUS_WRONG_VOLUME) &&
1900  (Vcb->VcbCondition == VcbGood) ) {
1901 
1903  }
1904  else if ((STATUS_SUCCESS == Status) && (Vcb->VcbCondition != VcbGood)) {
1905 
1907  }
1908 
1909  //
1910  // Do a quick unprotected check here. The routine will do
1911  // a safe check. After here we can release the resource.
1912  // Note that if the volume really went away, we will be taking
1913  // the Reparse path.
1914  //
1915 
1916  if ((VcbGood != Vcb->VcbCondition) &&
1917  (0 == Vcb->OpenFileCount) ) {
1918 
1919  FatReleaseVcb( IrpContext, Vcb);
1920 
1921 #ifdef _MSC_VER
1922 #pragma prefast( push )
1923 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" )
1924 #pragma prefast( disable: 28193 )
1925 #endif
1926  FatAcquireExclusiveGlobal( IrpContext );
1927 #ifdef _MSC_VER
1928 #pragma prefast( pop )
1929 #endif
1930 
1931  FatAcquireExclusiveVcb( IrpContext,
1932  Vcb );
1933 
1934  VcbDeleted = FatCheckForDismount( IrpContext,
1935  Vcb,
1936  FALSE );
1937 
1938  if (!VcbDeleted) {
1939 
1940  FatReleaseVcb( IrpContext,
1941  Vcb );
1942  }
1943 
1944  FatReleaseGlobal( IrpContext );
1945  }
1946  else {
1947 
1948  FatReleaseVcb( IrpContext, Vcb);
1949  }
1950 
1951  //
1952  // If the IopMount in IoVerifyVolume did something, and
1953  // this is an absolute open, force a reparse.
1954  //
1955 
1956  if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
1957  (FileObject->RelatedFileObject == NULL) &&
1959 
1960  Irp->IoStatus.Information = IO_REMOUNT;
1961 
1962  FatCompleteRequest( IrpContext, Irp, STATUS_REPARSE );
1964  Irp = NULL;
1965  }
1966 
1967  if ( (Irp != NULL) && !NT_SUCCESS(Status) ) {
1968 
1969  //
1970  // Fill in the device object if required.
1971  //
1972 
1973  if ( IoIsErrorUserInduced( Status ) ) {
1974 
1976  }
1977 
1979 
1980  FatNormalizeAndRaiseStatus( IrpContext, Status );
1981  }
1982 
1983  //
1984  // If there is still an Irp, send it off to an Ex Worker thread.
1985  //
1986 
1987  if ( Irp != NULL ) {
1988 
1989  Status = FatFsdPostRequest( IrpContext, Irp );
1990  }
1991 
1992  }
1994 
1995  //
1996  // We had some trouble trying to perform the verify or raised
1997  // an error ourselves. So we'll abort the I/O request with
1998  // the error status that we get back from the execption code.
1999  //
2000 
2001  Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
2002  } _SEH2_END;
2003 
2004  return Status;
2005 }
2006 
2007 //
2008 // Local support routine
2009 //
2010 
2011 NTSTATUS
2012 NTAPI
2015  _In_ PIRP Irp,
2016  _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt
2017  )
2018 
2019 {
2020  //
2021  // Set the event so that our call will wake up.
2022  //
2023 
2024  KeSetEvent( (PKEVENT)Contxt, 0, FALSE );
2025 
2028 
2030 }
2031 
2032 
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:39
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:1996
#define TRUE
Definition: types.h:120
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1636
#define IsBpbFat32(bpb)
Definition: fat.h:101
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2992
#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:801
union _FILE_NAME_NODE::@710 Name
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:411
#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:2029
_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:2630
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
struct _FCB::@711::@713 Dcb
#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:1448
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:2013
#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:2974
#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 _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:4226
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
VOID FatQuickVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1662
#define IRP_MN_COMPLETE
Definition: iotypes.h:4066
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:4051
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IO_DISK_INCREMENT
Definition: iotypes.h:570
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:1495
#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:459
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:437
BOOLEAN FatIsBootSectorFat(IN PPACKED_BOOT_SECTOR BootSector)
Definition: fsctrl.c:2522
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
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:156
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:588
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:4050
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
VOID FatCheckDirtyBit(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1185
VOID FatVerifyOperationIsLegal(IN PIRP_CONTEXT IrpContext)
Definition: verfysup.c:1304
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3495
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:4049
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:511
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:1391
#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:2179
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:1415
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:2869
VOID FatResetFcb(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: verfysup.c:1396
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
* PFILE_OBJECT
Definition: iotypes.h:1957
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
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
Definition: typedefs.h:118
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
union _FCB::@711 Specific
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:1446
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:1569
__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:2815
#define FAT_BOOT_SECTOR_TEST_SURFACE
Definition: fat.h:214
_SEH2_END
Definition: create.c:4400
#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:1460
#define FatIsFastIoPossible(FCB)
Definition: fatprocs.h:2810
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1749
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define abort()
Definition: i386-dis.c:35
_SEH2_FINALLY
Definition: create.c:4371
#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:1640
#define IRP_PAGING_IO
#define SL_WRITE_THROUGH
Definition: iotypes.h:1783
#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:1495
#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:424
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID NTAPI FatFspMarkVolumeDirtyWithRecover(PVOID Parameter)
Definition: verfysup.c:1098
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:514
#define _SEH2_LEAVE
Definition: filesup.c:20
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2774
_In_ PFCB Fcb
Definition: cdprocs.h:159
struct _FSINFO_SECTOR * PFSINFO_SECTOR
return STATUS_SUCCESS
Definition: btrfs.c:3014
#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:113
#define FatAcquireExclusiveGlobal(IRPCONTEXT)
Definition: fatprocs.h:1387
#define PAGED_CODE()
#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:2615
FCB_CONDITION FcbCondition
Definition: fatstruc.h:849
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675