debug.h

来自「用于查询PC机上的USB端口是否有设备挂接上」· C头文件 代码 · 共 1,471 行 · 第 1/3 页

H
1,471
字号
;
;   Assert_Cur_VM_Handle (Register)
;
;   DESCRIPTION:
;
;   ENTRY:
;
;   EXIT:
;
;   USES:
;
;==============================================================================
;
; Optimized for the case R = ebx, since that is by far the most common case.

Assert_Cur_VM_Handle MACRO R, DL
	LOCAL	OK
	LOCAL myDebLevel

IF DEBLEVEL GT DEBLEVELRETAIL

IFB <DL>
	myDebLevel = DEBLEVELNORMAL
ELSE
	myDebLevel = DL
ENDIF

IF DEBLEVEL GE myDebLevel

IFDIFI <ebx>,<R>
	push	ebx
	mov	ebx, R
ENDIF
	VMMCall Debug_Test_Cur_VM
IFDIFI <ebx>,<R>
	pop	ebx
ENDIF

ENDIF

ENDIF
	ENDM


Assert_Client_Ptr MACRO Reg, DL
	LOCAL myDebLevel
IF DEBLEVEL GT DEBLEVELRETAIL

IFB <DL>
	myDebLevel = DEBLEVELNORMAL
ELSE
	myDebLevel = DL
ENDIF

IF DEBLEVEL GE myDebLevel
IFDIFI <ebp>,<Reg>
	push	ebp
	mov	ebp, Reg
ENDIF
	VMMCall Validate_Client_Ptr
IFDIFI <ebp>,<Reg>
	pop	ebp
ENDIF
ENDIF

ENDIF
	ENDM

endif ;* Not_VxD *


;******************************************************************************
;
;	TRAP
;
;------------------------------------------------------------------------------


;	Create the following macros:
;
;	TRAPs, TRAPns, TRAPc, TRAPnc, TRAPa, TRAPna, TRAPae, TRAPnae,
;	TRAPb, TRAPnb, TRAPbe, TRAPnbe, TRAPe, TRAPne, TRAPz, TRAPnz,
;	TRAPg, TRAPng, TRAPge, TRAPnge, TRAPl, TRAPnl, TRAPle, TRAPnle,
;	TRAPo, TRAPno
;
;	TRAPFATALs, TRAPFATALns, TRAPFATALc, TRAPFATALnc, TRAPFATALa,
;	TRAPFATALna, TRAPFATALae, TRAPFATALnae, TRAPFATALb, TRAPFATALnb,
;	TRAPFATALbe, TRAPFATALnbe, TRAPFATALe, TRAPFATALne, TRAPFATALz,
;	TRAPFATALnz, TRAPFATALg, TRAPFATALng, TRAPFATALge, TRAPFATALnge,
;	TRAPFATALl, TRAPFATALnl, TRAPFATALle, TRAPFATALnle, TRAPFATALo,
;	TRAPFATALno

irp	cond,<s,c,a,ae,b,be,e,z,g,ge,l,le,o>

TRAP&cond &macro
	?trap	jn&cond
	&endm

TRAPn&cond &macro
	?trap	j&cond
	&endm

TRAPFATAL&cond &macro
	?trap	jn&cond, FATAL
	&endm

TRAPFATALn&cond &macro
	?trap	j&cond, FATAL
	&endm
endm

TRAP	macro
if DEBLEVEL GT DEBLEVELRETAIL
	int	3
endif
	endm

TRAPFATAL	macro
	local	l
if DEBLEVEL GT DEBLEVELRETAIL
l:	int	3
	jmp	short l
endif
	endm

TRAPecxz macro
	local	l1,l2
if DEBLEVEL GT DEBLEVELRETAIL
	jecxz	l1
	jmp	short l2
l1:	int	3
l2:
endif
	endm

TRAPecxnz macro
	?trap	jecxz
	endm

?trap	macro	jmpop, fatal
	Local	l, n
if DEBLEVEL GT DEBLEVELRETAIL
	jmpop	short n
l:	int	3
ifnb	<fatal>
	jmp	short l
endif
n:
endif
	endm

ifndef Not_VxD

;******************************************************************************


Dump_Struc_Head MACRO
if DEBLEVEL GT DEBLEVELRETAIL
	Trace_Out "  Base    Address   Offs     Value  Field name"
ENDIF
	ENDM

Dump_Struc MACRO Base, X
if DEBLEVEL GT DEBLEVELRETAIL
	pushfd
	pushad
	lea	esi, [Base]
	mov	ecx, X
	lea	edx, [esi+ecx]

IF SIZE X EQ 6
	mov	bx, WORD PTR [edx+4]
	mov	eax, DWORD PTR [edx]
	Trace_Out "#ESI  #EDX  #CX  #BX:#EAX  &X"
