ReactOS  0.4.14-dev-49-gfb4591c
fsctrl.c File Reference
#include "cdprocs.h"
Include dependency graph for fsctrl.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_FSCTRL)
 

Functions

 _Requires_lock_held_ (_Requires_lock_held_() VOIDCdScanForDismountedVcb(_Inout_ PIRP_CONTEXT IrpContext) _Global_critical_region_)
 
NTSTATUS CdUnlockVolumeInternal (_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb, _In_opt_ PFILE_OBJECT FileObject)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
VOID CdReMountOldVcb (_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB OldVcb, _Inout_ PVCB NewVcb, _In_ PDEVICE_OBJECT DeviceObjectWeTalkTo)
 
NTSTATUS CdIsVolumeDirty (_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
 
NTSTATUS CdIsVolumeMounted (_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
 
NTSTATUS CdIsPathnameValid (_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
 
NTSTATUS CdAllowExtendedDasdIo (_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
 
 _Success_ (return !=FALSE)
 
VOID CdFindActiveVolDescriptor (_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Inout_updates_bytes_(ROUND_TO_PAGES(SECTOR_SIZE)) PCHAR RawIsoVd, _In_ BOOLEAN VerifyVolume)
 

Variables

BOOLEAN CdDisable = FALSE
 
BOOLEAN CdNoJoliet = FALSE
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_FSCTRL)

Definition at line 23 of file fsctrl.c.

Function Documentation

◆ _Requires_lock_held_() [1/2]

_Requires_lock_held_ ( _Requires_lock_held_()VOIDCdScanForDismountedVcb ( _Inout_ PIRP_CONTEXT IrpContext )  _Global_critical_region_)

Definition at line 36 of file fsctrl.c.

212 {
214  KIRQL SavedIrql;
216  ULONG RemainingUserReferences = (FileObject? 1: 0);
217 
218  //
219  // The cleanup count for the volume only reflects the fileobject that
220  // will lock the volume. Otherwise, we must fail the request.
221  //
222  // Since the only cleanup is for the provided fileobject, we will try
223  // to get rid of all of the other user references. If there is only one
224  // remaining after the purge then we can allow the volume to be locked.
225  //
226 
227  CdPurgeVolume( IrpContext, Vcb, FALSE );
228 
229  //
230  // Now back out of our synchronization and wait for the lazy writer
231  // to finish off any lazy closes that could have been outstanding.
232  //
233  // Since we purged, we know that the lazy writer will issue all
234  // possible lazy closes in the next tick - if we hadn't, an otherwise
235  // unopened file with a large amount of dirty data could have hung
236  // around for a while as the data trickled out to the disk.
237  //
238  // This is even more important now since we send notification to
239  // alert other folks that this style of check is about to happen so
240  // that they can close their handles. We don't want to enter a fast
241  // race with the lazy writer tearing down his references to the file.
242  //
243 
244  CdReleaseVcb( IrpContext, Vcb );
245 
247 
248  //
249  // This is intentional. If we were able to get the Vcb before, just
250  // wait for it and take advantage of knowing that it is OK to leave
251  // the flag up.
252  //
253 
254  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
255  CdAcquireVcbExclusive( IrpContext, Vcb, FALSE );
256 
257  if (!NT_SUCCESS( Status )) {
258 
259  return Status;
260  }
261 
262  CdFspClose( Vcb );
263 
264  //
265  // If the volume is already explicitly locked then fail. We use the
266  // Vpb locked flag as an 'explicit lock' flag in the same way as Fat.
267  //
268 
269  IoAcquireVpbSpinLock( &SavedIrql );
270 
271  if (!FlagOn( Vcb->Vpb->Flags, VPB_LOCKED ) &&
272  (Vcb->VcbCleanup == RemainingUserReferences) &&
273  (Vcb->VcbUserReference == CDFS_RESIDUAL_USER_REFERENCE + RemainingUserReferences)) {
274 
275  SetFlag( Vcb->VcbState, VCB_STATE_LOCKED );
276  SetFlag( Vcb->Vpb->Flags, VPB_LOCKED);
277  Vcb->VolumeLockFileObject = FileObject;
278  FinalStatus = STATUS_SUCCESS;
279  }
280 
281  IoReleaseVpbSpinLock( SavedIrql );
282 
283  return FinalStatus;
284 }
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define CDFS_RESIDUAL_USER_REFERENCE
Definition: cddata.h:44
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
VOID CdFspClose(_In_opt_ PVCB Vcb)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define VPB_LOCKED
Definition: iotypes.h:1765
#define VCB_STATE_LOCKED
Definition: cdstruc.h:715
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define CdAcquireVcbExclusive(IC, V, I)
Definition: cdprocs.h:984
NTSTATUS NTAPI CcWaitForCurrentLazyWriterActivity(VOID)
Definition: lazyrite.c:30
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:990
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
Status
Definition: gdiplustypes.h:24
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220

◆ _Requires_lock_held_() [2/2]

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 347 of file fsctrl.c.

371 {
374 
375  PAGED_CODE();
376 
377  //
378  // We know this is a file system control so we'll case on the
379  // minor function, and call a internal worker routine to complete
380  // the irp.
381  //
382 
383  switch (IrpSp->MinorFunction) {
384 
386 
387  Status = CdUserFsctl( IrpContext, Irp );
388  break;
389 
390  case IRP_MN_MOUNT_VOLUME:
391 
392  Status = CdMountVolume( IrpContext, Irp );
393  break;
394 
396 
397  Status = CdVerifyVolume( IrpContext, Irp );
398  break;
399 
400  default:
401 
404  break;
405  }
406 
407  return Status;
408 }
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define PAGED_CODE()
Definition: video.h:57
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4049
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4048
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4047
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157

◆ _Success_()

_Success_ ( return = FALSE)

Definition at line 2825 of file fsctrl.c.

2868 {
2869  NTSTATUS Status;
2870  ULONG ThisPass = 1;
2871  BOOLEAN FoundVd = FALSE;
2872 
2873  ULONG BaseSector;
2875 
2876  PCDROM_TOC_LARGE CdromToc;
2877 
2878  ULONG VolumeFlags;
2879 
2880  PAGED_CODE();
2881 
2882  //
2883  // If there are no data tracks, don't even bother hunting for descriptors.
2884  //
2885  // This explicitly breaks various non-BlueBook compliant CDs that scribble
2886  // an ISO filesystem on media claiming only audio tracks. Since these
2887  // disks can cause serious problems in some CDROM units, fail fast. I admit
2888  // that it is possible that someone can still record the descriptors in the
2889  // audio track, record a data track (but fail to record descriptors there)
2890  // and still have the disk work. As this form of error worked in NT 4.0, and
2891  // since these disks really do exist, I don't want to change them.
2892  //
2893  // If we wished to support all such media (we don't), it would be neccesary
2894  // to clear this flag on finding ISO or HSG descriptors below.
2895  //
2896 
2897  if (FlagOn(Vcb->VcbState, VCB_STATE_AUDIO_DISK)) {
2898 
2899  return FALSE;
2900  }
2901 
2902  //
2903  // We will make at most two passes through the volume descriptor sequence.
2904  //
2905  // On the first pass we will query for the last session. Using this
2906  // as a starting offset we will attempt to mount the volume. On any failure
2907  // we will go to the second pass and try without using any multi-session
2908  // information.
2909  //
2910  // On the second pass we will start offset from sector zero.
2911  //
2912 
2913  while (!FoundVd && (ThisPass <= 2)) {
2914 
2915  //
2916  // If we aren't at pass 1 then we start at sector 0. Otherwise we
2917  // try to look up the multi-session information.
2918  //
2919 
2920  BaseSector = 0;
2921 
2922  if (ThisPass == 1) {
2923 
2924  CdromToc = NULL;
2925 
2926  //
2927  // Check for whether this device supports XA and multi-session.
2928  //
2929 
2930  _SEH2_TRY {
2931 
2932  //
2933  // Allocate a buffer for the last session information.
2934  //
2935 
2937  sizeof( CDROM_TOC_LARGE ),
2938  TAG_CDROM_TOC );
2939 
2940  RtlZeroMemory( CdromToc, sizeof( CDROM_TOC_LARGE ));
2941 
2942  //
2943  // Query the last session information from the driver.
2944  //
2945 
2946  Status = CdPerformDevIoCtrl( IrpContext,
2948  Vcb->TargetDeviceObject,
2949  CdromToc,
2950  sizeof( CDROM_TOC_LARGE ),
2951  FALSE,
2952  TRUE,
2953  NULL );
2954 
2955  //
2956  // Raise an exception if there was an allocation failure.
2957  //
2958 
2960 
2961  CdRaiseStatus( IrpContext, Status );
2962  }
2963 
2964  //
2965  // We don't handle any errors yet. We will hit that below
2966  // as we try to scan the disk. If we have last session information
2967  // then modify the base sector.
2968  //
2969 
2970  if (NT_SUCCESS( Status ) &&
2971  (CdromToc->FirstTrack != CdromToc->LastTrack)) {
2972 
2973  PCHAR Source, Dest;
2974  ULONG Count;
2975 
2976  Count = 4;
2977 
2978  //
2979  // The track address is BigEndian, we need to flip the bytes.
2980  //
2981 
2982  Source = (PCHAR) &CdromToc->TrackData[0].Address[3];
2983  Dest = (PCHAR) &BaseSector;
2984 
2985  do {
2986 
2987  *Dest++ = *Source--;
2988 
2989  } while (--Count);
2990 
2991  //
2992  // Now adjust the base sector by the block factor of the
2993  // device.
2994  //
2995 
2996  BaseSector /= BlockFactor;
2997 
2998  //
2999  // Make this look like the second pass since we are only using the
3000  // first session. No reason to retry on error.
3001  //
3002 
3003  } else {
3004 
3005  ThisPass += 1;
3006  }
3007 
3008  } _SEH2_FINALLY {
3009 
3010  if (CdromToc != NULL) { CdFreePool( &CdromToc ); }
3011  } _SEH2_END;
3012  }
3013 
3014  //
3015  // Compute the starting sector offset from the start of the session.
3016  //
3017 
3019 
3020  //
3021  // Start by assuming we have neither Hsg or Iso volumes.
3022  //
3023 
3024  VolumeFlags = 0;
3025 
3026  //
3027  // Loop until either error encountered, primary volume descriptor is
3028  // found or a terminal volume descriptor is found.
3029  //
3030 
3031  while (TRUE) {
3032 
3033  //
3034  // Attempt to read the desired sector. Exit directly if operation
3035  // not completed.
3036  //
3037  // If this is pass 1 we will ignore errors in read sectors and just
3038  // go to the next pass.
3039  //
3040 
3041  if (!CdReadSectors( IrpContext,
3042  LlBytesFromSectors( BaseSector + SectorOffset ),
3043  SECTOR_SIZE,
3044  (BOOLEAN) ((ThisPass == 1) || ReturnOnError),
3045  RawIsoVd,
3046  Vcb->TargetDeviceObject )) {
3047 
3048  break;
3049  }
3050 
3051  //
3052  // Check if either an ISO or HSG volume.
3053  //
3054 
3055  if (RtlEqualMemory( CdIsoId,
3056  CdRvdId( RawIsoVd, VCB_STATE_ISO ),
3057  VOL_ID_LEN )) {
3058 
3059  SetFlag( VolumeFlags, VCB_STATE_ISO );
3060 
3061  } else if (RtlEqualMemory( CdHsgId,
3062  CdRvdId( RawIsoVd, VCB_STATE_HSG ),
3063  VOL_ID_LEN )) {
3064 
3065  SetFlag( VolumeFlags, VCB_STATE_HSG );
3066 
3067  //
3068  // We have neither so break out of the loop.
3069  //
3070 
3071  } else {
3072 
3073  break;
3074  }
3075 
3076  //
3077  // Break out if the version number is incorrect or this is
3078  // a terminator.
3079  //
3080 
3081  if ((CdRvdVersion( RawIsoVd, VolumeFlags ) != VERSION_1) ||
3082  (CdRvdDescType( RawIsoVd, VolumeFlags ) == VD_TERMINATOR)) {
3083 
3084  break;
3085  }
3086 
3087  //
3088  // If this is a primary volume descriptor then our search is over.
3089  //
3090 
3091  if (CdRvdDescType( RawIsoVd, VolumeFlags ) == VD_PRIMARY) {
3092 
3093  //
3094  // If we are not in the verify path then initialize the
3095  // fields in the Vcb with basic information from this
3096  // descriptor.
3097  //
3098 
3099  if (!VerifyVolume) {
3100 
3101  //
3102  // Set the flag for the volume type.
3103  //
3104 
3105  SetFlag( Vcb->VcbState, VolumeFlags );
3106 
3107  //
3108  // Store the base sector and sector offset for the
3109  // primary volume descriptor.
3110  //
3111 
3112  Vcb->BaseSector = BaseSector;
3113  Vcb->VdSectorOffset = SectorOffset;
3114  Vcb->PrimaryVdSectorOffset = SectorOffset;
3115  }
3116 
3117  FoundVd = TRUE;
3118  break;
3119  }
3120 
3121  //
3122  // Indicate that we're at the next sector.
3123  //
3124 
3125  SectorOffset += 1;
3126  }
3127 
3128  ThisPass += 1;
3129  }
3130 
3131  return FoundVd;
3132 }
signed char * PCHAR
Definition: retypes.h:7
#define CdRvdVersion(R, F)
Definition: cd.h:265
#define VCB_STATE_AUDIO_DISK
Definition: cdstruc.h:718
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR FirstTrack
Definition: cdstruc.h:448
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS_LARGE]
Definition: cdstruc.h:455
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS FASTCALL CdPerformDevIoCtrl(_In_ PIRP_CONTEXT IrpContext, _In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT Device, _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, _In_ BOOLEAN OverrideVerify, _Out_opt_ PIO_STATUS_BLOCK Iosb)
Definition: deviosup.c:1446
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:52
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
CHAR CdIsoId[]
Definition: cddata.c:62
UCHAR Address[4]
Definition: ntddcdrm.h:108
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define VCB_STATE_HSG
Definition: cdstruc.h:712
#define VOL_ID_LEN
Definition: cd.h:50
#define SectorOffset(L)
Definition: cdprocs.h:1632
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN CdReadSectors(_In_ PIRP_CONTEXT IrpContext, _In_ LONGLONG StartingOffset, _In_ ULONG ByteCount, _In_ BOOLEAN ReturnError, _Out_writes_bytes_(ByteCount) PVOID Buffer, _In_ PDEVICE_OBJECT TargetDeviceObject)
Definition: deviosup.c:1080
#define CdRvdId(R, F)
Definition: cd.h:259
UCHAR LastTrack
Definition: cdstruc.h:449
#define PCHAR
Definition: match.c:90
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define VCB_STATE_ISO
Definition: cdstruc.h:713
#define LlBytesFromSectors(L)
Definition: cdprocs.h:1624
#define FIRST_VD_SECTOR
Definition: cd.h:48
#define VD_TERMINATOR
Definition: cd.h:55
#define Vcb
Definition: cdprocs.h:1425
#define CdPagedPool
Definition: cdprocs.h:1385
#define CdRvdDescType(R, F)
Definition: cd.h:271
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
Status
Definition: gdiplustypes.h:24
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
CHAR CdHsgId[]
Definition: cddata.c:61
#define CdFreePool(x)
Definition: cdprocs.h:2200
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1869
_SEH2_FINALLY
Definition: create.c:4395
#define VD_PRIMARY
Definition: cd.h:56
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define SECTOR_SIZE
Definition: fs.h:22
#define TAG_CDROM_TOC
Definition: cdprocs.h:78
#define VERSION_1
Definition: cd.h:53

