ReactOS 0.4.15-dev-7842-g558ab78
verfysup.c File Reference
#include "cdprocs.h"
Include dependency graph for verfysup.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_VERFYSUP)
 

Functions

 _Requires_lock_held_ (_Global_critical_region_)
 
BOOLEAN CdMarkDevForVerifyIfVcbMounted (_Inout_ PVCB Vcb)
 
VOID CdVerifyVcb (_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb)
 
BOOLEAN CdVerifyFcbOperation (_In_opt_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_VERFYSUP)

Definition at line 22 of file verfysup.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 29 of file verfysup.c.

59{
60 PVCB Vcb;
63
64 ASSERT_IRP_CONTEXT( IrpContext );
65 ASSERT_IRP( Irp );
66
67 //
68 // Check if this Irp has a status of Verify required and if it does
69 // then call the I/O system to do a verify.
70 //
71 // Skip the IoVerifyVolume if this is a mount or verify request
72 // itself. Trying a recursive mount will cause a deadlock with
73 // the DeviceObject->DeviceLock.
74 //
75
76 if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
77 ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
78 (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) {
79
80 return CdFsdPostRequest( IrpContext, Irp );
81 }
82
83 //
84 // Extract a pointer to the Vcb from the VolumeDeviceObject.
85 // Note that since we have specifically excluded mount,
86 // requests, we know that IrpSp->DeviceObject is indeed a
87 // volume device object.
88 //
89
91
94 DeviceObject )->Vcb;
95 _SEH2_TRY {
96
97 //
98 // Send down the verify FSCTL. Note that this is sent to the
99 // currently mounted volume, which may not be this one.
100 //
101 // We will allow Raw to mount this volume if we were doing a
102 // an absolute DASD open.
103 //
104
106
107 //
108 // Acquire the Vcb so we're working with a stable VcbCondition.
109 //
110
111 CdAcquireVcbShared( IrpContext, Vcb, FALSE);
112
113 //
114 // If the verify operation completed it will return
115 // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
116 //
117 // If CdVerifyVolume encountered an error during
118 // processing, it will return that error. If we got
119 // STATUS_WRONG_VOLUME from the verify, and our volume
120 // is now mounted, commute the status to STATUS_SUCCESS.
121 //
122
123 if ((Status == STATUS_WRONG_VOLUME) &&
124 (Vcb->VcbCondition == VcbMounted)) {
125
127 }
128 else if ((STATUS_SUCCESS == Status) && (Vcb->VcbCondition != VcbMounted)) {
129
130 //
131 // If the verify succeeded, but our volume is not mounted,
132 // then some other volume is on the device.
133 //
134
136 }
137
138 //
139 // Do a quick unprotected check here. The routine will do
140 // a safe check. After here we can release the resource.
141 // Note that if the volume really went away, we will be taking
142 // the Reparse path.
143 //
144
145 //
146 // If the device might need to go away then call our dismount routine.
147 //
148
149 if (((Vcb->VcbCondition == VcbNotMounted) ||
150 (Vcb->VcbCondition == VcbInvalid) ||
151 (Vcb->VcbCondition == VcbDismountInProgress)) &&
152 (Vcb->VcbReference <= CDFS_RESIDUAL_REFERENCE)) {
153
154 CdReleaseVcb( IrpContext, Vcb);
155
156 CdAcquireCdData( IrpContext );
157 CdCheckForDismount( IrpContext, Vcb, FALSE );
158 CdReleaseCdData( IrpContext );
159 }
160 else {
161
162 CdReleaseVcb( IrpContext, Vcb);
163 }
164
165 //
166 // If this is a create and the verify succeeded then complete the
167 // request with a REPARSE status.
168 //
169
170 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
171 (IrpSp->FileObject->RelatedFileObject == NULL) &&
173
174 Irp->IoStatus.Information = IO_REMOUNT;
175
176 CdCompleteRequest( IrpContext, Irp, STATUS_REPARSE );
178 Irp = NULL;
179 IrpContext = NULL;
180
181 //
182 // If there is still an error to process then call the Io system
183 // for a popup.
184 //
185
186 } else if ((Irp != NULL) && !NT_SUCCESS( Status )) {
187
188 //
189 // Fill in the device object if required.
190 //
191
193
195 }
196
197 CdNormalizeAndRaiseStatus( IrpContext, Status );
198 }
199
200 //
201 // If there is still an Irp, send it off to an Ex Worker thread.
202 //
203
204 if (IrpContext != NULL) {
205
206 Status = CdFsdPostRequest( IrpContext, Irp );
207 }
208
210
211 //
212 // We had some trouble trying to perform the verify or raised
213 // an error ourselves. So we'll abort the I/O request with
214 // the error status that we get back from the execption code.
215 //
216
217 Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
218 } _SEH2_END;
219
220 return Status;
221}
LONG NTSTATUS
Definition: precomp.h:26
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
LONG CdExceptionFilter(_Inout_ PIRP_CONTEXT IrpContext, _In_ PEXCEPTION_POINTERS ExceptionPointer)
Definition: cddata.c:525
#define CDFS_RESIDUAL_REFERENCE
Definition: cddata.h:43
#define ASSERT_IRP(I)
Definition: cddata.h:250
#define ASSERT_IRP_CONTEXT(IC)
Definition: cddata.h:248
#define CdAcquireCdData(IC)
Definition: cdprocs.h:973
static INLINE BOOLEAN CdOperationIsDasdOpen(_In_ PIRP_CONTEXT IrpContext)
Definition: cdprocs.h:1392
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:985
#define CdReleaseCdData(IC)
Definition: cdprocs.h:976
#define CdAcquireVcbShared(IC, V, I)
Definition: cdprocs.h:982
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1409
#define CdNormalizeAndRaiseStatus(IC, S)
Definition: cdprocs.h:1860
@ VcbMounted
Definition: cdstruc.h:492
@ VcbNotMounted
Definition: cdstruc.h:490
@ VcbDismountInProgress
Definition: cdstruc.h:494
@ VcbInvalid
Definition: cdstruc.h:493
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
Definition: cdstruc.h:498
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define IO_REMOUNT
Definition: iotypes.h:544
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404

