/*+r Copyright (c) 1989 Microsoft Corporation Module Name: afd.h Abstract: This is the local header file for AFD. It includes all other necessary header files for AFD. Author: David Treadwell (davidtr) 21-Feb-1992 Revision History: --*/ #ifndef _AFDP_ #define _AFDP_ #include #include #include #ifndef _AFDKDP_H_ extern POBJECT_TYPE *ExEventObjectType; #endif // _AFDKDP_H_ #if DBG #ifndef AFD_PERF_DBG #define AFD_PERF_DBG 1 #endif #ifndef AFD_KEEP_STATS #define AFD_KEEP_STATS 1 #endif #else #ifndef AFD_PERF_DBG #define AFD_PERF_DBG 0 #endif #ifndef AFD_KEEP_STATS #define AFD_KEEP_STATS 0 #endif #endif // DBG // // Hack-O-Rama. TDI has a fundamental flaw in that it is often impossible // to determine exactly when a TDI protocol is "done" with a connection // object. The biggest problem here is that AFD may get a suprious TDI // indication *after* an abort request has completed. As a temporary work- // around, whenever an abort request completes, we'll start a timer. AFD // will defer further processing on the connection until that timer fires. // // If the following symbol is defined, then our timer hack is enabled. // Afd now uses InterlockedCompareExchange to protect itself // // #define ENABLE_ABORT_TIMER_HACK 0 // // The following constant defines the relative time interval (in seconds) // for the "post abort request complete" timer. // // #define AFD_ABORT_TIMER_TIMEOUT_VALUE 5 // seconds // // Goodies stolen from other header files. // #ifndef FAR #define FAR #endif #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif typedef unsigned short u_short; #ifndef SG_UNCONSTRAINED_GROUP #define SG_UNCONSTRAINED_GROUP 0x01 #endif #ifndef SG_CONSTRAINED_GROUP #define SG_CONSTRAINED_GROUP 0x02 #endif #include #include "afdstr.h" #include "afddata.h" #include "afdprocs.h" #define AFD_EA_POOL_TAG ( (ULONG)'AdfA' | PROTECTED_POOL ) #define AFD_DATA_BUFFER_POOL_TAG ( (ULONG)'BdfA' | PROTECTED_POOL ) #define AFD_CONNECTION_POOL_TAG ( (ULONG)'CdfA' | PROTECTED_POOL ) #define AFD_CONNECT_DATA_POOL_TAG ( (ULONG)'cdfA' | PROTECTED_POOL ) #define AFD_DEBUG_POOL_TAG ( (ULONG)'DdfA' | PROTECTED_POOL ) #define AFD_ENDPOINT_POOL_TAG ( (ULONG)'EdfA' | PROTECTED_POOL ) #define AFD_TRANSMIT_INFO_POOL_TAG ( (ULONG)'FdfA' | PROTECTED_POOL ) #define AFD_GROUP_POOL_TAG ( (ULONG)'GdfA' | PROTECTED_POOL ) #define AFD_ADDRESS_CHANGE_POOL_TAG ( (ULONG)'hdfA' | PROTECTED_POOL ) #define AFD_TDI_POOL_TAG ( (ULONG)'IdfA' | PROTECTED_POOL ) #define AFD_LOCAL_ADDRESS_POOL_TAG ( (ULONG)'LdfA' | PROTECTED_POOL ) #define AFD_POLL_POOL_TAG ( (ULONG)'PdfA' | PROTECTED_POOL ) #define AFD_TRANSPORT_IRP_POOL_TAG ( (ULONG)'pdfA' | PROTECTED_POOL ) #define AFD_ROUTING_QUERY_POOL_TAG ( (ULONG)'qdfA' | PROTECTED_POOL ) #define AFD_REMOTE_ADDRESS_POOL_TAG ( (ULONG)'RdfA' | PROTECTED_POOL ) #define AFD_RESOURCE_POOL_TAG ( (ULONG)'rdfA' | PROTECTED_POOL ) // Can't be protected - freed by kernel. #define AFD_SECURITY_POOL_TAG ( (ULONG)'SdfA' ) #define AFD_TRANSPORT_ADDRESS_POOL_TAG ( (ULONG)'tdfA' | PROTECTED_POOL ) #define AFD_TRANSPORT_INFO_POOL_TAG ( (ULONG)'TdfA' | PROTECTED_POOL ) // Can't be protected - freed by kernel. #define AFD_TEMPORARY_POOL_TAG ( (ULONG)' dfA' ) #define AFD_CONTEXT_POOL_TAG ( (ULONG)'XdfA' | PROTECTED_POOL ) #define AFD_SAN_CONTEXT_POOL_TAG ( (ULONG)'xdfA' | PROTECTED_POOL ) #define MyFreePoolWithTag(a,t) ExFreePoolWithTag(a,t) #if DBG // // N.B. This structure MUST be quadword aligned! // typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _AFD_POOL_HEADER { SIZE_T Size; PCHAR FileName; ULONG LineNumber; ULONG InUse; } AFD_POOL_HEADER, *PAFD_POOL_HEADER; #define AFD_POOL_OVERHEAD (sizeof(AFD_POOL_HEADER)) #else #define AFD_POOL_OVERHEAD 0 #endif #if DBG extern ULONG AfdDebug; extern ULONG AfdLocksAcquired; #undef IF_DEBUG #define IF_DEBUG(a) if ( (AFD_DEBUG_ ## a & AfdDebug) != 0 ) #define AFD_DEBUG_OPEN_CLOSE 0x00000001 #define AFD_DEBUG_ENDPOINT 0x00000002 #define AFD_DEBUG_CONNECTION 0x00000004 #define AFD_DEBUG_EVENT_SELECT 0x00000008 #define AFD_DEBUG_BIND 0x00000010 #define AFD_DEBUG_CONNECT 0x00000020 #define AFD_DEBUG_LISTEN 0x00000040 #define AFD_DEBUG_ACCEPT 0x00000080 #define AFD_DEBUG_SEND 0x00000100 #define AFD_DEBUG_QUOTA 0x00000200 #define AFD_DEBUG_RECEIVE 0x00000400 #define AFD_DEBUG_11 0x00000800 #define AFD_DEBUG_POLL 0x00001000 #define AFD_DEBUG_FAST_IO 0x00002000 #define AFD_DEBUG_ROUTING_QUERY 0x00010000 #define AFD_DEBUG_ADDRESS_LIST 0x00020000 #define AFD_DEBUG_TRANSMIT 0x00100000 #define AFD_DEBUG_SAN_SWITCH 0x00200000 #define DEBUG #define AFD_ALLOCATE_POOL(a,b,t) AfdAllocatePool( a,b,t,__FILE__,__LINE__,FALSE,LowPoolPriority ) #define AFD_ALLOCATE_POOL_WITH_QUOTA(a,b,t) AfdAllocatePool( (a)|POOL_RAISE_IF_ALLOCATION_FAILURE,b,t,__FILE__,__LINE__,TRUE,LowPoolPriority ) #define AFD_ALLOCATE_POOL_PRIORITY(a,b,t,p) AfdAllocatePool( a,b,t,__FILE__,__LINE__,FALSE,p ) PVOID AfdAllocatePool ( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag, IN PCHAR FileName, IN ULONG LineNumber, IN BOOLEAN WithQuota, IN EX_POOL_PRIORITY Priority ); #define AFD_FREE_POOL(a,t) AfdFreePool(a,t) VOID AfdFreePool ( IN PVOID Pointer, IN ULONG Tag ); #define AfdRecordOutstandingIrp(a,b,c) \ AfdRecordOutstandingIrpDebug(a,b,c,__FILE__,__LINE__) BOOLEAN AfdRecordOutstandingIrpDebug ( IN PAFD_ENDPOINT Endpoint, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PCHAR FileName, IN ULONG LineNumber ); #define AfdIoCallDriver(a,b,c) \ (AfdRecordOutstandingIrp(a,b,c) \ ? IoCallDriver (b,c) \ : STATUS_INSUFFICIENT_RESOURCES \ ) #define AfdCompleteOutstandingIrp(a,b) \ AfdCompleteOutstandingIrpDebug(a,b) VOID AfdCompleteOutstandingIrpDebug ( IN PAFD_ENDPOINT Endpoint, IN PIRP Irp ); #ifdef AFDDBG_QUOTA VOID AfdRecordQuotaHistory( IN PEPROCESS Process, IN LONG Bytes, IN PSZ Type, IN PVOID Block ); #else #define AfdRecordQuotaHistory(a,b,c,d) #endif // // Queued spinlock wrappers - perform basic validation // #define AfdAcquireSpinLock(a,b) \ ASSERT(AfdLoaded); (b)->SpinLock=(a); KeAcquireInStackQueuedSpinLock(&(a)->ActualSpinLock,&((b)->LockHandle)); AfdLocksAcquired++ #define AfdReleaseSpinLock(a,b) \ AfdLocksAcquired--; ASSERT ((b)->SpinLock==(a)); ASSERT( AfdLoaded ); KeReleaseInStackQueuedSpinLock(&((b)->LockHandle)); #define AfdAcquireSpinLockAtDpcLevel(a,b) \ ASSERT( AfdLoaded ); (b)->SpinLock=(a); KeAcquireInStackQueuedSpinLockAtDpcLevel(&(a)->ActualSpinLock,&((b)->LockHandle)); AfdLocksAcquired++ #define AfdReleaseSpinLockFromDpcLevel(a,b) \ AfdLocksAcquired--; ASSERT ((b)->SpinLock==(a)); ASSERT( AfdLoaded ); KeReleaseInStackQueuedSpinLockFromDpcLevel(&((b)->LockHandle)) #define AfdInitializeSpinLock(a) \ KeInitializeSpinLock(&(a)->ActualSpinLock) // // Define our own assert so that we can actually catch assertion failures // when running a checked AFD on a free kernel. // VOID AfdAssert( PVOID FailedAssertion, PVOID FileName, ULONG LineNumber, PCHAR Message ); #undef ASSERT #define ASSERT( exp ) \ if (!(exp)) \ AfdAssert( #exp, __FILE__, __LINE__, NULL ) #undef ASSERTMSG #define ASSERTMSG( msg, exp ) \ if (!(exp)) \ AfdAssert( #exp, __FILE__, __LINE__, msg ) #define AFD_EXCEPTION_FILTER(_s) \ AfdExceptionFilter( \ (LPSTR)__FILE__, \ (LONG)__LINE__, \ GetExceptionInformation(), \ _s \ ) #else // !DBG #undef IF_DEBUG #define IF_DEBUG(a) if (FALSE) #define DEBUG if ( FALSE ) #define AFD_ALLOCATE_POOL(a,b,t) ExAllocatePoolWithTagPriority(a,b,t,LowPoolPriority) #define AFD_ALLOCATE_POOL_WITH_QUOTA(a,b,t) ExAllocatePoolWithQuotaTag((a)|POOL_RAISE_IF_ALLOCATION_FAILURE,b,t) #define AFD_ALLOCATE_POOL_PRIORITY(a,b,t,p) ExAllocatePoolWithTagPriority(a,b,t,p) #define AFD_FREE_POOL(a,t) MyFreePoolWithTag(a,t) #define AfdRecordOutstandingIrp(a,b,c) \ (InterlockedIncrement(&((a)->OutstandingIrpCount)), TRUE) #define AfdIoCallDriver(a,b,c) \ (AfdRecordOutstandingIrp(a,b,c), IoCallDriver(b,c)) #define AfdCompleteOutstandingIrp(a,b) \ InterlockedDecrement(&((a)->OutstandingIrpCount)) NTSTATUS AfdIoCallDriverFree ( IN PAFD_ENDPOINT Endpoint, IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID AfdCompleteOutstandingIrpFree ( IN PAFD_ENDPOINT Endpoint, IN PIRP Irp ); #define AfdRecordQuotaHistory(a,b,c,d) #define AfdAcquireSpinLock(a,b) KeAcquireInStackQueuedSpinLock(&(a)->ActualSpinLock,(b)) #define AfdReleaseSpinLock(a,b) KeReleaseInStackQueuedSpinLock((b)) #define AfdAcquireSpinLockAtDpcLevel(a,b) KeAcquireInStackQueuedSpinLockAtDpcLevel(&(a)->ActualSpinLock,(b)) #define AfdReleaseSpinLockFromDpcLevel(a,b) KeReleaseInStackQueuedSpinLockFromDpcLevel((b)) #define AfdInitializeSpinLock(a) \ KeInitializeSpinLock(&(a)->ActualSpinLock) #define AFD_EXCEPTION_FILTER(_s) \ AfdExceptionFilter( \ GetExceptionInformation(), \ _s \ ) #endif // def DBG #if DBG || REFERENCE_DEBUG VOID AfdInitializeDebugData( VOID ); VOID AfdFreeDebugData ( VOID ); #endif // // Make some of the receive code a bit prettier. // #define TDI_RECEIVE_EITHER ( TDI_RECEIVE_NORMAL | TDI_RECEIVE_EXPEDITED ) #endif // ndef _AFDP_