ELSE
IF SIZE X EQ 4
	mov	eax, DWORD PTR [edx]
	Trace_Out "#ESI  #EDX  #CX  #EAX  &X"
ELSE
IF SIZE X EQ 2
	mov	ax, WORD PTR [edx]
	Trace_Out "#ESI  #EDX  #CX      #AX  &X"
ELSE
	mov	al, BYTE PTR [edx]
	Trace_Out "#ESI  #EDX  #CX        #AL  &X"
ENDIF
ENDIF
ENDIF

	popad
	popfd
ENDIF
	ENDM

BeginDoc
;******************************************************************************
;
;   Begin_Touch_1st_Meg / End_Touch_1st_Meg
;
;   DESCRIPTION:
;	These macros should be used by VxDs that need to touch memory in
;	the 1st megabyte.  For example, if a VxD wanted to examine interrupt
;	vector 21h, the code would look like this:
;
;	    Begin_Touch_1st_Meg
;	    mov     eax, DWORD PTR ds:[21h*4]
;	    End_Touch_1st_Meg
;
;	When building retail VxDs, these macros generate no code.  When
;	building debug VxDs these macros generate calls to Enable_Touch_1st_Meg
;	and Disable_Touch_1st_Meg.
;
;   ENTRY:
;	None
;
;   EXIT:
;	None
;
;   USES:
;	Nothing
;
;==============================================================================
EndDoc

Begin_Touch_1st_Meg MACRO DL
	LOCAL myDebLevel
IF DEBLEVEL GT DEBLEVELRETAIL
IFB <DL>
	myDebLevel = DEBLEVELMAX
ELSE
	myDebLevel = DL
ENDIF
IF DEBLEVEL GE myDebLevel
	VMMCall Enable_Touch_1st_Meg
ENDIF
ENDIF
	ENDM

;------------------------------------------------------------------------------

End_Touch_1st_Meg MACRO DL
	LOCAL myDebLevel
IF DEBLEVEL GT DEBLEVELRETAIL
IFB <DL>
	myDebLevel = DEBLEVELMAX
ELSE
	myDebLevel = DL
ENDIF
IF DEBLEVEL GE myDebLevel
	VMMCall Disable_Touch_1st_Meg
ENDIF
ENDIF
	ENDM

endif ;* Not_VxD *
*/

/* XLATON */
/******************************************************************************
 *
 *   TrashThis
 *
 *  DESCRIPTION:
 *
 *	In DEBUG, trashes a register or variable to ensure that the
 *	caller is not relying on its value being preserved, or containing
 *	any particular value.  Does nothing in RETAIL.
 *
 *	Procedures that use the C calling convention should trash the
 *	ECX and EDX registers (and possibly also EAX) on exit, as well
 *	as all the stack parameters.
 *
 *  PARAMETERS:
 *
 *  C:
 *	TrashThis1(a) - destroy variable `a'
 *	TrashThis2(a,b) - destroy variables `a' and `b'
 *	 ...
 *
 *  Asm:
 *	l - list of registers or variables to munge
 *	    More efficient code is generated if the first element of `l'
 *	    is a register, because that register will be used to trash
 *	    the other values.
 *
 *****************************************************************************/

/* XLATOFF */

#ifdef	DEBUG
#define TrashThis1(a) (*(PULONG)&(a) |= 0xFFFFFF80)
#define TrashThis2(a,b) (TrashThis1(a), TrashThis1(b))
#define TrashThis3(a,b,c) (TrashThis1(a), TrashThis2(b,c))
#define TrashThis4(a,b,c,d) (TrashThis1(a), TrashThis3(b,c,d))
#else
#define TrashThis1(a)
#define TrashThis2(a,b)
#define TrashThis3(a,b,c)
#define TrashThis4(a,b,c,d)
#endif

/* XLATON */

/* ASM
IFDEF	DEBUG
TrashThis Macro	l:vararg
    ?TrashThisVal equ <0FFFFFF80h>
    ?TrashThisValSet = 0
    for r, <l>
	or	r, ?TrashThisVal	; Mangle the value
      ife ?TrashThisValSet
        if (OPATTR r) and 10h		; If is a register
	    ?TrashThisVal equ <r>	; use it to mangle others
	    ?TrashThisValSet = 1
	endif
      endif
    endm
endm
ELSE
TrashThis Macro	l:vararg
endm
ENDIF

*/



#ifndef Not_VxD

/*XLATOFF*/
#if DEBLEVEL >= DEBLEVELMAX

#define	Begin_Touch_1st_Meg()	Enable_Touch_1st_Meg()
#define	End_Touch_1st_Meg()	Disable_Touch_1st_Meg()

#else

#define	Begin_Touch_1st_Meg()
#define	End_Touch_1st_Meg()

