windows-nt/Source/XPSP1/NT/drivers/wdm/input/tabletpc/wintrace/wintrace.c
2020-09-26 16:20:57 +08:00

671 lines
22 KiB
C

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
wintrace.c
Abstract:
This module contains the code for the wintrace APIs.
Author:
Michael Tsang (MikeTs) 01-May-2000
Environment:
User mode
Revision History:
--*/
#include "pch.h"
int giIndentLevel = 0;
DWORD gdwfTraceTxt = 0;
NAMETABLE WMMsgNames[] =
{
WM_NULL, "Null",
WM_CREATE, "Create",
WM_DESTROY, "Destroy",
WM_MOVE, "Move",
WM_SIZE, "Size",
WM_ACTIVATE, "Activate",
WM_SETFOCUS, "SetFocus",
WM_KILLFOCUS, "KillFocus",
WM_ENABLE, "Enable",
WM_SETREDRAW, "SetRedraw",
WM_SETTEXT, "SetText",
WM_GETTEXT, "GetText",
WM_GETTEXTLENGTH, "GetTextLen",
WM_PAINT, "Paint",
WM_CLOSE, "Close",
WM_QUERYENDSESSION, "QueryEndSession",
WM_QUERYOPEN, "QueryOpen",
WM_ENDSESSION, "EndSession",
WM_QUIT, "Quit",
WM_ERASEBKGND, "EraseBackground",
WM_SYSCOLORCHANGE, "SysColorChange",
WM_SHOWWINDOW, "ShowWindow",
WM_WININICHANGE, "WinIniChange",
WM_SETTINGCHANGE, "SettingChange",
WM_DEVMODECHANGE, "DevModeChange",
WM_ACTIVATEAPP, "ActivateApp",
WM_FONTCHANGE, "FontChange",
WM_TIMECHANGE, "TimeChange",
WM_CANCELMODE, "CancelMode",
WM_SETCURSOR, "SetCursor",
WM_MOUSEACTIVATE, "MouseActivate",
WM_CHILDACTIVATE, "ChildActivate",
WM_QUEUESYNC, "QueueSync",
WM_GETMINMAXINFO, "GetMinMaxInfo",
WM_PAINTICON, "PaintIcon",
WM_ICONERASEBKGND, "IconEraseBackground",
WM_NEXTDLGCTL, "NextDialogControl",
WM_SPOOLERSTATUS, "SpoolerStatus",
WM_DRAWITEM, "DrawItem",
WM_MEASUREITEM, "MeasureItem",
WM_DELETEITEM, "DeleteItem",
WM_VKEYTOITEM, "VKeyToItem",
WM_CHARTOITEM, "CharToItem",
WM_SETFONT, "SetFont",
WM_GETFONT, "GetFont",
WM_SETHOTKEY, "SetHotKey",
WM_GETHOTKEY, "GetHotKey",
WM_QUERYDRAGICON, "QueryDragIcon",
WM_COMPAREITEM, "CompareItem",
WM_GETOBJECT, "GetObject",
WM_COMPACTING, "Compacting",
WM_COMMNOTIFY, "CommNotify",
WM_WINDOWPOSCHANGING, "WindowPosChanging",
WM_WINDOWPOSCHANGED, "WindowPosChanged",
WM_POWER, "Power",
WM_COPYDATA, "CopyData",
WM_CANCELJOURNAL, "CancelJournal",
WM_NOTIFY, "Notify",
WM_INPUTLANGCHANGEREQUEST, "InputLangChangeRequest",
WM_INPUTLANGCHANGE, "InputLangChange",
WM_TCARD, "TCard",
WM_HELP, "Help",
WM_USERCHANGED, "UserChanged",
WM_NOTIFYFORMAT, "NotifyFormat",
WM_CONTEXTMENU, "ContextMenu",
WM_STYLECHANGING, "StyleChanging",
WM_STYLECHANGED, "StyleChanged",
WM_DISPLAYCHANGE, "DisplayChange",
WM_GETICON, "GetIcon",
WM_SETICON, "SetIcon",
WM_NCCREATE, "NCCreate",
WM_NCDESTROY, "NCDestroy",
WM_NCCALCSIZE, "NCCalcSize",
WM_NCHITTEST, "NCHitTest",
WM_NCPAINT, "NCPaint",
WM_NCACTIVATE, "NCActivate",
WM_GETDLGCODE, "GetDialogCode",
WM_SYNCPAINT, "SyncPaint",
WM_NCMOUSEMOVE, "NCMouseMove",
WM_NCLBUTTONDOWN, "NCLeftButtonDown",
WM_NCLBUTTONUP, "NCLeftButtonUp",
WM_NCLBUTTONDBLCLK, "NCLeftButtonDoubleClick",
WM_NCRBUTTONDOWN, "NCRightButtonDown",
WM_NCRBUTTONUP, "NCRightButtonUp",
WM_NCRBUTTONDBLCLK, "NCRightButtonDoubleClick",
WM_NCMBUTTONDOWN, "NCMiddleButtonDown",
WM_NCMBUTTONUP, "NCMiddleButtonUp",
WM_NCMBUTTONDBLCLK, "NCMiddleButtonDoubleClick",
WM_NCXBUTTONDOWN, "NCXButtonDown",
WM_NCXBUTTONUP, "NCXButtonUp",
WM_NCXBUTTONDBLCLK, "NCXButtonDoubleClick",
WM_KEYFIRST, "KeyFirst",
WM_KEYDOWN, "KeyDown",
WM_KEYUP, "KeyUp",
WM_CHAR, "Char",
WM_DEADCHAR, "DeadChar",
WM_SYSKEYDOWN, "SysKeyDown",
WM_SYSKEYUP, "SysKeyUp",
WM_SYSCHAR, "SysChar",
WM_SYSDEADCHAR, "SysDeadChar",
WM_KEYLAST, "KeyLast",
WM_IME_STARTCOMPOSITION, "IMEStartComposition",
WM_IME_ENDCOMPOSITION, "IMEEndComposition",
WM_IME_COMPOSITION, "IMEComposition",
WM_IME_KEYLAST, "IMEKeyLast",
WM_INITDIALOG, "InitDialog",
WM_COMMAND, "Command",
WM_SYSCOMMAND, "SysCommand",
WM_TIMER, "Timer",
WM_HSCROLL, "HScroll",
WM_VSCROLL, "VScroll",
WM_INITMENU, "InitMenu",
WM_INITMENUPOPUP, "InitMenuPopup",
WM_MENUSELECT, "MenuSelect",
WM_MENUCHAR, "MenuChar",
WM_ENTERIDLE, "EnterIdle",
WM_MENURBUTTONUP, "MenuRightButtonUp",
WM_MENUDRAG, "MenuDrag",
WM_MENUGETOBJECT, "MenuGetObject",
WM_UNINITMENUPOPUP, "UninitMenuPopup",
WM_MENUCOMMAND, "MenuCommand",
WM_CHANGEUISTATE, "ChangeUIState",
WM_UPDATEUISTATE, "UpdateUIState",
WM_QUERYUISTATE, "QueryUIState",
WM_CTLCOLORMSGBOX, "CtlColorMsgBox",
WM_CTLCOLOREDIT, "CtlColorEdit",
WM_CTLCOLORLISTBOX, "CtlColorListBox",
WM_CTLCOLORBTN, "CtlColorButton",
WM_CTLCOLORDLG, "CtlColorDialog",
WM_CTLCOLORSCROLLBAR, "CtlColorScrollBar",
WM_CTLCOLORSTATIC, "CtlColorStatic",
WM_MOUSEFIRST, "MouseFirst",
WM_MOUSEMOVE, "MouseMove",
WM_LBUTTONDOWN, "LeftButtonDown",
WM_LBUTTONUP, "LeftButtonUp",
WM_LBUTTONDBLCLK, "LeftButtonDoubleClick",
WM_RBUTTONDOWN, "RightButtonDown",
WM_RBUTTONUP, "RightButtonUp",
WM_RBUTTONDBLCLK, "RightButtonDoubleClick",
WM_MBUTTONDOWN, "MiddleButtonDown",
WM_MBUTTONUP, "MiddleButtonUp",
WM_MBUTTONDBLCLK, "MiddleButtonDoubleClick",
WM_MOUSEWHEEL, "MouseWheel",
WM_XBUTTONDOWN, "XButtonDown",
WM_XBUTTONUP, "XButtonUp",
WM_XBUTTONDBLCLK, "XButtonDoubleClick",
WM_MOUSELAST, "MouseLast",
WM_PARENTNOTIFY, "ParentNotify",
WM_ENTERMENULOOP, "EnterMenuLoop",
WM_EXITMENULOOP, "ExitMenuLoop",
WM_NEXTMENU, "NextMenu",
WM_SIZING, "Sizing",
WM_CAPTURECHANGED, "CaptureChanged",
WM_MOVING, "Moving",
WM_POWERBROADCAST, "PowerBroadcast",
WM_DEVICECHANGE, "DeviceChange",
WM_MDICREATE, "MDICreate",
WM_MDIDESTROY, "MDIDestroy",
WM_MDIACTIVATE, "MDIActivate",
WM_MDIRESTORE, "MDIRestore",
WM_MDINEXT, "MDINext",
WM_MDIMAXIMIZE, "MDIMaximize",
WM_MDITILE, "MDITitle",
WM_MDICASCADE, "MDICascade",
WM_MDIICONARRANGE, "MDIIconArrange",
WM_MDIGETACTIVE, "MDIGetActive",
WM_MDISETMENU, "MDISetMenu",
WM_ENTERSIZEMOVE, "EnterSizeMove",
WM_EXITSIZEMOVE, "ExitSizeMove",
WM_DROPFILES, "DropFiles",
WM_MDIREFRESHMENU, "MDIRefreshMenu",
WM_IME_SETCONTEXT, "IMESetContext",
WM_IME_NOTIFY, "IMENotify",
WM_IME_CONTROL, "IMEControl",
WM_IME_COMPOSITIONFULL, "IMECompositionFull",
WM_IME_SELECT, "IMESelect",
WM_IME_CHAR, "IMEChar",
WM_IME_REQUEST, "IMERequest",
WM_IME_KEYDOWN, "IMEKeyDown",
WM_IME_KEYUP, "IMEKeyUp",
WM_MOUSEHOVER, "MouseHover",
WM_MOUSELEAVE, "MouseLeave",
WM_NCMOUSEHOVER, "NCMouseHover",
WM_NCMOUSELEAVE, "NCMouseLeave",
WM_CUT, "Cut",
WM_COPY, "Copy",
WM_PASTE, "Paste",
WM_CLEAR, "Clear",
WM_UNDO, "Undo",
WM_RENDERFORMAT, "RenderFormat",
WM_RENDERALLFORMATS, "RenderAllFormats",
WM_DESTROYCLIPBOARD, "DestroyClipboard",
WM_DRAWCLIPBOARD, "DrawClipboard",
WM_PAINTCLIPBOARD, "PaintClipboard",
WM_VSCROLLCLIPBOARD, "VScrollClipboard",
WM_SIZECLIPBOARD, "SizeClipboard",
WM_ASKCBFORMATNAME, "AskCBFormatName",
WM_CHANGECBCHAIN, "ChangeCBChain",
WM_HSCROLLCLIPBOARD, "HScrollClipboard",
WM_QUERYNEWPALETTE, "QueryNewPalette",
WM_PALETTEISCHANGING, "PaletteIsChanging",
WM_PALETTECHANGED, "PaletteChanged",
WM_HOTKEY, "HotKey",
WM_PRINT, "Print",
WM_PRINTCLIENT, "PrintClient",
WM_APPCOMMAND, "AppCommand",
WM_HANDHELDFIRST, "HandHeldFirst",
WM_HANDHELDLAST, "HandHeldLast",
WM_AFXFIRST, "AFXFirst",
WM_AFXLAST, "AFXLast",
WM_PENWINFIRST, "PenWinFirst",
WM_PENWINLAST, "PenWinLast",
WM_USER, "User",
WM_APP, "App",
0x00, NULL
};
/*++
@doc EXTERNAL
@func VOID | TraceInit | Initialize the tracing component.
@parm IN PSZ | pszClientName | Points to the client name string.
@parm IN int | iDefTraceLevel | Specifies default trace level.
@parm IN int | iDefVerboseLevel | Specifies default verbose level.
@rvalue SUCCESS | Returns TRUE.
@rvalue FAILURE | Returns FALSE.
--*/
BOOL EXPORT
TraceInit(
IN PSZ pszClientName,
IN int iDefTraceLevel,
IN int iDefVerboseLevel
)
{
WTTRACEPROC("TraceInit", 1)
BOOL rc = FALSE;
char szMsg[128];
WTENTER(("(ClientName=%s,DefTraceLevel=%d,DefVerboseLevel=%d)\n",
pszClientName, iDefTraceLevel, iDefVerboseLevel));
if (ghClientThread == (HANDLE)-1)
{
gdwfWinTrace = 0;
gdwfTraceTxt = 0;
giIndentLevel = 0;
memset(&gClientInfo, 0, sizeof(gClientInfo));
memset(gszClientName, 0, sizeof(gszClientName));
lstrcpynA(gszClientName, pszClientName, sizeof(gszClientName));
gClientInfo.Settings.iTraceLevel = iDefTraceLevel;
gClientInfo.Settings.iVerboseLevel = iDefVerboseLevel;
ghTraceMutex = CreateMutex(NULL, FALSE, NULL);
if (ghTraceMutex == NULL)
{
WTERRPRINT(("Failed to create trace mutex (err=%d).\n",
GetLastError()));
}
else
{
ghClientThread = (HANDLE)_beginthread(ClientThread,
0,
pszClientName);
if (ghClientThread != (HANDLE)-1)
{
rc = TRUE;
}
else
{
CloseHandle(ghTraceMutex);
ghTraceMutex = 0;
WTERRPRINT(("Failed to create client thread.\n"));
}
}
}
else
{
WTERRPRINT(("Client is already initialized\n"));
}
WTEXIT(("=%x\n", rc));
return rc;
} //TraceInit
/*++
@doc EXTERNAL
@func VOID | TraceTerminate | Terminating trace, clean up.
@parm VOID | None.
@rvalue None
--*/
VOID EXPORT
TraceTerminate(
VOID
)
{
WTTRACEPROC("TraceTerminate", 1)
WTENTER(("()\n"));
if (ghClientThread != (HANDLE)-1)
{
DWORD rc;
gdwfWinTrace |= WTF_TERMINATING;
if (ghClient != 0)
{
RPC_TRY("WTDeregisterClient",
WTDeregisterClient(ghTracerBinding, ghClient));
ghClient = 0;
}
rc = WaitForSingleObject(ghClientThread, INFINITE);
WTASSERT(rc == WAIT_OBJECT_0);
gdwfWinTrace = 0;
gdwfTraceTxt = 0;
giIndentLevel = 0;
}
if (ghTraceMutex != NULL)
{
CloseHandle(ghTraceMutex);
ghTraceMutex = 0;
}
WTEXIT(("!\n"));
return;
} //TraceTerminate
/*++
@doc EXTERNAL
@func BOOL | IsTraceProcOn |
Determine if the given procedure should be traced.
@parm IN PSZ | pszProcName | Points to procedure name string.
@parm IN int | iProcLevel | Specifies the procedure trace level.
@parm IN BOOL | fEnter | TRUE if called from ENTERPROC.
@rvalue SUCCESS | Returns TRUE.
@rvalue FAILURE | Returns FALSE.
--*/
BOOL EXPORT
IsTraceProcOn(
IN PSZ pszProcName,
IN int iProcLevel,
IN BOOL fEnter
)
{
WTTRACEPROC("IsTraceProcOn", 2)
BOOL rc = FALSE;
DWORD rcWait;
static int icTriggers = 0;
WTENTER(("(ProcName=%s,ProcLevel=%d,fEnter=%x)\n",
pszProcName, iProcLevel, fEnter));
if (giIndentLevel < 0)
{
giIndentLevel = 0;
}
gdwfTraceTxt &= ~TRACETXT_BREAK;
if (ghTraceMutex != 0)
{
rcWait = WaitForSingleObject(ghTraceMutex, TIMEOUT_TRACEMUTEX);
if (rcWait == WAIT_OBJECT_0)
{
if (!(gdwfWinTrace & WTF_TRACE_INPROGRESS))
{
PTRIGPT TrigPt;
if ((gClientInfo.Settings.dwfSettings &
SETTINGS_TRIGMODE_ENABLED) &&
((TrigPt = FindTrigPt(pszProcName)) != NULL))
{
if (TrigPt->dwfTrigPt & TRIGPT_TRACE_ENABLED)
{
if (fEnter)
{
icTriggers++;
}
else
{
icTriggers--;
}
rc = TRUE;
}
if (TrigPt->dwfTrigPt & TRIGPT_BREAK_ENABLED)
{
gdwfTraceTxt |= TRACETXT_BREAK;
}
}
else if ((iProcLevel <= gClientInfo.Settings.iTraceLevel) &&
(!(gClientInfo.Settings.dwfSettings &
SETTINGS_TRIGMODE_ENABLED) || (icTriggers > 0)))
{
rc = TRUE;
}
if (rc == TRUE)
{
gpszProcName = pszProcName;
gdwfWinTrace |= WTF_TRACE_INPROGRESS;
}
}
if (rc == FALSE)
{
ReleaseMutex(ghTraceMutex);
}
}
else
{
WTERRPRINT(("Failed to wait for trace mutex (rc=%x).\n", rcWait));
}
}
WTEXIT(("=%x\n", rc));
return rc;
} //IsTraceProcOn
/*++
@doc EXTERNAL
@func VOID | TraceProc | Trace procedure.
@parm IN PSZ | pszFormat | Points to format string.
@parm ... | Substituting arguments for the format string.
@rvalue None.
--*/
VOID EXPORT
TraceProc(
IN PSZ pszFormat,
...
)
{
WTTRACEPROC("TraceProc", 2)
BOOL fToDebugger;
char szTraceTxt[MAX_TRACETXT_LEN];
va_list arglist;
WTENTER(("(Format=%s,...)\n", pszFormat));
if (!(gdwfWinTrace & WTF_CLIENT_READY) ||
(gClientInfo.Settings.dwfSettings & SETTINGS_TRACE_TO_DEBUGGER))
{
int i;
fToDebugger = TRUE;
wsprintfA(szTraceTxt, "[%08x]%s: ",
GetCurrentThreadId(), gszClientName);
for (i = 0; i < giIndentLevel; ++i)
{
lstrcatA(szTraceTxt, "| ");
}
}
else
{
fToDebugger = FALSE;
szTraceTxt[0] = '\0';
}
lstrcatA(szTraceTxt, gpszProcName);
va_start(arglist, pszFormat);
wvsprintfA(&szTraceTxt[lstrlenA(szTraceTxt)], pszFormat, arglist);
va_end(arglist);
if (fToDebugger)
{
OutputDebugStringA(szTraceTxt);
}
else
{
RPC_TRY("WTTraceProc",
WTTraceProc(ghTracerBinding,
ghClient,
GetCurrentThreadId(),
giIndentLevel,
szTraceTxt));
}
gdwfWinTrace &= ~WTF_TRACE_INPROGRESS;
ReleaseMutex(ghTraceMutex);
WTEXIT(("!\n"));
return;
} //TraceProc
/*++
@doc EXTERNAL
@func BOOL | IsTraceMsgOn | Determine if the message should be printed.
@parm IN PSZ | pszProcName | Points to procedure name string.
@parm IN int | iVerboseLevel | Specifies the verbose level of the message.
@rvalue SUCCESS | Returns TRUE.
@rvalue FAILURE | Returns FALSE.
--*/
BOOL EXPORT
IsTraceMsgOn(
IN PSZ pszProcName,
IN int iVerboseLevel
)
{
WTTRACEPROC("IsTraceMsgOn", 2)
BOOL rc = FALSE;
DWORD rcWait;
WTENTER(("(ProcName=%s,VerboseLevel=%d)\n", pszProcName, iVerboseLevel));
gdwfTraceTxt &= ~TRACETXT_MSGTYPE_MASK;
if (ghTraceMutex != 0)
{
rcWait = WaitForSingleObject(ghTraceMutex, TIMEOUT_TRACEMUTEX);
if (rcWait == WAIT_OBJECT_0)
{
if (iVerboseLevel <= gClientInfo.Settings.iVerboseLevel)
{
gpszProcName = pszProcName;
rc = TRUE;
}
if (rc == FALSE)
{
ReleaseMutex(ghTraceMutex);
}
}
else
{
WTERRPRINT(("Failed to wait for trace mutex (rc=%x).\n", rcWait));
}
}
WTEXIT(("=%x\n", rc));
return rc;
} //IsTraceMsgOn
/*++
@doc EXTERNAL
@func VOID | TraceMsg | Print a message.
@parm IN PSZ | pszFormat | Points to format string.
@parm ... | Substituting arguments for the format string.
@rvalue None.
--*/
VOID EXPORT
TraceMsg(
IN PSZ pszFormat,
...
)
{
WTTRACEPROC("TraceMsg", 2)
DWORD MsgType = gdwfTraceTxt & TRACETXT_MSGTYPE_MASK;
char szTraceTxt[MAX_TRACETXT_LEN];
va_list arglist;
WTENTER(("(Format=%s,...)\n", pszFormat));
wsprintfA(szTraceTxt, "[%08x]%s.%s%s: ",
GetCurrentThreadId(),
gszClientName, gpszProcName,
(MsgType == TRACETXT_MSGTYPE_ERROR)? "_ERR":
(MsgType == TRACETXT_MSGTYPE_WARN)? "_WARN":
(MsgType == TRACETXT_MSGTYPE_INFO)? "_INFO": "");
va_start(arglist, pszFormat);
wvsprintfA(&szTraceTxt[lstrlenA(szTraceTxt)], pszFormat, arglist);
va_end(arglist);
if (!(gdwfWinTrace & WTF_CLIENT_READY) ||
(gClientInfo.Settings.dwfSettings & SETTINGS_TRACE_TO_DEBUGGER))
{
OutputDebugStringA(szTraceTxt);
}
else
{
RPC_TRY("WTTraceMsg",
WTTraceMsg(ghTracerBinding, ghClient, szTraceTxt));
}
ReleaseMutex(ghTraceMutex);
WTEXIT(("!\n"));
return;
} //TraceMsg
/*++
@doc EXTERNAL
@func PSZ | LookupName |
Look up name string of a code in the given name table.
@parm IN ULONG | Code | The given code to lookup.
@parm IN PNAMETABLE | NameTable | The name table to look into.
@rvalue SUCCESS - Returns pointer to the minor function name string.
@rvalue FAILURE - Returns "unknown".
--*/
PSZ EXPORT
LookupName(
IN ULONG Code,
IN PNAMETABLE NameTable
)
{
PSZ pszName = NULL;
static char szUnknown[64];
while (NameTable->pszName != NULL)
{
if (Code == NameTable->Code)
{
pszName = NameTable->pszName;
break;
}
NameTable++;
}
if (pszName == NULL)
{
wsprintfA(szUnknown, "unknown [0x%x (%d)]", Code, Code);
pszName = szUnknown;
}
return pszName;
} //LookupName