384 lines
13 KiB
C
384 lines
13 KiB
C
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright (C) 1996 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* File: debug.h
|
||
|
* Content: DirectInput debugging macros
|
||
|
*@@BEGIN_MSINTERNAL
|
||
|
* History:
|
||
|
* Date By Reason
|
||
|
* ==== == ======
|
||
|
* 1996.05.07 raymondc Somebody had to
|
||
|
*
|
||
|
*@@END_MSINTERNAL
|
||
|
*
|
||
|
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
||
|
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
||
|
* PURPOSE.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
|
||
|
#ifndef _INC_DEBUG
|
||
|
#define _INC_DEBUG
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C"
|
||
|
{
|
||
|
#endif
|
||
|
|
||
|
#ifdef XDEBUG
|
||
|
#define RD(x) x
|
||
|
#ifdef DEBUG
|
||
|
#define D(x) x
|
||
|
#else
|
||
|
#define D(x)
|
||
|
#endif
|
||
|
#else
|
||
|
#define RD(x)
|
||
|
#define D(x)
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* assert.c - Assertion stuff
|
||
|
*
|
||
|
* A sqfl is in multiple parts.
|
||
|
*
|
||
|
* The low word specifies the area that is generating the message.
|
||
|
*
|
||
|
* The high word contains flags that describe why this squirty
|
||
|
* is being generated.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
typedef enum {
|
||
|
/*
|
||
|
* Areas.
|
||
|
*/
|
||
|
sqflAlways = 0x0000, /* Unconditional */
|
||
|
sqflDll = 0x0001, /* Dll bookkeeping */
|
||
|
sqflFactory = 0x0002, /* IClassFactory */
|
||
|
sqflDi = 0x0003, /* IDirectInput */
|
||
|
sqflMouse = 0x0004, /* IDirectInputMouse */
|
||
|
sqflDev = 0x0005, /* IDirectInputDevice */
|
||
|
sqflKbd = 0x0006, /* IDirectInputKeyboard */
|
||
|
sqflDf = 0x0007, /* DataFormat goo */
|
||
|
sqflJoy = 0x0008, /* joystick device */
|
||
|
sqflEm = 0x0009, /* Emulation */
|
||
|
sqflSubclass = 0x000A, /* subclassing */
|
||
|
sqflCursor = 0x000B, /* Cursor show/hide */
|
||
|
sqflHel = 0x000C, /* Hardware emulation layer */
|
||
|
sqflLl = 0x000D, /* Low-level hooks */
|
||
|
sqflExcl = 0x000E, /* Exclusivity management */
|
||
|
sqflDEnum = 0x000F, /* Device enumeration */
|
||
|
sqflExtDll = 0x0010, /* External DLLs */
|
||
|
sqflHid = 0x0011, /* HID support */
|
||
|
sqflHidDev = 0x0012, /* HID device support */
|
||
|
sqflJoyCfg = 0x0013, /* IDirectInputJoyConfig */
|
||
|
sqflEff = 0x0014, /* IDirectInputEffect */
|
||
|
sqflOleDup = 0x0015, /* OLE duplication */
|
||
|
sqflEShep = 0x0016, /* IDirectInputEffectShepherd */
|
||
|
sqflJoyEff = 0x0017, /* Dummy DIEffectDriver */
|
||
|
sqflJoyReg = 0x0018, /* Joystick registry goo */
|
||
|
sqflVxdEff = 0x0019, /* VxD DIEffectDriver */
|
||
|
sqflNil = 0x001A, /* CNil and CDefDcb */
|
||
|
sqflHidUsage = 0x001B, /* HID usage mapping */
|
||
|
sqflUtil = 0x001C, /* Misc utility fns */
|
||
|
sqflObj = 0x001D, /* Object creation/destruction */
|
||
|
sqflCommon = 0x001E, /* common.c */
|
||
|
sqflHidParse = 0x001F, /* HID report parsing */
|
||
|
sqflCal = 0x0020, /* Axis calibrations */
|
||
|
sqflJoyType = 0x0021, /* Joystick type key */
|
||
|
sqflHidOutput = 0x0022, /* HID output reports */
|
||
|
sqflHidIni = 0x0023, /* HID device initialization */
|
||
|
sqflPort = 0x0024, /* GamePort Bus Enumuration */
|
||
|
sqflWDM = 0x0025, /* WDM specific Code */
|
||
|
sqflRegUtils = 0x0026, /* Registry utilities */
|
||
|
sqflCrit = 0x0027, /* Critical Section tracking */
|
||
|
sqflCompat = 0x0028, /* App Hacks */
|
||
|
sqflRaw = 0x0029, /* Raw Input - keyboard and mouse */
|
||
|
sqflMaxArea, /* Last area */
|
||
|
|
||
|
/*
|
||
|
* Flags which may be combined. For now, they all fit into a byte.
|
||
|
*/
|
||
|
sqflTrace = 0x00010000, /* Trace squirties */
|
||
|
sqflIn = 0x00020000, /* Function entry */
|
||
|
sqflOut = 0x00040000, /* Function exit */
|
||
|
sqflBenign = 0x00080000, /* Not a bad error */
|
||
|
sqflError = 0x00100000, /* A bad error */
|
||
|
sqflVerbose = 0x00200000, /* Really verbose */
|
||
|
sqflMajor = 0x00400000, /* Significant, generally positive, events */
|
||
|
} SQFL; /* squiffle */
|
||
|
|
||
|
void EXTERNAL WarnPszV(LPCSTR ptsz, ...);
|
||
|
void EXTERNAL SquirtSqflPtszV(SQFL sqfl, LPCTSTR ptsz, ...);
|
||
|
|
||
|
#ifndef DEBUG
|
||
|
#define SquirtSqflPtszV sizeof
|
||
|
#endif
|
||
|
|
||
|
#ifdef XDEBUG
|
||
|
#define RPF WarnPszV
|
||
|
#else
|
||
|
#define WarnPszV sizeof
|
||
|
#define RPF sizeof
|
||
|
#define s_szProc 0
|
||
|
#define iarg 0
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Buffer scrambling
|
||
|
*
|
||
|
* All output buffers should be scrambled on entry to any function.
|
||
|
*
|
||
|
* Each output bitmask should set an unused bit randomly to ensure
|
||
|
* that callers ignore bits that aren't defined.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#ifdef XDEBUG
|
||
|
|
||
|
void EXTERNAL ScrambleBuf(LPVOID pv, UINT cb);
|
||
|
void EXTERNAL ScrambleBit(LPDWORD pdw, DWORD flMask);
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define ScrambleBuf(pv, cb)
|
||
|
#define ScrambleBit(pdw, flRandom)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* Procedure enter/exit tracking.
|
||
|
*
|
||
|
* Start a procedure with
|
||
|
*
|
||
|
* EnterProc(ProcedureName, (_ "format", arg, arg, arg, ...));
|
||
|
* EnterProcS(ProcedureName, (_ "format", arg, arg, arg, ...));
|
||
|
* EnterProcI(ProcedureName, (_ "format", arg, arg, arg, ...));
|
||
|
* EnterProcR(ProcedureName, (_ "format", arg, arg, arg, ...));
|
||
|
*
|
||
|
* The format string is documented in EmitPal.
|
||
|
*
|
||
|
* Suffixing an "S" indicates that the macro should not generate
|
||
|
* a procedure name because there is a formal parameter with the
|
||
|
* name s_szProc. This is a hack.
|
||
|
*
|
||
|
* Suffixing an "R" indicates that the macro should generate a
|
||
|
* procedure name in RDEBUG.
|
||
|
*
|
||
|
* Suffixing an "I" indicates that the macro should emit a dummy
|
||
|
* procedure name in RDEBUG because the interface is internal.
|
||
|
*
|
||
|
* No suffix means that the macro should be active only in the
|
||
|
* DEBUG build and should vanish in RDEBUG (and RETAIL).
|
||
|
*
|
||
|
* End a procedure with one of the following:
|
||
|
*
|
||
|
* ExitProc();
|
||
|
*
|
||
|
* Procedure returns no value.
|
||
|
*
|
||
|
* ExitProcX();
|
||
|
*
|
||
|
* Procedure returns an arbitrary DWORD.
|
||
|
*
|
||
|
* ExitProcF();
|
||
|
*
|
||
|
* Procedure returns a BOOL, where FALSE is an error.
|
||
|
*
|
||
|
* ExitOleProc();
|
||
|
*
|
||
|
* Procedure returns an HRESULT (named "hres").
|
||
|
*
|
||
|
* ExitOleProcPpv(ppvOut);
|
||
|
*
|
||
|
* Procedure returns an HRESULT (named "hres") and, on success,
|
||
|
* puts a new object in ppvOut.
|
||
|
*
|
||
|
* The ExitBenign* versions consider any error to be benign.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#define cpvArgMax 10 /* Max of 10 args per procedure */
|
||
|
|
||
|
typedef struct ARGLIST {
|
||
|
LPCSTR pszProc;
|
||
|
LPCSTR pszFormat;
|
||
|
PV rgpv[cpvArgMax];
|
||
|
} ARGLIST, *PARGLIST;
|
||
|
|
||
|
void EXTERNAL ArgsPalPszV(PARGLIST pal, LPCSTR psz, ...);
|
||
|
void EXTERNAL EnterSqflPszPal(SQFL sqfl, LPCSTR psz, PARGLIST pal);
|
||
|
void EXTERNAL ExitSqflPalHresPpv(SQFL, PARGLIST, HRESULT, PPV);
|
||
|
void EXTERNAL Sqfl_Init(void);
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
|
||
|
extern BYTE g_rgbSqfl[sqflMaxArea];
|
||
|
|
||
|
BOOL INLINE
|
||
|
IsSqflSet(SQFL sqfl)
|
||
|
{
|
||
|
WORD wHi;
|
||
|
if (LOWORD(sqfl) == sqflAlways) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
wHi = HIWORD(sqfl);
|
||
|
if (wHi == 0) {
|
||
|
wHi = HIWORD(sqflTrace);
|
||
|
}
|
||
|
|
||
|
return g_rgbSqfl[LOWORD(sqfl)] & wHi;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#define _SetupEnterProc(nm) \
|
||
|
static CHAR s_szProc[] = #nm; \
|
||
|
ARGLIST _al[1] \
|
||
|
|
||
|
#define _ _al,
|
||
|
|
||
|
#define ppvDword ((PPV)1)
|
||
|
#define ppvVoid ((PPV)2)
|
||
|
#define ppvBool ((PPV)3)
|
||
|
|
||
|
#define _DoEnterProc(v) \
|
||
|
ArgsPalPszV v; \
|
||
|
EnterSqflPszPal(sqfl, s_szProc, _al) \
|
||
|
|
||
|
#define _EnterProc(nm, v) \
|
||
|
_SetupEnterProc(nm); \
|
||
|
_DoEnterProc(v) \
|
||
|
|
||
|
#define _ExitOleProcPpv(ppv) \
|
||
|
ExitSqflPalHresPpv(sqfl, _al, hres, (PPV)(ppv)) \
|
||
|
|
||
|
#define _ExitOleProc() \
|
||
|
_ExitOleProcPpv(0) \
|
||
|
|
||
|
#define _ExitProc() \
|
||
|
ExitSqflPalHresPpv(sqfl, _al, 0, ppvVoid) \
|
||
|
|
||
|
#define _ExitProcX(x) \
|
||
|
ExitSqflPalHresPpv(sqfl, _al, (HRESULT)(x), ppvDword) \
|
||
|
|
||
|
#define _ExitProcF(x) \
|
||
|
ExitSqflPalHresPpv(sqfl, _al, (HRESULT)(x), ppvBool) \
|
||
|
|
||
|
#define _ExitBenignOleProcPpv(ppv) \
|
||
|
ExitSqflPalHresPpv(sqfl | sqflBenign, _al, hres, (PPV)(ppv)) \
|
||
|
|
||
|
#define _ExitBenignOleProc() \
|
||
|
_ExitBenignOleProcPpv(0) \
|
||
|
|
||
|
#define _ExitBenignProc() \
|
||
|
ExitSqflPalHresPpv(sqfl | sqflBenign, _al, 0, ppvVoid) \
|
||
|
|
||
|
#define _ExitBenignProcX(x) \
|
||
|
ExitSqflPalHresPpv(sqfl | sqflBenign, _al, (HRESULT)(x), ppvDword) \
|
||
|
|
||
|
#define _ExitBenignProcF(x) \
|
||
|
ExitSqflPalHresPpv(sqfl | sqflBenign, _al, (HRESULT)(x), ppvBool) \
|
||
|
|
||
|
#if defined(DEBUG)
|
||
|
|
||
|
#define EnterProc _EnterProc
|
||
|
#define ExitOleProcPpv _ExitOleProcPpv
|
||
|
#define ExitOleProc _ExitOleProc
|
||
|
#define ExitProc _ExitProc
|
||
|
#define ExitProcX _ExitProcX
|
||
|
#define ExitProcF _ExitProcF
|
||
|
#define ExitBenignOleProcPpv _ExitBenignOleProcPpv
|
||
|
#define ExitBenignOleProc _ExitBenignOleProc
|
||
|
#define ExitBenignProc _ExitBenignProc
|
||
|
#define ExitBenignProcX _ExitBenignProcX
|
||
|
#define ExitBenignProcF _ExitBenignProcF
|
||
|
|
||
|
#define EnterProcS(nm, v) \
|
||
|
static CHAR s_szProc2[] = #nm; \
|
||
|
ARGLIST _al[1]; \
|
||
|
ArgsPalPszV v; \
|
||
|
EnterSqflPszPal(sqfl, s_szProc2, _al) \
|
||
|
|
||
|
#define EnterProcI _EnterProc
|
||
|
#define EnterProcR _EnterProc
|
||
|
#define ExitOleProcPpvR _ExitOleProcPpv
|
||
|
#define ExitOleProcR _ExitOleProc
|
||
|
#define ExitProcR _ExitProc
|
||
|
#define ExitProcXR _ExitProcX
|
||
|
#define ExitProcFR _ExitProcF
|
||
|
#define ExitBenignOleProcPpvR _ExitBenignOleProcPpv
|
||
|
#define ExitBenignOleProcR _ExitBenignOleProc
|
||
|
#define ExitBenignProcR _ExitBenignProc
|
||
|
#define ExitBenignProcXR _ExitBenignProcX
|
||
|
#define ExitBenignProcFR _ExitBenignProcF
|
||
|
|
||
|
#elif defined(RDEBUG)
|
||
|
|
||
|
#define EnterProc(nm, v)
|
||
|
#define ExitOleProcPpv(ppv)
|
||
|
#define ExitOleProc()
|
||
|
#define ExitProc()
|
||
|
#define ExitProcX(x)
|
||
|
#define ExitProcF(x)
|
||
|
#define ExitBenignOleProcPpv(ppv)
|
||
|
#define ExitBenignOleProc()
|
||
|
#define ExitBenignProc()
|
||
|
#define ExitBenignProcX(x)
|
||
|
#define ExitBenignProcF(x)
|
||
|
|
||
|
#define EnterProcS(nm, v)
|
||
|
#define EnterProcI(nm, v) static CHAR s_szProc[] = ""
|
||
|
#define EnterProcR(nm, v) static CHAR s_szProc[] = #nm
|
||
|
#define ExitOleProcPpvR(ppv)
|
||
|
#define ExitOleProcR()
|
||
|
#define ExitProcR()
|
||
|
#define ExitProcXR()
|
||
|
#define ExitProcFR()
|
||
|
#define ExitBenignOleProcPpvR(ppv)
|
||
|
#define ExitBenignOleProcR()
|
||
|
#define ExitBenignProcR()
|
||
|
#define ExitBenignProcXR()
|
||
|
#define ExitBenignProcFR()
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define EnterProc(nm, v)
|
||
|
#define ExitOleProcPpv(ppv)
|
||
|
#define ExitOleProc()
|
||
|
#define ExitProc()
|
||
|
#define ExitProcX(x)
|
||
|
#define ExitProcF(x)
|
||
|
#define ExitBenignOleProcPpv(ppv)
|
||
|
#define ExitBenignOleProc()
|
||
|
#define ExitBenignProc()
|
||
|
#define ExitBenignProcX(x)
|
||
|
#define ExitBenignProcF(x)
|
||
|
|
||
|
#define EnterProcS(nm, v)
|
||
|
#define EnterProcI(nm, v)
|
||
|
#define EnterProcR(nm, v)
|
||
|
#define ExitOleProcPpvR(ppv)
|
||
|
#define ExitOleProcR()
|
||
|
#define ExitProcR()
|
||
|
#define ExitProcXR(x)
|
||
|
#define ExitProcFR(x)
|
||
|
#define ExitBenignOleProcPpvR(ppv)
|
||
|
#define ExitBenignOleProcR()
|
||
|
#define ExitBenignProcR()
|
||
|
#define ExitBenignProcXR()
|
||
|
#define ExitBenignProcFR()
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
#endif // _INC_DEBUG
|