◆ CdMarkDevForVerifyIfVcbMounted()

BOOLEAN CdMarkDevForVerifyIfVcbMounted ( _Inout_ PVCB  Vcb)

Definition at line 359 of file verfysup.c.

381{
383 KIRQL SavedIrql;
384
385 IoAcquireVpbSpinLock( &SavedIrql );
386
387#ifdef _MSC_VER
388#pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
389#endif
390 if (Vcb->Vpb->RealDevice->Vpb == Vcb->Vpb) {
391
392 CdMarkRealDevForVerify( Vcb->Vpb->RealDevice);
393 Marked = TRUE;
394 }
395 else {
396
397 //
398 // Flag this to avoid the VPB spinlock in future passes.
399 //
400
402 }
403
404 IoReleaseVpbSpinLock( SavedIrql );
405
406 return Marked;
407}
unsigned char BOOLEAN
#define CdMarkRealDevForVerify(DO)
Definition: cdprocs.h:1451
#define VCB_STATE_VPB_NOT_ON_DEVICE
Definition: cdstruc.h:714
#define TRUE
Definition: types.h:120
#define Marked(f)
Definition: render.c:146
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204

Referenced by _Requires_lock_held_(), and CdVerifyVcb().

◆ CdVerifyFcbOperation()

BOOLEAN CdVerifyFcbOperation ( _In_opt_ PIRP_CONTEXT  IrpContext,
_In_ PFCB  Fcb 
)

Definition at line 615 of file verfysup.c.