◆ CdAllowExtendedDasdIo()

NTSTATUS CdAllowExtendedDasdIo ( _Inout_ PIRP_CONTEXT  IrpContext,
_Inout_ PIRP  Irp 
)

Definition at line 2705 of file fsctrl.c.

2728 {
2729  NTSTATUS Status;
2731 
2732  PFCB Fcb;
2733  PCCB Ccb;
2734 
2735  PAGED_CODE();
2736 
2737  //
2738  // Decode the file object, the only type of opens we accept are
2739  // user volume opens.
2740  //
2741 
2742  if (CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb ) != UserVolumeOpen ) {
2743 
2745  }
2746  else {
2747 
2750  }
2751 
2752  CdCompleteRequest( IrpContext, Irp, Status );
2753  return Status;
2754 }
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1114
Definition: cdstruc.h:1073
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
ULONG Flags
Definition: ntfs.h:532
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ CdFindActiveVolDescriptor()

VOID CdFindActiveVolDescriptor ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PVCB  Vcb,
_Inout_updates_bytes_(ROUND_TO_PAGES(SECTOR_SIZE)) PCHAR  RawIsoVd,
_In_ BOOLEAN  VerifyVolume 
)

Definition at line 3289 of file fsctrl.c.

3325 {
3326  BOOLEAN FoundSecondaryVd = FALSE;
3328 
3329  ULONG Length;
3330 
3331  ULONG Index;
3332 
3333  PAGED_CODE();
3334 
3335  //
3336  // We only look for secondary volume descriptors on an Iso disk.
3337  //
3338 
3339  if ((FlagOn( Vcb->VcbState, VCB_STATE_ISO) || VerifyVolume) && !CdNoJoliet) {
3340 
3341  //
3342  // Scan the volume descriptors from the beginning looking for a valid
3343  // secondary or a terminator.
3344  //
3345 
3347 
3348  while (TRUE) {
3349 
3350  //
3351  // Read the next sector. We should never have an error in this
3352  // path.
3353  //
3354 
3355  CdReadSectors( IrpContext,
3356  LlBytesFromSectors( Vcb->BaseSector + SectorOffset ),
3357  SECTOR_SIZE,
3358  FALSE,
3359  RawIsoVd,
3360  Vcb->TargetDeviceObject );
3361 
3362  //
3363  // Break out if the version number or standard Id is incorrect.
3364  // Also break out if this is a terminator.
3365  //
3366 
3367  if (!RtlEqualMemory( CdIsoId, CdRvdId( RawIsoVd, VCB_STATE_JOLIET ), VOL_ID_LEN ) ||
3368  (CdRvdVersion( RawIsoVd, VCB_STATE_JOLIET ) != VERSION_1) ||
3369  (CdRvdDescType( RawIsoVd, VCB_STATE_JOLIET ) == VD_TERMINATOR)) {
3370 
3371  break;
3372  }
3373 
3374  //
3375  // We have a match if this is a secondary descriptor with a matching
3376  // escape sequence.
3377  //
3378 
3379  if ((CdRvdDescType( RawIsoVd, VCB_STATE_JOLIET ) == VD_SECONDARY) &&
3380  (RtlEqualMemory( CdRvdEsc( RawIsoVd, VCB_STATE_JOLIET ),
3381  CdJolietEscape[0],
3382  ESC_SEQ_LEN ) ||
3384  CdJolietEscape[1],
3385  ESC_SEQ_LEN ) ||
3387  CdJolietEscape[2],
3388  ESC_SEQ_LEN ))) {
3389 
3390  if (!VerifyVolume) {
3391 
3392  //
3393  // Update the Vcb with the new volume descriptor.
3394  //
3395 
3396  ClearFlag( Vcb->VcbState, VCB_STATE_ISO );
3397  SetFlag( Vcb->VcbState, VCB_STATE_JOLIET );
3398 
3399  Vcb->VdSectorOffset = SectorOffset;
3400  }
3401 
3402  FoundSecondaryVd = TRUE;
3403  break;
3404  }
3405 
3406  //
3407  // Otherwise move on to the next sector.
3408  //
3409 
3410  SectorOffset += 1;
3411  }
3412 
3413  //
3414  // If we didn't find the secondary then recover the original volume
3415  // descriptor stored in the second half of the RawIsoVd.
3416  //
3417 
3418  if (!FoundSecondaryVd) {
3419 
3420  RtlCopyMemory( RawIsoVd,
3421  Add2Ptr( RawIsoVd, SECTOR_SIZE, PVOID ),
3422  SECTOR_SIZE );
3423  }
3424  }
3425 
3426  //
3427  // If we're in the verify path, our work is done, since we don't want
3428  // to update any Vcb/Vpb values.
3429  //
3430 
3431  if (VerifyVolume) {
3432 
3433  return;
3434  }
3435 
3436  //
3437  // Compute the serial number and volume label from the volume descriptor.
3438  //
3439 
3440  Vcb->Vpb->SerialNumber = CdSerial32( RawIsoVd, SECTOR_SIZE );
3441 
3442  //
3443  // Make sure the CD label will fit in the Vpb.
3444  //
3445 
3447 
3448  //
3449  // If this is not a Unicode label we must convert it to unicode.
3450  //
3451 
3452  if (!FlagOn( Vcb->VcbState, VCB_STATE_JOLIET )) {
3453 
3454  //
3455  // Convert the label to unicode. If we get any error then use a name
3456  // length of zero.
3457  //
3458 
3459  Vcb->Vpb->VolumeLabelLength = 0;
3460 
3461  if (NT_SUCCESS( RtlOemToUnicodeN( &Vcb->Vpb->VolumeLabel[0],
3463  &Length,
3464  (PCH)CdRvdVolId( RawIsoVd, Vcb->VcbState ),
3465  VOLUME_ID_LENGTH ))) {
3466 
3467  Vcb->Vpb->VolumeLabelLength = (USHORT) Length;
3468  }
3469 
3470  //
3471  // We need to convert from big-endian to little endian.
3472  //
3473 
3474  } else {
3475 
3476  CdConvertBigToLittleEndian( IrpContext,
3477  (PCHAR) CdRvdVolId( RawIsoVd, Vcb->VcbState ),
3479  (PCHAR) Vcb->Vpb->VolumeLabel );
3480 
3481  Vcb->Vpb->VolumeLabelLength = VOLUME_ID_LENGTH * sizeof( WCHAR );
3482  }
3483 
3484  //
3485  // Strip the trailing spaces or zeroes from the name.
3486  //
3487 
3488  Index = Vcb->Vpb->VolumeLabelLength / sizeof( WCHAR );
3489 
3490  while (Index > 0) {
3491 
3492  if ((Vcb->Vpb->VolumeLabel[ Index - 1 ] != L'\0') &&
3493  (Vcb->Vpb->VolumeLabel[ Index - 1 ] != L' ')) {
3494 
3495  break;
3496  }
3497 
3498  Index -= 1;
3499  }
3500 
3501  //
3502  // Now set the final length for the name.
3503  //
3504 
3505  Vcb->Vpb->VolumeLabelLength = (USHORT) (Index * sizeof( WCHAR ));
3506 }
signed char * PCHAR
Definition: retypes.h:7
#define VCB_STATE_JOLIET
Definition: cdstruc.h:714
#define CdRvdVersion(R, F)
Definition: cd.h:265
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define Add2Ptr(PTR, INC)
NTSYSAPI NTSTATUS WINAPI RtlOemToUnicodeN(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD)
CHAR CdIsoId[]
Definition: cddata.c:62
VOID CdConvertBigToLittleEndian(_In_ PIRP_CONTEXT IrpContext, _In_reads_bytes_(ByteCount) PCHAR BigEndian, _In_ ULONG ByteCount, _Out_writes_bytes_(ByteCount) PCHAR LittleEndian)
Definition: namesup.c:110
#define PAGED_CODE()
Definition: video.h:57
#define VOLUME_ID_LENGTH
Definition: cd.h:59
#define VOL_ID_LEN
Definition: cd.h:50
CHAR * PCH
Definition: ntbasedef.h:398
#define SectorOffset(L)
Definition: cdprocs.h:1632
unsigned char BOOLEAN
BOOLEAN CdReadSectors(_In_ PIRP_CONTEXT IrpContext, _In_ LONGLONG StartingOffset, _In_ ULONG ByteCount, _In_ BOOLEAN ReturnError, _Out_writes_bytes_(ByteCount) PVOID Buffer, _In_ PDEVICE_OBJECT TargetDeviceObject)
Definition: deviosup.c:1080
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: iotypes.h:154
#define CdRvdId(R, F)
Definition: cd.h:259
PCHAR CdJolietEscape[]
Definition: cddata.c:86
#define ESC_SEQ_LEN
Definition: cd.h:51
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define VCB_STATE_ISO
Definition: cdstruc.h:713
#define LlBytesFromSectors(L)
Definition: cdprocs.h:1624
#define FIRST_VD_SECTOR
Definition: cd.h:48
#define VD_TERMINATOR
Definition: cd.h:55
#define Vcb
Definition: cdprocs.h:1425
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const WCHAR L[]
Definition: oid.c:1250
#define CdRvdVolId(R, F)
Definition: cd.h:283
BOOLEAN CdNoJoliet
Definition: fsctrl.c:30
#define CdRvdDescType(R, F)
Definition: cd.h:271
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
unsigned short USHORT
Definition: pedump.c:61
#define CdRvdEsc(R, F)
Definition: cd.h:277
#define VD_SECONDARY
Definition: cd.h:57
ULONG CdSerial32(_In_reads_bytes_(ByteCount) PCHAR Buffer, _In_ ULONG ByteCount)
Definition: cddata.c:1185
unsigned int ULONG
Definition: retypes.h:1
#define SECTOR_SIZE
Definition: fs.h:22
#define VERSION_1
Definition: cd.h:53
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ CdIsPathnameValid()

