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.
456 lines
10 KiB
456 lines
10 KiB
/*****************************************************************************\
|
|
*
|
|
* Module: spy.c
|
|
*
|
|
* Main module for the Windows debugging Spy SDK applet.
|
|
*
|
|
* History:
|
|
* 01/01/87 toddla Created.
|
|
* 09/14/92 byrond Cleaned up (after someone ported it to NT).
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
#include "spy.h"
|
|
#include <stdlib.h>
|
|
|
|
|
|
#define WM_EXECINSTANCE (WM_USER+100)
|
|
|
|
|
|
/*
|
|
* Macros to simplify working with menus.
|
|
*/
|
|
#define MyEnableMenuItem(hMenu, wIDEnableItem, fEnable) \
|
|
EnableMenuItem((hMenu),(wIDEnableItem),(fEnable)?MF_ENABLED:MF_GRAYED)
|
|
|
|
#define MyCheckMenuItem(hMenu, wIDCheckItem, fCheck) \
|
|
CheckMenuItem((hMenu),(wIDCheckItem),(fCheck)?MF_CHECKED:MF_UNCHECKED)
|
|
|
|
|
|
HANDLE ghInst;
|
|
HWND ghwndSpyApp;
|
|
HWND ghwndPrintf = NULL;
|
|
HANDLE ghHookThread = NULL;
|
|
HWND ghwndSpyHook = NULL;
|
|
HWND ghwndSpyingOn = NULL; // The window we are spying on.
|
|
HFONT ghfontPrintf;
|
|
INT gnLines;
|
|
BOOL gfSpyOn = FALSE;
|
|
BOOL gfSpyAll;
|
|
BOOL gfOutputWin;
|
|
BOOL gfOutputCom1;
|
|
BOOL gfOutputFile;
|
|
HFILE gfhFile;
|
|
#ifdef JAPAN // DBCS_FIX
|
|
HANDLE gfhCom1;
|
|
#endif
|
|
CHAR gszFile[MAXSTRING];
|
|
INT gcxBorder;
|
|
INT gcyBorder;
|
|
BOOL gfMsgsUser; // TRUE to spy on all WM_USER messages.
|
|
BOOL gfMsgsUnknown; // TRUE to spy on all unknown msgs.
|
|
CHAR gszAppName[] = SPYAPPNAME;
|
|
#ifdef JAPAN
|
|
// BUGBUG Should the Japan code be the standard? FloydR
|
|
UCHAR gszWindowName[40];
|
|
#endif
|
|
WINDOWPLACEMENT gwndpl;
|
|
|
|
|
|
PRIVATE HANDLE ghaccelTbl; // Accelerator table handle.
|
|
PRIVATE CHAR gszSpyClassName[] = SPYCLASSNAME;
|
|
|
|
|
|
PRIVATE BOOL SpyInit(HANDLE hInstance, INT nCmdShow);
|
|
PRIVATE VOID PutOptions(VOID);
|
|
PRIVATE VOID InitMenu(HMENU hmenu);
|
|
PRIVATE LRESULT SpyCommand(HWND hwnd, INT nCmd, INT nNotifyCode);
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* WinMain
|
|
*
|
|
* Main entry point for the Spy app.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
INT WINAPI
|
|
WinMain(
|
|
HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPSTR lpCmdLine,
|
|
INT nCmdShow
|
|
)
|
|
{
|
|
MSG msg;
|
|
|
|
if (!SpyInit(hInstance, nCmdShow))
|
|
return FALSE;
|
|
|
|
if (!CreateHookThread())
|
|
goto closespy;
|
|
|
|
/*
|
|
* Polling messages from event queue
|
|
*/
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
if (!TranslateAccelerator(ghwndSpyApp, ghaccelTbl, &msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
closespy:
|
|
if (IsWindow(ghwndSpyApp))
|
|
{
|
|
if (DestroyWindow(ghwndSpyApp))
|
|
{
|
|
ghwndSpyApp = NULL;
|
|
}
|
|
}
|
|
|
|
if (IsWindow(ghwndPrintf))
|
|
{
|
|
if (DestroyWindow(ghwndPrintf))
|
|
{
|
|
ghwndPrintf = NULL;
|
|
}
|
|
}
|
|
|
|
return (INT)msg.wParam;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* SpyInit
|
|
*
|
|
* Initializes the Spy application.
|
|
*
|
|
* Arguments:
|
|
*
|
|
*
|
|
*
|
|
* Returns:
|
|
* TRUE if successful, FALSE otherwise.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
PRIVATE BOOL
|
|
SpyInit(
|
|
HANDLE hInstance,
|
|
INT nCmdShow
|
|
)
|
|
{
|
|
WNDCLASS wc;
|
|
HWND hwndT;
|
|
CHAR szClassName[40];
|
|
BOOL bFoundPrevSpy = FALSE;
|
|
INT i;
|
|
INT j;
|
|
|
|
ghInst = hInstance;
|
|
|
|
/*
|
|
* Loop through windows to find one of the spy class.
|
|
*/
|
|
for (hwndT = GetWindow(GetDesktopWindow(), GW_CHILD); hwndT;
|
|
hwndT = GetWindow(hwndT, GW_HWNDNEXT))
|
|
{
|
|
if (GetClassName(hwndT, szClassName, 40))
|
|
{
|
|
if (!lstrcmpi(szClassName, gszSpyClassName))
|
|
{
|
|
bFoundPrevSpy = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bFoundPrevSpy)
|
|
{
|
|
if (hwndT)
|
|
SendMessage(hwndT, WM_EXECINSTANCE, 0, 0);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (!(ghaccelTbl = LoadAccelerators(ghInst, "spy")))
|
|
return FALSE;
|
|
|
|
ReadRegistry();
|
|
|
|
gcxBorder = GetSystemMetrics(SM_CXBORDER);
|
|
gcyBorder = GetSystemMetrics(SM_CYBORDER);
|
|
|
|
//
|
|
// Calculate the counts in the message groups. This is best
|
|
// done at run time to be safe.
|
|
//
|
|
for (i = 0; i < gcMessages; i++)
|
|
{
|
|
//
|
|
// If this message belongs to a message group,
|
|
// increment the total for that group.
|
|
//
|
|
for (j = 0; j < gcMsgGroups; j++)
|
|
{
|
|
if (gaMsgGroup[j].flMask & gaMsgs[i].Flags)
|
|
gaMsgGroup[j].cMsgs++;
|
|
}
|
|
}
|
|
|
|
#ifdef JAPAN
|
|
lstrcpy(gszWindowName,LoadResourceString(IDS_APPLICATION_NAME));
|
|
#endif
|
|
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hIcon = LoadIcon(hInstance, gszAppName);
|
|
wc.lpszMenuName = gszAppName;
|
|
wc.lpszClassName = gszSpyClassName;
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
wc.hInstance = hInstance;
|
|
wc.style = CS_BYTEALIGNCLIENT;
|
|
wc.lpfnWndProc = SpyWndProc;
|
|
wc.cbWndExtra = 0;
|
|
wc.cbClsExtra = 0;
|
|
|
|
if (!RegisterClass(&wc))
|
|
return FALSE;
|
|
|
|
#ifdef JAPAN
|
|
ghwndSpyApp = CreateWindow(gszSpyClassName, gszWindowName,
|
|
WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
|
|
NULL, NULL, hInstance, NULL);
|
|
#else
|
|
ghwndSpyApp = CreateWindow(gszSpyClassName, gszAppName,
|
|
WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
|
|
NULL, NULL, hInstance, NULL);
|
|
#endif
|
|
|
|
if (!ghwndSpyApp)
|
|
return FALSE;
|
|
|
|
if (nCmdShow != SW_SHOWNORMAL)
|
|
gwndpl.showCmd = nCmdShow;
|
|
|
|
SetWindowPlacement(ghwndSpyApp, &gwndpl);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* SpyWndProc
|
|
*
|
|
* Main window procedure for the spy app.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
LRESULT CALLBACK
|
|
SpyWndProc(
|
|
HWND hwnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_CREATE:
|
|
MyCreatePrintfWin(hwnd);
|
|
return 0;
|
|
|
|
case WM_INITMENU:
|
|
if (GetMenu(ghwndSpyApp) == (HMENU)wParam)
|
|
InitMenu((HMENU)wParam);
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
return SpyCommand(hwnd, LOWORD(wParam), HIWORD(wParam));
|
|
|
|
case WM_ACTIVATE:
|
|
/*
|
|
* Set the focus to the printf window if we are being activated.
|
|
*/
|
|
if (LOWORD(wParam))
|
|
SetFocus(ghwndPrintf);
|
|
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
/*
|
|
* Size the printf window to fit into the new client area size.
|
|
*/
|
|
MoveWindow(ghwndPrintf, -gcxBorder, -gcyBorder,
|
|
LOWORD(lParam) + (2 * gcxBorder),
|
|
HIWORD(lParam) + (2 * gcyBorder), TRUE);
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
SetSpyHook(FALSE);
|
|
|
|
#ifdef JAPAN // DBCS_FIX
|
|
if (gfhCom1 != INVALID_HANDLE_VALUE)
|
|
CloseHandle(gfhCom1);
|
|
#endif
|
|
if (gfhFile)
|
|
_lclose(gfhFile);
|
|
|
|
SendMessage(ghwndSpyHook, WM_CLOSE, 0, 0);
|
|
WriteRegistry();
|
|
WaitForSingleObject(ghHookThread, INFINITE);
|
|
DestroyWindow(ghwndSpyApp);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0); /* Kill the main window */
|
|
ghwndSpyApp = NULL;
|
|
ghwndPrintf = NULL;
|
|
break;
|
|
|
|
case WM_EXECINSTANCE:
|
|
/*
|
|
* another instance of spy has been started.
|
|
*/
|
|
if (IsIconic(hwnd))
|
|
ShowWindow(hwnd,SW_SHOWNORMAL);
|
|
|
|
SetForegroundWindow(hwnd);
|
|
BringWindowToTop(hwnd);
|
|
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* InitMenu
|
|
*
|
|
* This function grays/enables and checks/unchecks the menu items
|
|
* appropriately for the given state.
|
|
*
|
|
* Arguments:
|
|
* HMENU hmenu - The menu handle.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
PRIVATE VOID
|
|
InitMenu(
|
|
HMENU hmenu
|
|
)
|
|
{
|
|
BOOL fEnable = !IsPrintfEmpty();
|
|
|
|
MyEnableMenuItem(hmenu, MENU_EDIT_CUT, fEnable);
|
|
MyEnableMenuItem(hmenu, MENU_EDIT_COPY, fEnable);
|
|
MyEnableMenuItem(hmenu, MENU_EDIT_CLEAR, fEnable);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************\
|
|
* SpyCommand
|
|
*
|
|
* Handles thw WM_COMMAND messages for the Spy app.
|
|
*
|
|
* Arguments:
|
|
* HWND hwnd - Window handle of the main app window.
|
|
* INT nCmd - Command value.
|
|
* INT nNotifyCode - The notify code.
|
|
*
|
|
* Returns:
|
|
* The value that the window proc should return, based on the processing
|
|
* of the specific WM_COMMAND message received.
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
PRIVATE LRESULT
|
|
SpyCommand(
|
|
HWND hwnd,
|
|
INT nCmd,
|
|
INT nNotifyCode
|
|
)
|
|
{
|
|
HMENU hmenu;
|
|
|
|
switch (nCmd)
|
|
{
|
|
case MENU_SPY_SELECTWINDOW:
|
|
MyDialogBox(DID_SELECTWINDOW, SelectWindowDlgProc);
|
|
break;
|
|
|
|
case MENU_SPY_ABOUT:
|
|
MyDialogBox(DID_ABOUT, AboutDlgProc);
|
|
break;
|
|
|
|
case MENU_SPY_EXIT:
|
|
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
|
break;
|
|
|
|
case MENU_EDIT_CUT:
|
|
if (CopyToClipboard())
|
|
ClearPrintfWindow(ghwndPrintf);
|
|
|
|
break;
|
|
|
|
case MENU_EDIT_COPY:
|
|
CopyToClipboard();
|
|
break;
|
|
|
|
case MENU_EDIT_CLEAR:
|
|
ClearPrintfWindow(ghwndPrintf);
|
|
break;
|
|
|
|
case MENU_OPTIONS_MESSAGES:
|
|
MyDialogBox(DID_MESSAGES, MessagesDlgProc);
|
|
break;
|
|
|
|
case MENU_OPTIONS_FONT:
|
|
SelectFont();
|
|
break;
|
|
|
|
case MENU_OPTIONS_OUTPUT:
|
|
MyDialogBox(DID_OUTPUT, OutputDlgProc);
|
|
break;
|
|
|
|
case MENU_START:
|
|
if (SetSpyHook(TRUE))
|
|
{
|
|
hmenu = GetMenu(hwnd);
|
|
ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING,
|
|
MENU_STOP, LoadResourceString(IDS_MENU_STOP));
|
|
DrawMenuBar(hwnd);
|
|
|
|
SetSpyCaption();
|
|
}
|
|
|
|
break;
|
|
|
|
case MENU_STOP:
|
|
if (SetSpyHook(FALSE))
|
|
{
|
|
hmenu = GetMenu(hwnd);
|
|
ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING,
|
|
MENU_START, LoadResourceString(IDS_MENU_START));
|
|
DrawMenuBar(hwnd);
|
|
|
|
SetSpyCaption();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|