mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
412 lines
11 KiB
412 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
callmon.c
|
|
|
|
Abstract:
|
|
|
|
USAGE: callmon [callmon switches] command-line-of-application
|
|
|
|
|
|
Author:
|
|
|
|
Mark Lucovsky (markl) 26-Jan-1995
|
|
|
|
--*/
|
|
|
|
#include "callmonp.h"
|
|
|
|
int
|
|
WINAPI
|
|
WinMain(
|
|
HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPSTR lpCmdLine,
|
|
int nShowCmd
|
|
)
|
|
{
|
|
CHAR Line[256];
|
|
int i;
|
|
|
|
InitializeCallmon();
|
|
exit(0);
|
|
return 0;
|
|
}
|
|
|
|
int _CRTAPI1
|
|
ulcomp(const void *e1,const void *e2)
|
|
{
|
|
PBREAKPOINT_INFO p1;
|
|
PBREAKPOINT_INFO p2;
|
|
|
|
p1 = (*(PBREAKPOINT_INFO *)e1);
|
|
p2 = (*(PBREAKPOINT_INFO *)e2);
|
|
|
|
if ( p1 && p2 ) {
|
|
return (p2->ApiCount - p1->ApiCount);
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ProcessCallmonData(
|
|
VOID
|
|
)
|
|
{
|
|
|
|
CHAR OutputBuffer[ 512 ];
|
|
UCHAR LastKey;
|
|
LONG ScrollDelta;
|
|
WORD DisplayLine, LastDetailRow;
|
|
int i;
|
|
DWORD WaitRet;
|
|
|
|
if ( !fBreakPointsInitialized ) {
|
|
return;
|
|
}
|
|
|
|
sprintf(OutputBuffer,"%dms",GetTickCount() - BaseTime);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_TOTAL_MS),OutputBuffer);
|
|
if ( !NewCallmonData ) {
|
|
return;
|
|
}
|
|
sprintf(OutputBuffer,"%dms",GetTickCount() - StartingTick);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_INTERVAL_MS),OutputBuffer);
|
|
|
|
NewCallmonData = FALSE;
|
|
|
|
SendMessage(hwndOutput, WM_SETREDRAW, FALSE, 0);
|
|
SendMessage(hwndOutput, LB_RESETCONTENT, 0L, 0L);
|
|
|
|
qsort((void *)RegisteredBreakpoints,(size_t)NumberOfBreakpoints,(size_t)sizeof(PBREAKPOINT_INFO),ulcomp);
|
|
|
|
|
|
for(i=0;i<NumberOfBreakpoints;i++) {
|
|
if (RegisteredBreakpoints[i]) {
|
|
if ( RegisteredBreakpoints[i]->ApiCount ) {
|
|
sprintf(
|
|
OutputBuffer,
|
|
"%d\t%s",
|
|
RegisteredBreakpoints[i]->ApiCount,
|
|
RegisteredBreakpoints[i]->ApiName
|
|
);
|
|
|
|
SendMessage(hwndOutput,LB_ADDSTRING, 0L, (LPARAM)OutputBuffer);
|
|
|
|
}
|
|
}
|
|
}
|
|
SendMessage(hwndOutput, WM_SETREDRAW, TRUE, 0);
|
|
|
|
sprintf(OutputBuffer,"%d",TotalBreakPoints);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_TOTAL_API),OutputBuffer);
|
|
sprintf(OutputBuffer,"%d",RunningBreakPoints);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_INTERVAL_API),OutputBuffer);
|
|
}
|
|
|
|
BOOL
|
|
CALLBACK
|
|
CallmonDlgProc(
|
|
HWND hDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
|
|
BOOL ReturnValue;
|
|
|
|
ReturnValue = TRUE;
|
|
|
|
hwndDlg = hDlg;
|
|
switch (uMsg) {
|
|
HANDLE_MSG(hDlg, WM_INITDIALOG, CallmonDlgInit);
|
|
HANDLE_MSG(hDlg, WM_COMMAND, CallmonDlgCommand);
|
|
HANDLE_MSG(hDlg, WM_TIMER, CallmonDlgTimer);
|
|
|
|
default:
|
|
ReturnValue = FALSE;
|
|
break;
|
|
}
|
|
return ReturnValue;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CallmonDlgInit(
|
|
HWND hwnd,
|
|
HWND hwndFocus,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
HANDLE Thread;
|
|
DWORD ThreadId;
|
|
CHAR OutputBuffer[ 512 ];
|
|
|
|
//
|
|
// Get output window handle
|
|
//
|
|
|
|
hwndOutput = GetDlgItem(hwnd, ID_OUTPUT);
|
|
|
|
if ( fNtDll ) {
|
|
CheckDlgButton(hwndDlg,ID_NTDLL,1);
|
|
}
|
|
|
|
if ( fGdi32 ) {
|
|
CheckDlgButton(hwndDlg,ID_GDI32,1);
|
|
}
|
|
|
|
if ( fKernel32 ) {
|
|
CheckDlgButton(hwndDlg,ID_KERNEL32,1);
|
|
}
|
|
|
|
if ( fWsock32 ) {
|
|
CheckDlgButton(hwndDlg,ID_WSOCK32,1);
|
|
}
|
|
|
|
if ( fUser32 ) {
|
|
CheckDlgButton(hwndDlg,ID_USER32,1);
|
|
}
|
|
|
|
if ( fOle32 ) {
|
|
CheckDlgButton(hwndDlg,ID_OLE32,1);
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hwnd, ID_KERNEL32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_WSOCK32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_USER32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_GDI32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_OLE32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_NTDLL),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_START),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_BREAKCONTROL),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_CLEAR),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_STARTBUTTON),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_LOG),FALSE);
|
|
|
|
if ( fBreakPointsValid ) {
|
|
SetWindowText(GetDlgItem(hwnd, ID_BREAKCONTROL),"Disable Breakpoints");
|
|
}
|
|
else {
|
|
SetWindowText(GetDlgItem(hwnd, ID_BREAKCONTROL),"Enable Breakpoints");
|
|
}
|
|
|
|
BaseTime = GetTickCount();
|
|
sprintf(OutputBuffer,"Api Call Monitor - %s",RestOfCommandLine);
|
|
SetWindowText(hwnd,OutputBuffer);
|
|
Thread = CreateThread(NULL,0L,(PVOID)DebuggerThread,NULL,0,&ThreadId);
|
|
if ( !Thread ) {
|
|
return FALSE;
|
|
}
|
|
|
|
CloseHandle(Thread);
|
|
return(TRUE);
|
|
}
|
|
|
|
void
|
|
CallmonDlgCommand (
|
|
HWND hwnd,
|
|
int id,
|
|
HWND hwndCtl,
|
|
UINT codeNotify
|
|
)
|
|
|
|
{
|
|
CHAR OutputBuffer[ 512 ];
|
|
int i;
|
|
|
|
switch (id) {
|
|
|
|
case ID_STARTBUTTON:
|
|
case IDOK:
|
|
|
|
if ( !DebugeeActive && !fExiting ) {
|
|
|
|
SendMessage(hwndOutput, LB_RESETCONTENT, 0L, 0L);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, ID_KERNEL32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_WSOCK32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_USER32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_GDI32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_OLE32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_NTDLL),FALSE);
|
|
|
|
fKernel32 = IsDlgButtonChecked(hwnd, ID_KERNEL32);
|
|
fWsock32 = IsDlgButtonChecked(hwnd, ID_WSOCK32);
|
|
fUser32 = IsDlgButtonChecked(hwnd, ID_USER32);
|
|
fGdi32 = IsDlgButtonChecked(hwnd, ID_GDI32);
|
|
fOle32 = IsDlgButtonChecked(hwnd, ID_OLE32);
|
|
fNtDll = IsDlgButtonChecked(hwnd, ID_NTDLL);
|
|
|
|
SetWindowText(GetDlgItem(hwnd, ID_STARTBUTTON),"Stop");
|
|
Timer = SetTimer(hwnd,1,1000,NULL);
|
|
DebugeeActive = TRUE;
|
|
SetEvent(ReleaseDebugeeEvent);
|
|
}
|
|
else {
|
|
KillTimer(hwnd,Timer);
|
|
EnableWindow(GetDlgItem(hwnd, ID_KERNEL32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_WSOCK32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_USER32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_GDI32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_OLE32),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_NTDLL),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_START),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_BREAKCONTROL),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_CLEAR),FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, ID_STARTBUTTON),FALSE);
|
|
}
|
|
|
|
break;
|
|
|
|
case ID_CLEAR:
|
|
|
|
//
|
|
// Clear the Api counts
|
|
//
|
|
|
|
SendMessage(hwndOutput, LB_RESETCONTENT, 0L, 0L);
|
|
|
|
for(i=0;i<NumberOfBreakpoints;i++) {
|
|
if (RegisteredBreakpoints[i]) {
|
|
RegisteredBreakpoints[i]->ApiCount = 0;
|
|
}
|
|
}
|
|
|
|
StartingTick = GetTickCount();
|
|
RunningBreakPoints = 0;
|
|
sprintf(OutputBuffer,"%d",TotalBreakPoints);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_TOTAL_API),OutputBuffer);
|
|
sprintf(OutputBuffer,"%d",RunningBreakPoints);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_INTERVAL_API),OutputBuffer);
|
|
|
|
sprintf(OutputBuffer,"%dms",GetTickCount() - BaseTime);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_TOTAL_MS),OutputBuffer);
|
|
SetWindowText(GetDlgItem(hwndDlg, ID_INTERVAL_MS),"0ms");
|
|
|
|
if ( LogFile ) {
|
|
goto dolog;
|
|
}
|
|
|
|
break;
|
|
|
|
case ID_LOG:
|
|
if ( !LogFile ) {
|
|
LogFile = fopen("Callmon.log","wt");
|
|
if ( !LogFile ) {
|
|
EnableWindow(GetDlgItem(hwndDlg, ID_LOG),FALSE);
|
|
return;
|
|
}
|
|
}
|
|
dolog:
|
|
fprintf(LogFile,"\n Total APIs %d Running %d Time %dms (Since last clear %dms) \n\n",
|
|
TotalBreakPoints,
|
|
RunningBreakPoints,
|
|
GetTickCount() - BaseTime,
|
|
GetTickCount() - StartingTick
|
|
);
|
|
|
|
qsort((void *)RegisteredBreakpoints,(size_t)NumberOfBreakpoints,(size_t)sizeof(PBREAKPOINT_INFO),ulcomp);
|
|
|
|
|
|
for(i=0;i<NumberOfBreakpoints;i++) {
|
|
if (RegisteredBreakpoints[i]) {
|
|
if ( RegisteredBreakpoints[i]->ApiCount ) {
|
|
sprintf(
|
|
OutputBuffer,
|
|
"( %8d ) %8d %s\n",
|
|
RegisteredBreakpoints[i]->TotalApiCount,
|
|
RegisteredBreakpoints[i]->ApiCount,
|
|
RegisteredBreakpoints[i]->ApiName
|
|
);
|
|
fprintf(LogFile,"%s",OutputBuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case ID_BREAKCONTROL:
|
|
|
|
if ( fBreakPointsValid ) {
|
|
SetWindowText(GetDlgItem(hwnd, ID_BREAKCONTROL),"Enable Breakpoints");
|
|
}
|
|
else {
|
|
SetWindowText(GetDlgItem(hwnd, ID_BREAKCONTROL),"Disable Breakpoints");
|
|
}
|
|
|
|
if ( !fBreakPointsInitialized ) {
|
|
if ( fBreakPointsValid ) {
|
|
fBreakPointsValid = FALSE;
|
|
}
|
|
else {
|
|
fBreakPointsValid = TRUE;
|
|
}
|
|
return;
|
|
}
|
|
|
|
EnterCriticalSection(&BreakTable);
|
|
//
|
|
// if breakpoints are enabled, then disable them all
|
|
// otherwise enable them all
|
|
//
|
|
|
|
EndingTick = GetTickCount();
|
|
|
|
if ( fBreakPointsValid ) {
|
|
RunningBreakPoints = 0;
|
|
}
|
|
|
|
for(i=0;i<NumberOfBreakpoints;i++) {
|
|
if (RegisteredBreakpoints[i]) {
|
|
|
|
//
|
|
// If breakpoints are currently valid, then
|
|
// disable them
|
|
//
|
|
|
|
if ( fBreakPointsValid ) {
|
|
RemoveBreakpoint(TheProcess,RegisteredBreakpoints[i]);
|
|
}
|
|
else {
|
|
InstallBreakpoint(TheProcess,RegisteredBreakpoints[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
NewCallmonData = TRUE;
|
|
ProcessCallmonData();
|
|
|
|
if ( fBreakPointsValid ) {
|
|
fBreakPointsValid = FALSE;
|
|
}
|
|
else {
|
|
fBreakPointsValid = TRUE;
|
|
}
|
|
LeaveCriticalSection(&BreakTable);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
|
|
EndDialog(hwnd, id);
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
CallmonDlgTimer (
|
|
HWND hwnd,
|
|
UINT wParam
|
|
)
|
|
{
|
|
ProcessCallmonData();
|
|
}
|