3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module defines all of the globally used procedures in the Cdfs
27 #define INLINE __inline
36 //**** x86 compiler bug ****
40 #define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b))
44 // Here are the different pool tags.
47 #define TAG_CCB 'ccdC' // Ccb
48 #define TAG_CDROM_TOC 'ctdC' // TOC
49 #define TAG_DIRENT_NAME 'nddC' // CdName in dirent
50 #define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration
51 #define TAG_FCB_DATA 'dfdC' // Data Fcb
52 #define TAG_FCB_INDEX 'ifdC' // Index Fcb
53 #define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb
54 #define TAG_FCB_TABLE 'tfdC' // Fcb Table entry
55 #define TAG_FILE_NAME 'nFdC' // Filename buffer
56 #define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name
57 #define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer
58 #define TAG_IO_CONTEXT 'oidC' // Io context for async reads
59 #define TAG_IRP_CONTEXT 'cidC' // Irp Context
60 #define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite
61 #define TAG_MCB_ARRAY 'amdC' // Mcb array
62 #define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry
63 #define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry
64 #define TAG_PREFIX_NAME 'npdC' // Prefix Entry name
65 #define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table
66 #define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name
67 #define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor
68 #define TAG_VPB 'pvdC' // Vpb allocated in filesystem
71 // Tag all of our allocations if tagging is turned on
76 #undef FsRtlAllocatePool
77 #undef FsRtlAllocatePoolWithQuota
78 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC')
79 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC')
81 #endif // POOL_TAGGING
85 // File access check routine, implemented in AcChkSup.c
90 // CdIllegalFcbAccess (
91 // IN PIRP_CONTEXT IrpContext,
92 // IN TYPE_OF_OPEN TypeOfOpen,
93 // IN ACCESS_MASK DesiredAccess
97 #define CdIllegalFcbAccess(IC,T,DA) ( \
98 BooleanFlagOn( (DA), \
99 ((T) != UserVolumeOpen ? \
100 (FILE_WRITE_ATTRIBUTES | \
104 FILE_ADD_SUBDIRECTORY | \
105 FILE_APPEND_DATA) : 0) | \
106 FILE_DELETE_CHILD | \
112 // Allocation support routines, implemented in AllocSup.c
114 // These routines are for querying allocation on individual streams.
119 IN PIRP_CONTEXT IrpContext
,
121 IN LONGLONG FileOffset
,
122 OUT PLONGLONG DiskOffset
,
127 CdAddAllocationFromDirent (
128 IN PIRP_CONTEXT IrpContext
,
130 IN ULONG McbEntryOffset
,
131 IN LONGLONG StartingFileOffset
,
136 CdAddInitialAllocation (
137 IN PIRP_CONTEXT IrpContext
,
139 IN ULONG StartingBlock
,
140 IN LONGLONG DataLength
144 CdTruncateAllocation (
145 IN PIRP_CONTEXT IrpContext
,
147 IN LONGLONG StartingFileOffset
152 IN PIRP_CONTEXT IrpContext
,
158 IN PIRP_CONTEXT IrpContext
,
164 // Buffer control routines for data caching, implemented in CacheSup.c
168 CdCreateInternalStream (
169 IN PIRP_CONTEXT IrpContext
,
175 CdDeleteInternalStream (
176 IN PIRP_CONTEXT IrpContext
,
182 IN PIRP_CONTEXT IrpContext
,
188 IN PIRP_CONTEXT IrpContext
,
190 IN BOOLEAN DismountUnderway
196 // IN PIRP_CONTEXT IrpContext,
201 #define CdUnpinData(IC,B) \
202 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
206 // Device I/O routines, implemented in DevIoSup.c
208 // These routines perform the actual device read and writes. They only affect
209 // the on disk structure and do not alter any other data structures.
214 IN PIRP_CONTEXT IrpContext
,
216 IN LONGLONG StartingOffset
,
222 IN PIRP_CONTEXT IrpContext
,
224 IN LONGLONG StartingOffset
,
230 IN PIRP_CONTEXT IrpContext
,
231 IN LONGLONG StartingOffset
,
233 IN BOOLEAN RaiseOnError
,
235 IN PDEVICE_OBJECT TargetDeviceObject
240 IN PIRP_CONTEXT IrpContext
,
241 IN ULONG BufferLength
,
242 IN BOOLEAN RaiseOnError
247 IN PIRP_CONTEXT IrpContext
,
248 IN ULONG IoControlCode
,
249 IN PDEVICE_OBJECT Device
,
250 OUT PVOID OutputBuffer OPTIONAL
,
251 IN ULONG OutputBufferLength
,
252 IN BOOLEAN InternalDeviceIoControl
,
253 IN BOOLEAN OverrideVerify
,
254 OUT PIO_STATUS_BLOCK Iosb OPTIONAL
260 // IN PIRP_CONTEXT IrpContext
261 // OUT PVOID UserBuffer
264 // Returns pointer to sys address. Will raise on failure.
268 // CdLockUserBuffer (
269 // IN PIRP_CONTEXT IrpContext,
270 // IN ULONG BufferLength
274 #define CdMapUserBuffer(IC, UB) { \
275 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
276 (IC)->Irp->UserBuffer : \
277 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \
278 if (NULL == *(UB)) { \
279 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
284 #define CdLockUserBuffer(IC,BL) { \
285 if ((IC)->Irp->MdlAddress == NULL) { \
286 (VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \
292 // Dirent support routines, implemented in DirSup.c
297 IN PIRP_CONTEXT IrpContext
,
299 IN ULONG DirentOffset
,
300 OUT PDIRENT_ENUM_CONTEXT DirContext
305 IN PIRP_CONTEXT IrpContext
,
307 IN PDIRENT_ENUM_CONTEXT CurrentDirContext
,
308 OUT PDIRENT_ENUM_CONTEXT NextDirContext
312 CdUpdateDirentFromRawDirent (
313 IN PIRP_CONTEXT IrpContext
,
315 IN PDIRENT_ENUM_CONTEXT DirContext
,
316 IN OUT PDIRENT Dirent
321 IN PIRP_CONTEXT IrpContext
,
322 IN OUT PDIRENT Dirent
,
328 IN PIRP_CONTEXT IrpContext
,
331 IN BOOLEAN IgnoreCase
,
332 IN OUT PFILE_ENUM_CONTEXT FileContext
,
333 OUT PCD_NAME
*MatchingName
338 IN PIRP_CONTEXT IrpContext
,
341 IN BOOLEAN IgnoreCase
,
342 IN OUT PFILE_ENUM_CONTEXT FileContext
346 CdFindFileByShortName (
347 IN PIRP_CONTEXT IrpContext
,
350 IN BOOLEAN IgnoreCase
,
351 IN ULONG ShortNameDirentOffset
,
352 IN OUT PFILE_ENUM_CONTEXT FileContext
356 CdLookupNextInitialFileDirent (
357 IN PIRP_CONTEXT IrpContext
,
359 IN OUT PFILE_ENUM_CONTEXT FileContext
363 CdLookupLastFileDirent (
364 IN PIRP_CONTEXT IrpContext
,
366 IN PFILE_ENUM_CONTEXT FileContext
370 CdCleanupFileContext (
371 IN PIRP_CONTEXT IrpContext
,
372 IN PFILE_ENUM_CONTEXT FileContext
377 // CdInitializeFileContext (
378 // IN PIRP_CONTEXT IrpContext,
379 // IN PFILE_ENUM_CONTEXT FileContext
384 // CdInitializeDirent (
385 // IN PIRP_CONTEXT IrpContext,
390 // CdInitializeDirContext (
391 // IN PIRP_CONTEXT IrpContext,
392 // IN PDIRENT_ENUM_CONTEXT DirContext
397 // IN PIRP_CONTEXT IrpContext,
402 // CdCleanupDirContext (
403 // IN PIRP_CONTEXT IrpContext,
404 // IN PDIRENT_ENUM_CONTEXT DirContext
408 // CdLookupInitialFileDirent (
409 // IN PIRP_CONTEXT IrpContext,
411 // IN PFILE_ENUM_CONTEXT FileContext,
412 // IN ULONG DirentOffset
416 #define CdInitializeFileContext(IC,FC) { \
417 RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \
418 (FC)->PriorDirent = &(FC)->Dirents[0]; \
419 (FC)->InitialDirent = &(FC)->Dirents[1]; \
420 (FC)->CurrentDirent = &(FC)->Dirents[2]; \
421 (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \
422 (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \
425 #define CdInitializeDirent(IC,D) \
426 RtlZeroMemory( D, sizeof( DIRENT ))
428 #define CdInitializeDirContext(IC,DC) \
429 RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT ))
431 #define CdCleanupDirent(IC,D) { \
432 if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \
433 CdFreePool( &(D)->CdFileName.FileName.Buffer ); \
437 #define CdCleanupDirContext(IC,DC) \
438 CdUnpinData( (IC), &(DC)->Bcb )
440 #define CdLookupInitialFileDirent(IC,F,FC,DO) \
441 CdLookupDirent( IC, \
444 &(FC)->InitialDirent->DirContext ); \
445 CdUpdateDirentFromRawDirent( IC, \
447 &(FC)->InitialDirent->DirContext, \
448 &(FC)->InitialDirent->Dirent )
452 // The following routines are used to manipulate the fscontext fields
453 // of the file object, implemented in FilObSup.c
457 // Type of opens. FilObSup.c depends on this order.
460 typedef enum _TYPE_OF_OPEN
{
462 UnopenedFileObject
= 0,
470 typedef TYPE_OF_OPEN
*PTYPE_OF_OPEN
;
474 IN PIRP_CONTEXT IrpContext
,
475 IN PFILE_OBJECT FileObject
,
476 IN TYPE_OF_OPEN TypeOfOpen
,
477 IN PFCB Fcb OPTIONAL
,
483 IN PIRP_CONTEXT IrpContext
,
484 IN PFILE_OBJECT FileObject
,
490 CdFastDecodeFileObject (
491 IN PFILE_OBJECT FileObject
,
497 // Name support routines, implemented in NameSup.c
501 CdConvertNameToCdName (
502 IN PIRP_CONTEXT IrpContext
,
503 IN OUT PCD_NAME CdName
507 CdConvertBigToLittleEndian (
508 IN PIRP_CONTEXT IrpContext
,
511 OUT PCHAR LittleEndian
516 IN PIRP_CONTEXT IrpContext
,
518 IN OUT PCD_NAME UpcaseName
523 IN PIRP_CONTEXT IrpContext
,
524 IN OUT PUNICODE_STRING RemainingName
,
525 OUT PUNICODE_STRING FinalName
530 IN PIRP_CONTEXT IrpContext
,
531 IN UNICODE_STRING FileName
535 CdGenerate8dot3Name (
536 IN PIRP_CONTEXT IrpContext
,
537 IN PUNICODE_STRING FileName
,
538 IN ULONG DirentOffset
,
539 OUT PWCHAR ShortFileName
,
540 OUT PUSHORT ShortByteCount
544 CdIsNameInExpression (
545 IN PIRP_CONTEXT IrpContext
,
546 IN PCD_NAME CurrentName
,
547 IN PCD_NAME SearchExpression
,
548 IN ULONG WildcardFlags
,
549 IN BOOLEAN CheckVersion
553 CdShortNameDirentOffset (
554 IN PIRP_CONTEXT IrpContext
,
555 IN PUNICODE_STRING Name
558 FSRTL_COMPARISON_RESULT
560 IN PIRP_CONTEXT IrpContext
,
561 IN PUNICODE_STRING NameA
,
562 IN PUNICODE_STRING NameB
567 // Filesystem control operations. Implemented in Fsctrl.c
571 CdLockVolumeInternal (
572 IN PIRP_CONTEXT IrpContext
,
574 IN PFILE_OBJECT FileObject OPTIONAL
578 CdUnlockVolumeInternal (
579 IN PIRP_CONTEXT IrpContext
,
581 IN PFILE_OBJECT FileObject OPTIONAL
586 // Path table enumeration routines. Implemented in PathSup.c
591 IN PIRP_CONTEXT IrpContext
,
592 IN ULONG PathEntryOffset
,
594 IN BOOLEAN VerifyBounds
,
595 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
599 CdLookupNextPathEntry (
600 IN PIRP_CONTEXT IrpContext
,
601 IN OUT PPATH_ENUM_CONTEXT PathContext
,
602 IN OUT PPATH_ENTRY PathEntry
607 IN PIRP_CONTEXT IrpContext
,
610 IN BOOLEAN IgnoreCase
,
611 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
615 CdUpdatePathEntryName (
616 IN PIRP_CONTEXT IrpContext
,
617 IN OUT PPATH_ENTRY PathEntry
,
618 IN BOOLEAN IgnoreCase
623 // CdInitializeCompoundPathEntry (
624 // IN PIRP_CONTEXT IrpContext,
625 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
629 // CdCleanupCompoundPathEntry (
630 // IN PIRP_CONTEXT IrpContext,
631 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
635 #define CdInitializeCompoundPathEntry(IC,CP) \
636 RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY ))
638 #define CdCleanupCompoundPathEntry(IC,CP) { \
639 CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \
640 if ((CP)->PathContext.AllocatedData) { \
641 CdFreePool( &(CP)->PathContext.Data ); \
643 if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \
644 CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \
650 // Largest matching prefix searching routines, implemented in PrefxSup.c
655 IN PIRP_CONTEXT IrpContext
,
658 IN BOOLEAN IgnoreCase
,
659 IN BOOLEAN ShortNameMatch
,
665 IN PIRP_CONTEXT IrpContext
,
671 IN PIRP_CONTEXT IrpContext
,
672 IN OUT PFCB
*CurrentFcb
,
673 IN OUT PUNICODE_STRING RemainingName
,
674 IN BOOLEAN IgnoreCase
679 // Synchronization routines. Implemented in Resrcsup.c
681 // The following routines/macros are used to synchronize the in-memory structures.
683 // Routine/Macro Synchronizes Subsequent
685 // CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData
686 // CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb
687 // CdAcquireVcbShared Vcb for open/close CdReleaseVcb
688 // CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles
689 // CdAcquireFileExclusive Locks out file operations CdReleaseFile
690 // CdAcquireFileShared Files for file operations CdReleaseFile
691 // CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb
692 // CdAcquireFcbShared Fcb for open/close CdReleaseFcb
693 // CdLockCdData Fields in CdData CdUnlockCdData
694 // CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb
695 // CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb
698 typedef enum _TYPE_OF_ACQUIRE
{
702 AcquireSharedStarveExclusive
704 } TYPE_OF_ACQUIRE
, *PTYPE_OF_ACQUIRE
;
708 IN PIRP_CONTEXT IrpContext
,
709 IN PERESOURCE Resource
,
710 IN BOOLEAN IgnoreWait
,
711 IN TYPE_OF_ACQUIRE Type
717 // IN PIRP_CONTEXT IrpContext
722 // IN PIRP_CONTEXT IrpContext
726 // CdAcquireVcbExclusive (
727 // IN PIRP_CONTEXT IrpContext,
729 // IN BOOLEAN IgnoreWait
733 // CdAcquireVcbShared (
734 // IN PIRP_CONTEXT IrpContext,
736 // IN BOOLEAN IgnoreWait
741 // IN PIRP_CONTEXT IrpContext,
746 // CdAcquireAllFiles (
752 // CdReleaseAllFiles (
758 // CdAcquireFileExclusive (
759 // IN PIRP_CONTEXT IrpContext,
764 // CdAcquireFileShared (
765 // IN PIRP_CONTEXT IrpContext,
771 // IN PIRP_CONTEXT IrpContext,
776 // CdAcquireFcbExclusive (
777 // IN PIRP_CONTEXT IrpContext,
779 // IN BOOLEAN IgnoreWait
783 // CdAcquireFcbShared (
784 // IN PIRP_CONTEXT IrpContext,
786 // IN BOOLEAN IgnoreWait
791 // IN PIRP_CONTEXT IrpContext,
805 // IN PIRP_CONTEXT IrpContext
810 // IN PIRP_CONTEXT IrpContext
815 // IN PIRP_CONTEXT IrpContext,
821 // IN PIRP_CONTEXT IrpContext,
826 #define CdAcquireCdData(IC) \
827 ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
829 #define CdReleaseCdData(IC) \
830 ExReleaseResourceLite( &CdData.DataResource )
832 #define CdAcquireVcbExclusive(IC,V,I) \
833 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
835 #define CdAcquireVcbShared(IC,V,I) \
836 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
838 #define CdReleaseVcb(IC,V) \
839 ExReleaseResourceLite( &(V)->VcbResource )
841 #define CdAcquireAllFiles(IC,V) \
842 CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
844 #define CdReleaseAllFiles(IC,V) \
845 ExReleaseResourceLite( &(V)->FileResource )
847 #define CdAcquireFileExclusive(IC,F) \
848 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
850 #define CdAcquireFileShared(IC,F) \
851 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
853 #define CdAcquireFileSharedStarveExclusive(IC,F) \
854 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
856 #define CdReleaseFile(IC,F) \
857 ExReleaseResourceLite( (F)->Resource )
859 #define CdAcquireFcbExclusive(IC,F,I) \
860 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
862 #define CdAcquireFcbShared(IC,F,I) \
863 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
865 #define CdReleaseFcb(IC,F) \
866 ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
868 #define CdLockCdData() \
869 ExAcquireFastMutex( &CdData.CdDataMutex ); \
870 CdData.CdDataLockThread = PsGetCurrentThread()
872 #define CdUnlockCdData() \
873 CdData.CdDataLockThread = NULL; \
874 ExReleaseFastMutex( &CdData.CdDataMutex )
876 #define CdLockVcb(IC,V) \
877 ExAcquireFastMutex( &(V)->VcbMutex ); \
878 ASSERT( NULL == (V)->VcbLockThread); \
879 (V)->VcbLockThread = PsGetCurrentThread()
881 #define CdUnlockVcb(IC,V) \
882 ASSERT( NULL != (V)->VcbLockThread); \
883 (V)->VcbLockThread = NULL; \
884 ExReleaseFastMutex( &(V)->VcbMutex )
886 #define CdLockFcb(IC,F) { \
887 PVOID _CurrentThread = PsGetCurrentThread(); \
888 if (_CurrentThread != (F)->FcbLockThread) { \
889 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
890 ASSERT( (F)->FcbLockCount == 0 ); \
891 (F)->FcbLockThread = _CurrentThread; \
893 (F)->FcbLockCount += 1; \
896 #define CdUnlockFcb(IC,F) { \
897 (F)->FcbLockCount -= 1; \
898 if ((F)->FcbLockCount == 0) { \
899 (F)->FcbLockThread = NULL; \
900 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
905 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
912 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
918 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
925 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
931 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
932 CdAcquireForCreateSection (
933 IN PFILE_OBJECT FileObject
937 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
938 CdReleaseForCreateSection (
939 IN PFILE_OBJECT FileObject
944 // In-memory structure support routines. Implemented in StrucSup.c
949 IN PIRP_CONTEXT IrpContext
,
951 IN PDEVICE_OBJECT TargetDeviceObject
,
953 IN PCDROM_TOC CdromToc
,
955 IN ULONG TocTrackCount
,
956 IN ULONG TocDiskFlags
,
957 IN ULONG BlockFactor
,
958 IN ULONG MediaChangeCount
962 CdUpdateVcbFromVolDescriptor (
963 IN PIRP_CONTEXT IrpContext
,
965 IN PCHAR RawIsoVd OPTIONAL
970 IN PIRP_CONTEXT IrpContext
,
976 IN PIRP_CONTEXT IrpContext
,
978 IN NODE_TYPE_CODE NodeTypeCode
,
979 OUT PBOOLEAN FcbExisted OPTIONAL
983 CdInitializeFcbFromPathEntry (
984 IN PIRP_CONTEXT IrpContext
,
986 IN PFCB ParentFcb OPTIONAL
,
987 IN PPATH_ENTRY PathEntry
991 CdInitializeFcbFromFileContext (
992 IN PIRP_CONTEXT IrpContext
,
994 IN PFCB ParentFcb OPTIONAL
,
995 IN PFILE_ENUM_CONTEXT FileContext
1000 IN PIRP_CONTEXT IrpContext
,
1007 IN PIRP_CONTEXT IrpContext
,
1013 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1015 IN BOOLEAN RaiseOnError
1020 IN PIRP_CONTEXT IrpContext
,
1021 IN PFILE_LOCK FileLock
1025 CdCreateIrpContext (
1031 CdCleanupIrpContext (
1032 IN PIRP_CONTEXT IrpContext
,
1037 CdInitializeStackIrpContext (
1038 OUT PIRP_CONTEXT IrpContext
,
1039 IN PIRP_CONTEXT_LITE IrpContextLite
1043 // PIRP_CONTEXT_LITE
1044 // CdCreateIrpContextLite (
1045 // IN PIRP_CONTEXT IrpContext
1049 // CdFreeIrpContextLite (
1050 // IN PIRP_CONTEXT_LITE IrpContextLite
1054 #define CdCreateIrpContextLite(IC) \
1055 ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
1057 #define CdFreeIrpContextLite(ICL) \
1058 CdFreePool( &(ICL) )
1061 CdTeardownStructures (
1062 IN PIRP_CONTEXT IrpContext
,
1063 IN PFCB StartingFcb
,
1064 OUT PBOOLEAN RemovedStartingFcb
1069 // CdIncrementCleanupCounts (
1070 // IN PIRP_CONTEXT IrpContext,
1075 // CdDecrementCleanupCounts (
1076 // IN PIRP_CONTEXT IrpContext,
1081 // CdIncrementReferenceCounts (
1082 // IN PIRP_CONTEXT IrpContext,
1084 // IN ULONG ReferenceCount
1085 // IN ULONG UserReferenceCount
1089 // CdDecrementReferenceCounts (
1090 // IN PIRP_CONTEXT IrpContext,
1092 // IN ULONG ReferenceCount
1093 // IN ULONG UserReferenceCount
1097 // CdIncrementFcbReference (
1098 // IN PIRP_CONTEXT IrpContext,
1103 // CdDecrementFcbReference (
1104 // IN PIRP_CONTEXT IrpContext,
1109 #define CdIncrementCleanupCounts(IC,F) { \
1110 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1111 (F)->FcbCleanup += 1; \
1112 (F)->Vcb->VcbCleanup += 1; \
1115 #define CdDecrementCleanupCounts(IC,F) { \
1116 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1117 (F)->FcbCleanup -= 1; \
1118 (F)->Vcb->VcbCleanup -= 1; \
1121 #define CdIncrementReferenceCounts(IC,F,C,UC) { \
1122 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1123 (F)->FcbReference += (C); \
1124 (F)->FcbUserReference += (UC); \
1125 (F)->Vcb->VcbReference += (C); \
1126 (F)->Vcb->VcbUserReference += (UC); \
1129 #define CdDecrementReferenceCounts(IC,F,C,UC) { \
1130 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1131 (F)->FcbReference -= (C); \
1132 (F)->FcbUserReference -= (UC); \
1133 (F)->Vcb->VcbReference -= (C); \
1134 (F)->Vcb->VcbUserReference -= (UC); \
1139 // CdAllocateIoContext (
1143 // CdFreeIoContext (
1144 // PCD_IO_CONTEXT IoContext
1148 #define CdAllocateIoContext() \
1149 FsRtlAllocatePoolWithTag( CdNonPagedPool, \
1150 sizeof( CD_IO_CONTEXT ), \
1153 #define CdFreeIoContext(IO) CdFreePool( &(IO) )
1157 IN PIRP_CONTEXT IrpContext
,
1164 IN PIRP_CONTEXT IrpContext
,
1166 IN PVOID
*RestartKey
1171 IN PIRP_CONTEXT IrpContext
,
1172 IN PDEVICE_OBJECT TargetDeviceObject
,
1173 IN PCDROM_TOC CdromToc
,
1174 IN OUT PULONG Length
,
1175 OUT PULONG TrackCount
,
1176 OUT PULONG DiskFlags
1180 // For debugging purposes we sometimes want to allocate our structures from nonpaged
1181 // pool so that in the kernel debugger we can walk all the structures.
1184 #define CdPagedPool PagedPool
1185 #define CdNonPagedPool NonPagedPool
1186 #define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned
1190 // Verification support routines. Contained in verfysup.c
1193 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1196 CdOperationIsDasdOpen(
1197 IN PIRP_CONTEXT IrpContext
1200 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( IrpContext
->Irp
);
1202 return ((IrpContext
->MajorFunction
== IRP_MJ_CREATE
) &&
1203 (IrpSp
->FileObject
->FileName
.Length
== 0) &&
1204 (IrpSp
->FileObject
->RelatedFileObject
== NULL
));
1210 IN PIRP_CONTEXT IrpContext
,
1212 IN PDEVICE_OBJECT DeviceToVerify
1216 CdCheckForDismount (
1217 IN PIRP_CONTEXT IrpContext
,
1224 IN PIRP_CONTEXT IrpContext
,
1229 CdVerifyFcbOperation (
1230 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1236 IN PIRP_CONTEXT IrpContext
,
1242 // Macros to abstract device verify flag changes.
1245 #define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
1246 #define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C)
1248 #define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1250 #define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1253 #define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
1258 // IN PIRP_CONTEXT IrpContext,
1259 // IN NTSTATUS Status
1263 #define CdIsRawDevice(IC,S) ( \
1264 ((S) == STATUS_DEVICE_NOT_READY) || \
1265 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
1270 // Work queue routines for posting and retrieving an Irp, implemented in
1276 IN PIRP_CONTEXT IrpContext
,
1281 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1283 IN PIRP_CONTEXT IrpContext
,
1288 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1290 IN PIRP_CONTEXT IrpContext
,
1296 // Miscellaneous support routines
1300 // This macro returns TRUE if a flag in a set of flags is on and FALSE
1304 /* ReactOS Change: GCC doesn't understand the comment style */
1306 //#ifndef BooleanFlagOn
1307 //#define BooleanFlagOn(F,SF) ( \
1308 // (BOOLEAN)(((F) & (SF)) != 0) \
1313 //#define SetFlag(Flags,SingleFlag) { \
1314 // (Flags) |= (SingleFlag); \
1319 //#define ClearFlag(Flags,SingleFlag) { \
1320 // (Flags) &= ~(SingleFlag); \
1328 // IN PVOID Pointer,
1329 // IN ULONG Increment
1335 // IN PVOID BasePtr,
1336 // IN PVOID OffsetPtr
1340 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
1342 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
1345 // This macro takes a pointer (or ulong) and returns its rounded up word
1349 #define WordAlign(Ptr) ( \
1350 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
1354 // This macro takes a pointer (or ulong) and returns its rounded up longword
1358 #define LongAlign(Ptr) ( \
1359 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
1363 // This macro takes a pointer (or ulong) and returns its rounded up quadword
1367 #define QuadAlign(Ptr) ( \
1368 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
1372 // The following macros round up and down to sector boundaries.
1375 #define SectorAlign(L) ( \
1376 ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1379 #define LlSectorAlign(L) ( \
1380 ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1383 #define SectorTruncate(L) ( \
1384 ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \
1387 #define LlSectorTruncate(L) ( \
1388 ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \
1391 #define BytesFromSectors(L) ( \
1392 ((ULONG) (L)) << SECTOR_SHIFT \
1395 #define SectorsFromBytes(L) ( \
1396 ((ULONG) (L)) >> SECTOR_SHIFT \
1399 #define LlBytesFromSectors(L) ( \
1400 Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1403 #define LlSectorsFromBytes(L) ( \
1404 Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1407 #define SectorOffset(L) ( \
1408 ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \
1411 #define SectorBlockOffset(V,LB) ( \
1412 ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \
1415 #define BytesFromBlocks(V,B) ( \
1416 (ULONG) (B) << (V)->BlockToByteShift \
1419 #define LlBytesFromBlocks(V,B) ( \
1420 Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \
1423 #define BlockAlign(V,L) ( \
1424 ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \
1428 // Carefully make sure the mask is sign extended to 64bits
1431 #define LlBlockAlign(V,L) ( \
1432 ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \
1435 #define BlockOffset(V,L) ( \
1436 ((ULONG) (L)) & (V)->BlockMask \
1439 #define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE)
1442 // The following types and macros are used to help unpack the packed and
1443 // misaligned fields found in the Bios parameter block
1446 typedef union _UCHAR1
{
1448 UCHAR ForceAlignment
;
1451 typedef union _UCHAR2
{
1453 USHORT ForceAlignment
;
1456 typedef union _UCHAR4
{
1458 ULONG ForceAlignment
;
1461 typedef union _USHORT2
{
1463 ULONG ForceAlignment
;
1464 } USHORT2
, *PUSHORT2
;
1467 // This macro copies an unaligned src byte to an aligned dst byte
1470 #define CopyUchar1(Dst,Src) { \
1471 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
1475 // This macro copies an unaligned src word to an aligned dst word
1478 #define CopyUchar2(Dst,Src) { \
1479 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
1483 // This macro copies an unaligned src longword to an aligned dsr longword
1486 #define CopyUchar4(Dst,Src) { \
1487 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
1491 // This macro copies an unaligned src longword to an aligned dsr longword
1492 // accessing the source on a word boundary.
1495 #define CopyUshort2(Dst,Src) { \
1496 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
1501 // Following routines handle entry in and out of the filesystem. They are
1502 // contained in CdData.c
1507 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject
,
1513 IN PIRP_CONTEXT IrpContext
,
1514 IN PEXCEPTION_POINTERS ExceptionPointer
1518 CdProcessException (
1519 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1521 IN NTSTATUS ExceptionCode
1526 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1527 IN PIRP Irp OPTIONAL
,
1534 // IN PRIP_CONTEXT IrpContext,
1535 // IN NT_STATUS Status
1539 // CdNormalizeAndRaiseStatus (
1540 // IN PRIP_CONTEXT IrpContext,
1541 // IN NT_STATUS Status
1546 #define AssertVerifyDevice(C, S) \
1547 ASSERT( (C) == NULL || \
1548 FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \
1549 !((S) == STATUS_VERIFY_REQUIRED && \
1550 IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
1552 #define AssertVerifyDeviceIrp(I) \
1553 ASSERT( (I) == NULL || \
1554 !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \
1555 ((I)->Tail.Overlay.Thread == NULL || \
1556 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
1558 #define AssertVerifyDevice(C, S)
1559 #define AssertVerifyDeviceIrp(I)
1568 IN PIRP_CONTEXT IrpContext
,
1570 IN BOOLEAN NormalizeStatus
,
1571 IN OPTIONAL ULONG FileId
,
1572 IN OPTIONAL ULONG Line
1581 IN PIRP_CONTEXT IrpContext
,
1583 IN BOOLEAN NormalizeStatus
,
1588 if (NormalizeStatus
) {
1590 IrpContext
->ExceptionStatus
= FsRtlNormalizeNtstatus( Status
, STATUS_UNEXPECTED_IO_ERROR
);
1594 IrpContext
->ExceptionStatus
= Status
;
1597 IrpContext
->RaisedAtLineFile
= (Fileid
<< 16) | Line
;
1599 ExRaiseStatus( IrpContext
->ExceptionStatus
);
1604 #define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__);
1605 #define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__);
1608 // Following are the fast entry points.
1612 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1613 CdFastQueryBasicInfo (
1614 IN PFILE_OBJECT FileObject
,
1616 IN OUT PFILE_BASIC_INFORMATION Buffer
,
1617 OUT PIO_STATUS_BLOCK IoStatus
,
1618 IN PDEVICE_OBJECT DeviceObject
1622 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1623 CdFastQueryStdInfo (
1624 IN PFILE_OBJECT FileObject
,
1626 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
1627 OUT PIO_STATUS_BLOCK IoStatus
,
1628 IN PDEVICE_OBJECT DeviceObject
1632 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1634 IN PFILE_OBJECT FileObject
,
1635 IN PLARGE_INTEGER FileOffset
,
1636 IN PLARGE_INTEGER Length
,
1637 PEPROCESS ProcessId
,
1639 BOOLEAN FailImmediately
,
1640 BOOLEAN ExclusiveLock
,
1641 OUT PIO_STATUS_BLOCK IoStatus
,
1642 IN PDEVICE_OBJECT DeviceObject
1646 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1647 CdFastUnlockSingle (
1648 IN PFILE_OBJECT FileObject
,
1649 IN PLARGE_INTEGER FileOffset
,
1650 IN PLARGE_INTEGER Length
,
1651 PEPROCESS ProcessId
,
1653 OUT PIO_STATUS_BLOCK IoStatus
,
1654 IN PDEVICE_OBJECT DeviceObject
1658 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1660 IN PFILE_OBJECT FileObject
,
1661 PEPROCESS ProcessId
,
1662 OUT PIO_STATUS_BLOCK IoStatus
,
1663 IN PDEVICE_OBJECT DeviceObject
1667 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1668 CdFastUnlockAllByKey (
1669 IN PFILE_OBJECT FileObject
,
1672 OUT PIO_STATUS_BLOCK IoStatus
,
1673 IN PDEVICE_OBJECT DeviceObject
1677 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1678 CdFastIoCheckIfPossible (
1679 IN PFILE_OBJECT FileObject
,
1680 IN PLARGE_INTEGER FileOffset
,
1684 IN BOOLEAN CheckForReadOperation
,
1685 OUT PIO_STATUS_BLOCK IoStatus
,
1686 IN PDEVICE_OBJECT DeviceObject
1690 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1691 CdFastQueryNetworkInfo (
1692 IN PFILE_OBJECT FileObject
,
1694 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1695 OUT PIO_STATUS_BLOCK IoStatus
,
1696 IN PDEVICE_OBJECT DeviceObject
1700 // Following are the routines to handle the top level thread logic.
1704 CdSetThreadContext (
1705 IN PIRP_CONTEXT IrpContext
,
1706 IN PTHREAD_CONTEXT ThreadContext
1712 // CdRestoreThreadContext (
1713 // IN PIRP_CONTEXT IrpContext
1717 #define CdRestoreThreadContext(IC) \
1718 (IC)->ThreadContext->Cdfs = 0; \
1719 IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \
1720 (IC)->ThreadContext = NULL
1729 // The following macro is used to determine if an FSD thread can block
1730 // for I/O or wait for a resource. It returns TRUE if the thread can
1731 // block and FALSE otherwise. This attribute can then be used to call
1732 // the FSD & FSP common work routine with the proper wait value.
1735 #define CanFsdWait(I) IoIsOperationSynchronous(I)
1738 // The following macro is used to set the fast i/o possible bits in the
1741 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
1743 // FastIoIsQuestionable - If there are file locks.
1745 // FastIoIsPossible - In all other cases.
1749 #define CdIsFastIoPossible(F) ((BOOLEAN) \
1750 ((((F)->Vcb->VcbCondition != VcbMounted ) || \
1751 !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
1753 FastIoIsNotPossible : \
1755 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
1757 FastIoIsQuestionable : \
1759 FastIoIsPossible)) \
1764 // The FSP level dispatch/main routine. This is the routine that takes
1765 // IRP's off of the work queue and calls the appropriate FSP level
1770 CdFspDispatch ( // implemented in FspDisp.c
1771 IN PIRP_CONTEXT IrpContext
1775 CdFspClose ( // implemented in Close.c
1776 IN PVCB Vcb OPTIONAL
1780 // The following routines are the entry points for the different operations
1781 // based on the IrpSp major functions.
1785 CdCommonCreate ( // Implemented in Create.c
1786 IN PIRP_CONTEXT IrpContext
,
1791 CdCommonClose ( // Implemented in Close.c
1792 IN PIRP_CONTEXT IrpContext
,
1797 CdCommonRead ( // Implemented in Read.c
1798 IN PIRP_CONTEXT IrpContext
,
1803 CdCommonQueryInfo ( // Implemented in FileInfo.c
1804 IN PIRP_CONTEXT IrpContext
,
1809 CdCommonSetInfo ( // Implemented in FileInfo.c
1810 IN PIRP_CONTEXT IrpContext
,
1815 CdCommonQueryVolInfo ( // Implemented in VolInfo.c
1816 IN PIRP_CONTEXT IrpContext
,
1821 CdCommonDirControl ( // Implemented in DirCtrl.c
1822 IN PIRP_CONTEXT IrpContext
,
1827 CdCommonFsControl ( // Implemented in FsCtrl.c
1828 IN PIRP_CONTEXT IrpContext
,
1833 CdCommonDevControl ( // Implemented in DevCtrl.c
1834 IN PIRP_CONTEXT IrpContext
,
1839 CdCommonLockControl ( // Implemented in LockCtrl.c
1840 IN PIRP_CONTEXT IrpContext
,
1845 CdCommonCleanup ( // Implemented in Cleanup.c
1846 IN PIRP_CONTEXT IrpContext
,
1851 CdCommonPnp ( // Implemented in Pnp.c
1852 IN PIRP_CONTEXT IrpContext
,
1858 // The following macros are used to establish the semantics needed
1859 // to do a return from within a try-finally clause. As a rule every
1860 // try clause must end with a label call try_exit. For example,
1866 // try_exit: NOTHING;
1873 // Every return statement executed inside of a try clause should use the
1874 // try_return macro. If the compiler fully supports the try-finally construct
1875 // then the macro should be
1877 // #define try_return(S) { return(S); }
1879 // If the compiler does not support the try-finally construct then the macro
1882 // #define try_return(S) { S; goto try_exit; }
1884 /* ReactOS Change: Remove SEH */
1886 #define leave goto exitLabel;
1887 #define finally if (0) goto exitLabel; exitLabel:
1888 #define except(x) while (0)
1889 #define GetExceptionCode() 0
1890 #define AbnormalTermination() 0
1892 #define try_return(S) { S; goto try_exit; }
1893 #define try_leave(S) { S; leave; }
1897 // Encapsulate safe pool freeing
1899 /* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */
1900 #define CdFreePool(x) _CdFreePool((PVOID*)(x))
1902 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1903 static inline void _CdFreePool(
1907 if (*Pool
!= NULL
) {