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 /* ReactOS Change: GCC doesn't understand this, use TAG macro */
48 #include <reactos/helper.h>
49 #define TAG_CCB TAG('c','c','d','C') // Ccb
50 #define TAG_CDROM_TOC TAG('c','t','d','C') // TOC
51 #define TAG_DIRENT_NAME TAG('n','d','d','C') // CdName in dirent
52 #define TAG_ENUM_EXPRESSION TAG('e','e','d','C') // Search expression for enumeration
53 #define TAG_FCB_DATA TAG('d','f','d','C') // Data Fcb
54 #define TAG_FCB_INDEX TAG('i','f','d','C') // Index Fcb
55 #define TAG_FCB_NONPAGED TAG('n','f','d','C') // Nonpaged Fcb
56 #define TAG_FCB_TABLE TAG('t','f','d','C') // Fcb Table entry
57 #define TAG_FILE_NAME TAG('n','F','d','C') // Filename buffer
58 #define TAG_GEN_SHORT_NAME TAG('s','g','d','C') // Generated short name
59 #define TAG_IO_BUFFER TAG('f','b','d','C') // Temporary IO buffer
60 #define TAG_IO_CONTEXT TAG('o','i','d','C') // Io context for async reads
61 #define TAG_IRP_CONTEXT TAG('c','i','d','C') // Irp Context
62 #define TAG_IRP_CONTEXT_LITE TAG('l','i','d','C') // Irp Context lite
63 #define TAG_MCB_ARRAY TAG('a','m','d','C') // Mcb array
64 #define TAG_PATH_ENTRY_NAME TAG('n','P','d','C') // CdName in path entry
65 #define TAG_PREFIX_ENTRY TAG('e','p','d','C') // Prefix Entry
66 #define TAG_PREFIX_NAME TAG('n','p','d','C') // Prefix Entry name
67 #define TAG_SPANNING_PATH_TABLE TAG('p','s','d','C') // Buffer for spanning path table
68 #define TAG_UPCASE_NAME TAG('n','u','d','C') // Buffer for upcased name
69 #define TAG_VOL_DESC TAG('d','v','d','C') // Buffer for volume descriptor
70 #define TAG_VPB TAG('p','v','d','C') // Vpb allocated in filesystem
73 // Tag all of our allocations if tagging is turned on
78 #undef FsRtlAllocatePool
79 #undef FsRtlAllocatePoolWithQuota
80 #define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC')
81 #define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC')
83 #endif // POOL_TAGGING
87 // File access check routine, implemented in AcChkSup.c
92 // CdIllegalFcbAccess (
93 // IN PIRP_CONTEXT IrpContext,
94 // IN TYPE_OF_OPEN TypeOfOpen,
95 // IN ACCESS_MASK DesiredAccess
99 #define CdIllegalFcbAccess(IC,T,DA) ( \
100 BooleanFlagOn( (DA), \
101 ((T) != UserVolumeOpen ? \
102 (FILE_WRITE_ATTRIBUTES | \
106 FILE_ADD_SUBDIRECTORY | \
107 FILE_APPEND_DATA) : 0) | \
108 FILE_DELETE_CHILD | \
114 // Allocation support routines, implemented in AllocSup.c
116 // These routines are for querying allocation on individual streams.
121 IN PIRP_CONTEXT IrpContext
,
123 IN LONGLONG FileOffset
,
124 OUT PLONGLONG DiskOffset
,
129 CdAddAllocationFromDirent (
130 IN PIRP_CONTEXT IrpContext
,
132 IN ULONG McbEntryOffset
,
133 IN LONGLONG StartingFileOffset
,
138 CdAddInitialAllocation (
139 IN PIRP_CONTEXT IrpContext
,
141 IN ULONG StartingBlock
,
142 IN LONGLONG DataLength
146 CdTruncateAllocation (
147 IN PIRP_CONTEXT IrpContext
,
149 IN LONGLONG StartingFileOffset
154 IN PIRP_CONTEXT IrpContext
,
160 IN PIRP_CONTEXT IrpContext
,
166 // Buffer control routines for data caching, implemented in CacheSup.c
170 CdCreateInternalStream (
171 IN PIRP_CONTEXT IrpContext
,
177 CdDeleteInternalStream (
178 IN PIRP_CONTEXT IrpContext
,
184 IN PIRP_CONTEXT IrpContext
,
190 IN PIRP_CONTEXT IrpContext
,
192 IN BOOLEAN DismountUnderway
198 // IN PIRP_CONTEXT IrpContext,
203 #define CdUnpinData(IC,B) \
204 if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
208 // Device I/O routines, implemented in DevIoSup.c
210 // These routines perform the actual device read and writes. They only affect
211 // the on disk structure and do not alter any other data structures.
216 IN PIRP_CONTEXT IrpContext
,
218 IN LONGLONG StartingOffset
,
224 IN PIRP_CONTEXT IrpContext
,
226 IN LONGLONG StartingOffset
,
232 IN PIRP_CONTEXT IrpContext
,
233 IN LONGLONG StartingOffset
,
235 IN BOOLEAN RaiseOnError
,
237 IN PDEVICE_OBJECT TargetDeviceObject
242 IN PIRP_CONTEXT IrpContext
,
243 IN ULONG BufferLength
,
244 IN BOOLEAN RaiseOnError
249 IN PIRP_CONTEXT IrpContext
,
250 IN ULONG IoControlCode
,
251 IN PDEVICE_OBJECT Device
,
252 OUT PVOID OutputBuffer OPTIONAL
,
253 IN ULONG OutputBufferLength
,
254 IN BOOLEAN InternalDeviceIoControl
,
255 IN BOOLEAN OverrideVerify
,
256 OUT PIO_STATUS_BLOCK Iosb OPTIONAL
262 // IN PIRP_CONTEXT IrpContext
263 // OUT PVOID UserBuffer
266 // Returns pointer to sys address. Will raise on failure.
270 // CdLockUserBuffer (
271 // IN PIRP_CONTEXT IrpContext,
272 // IN ULONG BufferLength
276 #define CdMapUserBuffer(IC, UB) { \
277 *(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
278 (IC)->Irp->UserBuffer : \
279 (MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \
280 if (NULL == *(UB)) { \
281 CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
286 #define CdLockUserBuffer(IC,BL) { \
287 if ((IC)->Irp->MdlAddress == NULL) { \
288 (VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \
294 // Dirent support routines, implemented in DirSup.c
299 IN PIRP_CONTEXT IrpContext
,
301 IN ULONG DirentOffset
,
302 OUT PDIRENT_ENUM_CONTEXT DirContext
307 IN PIRP_CONTEXT IrpContext
,
309 IN PDIRENT_ENUM_CONTEXT CurrentDirContext
,
310 OUT PDIRENT_ENUM_CONTEXT NextDirContext
314 CdUpdateDirentFromRawDirent (
315 IN PIRP_CONTEXT IrpContext
,
317 IN PDIRENT_ENUM_CONTEXT DirContext
,
318 IN OUT PDIRENT Dirent
323 IN PIRP_CONTEXT IrpContext
,
324 IN OUT PDIRENT Dirent
,
330 IN PIRP_CONTEXT IrpContext
,
333 IN BOOLEAN IgnoreCase
,
334 IN OUT PFILE_ENUM_CONTEXT FileContext
,
335 OUT PCD_NAME
*MatchingName
340 IN PIRP_CONTEXT IrpContext
,
343 IN BOOLEAN IgnoreCase
,
344 IN OUT PFILE_ENUM_CONTEXT FileContext
348 CdFindFileByShortName (
349 IN PIRP_CONTEXT IrpContext
,
352 IN BOOLEAN IgnoreCase
,
353 IN ULONG ShortNameDirentOffset
,
354 IN OUT PFILE_ENUM_CONTEXT FileContext
358 CdLookupNextInitialFileDirent (
359 IN PIRP_CONTEXT IrpContext
,
361 IN OUT PFILE_ENUM_CONTEXT FileContext
365 CdLookupLastFileDirent (
366 IN PIRP_CONTEXT IrpContext
,
368 IN PFILE_ENUM_CONTEXT FileContext
372 CdCleanupFileContext (
373 IN PIRP_CONTEXT IrpContext
,
374 IN PFILE_ENUM_CONTEXT FileContext
379 // CdInitializeFileContext (
380 // IN PIRP_CONTEXT IrpContext,
381 // IN PFILE_ENUM_CONTEXT FileContext
386 // CdInitializeDirent (
387 // IN PIRP_CONTEXT IrpContext,
392 // CdInitializeDirContext (
393 // IN PIRP_CONTEXT IrpContext,
394 // IN PDIRENT_ENUM_CONTEXT DirContext
399 // IN PIRP_CONTEXT IrpContext,
404 // CdCleanupDirContext (
405 // IN PIRP_CONTEXT IrpContext,
406 // IN PDIRENT_ENUM_CONTEXT DirContext
410 // CdLookupInitialFileDirent (
411 // IN PIRP_CONTEXT IrpContext,
413 // IN PFILE_ENUM_CONTEXT FileContext,
414 // IN ULONG DirentOffset
418 #define CdInitializeFileContext(IC,FC) { \
419 RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \
420 (FC)->PriorDirent = &(FC)->Dirents[0]; \
421 (FC)->InitialDirent = &(FC)->Dirents[1]; \
422 (FC)->CurrentDirent = &(FC)->Dirents[2]; \
423 (FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \
424 (FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \
427 #define CdInitializeDirent(IC,D) \
428 RtlZeroMemory( D, sizeof( DIRENT ))
430 #define CdInitializeDirContext(IC,DC) \
431 RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT ))
433 #define CdCleanupDirent(IC,D) { \
434 if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \
435 CdFreePool( &(D)->CdFileName.FileName.Buffer ); \
439 #define CdCleanupDirContext(IC,DC) \
440 CdUnpinData( (IC), &(DC)->Bcb )
442 #define CdLookupInitialFileDirent(IC,F,FC,DO) \
443 CdLookupDirent( IC, \
446 &(FC)->InitialDirent->DirContext ); \
447 CdUpdateDirentFromRawDirent( IC, \
449 &(FC)->InitialDirent->DirContext, \
450 &(FC)->InitialDirent->Dirent )
454 // The following routines are used to manipulate the fscontext fields
455 // of the file object, implemented in FilObSup.c
459 // Type of opens. FilObSup.c depends on this order.
462 typedef enum _TYPE_OF_OPEN
{
464 UnopenedFileObject
= 0,
472 typedef TYPE_OF_OPEN
*PTYPE_OF_OPEN
;
476 IN PIRP_CONTEXT IrpContext
,
477 IN PFILE_OBJECT FileObject
,
478 IN TYPE_OF_OPEN TypeOfOpen
,
479 IN PFCB Fcb OPTIONAL
,
485 IN PIRP_CONTEXT IrpContext
,
486 IN PFILE_OBJECT FileObject
,
492 CdFastDecodeFileObject (
493 IN PFILE_OBJECT FileObject
,
499 // Name support routines, implemented in NameSup.c
503 CdConvertNameToCdName (
504 IN PIRP_CONTEXT IrpContext
,
505 IN OUT PCD_NAME CdName
509 CdConvertBigToLittleEndian (
510 IN PIRP_CONTEXT IrpContext
,
513 OUT PCHAR LittleEndian
518 IN PIRP_CONTEXT IrpContext
,
520 IN OUT PCD_NAME UpcaseName
525 IN PIRP_CONTEXT IrpContext
,
526 IN OUT PUNICODE_STRING RemainingName
,
527 OUT PUNICODE_STRING FinalName
532 IN PIRP_CONTEXT IrpContext
,
533 IN UNICODE_STRING FileName
537 CdGenerate8dot3Name (
538 IN PIRP_CONTEXT IrpContext
,
539 IN PUNICODE_STRING FileName
,
540 IN ULONG DirentOffset
,
541 OUT PWCHAR ShortFileName
,
542 OUT PUSHORT ShortByteCount
546 CdIsNameInExpression (
547 IN PIRP_CONTEXT IrpContext
,
548 IN PCD_NAME CurrentName
,
549 IN PCD_NAME SearchExpression
,
550 IN ULONG WildcardFlags
,
551 IN BOOLEAN CheckVersion
555 CdShortNameDirentOffset (
556 IN PIRP_CONTEXT IrpContext
,
557 IN PUNICODE_STRING Name
560 FSRTL_COMPARISON_RESULT
562 IN PIRP_CONTEXT IrpContext
,
563 IN PUNICODE_STRING NameA
,
564 IN PUNICODE_STRING NameB
569 // Filesystem control operations. Implemented in Fsctrl.c
573 CdLockVolumeInternal (
574 IN PIRP_CONTEXT IrpContext
,
576 IN PFILE_OBJECT FileObject OPTIONAL
580 CdUnlockVolumeInternal (
581 IN PIRP_CONTEXT IrpContext
,
583 IN PFILE_OBJECT FileObject OPTIONAL
588 // Path table enumeration routines. Implemented in PathSup.c
593 IN PIRP_CONTEXT IrpContext
,
594 IN ULONG PathEntryOffset
,
596 IN BOOLEAN VerifyBounds
,
597 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
601 CdLookupNextPathEntry (
602 IN PIRP_CONTEXT IrpContext
,
603 IN OUT PPATH_ENUM_CONTEXT PathContext
,
604 IN OUT PPATH_ENTRY PathEntry
609 IN PIRP_CONTEXT IrpContext
,
612 IN BOOLEAN IgnoreCase
,
613 IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
617 CdUpdatePathEntryName (
618 IN PIRP_CONTEXT IrpContext
,
619 IN OUT PPATH_ENTRY PathEntry
,
620 IN BOOLEAN IgnoreCase
625 // CdInitializeCompoundPathEntry (
626 // IN PIRP_CONTEXT IrpContext,
627 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
631 // CdCleanupCompoundPathEntry (
632 // IN PIRP_CONTEXT IrpContext,
633 // IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
637 #define CdInitializeCompoundPathEntry(IC,CP) \
638 RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY ))
640 #define CdCleanupCompoundPathEntry(IC,CP) { \
641 CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \
642 if ((CP)->PathContext.AllocatedData) { \
643 CdFreePool( &(CP)->PathContext.Data ); \
645 if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \
646 CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \
652 // Largest matching prefix searching routines, implemented in PrefxSup.c
657 IN PIRP_CONTEXT IrpContext
,
660 IN BOOLEAN IgnoreCase
,
661 IN BOOLEAN ShortNameMatch
,
667 IN PIRP_CONTEXT IrpContext
,
673 IN PIRP_CONTEXT IrpContext
,
674 IN OUT PFCB
*CurrentFcb
,
675 IN OUT PUNICODE_STRING RemainingName
,
676 IN BOOLEAN IgnoreCase
681 // Synchronization routines. Implemented in Resrcsup.c
683 // The following routines/macros are used to synchronize the in-memory structures.
685 // Routine/Macro Synchronizes Subsequent
687 // CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData
688 // CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb
689 // CdAcquireVcbShared Vcb for open/close CdReleaseVcb
690 // CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles
691 // CdAcquireFileExclusive Locks out file operations CdReleaseFile
692 // CdAcquireFileShared Files for file operations CdReleaseFile
693 // CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb
694 // CdAcquireFcbShared Fcb for open/close CdReleaseFcb
695 // CdLockCdData Fields in CdData CdUnlockCdData
696 // CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb
697 // CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb
700 typedef enum _TYPE_OF_ACQUIRE
{
704 AcquireSharedStarveExclusive
706 } TYPE_OF_ACQUIRE
, *PTYPE_OF_ACQUIRE
;
710 IN PIRP_CONTEXT IrpContext
,
711 IN PERESOURCE Resource
,
712 IN BOOLEAN IgnoreWait
,
713 IN TYPE_OF_ACQUIRE Type
719 // IN PIRP_CONTEXT IrpContext
724 // IN PIRP_CONTEXT IrpContext
728 // CdAcquireVcbExclusive (
729 // IN PIRP_CONTEXT IrpContext,
731 // IN BOOLEAN IgnoreWait
735 // CdAcquireVcbShared (
736 // IN PIRP_CONTEXT IrpContext,
738 // IN BOOLEAN IgnoreWait
743 // IN PIRP_CONTEXT IrpContext,
748 // CdAcquireAllFiles (
754 // CdReleaseAllFiles (
760 // CdAcquireFileExclusive (
761 // IN PIRP_CONTEXT IrpContext,
766 // CdAcquireFileShared (
767 // IN PIRP_CONTEXT IrpContext,
773 // IN PIRP_CONTEXT IrpContext,
778 // CdAcquireFcbExclusive (
779 // IN PIRP_CONTEXT IrpContext,
781 // IN BOOLEAN IgnoreWait
785 // CdAcquireFcbShared (
786 // IN PIRP_CONTEXT IrpContext,
788 // IN BOOLEAN IgnoreWait
793 // IN PIRP_CONTEXT IrpContext,
807 // IN PIRP_CONTEXT IrpContext
812 // IN PIRP_CONTEXT IrpContext
817 // IN PIRP_CONTEXT IrpContext,
823 // IN PIRP_CONTEXT IrpContext,
828 #define CdAcquireCdData(IC) \
829 ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
831 #define CdReleaseCdData(IC) \
832 ExReleaseResourceLite( &CdData.DataResource )
834 #define CdAcquireVcbExclusive(IC,V,I) \
835 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
837 #define CdAcquireVcbShared(IC,V,I) \
838 CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
840 #define CdReleaseVcb(IC,V) \
841 ExReleaseResourceLite( &(V)->VcbResource )
843 #define CdAcquireAllFiles(IC,V) \
844 CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
846 #define CdReleaseAllFiles(IC,V) \
847 ExReleaseResourceLite( &(V)->FileResource )
849 #define CdAcquireFileExclusive(IC,F) \
850 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
852 #define CdAcquireFileShared(IC,F) \
853 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
855 #define CdAcquireFileSharedStarveExclusive(IC,F) \
856 CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
858 #define CdReleaseFile(IC,F) \
859 ExReleaseResourceLite( (F)->Resource )
861 #define CdAcquireFcbExclusive(IC,F,I) \
862 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
864 #define CdAcquireFcbShared(IC,F,I) \
865 CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
867 #define CdReleaseFcb(IC,F) \
868 ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
870 #define CdLockCdData() \
871 ExAcquireFastMutex( &CdData.CdDataMutex ); \
872 CdData.CdDataLockThread = PsGetCurrentThread()
874 #define CdUnlockCdData() \
875 CdData.CdDataLockThread = NULL; \
876 ExReleaseFastMutex( &CdData.CdDataMutex )
878 #define CdLockVcb(IC,V) \
879 ExAcquireFastMutex( &(V)->VcbMutex ); \
880 ASSERT( NULL == (V)->VcbLockThread); \
881 (V)->VcbLockThread = PsGetCurrentThread()
883 #define CdUnlockVcb(IC,V) \
884 ASSERT( NULL != (V)->VcbLockThread); \
885 (V)->VcbLockThread = NULL; \
886 ExReleaseFastMutex( &(V)->VcbMutex )
888 #define CdLockFcb(IC,F) { \
889 PVOID _CurrentThread = PsGetCurrentThread(); \
890 if (_CurrentThread != (F)->FcbLockThread) { \
891 ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
892 ASSERT( (F)->FcbLockCount == 0 ); \
893 (F)->FcbLockThread = _CurrentThread; \
895 (F)->FcbLockCount += 1; \
898 #define CdUnlockFcb(IC,F) { \
899 (F)->FcbLockCount -= 1; \
900 if ((F)->FcbLockCount == 0) { \
901 (F)->FcbLockThread = NULL; \
902 ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
907 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
914 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
920 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
927 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
933 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
934 CdAcquireForCreateSection (
935 IN PFILE_OBJECT FileObject
939 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
940 CdReleaseForCreateSection (
941 IN PFILE_OBJECT FileObject
946 // In-memory structure support routines. Implemented in StrucSup.c
951 IN PIRP_CONTEXT IrpContext
,
953 IN PDEVICE_OBJECT TargetDeviceObject
,
955 IN PCDROM_TOC CdromToc
,
957 IN ULONG TocTrackCount
,
958 IN ULONG TocDiskFlags
,
959 IN ULONG BlockFactor
,
960 IN ULONG MediaChangeCount
964 CdUpdateVcbFromVolDescriptor (
965 IN PIRP_CONTEXT IrpContext
,
967 IN PCHAR RawIsoVd OPTIONAL
972 IN PIRP_CONTEXT IrpContext
,
978 IN PIRP_CONTEXT IrpContext
,
980 IN NODE_TYPE_CODE NodeTypeCode
,
981 OUT PBOOLEAN FcbExisted OPTIONAL
985 CdInitializeFcbFromPathEntry (
986 IN PIRP_CONTEXT IrpContext
,
988 IN PFCB ParentFcb OPTIONAL
,
989 IN PPATH_ENTRY PathEntry
993 CdInitializeFcbFromFileContext (
994 IN PIRP_CONTEXT IrpContext
,
996 IN PFCB ParentFcb OPTIONAL
,
997 IN PFILE_ENUM_CONTEXT FileContext
1002 IN PIRP_CONTEXT IrpContext
,
1009 IN PIRP_CONTEXT IrpContext
,
1015 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1017 IN BOOLEAN RaiseOnError
1022 IN PIRP_CONTEXT IrpContext
,
1023 IN PFILE_LOCK FileLock
1027 CdCreateIrpContext (
1033 CdCleanupIrpContext (
1034 IN PIRP_CONTEXT IrpContext
,
1039 CdInitializeStackIrpContext (
1040 OUT PIRP_CONTEXT IrpContext
,
1041 IN PIRP_CONTEXT_LITE IrpContextLite
1045 // PIRP_CONTEXT_LITE
1046 // CdCreateIrpContextLite (
1047 // IN PIRP_CONTEXT IrpContext
1051 // CdFreeIrpContextLite (
1052 // IN PIRP_CONTEXT_LITE IrpContextLite
1056 #define CdCreateIrpContextLite(IC) \
1057 ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
1059 #define CdFreeIrpContextLite(ICL) \
1060 CdFreePool( &(ICL) )
1063 CdTeardownStructures (
1064 IN PIRP_CONTEXT IrpContext
,
1065 IN PFCB StartingFcb
,
1066 OUT PBOOLEAN RemovedStartingFcb
1071 // CdIncrementCleanupCounts (
1072 // IN PIRP_CONTEXT IrpContext,
1077 // CdDecrementCleanupCounts (
1078 // IN PIRP_CONTEXT IrpContext,
1083 // CdIncrementReferenceCounts (
1084 // IN PIRP_CONTEXT IrpContext,
1086 // IN ULONG ReferenceCount
1087 // IN ULONG UserReferenceCount
1091 // CdDecrementReferenceCounts (
1092 // IN PIRP_CONTEXT IrpContext,
1094 // IN ULONG ReferenceCount
1095 // IN ULONG UserReferenceCount
1099 // CdIncrementFcbReference (
1100 // IN PIRP_CONTEXT IrpContext,
1105 // CdDecrementFcbReference (
1106 // IN PIRP_CONTEXT IrpContext,
1111 #define CdIncrementCleanupCounts(IC,F) { \
1112 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1113 (F)->FcbCleanup += 1; \
1114 (F)->Vcb->VcbCleanup += 1; \
1117 #define CdDecrementCleanupCounts(IC,F) { \
1118 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1119 (F)->FcbCleanup -= 1; \
1120 (F)->Vcb->VcbCleanup -= 1; \
1123 #define CdIncrementReferenceCounts(IC,F,C,UC) { \
1124 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1125 (F)->FcbReference += (C); \
1126 (F)->FcbUserReference += (UC); \
1127 (F)->Vcb->VcbReference += (C); \
1128 (F)->Vcb->VcbUserReference += (UC); \
1131 #define CdDecrementReferenceCounts(IC,F,C,UC) { \
1132 ASSERT_LOCKED_VCB( (F)->Vcb ); \
1133 (F)->FcbReference -= (C); \
1134 (F)->FcbUserReference -= (UC); \
1135 (F)->Vcb->VcbReference -= (C); \
1136 (F)->Vcb->VcbUserReference -= (UC); \
1141 // CdAllocateIoContext (
1145 // CdFreeIoContext (
1146 // PCD_IO_CONTEXT IoContext
1150 #define CdAllocateIoContext() \
1151 FsRtlAllocatePoolWithTag( CdNonPagedPool, \
1152 sizeof( CD_IO_CONTEXT ), \
1155 #define CdFreeIoContext(IO) CdFreePool( &(IO) )
1159 IN PIRP_CONTEXT IrpContext
,
1166 IN PIRP_CONTEXT IrpContext
,
1168 IN PVOID
*RestartKey
1173 IN PIRP_CONTEXT IrpContext
,
1174 IN PDEVICE_OBJECT TargetDeviceObject
,
1175 IN PCDROM_TOC CdromToc
,
1176 IN OUT PULONG Length
,
1177 OUT PULONG TrackCount
,
1178 OUT PULONG DiskFlags
1182 // For debugging purposes we sometimes want to allocate our structures from nonpaged
1183 // pool so that in the kernel debugger we can walk all the structures.
1186 #define CdPagedPool PagedPool
1187 #define CdNonPagedPool NonPagedPool
1188 #define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned
1192 // Verification support routines. Contained in verfysup.c
1195 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1198 CdOperationIsDasdOpen(
1199 IN PIRP_CONTEXT IrpContext
1202 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( IrpContext
->Irp
);
1204 return ((IrpContext
->MajorFunction
== IRP_MJ_CREATE
) &&
1205 (IrpSp
->FileObject
->FileName
.Length
== 0) &&
1206 (IrpSp
->FileObject
->RelatedFileObject
== NULL
));
1212 IN PIRP_CONTEXT IrpContext
,
1214 IN PDEVICE_OBJECT DeviceToVerify
1218 CdCheckForDismount (
1219 IN PIRP_CONTEXT IrpContext
,
1226 IN PIRP_CONTEXT IrpContext
,
1231 CdVerifyFcbOperation (
1232 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1238 IN PIRP_CONTEXT IrpContext
,
1244 // Macros to abstract device verify flag changes.
1247 #define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
1248 #define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C)
1250 #define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1252 #define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
1255 #define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
1260 // IN PIRP_CONTEXT IrpContext,
1261 // IN NTSTATUS Status
1265 #define CdIsRawDevice(IC,S) ( \
1266 ((S) == STATUS_DEVICE_NOT_READY) || \
1267 ((S) == STATUS_NO_MEDIA_IN_DEVICE) \
1272 // Work queue routines for posting and retrieving an Irp, implemented in
1278 IN PIRP_CONTEXT IrpContext
,
1283 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1285 IN PIRP_CONTEXT IrpContext
,
1290 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1292 IN PIRP_CONTEXT IrpContext
,
1298 // Miscellaneous support routines
1302 // This macro returns TRUE if a flag in a set of flags is on and FALSE
1306 /* ReactOS Change: GCC doesn't understand the comment style */
1308 //#ifndef BooleanFlagOn
1309 //#define BooleanFlagOn(F,SF) ( \
1310 // (BOOLEAN)(((F) & (SF)) != 0) \
1315 //#define SetFlag(Flags,SingleFlag) { \
1316 // (Flags) |= (SingleFlag); \
1321 //#define ClearFlag(Flags,SingleFlag) { \
1322 // (Flags) &= ~(SingleFlag); \
1330 // IN PVOID Pointer,
1331 // IN ULONG Increment
1337 // IN PVOID BasePtr,
1338 // IN PVOID OffsetPtr
1342 #define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
1344 #define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
1347 // This macro takes a pointer (or ulong) and returns its rounded up word
1351 #define WordAlign(Ptr) ( \
1352 ((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
1356 // This macro takes a pointer (or ulong) and returns its rounded up longword
1360 #define LongAlign(Ptr) ( \
1361 ((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
1365 // This macro takes a pointer (or ulong) and returns its rounded up quadword
1369 #define QuadAlign(Ptr) ( \
1370 ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
1374 // The following macros round up and down to sector boundaries.
1377 #define SectorAlign(L) ( \
1378 ((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1381 #define LlSectorAlign(L) ( \
1382 ((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
1385 #define SectorTruncate(L) ( \
1386 ((ULONG)(L)) & ~(SECTOR_SIZE - 1) \
1389 #define LlSectorTruncate(L) ( \
1390 ((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \
1393 #define BytesFromSectors(L) ( \
1394 ((ULONG) (L)) << SECTOR_SHIFT \
1397 #define SectorsFromBytes(L) ( \
1398 ((ULONG) (L)) >> SECTOR_SHIFT \
1401 #define LlBytesFromSectors(L) ( \
1402 Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1405 #define LlSectorsFromBytes(L) ( \
1406 Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
1409 #define SectorOffset(L) ( \
1410 ((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \
1413 #define SectorBlockOffset(V,LB) ( \
1414 ((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \
1417 #define BytesFromBlocks(V,B) ( \
1418 (ULONG) (B) << (V)->BlockToByteShift \
1421 #define LlBytesFromBlocks(V,B) ( \
1422 Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \
1425 #define BlockAlign(V,L) ( \
1426 ((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \
1430 // Carefully make sure the mask is sign extended to 64bits
1433 #define LlBlockAlign(V,L) ( \
1434 ((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \
1437 #define BlockOffset(V,L) ( \
1438 ((ULONG) (L)) & (V)->BlockMask \
1441 #define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE)
1444 // The following types and macros are used to help unpack the packed and
1445 // misaligned fields found in the Bios parameter block
1448 typedef union _UCHAR1
{
1450 UCHAR ForceAlignment
;
1453 typedef union _UCHAR2
{
1455 USHORT ForceAlignment
;
1458 typedef union _UCHAR4
{
1460 ULONG ForceAlignment
;
1463 typedef union _USHORT2
{
1465 ULONG ForceAlignment
;
1466 } USHORT2
, *PUSHORT2
;
1469 // This macro copies an unaligned src byte to an aligned dst byte
1472 #define CopyUchar1(Dst,Src) { \
1473 *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
1477 // This macro copies an unaligned src word to an aligned dst word
1480 #define CopyUchar2(Dst,Src) { \
1481 *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
1485 // This macro copies an unaligned src longword to an aligned dsr longword
1488 #define CopyUchar4(Dst,Src) { \
1489 *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
1493 // This macro copies an unaligned src longword to an aligned dsr longword
1494 // accessing the source on a word boundary.
1497 #define CopyUshort2(Dst,Src) { \
1498 *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
1503 // Following routines handle entry in and out of the filesystem. They are
1504 // contained in CdData.c
1509 IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject
,
1515 IN PIRP_CONTEXT IrpContext
,
1516 IN PEXCEPTION_POINTERS ExceptionPointer
1520 CdProcessException (
1521 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1523 IN NTSTATUS ExceptionCode
1528 IN PIRP_CONTEXT IrpContext OPTIONAL
,
1529 IN PIRP Irp OPTIONAL
,
1536 // IN PRIP_CONTEXT IrpContext,
1537 // IN NT_STATUS Status
1541 // CdNormalizeAndRaiseStatus (
1542 // IN PRIP_CONTEXT IrpContext,
1543 // IN NT_STATUS Status
1548 #define AssertVerifyDevice(C, S) \
1549 ASSERT( (C) == NULL || \
1550 FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \
1551 !((S) == STATUS_VERIFY_REQUIRED && \
1552 IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
1554 #define AssertVerifyDeviceIrp(I) \
1555 ASSERT( (I) == NULL || \
1556 !(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \
1557 ((I)->Tail.Overlay.Thread == NULL || \
1558 IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
1560 #define AssertVerifyDevice(C, S)
1561 #define AssertVerifyDeviceIrp(I)
1570 IN PIRP_CONTEXT IrpContext
,
1572 IN BOOLEAN NormalizeStatus
,
1573 IN OPTIONAL ULONG FileId
,
1574 IN OPTIONAL ULONG Line
1583 IN PIRP_CONTEXT IrpContext
,
1585 IN BOOLEAN NormalizeStatus
,
1590 if (NormalizeStatus
) {
1592 IrpContext
->ExceptionStatus
= FsRtlNormalizeNtstatus( Status
, STATUS_UNEXPECTED_IO_ERROR
);
1596 IrpContext
->ExceptionStatus
= Status
;
1599 IrpContext
->RaisedAtLineFile
= (Fileid
<< 16) | Line
;
1601 ExRaiseStatus( IrpContext
->ExceptionStatus
);
1606 #define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__);
1607 #define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__);
1610 // Following are the fast entry points.
1614 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1615 CdFastQueryBasicInfo (
1616 IN PFILE_OBJECT FileObject
,
1618 IN OUT PFILE_BASIC_INFORMATION Buffer
,
1619 OUT PIO_STATUS_BLOCK IoStatus
,
1620 IN PDEVICE_OBJECT DeviceObject
1624 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1625 CdFastQueryStdInfo (
1626 IN PFILE_OBJECT FileObject
,
1628 IN OUT PFILE_STANDARD_INFORMATION Buffer
,
1629 OUT PIO_STATUS_BLOCK IoStatus
,
1630 IN PDEVICE_OBJECT DeviceObject
1634 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1636 IN PFILE_OBJECT FileObject
,
1637 IN PLARGE_INTEGER FileOffset
,
1638 IN PLARGE_INTEGER Length
,
1639 PEPROCESS ProcessId
,
1641 BOOLEAN FailImmediately
,
1642 BOOLEAN ExclusiveLock
,
1643 OUT PIO_STATUS_BLOCK IoStatus
,
1644 IN PDEVICE_OBJECT DeviceObject
1648 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1649 CdFastUnlockSingle (
1650 IN PFILE_OBJECT FileObject
,
1651 IN PLARGE_INTEGER FileOffset
,
1652 IN PLARGE_INTEGER Length
,
1653 PEPROCESS ProcessId
,
1655 OUT PIO_STATUS_BLOCK IoStatus
,
1656 IN PDEVICE_OBJECT DeviceObject
1660 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1662 IN PFILE_OBJECT FileObject
,
1663 PEPROCESS ProcessId
,
1664 OUT PIO_STATUS_BLOCK IoStatus
,
1665 IN PDEVICE_OBJECT DeviceObject
1669 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1670 CdFastUnlockAllByKey (
1671 IN PFILE_OBJECT FileObject
,
1674 OUT PIO_STATUS_BLOCK IoStatus
,
1675 IN PDEVICE_OBJECT DeviceObject
1679 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1680 CdFastIoCheckIfPossible (
1681 IN PFILE_OBJECT FileObject
,
1682 IN PLARGE_INTEGER FileOffset
,
1686 IN BOOLEAN CheckForReadOperation
,
1687 OUT PIO_STATUS_BLOCK IoStatus
,
1688 IN PDEVICE_OBJECT DeviceObject
1692 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
1693 CdFastQueryNetworkInfo (
1694 IN PFILE_OBJECT FileObject
,
1696 OUT PFILE_NETWORK_OPEN_INFORMATION Buffer
,
1697 OUT PIO_STATUS_BLOCK IoStatus
,
1698 IN PDEVICE_OBJECT DeviceObject
1702 // Following are the routines to handle the top level thread logic.
1706 CdSetThreadContext (
1707 IN PIRP_CONTEXT IrpContext
,
1708 IN PTHREAD_CONTEXT ThreadContext
1714 // CdRestoreThreadContext (
1715 // IN PIRP_CONTEXT IrpContext
1719 #define CdRestoreThreadContext(IC) \
1720 (IC)->ThreadContext->Cdfs = 0; \
1721 IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \
1722 (IC)->ThreadContext = NULL
1731 // The following macro is used to determine if an FSD thread can block
1732 // for I/O or wait for a resource. It returns TRUE if the thread can
1733 // block and FALSE otherwise. This attribute can then be used to call
1734 // the FSD & FSP common work routine with the proper wait value.
1737 #define CanFsdWait(I) IoIsOperationSynchronous(I)
1740 // The following macro is used to set the fast i/o possible bits in the
1743 // FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
1745 // FastIoIsQuestionable - If there are file locks.
1747 // FastIoIsPossible - In all other cases.
1751 #define CdIsFastIoPossible(F) ((BOOLEAN) \
1752 ((((F)->Vcb->VcbCondition != VcbMounted ) || \
1753 !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
1755 FastIoIsNotPossible : \
1757 ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
1759 FastIoIsQuestionable : \
1761 FastIoIsPossible)) \
1766 // The FSP level dispatch/main routine. This is the routine that takes
1767 // IRP's off of the work queue and calls the appropriate FSP level
1772 CdFspDispatch ( // implemented in FspDisp.c
1773 IN PIRP_CONTEXT IrpContext
1777 CdFspClose ( // implemented in Close.c
1778 IN PVCB Vcb OPTIONAL
1782 // The following routines are the entry points for the different operations
1783 // based on the IrpSp major functions.
1787 CdCommonCreate ( // Implemented in Create.c
1788 IN PIRP_CONTEXT IrpContext
,
1793 CdCommonClose ( // Implemented in Close.c
1794 IN PIRP_CONTEXT IrpContext
,
1799 CdCommonRead ( // Implemented in Read.c
1800 IN PIRP_CONTEXT IrpContext
,
1805 CdCommonQueryInfo ( // Implemented in FileInfo.c
1806 IN PIRP_CONTEXT IrpContext
,
1811 CdCommonSetInfo ( // Implemented in FileInfo.c
1812 IN PIRP_CONTEXT IrpContext
,
1817 CdCommonQueryVolInfo ( // Implemented in VolInfo.c
1818 IN PIRP_CONTEXT IrpContext
,
1823 CdCommonDirControl ( // Implemented in DirCtrl.c
1824 IN PIRP_CONTEXT IrpContext
,
1829 CdCommonFsControl ( // Implemented in FsCtrl.c
1830 IN PIRP_CONTEXT IrpContext
,
1835 CdCommonDevControl ( // Implemented in DevCtrl.c
1836 IN PIRP_CONTEXT IrpContext
,
1841 CdCommonLockControl ( // Implemented in LockCtrl.c
1842 IN PIRP_CONTEXT IrpContext
,
1847 CdCommonCleanup ( // Implemented in Cleanup.c
1848 IN PIRP_CONTEXT IrpContext
,
1853 CdCommonPnp ( // Implemented in Pnp.c
1854 IN PIRP_CONTEXT IrpContext
,
1860 // The following macros are used to establish the semantics needed
1861 // to do a return from within a try-finally clause. As a rule every
1862 // try clause must end with a label call try_exit. For example,
1868 // try_exit: NOTHING;
1875 // Every return statement executed inside of a try clause should use the
1876 // try_return macro. If the compiler fully supports the try-finally construct
1877 // then the macro should be
1879 // #define try_return(S) { return(S); }
1881 // If the compiler does not support the try-finally construct then the macro
1884 // #define try_return(S) { S; goto try_exit; }
1886 /* ReactOS Change: Remove SEH */
1888 #define leave goto exitLabel;
1889 #define finally if (0) goto exitLabel; exitLabel:
1890 #define except(x) while (0)
1891 #define GetExceptionCode() 0
1892 #define AbnormalTermination() 0
1894 #define try_return(S) { goto try_exit; }
1895 #define try_leave(S) { leave; }
1899 // Encapsulate safe pool freeing
1901 /* ReactOS Change: GCC "passing argument 1 of CdFreePool from incompatible pointer type" */
1902 #define CdFreePool(x) _CdFreePool((PVOID*)(x))
1904 /* ReactOS Change: "LD multiple definition of `_CdOperationIsDasdOpen'" */
1905 static inline void _CdFreePool(
1909 if (*Pool
!= NULL
) {