|
|
Microsoft OS/2 SDK 2.0 05-30-1990
/****************************** Module Header ******************************\
* Module Name: spy.c - Spy application
*
* Created: Microsoft, IBM Corporation 1990
*
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is
* sample code created by Microsoft Corporation and/or IBM
* Corporation. This sample code is not part of any standard
* Microsoft or IBM product and is provided to you solely for
* the purpose of assisting you in the development of your
* applications. The code is provided "AS IS", without
* warranty of any kind. Neither Microsoft nor IBM shall be
* liable for any damages arising out of your use of the sample
* code, even if they have been advised of the possibility of
* such damages.
*
\***************************************************************************/
#define INCL_WIN
#define INCL_WINSYS
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DOSMODULEMGR
#define INCL_DOSRESOURCES
#define INCL_HELP
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include "spy.h"
#include "spyhk32.h"
#include "help.h"
#include <time.h>
#include <stdlib.h>
/************* GLOBAL VARIABLES */
/************************** IN SPY.H *********************************** */
HAB hab;
HMQ hmqSpy;
HWND hwndSpy;
HWND hwndSpyFrame;
HWND hwndSpyList = NULL;
HWND hwndWindowLB;
HWND hwndMessageLB;
HWND hwndHelpInstance = NULL;
HHEAP hHeap;
SHORT cxBorder;
SHORT cyBorder;
ULONG uVersion;
BOOL fV11 = TRUE; // Are we version 1.1?
HPOINTER hptrArrow;
HPOINTER hptrSelWin;
HPOINTER hptrIcon11 = NULL; /* 1.1 Spy Icon */
BOOL fDebug = FALSE;
USHORT iCurItemFocus; /* Index to item that has the focus */
BOOL fSpyActive = MIA_CHECKED; /* Any non-zero is true */
BOOL fTrackingListBox = FALSE; /* Tracking windows active ? */
BOOL fAllFrames = 0; /* Are we processing all frames ? */
BOOL fAllWindows = 0; /* Are we processing all windows ? */
HWND hwndWinDlgDisp = NULL; /* hwnds info in Window Dialog */
SHORT wDumpCount = 0; /* Count of which window is being dumped */
SPWD *pspwd = NULL;
/*********************************************************************** */
/* Define memory semaphore to have second thread sleep on */
HEV hevThread; /* Event semaphore to wait on */
UCHAR rgMsgData[MAXMSGBYTES]; /* Max bytes to extract per message */
char szSpyClass[] = "Spy";
char szTitle[] = "32-bit spy sample";
/************* PROCEDURE DECLARATIONS */
void ProcHookThread(void); /* will process the hook messages */
void ProcessQueueMsg(QMSGSPY *);
void UpdateMsgBoxCurMsgText(HWND);
void InitializeOptions(int, char **); /* initialize Spy initial state */
void InitializeMenus(void);
void InitializeHelp(void);
void DebugBreak(void);
PSZ DumpParam(PSZ prgData, SHORT cb, BOOL fValidData,
UCHAR bMPType);
/* Define some variables needed for help processing */
/**************************** Public Function ******************************\
* int cdecl main (argc, argv)
*
* Effects: Spy Main function
*
* Return value:
\***************************************************************************/
int main(argc, argv)
int argc;
char **argv;
{
ULONG flCreateFlags;
QMSG qmsg;
RECTL rcl;
TID tid;
// Make sure the Spy Hook DLL is initialized
SpyInitializeHook();
hab = WinInitialize(0);
uVersion = WinQueryVersion(hab);
if ((LOBYTE(LOUSHORT(uVersion)) > 10) ||
(HIBYTE(LOUSHORT(uVersion)) > 10))
fV11 = FALSE;
hmqSpy = WinCreateMsgQueue(hab, 0);
if (!WinRegisterClass((HAB)NULL, szSpyClass, (PFNWP)SpyWndProc,
CS_SYNCPAINT, 0)) {
WinAlarm(HWND_DESKTOP, WA_ERROR);
return(0);
}
/*
* We need to process the options, before we create a heap, or we
* will blow away our options
*/
InitializeOptions(argc, argv); /* initialize Spy initial state */
/*
* Create a heap for the program
*/
hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0);
hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
cxBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
cyBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE);
SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
SpySetAllWindowOpt (fAllWindows);
SpySetAllFrameOpt (fAllFrames);
flCreateFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER
| FCF_MINMAX | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_MENU
| FCF_ACCELTABLE | FCF_ICON;
// See if we get here
hwndSpyFrame = WinCreateStdWindow(HWND_DESKTOP,
WS_VISIBLE,
(PULONG)&flCreateFlags,
(PSZ)szSpyClass, (PSZ)szTitle,
WS_VISIBLE,
(HMODULE)NULL, IDR_SPY,
(PHWND)&hwndSpy);
WinQueryWindowRect(hwndSpy, &rcl);
hwndSpyList = WinCreateWindow (hwndSpy, WC_LISTBOX, "",
fV11 ? (WS_VISIBLE | LS_NOADJUSTPOS) :
(WS_VISIBLE | LS_NOADJUSTPOS | LS_HORZSCROLL),
-cxBorder, -cyBorder,
(SHORT)(rcl.xRight - rcl.xLeft) + 2 * cxBorder,
(SHORT)(rcl.yTop - rcl.yBottom) + 2 * cyBorder,
hwndSpy, HWND_TOP, DID_SPYLIST, NULL, NULL);
/*
* Read the os2.ini information if it exists, and set the menu items
* to correspond to the initial state read from OS2.ini
*/
InitializeMenus();
InitializeHelp();
/*
* Set the focus to the list box. Note: Only call WinSetFocus if
* our frame is the active window. As we may have been started in
* the background. If this is the case, we want to set the frames
* focus save to the listbox, such that it will be the active window
* when our frame is activated
*/
if (WinQueryWindow(HWND_DESKTOP, QW_TOP, FALSE) == hwndSpyFrame)
WinSetFocus(HWND_DESKTOP, hwndSpyList);
else
WinSetWindowULong(hwndSpyFrame, QWL_HWNDFOCUSSAVE,
(ULONG)hwndSpyList);
/* Start the thread that will process the messages from the hook */
DosCreateEventSem(NULL, &hevThread, 0L, FALSE);
DosCreateThread((PTID)&tid, ProcHookThread, 0L, 0L, 4096L);
UpdateHooksMsgTable(); /* Set Spys Msg table */
SpyHookOnOrOff (TRUE); /* Turn the hook on */
/*
* Now process all of the messages
*/
while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) {
WinDispatchMsg(NULL, (PQMSG)&qmsg);
}
SpyReleaseHook (TRUE); /* Release input hook */
WinDestroyWindow(hwndSpyFrame);
SpyTerminateHook ();
WinDestroyPointer(hptrArrow);
WinDestroyPointer(hptrSelWin);
if (hptrIcon11 != NULL)
WinDestroyPointer (hptrIcon11);
if (hwndHelpInstance != NULL)
WinDestroyHelpInstance(hwndHelpInstance);
WinDestroyMsgQueue(hmqSpy);
WinTerminate(hab);
/* If the spy output file is open, close it now */
if (spyopt.hfileSpy != NULL)
DosClose(spyopt.hfileSpy);
DosExit(EXIT_PROCESS, 0);
}
/**************************** Public Function ******************************\
* InitializeOptions(argc, argv)
*
* Effects: Initialize spy, first from the default options, second from
* OS2.INI file, and override from command switches.
*
* Return value:
\***************************************************************************/
VOID InitializeOptions(argc, argv)
int argc;
char **argv;
{
ULONG cch;
/*
* If the OS2.INI information exists, initialize our options to
* the stored values
*/
if (PrfQueryProfileSize (HINI_USER, "Spy", "Options", &cch) == 0) {
cch = sizeof(SPYOPT);
PrfQueryProfileData(HINI_USER, "Spy", "Options", (PSZ)&spyopt,
&cch);
PrfQueryProfileString(HINI_USER, "Spy", "FileName", "spy.out",
(PSZ)spystr.szFileName, sizeof(spystr.szFileName));
PrfQueryProfileString(HINI_USER, "Spy", "SaveFileName", "spy.lis",
(PSZ)spystr.szSaveFileName, sizeof(spystr.szSaveFileName));
}
/*
* Then check for command line overrides
*/
while (argc > 1) {
argv++; /* get beyond the program name */
/* Test for debug flag */
if (!strcmpi(*argv, "/d") ) {
fDebug = TRUE;
DebugBreak();
}
/* Test for send message hook flag */
if (!strcmpi(*argv, "+s"))
spyopt.bHooks |= SPYH_SENDMSG;
if (!strcmpi(*argv, "-s"))
spyopt.bHooks &= ~SPYH_SENDMSG;
/* Test for input hook flag */
if (!strcmpi(*argv, "+i"))
spyopt.bHooks |= SPYH_INPUT;
if (!strcmpi(*argv, "-i"))
spyopt.bHooks &= ~SPYH_INPUT;
argc--;
}
}
/**************************** Public Function ******************************\
* InitializeMenus()
*
* Effects: Initialize the menus from the initialized defaults.
*
* Return value:
\***************************************************************************/
VOID InitializeMenus()
{
HWND hwndMenu;
USHORT wAction;
/*
* Now we need to update the menu items to the final
* state
*/
hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
MPFROM2SHORT(MIA_CHECKED,
(spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
MPFROM2SHORT(MIA_CHECKED,
(spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
MPFROM2SHORT(MIA_CHECKED,
spyopt.fSendExtend ? MIA_CHECKED : 0));
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTTERM, TRUE),
MPFROM2SHORT(MIA_CHECKED, spyopt.fDebugOutput ? MIA_CHECKED : 0));
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
MPFROM2SHORT(MIA_CHECKED,
spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
/*
* If the options specify output to file, open the file now
*/
if (spyopt.fFile) {
if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
(ULONG *)&wAction, 0L, 0,
0x0012, 0x00C1, 0L) != 0)
spyopt.hfileSpy = NULL; /* Failed on open */
}
}
/**************************** Public Function ******************************\
* InitializeHelp
*
* Effects: Initialize the help subsubsystem.
*
*
* Return value:
\***************************************************************************/
VOID InitializeHelp()
{
/*
* Now initialize Help - First we need to verify that the the help
* DLL is avaialable, if not, we will not do help processing.
*/
HELPINIT hi;
char szTitle[256]; /* Assume the title is not more than 256 chars */
HWND hwndMenu;
SHORT sMenuIndex;
/* Now try to create the help instance */
hi.hmodHelpTableModule =
hi.hmodAccelActionBarModule = (HMODULE)NULL;
hi.pszTutorialName = (PSZ)NULL;
hi.pszHelpLibraryName = "spy32.hlp";
hi.idAccelTable =
hi.idActionBar = 0;
hi.cb = sizeof(HELPINIT);
hi.usShowPanelId = CMIC_HIDE_PANEL_ID;
hi.phtHelpTable = (PHELPTABLE)MAKEULONG(IDR_SPY, 0xffff);
WinQueryWindowText(hwndSpyFrame, sizeof(szTitle), szTitle);
hi.pszHelpWindowTitle = szTitle;
hwndHelpInstance = WinCreateHelpInstance(hab, &hi);
if (hwndHelpInstance != NULL) {
if(!WinAssociateHelpInstance(hwndHelpInstance, hwndSpyFrame) ) {
WinDestroyHelpInstance(hwndHelpInstance);
hwndHelpInstance = (HWND)NULL;
}
}
if (hwndHelpInstance == NULL) {
/* Help was not initialized, so gray out help items */
hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);
for (sMenuIndex = CMD_HOWHELP; sMenuIndex <= CMD_HELPINDEX;
sMenuIndex++) {
WinSendMsg(hwndMenu, MM_SETITEMATTR,
MPFROM2SHORT(sMenuIndex, TRUE),
MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
}
}
}
/**************************** Public Function ******************************\
* MRESULT EXPENTRY SpyWndProc(hwnd, msg, mp1, mp2)
*
* Effects: Spy Client window procedure
*
*
* Return value:
\***************************************************************************/
MRESULT EXPENTRY SpyWndProc(hwnd, msg, mp1, mp2)
HWND hwnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
QMSGSPY qmsgspy;
VOID SpyPaint();
SHORT cBytes;
ULONG ulAction;
switch (msg) {
case WM_CREATE:
/* Set up this global first thing in case we need it elsewhere */
hwndSpy = hwnd;
break;
case WM_SEM2:
/*
* Other thread told use there are some messages out there. Loop
* through and process all of the pending messages, and output
* the listbox position at the end. Also make sure to flush
* the file buffer before we go back to sleep.
*/
while (SpyGetNextMessage(&qmsgspy, rgMsgData, sizeof(rgMsgData), 0L)) {
ProcessQueueMsg(&qmsgspy);
}
if (spyopt.fFile)
DosBufReset(spyopt.hfileSpy);
DosPostEventSem(hevThread);
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1)) {
case CMD_ACTIVE:
/*
* THe active menu item was selected, we will toggle the
* the selection by setting active to 0 or MIA_CHECKED.
* Call the hook, and then update the checkmark on the menu
*/
fSpyActive ^= MIA_CHECKED; /* Toggle on or off */
SpyHookOnOrOff (fSpyActive);
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_ACTIVE, TRUE),
MPFROM2SHORT(MIA_CHECKED, fSpyActive));
break;
case CMD_ABOUT:
WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL,
IDD_About1Dlg, (PCH)NULL);
break;
case CMD_EXIT:
WinPostMsg(NULL, WM_QUIT, 0L, 0L);
break;
case CMD_CLRWIN:
/*
* Delete all items in the list. Simply do this
* By deleting the first item, until the count goes to
* zero
*/
WinSendMsg(hwndSpyList, LM_DELETEALL, 0L, 0L);
break;
case CMD_SAVEWIN:
SpyHookOnOrOff (FALSE);
WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
(PFNWP)SpySaveListDlgProc, (HMODULE)NULL,
IDD_SaveListDlg, (PCH)NULL);
SpyHookOnOrOff (fSpyActive);
break;
/*
* This command saves out the current options to OS2.ini
*/
case CMD_SAVEOPT:
PrfWriteProfileData(HINI_USER, "Spy", "Options", (PSZ)&spyopt,
sizeof(SPYOPT));
PrfWriteProfileString(HINI_USER, "Spy", "FileName",
(PSZ)spystr.szFileName);
PrfWriteProfileString(HINI_USER, "Spy", "SaveFileName",
(PSZ)spystr.szSaveFileName);
break;
case CMD_WINDOWS:
SpyHookOnOrOff (FALSE);
hwndWindowLB = NULL;
iCurItemFocus = (USHORT)-1;
WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
(PFNWP)SpyWindowsDlgProc, (HMODULE)NULL,
IDD_WindowsDlg, (PCH)NULL);
SpyHookOnOrOff (fSpyActive);
break;
case CMD_QUEUES:
SpyHookOnOrOff (FALSE);
hwndWindowLB = NULL;
iCurItemFocus = (USHORT)-1;
WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
(PFNWP)SpyQueuesDlgProc, (HMODULE)NULL,
IDD_MsgQueueDlg, (PCH)NULL);
SpyHookOnOrOff (fSpyActive);
break;
case CMD_WNMSSEL:
case CMD_WNMSDSL:
SpyHookOnOrOff (FALSE);
SelOrDeselWithMouse(SHORT1FROMMP(mp1) == CMD_WNMSSEL);
SpyHookOnOrOff (fSpyActive);
break;
case CMD_ALLWNDWS:
/*
* The user selected the ALLFRAMES, toggle the state, and
* update the menu and the hook state.
*/
fAllWindows ^= MIA_CHECKED; /* Toggle on or off */
SpySetAllWindowOpt (fAllWindows);
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLWNDWS, TRUE),
MPFROM2SHORT(MIA_CHECKED, fAllWindows));
break;
case CMD_ALLFRAMES:
/*
* The user selected the ALLFRAMES, toggle the state, and
* update the menu and the hook state.
*/
fAllFrames ^= MIA_CHECKED; /* Toggle on or off */
SpySetAllFrameOpt (fAllFrames);
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLFRAMES, TRUE),
MPFROM2SHORT(MIA_CHECKED, fAllFrames));
break;
case CMD_WNDPWIN:
wDumpCount = 0;
DumpOneWindowInfo();
break;
case CMD_WNDPALL:
wDumpCount = 0;
pspwd = (SPWD *)WinAllocMem(hHeap, sizeof(SPWD)* MAXSPYDUMP);
cBytes = DumpAllWindowsInfo(HWND_DESKTOP, 0);
cBytes += DumpAllWindowsInfo(HWND_OBJECT, -10);
DumpWindowIndex(cBytes);
WinFreeMem(hHeap, (char *)pspwd, sizeof(SPWD)* MAXSPYDUMP);
break;
case CMD_DACCEL:
DumpFrameAcclTable();
break;
case CMD_MESSAGES:
SpyHookOnOrOff (FALSE);
WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
(PFNWP)SpyMsgDlgProc, (HMODULE)NULL,
IDD_MessagesDlg, (PCH)NULL);
SpyHookOnOrOff (fSpyActive);
break;
case CMD_ALPHASORT:
spyopt.fAlphaSortMsgList ^= TRUE;
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
MPFROM2SHORT(MIA_CHECKED,
spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
break;
case CMD_SENDMSG:
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSG, TRUE),
MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
WinLoadDlg(HWND_DESKTOP, hwndSpyFrame,
(PFNWP)SendMsgDlgProc, (HMODULE)NULL,
IDD_SendMsgDlg, (PCH)NULL);
break;
/*
* The command in this section are defined in the Hooks Menu.
* All of these items toggle selections on or off. The first two
* Items must be registered with the input hook. The last two simply
* retrict how much information is displayed for send messages
*/
case CMD_INPUTHOOK:
spyopt.bHooks ^= SPYH_INPUT;
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
MPFROM2SHORT(MIA_CHECKED,
(spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
SpyReleaseHook (FALSE); /* Dont clear queue */
SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
break;
case CMD_SENDMSGHOOK:
spyopt.bHooks ^= SPYH_SENDMSG;
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
MPFROM2SHORT(MIA_CHECKED,
(spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
SpyReleaseHook (FALSE); /* Dont clear queue */
SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
break;
case CMD_SENDEXTEND:
spyopt.fSendExtend ^= 1; /* Toggle on or off */
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
MPFROM2SHORT(MIA_CHECKED,
spyopt.fSendExtend ? MIA_CHECKED : 0));
break;
/*
* The commands in this section are defined in the Outputs Menu.
* The first 3 items simply toggle outputs on or off, where the
* last item allows the user to change all of the output options.
*/
case CMD_OUTSCREEN:
spyopt.fWindow ^= 1; /* Toggle on or off */
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
break;
case CMD_OUTTERM:
spyopt.fDebugOutput ^= 1; /* Toggle on or off */
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTTERM, TRUE),
MPFROM2SHORT(MIA_CHECKED, spyopt.fDebugOutput ? MIA_CHECKED : 0));
break;
case CMD_OUTFILE:
spyopt.fFile ^= 1; /* Toggle on or off */
WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
/*
* Open or close the output file
*/
if (spyopt.fFile) {
if (spyopt.hfileSpy == NULL)
if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
&ulAction, 0L, 0,
0x0012, 0x00C1, 0L) != 0)
spyopt.hfileSpy = NULL; /* Failed on open */
} else {
if (spyopt.hfileSpy != NULL) {
/* file open, not outputing, close it now */
DosClose (spyopt.hfileSpy);
spyopt.hfileSpy = NULL;
}
}
break;
case CMD_OUTPUTS:
SpyHookOnOrOff (FALSE);
WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
(PFNWP)SpyOutputsDlgProc, (HMODULE)NULL,
IDD_OutputsDlg, (PCH)NULL);
SpyHookOnOrOff (fSpyActive);
break;
case CMD_MGDABLE:
case CMD_MGEABLE:
EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE);
break;
/*
* Help Menu items, send message to help manager
*/
case CMD_HOWHELP:
if (hwndHelpInstance != NULL)
WinSendMsg(hwndHelpInstance, HM_DISPLAY_HELP,
(MPARAM)NULL, (MPARAM)NULL);
break;
/* Extended help option was chosen from pull-down */
case CMD_HELPEXTENDED:
if (hwndHelpInstance != NULL)
WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
(MPARAM) 0, (MPARAM) 0 );
break;
/* Keys help option was chosen from pull-down */
case CMD_HELPKEYS:
if (hwndHelpInstance != NULL)
WinSendMsg(hwndHelpInstance, HM_KEYS_HELP,
(MPARAM) 0, (MPARAM) 0 );
break;
/* Index option was chosen from pull-down */
case CMD_HELPINDEX:
if (hwndHelpInstance != NULL)
WinSendMsg(hwndHelpInstance, HM_HELP_INDEX,
(MPARAM) 0, (MPARAM) 0 );
break;
}
break;
case HM_HELPSUBITEM_NOT_FOUND:
if (hwndHelpInstance != NULL)
(void)WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
(MPARAM)NULL, (MPARAM)NULL);
break;
case HM_QUERY_KEYS_HELP:
return (MRESULT)HLP_KEYS;
case WM_SIZE:
/* We need to resize the listbox, if it exists */
if (hwndSpyList != NULL) {
WinSetWindowPos(hwndSpyList, HWND_TOP, -cxBorder, -cyBorder,
SHORT1FROMMP(mp2) + 2 * cxBorder,
SHORT2FROMMP(mp2) + 2 * cyBorder, SWP_MOVE | SWP_SIZE);
}
/* Now fall through to process the message */
default:
return(WinDefWindowProc(hwnd, msg, mp1, mp2));
break;
}
return(0L);
}
/***************************** Private Function ****************************\
* USHORT UConvertStringToNum(psz)
*
* Effects:
* Converts the passed string to a number 0xffff if not number
*
* History:
* 27-September-1988 KurtE
\***************************************************************************/
USHORT UConvertStringToNum(psz)
register char *psz;
{
register USHORT uNum;
/*
* This aint to fancy yet, but if the first few chars are
* 0x, we assume the user typed in a HEX number, else if 0-9,
* we assume decimal, else we use the string, also for windows if the
* user left the 0000:0000 we ignore the high end and assume it is
* hex.
*/
/* First see if digit in first position */
if ((*psz >= '0') && (*psz <= '9')) {
/* Assume numbers now */
if ((*psz == '0') && (*(psz+1) == 'x')) {
/* We are in hex mode */
psz += 2;
uNum = 0;
for (;;) {
if ((*psz >= '0') && (*psz <= '9'))
uNum = uNum * 16 + (USHORT)(*psz - '0');
else if ((*psz >= 'a') && (*psz <= 'f'))
uNum = uNum * 16 + (USHORT)(*psz - 'a');
else if ((*psz >= 'F') && (*psz <= 'F'))
uNum = uNum * 16 + (USHORT)(*psz - 'A');
else
break;
psz++;
}
} else {
/* Decimal mode */
uNum = (USHORT)(*psz++ - '0');
while ((*psz >= '0') && (*psz <= '9')) {
uNum = uNum * 10 + (USHORT)(*psz++ - '0');
}
}
return (uNum);
} else if (psz=strchr(psz,':')) {
// boy this is sh.t, it should be combined above!!!
/* We are in hex mode */
psz++;
uNum = 0;
for (;;) {
if ((*psz >= '0') && (*psz <= '9'))
uNum = uNum * 16 + (USHORT)(*psz - '0');
else if ((*psz >= 'a') && (*psz <= 'f'))
uNum = uNum * 16 + (USHORT)(*psz - 'a');
else if ((*psz >= 'F') && (*psz <= 'F'))
uNum = uNum * 16 + (USHORT)(*psz - 'A');
else
break;
psz++;
}
} else
/* Not num, return 0xffff */
return (0xffff);
}
/**************************** Public Function ******************************\
* void ProcHookThread()
*
* Effects: This function will wait for the hook to have messages, when it
* does, it will Set a memory semaphore, Post a WM_SEM1 message to the other
* thread, and wait for the other thread has processed all of the messages.
*
* Return value: none
\***************************************************************************/
void ProcHookThread()
{
ULONG ulPostCt;
/* We'll look for a variation to run while the thread is active. */
if (fDebug)
DebugBreak();
while (TRUE) {
/*
* Wait for a message to become available.
*/
if (!SpyGetNextMessage(NULL, NULL, 0, -1L))
break;
/*
* Now we have a message, set our semaphore, Post a WM_SEM2
* message to the Client window, and wait for the client to
* clear the semaphore.
*/
DosResetEventSem(hevThread, &ulPostCt);
WinPostMsg(hwndSpy, WM_SEM2, (MPARAM)1, (MPARAM)1);
DosWaitEventSem(hevThread, -1L);
}
DosExit(EXIT_THREAD, 0);
}
/**************************** Public Function ******************************\
* void ProcessQueueMsg(pqmsg)
*
* Effects: This function will process the hook, by calling the hooks
* get message. We will than post the message to the current output
* destinations.
*
* Return value: none
\***************************************************************************/
void ProcessQueueMsg(pqmsgspy)
QMSGSPY *pqmsgspy;
{
MSGI *pmsgi;
CHAR cSource;
CHAR cThread;
char szNextMessage[100];
char szTime[12];
SHORT cch;
CHAR bAscii;
PSZ prgData;
/*
* Now lets Build the message to output
*/
if (WinIsWindow(hab, pqmsgspy->qmsg.hwnd)) {
if (WinIsChild(pqmsgspy->qmsg.hwnd, hwndSpy))
return; /* dont want endless loops */
}
cThread = ':';
if (pqmsgspy->qmsg.time == (ULONG)-1) {
/* Sent message */
szTime[0] = '\0';
cSource = 'S';
if (pqmsgspy->fs)
cThread = '*';
} else {
cSource = 'I';
if (pqmsgspy->fs != PM_REMOVE)
cThread = '-'; /* Show different for non-remove */
sprintf (szTime, "%-08lx", pqmsgspy->qmsg.time);
}
if ((pmsgi = PmsgiFromMsg(pqmsgspy->qmsg.msg)) == NULL) {
/*
* Message not in list, use default
*/
cch = sprintf(szNextMessage,
"%c%cMSG:0x%04x H:%p 1:%08lx 2:%08lx T:%s",
cSource, cThread, (SHORT)pqmsgspy->qmsg.msg, pqmsgspy->qmsg.hwnd,
pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
} else if (pmsgi->wOptions & MSGI_MOUSE) {
/*
* Mouse message, decode to mouse types
*/
cch = sprintf(szNextMessage,
"%c%c%-20s H:%p X:%-4d Y:%-4d HT:%04x T:%s",
cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
SHORT1FROMMP(pqmsgspy->qmsg.mp1), SHORT2FROMMP(pqmsgspy->qmsg.mp1),
SHORT1FROMMP(pqmsgspy->qmsg.mp2), szTime);
} else if (pmsgi->wOptions & MSGI_KEY) {
/*
* Key messages, output special
*/
bAscii = (CHAR)SHORT1FROMMP(pqmsgspy->qmsg.mp2);
if ((bAscii < ' ') || (bAscii > '~'))
bAscii = ' ';
cch = sprintf(szNextMessage,
"%c%c%-20s H:%p F:%04x R:%d S:%2x C:%04x(%c) V:%02x T:%s",
cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
SHORT1FROMMP(pqmsgspy->qmsg.mp1),
CHAR3FROMMP(pqmsgspy->qmsg.mp1), CHAR4FROMMP(pqmsgspy->qmsg.mp1),
SHORT1FROMMP(pqmsgspy->qmsg.mp2), bAscii,
SHORT2FROMMP(pqmsgspy->qmsg.mp2), szTime);
} else {
/* No special format */
cch = sprintf(szNextMessage,
"%c%c%-20s H:%p 1:%08lx 2:%08lx T:%s",
cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
}
OutputString(szNextMessage, cch);
/*
* Now dump out any additional information associated with the
* message. The processing depends of the type of message on
* how we are going to process the data.
*/
if (spyopt.fSendExtend) {
prgData = DumpParam((PSZ)rgMsgData, pqmsgspy->cbDataMP1,
pqmsgspy->fMP1Valid, pqmsgspy->bMPType);
DumpParam(prgData, pqmsgspy->cbDataMP2, pqmsgspy->fMP1Valid,
(UCHAR)((pqmsgspy->bMPType) >> 3));
}
}
/**************************** Public Function ******************************\
* PSZ DumpParam(PSZ prgData, MPARAM mp, SHORT cb, BOOL fValid, UCHAR bMPType)
*
* Dump the additional information that was captured for the message.
* using the currently defined types.
*
* Return value: PSZ - Pointer to next available byte after process DATA
\***************************************************************************/
PSZ DumpParam(prgData, cb, fValidData, bMPType)
PSZ prgData;
SHORT cb;
BOOL fValidData;
UCHAR bMPType;
{
char szNextMessage[100];
SHORT cch;
if (fValidData) {
/* Process by type */
switch (bMPType & 0x07) {
case MPT_SWP:
cch = sprintf(szNextMessage,
" SWP: fs:%p cx:%d cy:%d y:%d x:%d HB:%p H:%p",
((PSWP)prgData)->fl, ((PSWP)prgData)->cy, ((PSWP)prgData)->cx,
((PSWP)prgData)->y, ((PSWP)prgData)->x,
((PSWP)prgData)->hwndInsertBehind,
((PSWP)prgData)->hwnd);
break;
case MPT_RECTL:
cch = sprintf(szNextMessage,
" RECTL: xLeft:%d yBottom:%d xRight:%d yTop:%d",
((PRECTL)prgData)->xLeft, ((PRECTL)prgData)->yBottom,
((PRECTL)prgData)->xRight, ((PRECTL)prgData)->yTop);
break;
case MPT_QMSG:
cch = sprintf(szNextMessage,
" QMSG: H:%p M:%04x M1:%08lx M2:%08lx T:%08lx (%d, %d)",
((PQMSG)prgData)->hwnd, ((PQMSG)prgData)->msg,
((PQMSG)prgData)->mp1,((PQMSG)prgData)->mp2,
((PQMSG)prgData)->time,
((PQMSG)prgData)->ptl.x, ((PQMSG)prgData)->ptl.y);
break;
default:
goto NoData;
}
OutputString(szNextMessage, cch);
}
NoData:
return (prgData + cb);
}
/**************************** Public Function ******************************\
* void OutputString(char szOut, SHORT cch);
*
* Effects: This function will output the specified string to the
* destinations.
*
* Return value: none
\***************************************************************************/
void OutputString(szOut, cch)
char szOut[];
SHORT cch;
{
SHORT item;
char *psz;
ULONG cchWritten;
/* This is a private entry point in the PMWIN dll that places */
/* strings into the window. */
SHORT _far16 _pascal _loadds DebugOutput( char _far16 * );
/* Now display the new Line on the screen */
if (spyopt.fWindow) {
item = (SHORT)WinSendMsg(hwndSpyList, LM_INSERTITEM,
(MPARAM)LIT_END, (MPARAM)(PSZ)szOut);
WinSendMsg(hwndSpyList, LM_SETTOPINDEX, (MPARAM)item, 0L);
/* See if we have to many lines now */
while (item >= spyopt.cWindowLines)
item = (SHORT)WinSendMsg(hwndSpyList, LM_DELETEITEM,
(MPARAM)0, 0L);
}
/* now for file or debug terminal need cr/lf */
psz = szOut + cch; /* point to trailing null */
*psz++ = '\r';
*psz++ = '\n';
*psz = '\0';
if (spyopt.fDebugOutput)
DebugOutput((char _far16*)szOut);
if (spyopt.fFile)
DosWrite(spyopt.hfileSpy, (PSZ)szOut, cch+2,
&cchWritten);
}
/**************************** Public Function ******************************\
* MSGI * PmsgiFromMsg(USHORT msg)
*
* Effects: Locate the msg in the array of message items
*
* Return value: pointer to item that has the specified msg, or NULL
\***************************************************************************/
MSGI *PmsgiFromMsg(msg)
USHORT msg;
{
register MSGI *pmsgi = rgmsgi; /* Start at beginning */
register USHORT i;
/*
* Currently is a simple linear search, should be made faster
* Probabably a binary search.
*/
for (i=0; i< cmsgi; i++) {
if (pmsgi->msg == msg)
return (pmsgi);
if (pmsgi->msg > msg)
return (NULL);
pmsgi++;
};
return (NULL);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.