688 lines
21 KiB
C
688 lines
21 KiB
C
/*++
|
|
|
|
Copyright (c) 1998-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
debug.h
|
|
|
|
Abstract:
|
|
|
|
This module contains debug-specific declarations.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 10-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _DEBUG_H_
|
|
#define _DEBUG_H_
|
|
|
|
|
|
#if DBG
|
|
|
|
//
|
|
// Initialization/termination functions.
|
|
//
|
|
|
|
VOID
|
|
UlDbgInitializeDebugData(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UlDbgTerminateDebugData(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Driver entry/exit notifications.
|
|
//
|
|
|
|
VOID
|
|
UlDbgEnterDriver(
|
|
IN PSTR pFunctionName,
|
|
IN PIRP pIrp OPTIONAL,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgLeaveDriver(
|
|
IN PSTR pFunctionName,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_ENTER_DRIVER( function, pirp ) \
|
|
UlDbgEnterDriver( \
|
|
(function), \
|
|
(pirp), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UL_LEAVE_DRIVER( function ) \
|
|
UlDbgLeaveDriver( \
|
|
(function), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
|
|
//
|
|
// An instrumented resource.
|
|
//
|
|
|
|
#define MAX_RESOURCE_NAME_LENGTH 64
|
|
|
|
typedef struct _UL_ERESOURCE
|
|
{
|
|
//
|
|
// The actual resource.
|
|
//
|
|
// N.B. This must be the first entry in the structure to make the
|
|
// debugger extension work properly!
|
|
//
|
|
|
|
ERESOURCE Resource;
|
|
|
|
//
|
|
// Links onto the global resource list.
|
|
//
|
|
|
|
LIST_ENTRY GlobalResourceListEntry;
|
|
|
|
//
|
|
// Pointer to the thread that owns this lock exclusively.
|
|
//
|
|
|
|
PETHREAD pExclusiveOwner;
|
|
|
|
//
|
|
// Statistics.
|
|
//
|
|
|
|
LONG ExclusiveCount;
|
|
LONG SharedCount;
|
|
LONG ReleaseCount;
|
|
|
|
//
|
|
// The name of the resource, for display purposes.
|
|
//
|
|
|
|
UCHAR ResourceName[MAX_RESOURCE_NAME_LENGTH];
|
|
|
|
} UL_ERESOURCE, *PUL_ERESOURCE;
|
|
|
|
NTSTATUS
|
|
UlDbgInitializeResource(
|
|
IN PUL_ERESOURCE pResource,
|
|
IN PSTR pResourceName,
|
|
IN ULONG_PTR Parameter,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
NTSTATUS
|
|
UlDbgDeleteResource(
|
|
IN PUL_ERESOURCE pResource,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
BOOLEAN
|
|
UlDbgAcquireResourceExclusive(
|
|
IN PUL_ERESOURCE pResource,
|
|
IN BOOLEAN Wait,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
BOOLEAN
|
|
UlDbgAcquireResourceShared(
|
|
IN PUL_ERESOURCE pResource,
|
|
IN BOOLEAN Wait,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgReleaseResource(
|
|
IN PUL_ERESOURCE pResource,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
BOOLEAN
|
|
UlDbgResourceOwnedExclusive(
|
|
IN PUL_ERESOURCE pResource
|
|
);
|
|
|
|
BOOLEAN
|
|
UlDbgResourceUnownedExclusive(
|
|
IN PUL_ERESOURCE pResource
|
|
);
|
|
|
|
#define UlInitializeResource( resource, name, param ) \
|
|
UlDbgInitializeResource( \
|
|
(resource), \
|
|
(name), \
|
|
(ULONG_PTR)(param), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlDeleteResource( resource ) \
|
|
UlDbgDeleteResource( \
|
|
(resource), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlAcquireResourceExclusive( resource, wait ) \
|
|
UlDbgAcquireResourceExclusive( \
|
|
(resource), \
|
|
(wait), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlAcquireResourceShared( resource, wait ) \
|
|
UlDbgAcquireResourceShared( \
|
|
(resource), \
|
|
(wait), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlReleaseResource( resource ) \
|
|
UlDbgReleaseResource( \
|
|
(resource), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define IS_RESOURCE_INITIALIZED( resource ) \
|
|
((resource)->Resource.SystemResourcesList.Flink != NULL)
|
|
|
|
|
|
//
|
|
// An instrumented spinlock.
|
|
//
|
|
|
|
typedef struct _UL_SPIN_LOCK // SpinLock
|
|
{
|
|
//
|
|
// The actual lock.
|
|
//
|
|
// N.B. This must be the first entry in the structure to make the
|
|
// debugger extension work properly!
|
|
//
|
|
|
|
KSPIN_LOCK KSpinLock;
|
|
|
|
//
|
|
// The name of the spinlock, for display purposes.
|
|
//
|
|
|
|
PSTR pSpinLockName;
|
|
|
|
//
|
|
// Pointer to the thread that owns this lock.
|
|
//
|
|
|
|
PETHREAD pOwnerThread;
|
|
|
|
//
|
|
// Statistics.
|
|
//
|
|
|
|
PSTR pLastAcquireFileName;
|
|
PSTR pLastReleaseFileName;
|
|
USHORT LastAcquireLineNumber;
|
|
USHORT LastReleaseLineNumber;
|
|
ULONG OwnerProcessor;
|
|
LONG Acquisitions;
|
|
LONG Releases;
|
|
LONG AcquisitionsAtDpcLevel;
|
|
LONG ReleasesFromDpcLevel;
|
|
LONG Spare;
|
|
|
|
} UL_SPIN_LOCK, *PUL_SPIN_LOCK;
|
|
|
|
#define KSPIN_LOCK_FROM_UL_SPIN_LOCK( pLock ) \
|
|
&((pLock)->KSpinLock)
|
|
|
|
VOID
|
|
UlDbgInitializeSpinLock(
|
|
IN PUL_SPIN_LOCK pSpinLock,
|
|
IN PSTR pSpinLockName,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgAcquireSpinLock(
|
|
IN PUL_SPIN_LOCK pSpinLock,
|
|
OUT PKIRQL pOldIrql,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgReleaseSpinLock(
|
|
IN PUL_SPIN_LOCK pSpinLock,
|
|
IN KIRQL OldIrql,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgAcquireSpinLockAtDpcLevel(
|
|
IN PUL_SPIN_LOCK pSpinLock,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgReleaseSpinLockFromDpcLevel(
|
|
IN PUL_SPIN_LOCK pSpinLock,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
BOOLEAN
|
|
UlDbgSpinLockOwned(
|
|
IN PUL_SPIN_LOCK pSpinLock
|
|
);
|
|
|
|
BOOLEAN
|
|
UlDbgSpinLockUnowned(
|
|
IN PUL_SPIN_LOCK pSpinLock
|
|
);
|
|
|
|
#define UlInitializeSpinLock( spinlock, name ) \
|
|
UlDbgInitializeSpinLock( \
|
|
(spinlock), \
|
|
(name), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlAcquireSpinLock( spinlock, oldirql ) \
|
|
UlDbgAcquireSpinLock( \
|
|
(spinlock), \
|
|
(oldirql), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlReleaseSpinLock( spinlock, oldirql ) \
|
|
UlDbgReleaseSpinLock( \
|
|
(spinlock), \
|
|
(oldirql), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlAcquireSpinLockAtDpcLevel( spinlock ) \
|
|
UlDbgAcquireSpinLockAtDpcLevel( \
|
|
(spinlock), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UlReleaseSpinLockFromDpcLevel( spinlock ) \
|
|
UlDbgReleaseSpinLockFromDpcLevel( \
|
|
(spinlock), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
|
|
//
|
|
// Debug spew control.
|
|
// If you change or add a flag, please update the FlagTable
|
|
// in ul\test\dll\tul.c.
|
|
//
|
|
|
|
#undef IF_DEBUG
|
|
#define IF_DEBUG(a) if ( (UL_DEBUG_ ## a & g_UlDebug) != 0 )
|
|
|
|
#define UL_DEBUG_OPEN_CLOSE 0x00000001
|
|
#define UL_DEBUG_SEND_RESPONSE 0x00000002
|
|
#define UL_DEBUG_SEND_BUFFER 0x00000004
|
|
#define UL_DEBUG_TDI 0x00000008
|
|
|
|
#define UL_DEBUG_FILE_CACHE 0x00000010
|
|
#define UL_DEBUG_CONFIG_GROUP_FNC 0x00000020
|
|
#define UL_DEBUG_CONFIG_GROUP_TREE 0x00000040
|
|
#define UL_DEBUG_REFCOUNT 0x00000080
|
|
|
|
#define UL_DEBUG_HTTP_IO 0x00000100
|
|
#define UL_DEBUG_ROUTING 0x00000200
|
|
#define UL_DEBUG_URI_CACHE 0x00000400
|
|
#define UL_DEBUG_PARSER 0x00000800
|
|
|
|
#define UL_DEBUG_SITE 0x00001000
|
|
#define UL_DEBUG_WORK_ITEM 0x00002000
|
|
|
|
#define UL_DEBUG_PARSER2 0x80000000
|
|
|
|
#define DEBUG
|
|
|
|
|
|
//
|
|
// Tracing.
|
|
//
|
|
|
|
#define UlTrace(a, _b_) \
|
|
do \
|
|
{ \
|
|
IF_DEBUG(##a) \
|
|
{ \
|
|
DbgPrint _b_ ; \
|
|
} \
|
|
} while (FALSE)
|
|
|
|
|
|
//
|
|
// Debug pool allocator.
|
|
//
|
|
|
|
PVOID
|
|
UlDbgAllocatePool (
|
|
IN POOL_TYPE PoolType,
|
|
IN SIZE_T NumberOfBytes,
|
|
IN ULONG Tag,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgFreePool (
|
|
IN PVOID pPointer,
|
|
IN ULONG Tag
|
|
);
|
|
|
|
#define UL_ALLOCATE_POOL( type, len, tag ) \
|
|
UlDbgAllocatePool( \
|
|
(type), \
|
|
(len), \
|
|
(tag), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define UL_FREE_POOL( ptr, tag ) \
|
|
UlDbgFreePool( \
|
|
(ptr), \
|
|
(tag) \
|
|
)
|
|
|
|
//
|
|
// Exception filter.
|
|
//
|
|
|
|
LONG
|
|
UlDbgExceptionFilter(
|
|
IN PEXCEPTION_POINTERS pExceptionPointers,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_EXCEPTION_FILTER() \
|
|
UlDbgExceptionFilter( \
|
|
GetExceptionInformation(), \
|
|
(PSTR)__FILE__, \
|
|
(USHORT)__LINE__ \
|
|
)
|
|
|
|
|
|
//
|
|
// Invalid completion routine for catching incomplete IRP contexts.
|
|
//
|
|
|
|
VOID
|
|
UlDbgInvalidCompletionRoutine(
|
|
IN PVOID pCompletionContext,
|
|
IN NTSTATUS Status,
|
|
IN ULONG_PTR Information
|
|
);
|
|
|
|
|
|
//
|
|
// Error handlers.
|
|
//
|
|
|
|
NTSTATUS
|
|
UlDbgStatus(
|
|
IN NTSTATUS Status,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define RETURN(status) \
|
|
return UlDbgStatus( \
|
|
(status), \
|
|
__FILE__, \
|
|
__LINE__ \
|
|
)
|
|
|
|
#define CHECK_STATUS(status) \
|
|
UlDbgStatus( \
|
|
(status), \
|
|
(PSTR)__FILE__, \
|
|
(USHORT)__LINE__ \
|
|
)
|
|
|
|
//
|
|
// Random structure dumpers.
|
|
//
|
|
|
|
VOID
|
|
UlDbgDumpRequestBuffer(
|
|
IN struct _UL_REQUEST_BUFFER *pBuffer,
|
|
IN PSTR pName
|
|
);
|
|
|
|
VOID
|
|
UlDbgDumpHttpConnection(
|
|
IN struct _HTTP_CONNECTION *pConnection,
|
|
IN PSTR pName
|
|
);
|
|
|
|
|
|
//
|
|
// IO wrappers.
|
|
//
|
|
|
|
PIRP
|
|
UlDbgAllocateIrp(
|
|
IN CCHAR StackSize,
|
|
IN BOOLEAN ChargeQuota,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgFreeIrp(
|
|
IN PIRP pIrp,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
NTSTATUS
|
|
UlDbgCallDriver(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN OUT PIRP pIrp,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlDbgCompleteRequest(
|
|
IN PIRP pIrp,
|
|
IN CCHAR PriorityBoost,
|
|
IN PSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UlAllocateIrp( stack, quota ) \
|
|
UlDbgAllocateIrp( \
|
|
(stack), \
|
|
(quota), \
|
|
(PSTR)__FILE__, \
|
|
(USHORT)__LINE__ \
|
|
)
|
|
|
|
#define UlFreeIrp( pirp ) \
|
|
UlDbgFreeIrp( \
|
|
(pirp), \
|
|
(PSTR)__FILE__, \
|
|
(USHORT)__LINE__ \
|
|
)
|
|
|
|
#define UlCallDriver( pdevice, pirp ) \
|
|
UlDbgCallDriver( \
|
|
(pdevice), \
|
|
(pirp), \
|
|
(PSTR)__FILE__, \
|
|
(USHORT)__LINE__ \
|
|
)
|
|
|
|
#define UlCompleteRequest( pirp, boost ) \
|
|
UlDbgCompleteRequest( \
|
|
(pirp), \
|
|
(boost), \
|
|
(PSTR)__FILE__, \
|
|
(USHORT)__LINE__ \
|
|
)
|
|
|
|
#else // !DBG
|
|
|
|
//
|
|
// Disable all of the above.
|
|
//
|
|
|
|
#define UL_ENTER_DRIVER( function, pirp )
|
|
#define UL_LEAVE_DRIVER( function )
|
|
|
|
#define UL_ERESOURCE ERESOURCE
|
|
#define PUL_ERESOURCE PERESOURCE
|
|
|
|
#define UlInitializeResource( resource, name, param ) \
|
|
ExInitializeResource( (resource) )
|
|
|
|
#define UlDeleteResource( resource ) \
|
|
ExDeleteResource( (resource) )
|
|
|
|
#define UlAcquireResourceExclusive( resource, wait ) \
|
|
do \
|
|
{ \
|
|
KeEnterCriticalRegion(); \
|
|
ExAcquireResourceExclusive( (resource), (wait) ); \
|
|
} while (FALSE)
|
|
|
|
#define UlAcquireResourceShared( resource, wait ) \
|
|
do \
|
|
{ \
|
|
KeEnterCriticalRegion(); \
|
|
ExAcquireResourceShared( (resource), (wait) ); \
|
|
} while (FALSE)
|
|
|
|
#define UlReleaseResource( resource ) \
|
|
do \
|
|
{ \
|
|
ExReleaseResource( (resource) ); \
|
|
KeLeaveCriticalRegion(); \
|
|
} while (FALSE)
|
|
|
|
#define IS_RESOURCE_INITIALIZED( resource ) \
|
|
((resource)->SystemResourcesList.Flink != NULL)
|
|
|
|
#define UL_SPIN_LOCK KSPIN_LOCK
|
|
#define PUL_SPIN_LOCK PKSPIN_LOCK
|
|
|
|
#define KSPIN_LOCK_FROM_UL_SPIN_LOCK( pLock ) (pLock)
|
|
|
|
#define UlInitializeSpinLock( spinlock, name ) \
|
|
KeInitializeSpinLock( (spinlock) )
|
|
|
|
#define UlAcquireSpinLock( spinlock, oldirql ) \
|
|
KeAcquireSpinLock( (spinlock), (oldirql) )
|
|
|
|
#define UlReleaseSpinLock( spinlock, oldirql ) \
|
|
KeReleaseSpinLock( (spinlock), (oldirql) )
|
|
|
|
#define UlAcquireSpinLockAtDpcLevel( spinlock ) \
|
|
KeAcquireSpinLockAtDpcLevel( (spinlock) )
|
|
|
|
#define UlReleaseSpinLockFromDpcLevel( spinlock ) \
|
|
KeReleaseSpinLockFromDpcLevel( (spinlock) )
|
|
|
|
#undef IF_DEBUG
|
|
#define IF_DEBUG(a) if (FALSE)
|
|
#define DEBUG if ( FALSE )
|
|
|
|
#define UlTrace(a, _b_)
|
|
|
|
#define UL_ALLOCATE_POOL( type, len, tag ) \
|
|
ExAllocatePoolWithTag( \
|
|
(type), \
|
|
(len), \
|
|
(tag) \
|
|
)
|
|
|
|
#define UL_FREE_POOL( ptr, tag ) \
|
|
MyFreePoolWithTag( \
|
|
(ptr), \
|
|
(tag) \
|
|
)
|
|
|
|
#define UL_EXCEPTION_FILTER() EXCEPTION_EXECUTE_HANDLER
|
|
|
|
#define RETURN(status) return (status)
|
|
#define CHECK_STATUS(Status)
|
|
|
|
#define UlAllocateIrp( stack, quota ) \
|
|
IoAllocateIrp( (stack), (quota) )
|
|
|
|
#define UlFreeIrp( pirp ) \
|
|
IoFreeIrp( (pirp) )
|
|
|
|
#define UlCallDriver( pdevice, pirp ) \
|
|
IoCallDriver( (pdevice), (pirp) )
|
|
|
|
#define UlCompleteRequest( pirp, boost ) \
|
|
IoCompleteRequest( (pirp), (boost) )
|
|
|
|
#endif // DBG
|
|
|
|
// BUGBUG: ALIGN_UP(PVOID) won't work, it needs to be the type of the first entry of the
|
|
// following data (paulmcd 4/29/99)
|
|
|
|
#define UL_ALLOCATE_STRUCT_WITH_SPACE(pt,ot,cb,t) \
|
|
(ot *)(UL_ALLOCATE_POOL(pt,ALIGN_UP(sizeof(ot),PVOID)+(cb),t))
|
|
|
|
#define UL_ALLOCATE_STRUCT(pt,ot,t) \
|
|
(ot *)(UL_ALLOCATE_POOL(pt,sizeof(ot),t))
|
|
|
|
#define UL_ALLOCATE_ARRAY(pt,et,c,t) \
|
|
(et *)(UL_ALLOCATE_POOL(pt,sizeof(et)*(c),t))
|
|
|
|
#define UL_FREE_POOL_WITH_SIG(a,t) \
|
|
do { \
|
|
(a)->Signature = MAKE_FREE_TAG(t); \
|
|
UL_FREE_POOL(a,t); \
|
|
(a) = NULL; \
|
|
} while (0)
|
|
|
|
#endif // _DEBUG_H_
|
|
|