test: udfs/verfysup.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# verfysup.c File Reference

`#include "UdfProcs.h"`

Go to the source code of this file.

## Defines

#define | BugCheckFileId (UDFS_BUG_CHECK_VERFYSUP)
#define | Dbg (UDFS_DEBUG_LEVEL_VERFYSUP)

## Functions

NTSTATUS | UdfPerformVerify (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
BOOLEAN | UdfCheckForDismount (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN Force)
BOOLEAN | UdfDismountVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
VOID | UdfVerifyVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
BOOLEAN | UdfVerifyFcbOperation (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PFCB Fcb)

## Define Documentation

#define BugCheckFileId (UDFS_BUG_CHECK_VERFYSUP)

| Definition at line 27 of file udfs/verfysup.c.

#define Dbg (UDFS_DEBUG_LEVEL_VERFYSUP)

| Definition at line 33 of file udfs/verfysup.c.

## Function Documentation

BOOLEAN UdfCheckForDismount | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PVCB | Vcb,
|  | IN BOOLEAN | Force
| ) |

Definition at line 236 of file udfs/verfysup.c.

References ASSERT_EXCLUSIVE_UDFDATA, ASSERT_IRP_CONTEXT, ASSERT_VCB, FALSE, IoAcquireVpbSpinLock(), IoReleaseVpbSpinLock(), TRUE, UdfAcquireVcbExclusive, UdfDeleteVcb(), UdfDismountVcb(), UdfFspClose(), UdfLockVcb, UdfReleaseVcb, UdfUnlockVcb, and VcbDismountInProgress.

Referenced by UdfCommonClose(), UdfFspClose(), UdfInvalidateVolumes(), UdfPerformVerify(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfScanForDismountedVcb(), and UdfVerifyVolume().

    00244                    :
    00245
    00246     This routine is called to check if a volume is ready for dismount.  This
    00247     occurs when only file system references are left on the volume.
    00248
    00249     If the dismount is not currently underway and the user reference count
    00250     has gone to zero then we can begin the dismount.
    00251
    00252     If the dismount is in progress and there are no references left on the
    00253     volume (we check the Vpb for outstanding references as well to catch
    00254     any create calls dispatched to the file system) then we can delete
    00255     the Vcb.
    00256
    00257 Arguments:
    00258
    00259     Vcb - Vcb for the volume to try to dismount.
    00260
    00261     Force - Whether we will force this volume to be dismounted.
    00262
    00263 Return Value:
    00264
    00265     BOOLEAN - True if the Vcb was not gone by the time this function finished,
    00266         False if it was deleted.
    00267
    00268     This is only a trustworthy indication to the caller if it had the vcb
    00269     exclusive itself.
    00270
    00271 --*/
    00272
    00273 {
    00274     BOOLEAN UnlockVcb = TRUE;
    00275     BOOLEAN VcbPresent = TRUE;
    00276     KIRQL SavedIrql;
    00277
    00278     ASSERT_IRP_CONTEXT( IrpContext );
    00279     ASSERT_VCB( Vcb );
    00280
    00281     ASSERT_EXCLUSIVE_UDFDATA;
    00282
    00283     //
    00284     //  Acquire and lock this Vcb to check the dismount state.
    00285     //
    00286
    00287     UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE );
    00288
    00289     //
    00290     //  Lets get rid of any pending closes for this volume.
    00291     //
    00292
    00293     UdfFspClose( Vcb );
    00294
    00295     UdfLockVcb( IrpContext, Vcb );
    00296
    00297     //
    00298     //  If the dismount is not already underway then check if the
    00299     //  user reference count has gone to zero or we are being forced
    00300     //  to disconnect.  If so start the teardown on the Vcb.
    00301     //
    00302
    00303     if (Vcb->VcbCondition != VcbDismountInProgress) {
    00304
    00305         if (Vcb->VcbUserReference <= Vcb->VcbResidualUserReference || Force) {
    00306
    00307             UdfUnlockVcb( IrpContext, Vcb );
    00308             UnlockVcb = FALSE;
    00309             VcbPresent = UdfDismountVcb( IrpContext, Vcb );
    00310         }
    00311
    00312     //
    00313     //  If the teardown is underway and there are absolutely no references
    00314     //  remaining then delete the Vcb.  References here include the
    00315     //  references in the Vcb and Vpb.
    00316     //
    00317
    00318     } else if (Vcb->VcbReference == 0) {
    00319
    00320         IoAcquireVpbSpinLock( &SavedIrql );
    00321
    00322         //
    00323         //  If there are no file objects and no reference counts in the
    00324         //  Vpb we can delete the Vcb.  Don't forget that we have the
    00325         //  last reference in the Vpb.
    00326         //
    00327
    00328         if (Vcb->Vpb->ReferenceCount == 1) {
    00329
    00330             IoReleaseVpbSpinLock( SavedIrql );
    00331             UdfUnlockVcb( IrpContext, Vcb );
    00332             UnlockVcb = FALSE;
    00333             UdfDeleteVcb( IrpContext, Vcb );
    00334             VcbPresent = FALSE;
    00335
    00336         } else {
    00337
    00338             IoReleaseVpbSpinLock( SavedIrql );
    00339         }
    00340     }
    00341
    00342     //
    00343     //  Unlock the Vcb if still held.
    00344     //
    00345
    00346     if (UnlockVcb) {
    00347
    00348         UdfUnlockVcb( IrpContext, Vcb );
    00349     }
    00350
    00351     //
    00352     //  Release any resources still acquired.
    00353     //
    00354
    00355     if (VcbPresent) {
    00356
    00357         UdfReleaseVcb( IrpContext, Vcb );
    00358     }
    00359
    00360     return VcbPresent;
    00361 }

