ReactOS  0.4.13-dev-1148-g9b75b67
verfysup.cpp File Reference
#include "udffs.h"
Include dependency graph for verfysup.cpp:

Go to the source code of this file.

Macros

#define UDF_BUG_CHECK_ID   UDF_FILE_VERIFY_FS_CONTROL
 
#define VCB_NE(x)   (OldVcb->x != NewVcb->x)
 

Functions

NTSTATUS UDFVerifyVcb (IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
 
NTSTATUS UDFVerifyVolume (IN PIRP Irp)
 
NTSTATUS UDFPerformVerify (IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
 
BOOLEAN UDFCheckForDismount (IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN _VcbAcquired)
 
BOOLEAN UDFDismountVcb (IN PVCB Vcb, IN BOOLEAN VcbAcquired)
 
NTSTATUS UDFCompareVcb (IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly)
 

Macro Definition Documentation

◆ UDF_BUG_CHECK_ID

#define UDF_BUG_CHECK_ID   UDF_FILE_VERIFY_FS_CONTROL

Definition at line 23 of file verfysup.cpp.

◆ VCB_NE

#define VCB_NE (   x)    (OldVcb->x != NewVcb->x)

Function Documentation

◆ UDFCheckForDismount()

BOOLEAN UDFCheckForDismount ( IN PtrUDFIrpContext  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  _VcbAcquired 
)

Definition at line 629 of file verfysup.cpp.

634 {
635  BOOLEAN VcbPresent = TRUE;
636  KIRQL SavedIrql;
637  BOOLEAN VcbAcquired;
638  ULONG ResidualReferenceCount;
639 
640  UDFPrint(("UDFCheckForDismount:\n"));
641  if(!Vcb) return FALSE;
642 
643  // GlobalDataResource is already acquired
644  if(!_VcbAcquired) {
645  VcbAcquired = UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE/*FALSE*/ );
646  if(!VcbAcquired)
647  return TRUE;
648  } else {
649  VcbAcquired = TRUE;
650  }
651 
652  if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
653  (IrpContext->TargetDeviceObject == Vcb->TargetDeviceObject)) {
654 
655  ResidualReferenceCount = 2;
656 
657  } else {
658 
659  ResidualReferenceCount = 1;
660  }
661 
662  // If the dismount is not already underway then check if the
663  // user reference count has gone to zero. If so start the teardown
664  // on the Vcb.
665  if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) {
666  if (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE) {
667  VcbPresent = UDFDismountVcb(Vcb, VcbAcquired);
668  }
669  VcbAcquired = VcbAcquired && VcbPresent;
670 
671  // If the teardown is underway and there are absolutely no references
672  // remaining then delete the Vcb. References here include the
673  // references in the Vcb and Vpb.
674  } else if (!(Vcb->VCBOpenCount)) {
675 
676  IoAcquireVpbSpinLock( &SavedIrql );
677  // If there are no file objects and no reference counts in the
678  // Vpb we can delete the Vcb. Don't forget that we have the
679  // last reference in the Vpb.
680  if (Vcb->Vpb->ReferenceCount <= ResidualReferenceCount) {
681 
682  IoReleaseVpbSpinLock( SavedIrql );
683  if(VcbAcquired)
684  UDFReleaseResource(&(Vcb->VCBResource));
687  VcbAcquired =
688  VcbPresent = FALSE;
689 
690  } else {
691 
692  IoReleaseVpbSpinLock( SavedIrql );
693  }
694  }
695 
696  // Release any resources still acquired.
697  if (!_VcbAcquired && VcbAcquired) {
698  UDFReleaseResource(&(Vcb->VCBResource));
699  }
700 
701  return VcbPresent;
702 } // end UDFCheckForDismount()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
VOID UDFReleaseVCB(PVCB Vcb)
Definition: misc.cpp:2137
BOOLEAN UDFDismountVcb(IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:727
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
unsigned char BOOLEAN
#define Vcb
Definition: cdprocs.h:1425
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336

Referenced by UDFCommonClose(), UDFPerformVerify(), UDFPnpQueryRemove(), UDFPnpRemove(), UDFPnpSurpriseRemove(), and UDFScanForDismountedVcb().

◆ UDFCompareVcb()

NTSTATUS UDFCompareVcb ( IN PVCB  OldVcb,
IN PVCB  NewVcb,
IN BOOLEAN  PhysicalOnly 
)

Definition at line 849 of file verfysup.cpp.

854 {
855  NTSTATUS RC;
856  UDF_FILE_INFO RootFileInfo;
857  BOOLEAN SimpleLogicalCheck = FALSE;
858 
859  UDFPrint(("UDFCompareVcb:\n"));
861  UDFPrint((" WRONG_VOLUME\n"));
862  return STATUS_WRONG_VOLUME;
863  }
864 
865 #define VCB_NE(x) (OldVcb->x != NewVcb->x)
866 
867  // compare physical parameters
868  if(PhysicalOnly) {
869  UDFPrint((" PhysicalOnly\n"));
870  if(VCB_NE(FirstLBA) ||
871  VCB_NE(LastLBA) ||
872  VCB_NE(FirstTrackNum) ||
873  VCB_NE(LastTrackNum) ||
874  VCB_NE(NWA) ||
875  VCB_NE(LastPossibleLBA) ||
876  VCB_NE(PhSerialNumber) ||
877  VCB_NE(PhErasable) ||
878  VCB_NE(PhDiskType) ||
879  VCB_NE(MediaClassEx) ||
880 
881  /* We cannot compare these flags, because NewVcb is in unconditional ReadOnly */
882 
883  /*((OldVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) ||
884  ((OldVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) ||*/
885 
887  // VCB_NE(xxx) ||
888  // VCB_NE(xxx) ||
889  VCB_NE(LastSession) ) {
890 
891  UDFPrint((" WRONG_VOLUME (2)\n"));
892  return STATUS_WRONG_VOLUME;
893  }
894  // Note, MRWStatus can change while media is mounted (stoppped/in-progress/complete)
895  // We can compare only (Vcb->MRWStatus == 0) values
896  if((OldVcb->MRWStatus == 0) != (NewVcb->MRWStatus == 0)) {
897  UDFPrint((" WRONG_VOLUME (4), missmatch MRW status\n"));
898  }
899  for(uint32 i=OldVcb->FirstTrackNum; i<=OldVcb->LastTrackNum; i++) {
900  if(VCB_NE(TrackMap[i].FirstLba) ||
901  VCB_NE(TrackMap[i].LastLba) ||
902  VCB_NE(TrackMap[i].PacketSize) ||
903  VCB_NE(TrackMap[i].TrackParam) ||
904  VCB_NE(TrackMap[i].DataParam) ||
905  VCB_NE(TrackMap[i].NWA_V) ) {
906  UDFPrint((" WRONG_VOLUME (3), missmatch trk %d\n", i));
907  return STATUS_WRONG_VOLUME;
908  }
909  }
910  UDFPrint((" Vcb compare Ok\n"));
911  return STATUS_SUCCESS;
912  }
913 
914  // Something is nasty!!! We perform verify for not flushed volume
915  // This should never happen, but some devices/buses and their drivers
916  // can lead us to such condition. For example with help of RESET.
917  // Now, we hope, that nobody changed media.
918  // We shall make simplified logical structure check
919  if(OldVcb->Modified) {
920  UDFPrint((" Vcb SIMPLE compare on !!!MODIFIED!!! volume\n"));
921  ASSERT(FALSE);
922  SimpleLogicalCheck = TRUE;
923  }
924 
925  // compare logical structure
926  if(!SimpleLogicalCheck && (OldVcb->InitVatCount != NewVcb->InitVatCount)) {
927  UDFPrint((" InitVatCount %d != %d \n", OldVcb->InitVatCount, NewVcb->InitVatCount));
928  return STATUS_WRONG_VOLUME;
929  }
930 
931  // Compare volume creation time
932  if(OldVcb->VolCreationTime != NewVcb->VolCreationTime) {
933  UDFPrint((" VolCreationTime %I64x != %I64x \n", OldVcb->VolCreationTime, NewVcb->VolCreationTime));
934  return STATUS_WRONG_VOLUME;
935  }
936  // Compare serial numbers
937  if(OldVcb->SerialNumber != NewVcb->SerialNumber) {
938  UDFPrint((" SerialNumber %x != %x \n", OldVcb->SerialNumber, NewVcb->SerialNumber));
939  return STATUS_WRONG_VOLUME;
940  }
941  // Compare volume idents
942  if(!SimpleLogicalCheck &&
943  RtlCompareUnicodeString(&(OldVcb->VolIdent),&(NewVcb->VolIdent),FALSE)) {
944  UDFPrint((" VolIdent missmatch \n"));
945  return STATUS_WRONG_VOLUME;
946  }
947  if(SimpleLogicalCheck) {
948  // do not touch RootDir. It can be partially recorded
949  UDFPrint((" SimpleLogicalCheck Ok\n"));
950  return STATUS_SUCCESS;
951  }
952 
953  RC = UDFOpenRootFile__(NewVcb, &(NewVcb->RootLbAddr), &RootFileInfo);
954  if(!NT_SUCCESS(RC)) {
955  UDFPrint((" Can't open root file, status %x\n", RC));
956  UDFCleanUpFile__(NewVcb, &RootFileInfo);
957  return STATUS_WRONG_VOLUME;
958  }
959  // perform exhaustive check
960  if(!(OldVcb->RootDirFCB)) {
961  UDFPrint((" !(OldVcb->RootDirFCB)\n"));
962 wr_vol:
963  UDFCloseFile__(NewVcb, &RootFileInfo);
964  UDFCleanUpFile__(NewVcb, &RootFileInfo);
965  return STATUS_WRONG_VOLUME;
966  }
967 
968  if(!UDFCompareFileInfo(&RootFileInfo, OldVcb->RootDirFCB->FileInfo)) {
969  UDFPrint((" !UDFCompareFileInfo\n"));
970  goto wr_vol;
971  }
972  UDFCloseFile__(NewVcb, &RootFileInfo);
973  UDFCleanUpFile__(NewVcb, &RootFileInfo);
974 
975  UDFPrint(("UDFCompareVcb: Ok\n"));
976  return STATUS_SUCCESS;
977 
978 #undef VCB_NE
979 
980 } // end UDFCompareVcb()
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
unsigned int uint32
Definition: types.h:32
LONG NTSTATUS
Definition: precomp.h:26
#define UDF_DATA_FLAGS_BEING_UNLOADED
Definition: udf_common.h:636
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1, IN PUDF_FILE_INFO f2)
Definition: udf_info.cpp:4218
unsigned char BOOLEAN
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define VCB_NE(x)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
UDFData UDFGlobalData
Definition: udfinit.cpp:25
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
uint32 UDFFlags
Definition: udf_common.h:627
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1664
return STATUS_SUCCESS
Definition: btrfs.c:2966
OSSTATUS UDFOpenRootFile__(IN PVCB Vcb, IN lb_addr *RootLoc, OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2187

Referenced by UDFVerifyVolume().

◆ UDFDismountVcb()

BOOLEAN UDFDismountVcb ( IN PVCB  Vcb,
IN BOOLEAN  VcbAcquired 
)

Definition at line 727 of file verfysup.cpp.

731 {
732 
733  PVPB OldVpb;
734  PVPB NewVpb;
735  BOOLEAN VcbPresent = TRUE;
736  KIRQL SavedIrql;
737 
738  BOOLEAN FinalReference;
739 
740  UDFPrint(("UDFDismountVcb:\n"));
741  // We should only take this path once.
742  ASSERT( !(Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) );
743 
744  // Mark the Vcb as DismountInProgress.
745  Vcb->VCBFlags |= UDF_VCB_FLAGS_BEING_DISMOUNTED;
746 
747  // Allocate a new Vpb in case we will need it.
748  NewVpb = (PVPB)DbgAllocatePoolWithTag( NonPagedPool, sizeof( VPB ), 'bpvU' );
749  if(!NewVpb) {
750  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_BEING_DISMOUNTED;
751  return TRUE;
752  }
753 
754  RtlZeroMemory( NewVpb, sizeof(VPB) );
755 
756  OldVpb = Vcb->Vpb;
757 
758  // Remove the mount volume reference.
760  // the only residual reference is cleaned above
761 
762  // Acquire the Vpb spinlock to check for Vpb references.
763  IoAcquireVpbSpinLock(&SavedIrql);
764 
765  // Remember if this is the last reference on this Vcb. We incremented
766  // the count on the Vpb earlier so we get one last crack it. If our
767  // reference has gone to zero but the vpb reference count is greater
768  // than zero then the Io system will be responsible for deleting the
769  // Vpb.
770  FinalReference = (BOOLEAN)(OldVpb->ReferenceCount == 1);
771 
772  // There is a reference count in the Vpb and in the Vcb. We have
773  // incremented the reference count in the Vpb to make sure that
774  // we have last crack at it. If this is a failed mount then we
775  // want to return the Vpb to the IO system to use for the next
776  // mount request.
777  if (OldVpb->RealDevice->Vpb == OldVpb) {
778 
779  // If not the final reference then swap out the Vpb.
780  if (!FinalReference) {
781 
782  NewVpb->Type = IO_TYPE_VPB;
783  NewVpb->Size = sizeof( VPB );
784  NewVpb->RealDevice = OldVpb->RealDevice;
785 
786  NewVpb->RealDevice->Vpb = NewVpb;
787 
788  NewVpb = NULL;
789  IoReleaseVpbSpinLock(SavedIrql);
790  // We want to leave the Vpb for the IO system. Mark it
791  // as being not mounted. Go ahead and delete the Vcb as
792  // well.
793  } else {
794 
795  // Make sure to remove the last reference on the Vpb.
796 
797  OldVpb->ReferenceCount--;
798 
799  OldVpb->DeviceObject = NULL;
800  Vcb->Vpb->Flags &= ~VPB_MOUNTED;
801 
802  // Clear the Vpb flag so we know not to delete it.
803  Vcb->Vpb = NULL;
804 
805  IoReleaseVpbSpinLock(SavedIrql);
806  if(VcbAcquired)
807  UDFReleaseResource(&(Vcb->VCBResource));
810  VcbPresent = FALSE;
811  }
812 
813  // Someone has already swapped in a new Vpb. If this is the final reference
814  // then the file system is responsible for deleting the Vpb.
815  } else if (FinalReference) {
816 
817  // Make sure to remove the last reference on the Vpb.
818  OldVpb->ReferenceCount--;
819 
820  IoReleaseVpbSpinLock( SavedIrql );
821  if(VcbAcquired)
822  UDFReleaseResource(&(Vcb->VCBResource));
825  VcbPresent = FALSE;
826 
827  // The current Vpb is no longer the Vpb for the device (the IO system
828  // has already allocated a new one). We leave our reference in the
829  // Vpb and will be responsible for deleting it at a later time.
830  } else {
831 
832  OldVpb->DeviceObject = NULL;
833  Vcb->Vpb->Flags &= ~VPB_MOUNTED;
834 
835  IoReleaseVpbSpinLock( SavedIrql );
836  }
837 
838  // Deallocate the new Vpb if we don't need it.
839  if (NewVpb != NULL) {
840  DbgFreePool( NewVpb );
841  }
842 
843  // Let our caller know whether the Vcb is still present.
844  return VcbPresent;
845 } // end UDFDismountVcb()
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
#define DbgAllocatePoolWithTag(a, b, c)
Definition: env_spec_w32.h:333
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
VOID UDFReleaseVCB(PVCB Vcb)
Definition: misc.cpp:2137
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG ReferenceCount
Definition: iotypes.h:174
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:171
#define DbgFreePool
Definition: env_spec_w32.h:334
VOID UDFCloseResidual(IN PVCB Vcb)
Definition: fscntrl.cpp:1349
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:172
#define Vcb
Definition: cdprocs.h:1425
CSHORT Size
Definition: iotypes.h:168
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IO_TYPE_VPB
struct _VPB VPB
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
struct _VPB * PVPB
CSHORT Type
Definition: iotypes.h:167
Definition: iotypes.h:166
#define BOOLEAN
Definition: pedump.c:73
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define VPB_MOUNTED
Definition: iotypes.h:1764
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220

Referenced by UDFCheckForDismount(), and UDFMountVolume().

◆ UDFPerformVerify()

NTSTATUS UDFPerformVerify ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp,
IN PDEVICE_OBJECT  DeviceToVerify 
)

