Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1957 lines
49 KiB

/*++
Copyright (c) 1989-2000 Microsoft Corporation
Module Name:
CdProcs.h
Abstract:
This module defines all of the globally used procedures in the Cdfs
file system.
// @@BEGIN_DDKSPLIT
Author:
Brian Andrew [BrianAn] 01-July-1995
Revision History:
// @@END_DDKSPLIT
--*/
#ifndef _CDPROCS_
#define _CDPROCS_
#include <ntifs.h>
#include <ntddcdrm.h>
#include <ntdddisk.h>
#include <ntddscsi.h>
#ifndef INLINE
#define INLINE __inline
#endif
#include "nodetype.h"
#include "Cd.h"
#include "CdStruc.h"
#include "CdData.h"
//**** x86 compiler bug ****
#if defined(_M_IX86)
#undef Int64ShraMod32
#define Int64ShraMod32(a, b) ((LONGLONG)(a) >> (b))
#endif
//
// Here are the different pool tags.
//
#define TAG_CCB 'ccdC' // Ccb
#define TAG_CDROM_TOC 'ctdC' // TOC
#define TAG_DIRENT_NAME 'nddC' // CdName in dirent
#define TAG_ENUM_EXPRESSION 'eedC' // Search expression for enumeration
#define TAG_FCB_DATA 'dfdC' // Data Fcb
#define TAG_FCB_INDEX 'ifdC' // Index Fcb
#define TAG_FCB_NONPAGED 'nfdC' // Nonpaged Fcb
#define TAG_FCB_TABLE 'tfdC' // Fcb Table entry
#define TAG_FILE_NAME 'nFdC' // Filename buffer
#define TAG_GEN_SHORT_NAME 'sgdC' // Generated short name
#define TAG_IO_BUFFER 'fbdC' // Temporary IO buffer
#define TAG_IO_CONTEXT 'oidC' // Io context for async reads
#define TAG_IRP_CONTEXT 'cidC' // Irp Context
#define TAG_IRP_CONTEXT_LITE 'lidC' // Irp Context lite
#define TAG_MCB_ARRAY 'amdC' // Mcb array
#define TAG_PATH_ENTRY_NAME 'nPdC' // CdName in path entry
#define TAG_PREFIX_ENTRY 'epdC' // Prefix Entry
#define TAG_PREFIX_NAME 'npdC' // Prefix Entry name
#define TAG_SPANNING_PATH_TABLE 'psdC' // Buffer for spanning path table
#define TAG_UPCASE_NAME 'nudC' // Buffer for upcased name
#define TAG_VOL_DESC 'dvdC' // Buffer for volume descriptor
#define TAG_VPB 'pvdC' // Vpb allocated in filesystem
//
// Tag all of our allocations if tagging is turned on
//
#ifdef POOL_TAGGING
#undef FsRtlAllocatePool
#undef FsRtlAllocatePoolWithQuota
#define FsRtlAllocatePool(a,b) FsRtlAllocatePoolWithTag(a,b,'sfdC')
#define FsRtlAllocatePoolWithQuota(a,b) FsRtlAllocatePoolWithQuotaTag(a,b,'sfdC')
#endif // POOL_TAGGING
// @@BEGIN_DDKSPLIT
#ifdef CD_TRACE
#include <stdarg.h>
BOOLEAN
CdDebugTrace (
ULONG TraceMask,
PCHAR Format,
...
);
#define DebugTrace(x) CdDebugTrace x
#else
#define DebugTrace(x)
#endif
// @@END_DDKSPLIT
//
// File access check routine, implemented in AcChkSup.c
//
//
// BOOLEAN
// CdIllegalFcbAccess (
// IN PIRP_CONTEXT IrpContext,
// IN TYPE_OF_OPEN TypeOfOpen,
// IN ACCESS_MASK DesiredAccess
// );
//
#define CdIllegalFcbAccess(IC,T,DA) ( \
BooleanFlagOn( (DA), \
((T) != UserVolumeOpen ? \
(FILE_WRITE_ATTRIBUTES | \
FILE_WRITE_DATA | \
FILE_WRITE_EA | \
FILE_ADD_FILE | \
FILE_ADD_SUBDIRECTORY | \
FILE_APPEND_DATA) : 0) | \
FILE_DELETE_CHILD | \
DELETE | \
WRITE_DAC ))
//
// Allocation support routines, implemented in AllocSup.c
//
// These routines are for querying allocation on individual streams.
//
VOID
CdLookupAllocation (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN LONGLONG FileOffset,
OUT PLONGLONG DiskOffset,
OUT PULONG ByteCount
);
VOID
CdAddAllocationFromDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN ULONG McbEntryOffset,
IN LONGLONG StartingFileOffset,
IN PDIRENT Dirent
);
VOID
CdAddInitialAllocation (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN ULONG StartingBlock,
IN LONGLONG DataLength
);
VOID
CdTruncateAllocation (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN LONGLONG StartingFileOffset
);
VOID
CdInitializeMcb (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb
);
VOID
CdUninitializeMcb (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb
);
//
// Buffer control routines for data caching, implemented in CacheSup.c
//
VOID
CdCreateInternalStream (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFCB Fcb
);
VOID
CdDeleteInternalStream (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb
);
NTSTATUS
CdCompleteMdl (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdPurgeVolume (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN BOOLEAN DismountUnderway
);
//
// VOID
// CdUnpinData (
// IN PIRP_CONTEXT IrpContext,
// IN OUT PBCB *Bcb
// );
//
#define CdUnpinData(IC,B) \
if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
//
// Device I/O routines, implemented in DevIoSup.c
//
// These routines perform the actual device read and writes. They only affect
// the on disk structure and do not alter any other data structures.
//
NTSTATUS
CdNonCachedRead (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN LONGLONG StartingOffset,
IN ULONG ByteCount
);
NTSTATUS
CdNonCachedXARead (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN LONGLONG StartingOffset,
IN ULONG ByteCount
);
BOOLEAN
CdReadSectors (
IN PIRP_CONTEXT IrpContext,
IN LONGLONG StartingOffset,
IN ULONG ByteCount,
IN BOOLEAN RaiseOnError,
IN OUT PVOID Buffer,
IN PDEVICE_OBJECT TargetDeviceObject
);
NTSTATUS
CdCreateUserMdl (
IN PIRP_CONTEXT IrpContext,
IN ULONG BufferLength,
IN BOOLEAN RaiseOnError
);
NTSTATUS
CdPerformDevIoCtrl (
IN PIRP_CONTEXT IrpContext,
IN ULONG IoControlCode,
IN PDEVICE_OBJECT Device,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength,
IN BOOLEAN InternalDeviceIoControl,
IN BOOLEAN OverrideVerify,
OUT PIO_STATUS_BLOCK Iosb OPTIONAL
);
//
// VOID
// CdMapUserBuffer (
// IN PIRP_CONTEXT IrpContext
// OUT PVOID UserBuffer
// );
//
// Returns pointer to sys address. Will raise on failure.
//
//
// VOID
// CdLockUserBuffer (
// IN PIRP_CONTEXT IrpContext,
// IN ULONG BufferLength
// );
//
#define CdMapUserBuffer(IC, UB) { \
*(UB) = (PVOID) ( ((IC)->Irp->MdlAddress == NULL) ? \
(IC)->Irp->UserBuffer : \
(MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority))); \
if (NULL == *(UB)) { \
CdRaiseStatus( (IC), STATUS_INSUFFICIENT_RESOURCES); \
} \
}
#define CdLockUserBuffer(IC,BL) { \
if ((IC)->Irp->MdlAddress == NULL) { \
(VOID) CdCreateUserMdl( (IC), (BL), TRUE ); \
} \
}
//
// Dirent support routines, implemented in DirSup.c
//
VOID
CdLookupDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN ULONG DirentOffset,
OUT PDIRENT_ENUM_CONTEXT DirContext
);
BOOLEAN
CdLookupNextDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PDIRENT_ENUM_CONTEXT CurrentDirContext,
OUT PDIRENT_ENUM_CONTEXT NextDirContext
);
VOID
CdUpdateDirentFromRawDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PDIRENT_ENUM_CONTEXT DirContext,
IN OUT PDIRENT Dirent
);
VOID
CdUpdateDirentName (
IN PIRP_CONTEXT IrpContext,
IN OUT PDIRENT Dirent,
IN ULONG IgnoreCase
);
BOOLEAN
CdFindFile (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN OUT PFILE_ENUM_CONTEXT FileContext,
OUT PCD_NAME *MatchingName
);
BOOLEAN
CdFindDirectory (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN OUT PFILE_ENUM_CONTEXT FileContext
);
BOOLEAN
CdFindFileByShortName (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN ULONG ShortNameDirentOffset,
IN OUT PFILE_ENUM_CONTEXT FileContext
);
BOOLEAN
CdLookupNextInitialFileDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN OUT PFILE_ENUM_CONTEXT FileContext
);
VOID
CdLookupLastFileDirent (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFILE_ENUM_CONTEXT FileContext
);
VOID
CdCleanupFileContext (
IN PIRP_CONTEXT IrpContext,
IN PFILE_ENUM_CONTEXT FileContext
);
//
// VOID
// CdInitializeFileContext (
// IN PIRP_CONTEXT IrpContext,
// IN PFILE_ENUM_CONTEXT FileContext
// );
//
//
// VOID
// CdInitializeDirent (
// IN PIRP_CONTEXT IrpContext,
// IN PDIRENT Dirent
// );
//
// VOID
// CdInitializeDirContext (
// IN PIRP_CONTEXT IrpContext,
// IN PDIRENT_ENUM_CONTEXT DirContext
// );
//
// VOID
// CdCleanupDirent (
// IN PIRP_CONTEXT IrpContext,
// IN PDIRENT Dirent
// );
//
// VOID
// CdCleanupDirContext (
// IN PIRP_CONTEXT IrpContext,
// IN PDIRENT_ENUM_CONTEXT DirContext
// );
//
// VOID
// CdLookupInitialFileDirent (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb,
// IN PFILE_ENUM_CONTEXT FileContext,
// IN ULONG DirentOffset
// );
//
#define CdInitializeFileContext(IC,FC) { \
RtlZeroMemory( FC, sizeof( FILE_ENUM_CONTEXT )); \
(FC)->PriorDirent = &(FC)->Dirents[0]; \
(FC)->InitialDirent = &(FC)->Dirents[1]; \
(FC)->CurrentDirent = &(FC)->Dirents[2]; \
(FC)->ShortName.FileName.MaximumLength = BYTE_COUNT_8_DOT_3; \
(FC)->ShortName.FileName.Buffer = (FC)->ShortNameBuffer; \
}
#define CdInitializeDirent(IC,D) \
RtlZeroMemory( D, sizeof( DIRENT ))
#define CdInitializeDirContext(IC,DC) \
RtlZeroMemory( DC, sizeof( DIRENT_ENUM_CONTEXT ))
#define CdCleanupDirent(IC,D) { \
if (FlagOn( (D)->Flags, DIRENT_FLAG_ALLOC_BUFFER )) { \
CdFreePool( &(D)->CdFileName.FileName.Buffer ); \
} \
}
#define CdCleanupDirContext(IC,DC) \
CdUnpinData( (IC), &(DC)->Bcb )
#define CdLookupInitialFileDirent(IC,F,FC,DO) \
CdLookupDirent( IC, \
F, \
DO, \
&(FC)->InitialDirent->DirContext ); \
CdUpdateDirentFromRawDirent( IC, \
F, \
&(FC)->InitialDirent->DirContext, \
&(FC)->InitialDirent->Dirent )
//
// The following routines are used to manipulate the fscontext fields
// of the file object, implemented in FilObSup.c
//
//
// Type of opens. FilObSup.c depends on this order.
//
typedef enum _TYPE_OF_OPEN {
UnopenedFileObject = 0,
StreamFileOpen,
UserVolumeOpen,
UserDirectoryOpen,
UserFileOpen,
BeyondValidType
} TYPE_OF_OPEN;
typedef TYPE_OF_OPEN *PTYPE_OF_OPEN;
VOID
CdSetFileObject (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
IN TYPE_OF_OPEN TypeOfOpen,
IN PFCB Fcb OPTIONAL,
IN PCCB Ccb OPTIONAL
);
TYPE_OF_OPEN
CdDecodeFileObject (
IN PIRP_CONTEXT IrpContext,
IN PFILE_OBJECT FileObject,
OUT PFCB *Fcb,
OUT PCCB *Ccb
);
TYPE_OF_OPEN
CdFastDecodeFileObject (
IN PFILE_OBJECT FileObject,
OUT PFCB *Fcb
);
//
// Name support routines, implemented in NameSup.c
//
VOID
CdConvertNameToCdName (
IN PIRP_CONTEXT IrpContext,
IN OUT PCD_NAME CdName
);
VOID
CdConvertBigToLittleEndian (
IN PIRP_CONTEXT IrpContext,
IN PCHAR BigEndian,
IN ULONG ByteCount,
OUT PCHAR LittleEndian
);
VOID
CdUpcaseName (
IN PIRP_CONTEXT IrpContext,
IN PCD_NAME Name,
IN OUT PCD_NAME UpcaseName
);
VOID
CdDissectName (
IN PIRP_CONTEXT IrpContext,
IN OUT PUNICODE_STRING RemainingName,
OUT PUNICODE_STRING FinalName
);
BOOLEAN
CdIs8dot3Name (
IN PIRP_CONTEXT IrpContext,
IN UNICODE_STRING FileName
);
VOID
CdGenerate8dot3Name (
IN PIRP_CONTEXT IrpContext,
IN PUNICODE_STRING FileName,
IN ULONG DirentOffset,
OUT PWCHAR ShortFileName,
OUT PUSHORT ShortByteCount
);
BOOLEAN
CdIsNameInExpression (
IN PIRP_CONTEXT IrpContext,
IN PCD_NAME CurrentName,
IN PCD_NAME SearchExpression,
IN ULONG WildcardFlags,
IN BOOLEAN CheckVersion
);
ULONG
CdShortNameDirentOffset (
IN PIRP_CONTEXT IrpContext,
IN PUNICODE_STRING Name
);
FSRTL_COMPARISON_RESULT
CdFullCompareNames (
IN PIRP_CONTEXT IrpContext,
IN PUNICODE_STRING NameA,
IN PUNICODE_STRING NameB
);
//
// Filesystem control operations. Implemented in Fsctrl.c
//
NTSTATUS
CdLockVolumeInternal (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_OBJECT FileObject OPTIONAL
);
NTSTATUS
CdUnlockVolumeInternal (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFILE_OBJECT FileObject OPTIONAL
);
//
// Path table enumeration routines. Implemented in PathSup.c
//
VOID
CdLookupPathEntry (
IN PIRP_CONTEXT IrpContext,
IN ULONG PathEntryOffset,
IN ULONG Ordinal,
IN BOOLEAN VerifyBounds,
IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
);
BOOLEAN
CdLookupNextPathEntry (
IN PIRP_CONTEXT IrpContext,
IN OUT PPATH_ENUM_CONTEXT PathContext,
IN OUT PPATH_ENTRY PathEntry
);
BOOLEAN
CdFindPathEntry (
IN PIRP_CONTEXT IrpContext,
IN PFCB ParentFcb,
IN PCD_NAME DirName,
IN BOOLEAN IgnoreCase,
IN OUT PCOMPOUND_PATH_ENTRY CompoundPathEntry
);
VOID
CdUpdatePathEntryName (
IN PIRP_CONTEXT IrpContext,
IN OUT PPATH_ENTRY PathEntry,
IN BOOLEAN IgnoreCase
);
//
// VOID
// CdInitializeCompoundPathEntry (
// IN PIRP_CONTEXT IrpContext,
// IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
// );
//
// VOID
// CdCleanupCompoundPathEntry (
// IN PIRP_CONTEXT IrpContext,
// IN PCOMPOUND_PATH_ENTRY CompoundPathEntry
// );
//
#define CdInitializeCompoundPathEntry(IC,CP) \
RtlZeroMemory( CP, sizeof( COMPOUND_PATH_ENTRY ))
#define CdCleanupCompoundPathEntry(IC,CP) { \
CdUnpinData( (IC), &(CP)->PathContext.Bcb ); \
if ((CP)->PathContext.AllocatedData) { \
CdFreePool( &(CP)->PathContext.Data ); \
} \
if (FlagOn( (CP)->PathEntry.Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) { \
CdFreePool( &(CP)->PathEntry.CdDirName.FileName.Buffer ); \
} \
}
//
// Largest matching prefix searching routines, implemented in PrefxSup.c
//
VOID
CdInsertPrefix (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PCD_NAME Name,
IN BOOLEAN IgnoreCase,
IN BOOLEAN ShortNameMatch,
IN PFCB ParentFcb
);
VOID
CdRemovePrefix (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb
);
VOID
CdFindPrefix (
IN PIRP_CONTEXT IrpContext,
IN OUT PFCB *CurrentFcb,
IN OUT PUNICODE_STRING RemainingName,
IN BOOLEAN IgnoreCase
);
//
// Synchronization routines. Implemented in Resrcsup.c
//
// The following routines/macros are used to synchronize the in-memory structures.
//
// Routine/Macro Synchronizes Subsequent
//
// CdAcquireCdData Volume Mounts/Dismounts,Vcb Queue CdReleaseCdData
// CdAcquireVcbExclusive Vcb for open/close CdReleaseVcb
// CdAcquireVcbShared Vcb for open/close CdReleaseVcb
// CdAcquireAllFiles Locks out operations to all files CdReleaseAllFiles
// CdAcquireFileExclusive Locks out file operations CdReleaseFile
// CdAcquireFileShared Files for file operations CdReleaseFile
// CdAcquireFcbExclusive Fcb for open/close CdReleaseFcb
// CdAcquireFcbShared Fcb for open/close CdReleaseFcb
// CdLockCdData Fields in CdData CdUnlockCdData
// CdLockVcb Vcb fields, FcbReference, FcbTable CdUnlockVcb
// CdLockFcb Fcb fields, prefix table, Mcb CdUnlockFcb
//
typedef enum _TYPE_OF_ACQUIRE {
AcquireExclusive,
AcquireShared,
AcquireSharedStarveExclusive
} TYPE_OF_ACQUIRE, *PTYPE_OF_ACQUIRE;
BOOLEAN
CdAcquireResource (
IN PIRP_CONTEXT IrpContext,
IN PERESOURCE Resource,
IN BOOLEAN IgnoreWait,
IN TYPE_OF_ACQUIRE Type
);
//
// BOOLEAN
// CdAcquireCdData (
// IN PIRP_CONTEXT IrpContext
// );
//
// VOID
// CdReleaseCdData (
// IN PIRP_CONTEXT IrpContext
// );
//
// BOOLEAN
// CdAcquireVcbExclusive (
// IN PIRP_CONTEXT IrpContext,
// IN PVCB Vcb,
// IN BOOLEAN IgnoreWait
// );
//
// BOOLEAN
// CdAcquireVcbShared (
// IN PIRP_CONTEXT IrpContext,
// IN PVCB Vcb,
// IN BOOLEAN IgnoreWait
// );
//
// VOID
// CdReleaseVcb (
// IN PIRP_CONTEXT IrpContext,
// IN PVCB Vcb
// );
//
// VOID
// CdAcquireAllFiles (
// IN PIRP_CONTEXT,
// IN PVCB Vcb
// );
//
// VOID
// CdReleaseAllFiles (
// IN PIRP_CONTEXT,
// IN PVCB Vcb
// );
//
// VOID
// CdAcquireFileExclusive (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb,
// );
//
// VOID
// CdAcquireFileShared (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// VOID
// CdReleaseFile (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// BOOLEAN
// CdAcquireFcbExclusive (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb,
// IN BOOLEAN IgnoreWait
// );
//
// BOOLEAN
// CdAcquireFcbShared (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb,
// IN BOOLEAN IgnoreWait
// );
//
// BOOLEAN
// CdReleaseFcb (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// VOID
// CdLockCdData (
// );
//
// VOID
// CdUnlockCdData (
// );
//
// VOID
// CdLockVcb (
// IN PIRP_CONTEXT IrpContext
// );
//
// VOID
// CdUnlockVcb (
// IN PIRP_CONTEXT IrpContext
// );
//
// VOID
// CdLockFcb (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// VOID
// CdUnlockFcb (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
#define CdAcquireCdData(IC) \
ExAcquireResourceExclusiveLite( &CdData.DataResource, TRUE )
#define CdReleaseCdData(IC) \
ExReleaseResourceLite( &CdData.DataResource )
#define CdAcquireVcbExclusive(IC,V,I) \
CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
#define CdAcquireVcbShared(IC,V,I) \
CdAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
#define CdReleaseVcb(IC,V) \
ExReleaseResourceLite( &(V)->VcbResource )
#define CdAcquireAllFiles(IC,V) \
CdAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
#define CdReleaseAllFiles(IC,V) \
ExReleaseResourceLite( &(V)->FileResource )
#define CdAcquireFileExclusive(IC,F) \
CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
#define CdAcquireFileShared(IC,F) \
CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
#define CdAcquireFileSharedStarveExclusive(IC,F) \
CdAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
#define CdReleaseFile(IC,F) \
ExReleaseResourceLite( (F)->Resource )
#define CdAcquireFcbExclusive(IC,F,I) \
CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
#define CdAcquireFcbShared(IC,F,I) \
CdAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
#define CdReleaseFcb(IC,F) \
ExReleaseResourceLite( &(F)->FcbNonpaged->FcbResource )
#define CdLockCdData() \
ExAcquireFastMutex( &CdData.CdDataMutex ); \
CdData.CdDataLockThread = PsGetCurrentThread()
#define CdUnlockCdData() \
CdData.CdDataLockThread = NULL; \
ExReleaseFastMutex( &CdData.CdDataMutex )
#define CdLockVcb(IC,V) \
ExAcquireFastMutex( &(V)->VcbMutex ); \
ASSERT( NULL == (V)->VcbLockThread); \
(V)->VcbLockThread = PsGetCurrentThread()
#define CdUnlockVcb(IC,V) \
ASSERT( NULL != (V)->VcbLockThread); \
(V)->VcbLockThread = NULL; \
ExReleaseFastMutex( &(V)->VcbMutex )
#define CdLockFcb(IC,F) { \
PVOID _CurrentThread = PsGetCurrentThread(); \
if (_CurrentThread != (F)->FcbLockThread) { \
ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
ASSERT( (F)->FcbLockCount == 0 ); \
(F)->FcbLockThread = _CurrentThread; \
} \
(F)->FcbLockCount += 1; \
}
#define CdUnlockFcb(IC,F) { \
(F)->FcbLockCount -= 1; \
if ((F)->FcbLockCount == 0) { \
(F)->FcbLockThread = NULL; \
ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \
} \
}
BOOLEAN
CdNoopAcquire (
IN PVOID Fcb,
IN BOOLEAN Wait
);
VOID
CdNoopRelease (
IN PVOID Fcb
);
BOOLEAN
CdAcquireForCache (
IN PFCB Fcb,
IN BOOLEAN Wait
);
VOID
CdReleaseFromCache (
IN PFCB Fcb
);
VOID
CdAcquireForCreateSection (
IN PFILE_OBJECT FileObject
);
VOID
CdReleaseForCreateSection (
IN PFILE_OBJECT FileObject
);
//
// In-memory structure support routines. Implemented in StrucSup.c
//
VOID
CdInitializeVcb (
IN PIRP_CONTEXT IrpContext,
IN OUT PVCB Vcb,
IN PDEVICE_OBJECT TargetDeviceObject,
IN PVPB Vpb,
IN PCDROM_TOC CdromToc,
IN ULONG TocLength,
IN ULONG TocTrackCount,
IN ULONG TocDiskFlags,
IN ULONG BlockFactor,
IN ULONG MediaChangeCount
);
VOID
CdUpdateVcbFromVolDescriptor (
IN PIRP_CONTEXT IrpContext,
IN OUT PVCB Vcb,
IN PCHAR RawIsoVd OPTIONAL
);
VOID
CdDeleteVcb (
IN PIRP_CONTEXT IrpContext,
IN OUT PVCB Vcb
);
PFCB
CdCreateFcb (
IN PIRP_CONTEXT IrpContext,
IN FILE_ID FileId,
IN NODE_TYPE_CODE NodeTypeCode,
OUT PBOOLEAN FcbExisted OPTIONAL
);
VOID
CdInitializeFcbFromPathEntry (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFCB ParentFcb OPTIONAL,
IN PPATH_ENTRY PathEntry
);
VOID
CdInitializeFcbFromFileContext (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFCB ParentFcb OPTIONAL,
IN PFILE_ENUM_CONTEXT FileContext
);
PCCB
CdCreateCcb (
IN PIRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN ULONG Flags
);
VOID
CdDeleteCcb (
IN PIRP_CONTEXT IrpContext,
IN PCCB Ccb
);
BOOLEAN
CdCreateFileLock (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PFCB Fcb,
IN BOOLEAN RaiseOnError
);
VOID
CdDeleteFileLock (
IN PIRP_CONTEXT IrpContext,
IN PFILE_LOCK FileLock
);
PIRP_CONTEXT
CdCreateIrpContext (
IN PIRP Irp,
IN BOOLEAN Wait
);
VOID
CdCleanupIrpContext (
IN PIRP_CONTEXT IrpContext,
IN BOOLEAN Post
);
VOID
CdInitializeStackIrpContext (
OUT PIRP_CONTEXT IrpContext,
IN PIRP_CONTEXT_LITE IrpContextLite
);
//
// PIRP_CONTEXT_LITE
// CdCreateIrpContextLite (
// IN PIRP_CONTEXT IrpContext
// );
//
// VOID
// CdFreeIrpContextLite (
// IN PIRP_CONTEXT_LITE IrpContextLite
// );
//
#define CdCreateIrpContextLite(IC) \
ExAllocatePoolWithTag( CdNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
#define CdFreeIrpContextLite(ICL) \
CdFreePool( &(ICL) )
VOID
CdTeardownStructures (
IN PIRP_CONTEXT IrpContext,
IN PFCB StartingFcb,
OUT PBOOLEAN RemovedStartingFcb
);
//
// VOID
// CdIncrementCleanupCounts (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// VOID
// CdDecrementCleanupCounts (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// VOID
// CdIncrementReferenceCounts (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb,
// IN ULONG ReferenceCount
// IN ULONG UserReferenceCount
// );
//
// VOID
// CdDecrementReferenceCounts (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb,
// IN ULONG ReferenceCount
// IN ULONG UserReferenceCount
// );
//
// VOID
// CdIncrementFcbReference (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
// VOID
// CdDecrementFcbReference (
// IN PIRP_CONTEXT IrpContext,
// IN PFCB Fcb
// );
//
#define CdIncrementCleanupCounts(IC,F) { \
ASSERT_LOCKED_VCB( (F)->Vcb ); \
(F)->FcbCleanup += 1; \
(F)->Vcb->VcbCleanup += 1; \
}
#define CdDecrementCleanupCounts(IC,F) { \
ASSERT_LOCKED_VCB( (F)->Vcb ); \
(F)->FcbCleanup -= 1; \
(F)->Vcb->VcbCleanup -= 1; \
}
#define CdIncrementReferenceCounts(IC,F,C,UC) { \
ASSERT_LOCKED_VCB( (F)->Vcb ); \
(F)->FcbReference += (C); \
(F)->FcbUserReference += (UC); \
(F)->Vcb->VcbReference += (C); \
(F)->Vcb->VcbUserReference += (UC); \
}
#define CdDecrementReferenceCounts(IC,F,C,UC) { \
ASSERT_LOCKED_VCB( (F)->Vcb ); \
(F)->FcbReference -= (C); \
(F)->FcbUserReference -= (UC); \
(F)->Vcb->VcbReference -= (C); \
(F)->Vcb->VcbUserReference -= (UC); \
}
//
// PCD_IO_CONTEXT
// CdAllocateIoContext (
// );
//
// VOID
// CdFreeIoContext (
// PCD_IO_CONTEXT IoContext
// );
//
#define CdAllocateIoContext() \
FsRtlAllocatePoolWithTag( CdNonPagedPool, \
sizeof( CD_IO_CONTEXT ), \
TAG_IO_CONTEXT )
#define CdFreeIoContext(IO) CdFreePool( &(IO) )
PFCB
CdLookupFcbTable (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN FILE_ID FileId
);
PFCB
CdGetNextFcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PVOID *RestartKey
);
NTSTATUS
CdProcessToc (
IN PIRP_CONTEXT IrpContext,
IN PDEVICE_OBJECT TargetDeviceObject,
IN PCDROM_TOC CdromToc,
IN OUT PULONG Length,
OUT PULONG TrackCount,
OUT PULONG DiskFlags
);
//
// For debugging purposes we sometimes want to allocate our structures from nonpaged
// pool so that in the kernel debugger we can walk all the structures.
//
#define CdPagedPool PagedPool
#define CdNonPagedPool NonPagedPool
#define CdNonPagedPoolCacheAligned NonPagedPoolCacheAligned
//
// Verification support routines. Contained in verfysup.c
//
INLINE
BOOLEAN
CdOperationIsDasdOpen(
IN PIRP_CONTEXT IrpContext
)
{
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->Irp);
return ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
(IrpSp->FileObject->FileName.Length == 0) &&
(IrpSp->FileObject->RelatedFileObject == NULL));
}
NTSTATUS
CdPerformVerify (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PDEVICE_OBJECT DeviceToVerify
);
BOOLEAN
CdCheckForDismount (
IN PIRP_CONTEXT IrpContext,
IN PVCB,
IN BOOLEAN Force
);
VOID
CdVerifyVcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
);
BOOLEAN
CdVerifyFcbOperation (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PFCB Fcb
);
BOOLEAN
CdDismountVcb (
IN PIRP_CONTEXT IrpContext,
IN PVCB Vcb
);
// @@BEGIN_DDKSPLIT
//
// Some debug aids we don't want cluttering the shipped IFSkit sample code.
//
//
// Macros for insterting delays for debugging purposes.
//
#define DELAY_N_SECONDS( S) { \
INT64 Delay = -1000*1000*(S); \
KeDelayExecutionThread( KernelMode, FALSE, (PLARGE_INTEGER)&Delay); \
}
#define DELAY_WHILE_TRUE( V) { \
while (V) { \
DELAY_N_SECONDS( 1); \
} \
}
#ifdef CD_TRACE
#define CdUpdateMediaChangeCount( V, C) { DebugTrace(( 1, "V %p MC %d -> %d (%d %s)\n", (V), (V)->MediaChangeCount, (C), __LINE__, __FILE__)); \
(V)->MediaChangeCount = (C); }
#define CdUpdateVcbCondition( V, C) { DebugTrace(( 1, "V %p Condition %d -> %d (%d %s)\n", (V), (V)->VcbCondition, (C), __LINE__, __FILE__)); \
(V)->VcbCondition = (C); }
#define CdMarkRealDevForVerify( DO) { DebugTrace(( 1, "D %p Mark for verify (%d %s)\n", (DO), __LINE__, __FILE__)); \
SetFlag( (DO)->Flags, DO_VERIFY_VOLUME); }
#define CdMarkRealDevVerifyOk( DO) { DebugTrace(( 1, "D %p Mark verify OK (%d %s)\n", (DO), __LINE__, __FILE__)); \
ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME); }
#else
// @@END_DDKSPLIT
//
// Macros to abstract device verify flag changes.
//
#define CdUpdateMediaChangeCount( V, C) (V)->MediaChangeCount = (C)
#define CdUpdateVcbCondition( V, C) (V)->VcbCondition = (C)
#define CdMarkRealDevForVerify( DO) SetFlag( (DO)->Flags, DO_VERIFY_VOLUME)
#define CdMarkRealDevVerifyOk( DO) ClearFlag( (DO)->Flags, DO_VERIFY_VOLUME)
// @@BEGIN_DDKSPLIT
#endif
// @@END_DDKSPLIT
#define CdRealDevNeedsVerify( DO) BooleanFlagOn( (DO)->Flags, DO_VERIFY_VOLUME)
//
// BOOLEAN
// CdIsRawDevice (
// IN PIRP_CONTEXT IrpContext,
// IN NTSTATUS Status
// );
//
#define CdIsRawDevice(IC,S) ( \
((S) == STATUS_DEVICE_NOT_READY) || \
((S) == STATUS_NO_MEDIA_IN_DEVICE) \
)
//
// Work queue routines for posting and retrieving an Irp, implemented in
// workque.c
//
NTSTATUS
CdFsdPostRequest(
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
VOID
CdPrePostIrp (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
VOID
CdOplockComplete (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
//
// Miscellaneous support routines
//
//
// This macro returns TRUE if a flag in a set of flags is on and FALSE
// otherwise
//
//#ifndef BooleanFlagOn
//#define BooleanFlagOn(F,SF) ( \
// (BOOLEAN)(((F) & (SF)) != 0) \
//)
//#endif
//#ifndef SetFlag
//#define SetFlag(Flags,SingleFlag) { \
// (Flags) |= (SingleFlag); \
//}
//#endif
//#ifndef ClearFlag
//#define ClearFlag(Flags,SingleFlag) { \
// (Flags) &= ~(SingleFlag); \
//}
//#endif
//
// CAST
// Add2Ptr (
// IN PVOID Pointer,
// IN ULONG Increment
// IN (CAST)
// );
//
// ULONG
// PtrOffset (
// IN PVOID BasePtr,
// IN PVOID OffsetPtr
// );
//
#define Add2Ptr(PTR,INC,CAST) ((CAST)((PUCHAR)(PTR) + (INC)))
#define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG_PTR)(OFFSET) - (ULONG_PTR)(BASE)))
//
// This macro takes a pointer (or ulong) and returns its rounded up word
// value
//
#define WordAlign(Ptr) ( \
((((ULONG)(Ptr)) + 1) & 0xfffffffe) \
)
//
// This macro takes a pointer (or ulong) and returns its rounded up longword
// value
//
#define LongAlign(Ptr) ( \
((((ULONG)(Ptr)) + 3) & 0xfffffffc) \
)
//
// This macro takes a pointer (or ulong) and returns its rounded up quadword
// value
//
#define QuadAlign(Ptr) ( \
((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
)
//
// The following macros round up and down to sector boundaries.
//
#define SectorAlign(L) ( \
((((ULONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
)
#define LlSectorAlign(L) ( \
((((LONGLONG)(L)) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) \
)
#define SectorTruncate(L) ( \
((ULONG)(L)) & ~(SECTOR_SIZE - 1) \
)
#define LlSectorTruncate(L) ( \
((LONGLONG)(L)) & ~(SECTOR_SIZE - 1) \
)
#define BytesFromSectors(L) ( \
((ULONG) (L)) << SECTOR_SHIFT \
)
#define SectorsFromBytes(L) ( \
((ULONG) (L)) >> SECTOR_SHIFT \
)
#define LlBytesFromSectors(L) ( \
Int64ShllMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
)
#define LlSectorsFromBytes(L) ( \
Int64ShraMod32( (LONGLONG)(L), SECTOR_SHIFT ) \
)
#define SectorOffset(L) ( \
((ULONG)(ULONG_PTR) (L)) & SECTOR_MASK \
)
#define SectorBlockOffset(V,LB) ( \
((ULONG) (LB)) & ((V)->BlocksPerSector - 1) \
)
#define BytesFromBlocks(V,B) ( \
(ULONG) (B) << (V)->BlockToByteShift \
)
#define LlBytesFromBlocks(V,B) ( \
Int64ShllMod32( (LONGLONG) (B), (V)->BlockToByteShift ) \
)
#define BlockAlign(V,L) ( \
((ULONG)(L) + (V)->BlockMask) & (V)->BlockInverseMask \
)
//
// Carefully make sure the mask is sign extended to 64bits
//
#define LlBlockAlign(V,L) ( \
((LONGLONG)(L) + (V)->BlockMask) & (LONGLONG)((LONG)(V)->BlockInverseMask) \
)
#define BlockOffset(V,L) ( \
((ULONG) (L)) & (V)->BlockMask \
)
#define RawSectorAlign( B) ((((B)+(RAW_SECTOR_SIZE - 1)) / RAW_SECTOR_SIZE) * RAW_SECTOR_SIZE)
//
// The following types and macros are used to help unpack the packed and
// misaligned fields found in the Bios parameter block
//
typedef union _UCHAR1 {
UCHAR Uchar[1];
UCHAR ForceAlignment;
} UCHAR1, *PUCHAR1;
typedef union _UCHAR2 {
UCHAR Uchar[2];
USHORT ForceAlignment;
} UCHAR2, *PUCHAR2;
typedef union _UCHAR4 {
UCHAR Uchar[4];
ULONG ForceAlignment;
} UCHAR4, *PUCHAR4;
typedef union _USHORT2 {
USHORT Ushort[2];
ULONG ForceAlignment;
} USHORT2, *PUSHORT2;
//
// This macro copies an unaligned src byte to an aligned dst byte
//
#define CopyUchar1(Dst,Src) { \
*((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
}
//
// This macro copies an unaligned src word to an aligned dst word
//
#define CopyUchar2(Dst,Src) { \
*((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
}
//
// This macro copies an unaligned src longword to an aligned dsr longword
//
#define CopyUchar4(Dst,Src) { \
*((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
}
//
// This macro copies an unaligned src longword to an aligned dsr longword
// accessing the source on a word boundary.
//
#define CopyUshort2(Dst,Src) { \
*((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
}
//
// Following routines handle entry in and out of the filesystem. They are
// contained in CdData.c
//
NTSTATUS
CdFsdDispatch (
IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
IN PIRP Irp
);
LONG
CdExceptionFilter (
IN PIRP_CONTEXT IrpContext,
IN PEXCEPTION_POINTERS ExceptionPointer
);
NTSTATUS
CdProcessException (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PIRP Irp,
IN NTSTATUS ExceptionCode
);
VOID
CdCompleteRequest (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PIRP Irp OPTIONAL,
IN NTSTATUS Status
);
//
// VOID
// CdRaiseStatus (
// IN PRIP_CONTEXT IrpContext,
// IN NT_STATUS Status
// );
//
// VOID
// CdNormalizeAndRaiseStatus (
// IN PRIP_CONTEXT IrpContext,
// IN NT_STATUS Status
// );
//
#if 0
#define AssertVerifyDevice(C, S) \
ASSERT( (C) == NULL || \
FlagOn( (C)->Flags, IRP_CONTEXT_FLAG_IN_FSP ) || \
!((S) == STATUS_VERIFY_REQUIRED && \
IoGetDeviceToVerify( PsGetCurrentThread() ) == NULL ));
#define AssertVerifyDeviceIrp(I) \
ASSERT( (I) == NULL || \
!(((I)->IoStatus.Status) == STATUS_VERIFY_REQUIRED && \
((I)->Tail.Overlay.Thread == NULL || \
IoGetDeviceToVerify( (I)->Tail.Overlay.Thread ) == NULL )));
#else
#define AssertVerifyDevice(C, S)
#define AssertVerifyDeviceIrp(I)
#endif
#ifdef CD_SANITY
DECLSPEC_NORETURN
VOID
CdRaiseStatusEx(
IN PIRP_CONTEXT IrpContext,
IN NTSTATUS Status,
IN BOOLEAN NormalizeStatus,
IN OPTIONAL ULONG FileId,
IN OPTIONAL ULONG Line
);
#else
INLINE
DECLSPEC_NORETURN
VOID
CdRaiseStatusEx(
IN PIRP_CONTEXT IrpContext,
IN NTSTATUS Status,
IN BOOLEAN NormalizeStatus,
IN ULONG Fileid,
IN ULONG Line
)
{
if (NormalizeStatus) {
IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR);
}
else {
IrpContext->ExceptionStatus = Status;
}
IrpContext->RaisedAtLineFile = (Fileid << 16) | Line;
ExRaiseStatus( IrpContext->ExceptionStatus );
}
#endif
#define CdRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), FALSE, BugCheckFileId, __LINE__);
#define CdNormalizeAndRaiseStatus( IC, S) CdRaiseStatusEx( (IC), (S), TRUE, BugCheckFileId, __LINE__);
//
// Following are the fast entry points.
//
BOOLEAN
CdFastQueryBasicInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN OUT PFILE_BASIC_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastQueryStdInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN OUT PFILE_STANDARD_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastLock (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
PEPROCESS ProcessId,
ULONG Key,
BOOLEAN FailImmediately,
BOOLEAN ExclusiveLock,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastUnlockSingle (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PLARGE_INTEGER Length,
PEPROCESS ProcessId,
ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastUnlockAll (
IN PFILE_OBJECT FileObject,
PEPROCESS ProcessId,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastUnlockAllByKey (
IN PFILE_OBJECT FileObject,
PVOID ProcessId,
ULONG Key,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastIoCheckIfPossible (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
BOOLEAN
CdFastQueryNetworkInfo (
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
);
//
// Following are the routines to handle the top level thread logic.
//
VOID
CdSetThreadContext (
IN PIRP_CONTEXT IrpContext,
IN PTHREAD_CONTEXT ThreadContext
);
//
// VOID
// CdRestoreThreadContext (
// IN PIRP_CONTEXT IrpContext
// );
//
#define CdRestoreThreadContext(IC) \
(IC)->ThreadContext->Cdfs = 0; \
IoSetTopLevelIrp( (IC)->ThreadContext->SavedTopLevelIrp ); \
(IC)->ThreadContext = NULL
ULONG
CdSerial32 (
IN PCHAR Buffer,
IN ULONG ByteCount
);
//
// The following macro is used to determine if an FSD thread can block
// for I/O or wait for a resource. It returns TRUE if the thread can
// block and FALSE otherwise. This attribute can then be used to call
// the FSD & FSP common work routine with the proper wait value.
//
#define CanFsdWait(I) IoIsOperationSynchronous(I)
//
// The following macro is used to set the fast i/o possible bits in the
// FsRtl header.
//
// FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
//
// FastIoIsQuestionable - If there are file locks.
//
// FastIoIsPossible - In all other cases.
//
//
#define CdIsFastIoPossible(F) ((BOOLEAN) \
((((F)->Vcb->VcbCondition != VcbMounted ) || \
!FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
\
FastIoIsNotPossible : \
\
((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
\
FastIoIsQuestionable : \
\
FastIoIsPossible)) \
)
//
// The FSP level dispatch/main routine. This is the routine that takes
// IRP's off of the work queue and calls the appropriate FSP level
// work routine.
//
VOID
CdFspDispatch ( // implemented in FspDisp.c
IN PIRP_CONTEXT IrpContext
);
VOID
CdFspClose ( // implemented in Close.c
IN PVCB Vcb OPTIONAL
);
//
// The following routines are the entry points for the different operations
// based on the IrpSp major functions.
//
NTSTATUS
CdCommonCreate ( // Implemented in Create.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonClose ( // Implemented in Close.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonRead ( // Implemented in Read.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonQueryInfo ( // Implemented in FileInfo.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonSetInfo ( // Implemented in FileInfo.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonQueryVolInfo ( // Implemented in VolInfo.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonDirControl ( // Implemented in DirCtrl.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonFsControl ( // Implemented in FsCtrl.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonDevControl ( // Implemented in DevCtrl.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonLockControl ( // Implemented in LockCtrl.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonCleanup ( // Implemented in Cleanup.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
NTSTATUS
CdCommonPnp ( // Implemented in Pnp.c
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
);
//
// The following macros are used to establish the semantics needed
// to do a return from within a try-finally clause. As a rule every
// try clause must end with a label call try_exit. For example,
//
// try {
// :
// :
//
// try_exit: NOTHING;
// } finally {
//
// :
// :
// }
//
// Every return statement executed inside of a try clause should use the
// try_return macro. If the compiler fully supports the try-finally construct
// then the macro should be
//
// #define try_return(S) { return(S); }
//
// If the compiler does not support the try-finally construct then the macro
// should be
//
// #define try_return(S) { S; goto try_exit; }
//
#define try_return(S) { S; goto try_exit; }
#define try_leave(S) { S; leave; }
//
// Encapsulate safe pool freeing
//
INLINE
VOID
CdFreePool(
IN PVOID *Pool
)
{
if (*Pool != NULL) {
ExFreePool(*Pool);
*Pool = NULL;
}
}
#endif // _CDPROCS_