BOOLEAN UdfDismountVcb | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PVCB | Vcb
| ) |

Definition at line 365 of file udfs/verfysup.c.

References ASSERT, ASSERT_EXCLUSIVE_UDFDATA, ASSERT_EXCLUSIVE_VCB, ClearFlag, _VPB::DeviceObject, ExAllocatePoolWithTag, FALSE, FlagOn, _VPB::Flags, IO_TYPE_VPB, IoAcquireVpbSpinLock(), IoReleaseVpbSpinLock(), NonPagedPoolMustSucceed, NULL, _VPB::RealDevice, _VPB::ReferenceCount, _VPB::Size, TAG_VPB, TRUE, _VPB::Type, UdfDeleteVcb(), UdfFreePool(), UdfFspClose(), UdfLockVcb, UdfPurgeVolume(), UdfUnlockVcb, VcbDismountInProgress, _DEVICE_OBJECT::Vpb, VPB, VPB_MOUNTED, and VPB_REMOVE_PENDING.

Referenced by UdfCheckForDismount(), and UdfMountVolume().

    00372                    :
    00373
    00374     This routine is called when all of the user references to a volume are
    00375     gone.  We will initiate all of the teardown any system resources.
    00376
    00377     If all of the references to this volume are gone at the end of this routine
    00378     then we will complete the teardown of this Vcb and mark the current Vpb
    00379     as not mounted.  Otherwise we will allocated a new Vpb for this device
    00380     and keep the current Vpb attached to the Vcb.
    00381
    00382 Arguments:
    00383
    00384     Vcb - Vcb for the volume to dismount.
    00385
    00386 Return Value:
    00387
    00388     BOOLEAN - TRUE if we didn't delete the Vcb, FALSE otherwise.
    00389
    00390 --*/
    00391
    00392 {
    00393     PVPB OldVpb;
    00394     PVPB NewVpb;
    00395     BOOLEAN VcbPresent = TRUE;
    00396     KIRQL SavedIrql;
    00397
    00398     BOOLEAN FinalReference;
    00399
    00400     ASSERT_EXCLUSIVE_UDFDATA;
    00401     ASSERT_EXCLUSIVE_VCB( Vcb );
    00402
    00403     UdfLockVcb( IrpContext, Vcb );
    00404
    00405     //
    00406     //  We should only take this path once.
    00407     //
    00408
    00409     ASSERT( Vcb->VcbCondition != VcbDismountInProgress );
    00410
    00411     //
    00412     //  Mark the Vcb as DismountInProgress.
    00413     //
    00414
    00415     Vcb->VcbCondition = VcbDismountInProgress;
    00416
    00417     //
    00418     //  Remove our reference to the internal Fcb's.  The Fcb's will then
    00419     //  be removed in the purge path below.
    00420     //
    00421
    00422     if (Vcb->RootIndexFcb != NULL) {
    00423
    00424         Vcb->RootIndexFcb->FcbReference -= 1;
    00425         Vcb->RootIndexFcb->FcbUserReference -= 1;
    00426     }
    00427
    00428     if (Vcb->MetadataFcb != NULL) {
    00429
    00430         Vcb->MetadataFcb->FcbReference -= 1;
    00431         Vcb->MetadataFcb->FcbUserReference -= 1;
    00432     }
    00433
    00434     if (Vcb->VatFcb != NULL) {
    00435
    00436         Vcb->VatFcb->FcbReference -= 1;
    00437         Vcb->VatFcb->FcbUserReference -= 1;
    00438     }
    00439
    00440     if (Vcb->VolumeDasdFcb != NULL) {
    00441
    00442         Vcb->VolumeDasdFcb->FcbReference -= 1;
    00443         Vcb->VolumeDasdFcb->FcbUserReference -= 1;
    00444     }
    00445
    00446     UdfUnlockVcb( IrpContext, Vcb );
    00447
    00448     //
    00449     //  Purge the volume.
    00450     //
    00451
    00452     UdfPurgeVolume( IrpContext, Vcb, TRUE );
    00453
    00454     //
    00455     //  Empty the delayed and async close queues.
    00456     //
    00457
    00458     UdfFspClose( Vcb );
    00459
    00460     //
    00461     //  Allocate a new Vpb in case we will need it.
    00462     //
    00463
    00464     NewVpb = ExAllocatePoolWithTag( NonPagedPoolMustSucceed, sizeof( VPB ), TAG_VPB );
    00465     RtlZeroMemory( NewVpb, sizeof( VPB ) );
    00466
    00467     OldVpb = Vcb->Vpb;
    00468
    00469     //
    00470     //  Remove the mount volume reference.
    00471     //
    00472
    00473     UdfLockVcb( IrpContext, Vcb );
    00474     Vcb->VcbReference -= 1;
    00475
    00476     //
    00477     //  Acquire the Vpb spinlock to check for Vpb references.
    00478     //
    00479
    00480     IoAcquireVpbSpinLock( &SavedIrql );
    00481
    00482     //
    00483     //  Remember if this is the last reference on this Vcb.  We incremented
    00484     //  the count on the Vpb earlier so we get one last crack it.  If our
    00485     //  reference has gone to zero but the vpb reference count is greater
    00486     //  than zero then the Io system will be responsible for deleting the
    00487     //  Vpb.
    00488     //
    00489
    00490     FinalReference = (BOOLEAN) ((Vcb->VcbReference == 0) &&
    00491                                 (OldVpb->ReferenceCount == 1));
    00492
    00493     //
    00494     //  There is a reference count in the Vpb and in the Vcb.  We have
    00495     //  incremented the reference count in the Vpb to make sure that
    00496     //  we have last crack at it.  If this is a failed mount then we
    00497     //  want to return the Vpb to the IO system to use for the next
    00498     //  mount request.
    00499     //
    00500
    00501     if (OldVpb->RealDevice->Vpb == OldVpb) {
    00502
    00503         //
    00504         //  If not the final reference then swap out the Vpb.  We must
    00505         //  preserve the REMOVE_PENDING flag so that the device is
    00506         //  not remounted in the middle of a PnP remove operation.
    00507         //
    00508
    00509         if (!FinalReference) {
    00510
    00511             NewVpb->Type = IO_TYPE_VPB;
    00512             NewVpb->Size = sizeof( VPB );
    00513             NewVpb->RealDevice = OldVpb->RealDevice;
    00514
    00515             NewVpb->RealDevice->Vpb = NewVpb;
    00516
    00517             NewVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING );
    00518
    00519             NewVpb = NULL;
    00520             IoReleaseVpbSpinLock( SavedIrql );
    00521             UdfUnlockVcb( IrpContext, Vcb );
    00522
    00523         //
    00524         //  We want to leave the Vpb for the IO system.  Mark it
    00525         //  as being not mounted.  Go ahead and delete the Vcb as
    00526         //  well.
    00527         //
    00528
    00529         } else {
    00530
    00531             //
    00532             //  Make sure to remove the last reference on the Vpb.
    00533             //
    00534
    00535             OldVpb->ReferenceCount -= 1;
    00536
    00537             OldVpb->DeviceObject = NULL;
    00538             ClearFlag( Vcb->Vpb->Flags, VPB_MOUNTED );
    00539
    00540             //
    00541             //  Clear the Vpb flag so we know not to delete it.
    00542             //
    00543
    00544             Vcb->Vpb = NULL;
    00545
    00546             IoReleaseVpbSpinLock( SavedIrql );
    00547             UdfUnlockVcb( IrpContext, Vcb );
    00548             UdfDeleteVcb( IrpContext, Vcb );
    00549             VcbPresent = FALSE;
    00550         }
    00551
    00552     //
    00553     //  Someone has already swapped in a new Vpb.  If this is the final reference
    00554     //  then the file system is responsible for deleting the Vpb.
    00555     //
    00556
    00557     } else if (FinalReference) {
    00558
    00559         //
    00560         //  Make sure to remove the last reference on the Vpb.
    00561         //
    00562
    00563         OldVpb->ReferenceCount -= 1;
    00564
    00565         IoReleaseVpbSpinLock( SavedIrql );
    00566         UdfUnlockVcb( IrpContext, Vcb );
    00567         UdfDeleteVcb( IrpContext, Vcb );
    00568         VcbPresent = FALSE;
    00569
    00570     //
    00571     //  The current Vpb is no longer the Vpb for the device (the IO system
    00572     //  has already allocated a new one).  We leave our reference in the
    00573     //  Vpb and will be responsible for deleting it at a later time.
    00574     //
    00575
    00576     } else {
    00577
    00578         OldVpb->DeviceObject = NULL;
    00579         ClearFlag( Vcb->Vpb->Flags, VPB_MOUNTED );
    00580
    00581         IoReleaseVpbSpinLock( SavedIrql );
    00582         UdfUnlockVcb( IrpContext, Vcb );
    00583     }
    00584
    00585     //
    00586     //  Deallocate the new Vpb if we don't need it.
    00587     //
    00588
    00589     if (NewVpb != NULL) {
    00590
    00591         UdfFreePool( &NewVpb );
    00592     }
    00593
    00594     //
    00595     //  Let our caller know whether the Vcb is still present.
    00596     //
    00597
    00598     return VcbPresent;
    00599 }