NTSTATUS CdIsPathnameValid ( _Inout_ PIRP_CONTEXT  IrpContext,
_Inout_ PIRP  Irp 
)

Definition at line 2421 of file fsctrl.c.

2443 {
2444  PAGED_CODE();
2445 
2446  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
2447  return STATUS_SUCCESS;
2448 }
_In_ PIRP Irp
Definition: csq.h:116
#define PAGED_CODE()
Definition: video.h:57
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ CdIsVolumeDirty()

NTSTATUS CdIsVolumeDirty ( _Inout_ PIRP_CONTEXT  IrpContext,
_Inout_ PIRP  Irp 
)

Definition at line 2259 of file fsctrl.c.

2280 {
2282 
2284  PFCB Fcb;
2285  PCCB Ccb;
2286 
2288 
2289  PAGED_CODE();
2290 
2291  //
2292  // Get the current stack location and extract the output
2293  // buffer information.
2294  //
2295 
2297 
2298  //
2299  // Get a pointer to the output buffer.
2300  //
2301 
2302  if (Irp->AssociatedIrp.SystemBuffer != NULL) {
2303 
2304  VolumeState = Irp->AssociatedIrp.SystemBuffer;
2305 
2306  } else {
2307 
2310  }
2311 
2312  //
2313  // Make sure the output buffer is large enough and then initialize
2314  // the answer to be that the volume isn't dirty.
2315  //
2316 
2317  if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(ULONG)) {
2318 
2320  return STATUS_INVALID_PARAMETER;
2321  }
2322 
2323  *VolumeState = 0;
2324 
2325  //
2326  // Decode the file object
2327  //
2328 
2329  TypeOfOpen = CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
2330 
2331  if (TypeOfOpen != UserVolumeOpen) {
2332 
2334  return STATUS_INVALID_PARAMETER;
2335  }
2336 
2337  if (Fcb->Vcb->VcbCondition != VcbMounted) {
2338 
2340  return STATUS_VOLUME_DISMOUNTED;
2341  }
2342 
2343  //
2344  // Now set up to return the clean state. CDs obviously can never be dirty
2345  // but we want to make sure we have enforced the full semantics of this call.
2346  //
2347 
2348  Irp->IoStatus.Information = sizeof( ULONG );
2349 
2350  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
2351  return STATUS_SUCCESS;
2352 }
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1987
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: cdstruc.h:1073
#define PAGED_CODE()
Definition: video.h:57
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:593
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
smooth NULL
Definition: ftsmooth.c:416
enum _TYPE_OF_OPEN TYPE_OF_OPEN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
VCB_CONDITION VcbCondition
Definition: cdstruc.h:547
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
unsigned int * PULONG
Definition: retypes.h:1
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:733
unsigned int ULONG
Definition: retypes.h:1
PVCB Vcb
Definition: cdstruc.h:939
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ CdIsVolumeMounted()

