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

1458 lines
44 KiB
C

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
tracer.c
Abstract:
This module contains the code for debug tracing of a windows app.
Author:
Michael Tsang (MikeTs) 02-May-2000
Environment:
User mode
Revision History:
--*/
#include "pch.h"
//
// Global Data
//
HANDLE ghServerThread = NULL;
HINSTANCE ghInstance = 0;
PSZ gpszWinTraceClass = "WinTrace_Class";
HWND ghwndTracer = 0;
HWND ghwndEdit = 0;
HWND ghwndPropSheet = 0;
HFONT ghFont = 0;
HCURSOR ghStdCursor = 0;
HCURSOR ghWaitCursor = 0;
DWORD gdwfTracer = 0;
LIST_ENTRY glistClients = {0};
char gszApp[16] = {0};
char gszSearchText[128] = {0}; //BUGBUG
char gszFileName[MAX_PATH + 1] = {0};
char gszSaveFilterSpec[80] = {0};
int giPointSize = 120;
LOGFONT gLogFont = {0};
SETTINGS gDefGlobalSettings = {0, 0, 0};
const int gTrigPtCtrlMap[NUM_TRIGPTS] =
{
IDC_TRIGPT1, IDC_TRIGPT2, IDC_TRIGPT3, IDC_TRIGPT4, IDC_TRIGPT5,
IDC_TRIGPT6, IDC_TRIGPT7, IDC_TRIGPT8, IDC_TRIGPT9, IDC_TRIGPT10
};
const int gTrigPtTraceMap[NUM_TRIGPTS] =
{
IDC_TRIGPT1_TRACE, IDC_TRIGPT2_TRACE, IDC_TRIGPT3_TRACE,
IDC_TRIGPT4_TRACE, IDC_TRIGPT5_TRACE, IDC_TRIGPT6_TRACE,
IDC_TRIGPT7_TRACE, IDC_TRIGPT8_TRACE, IDC_TRIGPT9_TRACE,
IDC_TRIGPT10_TRACE
};
const int gTrigPtBreakMap[NUM_TRIGPTS] =
{
IDC_TRIGPT1_BREAK, IDC_TRIGPT2_BREAK, IDC_TRIGPT3_BREAK,
IDC_TRIGPT4_BREAK, IDC_TRIGPT5_BREAK, IDC_TRIGPT6_BREAK,
IDC_TRIGPT7_BREAK, IDC_TRIGPT8_BREAK, IDC_TRIGPT9_BREAK,
IDC_TRIGPT10_BREAK
};
const int gTrigPtTextMap[NUM_TRIGPTS] =
{
IDC_TRIGPT1_TEXT, IDC_TRIGPT2_TEXT, IDC_TRIGPT3_TEXT,
IDC_TRIGPT4_TEXT, IDC_TRIGPT5_TEXT, IDC_TRIGPT6_TEXT,
IDC_TRIGPT7_TEXT, IDC_TRIGPT8_TEXT, IDC_TRIGPT9_TEXT,
IDC_TRIGPT10_TEXT
};
const int gTrigPtTraceTextMap[NUM_TRIGPTS] =
{
IDC_TRIGPT1_TRACE_TEXT, IDC_TRIGPT2_TRACE_TEXT,
IDC_TRIGPT3_TRACE_TEXT, IDC_TRIGPT4_TRACE_TEXT,
IDC_TRIGPT5_TRACE_TEXT, IDC_TRIGPT6_TRACE_TEXT,
IDC_TRIGPT7_TRACE_TEXT, IDC_TRIGPT8_TRACE_TEXT,
IDC_TRIGPT9_TRACE_TEXT, IDC_TRIGPT10_TRACE_TEXT
};
const int gTrigPtBreakTextMap[NUM_TRIGPTS] =
{
IDC_TRIGPT1_BREAK_TEXT, IDC_TRIGPT2_BREAK_TEXT,
IDC_TRIGPT3_BREAK_TEXT, IDC_TRIGPT4_BREAK_TEXT,
IDC_TRIGPT5_BREAK_TEXT, IDC_TRIGPT6_BREAK_TEXT,
IDC_TRIGPT7_BREAK_TEXT, IDC_TRIGPT8_BREAK_TEXT,
IDC_TRIGPT9_BREAK_TEXT, IDC_TRIGPT10_BREAK_TEXT
};
/*++
@doc EXTERNAL
@func int | WinMain | Program entry point.
@parm IN HINSTANCE | hInstance | Instance handle.
@parm IN HINSTANCE | hPrevInstance | Handle of previous instance.
@parm IN LPSTR | pszCmdLine | Points to the command line string.
@parm IN int | nCmdShow | Show state.
@rvalue Always returns 0.
--*/
int WINAPI
WinMain(
IN HINSTANCE hInstance,
IN HINSTANCE hPrevInstance,
IN LPSTR pszCmdLine,
IN int nCmdShow
)
{
TRTRACEPROC("WinMain", 1)
int rc = -1;
TRENTER(("(hInstance=%x,hPrevInstance=%x,CmdLine=%s,CmdShow=%x)\n",
hInstance, hPrevInstance, pszCmdLine, nCmdShow));
if (TracerInit(hInstance, nCmdShow))
{
MSG msg;
//
// Message pump.
//
while (GetMessage(&msg, NULL, 0, 0))
{
// if ((ghDlgSettings == 0) || !IsDialogMessage(ghDlgSettings, &msg))
{
// if (TranslateAccelerator(ghwndTracer, )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
rc = (int)msg.wParam;
}
TREXIT(("=%x\n", rc));
return rc;
} //WinMain
/*++
@doc INTERNAL
@func BOOL | TracerInit | Initialize tracer.
@parm IN HINSTANCE | hInstance | Instance handle.
@parm IN int | nCmdShow | Show state.
@rvalue Always returns 0.
--*/
BOOL
TracerInit(
IN HINSTANCE hInstance,
IN int nCmdShow
)
{
TRTRACEPROC("TracerInit", 2)
BOOL rc = FALSE;
TRENTER(("(hInstance=%x,CmdShow=%x)\n", hInstance, nCmdShow));
if ((rc = RegisterTracerClass(hInstance)) == FALSE)
{
TRERRPRINT(("Failed to register tracer class.\n"));
}
else
{
InitializeListHead(&glistClients);
ghServerThread = (HANDLE)_beginthread(ServerThread,
0,
0);
if (ghServerThread != (HANDLE)-1)
{
ghInstance = hInstance;
LoadStringA(hInstance, IDS_APP, gszApp, sizeof(gszApp));
ghStdCursor = LoadCursorA(NULL,
(LPSTR)MAKEINTRESOURCE(IDC_IBEAM));
ghWaitCursor = LoadCursorA(NULL,
(LPSTR)MAKEINTRESOURCE(IDC_WAIT));
ghwndTracer = CreateWindowA(gpszWinTraceClass,
"",
WS_OVERLAPPEDWINDOW,
//BUGBUG: get/save location from reg.
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (ghwndTracer != 0)
{
int size, len;
PSZ psz;
psz = gszSaveFilterSpec;
size = sizeof(gszSaveFilterSpec);
len = LoadStringA(ghInstance, IDS_TEXTFILES, psz, size) + 1;
psz += len;
size -= len;
lstrcpyA(psz, "*.txt");
len = lstrlenA(psz) + 1;
psz += len;
size -= len;
len = LoadStringA(ghInstance, IDS_ALLFILES, psz, size) + 1;
psz += len;
size -= len;
lstrcpyA(psz, "*.*");
len = lstrlenA(psz) + 1;
psz += len;
*psz = '\0';
gdwfTracer = TF_UNTITLED;
SetTitle(NULL);
ShowWindow(ghwndTracer, nCmdShow);
}
else
{
rc = FALSE;
TRERRPRINT(("Failed to create tracer window.\n"));
}
rc = TRUE;
}
else
{
ghServerThread = NULL;
TRERRPRINT(("Failed to create server thread.\n"));
}
}
TREXIT(("=%x\n", rc));
return rc;
} //TracerInit
/*++
@doc INTERNAL
@func BOOL | RegisterTracerClass | Register tracer window class.
@parm IN HINSTANCE | hInstance | Instance handle.
@rvalue SUCCESS | Returns TRUE.
@rvalue SUCCESS | Returns FALSE.
--*/
BOOL
RegisterTracerClass(
IN HINSTANCE hInstance
)
{
TRTRACEPROC("RegisterTracerClass", 2)
BOOL rc;
WNDCLASSEXA wcex;
TRENTER(("(hInstance=%x)\n", hInstance));
wcex.cbSize = sizeof(wcex);
wcex.style = 0;
wcex.lpfnWndProc = TracerWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIconA(hInstance, (LPSTR)MAKEINTRESOURCE(IDI_TRACER));
wcex.hCursor = LoadCursorA(NULL, (LPSTR)MAKEINTRESOURCE(IDC_ARROW));
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = (LPSTR)MAKEINTRESOURCE(IDD_MENU);
wcex.lpszClassName = gpszWinTraceClass;
wcex.hIconSm = NULL;
rc = RegisterClassExA(&wcex) != 0;
TREXIT(("=%x\n", rc));
return rc;
} //RegisterTracerClass
/*++
@doc EXTERNAL
@func LRESULT | TracerWndProc | Window procedure for Tracer.
@parm IN HWND | hwnd | Window handle.
@parm IN UINT | uiMsg | Message ID.
@parm IN WPARAM | wParam | First message parameter.
@parm IN LPARAM | lParam | Second message parameter.
@rvalue Return value is message specific.
--*/
LRESULT CALLBACK
TracerWndProc(
IN HWND hwnd,
IN UINT uiMsg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
TRTRACEPROC("TracerWndProc", 3)
LRESULT rc = 0;
TRENTER(("(hwnd=%x,Msg=%s,wParam=%x,lParam=%x)\n",
hwnd, LookupName(uiMsg, WMMsgNames), wParam, lParam));
switch (uiMsg)
{
case WM_CREATE:
{
ghwndEdit = CreateWindowExA(WS_EX_CLIENTEDGE,
"Edit",
"",
(gdwfTracer & TF_LINEWRAP)?
ES_STD:
(ES_STD | WS_HSCROLL),
0,
0,
0,
0,
hwnd,
NULL,
ghInstance,
NULL);
if (ghwndEdit != NULL)
{
HDC hDC;
hDC = GetDC(NULL);
if (hDC != NULL)
{
INITCOMMONCONTROLSEX ComCtrl;
SendMessage(ghwndEdit, EM_LIMITTEXT, 0, 0);
ghFont = GetStockObject(SYSTEM_FIXED_FONT);
GetObject(ghFont, sizeof(gLogFont), &gLogFont);
gLogFont.lfHeight = -MulDiv(giPointSize,
GetDeviceCaps(hDC,
LOGPIXELSY),
720);
ghFont = CreateFontIndirect(&gLogFont);
TRASSERT(ghFont != 0);
SendMessage(ghwndEdit,
WM_SETFONT,
(WPARAM)ghFont,
MAKELONG(FALSE, 0));
ReleaseDC(NULL, hDC);
ComCtrl.dwSize = sizeof(ComCtrl);
ComCtrl.dwICC = ICC_BAR_CLASSES | ICC_USEREX_CLASSES;
if (!InitCommonControlsEx(&ComCtrl))
{
DestroyWindow(ghwndEdit);
TRERRPRINT(("Failed to initialize Common Control\n"));
rc = -1;
}
}
else
{
DestroyWindow(ghwndEdit);
TRERRPRINT(("Failed to get display DC\n"));
rc = -1;
}
}
else
{
TRERRPRINT(("Failed to create edit window.\n"));
rc = -1;
}
break;
}
case WM_DESTROY:
{
PLIST_ENTRY plist;
PCLIENT_ENTRY ClientEntry;
while (!IsListEmpty(&glistClients))
{
plist = glistClients.Flink;
ClientEntry = CONTAINING_RECORD(plist,
CLIENT_ENTRY,
list);
WTDeregisterClient(NULL, (HCLIENT)ClientEntry);
}
DeleteObject(ghFont);
DestroyWindow(ghwndEdit);
PostQuitMessage(0);
break;
}
case WM_COMMAND:
if ((HWND)lParam == ghwndEdit)
{
switch (HIWORD(wParam))
{
case EN_ERRSPACE:
case EN_MAXTEXT:
ErrorMsg(IDS_ERRSPACE);
break;
}
}
else if (!TracerCmdProc(hwnd, wParam, lParam))
{
rc = DefWindowProc(hwnd, uiMsg, wParam, lParam);
}
break;
case WM_SETFOCUS:
SetFocus(ghwndEdit);
break;
case WM_SIZE:
MoveWindow(ghwndEdit,
0,
0,
LOWORD(lParam),
HIWORD(lParam),
TRUE);
break;
default:
rc = DefWindowProc(hwnd, uiMsg, wParam, lParam);
}
TREXIT(("=%x\n", rc));
return rc;
} //TracerWndProc
/*++
@doc INTERNAL
@func LRESULT | TracerCmdProc | Process the WM_COMMAND message.
@parm IN HWND | hwnd | Window handle.
@parm IN WPARAM | wParam | First message parameter.
@parm IN LPARAM | lParam | Second message parameter.
@rvalue Return value is message specific.
--*/
LRESULT
TracerCmdProc(
IN HWND hwnd,
IN WPARAM wParam,
IN LPARAM lParam
)
{
TRTRACEPROC("TracerCmdProc", 3)
LRESULT rc = 0;
TRENTER(("(hwnd=%x,wParam=%x,lParam=%x)\n", hwnd, wParam, lParam));
switch (LOWORD(wParam))
{
case M_SAVE:
if (!(gdwfTracer & TF_UNTITLED) &&
SaveFile(hwnd, gszFileName, FALSE))
{
break;
}
//
// Otherwise, fall through.
//
case M_SAVEAS:
{
OPENFILENAMEA ofn;
char szFileName[MAX_PATH + 1] = "";
char szSaveAs[16];
memset(&ofn, 0, sizeof(ofn));
LoadStringA(ghInstance, IDS_SAVEAS, szSaveAs, sizeof(szSaveAs));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = ghwndTracer;
ofn.hInstance = ghInstance;
ofn.lpstrFilter = gszSaveFilterSpec;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFileName;
ofn.nMaxFile = sizeof(szFileName);
if (gdwfTracer & TF_UNTITLED)
{
lstrcpyA(szFileName, "*.txt");
}
else
{
lstrcpynA(szFileName, gszFileName, MAX_PATH);
szFileName[MAX_PATH] = '\0';
}
ofn.lpstrTitle = szSaveAs;
ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST;
ofn.lpstrDefExt = "txt";
if (GetSaveFileNameA(&ofn))
{
if (SaveFile(hwnd, szFileName, TRUE))
{
lstrcpynA(gszFileName, szFileName, MAX_PATH);
gdwfTracer &= ~TF_UNTITLED;
SetTitle(NULL);
}
}
else
{
DWORD dwErr = CommDlgExtendedError();
if (dwErr != 0)
{
ErrorMsg(IDS_GETSAVEFILENAME_FAILED, dwErr);
}
}
break;
}
case M_PRINT:
//
// BUGBUG
//
break;
case M_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case M_CLEAR:
SendMessage(ghwndEdit, EM_SETSEL, 0, -1);
SendMessage(ghwndEdit, EM_REPLACESEL, 0, (LPARAM)"");
break;
case M_FIND:
if (gszSearchText[0])
{
//BUGBUG SearchText(gszSearchText);
break;
}
//
// Otherwise, fall through.
//
case M_FINDNEXT:
//
// BUGBUG
//
case M_GOTO:
//BUGBUG
break;
case M_WORDWRAP:
//BUGBUG
break;
case M_SETFONT:
{
HDC hDC;
hDC = GetDC(NULL);
if (hDC != NULL)
{
CHOOSEFONT cf;
memset(&cf, 0, sizeof(cf));
cf.lStructSize = sizeof(cf);
cf.hwndOwner = hwnd;
cf.lpLogFont = &gLogFont;
gLogFont.lfHeight = -MulDiv(giPointSize,
GetDeviceCaps(hDC, LOGPIXELSY),
720);
cf.Flags = CF_SCREENFONTS | CF_NOVERTFONTS |
CF_INITTOLOGFONTSTRUCT;
cf.nFontType = SCREEN_FONTTYPE;
ReleaseDC(NULL, hDC);
if (ChooseFont(&cf))
{
HFONT hfontNew;
SetCursor(ghWaitCursor);
hfontNew = CreateFontIndirect(&gLogFont);
if (hfontNew != NULL)
{
DeleteObject(ghFont);
ghFont = hfontNew;
SendMessage(ghwndEdit,
WM_SETFONT,
(WPARAM)ghFont,
MAKELONG(TRUE, 0));
giPointSize = cf.iPointSize;
}
SetCursor(ghStdCursor);
}
else
{
DWORD dwErr = CommDlgExtendedError();
if (dwErr != 0)
{
ErrorMsg(IDS_CHOOSEFONT_FAILED, dwErr);
}
}
}
break;
}
case M_CLIENTS:
{
PROPSHEETHEADER psh;
PLIST_ENTRY plist;
psh.dwSize = sizeof(psh);
psh.dwFlags = 0;
psh.hwndParent = hwnd;
psh.hInstance = ghInstance;
psh.pszCaption = MAKEINTRESOURCE(IDS_CLIENT_SETTINGS);
psh.nPages = 1;
for (plist = glistClients.Flink;
plist != &glistClients;
plist = plist->Flink)
{
psh.nPages++;;
}
psh.phpage = LocalAlloc(LMEM_FIXED,
sizeof(HPROPSHEETPAGE)*psh.nPages);
psh.nStartPage = 0;
CreatePropertyPages(psh.phpage);
if (PropertySheet(&psh) < 0)
{
ErrorMsg(IDSERR_PROP_SHEET, GetLastError());
}
LocalFree(psh.phpage);
break;
}
case M_HELP:
//BUGBUG
break;
case M_ABOUT:
ShellAboutA(hwnd,
gszApp,
"",
LoadIconA(ghInstance,
(LPCSTR)MAKEINTRESOURCE(IDI_TRACER)));
break;
}
TREXIT(("=%x\n", rc));
return rc;
} //TracerCmdProc
/*++
@doc EXTERNAL
@func INT_PTR | GlobalSettingsDlgProc | Global setting dialog procedure.
@parm IN HWND | hwnd | Window handle.
@parm IN UINT | uiMsg | Message ID.
@parm IN WPARAM | wParam | First message parameter.
@parm IN LPARAM | lParam | Second message parameter.
@rvalue Return value is message specific.
--*/
INT_PTR APIENTRY
GlobalSettingsDlgProc(
IN HWND hwnd,
IN UINT uiMsg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
TRTRACEPROC("GlobalSettingsDlgProc", 3)
INT_PTR rc = 0;
static SETTINGS GlobalSettings = {0};
TRENTER(("(hwnd=%x,Msg=%s,wParam=%x,lParam=%x)\n",
hwnd, LookupName(uiMsg, WMMsgNames), wParam, lParam));
switch (uiMsg)
{
case WM_INITDIALOG:
{
ghwndPropSheet = GetParent(hwnd);
GlobalSettings = gDefGlobalSettings;
SendDlgItemMessage(hwnd,
IDC_GLOBALVERBOSESPIN,
UDM_SETRANGE,
0,
MAKELONG(MAX_LEVELS, 0));
SendDlgItemMessage(hwnd,
IDC_GLOBALTRACESPIN,
UDM_SETRANGE,
0,
MAKELONG(MAX_LEVELS, 0));
SendDlgItemMessage(hwnd,
IDC_GLOBALVERBOSESPIN,
UDM_SETPOS,
0,
MAKELONG(GlobalSettings.iVerboseLevel, 0));
SendDlgItemMessage(hwnd,
IDC_GLOBALTRACESPIN,
UDM_SETPOS,
0,
MAKELONG(GlobalSettings.iTraceLevel, 0));
CheckDlgButton(hwnd,
IDC_GLOBALTRACEDEBUGGER,
(GlobalSettings.dwfSettings &
SETTINGS_TRACE_TO_DEBUGGER) != 0);
rc = TRUE;
break;
}
case WM_DESTROY:
ghwndPropSheet = NULL;
break;
case WM_NOTIFY:
{
NMHDR *lpnm = (NMHDR *)lParam;
switch (lpnm->code)
{
case PSN_APPLY:
gDefGlobalSettings = GlobalSettings;
break;
}
break;
}
case WM_COMMAND:
{
BOOL fChanged = FALSE;
switch (LOWORD(wParam))
{
case IDC_GLOBALVERBOSE:
case IDC_GLOBALTRACE:
{
switch (HIWORD(wParam))
{
BOOL fOK;
int n;
case EN_UPDATE:
n = GetDlgItemInt(hwnd,
LOWORD(wParam),
&fOK,
FALSE);
if (fOK && (n <= MAX_LEVELS))
{
if (LOWORD(wParam) == IDC_GLOBALVERBOSE)
{
GlobalSettings.iVerboseLevel = n;
}
else
{
GlobalSettings.iTraceLevel = n;
}
fChanged = TRUE;
}
else
{
SetDlgItemInt(hwnd,
LOWORD(wParam),
(LOWORD(wParam) ==
IDC_GLOBALVERBOSE)?
GlobalSettings.iVerboseLevel:
GlobalSettings.iTraceLevel,
FALSE);
SendMessage((HWND)lParam,
EM_SETSEL,
0,
-1);
}
break;
}
break;
}
case IDC_GLOBALTRACEDEBUGGER:
if (IsDlgButtonChecked(hwnd, IDC_GLOBALTRACEDEBUGGER))
{
GlobalSettings.dwfSettings |=
SETTINGS_TRACE_TO_DEBUGGER;
}
else
{
GlobalSettings.dwfSettings &=
~SETTINGS_TRACE_TO_DEBUGGER;
}
fChanged = TRUE;
break;
}
if (fChanged)
{
SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
}
break;
}
}
TREXIT(("=%x\n", rc));
return rc;
} //GlobalSettingsDlgProc
/*++
@doc EXTERNAL
@func INT_PTR | ClientSettingsDlgProc | Client setting dialog procedure.
@parm IN HWND | hwnd | Window handle.
@parm IN UINT | uiMsg | Message ID.
@parm IN WPARAM | wParam | First message parameter.
@parm IN LPARAM | lParam | Second message parameter.
@rvalue Return value is message specific.
--*/
INT_PTR APIENTRY
ClientSettingsDlgProc(
IN HWND hwnd,
IN UINT uiMsg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
TRTRACEPROC("ClientSettingsDlgProc", 3)
INT_PTR rc = 0;
TRENTER(("(hwnd=%x,Msg=%s,wParam=%x,lParam=%x)\n",
hwnd, LookupName(uiMsg, WMMsgNames), wParam, lParam));
switch (uiMsg)
{
case WM_INITDIALOG:
{
PCLIENT_ENTRY ClientEntry =
(PCLIENT_ENTRY)((LPPROPSHEETPAGE)lParam)->lParam;
int i;
ghwndPropSheet = GetParent(hwnd);
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)ClientEntry);
SendServerRequest(ClientEntry,
SRVREQ_GETCLIENTINFO,
&ClientEntry->ClientInfo);
SendDlgItemMessage(hwnd,
IDC_CLIENTVERBOSESPIN,
UDM_SETRANGE,
0,
MAKELONG(MAX_LEVELS, 0));
SendDlgItemMessage(hwnd,
IDC_CLIENTTRACESPIN,
UDM_SETRANGE,
0,
MAKELONG(MAX_LEVELS, 0));
SendDlgItemMessage(hwnd,
IDC_CLIENTVERBOSESPIN,
UDM_SETPOS,
0,
MAKELONG(ClientEntry->ClientInfo.Settings.iVerboseLevel,
0));
SendDlgItemMessage(hwnd,
IDC_CLIENTTRACESPIN,
UDM_SETPOS,
0,
MAKELONG(ClientEntry->ClientInfo.Settings.iTraceLevel,
0));
CheckDlgButton(hwnd,
IDC_CLIENTTRACEDEBUGGER,
(ClientEntry->ClientInfo.Settings.dwfSettings &
SETTINGS_TRACE_TO_DEBUGGER) != 0);
CheckDlgButton(hwnd,
IDC_CLIENTTRIGGERTRACE,
(ClientEntry->ClientInfo.Settings.dwfSettings &
SETTINGS_TRIGMODE_ENABLED) != 0);
for (i = 0; i < NUM_TRIGPTS; ++i)
{
SetDlgItemText(hwnd,
gTrigPtCtrlMap[i],
ClientEntry->ClientInfo.TrigPts[i].szProcName);
CheckDlgButton(hwnd,
gTrigPtTraceMap[i],
(ClientEntry->ClientInfo.TrigPts[i].dwfTrigPt &
TRIGPT_TRACE_ENABLED) != 0);
CheckDlgButton(hwnd,
gTrigPtBreakMap[i],
(ClientEntry->ClientInfo.TrigPts[i].dwfTrigPt &
TRIGPT_BREAK_ENABLED) != 0);
}
EnableTrigPts(hwnd,
(ClientEntry->ClientInfo.Settings.dwfSettings &
SETTINGS_TRIGMODE_ENABLED) != 0);
rc = TRUE;
break;
}
case WM_NOTIFY:
{
NMHDR *lpnm = (NMHDR *)lParam;
switch (lpnm->code)
{
case PSN_APPLY:
{
PCLIENT_ENTRY ClientEntry;
ClientEntry = (PCLIENT_ENTRY)GetWindowLongPtr(hwnd,
DWLP_USER);
if (ClientEntry != NULL)
{
ClientEntry->ClientInfo.Settings =
ClientEntry->TempSettings;
RtlCopyMemory(ClientEntry->ClientInfo.TrigPts,
ClientEntry->TempTrigPts,
sizeof(ClientEntry->ClientInfo.TrigPts));
SendServerRequest(ClientEntry,
SRVREQ_SETCLIENTINFO,
&ClientEntry->ClientInfo);
}
else
{
TRWARNPRINT(("Notify: Failed to get Client Entry\n"));
}
break;
}
}
break;
}
case WM_COMMAND:
{
BOOL fChanged = FALSE;
PCLIENT_ENTRY ClientEntry;
BOOL fTrace = FALSE;
switch (LOWORD(wParam))
{
case IDC_CLIENTVERBOSE:
case IDC_CLIENTTRACE:
switch (HIWORD(wParam))
{
case EN_UPDATE:
{
BOOL fOK;
int n;
ClientEntry = (PCLIENT_ENTRY)GetWindowLongPtr(
hwnd,
DWLP_USER);
if (ClientEntry != NULL)
{
n = GetDlgItemInt(hwnd,
LOWORD(wParam),
&fOK,
FALSE);
if (fOK && (n <= MAX_LEVELS))
{
if (LOWORD(wParam) == IDC_CLIENTVERBOSE)
{
ClientEntry->TempSettings.iVerboseLevel
= n;
}
else
{
ClientEntry->TempSettings.iTraceLevel
= n;
}
fChanged = TRUE;
}
else
{
SetDlgItemInt(
hwnd,
LOWORD(wParam),
(LOWORD(wParam) == IDC_CLIENTVERBOSE)?
ClientEntry->TempSettings.iVerboseLevel:
ClientEntry->TempSettings.iTraceLevel,
FALSE);
SendMessage((HWND)lParam,
EM_SETSEL,
0,
-1);
}
}
else
{
TRWARNPRINT(("Verbose/Trace: Failed to get Client Entry\n"));
}
break;
}
}
break;
case IDC_CLIENTTRACEDEBUGGER:
case IDC_CLIENTTRIGGERTRACE:
ClientEntry = (PCLIENT_ENTRY)GetWindowLongPtr(hwnd,
DWLP_USER);
if (ClientEntry != NULL)
{
DWORD dwf = (LOWORD(wParam) ==
IDC_CLIENTTRACEDEBUGGER)?
SETTINGS_TRACE_TO_DEBUGGER:
SETTINGS_TRIGMODE_ENABLED;
BOOL fChecked = IsDlgButtonChecked(hwnd,
LOWORD(wParam));
if (fChecked)
{
ClientEntry->TempSettings.dwfSettings |= dwf;
}
else
{
ClientEntry->TempSettings.dwfSettings &= ~dwf;
}
if (LOWORD(wParam) == IDC_CLIENTTRIGGERTRACE)
{
EnableTrigPts(hwnd, fChecked);
}
fChanged = TRUE;
}
else
{
TRWARNPRINT(("TraceToDebugger/TrigModeEnabled: Failed to get Client Entry\n"));
}
break;
case IDC_TRIGPT1:
case IDC_TRIGPT2:
case IDC_TRIGPT3:
case IDC_TRIGPT4:
case IDC_TRIGPT5:
case IDC_TRIGPT6:
case IDC_TRIGPT7:
case IDC_TRIGPT8:
case IDC_TRIGPT9:
case IDC_TRIGPT10:
switch (HIWORD(wParam))
{
case EN_UPDATE:
{
int n;
int iTrigPt;
ClientEntry = (PCLIENT_ENTRY)GetWindowLongPtr(
hwnd,
DWLP_USER);
if (ClientEntry != NULL)
{
iTrigPt = FindTrigPtIndex(LOWORD(wParam),
gTrigPtCtrlMap);
n = GetDlgItemTextA(
hwnd,
LOWORD(wParam),
ClientEntry->TempTrigPts[iTrigPt].szProcName,
MAX_PROCNAME_LEN - 1);
if ((n > 0) ||
(GetLastError() == ERROR_SUCCESS))
{
fChanged = TRUE;
}
else
{
TRWARNPRINT(("Failed to get trigger point text (err=%x)\n",
GetLastError()));
}
}
else
{
TRWARNPRINT(("TrigPt: Failed to get Client Entry\n"));
}
break;
}
}
break;
case IDC_TRIGPT1_TRACE:
case IDC_TRIGPT2_TRACE:
case IDC_TRIGPT3_TRACE:
case IDC_TRIGPT4_TRACE:
case IDC_TRIGPT5_TRACE:
case IDC_TRIGPT6_TRACE:
case IDC_TRIGPT7_TRACE:
case IDC_TRIGPT8_TRACE:
case IDC_TRIGPT9_TRACE:
case IDC_TRIGPT10_TRACE:
fTrace = TRUE;
//
// Fall through ...
//
case IDC_TRIGPT1_BREAK:
case IDC_TRIGPT2_BREAK:
case IDC_TRIGPT3_BREAK:
case IDC_TRIGPT4_BREAK:
case IDC_TRIGPT5_BREAK:
case IDC_TRIGPT6_BREAK:
case IDC_TRIGPT7_BREAK:
case IDC_TRIGPT8_BREAK:
case IDC_TRIGPT9_BREAK:
case IDC_TRIGPT10_BREAK:
{
int iTrigPt;
ClientEntry = (PCLIENT_ENTRY)GetWindowLongPtr(hwnd,
DWLP_USER);
if (ClientEntry != NULL)
{
DWORD dwf = fTrace? TRIGPT_TRACE_ENABLED:
TRIGPT_BREAK_ENABLED;
iTrigPt = FindTrigPtIndex(LOWORD(wParam),
fTrace? gTrigPtTraceMap:
gTrigPtBreakMap);
if (IsDlgButtonChecked(hwnd, LOWORD(wParam)))
{
ClientEntry->TempTrigPts[iTrigPt].dwfTrigPt |= dwf;
}
else
{
ClientEntry->TempTrigPts[iTrigPt].dwfTrigPt &=
~dwf;
}
fChanged = TRUE;
}
else
{
TRWARNPRINT(("TrigPtEnable: Failed to get Client Entry\n"));
}
break;
}
}
if (fChanged)
{
SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
}
break;
}
}
TREXIT(("=%x\n", rc));
return rc;
} //ClientSettingsDlgProc
/*++
@doc INTERNAL
@func VOID | EnableTrigPts | Enable trigger points controls.
@parm IN HWND | hDlg | Dialog box handle.
@parm IN BOOL | fEnable | TRUE if enable.
@rvalue None.
--*/
VOID
EnableTrigPts(
IN HWND hDlg,
IN BOOL fEnable
)
{
TRTRACEPROC("EnableTrigPts", 3)
int i;
TRENTER(("(hDlg=%x,fEnable=%x)\n", hDlg, fEnable));
EnableWindow(GetDlgItem(hDlg, IDC_CLIENTTRIGPTGROUPBOX), fEnable);
for (i = 0; i < NUM_TRIGPTS; ++i)
{
EnableWindow(GetDlgItem(hDlg, gTrigPtTextMap[i]), fEnable);
EnableWindow(GetDlgItem(hDlg, gTrigPtTraceTextMap[i]), fEnable);
EnableWindow(GetDlgItem(hDlg, gTrigPtBreakTextMap[i]), fEnable);
EnableWindow(GetDlgItem(hDlg, gTrigPtCtrlMap[i]), fEnable);
EnableWindow(GetDlgItem(hDlg, gTrigPtTraceMap[i]), fEnable);
EnableWindow(GetDlgItem(hDlg, gTrigPtBreakMap[i]), fEnable);
}
TREXIT(("!\n"));
return;
} //EnableTrigPts
/*++
@doc INTERNAL
@func BOOL | SaveFile | Save the text buffer to a file.
@parm IN HWND | hwndParent | Window handle parent.
@parm IN PSZ | pszFileName | Points to the file name string to save.
@parm IN BOOL | fSaveAs | TRUE if called from SaveAs.
@rvalue SUCCESS | Returns TRUE.
@rvalue FAILURE | Returns FALSE.
--*/
BOOL
SaveFile(
IN HWND hwndParent,
IN PSZ pszFileName,
IN BOOL fSaveAs
)
{
TRTRACEPROC("SaveFile", 3)
BOOL rc = FALSE;
HANDLE hFile;
TRENTER(("(hwnd=%x,File=%s,fSaveAs=%x)\n",
hwndParent, pszFileName, fSaveAs));
hFile = CreateFileA(pszFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
fSaveAs? OPEN_ALWAYS: OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
BOOL fNew;
UINT uiTextSize;
HLOCAL hlText;
LPSTR lpch;
DWORD dwcbWritten;
fNew = (GetLastError() != ERROR_ALREADY_EXISTS);
uiTextSize = (UINT)SendMessage(ghwndEdit, WM_GETTEXTLENGTH, 0, 0);
hlText = (HLOCAL)SendMessage(ghwndEdit, EM_GETHANDLE, 0, 0);
if ((hlText != NULL) && ((lpch = (LPSTR)LocalLock(hlText)) != NULL))
{
rc = WriteFile(hFile,
lpch,
uiTextSize,
&dwcbWritten,
NULL);
if (rc == FALSE)
{
ErrorMsg(IDS_WRITEFILE_FAILED, pszFileName);
}
LocalUnlock(hlText);
}
else
{
TRERRPRINT(("Failed to get text length or get text handle\n"));
}
CloseHandle(hFile);
if ((rc == FALSE) && fNew)
{
DeleteFileA(pszFileName);
}
}
else
{
ErrorMsg(IDS_CREATEFILE_FAILED, pszFileName);
}
TREXIT(("=%x\n", rc));
return rc;
} //SaveFile
/*++
@doc INTERNAL
@func UINT | CreatePropertyPages | Create the global setting page as
well as a property page for each registered clients.
@parm OUT HPROPSHEETPAGE *| hPages | Points to the array to hold all
the created property sheet handles.
@rvalue SUCCESS | Returns number of pages created.
@rvalue FAILURE | Returns 0.
--*/
UINT
CreatePropertyPages(
OUT HPROPSHEETPAGE *hPages
)
{
TRTRACEPROC("CreatePropertyPages", 3)
UINT nPages = 0;
PROPSHEETPAGEA psp;
PLIST_ENTRY plist;
PCLIENT_ENTRY ClientEntry;
TRENTER(("(hPages=%p)\n", hPages));
psp.dwSize = sizeof(psp);
psp.dwFlags = 0;
psp.hInstance = ghInstance;
psp.pszTitle = NULL;
psp.lParam = 0;
psp.pszTemplate = (LPSTR)MAKEINTRESOURCE(IDD_GLOBALSETTINGS);
psp.pfnDlgProc = GlobalSettingsDlgProc;
hPages[nPages] = CreatePropertySheetPageA(&psp);
if (hPages[nPages] != NULL)
{
nPages++;
}
psp.dwFlags = PSP_USETITLE;
psp.pszTemplate = (LPSTR)MAKEINTRESOURCE(IDD_CLIENTSETTINGS);
psp.pfnDlgProc = ClientSettingsDlgProc;
for (plist = glistClients.Flink;
plist != &glistClients;
plist = plist->Flink)
{
ClientEntry = CONTAINING_RECORD(plist, CLIENT_ENTRY, list);
psp.pszTitle = ClientEntry->szClientName;
psp.lParam = (LPARAM)ClientEntry;
hPages[nPages] = CreatePropertySheetPageA(&psp);
if (hPages[nPages] != NULL)
{
ClientEntry->hPage = hPages[nPages];
nPages++;
}
}
TREXIT(("=%d\n", nPages));
return nPages;
} //CreatePropertyPages
/*++
@doc INTERNAL
@func VOID | SetTitle | Set the title bar text.
@parm IN PSZ | pszTitle | Points to title text string. If NULL, set
title to current file name.
@rvalue None.
--*/
VOID
SetTitle(
IN PSZ pszTitle OPTIONAL
)
{
TRTRACEPROC("SetTitle", 3)
char szWindowText[MAX_PATH + 16];
TRENTER(("(Title=%s)\n", pszTitle));
if (pszTitle != NULL)
{
lstrcpyA(szWindowText, pszTitle);
}
else
{
int len;
if (gdwfTracer & TF_UNTITLED)
{
LoadStringA(ghInstance,
IDS_UNTITLED,
szWindowText,
sizeof(szWindowText));
}
else
{
lstrcpynA(szWindowText, gszFileName, sizeof(szWindowText));
}
len = lstrlenA(szWindowText);
LoadStringA(ghInstance,
IDS_TITLE,
&szWindowText[len],
sizeof(szWindowText) - len);
}
SetWindowTextA(ghwndTracer, szWindowText);
TREXIT(("!\n"));
return;
} //SetTitle
/*++
@doc INTERNAL
@func int | FindTrigPtIndex | Find the trigger point index by its
control ID.
@parm IN int | iID | Dialog object control ID.
@parm IN const int * | IDTable | Points to the ID map.
@rvalue SUCCESS | Returns the trigger point index.
@rvalue FAILURE | Returns -1.
--*/
int
FindTrigPtIndex(
IN int iID,
IN const int *IDTable
)
{
TRTRACEPROC("FindTrigPtIndex", 3)
int i;
TRENTER(("(ID=%d,IDTable=%p)\n", iID, IDTable));
for (i = 0; i < NUM_TRIGPTS; ++i)
{
if (iID == IDTable[i])
{
break;
}
}
if (i == NUM_TRIGPTS)
{
i = -1;
}
TREXIT(("=%d\n", i));
return i;
} //FindTrigPtIndex
/*++
@doc INTERNAL
@func VOID | ErrorMsg | Put out an error message box.
@parm IN ULONG | ErrCode | The given error code.
@parm ... | Substituting arguments for the error message.
@rvalue Returns the number of chars in the message.
--*/
int
ErrorMsg(
IN ULONG ErrCode,
...
)
{
static char szFormat[1024];
static char szErrMsg[1024];
int n;
va_list arglist;
LoadStringA(ghInstance, ErrCode, szFormat, sizeof(szFormat));
va_start(arglist, ErrCode);
n = wvsprintfA(szErrMsg, szFormat, arglist);
va_end(arglist);
MessageBoxA(NULL, szErrMsg, gszApp, MB_OK | MB_ICONERROR);
return n;
} //ErrorMsg