Definition at line 472 of file verfysup.cpp.

477 {
478 
479  PVCB Vcb;
482 
483  UDFPrint(("UDFPerformVerify:\n"));
484  if(!IrpContext) return STATUS_INVALID_PARAMETER;
485  if(!Irp) return STATUS_INVALID_PARAMETER;
486 
487  // Check if this Irp has a status of Verify required and if it does
488  // then call the I/O system to do a verify.
489  //
490  // Skip the IoVerifyVolume if this is a mount or verify request
491  // itself. Trying a recursive mount will cause a deadlock with
492  // the DeviceObject->DeviceLock.
493  if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
494  ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
495  (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) {
496 
497  return UDFPostRequest(IrpContext, Irp);
498  }
499 
500  // Extract a pointer to the Vcb from the VolumeDeviceObject.
501  // Note that since we have specifically excluded mount,
502  // requests, we know that IrpSp->DeviceObject is indeed a
503  // volume device object.
504 
506 
508 
509  UDFPrint(("UDFPerformVerify: check\n"));
510  // Check if the volume still thinks it needs to be verified,
511  // if it doesn't then we can skip doing a verify because someone
512  // else beat us to it.
513  _SEH2_TRY {
514 
515  if (DeviceToVerify->Flags & DO_VERIFY_VOLUME) {
516 
517  // If the IopMount in IoVerifyVolume did something, and
518  // this is an absolute open, force a reparse.
520 
521  // Bug?
522 /* if (UDFIsRawDevice(RC)) {
523  RC = STATUS_WRONG_VOLUME;
524  }*/
525 
526  // If the verify operation completed it will return
527  // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
528  if (RC == STATUS_SUCCESS) {
529  IrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_EXCEPTION;
530  }
531  // If UDFVerifyVolume encountered an error during
532  // processing, it will return that error. If we got
533  // STATUS_WRONG_VOLUME from the verify, and our volume
534  // is now mounted, commute the status to STATUS_SUCCESS.
535  if ((RC == STATUS_WRONG_VOLUME) &&
536  (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
537  RC = STATUS_SUCCESS;
538  }
539 
540  // Do a quick unprotected check here. The routine will do
541  // a safe check. After here we can release the resource.
542  // Note that if the volume really went away, we will be taking
543  // the Reparse path.
544 
545  // If the device might need to go away then call our dismount routine.
546  if ( (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) ||
547  (Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) &&
548  (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE) )
549  {
550  UDFPrint(("UDFPerformVerify: UDFCheckForDismount\n"));
551  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
552  UDFCheckForDismount( IrpContext, Vcb, FALSE );
553  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
554  }
555 
556  // If this is a create and the verify succeeded then complete the
557  // request with a REPARSE status.
558  if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
559  (IrpSp->FileObject->RelatedFileObject == NULL) &&
560  ((RC == STATUS_SUCCESS) || (RC == STATUS_WRONG_VOLUME)) ) {
561 
562  UDFPrint(("UDFPerformVerify: IO_REMOUNT\n"));
563 
564  Irp->IoStatus.Information = IO_REMOUNT;
565 
566  Irp->IoStatus.Status = STATUS_REPARSE;
568 
569  UDFReleaseIrpContext(IrpContext);
570 
571  RC = STATUS_REPARSE;
572  Irp = NULL;
573  IrpContext = NULL;
574 
575  // If there is still an error to process then call the Io system
576  // for a popup.
577  } else if ((Irp != NULL) && !NT_SUCCESS( RC )) {
578 
579  UDFPrint(("UDFPerformVerify: check IoIsErrorUserInduced\n"));
580  // Fill in the device object if required.
581  if (IoIsErrorUserInduced( RC ) ) {
583  }
584  UDFPrint(("UDFPerformVerify: UDFNormalizeAndRaiseStatus\n"));
585  UDFNormalizeAndRaiseStatus( IrpContext, RC );
586  }
587  }
588 
589  // If there is still an Irp, send it off to an Ex Worker thread.
590  if (IrpContext != NULL) {
591 
592  RC = UDFPostRequest( IrpContext, Irp );
593  }
594 
596  // We had some trouble trying to perform the verify or raised
597  // an error ourselves. So we'll abort the I/O request with
598  // the error status that we get back from the execption code.
599  RC = UDFExceptionHandler( IrpContext, Irp);
600  } _SEH2_END;
601 
602  UDFPrint(("UDFPerformVerify: RC = %x\n", RC));
603 
604  return RC;
605 
606 } // end UDFPerformVerify()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
#define UDFNormalizeAndRaiseStatus(IC, S)
Definition: udffs.h:319
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
Definition: cdstruc.h:504
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
_SEH2_TRY
Definition: create.c:4250
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4049
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4048
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define Vcb
Definition: cdprocs.h:1425
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN _VcbAcquired)
Definition: verfysup.cpp:629
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
UDFData UDFGlobalData
Definition: udfinit.cpp:25
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
struct _VCB * PVCB
Definition: fatstruc.h:556
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
_SEH2_END
Definition: create.c:4424
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define STATUS_REPARSE
Definition: ntstatus.h:83
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define IO_REMOUNT
Definition: iotypes.h:512
#define UDF_IRP_CONTEXT_EXCEPTION
Definition: struct.h:387
return STATUS_SUCCESS
Definition: btrfs.c:2966
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:882
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1417
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336