NTSTATUS UdfPerformVerify | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PIRP | Irp,
|  | IN PDEVICE_OBJECT | DeviceToVerify
| ) |

Definition at line 42 of file udfs/verfysup.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, _IO_STACK_LOCATION::DeviceObject, DO_VERIFY_VOLUME, FALSE, _FILE_OBJECT::FileName, _IO_STACK_LOCATION::FileObject, FlagOn, IO_REMOUNT, IoGetCurrentIrpStackLocation, IoIsErrorUserInduced, IoSetHardErrorOrVerifyDevice(), _IRP::IoStatus, IoVerifyVolume(), Irp, IRP_MJ_CREATE, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_MOUNT_VOLUME, IRP_MN_VERIFY_VOLUME, NT_SUCCESS, NTSTATUS(), NULL, _FILE_OBJECT::RelatedFileObject, Status, TRUE, UdfAcquireUdfData, UdfCheckForDismount(), UdfCompleteRequest(), UdfExceptionFilter(), UdfFsdPostRequest(), UdfNormalizeAndRaiseStatus(), UdfProcessException(), UdfReleaseUdfData, _VCB::VcbCondition, VcbDismountInProgress, VcbInvalid, VcbMounted, VcbNotMounted, _VCB::VcbReference, and _VCB::VcbResidualReference.

