|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
FsRtlP.h
Abstract:
This module defines private part of the File System Rtl component
Author:
Gary Kimura [GaryKi] 30-Jul-1990
Revision History:
--*/
#ifndef _FSRTLP_
#define _FSRTLP_
#pragma warning(disable:4214) // bit field types other than int
#pragma warning(disable:4201) // nameless struct/union
#pragma warning(disable:4127) // condition expression is constant
#pragma warning(disable:4115) // named type definition in parentheses
#pragma warning(disable:4706) // assignment within conditional expression
#include <ntos.h>
#include <FsRtl.h>
#include <NtDdFt.h>
#include <zwapi.h>
#define FsRtlAllocatePool(PoolType, NumberOfBytes ) \
ExAllocatePoolWithTag((POOL_TYPE)((PoolType) | POOL_RAISE_IF_ALLOCATION_FAILURE), \ NumberOfBytes, \ 'trSF')
#define FsRtlAllocatePoolWithQuota(PoolType, NumberOfBytes ) \
ExAllocatePoolWithQuotaTag((POOL_TYPE)((PoolType) | POOL_RAISE_IF_ALLOCATION_FAILURE), \ NumberOfBytes, \ 'trSF')
#define FsRtlpAllocatePool(a,b) FsRtlAllocatePoolWithTag((a),(b),MODULE_POOL_TAG)
//
// The global FsRtl debug level variable, its values are:
//
// 0x00000000 Always gets printed (used when about to bug check)
//
// 0x00000001 Error conditions
// 0x00000002 Debug hooks
// 0x00000004
// 0x00000008
//
// 0x00000010
// 0x00000020
// 0x00000040
// 0x00000080
//
// 0x00000100
// 0x00000200
// 0x00000400
// 0x00000800
//
// 0x00001000
// 0x00002000
// 0x00004000
// 0x00008000
//
// 0x00010000
// 0x00020000
// 0x00040000
// 0x00080000
//
// 0x00100000
// 0x00200000
// 0x00400000
// 0x00800000
//
// 0x01000000
// 0x02000000
// 0x04000000 NotifyChange routines
// 0x08000000 Oplock routines
//
// 0x10000000 Name routines
// 0x20000000 FileLock routines
// 0x40000000 Vmcb routines
// 0x80000000 Mcb routines
//
//
// Debug trace support
//
#ifdef FSRTLDBG
extern LONG FsRtlDebugTraceLevel; extern LONG FsRtlDebugTraceIndent;
#define DebugTrace(INDENT,LEVEL,X,Y) { \
LONG _i; \ if (((LEVEL) == 0) || (FsRtlDebugTraceLevel & (LEVEL))) { \ _i = (ULONG)PsGetCurrentThread(); \ DbgPrint("%08lx:",_i); \ if ((INDENT) < 0) { \ FsRtlDebugTraceIndent += (INDENT); \ } \ if (FsRtlDebugTraceIndent < 0) { \ FsRtlDebugTraceIndent = 0; \ } \ for (_i=0; _i<FsRtlDebugTraceIndent; _i+=1) { \ DbgPrint(" "); \ } \ DbgPrint(X,Y); \ if ((INDENT) > 0) { \ FsRtlDebugTraceIndent += (INDENT); \ } \ } \ }
#define DebugDump(STR,LEVEL,PTR) { \
ULONG _i; \ VOID FsRtlDump(); \ if (((LEVEL) == 0) || (FsRtlDebugTraceLevel & (LEVEL))) { \ _i = (ULONG)PsGetCurrentThread(); \ DbgPrint("%08lx:",_i); \ DbgPrint(STR); \ if (PTR != NULL) {FsRtlDump(PTR);} \ DbgBreakPoint(); \ } \ }
#else
#define DebugTrace(INDENT,LEVEL,X,Y) {NOTHING;}
#define DebugDump(STR,LEVEL,PTR) {NOTHING;}
#endif // FSRTLDBG
//
// Miscellaneous support routines
//
VOID FsRtlInitializeFileLocks ( VOID );
VOID FsRtlInitializeLargeMcbs ( VOID );
VOID FsRtlInitializeTunnels( VOID );
NTSTATUS FsRtlInitializeWorkerThread ( VOID );
//
// This macro returns TRUE if a flag in a set of flags is on and FALSE
// otherwise
//
#define FlagOn(Flags,SingleFlag) ((Flags) & (SingleFlag))
#define BooleanFlagOn(Flags,SingleFlag) ((BOOLEAN)(((Flags) & (SingleFlag)) != 0))
#define SetFlag(F,SF) { \
(F) |= (SF); \ }
#define ClearFlag(F,SF) { \
(F) &= ~(SF); \ }
//
// This macro takes a pointer (or ulong) and returns its rounded up word
// value
//
#define WordAlign(Ptr) ( \
((((ULONG_PTR)(Ptr)) + 1) & -2) \ )
//
// This macro takes a pointer (or ulong) and returns its rounded up longword
// value
//
#define LongAlign(Ptr) ( \
((((ULONG_PTR)(Ptr)) + 3) & -4) \ )
//
// This macro takes a pointer (or ulong) and returns its rounded up quadword
// value
//
#define QuadAlign(Ptr) ( \
((((ULONG_PTR)(Ptr)) + 7) & -8) \ )
//
// This macro takes a ulong and returns its value rounded up to a sector
// boundary
//
#define SectorAlign(Ptr) ( \
((((ULONG_PTR)(Ptr)) + 511) & -512) \ )
//
// This macro takes a number of bytes and returns the number of sectors
// required to contain that many bytes, i.e., it sector aligns and divides
// by the size of a sector.
//
#define SectorsFromBytes(bytes) ( \
((bytes) + 511) / 512 \ )
//
// This macro takes a number of sectors and returns the number of bytes
// contained in that many sectors.
//
#define BytesFromSectors(sectors) ( \
(sectors) * 512 \ )
//
// 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;
//
// 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)); \ }
//
// 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 GET_FAST_IO_DISPATCH(DevObj) \
((DevObj)->DriverObject->FastIoDispatch)
#define GET_FS_FILTER_CALLBACKS(DevObj) \
((DevObj)->DriverObject->DriverExtension->FsFilterCallbacks) //
// Macro for validating the FastIo dispatch routines before calling
// them in the FastIo pass through functions.
//
#define VALID_FAST_IO_DISPATCH_HANDLER(FastIoDispatchPtr, FieldName) \
(((FastIoDispatchPtr) != NULL) && \ (((FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \ (FIELD_OFFSET(FAST_IO_DISPATCH, FieldName) + sizeof(VOID *))) && \ ((FastIoDispatchPtr)->FieldName != NULL))
#define VALID_FS_FILTER_CALLBACK_HANDLER(FsFilterCallbackPtr, FieldName) \
(((FsFilterCallbackPtr) != NULL) && \ (((FsFilterCallbackPtr)->SizeOfFsFilterCallbacks) >= \ (FIELD_OFFSET(FS_FILTER_CALLBACKS, FieldName) + sizeof(VOID *))) && \ ((FsFilterCallbackPtr)->FieldName != NULL))
#define FSRTL_FILTER_MEMORY_TAG 'gmSF'
typedef struct _FS_FILTER_COMPLETION_NODE {
PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; PVOID CompletionContext; PFS_FILTER_COMPLETION_CALLBACK CompletionCallback; } FS_FILTER_COMPLETION_NODE, *PFS_FILTER_COMPLETION_NODE;
#define FS_FILTER_DEFAULT_STACK_SIZE 15
typedef struct _FS_FILTER_COMPLETION_STACK {
USHORT StackLength; USHORT NextStackPosition; PFS_FILTER_COMPLETION_NODE Stack; FS_FILTER_COMPLETION_NODE DefaultStack[FS_FILTER_DEFAULT_STACK_SIZE]; } FS_FILTER_COMPLETION_STACK, *PFS_FILTER_COMPLETION_STACK;
typedef struct _FS_FILTER_CTRL {
FS_FILTER_CALLBACK_DATA Data; ULONG Flags; ULONG Reserved; FS_FILTER_COMPLETION_STACK CompletionStack; } FS_FILTER_CTRL, *PFS_FILTER_CTRL;
//
// Flag values for FS_FILTER_CTRL
//
#define FS_FILTER_ALLOCATED_COMPLETION_STACK 0x00000001
#define FS_FILTER_USED_RESERVE_POOL 0x00000002
#define FS_FILTER_CHANGED_DEVICE_STACKS 0x00000004
NTSTATUS FsFilterInit( );
NTSTATUS FsFilterAllocateCompletionStack ( IN PFS_FILTER_CTRL FsFilterCtrl, IN BOOLEAN CanFail, OUT PULONG AllocationSize );
VOID FsFilterFreeCompletionStack ( IN PFS_FILTER_CTRL FsFilterCtrl );
NTSTATUS FsFilterCtrlInit ( IN OUT PFS_FILTER_CTRL FsFilterCtrl, IN UCHAR Operation, IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT BaseFsDeviceObject, IN PFILE_OBJECT FileObject, IN BOOLEAN CanFail );
VOID FsFilterCtrlFree ( IN PFS_FILTER_CTRL FsFilterCtrl );
#define PUSH_COMPLETION_NODE( completionStack ) \
(((completionStack)->NextStackPosition < (completionStack)->StackLength ) ? \ &(completionStack)->Stack[(completionStack)->NextStackPosition++] : \ (ASSERT( FALSE ), NULL) )
#define POP_COMPLETION_NODE( completionStack ) \
(ASSERT((completionStack)->NextStackPosition > 0), \ ((completionStack)->NextStackPosition--))
#define GET_COMPLETION_NODE( completionStack ) \
(ASSERT((completionStack)->NextStackPosition > 0),\ (&(completionStack)->Stack[(completionStack)->NextStackPosition-1]))
#define FS_FILTER_HAVE_COMPLETIONS( fsFilterCtrl ) \
((fsFilterCtrl)->CompletionStack.NextStackPosition > 0)
VOID FsFilterGetCallbacks ( IN UCHAR Operation, IN PDEVICE_OBJECT DeviceObject, OUT PFS_FILTER_CALLBACK *PreOperationCallback, OUT PFS_FILTER_COMPLETION_CALLBACK *PostOperationCallback );
NTSTATUS FsFilterPerformCallbacks ( IN PFS_FILTER_CTRL FsFilterCtrl, IN BOOLEAN AllowFilterToFail, IN BOOLEAN AllowBaseFsToFail, OUT BOOLEAN *BaseFsFailedOp );
VOID FsFilterPerformCompletionCallbacks( IN PFS_FILTER_CTRL FsFilterCtrl, IN NTSTATUS OperationStatus );
#endif // _FSRTLP_
|