NTSTATUS CdIsVolumeMounted ( _Inout_ PIRP_CONTEXT  IrpContext,
_Inout_ PIRP  Irp 
)

Definition at line 2360 of file fsctrl.c.

2381 {
2383 
2384  PFCB Fcb;
2385  PCCB Ccb;
2386 
2387  PAGED_CODE();
2388 
2389  //
2390  // Decode the file object.
2391  //
2392 
2393  CdDecodeFileObject( IrpContext, IrpSp->FileObject, &Fcb, &Ccb );
2394 
2395  if (Fcb != NULL) {
2396 
2397  //
2398  // Disable PopUps, we want to return any error.
2399  //
2400 
2401  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS );
2402 
2403  //
2404  // Verify the Vcb. This will raise in the error condition.
2405  //
2406 
2407  CdVerifyVcb( IrpContext, Fcb->Vcb );
2408  }
2409 
2410  CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
2411 
2412  return STATUS_SUCCESS;
2413 }
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdstruc.h:908
Definition: cdstruc.h:1073
#define IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: cdstruc.h:1228
#define PAGED_CODE()
Definition: video.h:57
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
VOID CdVerifyVcb(_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb)
Definition: verfysup.c:411
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
PVCB Vcb
Definition: cdstruc.h:939
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966

◆ CdReMountOldVcb()