#endif
/*XLATON*/

/*
 *  Macros for the _Debug_Flags_Service service.
 *
 *  Place ENTER_NOBLOCK at the beginning of a section of code
 *  that must not block and EXIT_NOBLOCK.  Between the two, any
 *  code that might block (e.g., accessing pageable code or data,
 *  blocking on a semaphore) will trigger an assertion failure.
 *
 *  You can use the Assert_Might_Block macro to force the above
 *  check to be made.
 *
 *  Assert_Not_Nest_Exec checks that the current thread is not
 *  in nested execution.
 *
 */

/* ASM

if DEBLEVEL GT DEBLEVELRETAIL

ENTER_NOBLOCK MACRO
	push	DFS_ENTER_NOBLOCK
	VMMCall _Debug_Flags_Service
	ENDM

EXIT_NOBLOCK MACRO
	push	DFS_EXIT_NOBLOCK
	VMMCall _Debug_Flags_Service
	ENDM

Assert_CLD MACRO
	pushfd
	test	dword ptr [esp], DF_MASK
	Debug_OutNZ "Direction flag is not clear."
	popfd
	ENDM

Assert_Might_Block MACRO
	push	DFS_TEST_BLOCK
	VMMCall _Debug_Flags_Service
	ENDM

Assert_Not_Nest_Exec MACRO
	push	DFS_TEST_NEST_EXEC
	VMMCall _Debug_Flags_Service
	ENDM

ELSE					; in retail, everything is a NOP

ENTER_NOBLOCK EQU <>
EXIT_NOBLOCK EQU <>
Assert_CLD EQU <>
Assert_Might_Block EQU <>
Assert_Not_Nest_Exec EQU <>

ENDIF ; DEBLEVEL GT DEBLEVELRETAIL

*/

//XLATOFF
#if DEBLEVEL > DEBLEVELRETAIL

#define ENTER_NOBLOCK() 	_Debug_Flags_Service(DFS_ENTER_NOBLOCK)
#define EXIT_NOBLOCK() 		_Debug_Flags_Service(DFS_EXIT_NOBLOCK)
#define Assert_CLD()		_Debug_Flags_Service(DFS_TEST_CLD)
#define Assert_Might_Block()	_Debug_Flags_Service(DFS_TEST_BLOCK)
#define Assert_Not_Nest_Exec()  _Debug_Flags_Service(DFS_TEST_NEST_EXEC)

/******************************************************************************
BeginDoc
 *
 *  BeginCProc
 *
 *  DESCRIPTION:
 *	This macro inserts inline assembly code to validate the current
 *	machine state, in the same manner that BeginProc does for assembly.
 *
 *	The following flags are supplied by default.
 *
 *	    DFS_LOG
 *	    DFS_TEST_CLD
 *
 *	You may combine any of the following flags.
 *
 *	   -DFS_LOG		// note minus sign!
 *	    DFS_NEVER_REENTER
 *	    DFS_TEST_REENTER
 *	   -DFS_TEST_CLD	// note minus sign!
 *	    DFS_NOT_SWAPPING
 *	    DFS_TEST_BLOCK
 *
 *  EXAMPLES:
 *
 *	BeginCProc(0);			// use the defaults
 *
 *	BeginCProc(DFS_TEST_REENTER);	// also check VMM reentrancy
 *
 *	BeginCProc(-DFS_LOG);		// don't log this procedure
 *
 *	BeginCProc(DFS_TEST_REENTER-DFS_LOG);
 *					// check VMM reentrancy, but don't log
 *
EndDoc
 *****************************************************************************/


#define BeginCProc(f) _Debug_Flags_Service(f+DFS_LOG+DFS_TEST_CLD)

#else					// in retail, everything is a NOP

#define ENTER_NOBLOCK()
#define EXIT_NOBLOCK()
#define Assert_CLD()
#define Assert_Might_Block()
#define Assert_Not_Nested_Exec()
#define BeginCProc(f)

#endif
//XLATON

#ifdef Begin_Service_Table		// define only if vmm.h is included

//XLATOFF
#define	DEBUG_Service	Declare_Service
#pragma warning (disable:4003)		// turn off not enough params warning
//XLATON

//MACROS
Begin_Service_Table(DEBUG)

DEBUG_Service	(DEBUG_Get_Version, LOCAL)
DEBUG_Service	(DEBUG_Fault, LOCAL)
DEBUG_Service	(DEBUG_CheckFault, LOCAL)
DEBUG_Service	(_DEBUG_LoadSyms)

End_Service_Table(DEBUG)
//ENDMACROS

//XLATOFF
#pragma warning (default:4003)		// turn on not enough params warning
//XLATON

#endif // Begin_Service_Table

#endif // Not_VxD

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?