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 }


Generated on Sat May 15 19:46:07 2004 for test by doxygen 1.3.7