VOID CdReMountOldVcb ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PVCB  OldVcb,
_Inout_ PVCB  NewVcb,
_In_ PDEVICE_OBJECT  DeviceObjectWeTalkTo 
)

Definition at line 518 of file fsctrl.c.

524 {
525  KIRQL SavedIrql;
526  ULONG Index;
527  PUCHAR Buffer;
528 
529  UNREFERENCED_PARAMETER( IrpContext );
530 
531  ObDereferenceObject( OldVcb->TargetDeviceObject );
532 
533  IoAcquireVpbSpinLock( &SavedIrql );
534 
535 #ifdef _MSC_VER
536 #pragma prefast(suppress: 28175, "this is a filesystem driver, touching the vpb is allowed")
537 #endif
538  NewVcb->Vpb->RealDevice->Vpb = OldVcb->Vpb;
539 
540  OldVcb->Vpb->RealDevice = NewVcb->Vpb->RealDevice;
541  OldVcb->TargetDeviceObject = DeviceObjectWeTalkTo;
542 
544  CdUpdateMediaChangeCount( OldVcb, NewVcb->MediaChangeCount);
545 
546  ClearFlag( OldVcb->VcbState, VCB_STATE_VPB_NOT_ON_DEVICE);
547 
548  Buffer = OldVcb->SectorCacheBuffer = NewVcb->SectorCacheBuffer;
549  NewVcb->SectorCacheBuffer = NULL;
550 
551  if (NULL != Buffer) {
552 
553  for (Index = 0; Index < CD_SEC_CACHE_CHUNKS; Index++) {
554 
555  OldVcb->SecCacheChunks[ Index].Buffer = Buffer;
556  OldVcb->SecCacheChunks[ Index].BaseLbn = (ULONG)-1;
557 
559  }
560  }
561 
562  IoReleaseVpbSpinLock( SavedIrql );
563 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
unsigned char * PUCHAR
Definition: retypes.h:3
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
static const UCHAR Index[8]
Definition: usbohci.c:18
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
#define CD_SEC_CACHE_CHUNKS
Definition: cdstruc.h:466
#define CD_SEC_CHUNK_BLOCKS
Definition: cdstruc.h:467
unsigned int ULONG
Definition: retypes.h:1
#define SECTOR_SIZE
Definition: fs.h:22
#define VCB_STATE_VPB_NOT_ON_DEVICE
Definition: cdstruc.h:720
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
#define CdUpdateMediaChangeCount(V, C)
Definition: cdprocs.h:1458
#define CdUpdateVcbCondition(V, C)
Definition: cdprocs.h:1459

◆ CdUnlockVolumeInternal()

NTSTATUS CdUnlockVolumeInternal ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PVCB  Vcb,
_In_opt_ PFILE_OBJECT  FileObject 
)

