debug.h
来自「用于查询PC机上的USB端口是否有设备挂接上」· C头文件 代码 · 共 1,471 行 · 第 1/3 页
H
1,471 行
/*****************************************************************************
*
* (C) Copyright MICROSOFT Corp. 1989-1990
*
*****************************************************************************/
#define NOBUGBUG 1
// XLATOFF
#if DEBLEVEL > DEBLEVELRETAIL
#ifndef Not_VxD
#ifdef WIN31COMPAT
#define Debug_Out(str) {Out_Debug_String(str "\r\n"); _asm {int 1}}
#define Trace_Out(str) {Out_Debug_String(str "\r\n");}
#else // not WIN31COMPAT
#define Debug_Out(str) {_Debug_Out_Service(str "\r\n");}
#define Trace_Out(str) {_Trace_Out_Service(str "\r\n");}
#define Debug_Printf _Debug_Printf_Service
#endif // WIN31COMPAT
#define Debug_OutC(cond, str) {if(cond) {Debug_Out(str)}}
#define Trace_OutC(cond, str) {if(cond) {Trace_Out(str)}}
#endif // Not_VxD
#define STATIC
#define Trap() {_asm {_emit 0xcc}}
#define TrapC(cond) {if(cond) {Trap()}}
#define TrapFatal() {_asm { \
_asm _emit 0xcc \
_asm _emit 0xeb \
_asm _emit 0xfd}}
#define TrapFatalC(cond) {if(cond) {TrapFatal()}}
#else // DEBLEVEL > DEBLEVELRETAIL
#ifndef Not_VxD
#define Debug_Out(str)
#define Trace_Out(str)
#define Debug_OutC(cond, str)
#define Trace_OutC(cond, str)
#define Debug_Printf()
#endif // Not_VxD
#define STATIC static
#define Trap()
#define TrapC(cond)
#define TrapFatal()
#define TrapFatalC(cond)
#endif // DEBLEVEL > DEBLEVELRETAIL
#ifndef Not_VxD
#if DEBLEVEL >= DEBLEVELMAX
#define Trace_Out_DebMax(str) Trace_Out(str)
#define Debug_Out_DebMax(str) Debug_Out(str)
#define Trace_OutC_DebMax(cond, str) Trace_OutC(cond, str)
#define Debug_OutC_DebMax(cond, str) Debug_OutC(cond, str)
#define Debug_Printf_DebMax _Debug_Printf_Service
#define Assert_VM_Handle_DebMax(hvm) Assert_VM_Handle(hvm)
#else
#define Trace_Out_DebMax(str)
#define Debug_Out_DebMax(str)
#define Trace_OutC_DebMax(cond, str)
#define Debug_OutC_DebMax(cond, str)
#define Debug_Printf_DebMax()
#define Assert_VM_Handle_DebMax(hvm)
#endif
#ifdef DEBUG
#define Queue_Out(sz, uleax, ulebx) Queue_Debug_String(sz "\r\n", uleax, ulebx)
#else
#define Queue_Out(sz, uleax, ulebx)
#endif // DEBUG
#ifdef WIN31COMPAT
#define Assert_VM_Handle(hvm) (VMM_TRUE)
#else
#define Assert_VM_Handle(hvm) Debug_OutC(((struct cb_s *)hvm)->CB_Signature != VMCB_ID, "Assert_VM_Handle failed")
#endif
#ifdef WIN31COMPAT
#define Assert_Thread_Handle(ptcb)
#else
#define Assert_Thread_Handle(ptcb) Debug_OutC(((struct tcb_s *)ptcb)->TCB_Signature != SCHED_OBJ_ID_THREAD, "Assert_Thread_Handle failed")
#endif
#endif // Not_VxD
#define BUGBUG(d, id, note)
#define IsDebugOnlyLoaded(pvar) (((unsigned long)(pvar)) <= MAXSYSTEMLADDR)
#ifdef DEBUG
#define Assert_FS VMMCall(Assert_FS_Service)
#else
#define Assert_FS
#endif
// XLATON
/* ASM
Assert_FS macro
ifdef DEBUG
VMMCall Assert_FS_Service
endif
endm
;*** BUGBUG - Document incomplete code, temporary assumptions, etc
;
; ENTRY d - date
; id - your email ID (eg, JeffPar)
; note - a few words about the problem, assumption, etc,
; in brackets (<>)
;
; NOBUGBUG Disables BUGBUG messages
; ERRBUGBUG Forces compilation error if any BUGBUGs exist
BUGBUG macro d, id, note
ifb <d>
%out Bad date in BUGBUG
.err
endif
ifb <id>
%out Bad email id in BUGBUG
.err
endif
ifndef NOBUGBUG
%out BUGBUG d id: note
endif
ifdef ERRBUGBUG
.err
endif
endm
;*** IsDebugOnlyLoaded
;
; ENTRY lab - label to jump if NOT loaded if not blank
;
; EXIT: jumps to label, if given, if debug only segment is NOT loaded
; ZF is clear if debug-only segment IS loaded
;
; USES: flags
;
; The code we generate is
;
; test [magic_address], magic_operand
; ifnb <lab>
; jz lab
; endif
;
; where magic_address is the address of magic_operand. Essentially,
; we are `test'ing an immediate constant with itself.
;
; If the debug-only segment is not loaded, the magic_operand
; will be zero, because _DB0START is placed at exactly
; MAXSYSTEMLADDR + 1 in the no-debug-only case.
;
; If the debug-only segment is loaded, the magic_operand will
; be nonzero because it will be offset of the actual debug-only
; segment (relative to MAXSYSTEMLADDR + 1).
;
; Unfortunately, RaymondC's clever version doesn't work with
; the linker that ships with C9, C10, etc. There are two problems:
;
; (1) The linker sorts segments in a group alphabetically instead of
; leaving them in the order in which they're defined. This
; used to put _DBOSTART last, so its starting address was *not*
; MAXSYSTEMLADDR + 1. Renaming it to _DB0START fixed this
; problem.
; (2) The linker does not always do the right thing with empty
; segments. In particular, if I defined "var" as a label in
; _DB1CODE with no bytes associated with it, its offset wasn't
; calculated properly for the "mov" below.
IsDebugOnlyLoaded macro lab
local var, magic
ifdef BLD_COFF
_DB1CODE segment
var db ?
_DB1CODE ends
push eax ; Save user's register
mov eax,OFFSET32 var ; (EAX) = address of dummy variable
cmp eax,MAXSYSTEMLADDR ; Does it reside in system space?
ifb <lab>
setbe al ; yes, (AL) = 1; no, (AL) = 0
or al,al ; yes, ZF clear; no, ZF set
endif
pop eax ; Restore user's register
ifnb <lab>
ja lab ; no, jump to given label
endif
else
_DB0START segment
var label byte
_DB0START ends
db 0F7h, 05h ; test memory absolute with immediate
dd OFFSET32 magic ; magic_address
magic dd OFFSET32 var - (MAXSYSTEMLADDR + 1) ; magic_operand
ifnb <lab>
jz lab
endif
endif
endm
;** DPublic - Make a public symbol for debugging
;
; A lot of debuggers only work with public symbols. This macro
; allows us to declare them public in debug mode but doesn't
; litter the distributed .OBJ files with symbols which
; 1) waste space, and
; 2) facilitate reverse engineering of DOS
DPublic MACRO arg
if DEBLEVEL GT DEBLEVELRETAIL
public arg
endif
ENDM
;******************************************************************************
;
; Assumes_Fall_Through
;
; DESCRIPTION:
; Used for debugging purposes only. It will generate an error if
; the IP <> the specified label.
;
; PARAMETERS:
; Label_Name = Name of label to fall-through to
;
;------------------------------------------------------------------------------
Assumes_Fall_Through MACRO L
ifndef MASM6
IF2
IFDEF profileall
IF (?prolog_&L - $) GT 3
%OUT ERROR: Fall through to &L invalid
.ERR
ENDIF
ELSE
IF (L - $) GT 3
%OUT ERROR: Fall through to &L invalid
.ERR
ENDIF
ENDIF
ENDIF
else
IFDEF profileall
.errnz ((?prolog_&L - $) GT 3), <ERROR: Fall through to &L invalid>
ELSE
.errnz ((L - $) GT 3), <ERROR: Fall through to &L invalid>
ENDIF
endif ; not MASM6
ENDM
ifndef Not_VxD
;******************************************************************************
;
; Assert_VM_Handle
;
; PARAMETERS:
; Handle_Register = Register that contains a VM handle
; MinDebugLevel = Validate only if debug level is this level or higher
; (default = DEBLEVELNORMAL)
; fUsesFlags = the symbol "USES_FLAGS" if the macro is permitted
; to damage flags
;
; ASSUMES:
; Debug_Test_Valid_Handle does not destroy any registers or flags
; unless USES_FLAGS is set, in which case flags are modified
;
; EXIT:
; NOTHING MODIFIED (not even flags)
; unless USES_FLAGS is set, in which case flags are modified
;
;------------------------------------------------------------------------------
;
; Optimized for the case R = ebx, since that is by far the most common case.
;
; If DEBLEVELRETAIL: Do nothing
; If DEBLEVELNORMAL: Expand in-line for fast validation
; If DEBLEVELMAX: Call into VMM for full validation
;
??avh_parse_one_arg macro arg
ifidni <arg>, <USES_FLAGS>
??_fUsesFlagsPushfd equ <> ; Don't need to preserve flags
??_fUsesFlagsPopfd equ <>
elseifnb <arg>
??_debLevel = arg
endif
endm
??avh_parse_args macro DL, fUSES_FLAGS
??_fUsesFlagsPushfd equ <pushfd> ; Preserve flags by default
??_fUsesFlagsPopfd equ <popfd>
??_debLevel = DEBLEVELNORMAL ; Default deblevel
??avh_parse_one_arg <DL>
??avh_parse_one_arg <fUSES_FLAGS>
endm
Assert_VM_Handle MACRO R, DL, fUSES_FLAGS
LOCAL l1
IF DEBLEVEL GT DEBLEVELRETAIL
??avh_parse_args <DL>, <fUSES_FLAGS>
IF DEBLEVEL GE ??_debLevel
IFNDEF WIN31COMPAT
IF DEBLEVEL LT DEBLEVELMAX
??_fUsesFlagsPushfd
cmp [R].CB_Signature, VMCB_ID
je SHORT l1
ENDIF
ENDIF
IFDIFI <ebx>,<R>
push ebx
mov ebx, R
ENDIF
VMMCall Debug_Test_Valid_Handle
IFDIFI <ebx>, <R>
pop ebx
ENDIF
IFNDEF WIN31COMPAT
IF DEBLEVEL LT DEBLEVELMAX
l1:
??_fUsesFlagsPopfd
ENDIF
ENDIF
ENDIF
ENDIF
ENDM
;******************************************************************************
;
; Assert_Thread_Handle
;
; PARAMETERS:
; Handle_Register = Register that contains a thread handle
; MinDebugLevel = Validate only if debug level is this level or higher
; (default = DEBLEVELNORMAL)
; fUsesFlags = the symbol "USES_FLAGS" if the macro is permitted
; to damage flags
;
; ASSUMES:
; Debug_Test_Valid_Thread_Handle does not destroy any registers or flags
; unless USES_FLAGS is set, in which case flags are modified
;
; EXIT:
; NOTHING MODIFIED (not even flags)
; unless USES_FLAGS is set, in which case flags are modified
;
;------------------------------------------------------------------------------
;
; Optimized for the case R = edi, since that is by far the most common case.
;
; If DEBLEVELRETAIL: Do nothing
; If DEBLEVELNORMAL: Expand in-line for fast validation
; If DEBLEVELMAX: Call into VMM for full validation
Assert_Thread_Handle MACRO R, DL, fUSES_FLAGS
LOCAL l1
IF DEBLEVEL GT DEBLEVELRETAIL
??avh_parse_args <DL>, <fUSES_FLAGS>
IF DEBLEVEL GE ??_debLevel
IF DEBLEVEL LT DEBLEVELMAX
??_fUsesFlagsPushfd
cmp dword ptr [R.TCB_Signature], SCHED_OBJ_ID_THREAD
je SHORT l1
ENDIF
IFDIFI <edi>,<R>
push edi
mov edi, R
ENDIF
VMMCall Debug_Test_Valid_Thread_Handle
IFDIFI <edi>,<R>
pop edi
ENDIF
IF DEBLEVEL LT DEBLEVELMAX
l1:
??_fUsesFlagsPopfd
ENDIF
ENDIF
ENDIF
ENDM
;******************************************************************************
;
; Assert_Cur_Thread_Handle (Register)
;
; DESCRIPTION: Verifies that the register contains the current thread handle
;
; ENTRY:
;
; EXIT:
;
; USES:
;
;==============================================================================
;
; Optimized for the case R = edi, since that is by far the most common case.
Assert_Cur_Thread_Handle MACRO R, DL
LOCAL myDebLevel
LOCAL OK
IF DEBLEVEL GT DEBLEVELRETAIL
IFB <DL>
myDebLevel EQU DEBLEVELNORMAL
ELSE
myDebLevel EQU <DL>
ENDIF
IF DEBLEVEL GE myDebLevel
IFDIFI <edi>,<R>
push edi
mov edi, R
ENDIF
VMMCall Debug_Test_Cur_Thread
IFDIFI <edi>,<R>
pop edi
ENDIF
ENDIF
ENDIF
ENDM
;******************************************************************************
;
; Debug_Printf
;
; ENTRY: fmt - format string
; args - printf arguments enclosed with <>
; dl - optional DEBLEVEL
;
; USES: NONE
;
;------------------------------------------------------------------------------
Debug_Printf macro fmt, args, dl
local fmtlab, myDebLevel
ife ?_DBOCODE
??_fDoit = VMM_TRUE
else
??_fDoit = FALSE
endif
if DEBLEVEL GT DEBLEVELRETAIL
ifb <dl>
myDebLevel EQU <DEBLEVELNORMAL>
else
myDebLevel EQU <dl>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?