|
|
/*++ BUILD Version: 0001 // Increment this if a change has global effects
Copyright (c) 1989 Microsoft Corporation
Module Name:
FsRtl.h
Abstract:
This module defines all of the general File System Rtl routines
Author:
Gary Kimura [GaryKi] 30-Jul-1990
Revision History:
--*/
#ifndef _FSRTL_
#define _FSRTL_
// begin_ntifs
//
// The following are globally used definitions for an LBN and a VBN
//
typedef ULONG LBN; typedef LBN *PLBN;
typedef ULONG VBN; typedef VBN *PVBN;
// end_ntifs
//
// The following routine is called during phase 1 initialization to allow
// us to create the pool of file system threads and the associated
// synchronization resources.
//
NTKERNELAPI BOOLEAN FsRtlInitSystem ( );
// begin_ntifs
//
// Every file system that uses the cache manager must have FsContext
// of the file object point to a common fcb header structure.
// end_ntifs
// Either the normal or advanced FsRtl Header.
// begin_ntifs
//
typedef enum _FAST_IO_POSSIBLE { FastIoIsNotPossible = 0, FastIoIsPossible, FastIoIsQuestionable } FAST_IO_POSSIBLE;
// end_ntifs
// Changes to this structure will affect FSRTL_ADVANCED_FCB_HEADER.
// begin_ntifs
typedef struct _FSRTL_COMMON_FCB_HEADER {
CSHORT NodeTypeCode; CSHORT NodeByteSize;
//
// General flags available to FsRtl.
//
UCHAR Flags;
//
// Indicates if fast I/O is possible or if we should be calling
// the check for fast I/O routine which is found via the driver
// object.
//
UCHAR IsFastIoPossible; // really type FAST_IO_POSSIBLE
//
// Second Flags Field
//
UCHAR Flags2;
//
// The following reserved field should always be 0
//
UCHAR Reserved;
PERESOURCE Resource;
PERESOURCE PagingIoResource;
LARGE_INTEGER AllocationSize; LARGE_INTEGER FileSize; LARGE_INTEGER ValidDataLength;
} FSRTL_COMMON_FCB_HEADER; typedef FSRTL_COMMON_FCB_HEADER *PFSRTL_COMMON_FCB_HEADER;
//
// This Fcb header is used for files which support caching
// of compressed data, and related new support.
//
// We start out by prefixing this structure with the normal
// FsRtl header from above, which we have to do two different
// ways for c++ or c.
//
#ifdef __cplusplus
typedef struct _FSRTL_ADVANCED_FCB_HEADER:FSRTL_COMMON_FCB_HEADER { #else // __cplusplus
typedef struct _FSRTL_ADVANCED_FCB_HEADER {
//
// Put in the standard FsRtl header fields
//
FSRTL_COMMON_FCB_HEADER ;
#endif // __cplusplus
//
// The following two fields are supported only if
// Flags2 contains FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS
//
//
// This is a pointer to a Fast Mutex which may be used to
// properly synchronize access to the FsRtl header. The
// Fast Mutex must be nonpaged.
//
PFAST_MUTEX FastMutex;
//
// This is a pointer to a list of context structures belonging to
// filesystem filter drivers that are linked above the filesystem.
// Each structure is headed by FSRTL_FILTER_CONTEXT.
//
LIST_ENTRY FilterContexts;
} FSRTL_ADVANCED_FCB_HEADER; typedef FSRTL_ADVANCED_FCB_HEADER *PFSRTL_ADVANCED_FCB_HEADER;
//
// Define FsRtl common header flags
//
#define FSRTL_FLAG_FILE_MODIFIED (0x01)
#define FSRTL_FLAG_FILE_LENGTH_CHANGED (0x02)
#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES (0x04)
//
// Following flags determine how the modified page writer should
// acquire the file. These flags can't change while either resource
// is acquired. If neither of these flags is set then the
// modified/mapped page writer will attempt to acquire the paging io
// resource shared.
//
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX (0x08)
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH (0x10)
//
// This flag will be set by the Cache Manager if a view is mapped
// to a file.
//
#define FSRTL_FLAG_USER_MAPPED_FILE (0x20)
// This flag indicates that the file system is using the
// FSRTL_ADVANCED_FCB_HEADER structure instead of the FSRTL_COMMON_FCB_HEADER
// structure.
//
#define FSRTL_FLAG_ADVANCED_HEADER (0x40)
// This flag determines whether there currently is an Eof advance
// in progress. All such advances must be serialized.
//
#define FSRTL_FLAG_EOF_ADVANCE_ACTIVE (0x80)
//
// Flag values for Flags2
//
// All unused bits are reserved and should NOT be modified.
//
//
// If this flag is set, the Cache Manager will allow modified writing
// in spite of the value of FsContext2.
//
#define FSRTL_FLAG2_DO_MODIFIED_WRITE (0x01)
//
// If this flag is set, the additional fields FilterContexts and FastMutex
// are supported in FSRTL_COMMON_HEADER, and can be used to associate
// context for filesystem filters with streams.
//
#define FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS (0x02)
//
// If this flag is set, the cache manager will flush and purge the cache map when
// a user first maps a file
//
#define FSRTL_FLAG2_PURGE_WHEN_MAPPED (0x04)
//
// The following constants are used to block top level Irp processing when
// (in either the fast io or cc case) file system resources have been
// acquired above the file system, or we are in an Fsp thread.
//
#define FSRTL_FSP_TOP_LEVEL_IRP 0x01
#define FSRTL_CACHE_TOP_LEVEL_IRP 0x02
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP 0x03
#define FSRTL_FAST_IO_TOP_LEVEL_IRP 0x04
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG 0x04
//
// The following structure is used to synchronize Eof extends.
//
typedef struct _EOF_WAIT_BLOCK {
LIST_ENTRY EofWaitLinks; KEVENT Event;
} EOF_WAIT_BLOCK;
typedef EOF_WAIT_BLOCK *PEOF_WAIT_BLOCK;
// begin_ntosp
//
// Normal uncompressed Copy and Mdl Apis
//
NTKERNELAPI BOOLEAN FsRtlCopyRead ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
NTKERNELAPI BOOLEAN FsRtlCopyWrite ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
// end_ntifs
NTKERNELAPI BOOLEAN FsRtlMdlRead ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus );
BOOLEAN FsRtlMdlReadComplete ( IN PFILE_OBJECT FileObject, IN PMDL MdlChain );
// end_ntosp
NTKERNELAPI BOOLEAN FsRtlPrepareMdlWrite ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus );
BOOLEAN FsRtlMdlWriteComplete ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain );
// begin_ntifs
NTKERNELAPI BOOLEAN FsRtlMdlReadDev ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
NTKERNELAPI BOOLEAN FsRtlMdlReadCompleteDev ( IN PFILE_OBJECT FileObject, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject );
NTKERNELAPI BOOLEAN FsRtlPrepareMdlWriteDev ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject );
NTKERNELAPI BOOLEAN FsRtlMdlWriteCompleteDev ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject );
//
// In Irps, compressed reads and writes are designated by the
// subfunction IRP_MN_COMPRESSED must be set and the Compressed
// Data Info buffer must be described by the following structure
// pointed to by Irp->Tail.Overlay.AuxiliaryBuffer.
//
typedef struct _FSRTL_AUXILIARY_BUFFER {
//
// Buffer description with length.
//
PVOID Buffer; ULONG Length;
//
// Flags
//
ULONG Flags;
//
// Pointer to optional Mdl mapping buffer for file system use
//
PMDL Mdl;
} FSRTL_AUXILIARY_BUFFER; typedef FSRTL_AUXILIARY_BUFFER *PFSRTL_AUXILIARY_BUFFER;
//
// If this flag is set, the auxiliary buffer structure is
// deallocated on Irp completion. The caller has the
// option in this case of appending this structure to the
// structure being described, causing it all to be
// deallocated at once. If this flag is clear, no deallocate
// occurs.
//
#define FSRTL_AUXILIARY_FLAG_DEALLOCATE 0x00000001
// end_ntifs
//
// The following routines are intended to be called by Mm to avoid deadlocks.
// They prerequire file system resources before acquire Mm resources.
//
//
// This macro is called once when the ModifiedPageWriter is started.
//
#define FsRtlSetTopLevelIrpForModWriter() { \
IoSetTopLevelIrp((PIRP)FSRTL_MOD_WRITE_TOP_LEVEL_IRP); \ }
NTKERNELAPI BOOLEAN FsRtlAcquireFileForModWrite ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER EndingOffset, OUT PERESOURCE *ResourceToRelease );
NTKERNELAPI NTSTATUS FsRtlAcquireFileForModWriteEx ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER EndingOffset, OUT PERESOURCE *ResourceToRelease );
NTKERNELAPI VOID FsRtlReleaseFileForModWrite ( IN PFILE_OBJECT FileObject, IN PERESOURCE ResourceToRelease );
NTKERNELAPI VOID FsRtlAcquireFileForCcFlush ( IN PFILE_OBJECT FileObject );
NTKERNELAPI NTSTATUS FsRtlAcquireFileForCcFlushEx ( IN PFILE_OBJECT FileObject );
NTKERNELAPI VOID FsRtlReleaseFileForCcFlush ( IN PFILE_OBJECT FileObject );
NTKERNELAPI NTSTATUS FsRtlAcquireToCreateMappedSection ( IN PFILE_OBJECT FileObject, IN ULONG SectionPageProtection ); NTKERNELAPI NTSTATUS FsRtlAcquireFileExclusiveCommon ( IN PFILE_OBJECT FileObject, IN FS_FILTER_SECTION_SYNC_TYPE SyncType, IN ULONG SectionPageProtection );
// begin_ntifs
//
// The following two routines are called from NtCreateSection to avoid
// deadlocks with the file systems.
//
NTKERNELAPI VOID FsRtlAcquireFileExclusive ( IN PFILE_OBJECT FileObject );
NTKERNELAPI VOID FsRtlReleaseFile ( IN PFILE_OBJECT FileObject );
//
// These routines provide a simple interface for the common operations
// of query/set file size.
//
NTSTATUS FsRtlGetFileSize( IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize );
// end_ntifs
NTSTATUS FsRtlSetFileSize( IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize );
// begin_ntddk begin_ntifs
//
// Determine if there is a complete device failure on an error.
//
NTKERNELAPI BOOLEAN FsRtlIsTotalDeviceFailure( IN NTSTATUS Status );
// end_ntddk
//
// Byte range file lock routines, implemented in FileLock.c
//
// The file lock info record is used to return enumerated information
// about a file lock
//
typedef struct _FILE_LOCK_INFO {
//
// A description of the current locked range, and if the lock
// is exclusive or shared
//
LARGE_INTEGER StartingByte; LARGE_INTEGER Length; BOOLEAN ExclusiveLock;
//
// The following fields describe the owner of the lock.
//
ULONG Key; PFILE_OBJECT FileObject; PVOID ProcessId;
//
// The following field is used internally by FsRtl
//
LARGE_INTEGER EndingByte;
} FILE_LOCK_INFO; typedef FILE_LOCK_INFO *PFILE_LOCK_INFO;
//
// The following two procedure prototypes are used by the caller of the
// file lock package to supply an alternate routine to call when
// completing an IRP and when unlocking a byte range. Note that the only
// utility to us this interface is currently the redirector, all other file
// system will probably let the IRP complete normally with IoCompleteRequest.
// The user supplied routine returns any value other than success then the
// lock package will remove any lock that we just inserted.
//
typedef NTSTATUS (*PCOMPLETE_LOCK_IRP_ROUTINE) ( IN PVOID Context, IN PIRP Irp );
typedef VOID (*PUNLOCK_ROUTINE) ( IN PVOID Context, IN PFILE_LOCK_INFO FileLockInfo );
//
// A FILE_LOCK is an opaque structure but we need to declare the size of
// it here so that users can allocate space for one.
//
typedef struct _FILE_LOCK {
//
// The optional procedure to call to complete a request
//
PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine;
//
// The optional procedure to call when unlocking a byte range
//
PUNLOCK_ROUTINE UnlockRoutine;
//
// FastIoIsQuestionable is set to true whenever the filesystem require
// additional checking about whether the fast path can be taken. As an
// example Ntfs requires checking for disk space before the writes can
// occur.
//
BOOLEAN FastIoIsQuestionable; BOOLEAN SpareC[3];
//
// FsRtl lock information
//
PVOID LockInformation;
//
// Contains continuation information for FsRtlGetNextFileLock
//
FILE_LOCK_INFO LastReturnedLockInfo; PVOID LastReturnedLock;
} FILE_LOCK; typedef FILE_LOCK *PFILE_LOCK;
PFILE_LOCK FsRtlAllocateFileLock ( IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL );
VOID FsRtlFreeFileLock ( IN PFILE_LOCK FileLock );
NTKERNELAPI VOID FsRtlInitializeFileLock ( IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL );
NTKERNELAPI VOID FsRtlUninitializeFileLock ( IN PFILE_LOCK FileLock );
NTKERNELAPI NTSTATUS FsRtlProcessFileLock ( IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL );
NTKERNELAPI BOOLEAN FsRtlCheckLockForReadAccess ( IN PFILE_LOCK FileLock, IN PIRP Irp );
NTKERNELAPI BOOLEAN FsRtlCheckLockForWriteAccess ( IN PFILE_LOCK FileLock, IN PIRP Irp );
NTKERNELAPI BOOLEAN FsRtlFastCheckLockForRead ( IN PFILE_LOCK FileLock, IN PLARGE_INTEGER StartingByte, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID ProcessId );
NTKERNELAPI BOOLEAN FsRtlFastCheckLockForWrite ( IN PFILE_LOCK FileLock, IN PLARGE_INTEGER StartingByte, IN PLARGE_INTEGER Length, IN ULONG Key, IN PVOID FileObject, IN PVOID ProcessId );
NTKERNELAPI PFILE_LOCK_INFO FsRtlGetNextFileLock ( IN PFILE_LOCK FileLock, IN BOOLEAN Restart );
NTKERNELAPI NTSTATUS FsRtlFastUnlockSingle ( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN LARGE_INTEGER UNALIGNED *FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS ProcessId, IN ULONG Key, IN PVOID Context OPTIONAL, IN BOOLEAN AlreadySynchronized );
NTKERNELAPI NTSTATUS FsRtlFastUnlockAll ( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS ProcessId, IN PVOID Context OPTIONAL );
NTKERNELAPI NTSTATUS FsRtlFastUnlockAllByKey ( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS ProcessId, IN ULONG Key, IN PVOID Context OPTIONAL );
NTKERNELAPI BOOLEAN FsRtlPrivateLock ( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS ProcessId, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK Iosb, IN PIRP Irp, IN PVOID Context, IN BOOLEAN AlreadySynchronized );
//
// BOOLEAN
// FsRtlFastLock (
// IN PFILE_LOCK FileLock,
// IN PFILE_OBJECT FileObject,
// IN PLARGE_INTEGER FileOffset,
// IN PLARGE_INTEGER Length,
// IN PEPROCESS ProcessId,
// IN ULONG Key,
// IN BOOLEAN FailImmediately,
// IN BOOLEAN ExclusiveLock,
// OUT PIO_STATUS_BLOCK Iosb,
// IN PVOID Context OPTIONAL,
// IN BOOLEAN AlreadySynchronized
// );
//
#define FsRtlFastLock(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11) ( \
FsRtlPrivateLock( A1, /* FileLock */ \ A2, /* FileObject */ \ A3, /* FileOffset */ \ A4, /* Length */ \ A5, /* ProcessId */ \ A6, /* Key */ \ A7, /* FailImmediately */ \ A8, /* ExclusiveLock */ \ A9, /* Iosb */ \ NULL, /* Irp */ \ A10, /* Context */ \ A11 /* AlreadySynchronized */ ) \ )
//
// BOOLEAN
// FsRtlAreThereCurrentFileLocks (
// IN PFILE_LOCK FileLock
// );
//
#define FsRtlAreThereCurrentFileLocks(FL) ( \
((FL)->FastIoIsQuestionable))
//
// Filesystem property tunneling, implemented in tunnel.c
//
//
// Tunnel cache structure
//
typedef struct {
//
// Mutex for cache manipulation
//
FAST_MUTEX Mutex;
//
// Splay Tree of tunneled information keyed by
// DirKey ## Name
//
PRTL_SPLAY_LINKS Cache;
//
// Timer queue used to age entries out of the main cache
//
LIST_ENTRY TimerQueue;
//
// Keep track of the number of entries in the cache to prevent
// excessive use of memory
//
USHORT NumEntries;
} TUNNEL, *PTUNNEL;
NTKERNELAPI VOID FsRtlInitializeTunnelCache ( IN TUNNEL *Cache);
NTKERNELAPI VOID FsRtlAddToTunnelCache ( IN TUNNEL *Cache, IN ULONGLONG DirectoryKey, IN UNICODE_STRING *ShortName, IN UNICODE_STRING *LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN VOID *Data);
NTKERNELAPI BOOLEAN FsRtlFindInTunnelCache ( IN TUNNEL *Cache, IN ULONGLONG DirectoryKey, IN UNICODE_STRING *Name, OUT UNICODE_STRING *ShortName, OUT UNICODE_STRING *LongName, IN OUT ULONG *DataLength, OUT VOID *Data);
NTKERNELAPI VOID FsRtlDeleteKeyFromTunnelCache ( IN TUNNEL *Cache, IN ULONGLONG DirectoryKey);
NTKERNELAPI VOID FsRtlDeleteTunnelCache ( IN TUNNEL *Cache);
//
// Dbcs name support routines, implemented in DbcsName.c
//
//
// The following enumerated type is used to denote the result of name
// comparisons
//
typedef enum _FSRTL_COMPARISON_RESULT { LessThan = -1, EqualTo = 0, GreaterThan = 1 } FSRTL_COMPARISON_RESULT;
#ifdef NLS_MB_CODE_PAGE_TAG
#undef NLS_MB_CODE_PAGE_TAG
#endif // NLS_MB_CODE_PAGE_TAG
// end_ntifs
#if defined(_NTIFS_) || defined(_NTDRIVER_)
// begin_ntifs
#define LEGAL_ANSI_CHARACTER_ARRAY (*FsRtlLegalAnsiCharacterArray) // ntosp
#define NLS_MB_CODE_PAGE_TAG (*NlsMbOemCodePageTag)
#define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo) // ntosp
// end_ntifs
#else
#define LEGAL_ANSI_CHARACTER_ARRAY FsRtlLegalAnsiCharacterArray
#define NLS_MB_CODE_PAGE_TAG NlsMbOemCodePageTag
#define NLS_OEM_LEAD_BYTE_INFO NlsOemLeadByteInfo
#endif
// begin_ntifs begin_ntosp
extern UCHAR const* const LEGAL_ANSI_CHARACTER_ARRAY; extern PUSHORT NLS_OEM_LEAD_BYTE_INFO; // Lead byte info. for ACP
//
// These following bit values are set in the FsRtlLegalDbcsCharacterArray
//
#define FSRTL_FAT_LEGAL 0x01
#define FSRTL_HPFS_LEGAL 0x02
#define FSRTL_NTFS_LEGAL 0x04
#define FSRTL_WILD_CHARACTER 0x08
#define FSRTL_OLE_LEGAL 0x10
#define FSRTL_NTFS_STREAM_LEGAL (FSRTL_NTFS_LEGAL | FSRTL_OLE_LEGAL)
//
// The following macro is used to determine if an Ansi character is wild.
//
#define FsRtlIsAnsiCharacterWild(C) ( \
FsRtlTestAnsiCharacter((C), FALSE, FALSE, FSRTL_WILD_CHARACTER) \ )
//
// The following macro is used to determine if an Ansi character is Fat legal.
//
#define FsRtlIsAnsiCharacterLegalFat(C,WILD_OK) ( \
FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_FAT_LEGAL) \ )
//
// The following macro is used to determine if an Ansi character is Hpfs legal.
//
#define FsRtlIsAnsiCharacterLegalHpfs(C,WILD_OK) ( \
FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_HPFS_LEGAL) \ )
//
// The following macro is used to determine if an Ansi character is Ntfs legal.
//
#define FsRtlIsAnsiCharacterLegalNtfs(C,WILD_OK) ( \
FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_LEGAL) \ )
//
// The following macro is used to determine if an Ansi character is
// legal in an Ntfs stream name
//
#define FsRtlIsAnsiCharacterLegalNtfsStream(C,WILD_OK) ( \
FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_STREAM_LEGAL) \ )
//
// The following macro is used to determine if an Ansi character is legal,
// according to the caller's specification.
//
#define FsRtlIsAnsiCharacterLegal(C,FLAGS) ( \
FsRtlTestAnsiCharacter((C), TRUE, FALSE, (FLAGS)) \ )
//
// The following macro is used to test attributes of an Ansi character,
// according to the caller's specified flags.
//
#define FsRtlTestAnsiCharacter(C, DEFAULT_RET, WILD_OK, FLAGS) ( \
((SCHAR)(C) < 0) ? DEFAULT_RET : \ FlagOn( LEGAL_ANSI_CHARACTER_ARRAY[(C)], \ (FLAGS) | \ ((WILD_OK) ? FSRTL_WILD_CHARACTER : 0) ) \ )
//
// The following two macros use global data defined in ntos\rtl\nlsdata.c
//
// BOOLEAN
// FsRtlIsLeadDbcsCharacter (
// IN UCHAR DbcsCharacter
// );
//
// /*++
//
// Routine Description:
//
// This routine takes the first bytes of a Dbcs character and
// returns whether it is a lead byte in the system code page.
//
// Arguments:
//
// DbcsCharacter - Supplies the input character being examined
//
// Return Value:
//
// BOOLEAN - TRUE if the input character is a dbcs lead and
// FALSE otherwise
//
// --*/
//
//
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \
(BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \ (NLS_MB_CODE_PAGE_TAG && \ (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \ )
NTKERNELAPI VOID FsRtlDissectDbcs ( IN ANSI_STRING InputName, OUT PANSI_STRING FirstPart, OUT PANSI_STRING RemainingPart );
NTKERNELAPI BOOLEAN FsRtlDoesDbcsContainWildCards ( IN PANSI_STRING Name );
NTKERNELAPI BOOLEAN FsRtlIsDbcsInExpression ( IN PANSI_STRING Expression, IN PANSI_STRING Name );
NTKERNELAPI BOOLEAN FsRtlIsFatDbcsLegal ( IN ANSI_STRING DbcsName, IN BOOLEAN WildCardsPermissible, IN BOOLEAN PathNamePermissible, IN BOOLEAN LeadingBackslashPermissible );
// end_ntosp
NTKERNELAPI BOOLEAN FsRtlIsHpfsDbcsLegal ( IN ANSI_STRING DbcsName, IN BOOLEAN WildCardsPermissible, IN BOOLEAN PathNamePermissible, IN BOOLEAN LeadingBackslashPermissible );
//
// Exception filter routines, implemented in Filter.c
//
NTKERNELAPI NTSTATUS FsRtlNormalizeNtstatus ( IN NTSTATUS Exception, IN NTSTATUS GenericException );
NTKERNELAPI BOOLEAN FsRtlIsNtstatusExpected ( IN NTSTATUS Exception );
//
// The following procedures are used to allocate executive pool and raise
// insufficient resource status if pool isn't currently available.
//
#define FsRtlAllocatePoolWithTag(PoolType, NumberOfBytes, Tag) \
ExAllocatePoolWithTag((POOL_TYPE)((PoolType) | POOL_RAISE_IF_ALLOCATION_FAILURE), \ NumberOfBytes, \ Tag)
#define FsRtlAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, Tag) \
ExAllocatePoolWithQuotaTag((POOL_TYPE)((PoolType) | POOL_RAISE_IF_ALLOCATION_FAILURE), \ NumberOfBytes, \ Tag)
//
// The following function allocates a resource from the FsRtl pool.
//
NTKERNELAPI PERESOURCE FsRtlAllocateResource ( );
//
// Large Integer Mapped Control Blocks routines, implemented in LargeMcb.c
//
// Originally this structure was truly opaque and code outside largemcb was
// never allowed to examine or alter the structures. However, for performance
// reasons we want to allow ntfs the ability to quickly truncate down the
// mcb without the overhead of an actual call to largemcb.c. So to do that we
// need to export the structure. This structure is not exact. The Mapping field
// is declared here as a pvoid but largemcb.c it is a pointer to mapping pairs.
//
typedef struct _LARGE_MCB { PFAST_MUTEX FastMutex; ULONG MaximumPairCount; ULONG PairCount; POOL_TYPE PoolType; PVOID Mapping; } LARGE_MCB; typedef LARGE_MCB *PLARGE_MCB;
NTKERNELAPI VOID FsRtlInitializeLargeMcb ( IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType );
NTKERNELAPI VOID FsRtlUninitializeLargeMcb ( IN PLARGE_MCB Mcb );
NTKERNELAPI VOID FsRtlResetLargeMcb ( IN PLARGE_MCB Mcb, IN BOOLEAN SelfSynchronized );
NTKERNELAPI VOID FsRtlTruncateLargeMcb ( IN PLARGE_MCB Mcb, IN LONGLONG Vbn );
NTKERNELAPI BOOLEAN FsRtlAddLargeMcbEntry ( IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount );
NTKERNELAPI VOID FsRtlRemoveLargeMcbEntry ( IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount );
NTKERNELAPI BOOLEAN FsRtlLookupLargeMcbEntry ( IN PLARGE_MCB Mcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, OUT PLONGLONG StartingLbn OPTIONAL, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL );
NTKERNELAPI BOOLEAN FsRtlLookupLastLargeMcbEntry ( IN PLARGE_MCB Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn );
NTKERNELAPI BOOLEAN FsRtlLookupLastLargeMcbEntryAndIndex ( IN PLARGE_MCB OpaqueMcb, OUT PLONGLONG LargeVbn, OUT PLONGLONG LargeLbn, OUT PULONG Index );
NTKERNELAPI ULONG FsRtlNumberOfRunsInLargeMcb ( IN PLARGE_MCB Mcb );
NTKERNELAPI BOOLEAN FsRtlGetNextLargeMcbEntry ( IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount );
NTKERNELAPI BOOLEAN FsRtlSplitLargeMcb ( IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Amount );
//
// Mapped Control Blocks routines, implemented in Mcb.c
//
// An MCB is an opaque structure but we need to declare the size of
// it here so that users can allocate space for one. Consequently the
// size computation here must be updated by hand if the MCB changes.
//
typedef struct _MCB { LARGE_MCB DummyFieldThatSizesThisStructureCorrectly; } MCB; typedef MCB *PMCB;
NTKERNELAPI VOID FsRtlInitializeMcb ( IN PMCB Mcb, IN POOL_TYPE PoolType );
NTKERNELAPI VOID FsRtlUninitializeMcb ( IN PMCB Mcb );
NTKERNELAPI VOID FsRtlTruncateMcb ( IN PMCB Mcb, IN VBN Vbn );
NTKERNELAPI BOOLEAN FsRtlAddMcbEntry ( IN PMCB Mcb, IN VBN Vbn, IN LBN Lbn, IN ULONG SectorCount );
NTKERNELAPI VOID FsRtlRemoveMcbEntry ( IN PMCB Mcb, IN VBN Vbn, IN ULONG SectorCount );
NTKERNELAPI BOOLEAN FsRtlLookupMcbEntry ( IN PMCB Mcb, IN VBN Vbn, OUT PLBN Lbn, OUT PULONG SectorCount OPTIONAL, OUT PULONG Index );
NTKERNELAPI BOOLEAN FsRtlLookupLastMcbEntry ( IN PMCB Mcb, OUT PVBN Vbn, OUT PLBN Lbn );
NTKERNELAPI ULONG FsRtlNumberOfRunsInMcb ( IN PMCB Mcb );
NTKERNELAPI BOOLEAN FsRtlGetNextMcbEntry ( IN PMCB Mcb, IN ULONG RunIndex, OUT PVBN Vbn, OUT PLBN Lbn, OUT PULONG SectorCount );
//
// Fault Tolerance routines, implemented in FaultTol.c
//
// The routines in this package implement routines that help file
// systems interact with the FT device drivers.
//
NTKERNELAPI NTSTATUS FsRtlBalanceReads ( IN PDEVICE_OBJECT TargetDevice );
// end_ntifs
NTKERNELAPI NTSTATUS FsRtlSyncVolumes ( IN PDEVICE_OBJECT TargetDevice, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PLARGE_INTEGER ByteCount );
// begin_ntifs
//
// Oplock routines, implemented in Oplock.c
//
// An OPLOCK is an opaque structure, we declare it as a PVOID and
// allocate the actual memory only when needed.
//
typedef PVOID OPLOCK, *POPLOCK;
typedef VOID (*POPLOCK_WAIT_COMPLETE_ROUTINE) ( IN PVOID Context, IN PIRP Irp );
typedef VOID (*POPLOCK_FS_PREPOST_IRP) ( IN PVOID Context, IN PIRP Irp );
NTKERNELAPI VOID FsRtlInitializeOplock ( IN OUT POPLOCK Oplock );
NTKERNELAPI VOID FsRtlUninitializeOplock ( IN OUT POPLOCK Oplock );
NTKERNELAPI NTSTATUS FsRtlOplockFsctrl ( IN POPLOCK Oplock, IN PIRP Irp, IN ULONG OpenCount );
NTKERNELAPI NTSTATUS FsRtlCheckOplock ( IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL );
NTKERNELAPI BOOLEAN FsRtlOplockIsFastIoPossible ( IN POPLOCK Oplock );
NTKERNELAPI BOOLEAN FsRtlCurrentBatchOplock ( IN POPLOCK Oplock );
//
// Volume lock/unlock notification routines, implemented in PnP.c
//
// These routines provide PnP volume lock notification support
// for all filesystems.
//
#define FSRTL_VOLUME_DISMOUNT 1
#define FSRTL_VOLUME_DISMOUNT_FAILED 2
#define FSRTL_VOLUME_LOCK 3
#define FSRTL_VOLUME_LOCK_FAILED 4
#define FSRTL_VOLUME_UNLOCK 5
#define FSRTL_VOLUME_MOUNT 6
NTKERNELAPI NTSTATUS FsRtlNotifyVolumeEvent ( IN PFILE_OBJECT FileObject, IN ULONG EventCode );
//
// Notify Change routines, implemented in Notify.c
//
// These routines provide Notify Change support for all filesystems.
// Any of the 'Full' notify routines will support returning the
// change information into the user's buffer.
//
typedef PVOID PNOTIFY_SYNC;
typedef BOOLEAN (*PCHECK_FOR_TRAVERSE_ACCESS) ( IN PVOID NotifyContext, IN PVOID TargetContext, IN PSECURITY_SUBJECT_CONTEXT SubjectContext );
typedef BOOLEAN (*PFILTER_REPORT_CHANGE) ( IN PVOID NotifyContext, IN PVOID FilterContext );
NTKERNELAPI VOID FsRtlNotifyInitializeSync ( IN PNOTIFY_SYNC *NotifySync );
NTKERNELAPI VOID FsRtlNotifyUninitializeSync ( IN PNOTIFY_SYNC *NotifySync );
// end_ntifs
NTKERNELAPI VOID FsRtlNotifyChangeDirectory ( IN PNOTIFY_SYNC NotifySync, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN PLIST_ENTRY NotifyList, IN BOOLEAN WatchTree, IN ULONG CompletionFilter, IN PIRP NotifyIrp );
// begin_ntifs
NTKERNELAPI VOID FsRtlNotifyFullChangeDirectory ( IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL );
NTKERNELAPI VOID FsRtlNotifyFilterChangeDirectory ( IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL, IN PFILTER_REPORT_CHANGE FilterCallback OPTIONAL );
NTKERNELAPI VOID FsRtlNotifyFilterReportChange ( IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext, IN PVOID FilterContext );
// end_ntifs
NTKERNELAPI VOID FsRtlNotifyReportChange ( IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN PSTRING TargetName, IN ULONG FilterMatch );
// begin_ntifs
NTKERNELAPI VOID FsRtlNotifyFullReportChange ( IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext );
NTKERNELAPI VOID FsRtlNotifyCleanup ( IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext );
//
// Unicode Name support routines, implemented in Name.c
//
// The routines here are used to manipulate unicode names
//
//
// The following macro is used to determine if a character is wild.
//
#define FsRtlIsUnicodeCharacterWild(C) ( \
(((C) >= 0x40) ? FALSE : FlagOn( LEGAL_ANSI_CHARACTER_ARRAY[(C)], \ FSRTL_WILD_CHARACTER ) ) \ )
NTKERNELAPI VOID FsRtlDissectName ( IN UNICODE_STRING Path, OUT PUNICODE_STRING FirstName, OUT PUNICODE_STRING RemainingName );
NTKERNELAPI BOOLEAN FsRtlDoesNameContainWildCards ( IN PUNICODE_STRING Name );
NTKERNELAPI BOOLEAN FsRtlAreNamesEqual ( PCUNICODE_STRING ConstantNameA, PCUNICODE_STRING ConstantNameB, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL );
NTKERNELAPI BOOLEAN FsRtlIsNameInExpression ( IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCH UpcaseTable OPTIONAL );
//
// Stack Overflow support routine, implemented in StackOvf.c
//
typedef VOID (*PFSRTL_STACK_OVERFLOW_ROUTINE) ( IN PVOID Context, IN PKEVENT Event );
NTKERNELAPI VOID FsRtlPostStackOverflow ( IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine );
NTKERNELAPI VOID FsRtlPostPagingFileStackOverflow ( IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine );
//
// UNC Provider support
//
NTKERNELAPI NTSTATUS FsRtlRegisterUncProvider( IN OUT PHANDLE MupHandle, IN PUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported );
NTKERNELAPI VOID FsRtlDeregisterUncProvider( IN HANDLE Handle ); // end_ntifs
// begin_ntifs
//
// File System Filter PerStream Context Support
//
//
// Filesystem filter drivers use these APIs to associate context
// with open streams (for filesystems that support this).
//
//
// OwnerId should uniquely identify a particular filter driver
// (e.g. the address of the driver's device object).
// InstanceId can be used to distinguish distinct contexts associated
// by a filter driver with a single stream (e.g. the address of the
// PerStream Context structure).
//
//
// This structure needs to be embedded within the users context that
// they want to associate with a given stream
//
typedef struct _FSRTL_PER_STREAM_CONTEXT { //
// This is linked into the StreamContext list inside the
// FSRTL_ADVANCED_FCB_HEADER structure.
//
LIST_ENTRY Links;
//
// A Unique ID for this filter (ex: address of Driver Object, Device
// Object, or Device Extension)
//
PVOID OwnerId;
//
// An optional ID to differentiate different contexts for the same
// filter.
//
PVOID InstanceId;
//
// A callback routine which is called by the underlying file system
// when the stream is being torn down. When this routine is called
// the given context has already been removed from the context linked
// list. The callback routine cannot recursively call down into the
// filesystem or acquire any of their resources which they might hold
// when calling the filesystem outside of the callback. This must
// be defined.
//
PFREE_FUNCTION FreeCallback;
} FSRTL_PER_STREAM_CONTEXT, *PFSRTL_PER_STREAM_CONTEXT;
//
// This will initialize the given FSRTL_PER_STREAM_CONTEXT structure. This
// should be used before calling "FsRtlInsertPerStreamContext".
//
#define FsRtlInitPerStreamContext( _fc, _owner, _inst, _cb) \
((_fc)->OwnerId = (_owner), \ (_fc)->InstanceId = (_inst), \ (_fc)->FreeCallback = (_cb))
//
// Given a FileObject this will return the StreamContext pointer that
// needs to be passed into the other FsRtl PerStream Context routines.
//
#define FsRtlGetPerStreamContextPointer(_fo) \
((PFSRTL_ADVANCED_FCB_HEADER)((_fo)->FsContext))
//
// This will test to see if PerStream contexts are supported for the given
// FileObject
//
#define FsRtlSupportsPerStreamContexts(_fo) \
((NULL != FsRtlGetPerStreamContextPointer(_fo)) && \ FlagOn(FsRtlGetPerStreamContextPointer(_fo)->Flags2, \ FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS))
//
// Associate the context at Ptr with the given stream. The Ptr structure
// should be filled in by the caller before calling this routine (see
// FsRtlInitPerStreamContext). If the underlying filesystem does not support
// filter contexts, STATUS_INVALID_DEVICE_REQUEST will be returned.
//
NTKERNELAPI NTSTATUS FsRtlInsertPerStreamContext ( IN PFSRTL_ADVANCED_FCB_HEADER PerStreamContext, IN PFSRTL_PER_STREAM_CONTEXT Ptr );
//
// Lookup a filter context associated with the stream specified. The first
// context matching OwnerId (and InstanceId, if present) is returned. By not
// specifying InstanceId, a filter driver can search for any context that it
// has previously associated with a stream. If no matching context is found,
// NULL is returned. If the file system does not support filter contexts,
// NULL is returned.
//
NTKERNELAPI PFSRTL_PER_STREAM_CONTEXT FsRtlLookupPerStreamContextInternal ( IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL );
#define FsRtlLookupPerStreamContext(_sc, _oid, _iid) \
(((NULL != (_sc)) && \ FlagOn((_sc)->Flags2,FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS) && \ !IsListEmpty(&(_sc)->FilterContexts)) ? \ FsRtlLookupPerStreamContextInternal((_sc), (_oid), (_iid)) : \ NULL)
//
// Normally, contexts should be deleted when the file system notifies the
// filter that the stream is being closed. There are cases when a filter
// may want to remove all existing contexts for a specific volume. This
// routine should be called at those times. This routine should NOT be
// called for the following cases:
// - Inside your FreeCallback handler - The underlying file system has
// already removed it from the linked list).
// - Inside your IRP_CLOSE handler - If you do this then you will not
// be notified when the stream is torn down.
//
// This functions identically to FsRtlLookupPerStreamContext, except that the
// returned context has been removed from the list.
//
NTKERNELAPI PFSRTL_PER_STREAM_CONTEXT FsRtlRemovePerStreamContext ( IN PFSRTL_ADVANCED_FCB_HEADER StreamContext, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL );
//
// APIs for file systems to use for initializing and cleaning up
// the Advaned FCB Header fields for PerStreamContext support
//
//
// This will properly initialize the advanced header so that it can be
// used with PerStream contexts.
// Note: A fast mutex must be placed in an advanced header. It is the
// caller's responsibility to properly create and initialize this
// mutex before calling this macro. The mutex field is only set
// if a non-NULL value is passed in.
//
#define FsRtlSetupAdvancedHeader( _advhdr, _fmutx ) \
{ \ SetFlag( (_advhdr)->Flags, FSRTL_FLAG_ADVANCED_HEADER ); \ SetFlag( (_advhdr)->Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS ); \ InitializeListHead( &(_advhdr)->FilterContexts ); \ if ((_fmutx) != NULL) { \ (_advhdr)->FastMutex = (_fmutx); \ } \ }
//
// File systems call this API to free any filter contexts still associated
// with an FSRTL_COMMON_FCB_HEADER that they are tearing down.
// The FreeCallback routine for each filter context will be called.
//
NTKERNELAPI VOID FsRtlTeardownPerStreamContexts ( IN PFSRTL_ADVANCED_FCB_HEADER AdvancedHeader );
// end_ntifs
//
// File System Filter PerFileObject Context Support
//
//
// Filesystem filter drivers use these APIs to associate context
// with individual open files. For now these are only supported on file
// objects with a FileObject extension which are only created by using
// IoCreateFileSpecifyDeviceObjectHint.
//
//
// OwnerId should uniquely identify a particular filter driver
// (e.g. the address of the driver's device object).
// InstanceId can be used to distinguish distinct contexts associated
// by a filter driver with a single stream (e.g. the address of the
// fileobject).
//
//
// This structure needs to be embedded within the users context that
// they want to associate with a given stream
//
typedef struct _FSRTL_PER_FILEOBJECT_CONTEXT { //
// This is linked into the File Object
//
LIST_ENTRY Links;
//
// A Unique ID for this filter (ex: address of Driver Object, Device
// Object, or Device Extension)
//
PVOID OwnerId;
//
// An optional ID to differentiate different contexts for the same
// filter.
//
PVOID InstanceId;
} FSRTL_PER_FILEOBJECT_CONTEXT, *PFSRTL_PER_FILEOBJECT_CONTEXT;
//
// This will initialize the given FSRTL_PER_FILEOBJECT_CONTEXT structure. This
// should be used before calling "FsRtlInsertPerFileObjectContext".
//
#define FsRtlInitPerFileObjectContext( _fc, _owner, _inst ) \
((_fc)->OwnerId = (_owner), \ (_fc)->InstanceId = (_inst)) \
//
// This will test to see if PerFileObject contexts are supported for the given
// FileObject
//
#define FsRtlSupportsPerFileObjectContexts(_fo) \
FlagOn((_fo)->Flags,FO_FILE_OBJECT_HAS_EXTENSION)
//
// Associate the context at Ptr with the given FileObject. The Ptr
// structure should be filled in by the caller before calling this
// routine (see FsRtlInitPerFileObjectContext). If this file object does not
// support filter contexts, STATUS_INVALID_DEVICE_REQUEST will be returned.
//
NTKERNELAPI NTSTATUS FsRtlInsertPerFileObjectContext ( IN PFILE_OBJECT FileObject, IN PFSRTL_PER_FILEOBJECT_CONTEXT Ptr );
//
// Lookup a filter context associated with the FileObject specified. The first
// context matching OwnerId (and InstanceId, if present) is returned. By not
// specifying InstanceId, a filter driver can search for any context that it
// has previously associated with a stream. If no matching context is found,
// NULL is returned. If the FileObject does not support contexts,
// NULL is returned.
//
NTKERNELAPI PFSRTL_PER_FILEOBJECT_CONTEXT FsRtlLookupPerFileObjectContext ( IN PFILE_OBJECT FileObject, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL );
//
// Normally, contexts should be deleted when the IoManager notifies the
// filter that the FileObject is being freed. There are cases when a filter
// may want to remove all existing contexts for a specific volume. This
// routine should be called at those times. This routine should NOT be
// called for the following case:
// - Inside your FreeCallback handler - The IoManager has already removed
// it from the linked list.
//
// This functions identically to FsRtlLookupPerFileObjectContext, except that
// the returned context has been removed from the list.
//
NTKERNELAPI PFSRTL_PER_FILEOBJECT_CONTEXT FsRtlRemovePerFileObjectContext ( IN PFILE_OBJECT FileObject, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL );
//
// Internal routine to free the context control structure
//
VOID FsRtlPTeardownPerFileObjectContexts ( IN PFILE_OBJECT FileObject );
// begin_ntifs
//++
//
// VOID
// FsRtlCompleteRequest (
// IN PIRP Irp,
// IN NTSTATUS Status
// );
//
// Routine Description:
//
// This routine is used to complete an IRP with the indicated
// status. It does the necessary raise and lower of IRQL.
//
// Arguments:
//
// Irp - Supplies a pointer to the Irp to complete
//
// Status - Supplies the completion status for the Irp
//
// Return Value:
//
// None.
//
//--
#define FsRtlCompleteRequest(IRP,STATUS) { \
(IRP)->IoStatus.Status = (STATUS); \ IoCompleteRequest( (IRP), IO_DISK_INCREMENT ); \ }
//++
//
// VOID
// FsRtlEnterFileSystem (
// );
//
// Routine Description:
//
// This routine is used when entering a file system (e.g., through its
// Fsd entry point). It ensures that the file system cannot be suspended
// while running and thus block other file I/O requests. Upon exit
// the file system must call FsRtlExitFileSystem.
//
// Arguments:
//
// Return Value:
//
// None.
//
//--
#define FsRtlEnterFileSystem() { \
KeEnterCriticalRegion(); \ }
//++
//
// VOID
// FsRtlExitFileSystem (
// );
//
// Routine Description:
//
// This routine is used when exiting a file system (e.g., through its
// Fsd entry point).
//
// Arguments:
//
// Return Value:
//
// None.
//
//--
#define FsRtlExitFileSystem() { \
KeLeaveCriticalRegion(); \ }
VOID FsRtlIncrementCcFastReadNotPossible( VOID );
VOID FsRtlIncrementCcFastReadWait( VOID );
VOID FsRtlIncrementCcFastReadNoWait( VOID );
VOID FsRtlIncrementCcFastReadResourceMiss( VOID );
//
// Returns TRUE if the given fileObject represents a paging file, returns
// FALSE otherwise.
//
LOGICAL FsRtlIsPagingFile ( IN PFILE_OBJECT FileObject );
// end_ntifs
#endif // _FSRTL_
|