3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module defines all of the globally used procedures in the Cdfs
26 #include <pseh/pseh2.h>
30 #define INLINE __inline
39 //**** x86 compiler bug ****
43 #define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b))
47 // Here are the different pool tags.
50 #define TAG_CCB 'ccdC' // Ccb
51 #define TAG_CDROM_TOC 'ctdC' // TOC
52 #define TAG_DIRENT_NAME 'nddC' // CdName in dirent
53 #define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration
54 #define TAG_FCB_DATA 'dfdC' // Data Fcb
55 #define TAG_FCB_INDEX 'ifdC' // Index Fcb
56 #define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb
57 #define TAG_FCB_TABLE 'tfdC' // Fcb Table entry
58 #define TAG_FILE_NAME 'nFdC' // Filename buffer
59 #define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name
60 #define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer
61 #define TAG_IO_CONTEXT 'oidC' // Io context for async reads
62 #define TAG_IRP_CONTEXT 'cidC' // Irp Context
63 #define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite
64 #define TAG_MCB_ARRAY 'amdC' // Mcb array
65 #define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry
66 #define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry
67 #define TAG_PREFIX_NAME 'npdC' // Prefix Entry name
68 #define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table
69 #define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name
70 #define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor
71 #define TAG_VPB 'pvdC' // Vpb allocated in filesystem
74 // Tag all of our allocations if tagging is turned on
79 #undef FsRtlAllocatePool
80 #undef FsRtlAllocatePoolWithQuota
81 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC')
82 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC')
84 #endif // POOL_TAGGING
88 // File access check routine, implemented in AcChkSup.c
93 // CdIllegalFcbAccess (
94 // IN PIRP_CONTEXT IrpContext,
95 // IN TYPE_OF_OPEN TypeOfOpen,
96 // IN ACCESS_MASK DesiredAccess
100 #define CdIllegalFcbAccess(IC,T,DA) ( \
101 BooleanFlagOn( (DA), \
102 ((T) != UserVolumeOpen ? \
103 (FILE_WRITE_ATTRIBUTES | \
107 FILE_ADD_SUBDIRECTORY | \
108 FILE_APPEND_DATA) : 0) | \
109 FILE_DELETE_CHILD | \
115 // Allocation support routines, implemented in AllocSup.c
117 // These routines are for querying allocation on individual streams.
122 IN PIRP_CONTEXT IrpContext
,
124 IN LONGLONG FileOffset
,
125 OUT PLONGLONG DiskOffset
,
130 CdAddAllocationFromDirent (
131 IN PIRP_CONTEXT IrpContext
,
133 IN ULONG McbEntryOffset
,
134 IN LONGLONG StartingFileOffset
,
139 CdAddInitialAllocation (
140 IN PIRP_CONTEXT IrpContext
,
142 IN ULONG StartingBlock
,
143 IN LONGLONG DataLength
147 CdTruncateAllocation (
148 IN PIRP_CONTEXT IrpContext
,
150 IN LONGLONG StartingFileOffset
155 IN PIRP_CONTEXT IrpContext
,
161 IN PIRP_CONTEXT IrpContext
,
167 // Buffer control routines for data caching, implemented in CacheSup.c
171 CdCreateInternalStream (
172 IN PIRP_CONTEXT IrpContext
,
178 CdDeleteInternalStream (
179 IN PIRP_CONTEXT IrpContext
,
185 IN PIRP_CONTEXT IrpContext
,
191 IN PIRP_CONTEXT IrpContext
,
193 IN BOOLEAN DismountUnderway
199 // IN PIRP_CONTEXT IrpContext,
204 #define CdUnpinData(IC,B) \
205 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
209 // Device I/O routines, implemented in DevIoSup.c
211 // These routines perform the actual device read and writes. They only affect
212 // the on disk structure and do not alter any other data structures.
217 IN PIRP_CONTEXT IrpContext
,
219 IN LONGLONG StartingOffset
,
225 IN PIRP_CONTEXT IrpContext
,
227 IN LONGLONG StartingOffset
,
233 IN PIRP_CONTEXT IrpContext
,
234 IN LONGLONG StartingOffset
,
236 IN BOOLEAN RaiseOnError
,
238 IN PDEVICE_OBJECT TargetDeviceObject
243 IN PIRP_CONTEXT IrpContext
,
244 IN ULONG BufferLength
,
245 IN BOOLEAN RaiseOnError
250 IN PIRP_CONTEXT IrpContext
,
251 IN ULONG IoControlCode
,
252 IN PDEVICE_OBJECT Device
,
253 OUT PVOID OutputBuffer OPTIONAL
,
254 IN ULONG OutputBufferLength
,
255 IN BOOLEAN InternalDeviceIoControl
,
256 IN BOOLEAN OverrideVerify
,
257 OUT PIO_STATUS_BLOCK Iosb OPTIONAL
263 // IN PIRP_CONTEXT IrpContext
264 // OUT PVOID UserBuffer
267 // Returns pointer to sys address. Will raise on failure.
271 // CdLockUserBuffer (
272 // IN PIRP_CONTEXT IrpContext,
273 // IN ULONG BufferLength
277 #define CdMapUserBuffer(IC, UB) { \
278 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
279 (IC)->Irp->UserBuffer : \
280 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \
281 if (NULL == *(UB)) { \
282 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
287 #define CdLockUserBuffer(IC,BL) { \
288 if ((IC)->Irp->MdlAddress == NULL) { \
289 (VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \
295 // Dirent support routines, implemented in DirSup.c
300 IN PIRP_CONTEXT IrpContext
,
302 IN ULONG DirentOffset
,
303 OUT PDIRENT_ENUM_CONTEXT DirContext
308 IN PIRP_CONTEXT IrpContext
,
310 IN PDIRENT_ENUM_CONTEXT CurrentDirContext
,
311 OUT PDIRENT_ENUM_CONTEXT NextDirContext
315 CdUpdateDirentFromRawDirent (
316 IN PIRP_CONTEXT IrpContext
,
318 IN PDIRENT_ENUM_CONTEXT DirContext
,
319 IN OUT PDIRENT Dirent
324 IN PIRP_CONTEXT IrpContext
,
325 IN OUT PDIRENT Dirent
,
331 IN PIRP_CONTEXT IrpContext
,
334 IN BOOLEAN IgnoreCase
,
335 IN OUT PFILE_ENUM_CONTEXT FileContext
,
336 OUT PCD_NAME
*MatchingName
341 IN PIRP_CONTEXT IrpContext
,
344 IN BOOLEAN IgnoreCase
,
345 IN OUT PFILE_ENUM_CONTEXT FileContext
349 CdFindFileByShortName (
350 IN PIRP_CONTEXT IrpContext
,
353 IN BOOLEAN IgnoreCase
,
354 IN ULONG ShortNameDirentOffset
,
355 IN OUT PFILE_ENUM_CONTEXT FileContext
359 CdLookupNextInitialFileDirent (
360 IN PIRP_CONTEXT IrpContext
,
362 IN OUT PFILE_ENUM_CONTEXT FileContext
366 CdLookupLastFileDirent (
367 IN PIRP_CONTEXT IrpContext
,
369 IN PFILE_ENUM_CONTEXT FileContext
373 CdCleanupFileContext (
374 IN PIRP_CONTEXT IrpContext
,
375 IN PFILE_ENUM_CONTEXT FileContext
380 // CdInitializeFileContext (
381 // IN PIRP_CONTEXT IrpContext,
382 // IN PFILE_ENUM_CONTEXT FileContext
387 // CdInitializeDirent (
388 // IN PIRP_CONTEXT IrpContext,
393 // CdInitializeDirContext (
394 // IN PIRP_CONTEXT IrpContext,
395 // IN PDIRENT_ENUM_CONTEXT DirContext
400 // IN PIRP_CONTEXT IrpContext,
405 // CdCleanupDirContext (
406 // IN PIRP_CONTEXT IrpContext,
407 // IN PDIRENT_ENUM_CONTEXT DirContext
411 // CdLookupInitialFileDirent (
412 // IN PIRP_CONTEXT IrpContext,
414 // IN PFILE_ENUM_CONTEXT FileContext,
415 // IN ULONG DirentOffset
419 #define CdInitializeFileContext(IC,FC) { \
420 RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \
421 (FC)->PriorDirent = &(FC)->Dirents[0]; \
422 (FC)->InitialDirent = &(FC)->Dirents[1]; \
423 (FC)->CurrentDirent = &(FC)->Dirents[2]; \
424 (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \
425 (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \
428 #define CdInitializeDirent(IC,D) \
429 RtlZeroMemory( D, sizeof( DIRENT ))
431 #define CdInitializeDirContext(IC,DC) \
432 RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT ))
434 #define CdCleanupDirent(IC,D) { \
435 if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \
436 CdFreePool( &(D)->CdFileName.FileName.Buffer ); \
440 #define CdCleanupDirContext(IC,DC) \
441 CdUnpinData( (IC), &(DC)->Bcb )
443 #define CdLookupInitialFileDirent(IC,F,FC,DO) \
444 CdLookupDirent( IC, \
447 &(FC)->InitialDirent->DirContext ); \
448 CdUpdateDirentFromRawDirent( IC, \
450 &(FC)->InitialDirent->DirContext, \
451 &(FC)->InitialDirent->Dirent )
455 // The following routines are used to manipulate the fscontext fields
456 // of the file object, implemented in FilObSup.c
460 // Type of opens. FilObSup.c depends on this order.
463 typedef enum _TYPE_OF_OPEN
{
465 UnopenedFileObject
= 0,
473 typedef TYPE_OF_OPEN
*PTYPE_OF_OPEN
;
477 IN PIRP_CONTEXT IrpContext
,
478 IN PFILE_OBJECT FileObject
,
479 IN TYPE_OF_OPEN TypeOfOpen
,
480 IN PFCB Fcb OPTIONAL
,
486 IN PIRP_CONTEXT IrpContext
,
487 IN PFILE_OBJECT FileObject
,
493 CdFastDecodeFileObject (
494 IN PFILE_OBJECT FileObject
,
500 // Name support routines, implemented in NameSup.c
504 CdConvertNameToCdName (
505 IN PIRP_CONTEXT IrpContext
,
506 IN OUT PCD_NAME CdName
510 CdConvertBigToLittleEndian (
511 IN PIRP_CONTEXT IrpContext
,
514 OUT PCHAR LittleEndian
519 IN PIRP_CONTEXT IrpContext
,
521 IN OUT PCD_NAME UpcaseName
526 IN PIRP_CONTEXT IrpContext
,
527 IN OUT PUNICODE_STRING RemainingName
,
528 OUT PUNICODE_STRING FinalName
533 IN PIRP_CONTEXT IrpContext
,
534 IN UNICODE_STRING FileName
538 CdGenerate8dot3Name (
539 IN PIRP_CONTEXT IrpContext
,
540 IN PUNICODE_STRING FileName
,
541 IN ULONG DirentOffset
,
542 OUT PWCHAR ShortFileName
,
543 OUT PUSHORT ShortByteCount
547 CdIsNameInExpression (
548 IN PIRP_CONTEXT IrpContext
,
549 IN PCD_NAME CurrentName
,
550 IN PCD_NAME SearchExpression
,
551 IN ULONG WildcardFlags
,
552 IN BOOLEAN CheckVersion
556 CdShortNameDirentOffset (
557 IN PIRP_CONTEXT IrpContext
,
558 IN PUNICODE_STRING Name
561 FSRTL_COMPARISON_RESULT
563 IN PIRP_CONTEXT IrpContext
,
564 IN PUNICODE_STRING NameA
,
565 IN PUNICODE_STRING NameB
570 // Filesystem control operations. Implemented in Fsctrl.c
574 CdLockVolumeInternal (
575 IN PIRP_CONTEXT IrpContext
,
577 IN PFILE_OBJECT FileObject OPTIONAL
581 CdUnlockVolumeInternal (
582 IN PIRP_CONTEXT IrpContext
,
584 IN PFILE_OBJECT FileObject OPTIONAL
589 // Path table enumeration routines. Implemented in PathSup.c
594 IN PIRP_CONTEXT IrpContext
,
595 IN ULONG PathEntryOffset
,
597 IN BOOLEAN VerifyBounds
,
598 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
602 CdLookupNextPathEntry (
603 IN PIRP_CONTEXT IrpContext
,
604 IN OUT PPATH_ENUM_CONTEXT PathContext
,
605 IN OUT PPATH_ENTRY PathEntry
610 IN PIRP_CONTEXT IrpContext
,
613 IN BOOLEAN IgnoreCase
,
614 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
618 CdUpdatePathEntryName (
619 IN PIRP_CONTEXT IrpContext
,
620 IN OUT PPATH_ENTRY PathEntry
,
621 IN BOOLEAN IgnoreCase
626 // CdInitializeCompoundPathEntry (
627 // IN PIRP_CONTEXT IrpContext,
628 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
632 // CdCleanupCompoundPathEntry (
633 // IN PIRP_CONTEXT IrpContext,
634 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
638 #define CdInitializeCompoundPathEntry(IC,CP) \
639 RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY ))
641 #define CdCleanupCompoundPathEntry(IC,CP) { \
642 CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \
643 if ((CP)->PathContext.AllocatedData) { \
644 CdFreePool( &(CP)->PathContext.Data ); \
646 if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \
647 CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \
653 // Largest matching prefix searching routines, implemented in PrefxSup.c
658 IN PIRP_CONTEXT IrpContext
,
661 IN BOOLEAN IgnoreCase
,
662 IN BOOLEAN ShortNameMatch
,
668 IN PIRP_CONTEXT IrpContext
,
674 IN PIRP_CONTEXT IrpContext
,
675 IN OUT PFCB
*CurrentFcb
,
676 IN OUT PUNICODE_STRING RemainingName
,
677 IN BOOLEAN IgnoreCase
682 // Synchronization routines. Implemented in Resrcsup.c
684 // The following routines/macros are used to synchronize the in-memory structures.
686 // Routine/Macro Synchronizes Subsequent
688 // CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData
689 // CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb
690 // CdAcquireVcbShared Vcb for open/close CdReleaseVcb
691 // CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles
692 // CdAcquireFileExclusive Locks out file operations CdReleaseFile
693 // CdAcquireFileShared Files for file operations CdReleaseFile
694 // CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb
695 // CdAcquireFcbShared Fcb for open/close CdReleaseFcb
696 // CdLockCdData Fields in CdData CdUnlockCdData
697 // CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb
698 // CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb
701 typedef enum _TYPE_OF_ACQUIRE
{
705 AcquireSharedStarveExclusive
707 } TYPE_OF_ACQUIRE
, *PTYPE_OF_ACQUIRE
;
711 IN PIRP_CONTEXT IrpContext
,
712 IN PERESOURCE Resource
,
713 IN BOOLEAN IgnoreWait
,
714 IN TYPE_OF_ACQUIRE Type
720 // IN PIRP_CONTEXT IrpContext
725 // IN PIRP_CONTEXT IrpContext
729 // CdAcquireVcbExclusive (
730 // IN PIRP_CONTEXT IrpContext,
732 // IN BOOLEAN IgnoreWait
736 // CdAcquireVcbShared (
737 // IN PIRP_CONTEXT IrpContext,
739 // IN BOOLEAN IgnoreWait
744 // IN PIRP_CONTEXT IrpContext,
749 // CdAcquireAllFiles (
755 // CdReleaseAllFiles (
761 // CdAcquireFileExclusive (
762 // IN PIRP_CONTEXT IrpContext,
767 // CdAcquireFileShared (
768 // IN PIRP_CONTEXT IrpContext,
774 // IN PIRP_CONTEXT IrpContext,
779 // CdAcquireFcbExclusive (
780 // IN PIRP_CONTEXT IrpContext,
782 // IN BOOLEAN IgnoreWait
786 // CdAcquireFcbShared (
787 // IN PIRP_CONTEXT IrpContext,
789 // IN BOOLEAN IgnoreWait
794 // IN PIRP_CONTEXT IrpContext,
808 // IN PIRP_CONTEXT IrpContext
813 // IN PIRP_CONTEXT IrpContext
818 // IN PIRP_CONTEXT IrpContext,
824 // IN PIRP_CONTEXT IrpContext,
829 #define CdAcquireCdData(IC) \
830 ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
832 #define CdReleaseCdData(IC) \
833 ExReleaseResourceLite( &CdData.DataResource )
835 #define CdAcquireVcbExclusive(IC,V,I) \
836 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
838 #define CdAcquireVcbShared(IC,V,I) \
839 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
841 #define CdReleaseVcb(IC,V) \
842 ExReleaseResourceLite( &(V)->VcbResource )
844 #define CdAcquireAllFiles(IC,V) \
845 CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
847 #define CdReleaseAllFiles(IC,V) \
848 ExReleaseResourceLite( &(V)->FileResource )
850 #define CdAcquireFileExclusive(IC,F) \
851 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
853 #define CdAcquireFileShared(IC,F) \
854 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
856 #define CdAcquireFileSharedStarveExclusive(IC,F) \
857 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
859 #define CdReleaseFile(IC,F) \
860 ExReleaseResourceLite( (F)->Resource )
862 #define CdAcquireFcbExclusive(IC,F,I) \
863 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
865 #define CdAcquireFcbShared(IC,F,I) \
866 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
868 #define CdReleaseFcb(IC,F) \
869 ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
871 #define CdLockCdData() \
872 ExAcquireFastMutex( &CdData.CdDataMutex ); \
873 CdData.CdDataLockThread = PsGetCurrentThread()
875 #define CdUnlockCdData() \
876 CdData.CdDataLockThread = NULL; \
877 ExReleaseFastMutex( &CdData.CdDataMutex )
879 #define CdLockVcb(IC,V) \
880 ExAcquireFastMutex( &(V)->VcbMutex ); \
881 ASSERT( NULL == (V)->VcbLockThread); \
882 (V)->VcbLockThread = PsGetCurrentThread()
884 #define CdUnlockVcb(IC,V) \
885 ASSERT( NULL != (V)->VcbLockThread); \
886 (V)->VcbLockThread = NULL; \
887 ExReleaseFastMutex( &(V)->VcbMutex )
889 #define CdLockFcb(IC,F) { \
890 PVOID _CurrentThread = PsGetCurrentThread(); \
891 if (_CurrentThread != (F)->FcbLockThread) { \
892 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
893 ASSERT( (F)->FcbLockCount == 0 ); \
894 (F)->FcbLockThread = _CurrentThread; \
896 (F)->FcbLockCount += 1; \
899 #define CdUnlockFcb(IC,F) { \
900 (F)->FcbLockCount -= 1; \
901 if ((F)->FcbLockCount == 0) { \
902 (F)->FcbLockThread = NULL; \
903 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
908 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
915 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
921 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
928 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
934 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
935 CdAcquireForCreateSection (
936 IN PFILE_OBJECT FileObject
940 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
941 CdReleaseForCreateSection (
942 IN PFILE_OBJECT FileObject
947 // In-memory structure support routines. Implemented in StrucSup.c
952 IN PIRP_CONTEXT IrpContext
,
954 IN PDEVICE_OBJECT TargetDeviceObject
,
956 IN PCDROM_TOC CdromToc
,
958 IN ULONG TocTrackCount
,
959 IN ULONG TocDiskFlags
,
960 IN ULONG BlockFactor
,
961 IN ULONG MediaChangeCount
965 CdUpdateVcbFromVolDescriptor (
966 IN PIRP_CONTEXT IrpContext
,
968 IN PCHAR RawIsoVd OPTIONAL
973 IN PIRP_CONTEXT IrpContext
,
979 IN PIRP_CONTEXT IrpContext
,
981 IN NODE_TYPE_CODE NodeTypeCode
,
982 OUT PBOOLEAN FcbExisted OPTIONAL
986 CdInitializeFcbFromPathEntry (
987 IN PIRP_CONTEXT IrpContext
,
989 IN PFCB ParentFcb OPTIONAL
,
990 IN PPATH_ENTRY PathEntry
994 CdInitializeFcbFromFileContext (
995 IN PIRP_CONTEXT IrpContext
,
997 IN PFCB ParentFcb OPTIONAL
,
998 IN PFILE_ENUM_CONTEXT FileContext
1003 IN PIRP_CONTEXT IrpContext
,
1010 IN PIRP_CONTEXT IrpContext
,
1016 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1018 IN BOOLEAN RaiseOnError
1023 IN PIRP_CONTEXT IrpContext
,
1024 IN PFILE_LOCK FileLock
1028 CdCreateIrpContext (
1034 CdCleanupIrpContext (
1035 IN PIRP_CONTEXT IrpContext
,
1040 CdInitializeStackIrpContext (
1041 OUT PIRP_CONTEXT IrpContext
,
1042 IN PIRP_CONTEXT_LITE IrpContextLite
1046 // PIRP_CONTEXT_LITE
1047 // CdCreateIrpContextLite (
1048 // IN PIRP_CONTEXT IrpContext
1052 // CdFreeIrpContextLite (
1053 // IN PIRP_CONTEXT_LITE IrpContextLite
1057 #define CdCreateIrpContextLite(IC) \
1058 ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
1060 #define CdFreeIrpContextLite(ICL) \
1061 CdFreePool( &(ICL) )
1064 CdTeardownStructures (
1065 IN PIRP_CONTEXT IrpContext
,
1066 IN PFCB StartingFcb
,
1067 OUT PBOOLEAN RemovedStartingFcb
1072 // CdIncrementCleanupCounts (
1073 // IN PIRP_CONTEXT IrpContext,
1078 // CdDecrementCleanupCounts (
1079 // IN PIRP_CONTEXT IrpContext,
1084 // CdIncrementReferenceCounts (
1085 // IN PIRP_CONTEXT IrpContext,
1087 // IN ULONG ReferenceCount
1088 // IN ULONG UserReferenceCount
1092 // CdDecrementReferenceCounts (
1093 // IN PIRP_CONTEXT IrpContext,
1095 // IN ULONG ReferenceCount
1096 // IN ULONG UserReferenceCount
1100 // CdIncrementFcbReference (
1101 // IN PIRP_CONTEXT IrpContext,
1106 // CdDecrementFcbReference (
1107 // IN PIRP_CONTEXT IrpContext,
1112 #define CdIncrementCleanupCounts(IC,F) { \
1113 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1114 (F)->FcbCleanup += 1; \
1115 (F)->Vcb->VcbCleanup += 1; \
1118 #define CdDecrementCleanupCounts(IC,F) { \
1119 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1120 (F)->FcbCleanup -= 1; \
1121 (F)->Vcb->VcbCleanup -= 1; \
1124 #define CdIncrementReferenceCounts(IC,F,C,UC) { \
1125 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1126 (F)->FcbReference += (C); \
1127 (F)->FcbUserReference += (UC); \
1128 (F)->Vcb->VcbReference += (C); \
1129 (F)->Vcb->VcbUserReference += (UC); \
1132 #define CdDecrementReferenceCounts(IC,F,C,UC) { \
1133 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1134 (F)->FcbReference -= (C); \
1135 (F)->FcbUserReference -= (UC); \
1136 (F)->Vcb->VcbReference -= (C); \
1137 (F)->Vcb->VcbUserReference -= (UC); \
1142 // CdAllocateIoContext (
1146 // CdFreeIoContext (
1147 // PCD_IO_CONTEXT IoContext
1151 #define CdAllocateIoContext() \
1152 FsRtlAllocatePoolWithTag( CdNonPagedPool, \
1153 sizeof( CD_IO_CONTEXT ), \
1156 #define CdFreeIoContext(IO) CdFreePool( &(IO) )
1160 IN PIRP_CONTEXT IrpContext
,
1167 IN PIRP_CONTEXT IrpContext
,
1169 IN PVOID
*RestartKey
1174 IN PIRP_CONTEXT IrpContext
,
1175 IN PDEVICE_OBJECT TargetDeviceObject
,
1176 IN PCDROM_TOC CdromToc
,
1177 IN OUT PULONG Length
,
1178 OUT PULONG TrackCount
,
1179 OUT PULONG DiskFlags
1183 // For debugging purposes we sometimes want to allocate our structures from nonpaged
1184 // pool so that in the kernel debugger we can walk all the structures.
1187 #define CdPagedPool PagedPool
1188 #define CdNonPagedPool NonPagedPool
1189 #define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned
1193 // Verification support routines. Contained in verfysup.c
1196 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1199 CdOperationIsDasdOpen(
1200 IN PIRP_CONTEXT IrpContext
1203 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( IrpContext
->Irp
);
1205 return ((IrpContext
->MajorFunction
== IRP_MJ_CREATE
) &&
1206 (IrpSp
->FileObject
->FileName
.Length
== 0) &&
1207 (IrpSp
->FileObject
->RelatedFileObject
== NULL
));
1213 IN PIRP_CONTEXT IrpContext
,
1215 IN PDEVICE_OBJECT DeviceToVerify
1219 CdCheckForDismount (
1220 IN PIRP_CONTEXT IrpContext
,
1227 IN PIRP_CONTEXT IrpContext
,
1232 CdVerifyFcbOperation (
1233 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1239 IN PIRP_CONTEXT IrpContext
,
1245 // Macros to abstract device verify flag changes.
1248 #define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
1249 #define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C)
1251 #define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1253 #define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1256 #define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
1261 // IN PIRP_CONTEXT IrpContext,
1262 // IN NTSTATUS Status
1266 #define CdIsRawDevice(IC,S) ( \
1267 ((S) == STATUS_DEVICE_NOT_READY) || \
1268 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
1273 // Work queue routines for posting and retrieving an Irp, implemented in
1279 IN PIRP_CONTEXT IrpContext
,
1284 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1286 IN PIRP_CONTEXT IrpContext
,
1291 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1293 IN PIRP_CONTEXT IrpContext
,
1299 // Miscellaneous support routines
1303 // This macro returns TRUE if a flag in a set of flags is on and FALSE
1307 /* ReactOS Change: GCC doesn't understand the comment style */
1309 //#ifndef BooleanFlagOn
1310 //#define BooleanFlagOn(F,SF) ( \
1311 // (BOOLEAN)(((F) & (SF)) != 0) \
1316 //#define SetFlag(Flags,SingleFlag) { \
1317 // (Flags) |= (SingleFlag); \
1322 //#define ClearFlag(Flags,SingleFlag) { \
1323 // (Flags) &= ~(SingleFlag); \
1331 // IN PVOID Pointer,
1332 // IN ULONG Increment
1338 // IN PVOID BasePtr,
1339 // IN PVOID OffsetPtr
1343 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
1345 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
1348 // This macro takes a pointer (or ulong) and returns its rounded up word
1352 #define WordAlign(Ptr) ( \
1353 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
1357 // This macro takes a pointer (or ulong) and returns its rounded up longword
1361 #define LongAlign(Ptr) ( \
1362 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
1366 // This macro takes a pointer (or ulong) and returns its rounded up quadword
1370 #define QuadAlign(Ptr) ( \
1371 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
1375 // The following macros round up and down to sector boundaries.
1378 #define SectorAlign(L) ( \
1379 ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1382 #define LlSectorAlign(L) ( \
1383 ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1386 #define SectorTruncate(L) ( \
1387 ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \
1390 #define LlSectorTruncate(L) ( \
1391 ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \
1394 #define BytesFromSectors(L) ( \
1395 ((ULONG) (L)) << SECTOR_SHIFT \
1398 #define SectorsFromBytes(L) ( \
1399 ((ULONG) (L)) >> SECTOR_SHIFT \
1402 #define LlBytesFromSectors(L) ( \
1403 Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1406 #define LlSectorsFromBytes(L) ( \
1407 Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1410 #define SectorOffset(L) ( \
1411 ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \
1414 #define SectorBlockOffset(V,LB) ( \
1415 ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \
1418 #define BytesFromBlocks(V,B) ( \
1419 (ULONG) (B) << (V)->BlockToByteShift \
1422 #define LlBytesFromBlocks(V,B) ( \
1423 Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \
1426 #define BlockAlign(V,L) ( \
1427 ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \
1431 // Carefully make sure the mask is sign extended to 64bits
1434 #define LlBlockAlign(V,L) ( \
1435 ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \
1438 #define BlockOffset(V,L) ( \
1439 ((ULONG) (L)) & (V)->BlockMask \
1442 #define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE)
1445 // The following types and macros are used to help unpack the packed and
1446 // misaligned fields found in the Bios parameter block
1449 typedef union _UCHAR1
{
1451 UCHAR ForceAlignment
;
1454 typedef union _UCHAR2
{
1456 USHORT ForceAlignment
;
1459 typedef union _UCHAR4
{
1461 ULONG ForceAlignment
;
1464 typedef union _USHORT2
{
1466 ULONG ForceAlignment
;
1467 } USHORT2
, *PUSHORT2
;
1470 // This macro copies an unaligned src byte to an aligned dst byte
1473 #define CopyUchar1(Dst,Src) { \
1474 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
1478 // This macro copies an unaligned src word to an aligned dst word
1481 #define CopyUchar2(Dst,Src) { \
1482 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
1486 // This macro copies an unaligned src longword to an aligned dsr longword
1489 #define CopyUchar4(Dst,Src) { \
1490 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
1494 // This macro copies an unaligned src longword to an aligned dsr longword
1495 // accessing the source on a word boundary.
1498 #define CopyUshort2(Dst,Src) { \
1499 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
1504 // Following routines handle entry in and out of the filesystem. They are
1505 // contained in CdData.c
1510 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject
,
1516 IN PIRP_CONTEXT IrpContext
,
1517 IN PEXCEPTION_POINTERS ExceptionPointer
1521 CdProcessException (
1522 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1524 IN NTSTATUS ExceptionCode
1529 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1530 IN PIRP Irp OPTIONAL
,
1537 // IN PRIP_CONTEXT IrpContext,
1538 // IN NT_STATUS Status
1542 // CdNormalizeAndRaiseStatus (
1543 // IN PRIP_CONTEXT IrpContext,
1544 // IN NT_STATUS Status
1549 #define AssertVerifyDevice(C, S) \
1550 ASSERT( (C) == NULL || \
1551 FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \
1552 !((S) == STATUS_VERIFY_REQUIRED && \
1553 IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
1555 #define AssertVerifyDeviceIrp(I) \
1556 ASSERT( (I) == NULL || \
1557 !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \
1558 ((I)->Tail.Overlay.Thread == NULL || \
1559 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
1561 #define AssertVerifyDevice(C, S)
1562 #define AssertVerifyDeviceIrp(I)
1571 IN PIRP_CONTEXT IrpContext
,
1573 IN BOOLEAN NormalizeStatus
,
1574 IN OPTIONAL ULONG FileId
,
1575 IN OPTIONAL ULONG Line
1584 IN PIRP_CONTEXT IrpContext
,
1586 IN BOOLEAN NormalizeStatus
,
1591 if (NormalizeStatus
) {
1593 IrpContext
->ExceptionStatus
= FsRtlNormalizeNtstatus( Status
, STATUS_UNEXPECTED_IO_ERROR
);
1597 IrpContext
->ExceptionStatus
= Status
;
1600 IrpContext
->RaisedAtLineFile
= (Fileid
<< 16) | Line
;
1602 ExRaiseStatus( IrpContext
->ExceptionStatus
);
1607 #define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__);
1608 #define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__);
1611 // Following are the fast entry points.
1615 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1616 CdFastQueryBasicInfo (
1617 IN PFILE_OBJECT FileObject
,
1619 IN OUT PFILE_BASIC_INFORMATION Buffer
,
1620 OUT PIO_STATUS_BLOCK IoStatus
,
1621 IN PDEVICE_OBJECT DeviceObject
1625 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1626 CdFastQueryStdInfo (
1627 IN PFILE_OBJECT FileObject
,
1629 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
1630 OUT PIO_STATUS_BLOCK IoStatus
,
1631 IN PDEVICE_OBJECT DeviceObject
1635 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1637 IN PFILE_OBJECT FileObject
,
1638 IN PLARGE_INTEGER FileOffset
,
1639 IN PLARGE_INTEGER Length
,
1640 PEPROCESS ProcessId
,
1642 BOOLEAN FailImmediately
,
1643 BOOLEAN ExclusiveLock
,
1644 OUT PIO_STATUS_BLOCK IoStatus
,
1645 IN PDEVICE_OBJECT DeviceObject
1649 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1650 CdFastUnlockSingle (
1651 IN PFILE_OBJECT FileObject
,
1652 IN PLARGE_INTEGER FileOffset
,
1653 IN PLARGE_INTEGER Length
,
1654 PEPROCESS ProcessId
,
1656 OUT PIO_STATUS_BLOCK IoStatus
,
1657 IN PDEVICE_OBJECT DeviceObject
1661 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1663 IN PFILE_OBJECT FileObject
,
1664 PEPROCESS ProcessId
,
1665 OUT PIO_STATUS_BLOCK IoStatus
,
1666 IN PDEVICE_OBJECT DeviceObject
1670 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1671 CdFastUnlockAllByKey (
1672 IN PFILE_OBJECT FileObject
,
1675 OUT PIO_STATUS_BLOCK IoStatus
,
1676 IN PDEVICE_OBJECT DeviceObject
1680 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1681 CdFastIoCheckIfPossible (
1682 IN PFILE_OBJECT FileObject
,
1683 IN PLARGE_INTEGER FileOffset
,
1687 IN BOOLEAN CheckForReadOperation
,
1688 OUT PIO_STATUS_BLOCK IoStatus
,
1689 IN PDEVICE_OBJECT DeviceObject
1693 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1694 CdFastQueryNetworkInfo (
1695 IN PFILE_OBJECT FileObject
,
1697 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1698 OUT PIO_STATUS_BLOCK IoStatus
,
1699 IN PDEVICE_OBJECT DeviceObject
1703 // Following are the routines to handle the top level thread logic.
1707 CdSetThreadContext (
1708 IN PIRP_CONTEXT IrpContext
,
1709 IN PTHREAD_CONTEXT ThreadContext
1715 // CdRestoreThreadContext (
1716 // IN PIRP_CONTEXT IrpContext
1720 #define CdRestoreThreadContext(IC) \
1721 (IC)->ThreadContext->Cdfs = 0; \
1722 IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \
1723 (IC)->ThreadContext = NULL
1732 // The following macro is used to determine if an FSD thread can block
1733 // for I/O or wait for a resource. It returns TRUE if the thread can
1734 // block and FALSE otherwise. This attribute can then be used to call
1735 // the FSD & FSP common work routine with the proper wait value.
1738 #define CanFsdWait(I) IoIsOperationSynchronous(I)
1741 // The following macro is used to set the fast i/o possible bits in the
1744 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
1746 // FastIoIsQuestionable - If there are file locks.
1748 // FastIoIsPossible - In all other cases.
1752 #define CdIsFastIoPossible(F) ((BOOLEAN) \
1753 ((((F)->Vcb->VcbCondition != VcbMounted ) || \
1754 !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
1756 FastIoIsNotPossible : \
1758 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
1760 FastIoIsQuestionable : \
1762 FastIoIsPossible)) \
1767 // The FSP level dispatch/main routine. This is the routine that takes
1768 // IRP's off of the work queue and calls the appropriate FSP level
1773 CdFspDispatch ( // implemented in FspDisp.c
1774 IN PIRP_CONTEXT IrpContext
1778 CdFspClose ( // implemented in Close.c
1779 IN PVCB Vcb OPTIONAL
1783 // The following routines are the entry points for the different operations
1784 // based on the IrpSp major functions.
1788 CdCommonCreate ( // Implemented in Create.c
1789 IN PIRP_CONTEXT IrpContext
,
1794 CdCommonClose ( // Implemented in Close.c
1795 IN PIRP_CONTEXT IrpContext
,
1800 CdCommonRead ( // Implemented in Read.c
1801 IN PIRP_CONTEXT IrpContext
,
1806 CdCommonQueryInfo ( // Implemented in FileInfo.c
1807 IN PIRP_CONTEXT IrpContext
,
1812 CdCommonSetInfo ( // Implemented in FileInfo.c
1813 IN PIRP_CONTEXT IrpContext
,
1818 CdCommonQueryVolInfo ( // Implemented in VolInfo.c
1819 IN PIRP_CONTEXT IrpContext
,
1824 CdCommonDirControl ( // Implemented in DirCtrl.c
1825 IN PIRP_CONTEXT IrpContext
,
1830 CdCommonFsControl ( // Implemented in FsCtrl.c
1831 IN PIRP_CONTEXT IrpContext
,
1836 CdCommonDevControl ( // Implemented in DevCtrl.c
1837 IN PIRP_CONTEXT IrpContext
,
1842 CdCommonLockControl ( // Implemented in LockCtrl.c
1843 IN PIRP_CONTEXT IrpContext
,
1848 CdCommonCleanup ( // Implemented in Cleanup.c
1849 IN PIRP_CONTEXT IrpContext
,
1854 CdCommonPnp ( // Implemented in Pnp.c
1855 IN PIRP_CONTEXT IrpContext
,
1861 // The following macros are used to establish the semantics needed
1862 // to do a return from within a try-finally clause. As a rule every
1863 // try clause must end with a label call try_exit. For example,
1869 // try_exit: NOTHING;
1876 // Every return statement executed inside of a try clause should use the
1877 // try_return macro. If the compiler fully supports the try-finally construct
1878 // then the macro should be
1880 // #define try_return(S) { return(S); }
1882 // If the compiler does not support the try-finally construct then the macro
1885 // #define try_return(S) { S; goto try_exit; }
1889 #define try_return(S) { S; goto try_exit; }
1890 #define try_leave(S) { S; leave; }
1892 #define try_return(S) { S; goto try_exit; }
1893 #define try_leave(S) { S; _SEH2_LEAVE; }
1898 // Encapsulate safe pool freeing
1900 /* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */
1901 #define CdFreePool(x) _CdFreePool((PVOID*)(x))
1903 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1904 static inline void _CdFreePool(
1908 if (*Pool
!= NULL
) {