ReactOS 0.4.15-dev-7711-g5627da4
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_ (_Global_critical_region_)
 
NTSTATUS CdUnlockVolumeInternal (_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb, _In_opt_ PFILE_OBJECT FileObject)
 
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_()

_Requires_lock_held_ ( _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}
LONG NTSTATUS
Definition: precomp.h:26
#define CDFS_RESIDUAL_USER_REFERENCE
Definition: cddata.h:44
VOID CdFspClose(_In_opt_ PVCB Vcb)
#define CdReleaseVcb(IC, V)
Definition: cdprocs.h:985
#define CdAcquireVcbExclusive(IC, V, I)
Definition: cdprocs.h:979
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define VCB_STATE_LOCKED
Definition: cdstruc.h:709
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI CcWaitForCurrentLazyWriterActivity(VOID)
Definition: lazyrite.c:30
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
#define Vcb
Definition: cdprocs.h:1415
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define VPB_LOCKED
Definition: iotypes.h:1808

◆ _Success_()

_Success_ ( return = FALSE)

Definition at line 2825 of file fsctrl.c.

2868{
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 ),
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
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}
#define PAGED_CODE()
unsigned char BOOLEAN
#define SECTOR_SIZE
Definition: fs.h:22
#define VD_TERMINATOR
Definition: cd.h:55
#define VOL_ID_LEN
Definition: cd.h:50
#define CdRvdVersion(R, F)
Definition: cd.h:265
#define CdRvdId(R, F)
Definition: cd.h:259
#define CdRvdDescType(R, F)
Definition: cd.h:271
#define VERSION_1
Definition: cd.h:53
#define FIRST_VD_SECTOR
Definition: cd.h:48
#define VD_PRIMARY
Definition: cd.h:56
CHAR CdHsgId[]
Definition: cddata.c:61
CHAR CdIsoId[]
Definition: cddata.c:62
#define LlBytesFromSectors(L)
Definition: cdprocs.h:1614
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 SectorOffset(L)
Definition: cdprocs.h:1622
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 CdFreePool(x)
Definition: cdprocs.h:2190
#define CdPagedPool
Definition: cdprocs.h:1380
#define TAG_CDROM_TOC
Definition: cdprocs.h:86
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1859
#define VCB_STATE_HSG
Definition: cdstruc.h:706
#define VCB_STATE_AUDIO_DISK
Definition: cdstruc.h:712
#define VCB_STATE_ISO
Definition: cdstruc.h:707
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
#define PCHAR
Definition: match.c:90
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
int Count
Definition: noreturn.cpp:7
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:64
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:449
UCHAR LastTrack
Definition: cdstruc.h:443
UCHAR FirstTrack
Definition: cdstruc.h:442
UCHAR Address[4]
Definition: ntddcdrm.h:141
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

◆ CdAllowExtendedDasdIo()

NTSTATUS CdAllowExtendedDasdIo ( _Inout_ PIRP_CONTEXT  IrpContext,
_Inout_ PIRP  Irp 
)

Definition at line 2705 of file fsctrl.c.

2728{
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}
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1108
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793

Referenced by _Success_().

◆ 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 ),
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) &&
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}
#define VOLUME_ID_LENGTH
Definition: cd.h:59
#define CdRvdVolId(R, F)
Definition: cd.h:283
#define CdRvdEsc(R, F)
Definition: cd.h:277
#define ESC_SEQ_LEN
Definition: cd.h:51
#define VD_SECONDARY
Definition: cd.h:57
ULONG CdSerial32(_In_reads_bytes_(ByteCount) PCHAR Buffer, _In_ ULONG ByteCount)
Definition: cddata.c:1185
PCHAR CdJolietEscape[]
Definition: cddata.c:86
BOOLEAN CdNoJoliet
Definition: fsctrl.c:30
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 VCB_STATE_JOLIET
Definition: cdstruc.h:708
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define Add2Ptr(PTR, INC)
_Use_decl_annotations_ NTSTATUS NTAPI RtlOemToUnicodeN(_Out_ PWCHAR UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH OemString, _In_ ULONG OemSize)
Definition: nlsboot.c:282
CHAR * PCH
Definition: ntbasedef.h:391
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ WDFCOLLECTION _In_ ULONG Index
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: iotypes.h:177
#define NT_ASSERT
Definition: rtlfuncs.h:3310
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by _Success_().

◆ 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}

Referenced by _Success_().

◆ 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
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
2335 }
2336
2337 if (Fcb->Vcb->VcbCondition != VcbMounted) {
2338
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}
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
enum _TYPE_OF_OPEN TYPE_OF_OPEN
@ VcbMounted
Definition: cdstruc.h:492
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1998
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
PVCB Vcb
Definition: cdstruc.h:933
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
VCB_CONDITION VcbCondition
Definition: cdstruc.h:541
uint32_t * PULONG
Definition: typedefs.h:59
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166

Referenced by _Success_().

◆ 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}
VOID CdVerifyVcb(_In_ PIRP_CONTEXT IrpContext, _Inout_ PVCB Vcb)
Definition: verfysup.c:411
#define IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: cdstruc.h:1222

Referenced by _Success_().

◆ 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;
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 CdUpdateMediaChangeCount(V, C)
Definition: cdprocs.h:1448
#define CdUpdateVcbCondition(V, C)
Definition: cdprocs.h:1449
#define VCB_STATE_VPB_NOT_ON_DEVICE
Definition: cdstruc.h:714
#define CD_SEC_CACHE_CHUNKS
Definition: cdstruc.h:460
#define CD_SEC_CHUNK_BLOCKS
Definition: cdstruc.h:461
Definition: bufpool.h:45
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
unsigned char * PUCHAR
Definition: typedefs.h:53
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ 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 STATUS_NOT_LOCKED
Definition: ntstatus.h:279

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().