Referenced by UdfProcessException().

    00050                    :
    00051
    00052     This routines performs an IoVerifyVolume operation and takes the
    00053     appropriate action.  If the verify is successful then we send the originating
    00054     Irp off to an Ex Worker Thread.  This routine is called from the exception handler.
    00055
    00056     No file system resources are held when this routine is called.
    00057
    00058 Arguments:
    00059
    00060     Irp - The irp to send off after all is well and done.
    00061
    00062     Device - The real device needing verification.
    00063
    00064 Return Value:
    00065
    00066     None.
    00067
    00068 --*/
    00069
    00070 {
    00071     PVCB Vcb;
    00072     NTSTATUS Status = STATUS_SUCCESS;
    00073     PIO_STACK_LOCATION IrpSp;
    00074
    00075     ASSERT_IRP_CONTEXT( IrpContext );
    00076     ASSERT_IRP( Irp );
    00077
    00078     //
    00079     //  Check if this Irp has a status of Verify required and if it does
    00080     //  then call the I/O system to do a verify.
    00081     //
    00082     //  Skip the IoVerifyVolume if this is a mount or verify request
    00083     //  itself.  Trying a recursive mount will cause a deadlock with
    00084     //  the DeviceObject->DeviceLock.
    00085     //
    00086
    00087     if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
    00088         ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
    00089          (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) {
    00090
    00091         return UdfFsdPostRequest( IrpContext, Irp );
    00092     }
    00093
    00094     //
    00095     //  Extract a pointer to the Vcb from the VolumeDeviceObject.
    00096     //  Note that since we have specifically excluded mount,
    00097     //  requests, we know that IrpSp->DeviceObject is indeed a
    00098     //  volume device object.
    00099     //
    00100
    00101     IrpSp = IoGetCurrentIrpStackLocation( Irp );
    00102
    00103     Vcb = &CONTAINING_RECORD( IrpSp->DeviceObject,
    00104                               VOLUME_DEVICE_OBJECT,
    00105                               DeviceObject )->Vcb;
    00106
    00107     //
    00108     //  Check if the volume still thinks it needs to be verified,
    00109     //  if it doesn't then we can skip doing a verify because someone
    00110     //  else beat us to it.
    00111     //
    00112
    00113     try {
    00114
    00115         if (FlagOn( DeviceToVerify->Flags, DO_VERIFY_VOLUME )) {
    00116
    00117             BOOLEAN AllowRawMount = FALSE;
    00118
    00119             //
    00120             //  We will allow Raw to mount this volume if we were doing a
    00121             //  an absolute DASD open.
    00122             //
    00123
    00124             if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
    00125                 (IrpSp->FileObject->FileName.Length == 0) &&
    00126                 (IrpSp->FileObject->RelatedFileObject == NULL)) {
    00127
    00128                 AllowRawMount = TRUE;
    00129             }
    00130
    00131             //
    00132             //  If the IopMount in IoVerifyVolume did something, and
    00133             //  this is an absolute open, force a reparse.
    00134             //
    00135
    00136             Status = IoVerifyVolume( DeviceToVerify, AllowRawMount );
    00137
    00138             //
    00139             //  If the verify operation completed it will return
    00140             //  either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
    00141             //
    00142             //  If UdfVerifyVolume encountered an error during
    00143             //  processing, it will return that error.  If we got
    00144             //  STATUS_WRONG_VOLUME from the verify, and our volume
    00145             //  is now mounted, commute the status to STATUS_SUCCESS.
    00146             //
    00147
    00148             if ((Status == STATUS_WRONG_VOLUME) &&
    00149                 (Vcb->VcbCondition == VcbMounted)) {
    00150
    00151                 Status = STATUS_SUCCESS;
    00152             }
    00153
    00154             //
    00155             //  Do a quick unprotected check here.  The routine will do
    00156             //  a safe check.  After here we can release the resource.
    00157             //  Note that if the volume really went away, we will be taking
    00158             //  the Reparse path.
    00159             //
    00160
    00161             //
    00162             //  If the device might need to go away then call our dismount routine.
    00163             //
    00164
    00165             if (((Vcb->VcbCondition == VcbNotMounted) ||
    00166                  (Vcb->VcbCondition == VcbInvalid) ||
    00167                  (Vcb->VcbCondition == VcbDismountInProgress)) &&
    00168                 (Vcb->VcbReference <= Vcb->VcbResidualReference)) {
    00169
    00170                 UdfAcquireUdfData( IrpContext );
    00171                 UdfCheckForDismount( IrpContext, Vcb, FALSE );
    00172                 UdfReleaseUdfData( IrpContext );
    00173             }
    00174
    00175             //
    00176             //  If this is a create and the verify succeeded then complete the
    00177             //  request with a REPARSE status.
    00178             //
    00179
    00180             if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
    00181                 (IrpSp->FileObject->RelatedFileObject == NULL) &&
    00182                 ((Status == STATUS_SUCCESS) || (Status == STATUS_WRONG_VOLUME))) {
    00183
    00184                 Irp->IoStatus.Information = IO_REMOUNT;
    00185
    00186                 UdfCompleteRequest( IrpContext, Irp, STATUS_REPARSE );
    00187                 Status = STATUS_REPARSE;
    00188                 Irp = NULL;
    00189                 IrpContext = NULL;
    00190
    00191             //
    00192             //  If there is still an error to process then call the Io system
    00193             //  for a popup.
    00194             //
    00195
    00196             } else if ((Irp != NULL) && !NT_SUCCESS( Status )) {
    00197
    00198                 //
    00199                 //  Fill in the device object if required.
    00200                 //
    00201
    00202                 if (IoIsErrorUserInduced( Status ) ) {
    00203
    00204                     IoSetHardErrorOrVerifyDevice( Irp, DeviceToVerify );
    00205                 }
    00206
    00207                 UdfNormalizeAndRaiseStatus( IrpContext, Status );
    00208             }
    00209         }
    00210
    00211         //
    00212         //  If there is still an Irp, send it off to an Ex Worker thread.
    00213         //
    00214
    00215         if (IrpContext != NULL) {
    00216
    00217             Status = UdfFsdPostRequest( IrpContext, Irp );
    00218         }
    00219
    00220     } except(UdfExceptionFilter( IrpContext, GetExceptionInformation() )) {
    00221
    00222         //
    00223         //  We had some trouble trying to perform the verify or raised
    00224         //  an error ourselves.  So we'll abort the I/O request with
    00225         //  the error status that we get back from the execption code.
    00226         //
    00227
    00228         Status = UdfProcessException( IrpContext, Irp, GetExceptionCode() );
    00229     }
    00230
    00231     return Status;
    00232 }