641{
642 PVCB Vcb = Fcb->Vcb;
643 PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice;
644 PIRP Irp;
645
646 PAGED_CODE();
647
648 //
649 // Check that the fileobject has not been cleaned up.
650 //
651
652 if ( ARGUMENT_PRESENT( IrpContext )) {
653
655
656 Irp = IrpContext->Irp;
658
660
662
663 //
664 // Following FAT, we allow certain operations even on cleaned up
665 // file objects. Everything else, we fail.
666 //
667
668 if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) ||
673
674 NOTHING;
675
676 } else {
677
678 CdRaiseStatus( IrpContext, STATUS_FILE_CLOSED );
679 }
680 }
681 }
682
683 //
684 // Fail immediately if the volume is in the progress of being dismounted
685 // or has been marked invalid.
686 //
687
688 if ((Vcb->VcbCondition == VcbInvalid) ||
689 (Vcb->VcbCondition == VcbDismountInProgress)) {
690
691 if (ARGUMENT_PRESENT( IrpContext )) {
692
693 if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
694
696
697 } else {
698
699 CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
700 }
701 }
702
703 return FALSE;
704 }
705
706 //
707 // Always fail if the volume needs to be verified.
708 //
709
710 if (CdRealDevNeedsVerify( RealDevice)) {
711
712 if (ARGUMENT_PRESENT( IrpContext )) {
713
714 IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
715 RealDevice );
716
718 }
719
720 return FALSE;
721
722 //
723 //
724 // All operations are allowed on mounted.
725 //
726
727 } else if ((Vcb->VcbCondition == VcbMounted) ||
728 (Vcb->VcbCondition == VcbMountInProgress)) {
729
730 return TRUE;
731
732 //
733 // Fail all requests for fast Io on other Vcb conditions.
734 //
735
736 } else if (!ARGUMENT_PRESENT( IrpContext )) {
737
738 return FALSE;
739
740 //
741 // The remaining case is VcbNotMounted.
742 // Mark the device to be verified and raise WRONG_VOLUME.
743 //
744
745 } else if (Vcb->VcbCondition == VcbNotMounted) {
746
747 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice );
748 CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
749
750// return FALSE; // unreachable code
751 }
752
753 return TRUE;
754}
#define PAGED_CODE()
#define CdRealDevNeedsVerify(DO)
Definition: cdprocs.h:1456
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1859
#define VCB_STATE_DISMOUNTED
Definition: cdstruc.h:716
@ VcbMountInProgress
Definition: cdstruc.h:491
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define NOTHING
Definition: input_list.c:10
#define ARGUMENT_PRESENT(ArgumentPointer)
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
PVCB Vcb
Definition: cdstruc.h:933
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_PAGING_IO
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by _Function_class_(), _Requires_lock_held_(), CdCommonLockControl(), CdFastLock(), CdFastUnlockAll(), CdFastUnlockAllByKey(), and CdFastUnlockSingle().

◆ CdVerifyVcb()

VOID CdVerifyVcb ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PVCB  Vcb 
)

Definition at line 411 of file verfysup.c.