Definition at line 288 of file fsctrl.c.

317 {
319  KIRQL SavedIrql;
320 
321  UNREFERENCED_PARAMETER( IrpContext );
322 
323  //
324  // Note that we check the VPB_LOCKED flag here rather than the Vcb
325  // lock flag. The Vpb flag is only set for an explicit lock request, not
326  // for the implicit lock obtained on a volume open with zero share mode.
327  //
328 
329  IoAcquireVpbSpinLock( &SavedIrql );
330 
331  if (FlagOn(Vcb->Vpb->Flags, VPB_LOCKED) &&
332  (FileObject == Vcb->VolumeLockFileObject)) {
333 
334  ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED );
335  ClearFlag( Vcb->Vpb->Flags, VPB_LOCKED);
336  Vcb->VolumeLockFileObject = NULL;
338  }
339 
340  IoReleaseVpbSpinLock( SavedIrql );
341 
342  return Status;
343 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define VPB_LOCKED
Definition: iotypes.h:1765
smooth NULL
Definition: ftsmooth.c:416
#define VCB_STATE_LOCKED
Definition: cdstruc.h:715
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define Vcb
Definition: cdprocs.h:1425
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
#define STATUS_NOT_LOCKED
Definition: ntstatus.h:265
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220

Variable Documentation

◆ CdDisable

BOOLEAN CdDisable = FALSE

Definition at line 29 of file fsctrl.c.

◆ CdNoJoliet

BOOLEAN CdNoJoliet = FALSE

Definition at line 30 of file fsctrl.c.

Referenced by CdFindActiveVolDescriptor().