BOOLEAN UdfVerifyFcbOperation | ( | IN PIRP_CONTEXT IrpContext | OPTIONAL,
|  | IN PFCB | Fcb
| ) |

Definition at line 760 of file udfs/verfysup.c.

References DO_VERIFY_VOLUME, FALSE, FlagOn, _DEVICE_OBJECT::Flags, IoSetHardErrorOrVerifyDevice(), NTSTATUS(), PAGED_CODE, _VPB::RealDevice, SetFlag, Status, TRUE, UdfRaiseStatus(), _VCB::VcbCondition, VcbDismountInProgress, VcbInvalid, VcbMounted, VcbMountInProgress, VcbNotMounted, and _VCB::Vpb.

Referenced by UdfCommonLockControl(), UdfCommonQueryInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfFastLock(), UdfFastQueryBasicInfo(), UdfFastQueryNetworkInfo(), UdfFastQueryStdInfo(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfOplockRequest(), and UdfQueryDirectory().

    00767                    :
    00768
    00769     This routine is called to verify that the state of the Fcb is valid
    00770     to allow the current operation to continue.  We use the state of the
    00771     Vcb, target device and type of operation to determine this.
    00772
    00773 Arguments:
    00774
    00775     IrpContext - IrpContext for the request.  If not present then we
    00776         were called from the fast IO path.
    00777
    00778     Fcb - Fcb to perform the request on.
    00779
    00780 Return Value:
    00781
    00782     BOOLEAN - TRUE if the request can continue, FALSE otherwise.
    00783
    00784 --*/
    00785
    00786 {
    00787     NTSTATUS Status = STATUS_SUCCESS;
    00788     PVCB Vcb = Fcb->Vcb;
    00789     PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice;
    00790
    00791     PAGED_CODE();
    00792
    00793     //
    00794     //  Fail immediately if the volume is in the progress of being dismounted
    00795     //  or has been marked invalid.
    00796     //
    00797
    00798     if ((Vcb->VcbCondition == VcbInvalid) ||
    00799         (Vcb->VcbCondition == VcbDismountInProgress)) {
    00800
    00801         if (ARGUMENT_PRESENT( IrpContext )) {
    00802
    00803             UdfRaiseStatus( IrpContext, STATUS_FILE_INVALID );
    00804         }
    00805
    00806         return FALSE;
    00807     }
    00808
    00809     //
    00810     //  Always fail if the volume needs to be verified.
    00811     //
    00812
    00813     if (FlagOn( RealDevice->Flags, DO_VERIFY_VOLUME )) {
    00814
    00815         if (ARGUMENT_PRESENT( IrpContext )) {
    00816
    00817             IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
    00818                                           RealDevice );
    00819
    00820             UdfRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED );
    00821         }
    00822
    00823         return FALSE;
    00824
    00825     //
    00826     //  All operations are allowed on mounted volumes.
    00827     //
    00828
    00829     } else if ((Vcb->VcbCondition == VcbMounted) ||
    00830                (Vcb->VcbCondition == VcbMountInProgress)) {
    00831
    00832         return TRUE;
    00833
    00834     //
    00835     //  Fail all requests for fast Io on other Vcb conditions.
    00836     //
    00837
    00838     } else if (!ARGUMENT_PRESENT( IrpContext )) {
    00839
    00840         return FALSE;
    00841
    00842     //
    00843     //  The remaining case is VcbNotMounted.
    00844     //  Mark the device to be verified and raise WRONG_VOLUME.
    00845     //
    00846
    00847     } else if (Vcb->VcbCondition == VcbNotMounted) {
    00848
    00849         if (ARGUMENT_PRESENT( IrpContext )) {
    00850
    00851             SetFlag(RealDevice->Flags, DO_VERIFY_VOLUME);
    00852
    00853             IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice );
    00854             UdfRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
    00855         }
    00856
    00857         return FALSE;
    00858     }
    00859
    00860     return TRUE;
    00861 }