436{
439 ULONG MediaChangeCount = 0;
440 BOOLEAN ForceVerify = FALSE;
441 BOOLEAN DevMarkedForVerify;
442
443 PAGED_CODE();
444
445 //
446 // Fail immediately if the volume is in the progress of being dismounted
447 // or has been marked invalid.
448 //
449
450 if ((Vcb->VcbCondition == VcbInvalid) ||
451 ((Vcb->VcbCondition == VcbDismountInProgress) &&
452 (IrpContext->MajorFunction != IRP_MJ_CREATE))) {
453
454 if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
455
457
458 } else {
459
460 CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
461 }
462 }
463
464 //
465 // Capture the real device verify state.
466 //
467
468 DevMarkedForVerify = CdRealDevNeedsVerify( Vcb->Vpb->RealDevice);
469
470 if (FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ) && !DevMarkedForVerify) {
471
472 //
473 // If the media is removable and the verify volume flag in the
474 // device object is not set then we want to ping the device
475 // to see if it needs to be verified.
476 //
477
478 if (Vcb->VcbCondition != VcbMountInProgress) {
479
480 Status = CdPerformDevIoCtrl( IrpContext,
482 Vcb->TargetDeviceObject,
483 &MediaChangeCount,
484 sizeof(ULONG),
485 FALSE,
486 FALSE,
487 &Iosb );
488
489 if (Iosb.Information != sizeof(ULONG)) {
490
491 //
492 // Be safe about the count in case the driver didn't fill it in
493 //
494
495 MediaChangeCount = 0;
496 }
497
498 //
499 // There are four cases when we want to do a verify. These are the
500 // first three.
501 //
502 // 1. We are mounted, and the device has become empty
503 // 2. The device has returned verify required (=> DO_VERIFY_VOL flag is
504 // set, but could be due to hardware condition)
505 // 3. Media change count doesn't match the one in the Vcb
506 //
507
508 if (((Vcb->VcbCondition == VcbMounted) &&
509 CdIsRawDevice( IrpContext, Status ))
510 ||
512 ||
513 (NT_SUCCESS(Status) &&
514 (Vcb->MediaChangeCount != MediaChangeCount))) {
515
516 //
517 // If we are currently the volume on the device then it is our
518 // responsibility to set the verify flag. If we're not on the device,
519 // then we shouldn't touch the flag.
520 //
521
522 if (!FlagOn( Vcb->VcbState, VCB_STATE_VPB_NOT_ON_DEVICE) &&
523 !DevMarkedForVerify) {
524
525 DevMarkedForVerify = CdMarkDevForVerifyIfVcbMounted( Vcb);
526 }
527
528 ForceVerify = TRUE;
529
530 //
531 // NOTE that we no longer update the media change count here. We
532 // do so only when we've actually completed a verify at a particular
533 // change count value.
534 //
535 }
536 }
537
538 //
539 // This is the 4th verify case.
540 //
541 // We ALWAYS force CREATE requests on unmounted volumes through the
542 // verify path. These requests could have been in limbo between
543 // IoCheckMountedVpb and us when a verify/mount took place and caused
544 // a completely different fs/volume to be mounted. In this case the
545 // checks above may not have caught the condition, since we may already
546 // have verified (wrong volume) and decided that we have nothing to do.
547 // We want the requests to be re routed to the currently mounted volume,
548 // since they were directed at the 'drive', not our volume.
549 //
550
551 if (NT_SUCCESS( Status) && !ForceVerify && !DevMarkedForVerify &&
552 (IrpContext->MajorFunction == IRP_MJ_CREATE)) {
553
555
556 ForceVerify = (IrpSp->FileObject->RelatedFileObject == NULL) &&
557 ((Vcb->VcbCondition == VcbDismountInProgress) ||
558 (Vcb->VcbCondition == VcbNotMounted));
559
560 //
561 // Note that we don't touch the device verify flag here. It required
562 // it would have been caught and set by the first set of checks.
563 //
564 }
565 }
566
567 //
568 // Raise the verify / error if neccessary.
569 //
570
571 if (ForceVerify || DevMarkedForVerify || !NT_SUCCESS( Status)) {
572
573 IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
574 Vcb->Vpb->RealDevice );
575
576 CdRaiseStatus( IrpContext, (ForceVerify || DevMarkedForVerify)
578 : Status);
579 }
580
581 //
582 // Based on the condition of the Vcb we'll either return to our
583 // caller or raise an error condition
584 //
585
586 switch (Vcb->VcbCondition) {
587
588 case VcbNotMounted:
589
590 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice );
591
592 CdRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
593 break;
594
595 case VcbInvalid:
597
598 if (FlagOn( Vcb->VcbState, VCB_STATE_DISMOUNTED )) {
599
601
602 } else {
603
604 CdRaiseStatus( IrpContext, STATUS_FILE_INVALID );
605 }
606 break;
607
608 /* ReactOS Change: GCC "enumeration value not handled in switch" */
609 default: break;
610 }
611}
BOOLEAN CdMarkDevForVerifyIfVcbMounted(_Inout_ PVCB Vcb)
Definition: verfysup.c:359
NTSTATUS FASTCALL CdPerformDevIoCtrl(_In_ PIRP_CONTEXT IrpContext, _In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT Device, _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, _In_ BOOLEAN OverrideVerify, _Out_opt_ PIO_STATUS_BLOCK Iosb)
Definition: deviosup.c:1446
#define CdIsRawDevice(IC, S)
Definition: cdprocs.h:1466
#define VCB_STATE_REMOVABLE_MEDIA
Definition: cdstruc.h:710
return Iosb
Definition: create.c:4402
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:103
uint32_t ULONG
Definition: typedefs.h:59

Referenced by CdCommonDevControl(), and CdIsVolumeMounted().