228 lines
7.4 KiB
C
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_
|