VOID UdfVerifyVcb | ( | IN PIRP_CONTEXT | IrpContext,
|  | IN PVCB | Vcb
| ) |

Definition at line 603 of file udfs/verfysup.c.

References DO_VERIFY_VOLUME, FALSE, FlagOn, IoSetHardErrorOrVerifyDevice(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, SetFlag, Status, UdfIsRawDevice, UdfNormalizeAndRaiseStatus(), UdfPerformDevIoCtrl(), UdfRaiseStatus(), VCB_STATE_REMOVABLE_MEDIA, VcbDismountInProgress, VcbInvalid, VcbMounted, VcbMountInProgress, VcbNotMounted, and VOID().

Referenced by UdfCommonCreate(), UdfCommonDevControl(), UdfCommonQueryVolInfo(), UdfIsVolumeMounted(), UdfLockVolume(), and UdfNotifyChangeDirectory().

    00610                    :
    00611
    00612     This routine checks that the current Vcb is valid and currently mounted
    00613     on the device.  It will raise on an error condition.
    00614
    00615     We check whether the volume needs verification and the current state
    00616     of the Vcb.
    00617
    00618 Arguments:
    00619
    00620     Vcb - This is the volume to verify.
    00621
    00622 Return Value:
    00623
    00624     None
    00625
    00626 --*/
    00627
    00628 {
    00629     NTSTATUS Status;
    00630     IO_STATUS_BLOCK Iosb;
    00631     ULONG MediaChangeCount = 0;
    00632
    00633     PAGED_CODE();
    00634
    00635     //
    00636     //  Fail immediately if the volume is in the progress of being dismounted
    00637     //  or has been marked invalid.
    00638     //
    00639
    00640     if ((Vcb->VcbCondition == VcbInvalid) ||
    00641         (Vcb->VcbCondition == VcbDismountInProgress)) {
    00642
    00643         UdfRaiseStatus( IrpContext, STATUS_FILE_INVALID );
    00644     }
    00645
    00646     //
    00647     //  If the media is removable and the verify volume flag in the
    00648     //  device object is not set then we want to ping the device
    00649     //  to see if it needs to be verified
    00650     //
    00651
    00652     if ((Vcb->VcbCondition != VcbMountInProgress) &&
    00653         FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ) &&
    00654         !FlagOn( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME )) {
    00655
    00656         Status = UdfPerformDevIoCtrl( IrpContext,
    00657                                       ( Vcb->Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM ?
    00658                                         IOCTL_CDROM_CHECK_VERIFY :
    00659                                         IOCTL_DISK_CHECK_VERIFY ),
    00660                                       Vcb->TargetDeviceObject,
    00661                                       &MediaChangeCount,
    00662                                       sizeof(ULONG),
    00663                                       FALSE,
    00664                                       FALSE,
    00665                                       &Iosb );
    00666
    00667         if (Iosb.Information != sizeof(ULONG)) {
    00668
    00669             //
    00670             //  Be safe about the count in case the driver didn't fill it in
    00671             //
    00672
    00673             MediaChangeCount = 0;
    00674         }
    00675
    00676         //
    00677         //  If the volume is now an empty device, or we have receieved a
    00678         //  bare STATUS_VERIFY_REQUIRED (various hardware conditions such
    00679         //  as bus resets, etc., will trigger this in the drivers), or the
    00680         //  media change count has moved since we last inspected the device,
    00681         //  then mark the volume to be verified.
    00682         //
    00683
    00684         if ((Vcb->VcbCondition == VcbMounted &&
    00685              UdfIsRawDevice( IrpContext, Status )) ||
    00686             (Status == STATUS_VERIFY_REQUIRED) ||
    00687             (NT_SUCCESS(Status) &&
    00688              (Vcb->MediaChangeCount != MediaChangeCount))) {
    00689
    00690             SetFlag( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME );
    00691
    00692             //
    00693             //  If the volume is not mounted and we got a media change count,
    00694             //  update the Vcb so we do not trigger a verify again at this
    00695             //  count value.  If the verify->mount path detects that the media
    00696             //  has actually changed and this Vcb is valid again, this will have
    00697             //  done nothing.  We are already synchronized since the caller has
    00698             //  the Vcb.
    00699             //
    00700
    00701             if ((Vcb->VcbCondition == VcbNotMounted) &&
    00702                 NT_SUCCESS(Status)) {
    00703
    00704                 Vcb->MediaChangeCount = MediaChangeCount;
    00705             }
    00706
    00707         //
    00708         //  Raise the error condition otherwise.
    00709         //
    00710
    00711         } else if (!NT_SUCCESS( Status )) {
    00712
    00713             UdfNormalizeAndRaiseStatus( IrpContext, Status );
    00714         }
    00715
    00716     }
    00717
    00718     //
    00719     //  The Vcb may be mounted but the underlying real device may need to be verified.
    00720     //  If it does then we'll set the Iosb in the irp to be our real device
    00721     //  and raise Verify required
    00722     //
    00723
    00724     if (FlagOn( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME )) {
    00725
    00726         IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
    00727                                       Vcb->Vpb->RealDevice );
    00728
    00729         UdfRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED );
    00730     }
    00731
    00732     //
    00733     //  Based on the condition of the Vcb we'll either return to our
    00734     //  caller or raise an error condition
    00735     //
    00736
    00737     switch (Vcb->VcbCondition) {
    00738
    00739     case VcbNotMounted:
    00740
    00741         SetFlag( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME );
    00742
    00743         IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice );
    00744
    00745         UdfRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
    00746         break;
    00747
    00748     case VcbInvalid:
    00749     case VcbDismountInProgress :
    00750
    00751         UdfRaiseStatus( IrpContext, STATUS_FILE_INVALID );
    00752         break;
    00753     }
    00754
    00755     return;
    00756 }