Referenced by UDFExceptionHandler().

◆ UDFVerifyVcb()

NTSTATUS UDFVerifyVcb ( IN PtrUDFIrpContext  IrpContext,
IN PVCB  Vcb 
)

Definition at line 37 of file verfysup.cpp.

41 {
44  ULONG MediaChangeCount = 0;
45  BOOLEAN Nop = TRUE;
46  BOOLEAN UnsafeIoctl = (Vcb->VCBFlags & UDF_VCB_FLAGS_UNSAFE_IOCTL) ? TRUE : FALSE;
47 
48  UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
49  // Fail immediately if the volume is in the progress of being dismounted
50  // or has been marked invalid.
51  if (Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) {
52  return STATUS_FILE_INVALID;
53  }
54 
55  // If the media is removable and the verify volume flag in the
56  // device object is not set then we want to ping the device
57  // to see if it needs to be verified
58  if ( (Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) &&
59  !(Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) &&
60  (!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) || UnsafeIoctl) ) {
61  UDFPrint(("UDFVerifyVCB: UnsafeIoctl=%d, locked=%d\n", UnsafeIoctl, (Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) ? 0 : 1));
62  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_UNSAFE_IOCTL;
64  Vcb,
65  NULL,0,
66  &MediaChangeCount,sizeof(ULONG),
67  FALSE,&Iosb );
68 
69  // Be safe about the count in case the driver didn't fill it in
70  if (Iosb.Information != sizeof(ULONG)) MediaChangeCount = 0;
71  UDFPrint((" MediaChangeCount %d -> %d\n", Vcb->MediaChangeCount, MediaChangeCount));
72 
73  // If the volume is now an empty device, or we have receieved a
74  // bare STATUS_VERIFY_REQUIRED (various hardware conditions such
75  // as bus resets, etc., will trigger this in the drivers), or the
76  // media change count has moved since we last inspected the device,
77  // then mark the volume to be verified.
78 
79  if ( (RC == STATUS_VERIFY_REQUIRED) ||
80  (UDFIsRawDevice(RC) && (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) ||
81  (NT_SUCCESS(RC) && (Vcb->MediaChangeCount != MediaChangeCount)) ||
82  UnsafeIoctl) {
83 
84  UDFPrint((" set DO_VERIFY_VOLUME\n"));
85  Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
86 
87  // If the volume is not mounted and we got a media change count,
88  // update the Vcb so we do not trigger a verify again at this
89  // count value. If the verify->mount path detects that the media
90  // has actually changed and this Vcb is valid again, this will have
91  // done nothing. We are already synchronized since the caller has
92  // the Vcb.
93  if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
94  NT_SUCCESS(RC) ) {
95  Vcb->MediaChangeCount = MediaChangeCount;
96  }
97 
98  } else if (!NT_SUCCESS(RC)) {
99 // Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
100  UDFPrint((" UDFNormalizeAndRaiseStatus(%x)\n", RC));
101  UDFNormalizeAndRaiseStatus(IrpContext,RC);
102  ASSERT(Nop);
103  }
104  }
105 
106  UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
107  // The Vcb may be mounted but the underlying real device may need to be verified.
108  // If it does then we'll set the Iosb in the irp to be our real device
109  if (Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) {
110 
111  UDFPrint((" DO_VERIFY_VOLUME -> IoSetHardErrorOrVerifyDevice()\n"));
112  IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
113  Vcb->Vpb->RealDevice );
114 
116  UDFPrint((" UDFRaiseStatus()\n"));
117  UDFRaiseStatus(IrpContext, RC);
118  ASSERT(Nop);
119  }
120 
121  UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
122  if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
123  UDFPrint((" !UDF_VCB_FLAGS_VOLUME_MOUNTED -> IoSetHardErrorOrVerifyDevice()\n"));
124  Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
125  IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice );
126  RC = STATUS_WRONG_VOLUME;
127  UDFPrint((" UDFRaiseStatus()\n"));
128  UDFRaiseStatus(IrpContext, RC);
129 // UDFRaiseStatus(IrpContext, STATUS_UNRECOGNIZED_VOLUME);
130  ASSERT(Nop);
131  }
132  if ((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) {
133  UDFPrint((" UDF_VCB_FLAGS_BEING_DISMOUNTED\n"));
134  RC = STATUS_FILE_INVALID;
135  UDFRaiseStatus( IrpContext, RC );
136  ASSERT(Nop);
137  }
138  UDFPrint(("UDFVerifyVcb: RC = %x\n", RC));
139 
140  return RC;
141 } // end UDFVerifyVcb()
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define UDFNormalizeAndRaiseStatus(IC, S)
Definition: udffs.h:319
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA
Definition: udf_common.h:468
NTSTATUS NTAPI UDFTSendIOCTL(IN ULONG IoControlCode, IN PVCB Vcb, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:462
#define UDF_VCB_FLAGS_UNSAFE_IOCTL
Definition: udf_common.h:488
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define UDFRaiseStatus(IC, S)
Definition: udffs.h:314
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
#define UDF_VCB_FLAGS_MEDIA_LOCKED
Definition: udf_common.h:469
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
#define UDFIsRawDevice(RC)
Definition: udffs.h:324
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by UDFCommonCreate(), UDFCommonDeviceControl(), UDFIsVolumeMounted(), and UDFLockVolume().

◆ UDFVerifyVolume()

NTSTATUS UDFVerifyVolume ( IN PIRP  Irp)

Definition at line 158 of file verfysup.cpp.

161 {
163  PVPB Vpb = IrpSp->Parameters.VerifyVolume.Vpb;
164  PVCB Vcb = (PVCB)IrpSp->Parameters.VerifyVolume.DeviceObject->DeviceExtension;
165  PVCB NewVcb = NULL;
167  ULONG MediaChangeCount = 0;
168  NTSTATUS RC;
169  ULONG Mode;
170  BOOLEAN UnsafeIoctl = (Vcb->VCBFlags & UDF_VCB_FLAGS_UNSAFE_IOCTL) ? TRUE : FALSE;
171 
172  // Update the real device in the IrpContext from the Vpb. There was no available
173  // file object when the IrpContext was created.
174  // IrpContext->RealDevice = Vpb->RealDevice;
175  UDFPrint(("UDFVerifyVolume:\n"));
176 
177  // Acquire shared global access, the termination handler for the
178  // following try statement will free the access.
179 
180  UDFAcquireResourceShared(&(UDFGlobalData.GlobalDataResource),TRUE);
181  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
182 
183  _SEH2_TRY {
184 
185  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
186  // Check if the real device still needs to be verified. If it doesn't
187  // then obviously someone beat us here and already did the work
188  // so complete the verify irp with success. Otherwise reenable
189  // the real device and get to work.
190  if( !(Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) &&
191  ((Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) && !UnsafeIoctl) ) {
192  UDFPrint(("UDFVerifyVolume: STATUS_SUCCESS (1)\n"));
194  }
195  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_UNSAFE_IOCTL;
196  // Verify that there is a disk here.
198  Vcb->TargetDeviceObject,
199  NULL,0,
200  &MediaChangeCount,sizeof(ULONG),
201  TRUE,&Iosb );
202 
203  if(!NT_SUCCESS( RC )) {
204  // If we will allow a raw mount then return WRONG_VOLUME to
205  // allow the volume to be mounted by raw.
207  UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (1)\n"));
208  RC = STATUS_WRONG_VOLUME;
209  }
210 
211  if(UDFIsRawDevice(RC)) {
212  UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (2)\n"));
213  RC = STATUS_WRONG_VOLUME;
214  }
215  try_return( RC );
216  }
217 
218  if(Iosb.Information != sizeof(ULONG)) {
219  // Be safe about the count in case the driver didn't fill it in
220  MediaChangeCount = 0;
221  }
222 
223  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
224  UDFPrint(("UDFVerifyVolume: MediaChangeCount=%x, Vcb->MediaChangeCount=%x, UnsafeIoctl=%x\n",
225  MediaChangeCount, Vcb->MediaChangeCount, UnsafeIoctl));
226  // Verify that the device actually saw a change. If the driver does not
227  // support the MCC, then we must verify the volume in any case.
228  if(MediaChangeCount == 0 ||
229  (Vcb->MediaChangeCount != MediaChangeCount) ||
230  UnsafeIoctl ) {
231 
232  UDFPrint(("UDFVerifyVolume: compare\n"));
233 
234  NewVcb = (PVCB)MyAllocatePool__(NonPagedPool,sizeof(VCB));
235  if(!NewVcb)
237  RtlZeroMemory(NewVcb,sizeof(VCB));
238 
239  NewVcb->TargetDeviceObject = Vcb->TargetDeviceObject;
240  NewVcb->Vpb = Vpb;
241 
242  // Set the removable media flag based on the real device's
243  // characteristics
244  if(Vpb->RealDevice->Characteristics & FILE_REMOVABLE_MEDIA) {
245  UDFSetFlag( NewVcb->VCBFlags, UDF_VCB_FLAGS_REMOVABLE_MEDIA );
246  }
247 
248  RC = UDFGetDiskInfo(NewVcb->TargetDeviceObject,NewVcb);
249  if(!NT_SUCCESS(RC)) try_return(RC);
250  // Prevent modification attempts durring Verify
251  NewVcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY |
253  // Compare physical parameters (phase 1)
254  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
255  RC = UDFCompareVcb(Vcb,NewVcb, TRUE);
256  if(!NT_SUCCESS(RC)) try_return(RC);
257 
258  if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
259  Vcb->MountPhErrorCount > MOUNT_ERR_THRESHOLD ) {
260  UDFPrint(("UDFVerifyVolume: it was very BAD volume. Do not perform Logical check\n"));
261  goto skip_logical_check;
262  }
263  // Initialize internal cache
264  // in *** READ ONLY *** mode
266 
267  RC = WCacheInit__(&(NewVcb->FastCache),
270  NewVcb->WriteBlockSize,
271  5, NewVcb->BlockSizeBits,
273  0/*NewVcb->FirstLBA*/, NewVcb->LastPossibleLBA, Mode,
274  /*WCACHE_CACHE_WHOLE_PACKET*/ 0 |
275  (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
276  WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS, // speed up mount on bad disks
279 #ifdef UDF_ASYNC_IO
280  UDFTWriteAsync, UDFTReadAsync,
281 #else //UDF_ASYNC_IO
282  NULL, NULL,
283 #endif //UDF_ASYNC_IO
286  if(!NT_SUCCESS(RC)) try_return(RC);
287 
288  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
289  RC = UDFGetDiskInfoAndVerify(NewVcb->TargetDeviceObject,NewVcb);
290  UDFPrint((" NewVcb->NSRDesc=%x\n", NewVcb->NSRDesc));
291  if(!NT_SUCCESS(RC)) {
292  if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
293  (NewVcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
294  !(NewVcb->NSRDesc & VRS_ISO9660_FOUND)) {
295  UDFPrint(("UDFVerifyVolume: both are RAW -> remount\n", Vcb->Modified));
296  RC = STATUS_SUCCESS;
297  goto skip_logical_check;
298  }
299  if(RC == STATUS_UNRECOGNIZED_VOLUME) {
301  }
302  try_return(RC);
303  }
304 
305  WCacheChFlags__(&(Vcb->FastCache),
306  WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
307  WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
308 
309  NewVcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_MOUNTED;
310  // Compare logical parameters (phase 2)
311  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
312  RC = UDFCompareVcb(Vcb,NewVcb, FALSE);
313  if(!NT_SUCCESS(RC)) try_return(RC);
314  // We have unitialized WCache, so it is better to
315  // force MOUNT_VOLUME call
316  if(!WCacheIsInitialized__(&(Vcb->FastCache)))
318 
319 skip_logical_check:;
320 
321  }
322 
323  UDFPrint(("UDFVerifyVolume: compared\n"));
324  UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
325  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED)) {
326  UDFPrint(("UDFVerifyVolume: set UDF_VCB_FLAGS_VOLUME_MOUNTED\n"));
327  Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_MOUNTED;
328  Vcb->SoftEjectReq = FALSE;
329  }
330  UDFClearFlag( Vpb->RealDevice->Flags, DO_VERIFY_VOLUME );
331 
332 try_exit: NOTHING;
333 
334  } _SEH2_FINALLY {
335 
336  // Update the media change count to note that we have verified the volume
337  // at this value
338  Vcb->MediaChangeCount = MediaChangeCount;
339 
340  // If we got the wrong volume, mark the Vcb as not mounted.
341  if(RC == STATUS_WRONG_VOLUME) {
342  UDFPrint(("UDFVerifyVolume: clear UDF_VCB_FLAGS_VOLUME_MOUNTED\n"));
343  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
344  Vcb->WriteSecurity = FALSE;
345 // ASSERT(!(Vcb->EjectWaiter));
346  if(Vcb->EjectWaiter) {
347  UDFReleaseResource(&(Vcb->VCBResource));
349  UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
350  }
351  } else
352  if(NT_SUCCESS(RC) &&
353  (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)){
354  BOOLEAN CacheInitialized = FALSE;
355  UDFPrint((" !!! VerifyVolume - QUICK REMOUNT !!!\n"));
356  // Initialize internal cache
357  CacheInitialized = WCacheIsInitialized__(&(Vcb->FastCache));
358  if(!CacheInitialized) {
360  RC = WCacheInit__(&(Vcb->FastCache),
361  Vcb->WCacheMaxFrames,
362  Vcb->WCacheMaxBlocks,
363  Vcb->WriteBlockSize,
364  5, Vcb->BlockSizeBits,
365  Vcb->WCacheBlocksPerFrameSh,
366  0/*Vcb->FirstLBA*/, Vcb->LastPossibleLBA, Mode,
367  /*WCACHE_CACHE_WHOLE_PACKET*/ 0 |
368  (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
369  (Vcb->CacheChainedIo ? WCACHE_CHAINED_IO : 0),
370  Vcb->WCacheFramesToKeepFree,
371 // UDFTWrite, UDFTRead,
373 #ifdef UDF_ASYNC_IO
374  UDFTWriteAsync, UDFTReadAsync,
375 #else //UDF_ASYNC_IO
376  NULL, NULL,
377 #endif //UDF_ASYNC_IO
380  }
381  if(NT_SUCCESS(RC)) {
382  if(!Vcb->VerifyCtx.VInited) {
383  RC = UDFVInit(Vcb);
384  }
385  }
386  if(NT_SUCCESS(RC)) {
387 
388  if(!CacheInitialized) {
389  if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) {
390  if(!Vcb->CDR_Mode) {
391  if((Vcb->TargetDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
392  CdrwMediaClassEx_IsRAM(Vcb->MediaClassEx)) {
393  UDFPrint(("UDFMountVolume: RAM mode\n"));
395  } else {
396  UDFPrint(("UDFMountVolume: RW mode\n"));
398  }
399  /* if(FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
400  } else {
401  Vcb->WriteSecurity = TRUE;
402  }*/
403  } else {
405  }
406  }
407  WCacheSetMode__(&(Vcb->FastCache), Mode);
408 
409  WCacheChFlags__(&(Vcb->FastCache),
410  WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
411  WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
412  }
413  // we can't record ACL on old format disks
414  if(!UDFNtAclSupported(Vcb)) {
415  Vcb->WriteSecurity = FALSE;
416  Vcb->UseExtendedFE = FALSE;
417  }
418  UDFPrint(("UDFVerifyVolume: try start EjectWaiter\n"));
419  RC = UDFStartEjectWaiter(Vcb);
420  if(!NT_SUCCESS(RC)) {
421  UDFPrint(("UDFVerifyVolume: start EjectWaiter failed\n"));
422  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
423  Vcb->WriteSecurity = FALSE;
424  }
425  }
426  }
427 
428  if(NewVcb) {
429  // Release internal cache
430  UDFPrint(("UDFVerifyVolume: delete NewVcb\n"));
431  WCacheFlushAll__(&(NewVcb->FastCache),NewVcb);
432  WCacheRelease__(&(NewVcb->FastCache));
433 
434  ASSERT(!(NewVcb->EjectWaiter));
435  // Waiter thread should be already stopped
436  // if MediaChangeCount have changed
437  ASSERT(!(Vcb->EjectWaiter));
438 
439  UDFCleanupVCB(NewVcb);
440  MyFreePool__(NewVcb);
441  }
442  UDFReleaseResource(&(Vcb->VCBResource));
443  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
444  } _SEH2_END;
445 
446  // Complete the request if no exception.
447  Irp->IoStatus.Information = 0;
448 
449  Irp->IoStatus.Status = RC;
451 
452  UDFPrint(("UDFVerifyVolume: RC = %x\n", RC));
453 
454  return RC;
455 } // end UDFVerifyVolume ()
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define UDFPrint(Args)
Definition: udffs.h:225
#define WCACHE_CHAINED_IO
Definition: wcache_lib.h:193
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI UDFPhSendIOCTL(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:511
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID WCacheRelease__(IN PW_CACHE Cache)
NTSTATUS UDFStartEjectWaiter(IN PVCB Vcb)
Definition: fscntrl.cpp:850
_In_ ULONG Mode
Definition: hubbusif.h:303
_In_ PIRP Irp
Definition: csq.h:116
#define UDFSetFlag(Flag, Value)
Definition: udffs.h:191
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
ULONG WCacheBlocksPerFrameSh
Definition: udf_common.h:623
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define UDFNtAclSupported(Vcb)
Definition: udf_info.h:1040
#define WCACHE_RO_BAD_BLOCKS
Definition: wcache_lib.h:195
Definition: cdstruc.h:504
ULONG WCacheFramesToKeepFree
Definition: udf_common.h:624
#define WCACHE_MARK_BAD_BLOCKS
Definition: wcache_lib.h:194
OSSTATUS WCacheInit__(IN PW_CACHE Cache, IN ULONG MaxFrames, IN ULONG MaxBlocks, IN SIZE_T MaxBytesToRead, IN ULONG PacketSizeSh, IN ULONG BlockSizeSh, IN ULONG BlocksPerFrameSh, IN lba_t FirstLba, IN lba_t LastLba, IN ULONG Mode, IN ULONG Flags, IN ULONG FramesToKeepFree, IN PWRITE_BLOCK WriteProc, IN PREAD_BLOCK ReadProc, IN PWRITE_BLOCK_ASYNC WriteProcAsync, IN PREAD_BLOCK_ASYNC ReadProcAsync, IN PCHECK_BLOCK CheckUsedProc, IN PUPDATE_RELOC UpdateRelocProc, IN PWC_ERROR_HANDLER ErrorHandlerProc)
Definition: wcache_lib.cpp:116
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA
Definition: udf_common.h:468
#define WCACHE_CACHE_WHOLE_PACKET
Definition: wcache_lib.h:191
#define UDFClearFlag(Flag, Value)
Definition: udffs.h:192
_SEH2_TRY
Definition: create.c:4250
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define UDF_VCB_FLAGS_UNSAFE_IOCTL
Definition: udf_common.h:488
ULONG WCacheChFlags__(IN PW_CACHE Cache, IN ULONG SetFlags, IN ULONG ClrFlags)
uint32 UDFIsBlockAllocated(IN void *_Vcb, IN uint32 Lba)
Definition: alloc.cpp:1164
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
OSSTATUS UDFUpdateVAT(IN void *_Vcb, IN uint32 Lba, IN uint32 *RelocTab, IN uint32 BCount)
Definition: udf_info.cpp:5316
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
NTSTATUS UDFWCacheErrorHandler(IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo)
Definition: misc.cpp:2583
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
OSSTATUS UDFTWrite(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
Definition: phys_lib.cpp:453
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:87
VOID UDFCleanupVCB(IN PVCB Vcb)
Definition: fscntrl.cpp:1428
#define UDF_VCB_FLAGS_MEDIA_LOCKED
Definition: udf_common.h:469
return Iosb
Definition: create.c:4426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define try_return(S)
Definition: cdprocs.h:2189
#define Vcb
Definition: cdprocs.h:1425
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1798
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG WCacheMaxBlocks
Definition: udf_common.h:622
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
ULONG WCacheMaxFrames
Definition: udf_common.h:621
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define WCACHE_MODE_RAM
Definition: wcache_lib.h:127
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
OSSTATUS UDFTRead(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
Definition: phys_lib.cpp:596
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_SEH2_END
Definition: create.c:4424
OSSTATUS UDFTWriteVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache)
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
#define UDFIsRawDevice(RC)
Definition: udffs.h:324
#define WCACHE_DO_NOT_COMPARE
Definition: wcache_lib.h:192
#define WCACHE_MODE_ROM
Definition: wcache_lib.h:124
Definition: iotypes.h:166
#define MOUNT_ERR_THRESHOLD
Definition: udffs.h:62
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
OSSTATUS UDFTReadVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
OSSTATUS UDFGetDiskInfo(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: phys_lib.cpp:3050
#define CdrwMediaClassEx_IsRAM(MediaClassEx)
Definition: cdrw_usr.h:799
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
OSSTATUS UDFVInit(IN PVCB Vcb)
Definition: remap.cpp:54
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WCACHE_MODE_RW
Definition: wcache_lib.h:125
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1664
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, IN ULONG Mode)
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460
NTSTATUS UDFCompareVcb(IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly)
Definition: verfysup.cpp:849

Referenced by UDFCommonFSControl().