Windows2000/private/ntos/io/ioassert.h

228 lines
7.4 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
ioassert.h
Abstract:
This module implements some useful assertion routines
Author:
Adrian J. Oney (adriao) 20-Apr-1998
*/
#ifndef _IOASSERT_H_
#define _IOASSERT_H_
#if defined(_WIN64)
#define NO_SPECIAL_IRP
#else
#undef NO_SPECIAL_IRP
#endif
#ifdef NO_SPECIAL_IRP
#define WDM_CHASTISE_CALLER3(x)
#define WDM_CHASTISE_CALLER5(x)
#define WDM_CHASTISE_ROUTINE(x)
#define WDM_FAIL_CALLER(x, depth)
#define WDM_FAIL_CALLER1(x)
#define WDM_FAIL_CALLER2(x)
#define WDM_FAIL_CALLER3(x)
#define WDM_FAIL_CALLER4(x)
#define WDM_FAIL_CALLER5(x)
#define WDM_FAIL_CALLER6(x)
#define WDM_FAIL_ROUTINE(x)
#define KDASSERT(x)
#define ASSERT_SPINLOCK_HELD(x)
#else // NO_SPECIAL_IRP
extern LONG IovpInitCalled;
extern ULONG IovpVerifierLevel;
extern ULONG IovpEnforcementLevel;
extern ULONG IopDcControlInitial;
extern ULONG IopDcControlOverride;
extern KSPIN_LOCK IopDcControlLock;
typedef enum _DCERROR_ID {
DCERROR_UNSPECIFIED = 0x200,
DCERROR_DELETE_WHILE_ATTACHED,
DCERROR_DETACH_NOT_ATTACHED,
DCERROR_CANCELROUTINE_FORWARDED,
DCERROR_NULL_DEVOBJ_FORWARDED,
DCERROR_QUEUED_IRP_FORWARDED,
DCERROR_NEXTIRPSP_DIRTY,
DCERROR_IRPSP_COPIED,
DCERROR_INSUFFICIENT_STACK_LOCATIONS,
DCERROR_QUEUED_IRP_COMPLETED,
DCERROR_FREE_OF_INUSE_TRACKED_IRP,
DCERROR_FREE_OF_INUSE_IRP,
DCERROR_FREE_OF_THREADED_IRP,
DCERROR_REINIT_OF_ALLOCATED_IRP_WITH_QUOTA,
DCERROR_PNP_IRP_BAD_INITIAL_STATUS,
DCERROR_POWER_IRP_BAD_INITIAL_STATUS,
DCERROR_WMI_IRP_BAD_INITIAL_STATUS,
DCERROR_SKIPPED_DEVICE_OBJECT,
DCERROR_BOGUS_FUNC_TRASHED,
DCERROR_BOGUS_STATUS_TRASHED,
DCERROR_BOGUS_INFO_TRASHED,
DCERROR_PNP_FAILURE_FORWARDED,
DCERROR_PNP_IRP_STATUS_RESET,
DCERROR_PNP_IRP_NEEDS_FDO_HANDLING,
DCERROR_PNP_IRP_FDO_HANDS_OFF,
DCERROR_POWER_FAILURE_FORWARDED,
DCERROR_POWER_IRP_STATUS_RESET,
DCERROR_INVALID_STATUS,
DCERROR_UNNECCESSARY_COPY,
DCERROR_SHOULDVE_DETACHED,
DCERROR_SHOULDVE_DELETED,
DCERROR_MISSING_DISPATCH_FUNCTION,
DCERROR_WMI_IRP_NOT_FORWARDED,
DCERROR_DELETED_PRESENT_PDO,
DCERROR_BUS_FILTER_ERRONEOUSLY_DETACHED,
DCERROR_BUS_FILTER_ERRONEOUSLY_DELETED,
DCERROR_INCONSISTANT_STATUS,
DCERROR_UNINITIALIZED_STATUS,
DCERROR_IRP_RETURNED_WITHOUT_COMPLETION,
DCERROR_COMPLETION_ROUTINE_PAGABLE,
DCERROR_PENDING_BIT_NOT_MIGRATED,
DCERROR_CANCELROUTINE_ON_FORWARDED_IRP,
DCERROR_PNP_IRP_NEEDS_PDO_HANDLING,
DCERROR_TARGET_RELATION_LIST_EMPTY,
DCERROR_TARGET_RELATION_NEEDS_REF,
DCERROR_BOGUS_PNP_IRP_COMPLETED,
DCERROR_SUCCESSFUL_PNP_IRP_NOT_FORWARDED,
DCERROR_UNTOUCHED_PNP_IRP_NOT_FORWARDED,
DCERROR_BOGUS_POWER_IRP_COMPLETED,
DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED,
DCERROR_UNTOUCHED_POWER_IRP_NOT_FORWARDED,
DCERROR_PNP_QUERY_CAP_BAD_VERSION,
DCERROR_PNP_QUERY_CAP_BAD_SIZE,
DCERROR_PNP_QUERY_CAP_BAD_ADDRESS,
DCERROR_PNP_QUERY_CAP_BAD_UI_NUM,
DCERROR_RESTRICTED_IRP,
DCERROR_REINIT_OF_ALLOCATED_IRP_WITHOUT_QUOTA,
DCERROR_UNFORWARDED_IRP_COMPLETED,
DCERROR_DISPATCH_CALLED_AT_BAD_IRQL,
DCERROR_BOGUS_MINOR_STATUS_TRASHED,
DCERROR_MAXIMUM
} DCERROR_ID ;
#define DIAG_INITIALIZED 0x00000001
#define DIAG_BEEP 0x00000002
#define DIAG_ZAPPED 0x00000004
#define DIAG_CLEARED 0x00000008
#define DIAG_FATAL_ERROR 0x00000010
#define DIAG_WDM_ERROR 0x00000020
#define DIAG_IGNORE_DRIVER_LIST 0x00000040
#define DCPARAM_IRP 0x00000001
#define DCPARAM_ROUTINE 0x00000008
#define DCPARAM_DEVOBJ 0x00000040
#define DCPARAM_STATUS 0x00000200
#define _DC_ASSERT_OUT(ParenWrappedParamList, Frames) \
{ \
static ULONG Flags=0 ; \
if (IovpInitCalled) { \
IopDriverCorrectnessTakeLock(&Flags, Frames) ;\
IopDriverCorrectnessCheckUnderLock##ParenWrappedParamList;\
IopDriverCorrectnessReleaseLock() ;\
} \
}
// These macro's allow printf style debug output. They are invoked
// as follows (the excess parathesis's are required):
// WDM_FAIL_CALLER3(("Foo=%x",FooValue), irp) ;
#define WDM_CHASTISE_CALLER3(x) _DC_ASSERT_OUT(x, 3)
#define WDM_CHASTISE_CALLER5(x) _DC_ASSERT_OUT(x, 5)
#define WDM_FAIL_CALLER(x, depth) _DC_ASSERT_OUT(x, depth)
#define WDM_FAIL_CALLER1(x) _DC_ASSERT_OUT(x, 1)
#define WDM_FAIL_CALLER2(x) _DC_ASSERT_OUT(x, 2)
#define WDM_FAIL_CALLER3(x) _DC_ASSERT_OUT(x, 3)
#define WDM_FAIL_CALLER4(x) _DC_ASSERT_OUT(x, 4)
#define WDM_FAIL_CALLER5(x) _DC_ASSERT_OUT(x, 5)
#define WDM_FAIL_CALLER6(x) _DC_ASSERT_OUT(x, 6)
#define WDM_FAIL_ROUTINE(x) _DC_ASSERT_OUT(x, -1)
#define WDM_CHASTISE_ROUTINE(x) _DC_ASSERT_OUT(x, -1)
#define KDASSERT(x) { if (KdDebuggerEnabled) { ASSERT(x) ; } }
#define ASSERT_SPINLOCK_HELD(x)
// From here to #else is for use of ioassert.c only
VOID IopDriverCorrectnessTakeLock(IN PULONG ControlNew, IN LONG StackFramesToSkip);
NTSTATUS IopDriverCorrectnessCheckUnderLock(
IN DCERROR_ID MessageIndex,
IN ULONG MessageParameterMask,
...
);
VOID IopDriverCorrectnessReleaseLock(VOID);
// This structure and the table using it define the types and ordering of
// IopDriverCorrectnessCheck (see this function for a more detailed explanation)
typedef struct _DCPARAM_TYPE_ENTRY {
ULONG DcParamMask;
PSTR DcParamName;
} DCPARAM_TYPE_ENTRY, *PDCPARAM_TYPE_ENTRY;
// Internal structures used in the buildup of a correctness check.
typedef struct _DCERROR_CLASS {
ULONG ClassFlags;
PSTR MessageClassText;
} DCERROR_CLASS, *PDCERROR_CLASS;
typedef const PDCERROR_CLASS PCDCERROR_CLASS;
typedef struct _DC_CHECK_DATA {
PULONG Control;
ULONG AssertionControl;
ULONG TableIndex;
DCERROR_ID MessageID;
PVOID CulpritAddress;
ULONG_PTR OffsetIntoImage;
UNICODE_STRING DriverName;
PDCERROR_CLASS AssertionClass;
PVOID *DcParamArray;
PSTR ClassText;
PSTR AssertionText;
BOOLEAN InVerifierList;
} DC_CHECK_DATA, *PDC_CHECK_DATA;
NTSTATUS
IopDriverCorrectnessProcessMessageText(
IN ULONG MaxOutputBufferSize,
OUT PSTR OutputBuffer,
IN OUT PDC_CHECK_DATA DcCheckData
);
VOID
IopDriverCorrectnessProcessParams(
IN OUT PULONG Control OPTIONAL,
IN LONG StackFramesToSkip,
IN DCERROR_ID MessageID,
IN ULONG MessageParameterMask,
IN va_list * MessageParameters,
IN PVOID * DcParamArray,
OUT PDC_CHECK_DATA DcCheckData
);
BOOLEAN IopDriverCorrectnessApplyControl(IN OUT PDC_CHECK_DATA DcCheckData);
VOID IopDriverCorrectnessThrowBugCheck(IN PDC_CHECK_DATA DcCheckData);
VOID IopDriverCorrectnessPrintBuffer(IN PDC_CHECK_DATA DcCheckData);
VOID IopDriverCorrectnessPrintParamData(IN PDC_CHECK_DATA DcCheckData);
VOID IopDriverCorrectnessPrintIrp(IN PIRP IrpToFlag);
VOID IopDriverCorrectnessPrintIrpStack(IN PIO_STACK_LOCATION IrpSp);
VOID IopDriverCorrectnessPrompt(IN PDC_CHECK_DATA DcCheckData, OUT PBOOLEAN ExitAssertion);
PVOID IopDriverCorrectnessAddressToFileHeader(IN PVOID PcValue, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry);
BOOLEAN IopIsMemoryRangeReadable(IN PVOID Location, IN size_t Length);
#endif // NO_SPECIAL_IRP
#endif // _IOASSERT_H_