Annotation of pmsdk/samples/spy/spy.c, revision 1.1.1.2

1.1.1.2 ! root        1: /***************************************************************************\
        !             2: * spy.c - Spy application
1.1       root        3: *
1.1.1.2 ! root        4: * Created by Microsoft Corporation, 1989
1.1       root        5: \***************************************************************************/
                      6: 
                      7: #define INCL_DOSPROCESS
1.1.1.2 ! root        8: #define        INCL_WINDIALOGS
        !             9: #define        INCL_WINFRAMEMGR
        !            10: #define        INCL_WINHEAP
        !            11: #define        INCL_WININPUT
        !            12: #define        INCL_WINLISTBOXES
        !            13: #define        INCL_WINMENUS
        !            14: #define        INCL_WINMESSAGEMGR
        !            15: #define        INCL_WINPOINTERS
        !            16: #define        INCL_WINSHELLDATA
        !            17: #define        INCL_WINSYS
        !            18: #define        INCL_WINWINDOWMGR
        !            19: #include <os2.h>
        !            20: #include <stdio.h>
        !            21: #include <stdlib.h>
        !            22: #include <string.h>
        !            23: #include <spyhook.h>
        !            24: #include <time.h>
1.1       root       25: #include "spy.h"
                     26: 
1.1.1.2 ! root       27: /* File Local Variables */
1.1       root       28: HAB         hab;
                     29: HMQ         hmqSpy;
                     30: HWND        hwndSpy;
                     31: HWND        hwndSpyFrame;
                     32: HWND        hwndSpyList = NULL;
                     33: HWND        hwndWindowLB;
                     34: HWND        hwndMessageLB;
                     35: HHEAP       hHeap;
1.1.1.2 ! root       36: SHORT       cxBorder;
        !            37: SHORT       cyBorder;
1.1       root       38: 
                     39: HPOINTER    hptrArrow;
                     40: HPOINTER    hptrSelWin;
                     41: 
                     42: USHORT      iCurItemFocus;              /* Index to item that has the focus */
                     43: BOOL        fSpyActive = MIA_CHECKED;   /* Any non-zero is true */
1.1.1.2 ! root       44: BOOL        fTrackingListBox = FALSE;   /* Tracking windows active ? */
1.1       root       45: BOOL        fAllFrames = 0;             /* Are we processing all frames ? */
1.1.1.2 ! root       46: BOOL        fAllWindows = 0;            /* Are we processing all windows ? */
1.1       root       47: 
                     48: 
                     49: HWND        hwndWinDlgDisp = NULL;      /* hwnds info in Window Dialog */
                     50: 
                     51: SHORT       wDumpCount = 0;             /* Count of which window is being dumped */
1.1.1.2 ! root       52: SPWD        *pspwd = NULL;
1.1       root       53: 
                     54: 
1.1.1.2 ! root       55: /* Define memory semaphore to have second thread sleep on */
        !            56: ULONG       semThread = 0L;             /* Thread to wait on */
        !            57: int         AboutCount = 0;
        !            58: UCHAR       rgMsgData[MAXMSGBYTES];     /* Max bytes to extract per message */
1.1       root       59: 
                     60: 
1.1.1.2 ! root       61: char szSpyClass[] = "Spy";
        !            62: char szTitle[] = "";
1.1       root       63: 
1.1.1.2 ! root       64: /* Function Prototypes */
        !            65: int    cdecl main(int, char **);
1.1       root       66: void    FAR ProcHookThread(void);    /* will process the hook messages */
1.1.1.2 ! root       67: void    ProcessQueueMsg(QMSGSPY *);
        !            68: void    UpdateMsgBoxCurMsgText(HWND);
        !            69: void    InitializeOptions(int, char **);    /* initialize Spy initial state */
        !            70: PSZ     DumpParam(PSZ prgData, MPARAM mp, SHORT cb, UCHAR bMPType);
        !            71: MRESULT CALLBACK SpyWndProc(HWND, USHORT, MPARAM, MPARAM);
        !            72: VOID   SpyPaint(VOID);
1.1       root       73: 
                     74: 
1.1.1.2 ! root       75: /***************************************************************************\
1.1       root       76: * int cdecl main (argc, argv)
                     77: *
1.1.1.2 ! root       78: * Spy Main function
1.1       root       79: \***************************************************************************/
                     80: int cdecl main(argc, argv)
                     81: int argc;
                     82: char **argv;
                     83: {
                     84:     ULONG   flCreateFlags;
                     85:     QMSG    qmsg;
                     86:     RECTL   rcl;
                     87:     TID     tid;
                     88:     char    *prgStack;
                     89: 
                     90: 
                     91:     hab = WinInitialize(0);
                     92: 
                     93:     hmqSpy = WinCreateMsgQueue(hab, 0);
                     94: 
                     95:     if (!WinRegisterClass((HAB)NULL, szSpyClass, (PFNWP)SpyWndProc,
1.1.1.2 ! root       96:             CS_SYNCPAINT, 0)) {
1.1       root       97:         WinAlarm(HWND_DESKTOP, 0xffff);
                     98:         return(0);
                     99:     }
                    100: 
1.1.1.2 ! root      101: 
1.1       root      102:     /*
                    103:      * Create a heap for the program
                    104:      */
                    105:     hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0);
                    106: 
                    107:     /*
                    108:      * Create a stack for the thread - also initialize the stack by zeroing
                    109:      * the first 32 bytes, and filling the remainder with a known value
                    110:      */
                    111:     prgStack = WinAllocMem(hHeap, CBSTACK);
                    112:     if (prgStack == NULL)
                    113:         goto Abort;
                    114:     memset(prgStack, '\0', 32); /* Init first 32 bytes to zero */
                    115:     memset(prgStack+32,'\345', CBSTACK-32); /* Remainder to known value */
                    116: 
1.1.1.2 ! root      117:     hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
        !           118:     cxBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
        !           119:     cyBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
1.1       root      120: 
1.1.1.2 ! root      121:     hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE);
1.1       root      122: 
1.1.1.2 ! root      123:     SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
1.1       root      124:     SpySetAllWindowOpt (fAllWindows);
                    125:     SpySetAllFrameOpt (fAllFrames);
                    126: 
1.1.1.2 ! root      127:     flCreateFlags = FCF_STANDARD;
1.1       root      128:     hwndSpyFrame = WinCreateStdWindow(HWND_DESKTOP,
1.1.1.2 ! root      129:             WS_VISIBLE,
1.1       root      130:             (VOID FAR *)&flCreateFlags,
                    131:             szSpyClass, szTitle,
                    132:             WS_VISIBLE,
                    133:             (HMODULE)NULL, IDR_SPY,
                    134:             (HWND FAR *)&hwndSpy);
                    135: 
                    136:     WinQueryWindowRect(hwndSpy, &rcl);
                    137:     hwndSpyList = WinCreateWindow (hwndSpy, WC_LISTBOX, "",
                    138:             WS_VISIBLE | LS_NOADJUSTPOS,
1.1.1.2 ! root      139:             -cxBorder, -cyBorder,
        !           140:             (SHORT)(rcl.xRight - rcl.xLeft) + 2 * cxBorder,
        !           141:             (SHORT)(rcl.yTop - rcl.yBottom) + 2 * cyBorder,
1.1       root      142:             hwndSpy, HWND_TOP, DID_SPYLIST, NULL, NULL);
                    143: 
1.1.1.2 ! root      144:     /*
        !           145:      * Read the os2.ini information if it exists, and set the menu items
        !           146:      * to correspond to the initial state read from OS2.INI.
        !           147:      */
        !           148:     InitializeOptions(argc, argv);    /* initialize Spy initial state */
        !           149: 
        !           150:     /*
        !           151:      * Set the focus to the list box.  Note: Only call WinSetFocus if
        !           152:      * our frame is the active window.  As we may have been started in
        !           153:      * the background.  If this is the case, we want to set the frame's
        !           154:      * focus save to the listbox, such that it will be the active window
        !           155:      * when our frame is activated.
        !           156:      */
        !           157:     if (WinQueryWindow(HWND_DESKTOP, QW_TOP, FALSE) == hwndSpyFrame)
        !           158:         WinSetFocus(HWND_DESKTOP, hwndSpyList);
        !           159:     else
        !           160:         WinSetWindowULong(hwndSpyFrame, QWL_HWNDFOCUSSAVE,
        !           161:             (ULONG)hwndSpyList);
        !           162: 
1.1       root      163: 
                    164: 
                    165:     /* Start the thread that will process the messages from the hook */
                    166:     DosCreateThread(ProcHookThread, (PTID)&tid,
                    167:         (PBYTE)(prgStack + CBSTACK - 1));
                    168: 
1.1.1.2 ! root      169:     UpdateHooksMsgTable();      /* Set Spy's Message Table */
1.1       root      170:     SpyHookOnOrOff (TRUE);      /* Turn the hook on */
                    171: 
1.1.1.2 ! root      172: 
        !           173:    /*
        !           174:     * Now process all of the messages
        !           175:     */
1.1       root      176:     while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) {
                    177:         WinDispatchMsg(NULL, (PQMSG)&qmsg);
                    178:     }
                    179: 
                    180:     SpyReleaseHook (TRUE);      /* Release input hook */
                    181: 
                    182:     WinDestroyWindow(hwndSpyFrame);
                    183: 
1.1.1.2 ! root      184:     WinDestroyPointer(hptrArrow);
        !           185:     WinDestroyPointer(hptrSelWin);
1.1       root      186: 
                    187: Abort:
                    188:     WinDestroyMsgQueue(hmqSpy);
                    189:     WinTerminate(hab);
                    190: 
                    191:     /* If the spy output file is open, close it now */
                    192:     if (spyopt.hfileSpy != NULL)
                    193:         DosClose(spyopt.hfileSpy);
                    194: 
1.1.1.2 ! root      195: 
1.1       root      196:     DosExit(EXIT_PROCESS, 0);
                    197: }
                    198: 
                    199: 
1.1.1.2 ! root      200: 
        !           201: 
        !           202: /***************************************************************************\
        !           203: * InitializeOptions(argc, argv)
1.1       root      204: *
1.1.1.2 ! root      205: * Initialize spy, first from the default options, second from
        !           206: * OS2.INI file, and override from command switches.
        !           207: \***************************************************************************/
        !           208: VOID InitializeOptions(argc, argv)
        !           209: int argc;
        !           210: char **argv;
        !           211: {
        !           212:     USHORT      cch;
        !           213:     USHORT      wAction;
        !           214:     HWND        hwndMenu;
        !           215: 
        !           216: 
        !           217:     /*
        !           218:      * If the OS2.INI information exists, initialize our options to
        !           219:      * the stored values.
        !           220:      */
        !           221:     if (WinQueryProfileSize (hab, "Spy", "Options", &cch) == 0) {
        !           222:         cch = sizeof(SPYOPT);
        !           223: 
        !           224:         WinQueryProfileData(hab, "Spy", "Options", (PSZ)&spyopt,
        !           225:                 &cch);
        !           226:         WinQueryProfileString(hab, "Spy", "FileName", "spy.out",
        !           227:                 (PSZ)spystr.szFileName, sizeof(spystr.szFileName));
        !           228:         WinQueryProfileString(hab, "Spy", "SaveFileName", "spy.lis",
        !           229:                 (PSZ)spystr.szSaveFileName, sizeof(spystr.szSaveFileName));
        !           230:     }
        !           231: 
        !           232:     /*
        !           233:      * Then check for command line overrides
        !           234:      */
        !           235:     while  (argc > 1) {
        !           236:         argv++; /* get beyond the program name */
        !           237: 
        !           238:         /* Test for send message hook flag */
        !           239:         if (!strcmpi(*argv, "+s"))
        !           240:             spyopt.bHooks |= SPYH_SENDMSG;
        !           241:         if (!strcmpi(*argv, "-s"))
        !           242:             spyopt.bHooks &= ~SPYH_SENDMSG;
        !           243: 
        !           244:         /* Test for input hook flag */
        !           245:         if (!strcmpi(*argv, "+i"))
        !           246:             spyopt.bHooks |= SPYH_INPUT;
        !           247:         if (!strcmpi(*argv, "-i"))
        !           248:             spyopt.bHooks &= ~SPYH_INPUT;
        !           249: 
        !           250:         argc--;
        !           251:     }
        !           252: 
        !           253:     /*
        !           254:      * Now we need to update the menu items to the final
        !           255:      * state
        !           256:      */
        !           257:     hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);
        !           258: 
        !           259:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
        !           260:             MPFROM2SHORT(MIA_CHECKED,
        !           261:              (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
        !           262:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
        !           263:              MPFROM2SHORT(MIA_CHECKED,
        !           264:              (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
        !           265: 
        !           266:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
        !           267:             MPFROM2SHORT(MIA_CHECKED,
        !           268:              spyopt.fSendExtend ? MIA_CHECKED : 0));
        !           269: 
        !           270:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDSTACK, TRUE),
        !           271:             MPFROM2SHORT(MIA_CHECKED,
        !           272:             spyopt.fSendStack ? MIA_CHECKED : 0));
        !           273:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
        !           274:             MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
        !           275: 
        !           276:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
        !           277:             MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
        !           278: 
        !           279:     WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
        !           280:             MPFROM2SHORT(MIA_CHECKED,
        !           281:                     spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
        !           282: 
        !           283:     /*
        !           284:      * If the options specify output to file, open the file now
        !           285:      */
        !           286:     if (spyopt.fFile) {
        !           287:         if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
        !           288:                 (USHORT far *)&wAction, 0L, 0,
        !           289:                 0x0012, 0x00C1, 0L) != 0)
        !           290:             spyopt.hfileSpy = NULL; /* Failed on open */
        !           291:     }
        !           292: }
        !           293: 
        !           294: 
        !           295: /***************************************************************************\
        !           296: * MRESULT CALLBACK SpyWndProc(hwnd, msg, mp1, mp2)
1.1       root      297: *
1.1.1.2 ! root      298: * Spy Client window procedure
1.1       root      299: \***************************************************************************/
1.1.1.2 ! root      300: MRESULT CALLBACK SpyWndProc(hwnd, msg, mp1, mp2)
1.1       root      301: HWND hwnd;
                    302: USHORT msg;
                    303: MPARAM mp1;
                    304: MPARAM mp2;
                    305: {
1.1.1.2 ! root      306:     QMSGSPY qmsgspy;
        !           307:     SHORT   cBytes;
        !           308:     USHORT      wAction;
1.1       root      309: 
                    310:     switch (msg) {
                    311:     case WM_CREATE:
                    312:         /* Set up this global first thing in case we need it elsewhere */
                    313:         hwndSpy = hwnd;
                    314:         break;
                    315: 
                    316:     case WM_SEM2:
                    317:         /*
                    318:          * Other thread told use there are some messages out there.  Loop
                    319:          * through and process all of the pending messages, and output
                    320:          * the listbox position at the end.  Also make sure to flush
                    321:          * the file buffer before we go back to sleep.
                    322:          */
1.1.1.2 ! root      323:         while (SpyGetNextMessage(&qmsgspy, rgMsgData, sizeof(rgMsgData), 0L)) {
        !           324:             ProcessQueueMsg(&qmsgspy);
1.1       root      325:         }
                    326: 
                    327:         if (spyopt.fFile)
                    328:             DosBufReset(spyopt.hfileSpy);
                    329: 
                    330:         DosSemClear((HSEM)(PULONG)&semThread);
                    331: 
                    332:         break;
                    333: 
                    334:     case WM_COMMAND:
                    335:         switch (SHORT1FROMMP(mp1)) {
                    336:         case CMD_ACTIVE:
                    337: 
                    338:             /*
                    339:              * THe active menu item was selected, we will toggle the
                    340:              * the selection by setting active to 0 or MIA_CHECKED.
                    341:              * Call the hook, and then update the checkmark on the menu
                    342:              */
                    343:             fSpyActive ^= MIA_CHECKED;  /* Toggle on or off */
                    344:             SpyHookOnOrOff (fSpyActive);
                    345:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                    346:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_ACTIVE, TRUE),
                    347:                 MPFROM2SHORT(MIA_CHECKED, fSpyActive));
                    348: 
                    349:             break;
                    350:         case CMD_ABOUT:
1.1.1.2 ! root      351:             WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL, AboutDlg, (PCH)NULL);
1.1       root      352:             break;
                    353: 
                    354:         case CMD_EXIT:
                    355:             WinPostMsg(NULL, WM_QUIT, 0L, 0L);
                    356:             break;
                    357: 
                    358:         case CMD_CLRWIN:
                    359:             /*
                    360:              * Delete all items in the list.  Simply do this
                    361:              * By deleting the first item, until the count goes to
                    362:              * zero
                    363:              */
                    364:             WinSendMsg(hwndSpyList, LM_DELETEALL, 0L, 0L);
                    365:             break;
                    366: 
                    367:         case CMD_SAVEWIN:
                    368:             SpyHookOnOrOff (FALSE);
                    369:             WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                    370:                 (PFNWP)SpySaveListDlgProc, (HMODULE)NULL,
                    371:                 SaveListDlg, (PCH)NULL);
                    372:             SpyHookOnOrOff (fSpyActive);
                    373:             break;
                    374: 
1.1.1.2 ! root      375:         /*
        !           376:          * This command saves out the current options to OS2.ini
        !           377:          */
        !           378:         case CMD_SAVEOPT:
        !           379:             WinWriteProfileData(hab, "Spy", "Options", (PSZ)&spyopt,
        !           380:                     sizeof(SPYOPT));
        !           381:             WinWriteProfileString(hab, "Spy", "FileName",
        !           382:                     (PSZ)spystr.szFileName);
        !           383:             WinWriteProfileString(hab, "Spy", "SaveFileName",
        !           384:                     (PSZ)spystr.szSaveFileName);
        !           385: 
        !           386:             break;
        !           387: 
        !           388:         case CMD_LISTNEAR:
        !           389:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           390:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_LISTNEAR, TRUE),
        !           391:                 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
        !           392:             WinLoadDlg(HWND_DESKTOP, hwndSpyFrame,
        !           393:                 (PFNWP)ListNearDlgProc, (HMODULE)NULL,
        !           394:                 ListNearDlg, (PCH)NULL);
        !           395:             break;
        !           396: 
1.1       root      397:         case CMD_WINDOWS:
                    398:             SpyHookOnOrOff (FALSE);
                    399:             hwndWindowLB = NULL;
                    400:             iCurItemFocus = (USHORT)-1;
                    401:             WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                    402:                 (PFNWP)SpyWindowsDlgProc, (HMODULE)NULL,
                    403:                 WindowsDlg, (PCH)NULL);
                    404: 
                    405:             SpyHookOnOrOff (fSpyActive);
                    406:             break;
                    407: 
1.1.1.2 ! root      408:         case CMD_QUEUES:
        !           409:             SpyHookOnOrOff (FALSE);
        !           410:             hwndWindowLB = NULL;
        !           411:             iCurItemFocus = (USHORT)-1;
        !           412:             WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
        !           413:                 (PFNWP)SpyQueuesDlgProc, (HMODULE)NULL,
        !           414:                 MsgQueueDlg, (PCH)NULL);
        !           415: 
        !           416:             SpyHookOnOrOff (fSpyActive);
        !           417:             break;
        !           418: 
1.1       root      419:         case CMD_WNMSSEL:
                    420:         case CMD_WNMSDSL:
                    421:             SpyHookOnOrOff (FALSE);
                    422:             SelOrDeselWithMouse(SHORT1FROMMP(mp1) == CMD_WNMSSEL);
                    423:             SpyHookOnOrOff (fSpyActive);
                    424:             break;
                    425: 
                    426:         case CMD_ALLWNDWS:
                    427: 
                    428:             /*
                    429:              * The user selected the ALLFRAMES, toggle the state, and
                    430:              * update the menu and the hook state.
                    431:              */
                    432:             fAllWindows ^= MIA_CHECKED;  /* Toggle on or off */
                    433:             SpySetAllWindowOpt (fAllWindows);
                    434:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                    435:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLWNDWS, TRUE),
                    436:                 MPFROM2SHORT(MIA_CHECKED, fAllWindows));
                    437:             break;
                    438: 
                    439:         case CMD_ALLFRAMES:
                    440: 
                    441:             /*
                    442:              * The user selected the ALLFRAMES, toggle the state, and
                    443:              * update the menu and the hook state.
                    444:              */
                    445:             fAllFrames ^= MIA_CHECKED;  /* Toggle on or off */
                    446:             SpySetAllFrameOpt (fAllFrames);
                    447:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                    448:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLFRAMES, TRUE),
                    449:                 MPFROM2SHORT(MIA_CHECKED, fAllFrames));
                    450:             break;
                    451: 
                    452:         case CMD_WNDPWIN:
1.1.1.2 ! root      453:             wDumpCount = 0;
1.1       root      454:             DumpOneWindowInfo();
                    455:             break;
1.1.1.2 ! root      456: 
1.1       root      457:         case CMD_WNDPALL:
1.1.1.2 ! root      458:             wDumpCount = 0;
1.1       root      459:             pspwd = (SPWD *)WinAllocMem(hHeap, sizeof(SPWD)* MAXSPYDUMP);
1.1.1.2 ! root      460:             cBytes = DumpAllWindowsInfo(HWND_DESKTOP, 0);
        !           461:             cBytes += DumpAllWindowsInfo(HWND_OBJECT, -10);
        !           462:             DumpWindowIndex(cBytes);
1.1       root      463:             WinFreeMem(hHeap, (char *)pspwd, sizeof(SPWD)* MAXSPYDUMP);
                    464:             break;
                    465: 
                    466:         case CMD_MESSAGES:
                    467:             SpyHookOnOrOff (FALSE);
                    468:             WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                    469:                 (PFNWP)SpyMsgDlgProc, (HMODULE)NULL,
                    470:                 MessagesDlg, (PCH)NULL);
                    471:             SpyHookOnOrOff (fSpyActive);
                    472:             break;
                    473: 
1.1.1.2 ! root      474:         case CMD_ALPHASORT:
        !           475:             spyopt.fAlphaSortMsgList ^= TRUE;
        !           476: 
        !           477:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           478:                     MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
        !           479:                     MPFROM2SHORT(MIA_CHECKED,
        !           480:                             spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
        !           481:             break;
        !           482: 
        !           483:         /*
        !           484:          * The command in this section are defined in the Hooks Menu.
        !           485:          * All of these items toggle selections on or off.  The first two
        !           486:          * items must be registered with the input hook.  The last two simply
        !           487:          * retrict how much information is displayed for send messages.
        !           488:          */
        !           489: 
        !           490:         case CMD_INPUTHOOK:
        !           491:             spyopt.bHooks ^= SPYH_INPUT;
        !           492:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           493:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
        !           494:                 MPFROM2SHORT(MIA_CHECKED,
        !           495:                      (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
        !           496:                 SpyReleaseHook (FALSE);     /* Dont clear queue */
        !           497:                 SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
        !           498:             break;
        !           499: 
        !           500:         case CMD_SENDMSGHOOK:
        !           501:             spyopt.bHooks ^= SPYH_SENDMSG;
        !           502:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           503:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
        !           504:                 MPFROM2SHORT(MIA_CHECKED,
        !           505:                      (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
        !           506:                 SpyReleaseHook (FALSE);     /* Dont clear queue */
        !           507:                 SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
        !           508:             break;
        !           509: 
        !           510:         case CMD_SENDEXTEND:
        !           511:             spyopt.fSendExtend ^= 1;  /* Toggle on or off */
        !           512:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           513:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
        !           514:                 MPFROM2SHORT(MIA_CHECKED,
        !           515:                      spyopt.fSendExtend ? MIA_CHECKED : 0));
        !           516:             break;
        !           517: 
        !           518:         case CMD_SENDSTACK:
        !           519:             spyopt.fSendStack ^= 1;  /* Toggle on or off */
        !           520:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           521:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDSTACK, TRUE),
        !           522:                 MPFROM2SHORT(MIA_CHECKED,
        !           523:                     spyopt.fSendStack ? MIA_CHECKED : 0));
        !           524:             break;
        !           525: 
        !           526:         /*
        !           527:          * The commands in this section are defined in the Outputs Menu.
        !           528:          * The first 3 items simply toggle outputs on or off, where the
        !           529:          * last item allows the user to change all of the output options.
        !           530:          */
        !           531:         case CMD_OUTSCREEN:
        !           532:             spyopt.fWindow ^= 1;  /* Toggle on or off */
        !           533:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           534:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
        !           535:                 MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
        !           536:             break;
        !           537: 
        !           538:         case CMD_OUTFILE:
        !           539:             spyopt.fFile ^= 1;  /* Toggle on or off */
        !           540:             WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
        !           541:                 MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
        !           542:                 MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
        !           543:             /*
        !           544:              * Open or close the output file
        !           545:              */
        !           546:             if (spyopt.fFile) {
        !           547:                  if (spyopt.hfileSpy == NULL)
        !           548:                     if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
        !           549:                             (USHORT far *)&wAction, 0L, 0,
        !           550:                             0x0012, 0x00C1, 0L) != 0)
        !           551:                         spyopt.hfileSpy = NULL; /* Failed on open */
        !           552:             } else {
        !           553:                 if (spyopt.hfileSpy != NULL) {
        !           554:                     /* file open, not outputing, close it now */
        !           555:                     DosClose (spyopt.hfileSpy);
        !           556:                     spyopt.hfileSpy = NULL;
        !           557:                 }
        !           558:             }
        !           559:             break;
        !           560: 
1.1       root      561:         case CMD_OUTPUTS:
                    562:             SpyHookOnOrOff (FALSE);
                    563:             WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                    564:                 (PFNWP)SpyOutputsDlgProc, (HMODULE)NULL,
                    565:                 OutputsDlg, (PCH)NULL);
                    566:             SpyHookOnOrOff (fSpyActive);
                    567:             break;
                    568: 
                    569:         case CMD_MGDABLE:
                    570:         case CMD_MGEABLE:
                    571:             EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE);
                    572:             break;
                    573:         }
                    574: 
                    575:         break;
                    576: 
                    577:     case WM_SIZE:
                    578:         /* We need to resize the listbox, if it exists */
                    579:         if (hwndSpyList != NULL) {
1.1.1.2 ! root      580:             WinSetWindowPos(hwndSpyList, HWND_TOP, -cxBorder, -cyBorder,
        !           581:                 SHORT1FROMMP(mp2) + 2 * cxBorder,
        !           582:                 SHORT2FROMMP(mp2) + 2 * cyBorder, SWP_MOVE | SWP_SIZE);
1.1       root      583:         }
                    584: 
                    585:         /* Now fall through to process the message */
                    586:     default:
                    587:         return(WinDefWindowProc(hwnd, msg, mp1, mp2));
                    588:         break;
                    589:     }
                    590:     return(0L);
                    591: }
                    592: 
                    593: 
                    594: 
1.1.1.2 ! root      595: 
        !           596: /***************************************************************************\
        !           597: * USHORT UConvertStringToNum(psz)
1.1       root      598: *
1.1.1.2 ! root      599: * Converts the passed string to a number 0xffff if not number
1.1       root      600: \***************************************************************************/
1.1.1.2 ! root      601: USHORT  UConvertStringToNum(psz)
        !           602: register char   *psz;
1.1       root      603: {
1.1.1.2 ! root      604:     register USHORT uNum;
        !           605: 
        !           606:     /*
        !           607:      * If the first few chars are 0x, we assume the user typed in a
        !           608:      * HEX number, else if 0-9, we assume decimal, else we use the string.
        !           609:      */
        !           610:     /* First see if digit in first position */
        !           611:     if ((*psz >= '0') && (*psz <= '9')) {
        !           612:         /* Assume numbers now */
        !           613:         if ((*psz == '0') && (*(psz+1) == 'x')) {
        !           614: 
        !           615:             /* We are in hex mode */
        !           616:             psz += 2;
        !           617:             uNum = 0;
        !           618:             for (;;) {
        !           619:                 if ((*psz >= '0') && (*psz <= '9'))
        !           620:                     uNum = uNum * 16 + (USHORT)(*psz - '0');
        !           621:                 else if ((*psz >= 'a') && (*psz <= 'f'))
        !           622:                     uNum = uNum * 16 + (USHORT)(*psz - 'a');
        !           623:                 else if ((*psz >= 'F') && (*psz <= 'F'))
        !           624:                     uNum = uNum * 16 + (USHORT)(*psz - 'A');
        !           625:                 else
        !           626:                     break;
        !           627:                 psz++;
        !           628:             }
1.1       root      629: 
1.1.1.2 ! root      630:         } else {
        !           631:             /* Decimal mode */
        !           632:             uNum = (USHORT)(*psz++ - '0');
        !           633:             while ((*psz >= '0') && (*psz <= '9')) {
        !           634:                 uNum = uNum * 10 + (USHORT)(*psz++ - '0');
1.1       root      635:             }
                    636:         }
                    637: 
1.1.1.2 ! root      638:         return (uNum);
        !           639:     } else
        !           640:         /* Not num, return 0xffff */
        !           641:         return (0xffff);
        !           642: }
1.1       root      643: 
                    644: 
                    645: 
                    646: 
                    647: 
1.1.1.2 ! root      648: /***************************************************************************\
        !           649: * void ProcHookThread()
        !           650: *
        !           651: *   This function will wait for the hook to have messages,  when it
        !           652: *   does, it will set a memory semaphore, post a WM_SEM1 message to the other
        !           653: *   thread, and wait for the other thread has processed all of the messages.
        !           654: \***************************************************************************/
1.1       root      655: 
1.1.1.2 ! root      656: void FAR ProcHookThread()
        !           657: {
        !           658:     while (TRUE) {
1.1       root      659:         /*
1.1.1.2 ! root      660:          * Wait for a message to become available.
1.1       root      661:          */
1.1.1.2 ! root      662:         if (!SpyGetNextMessage(NULL, NULL, 0, -1L))
1.1       root      663:             break;
                    664: 
1.1.1.2 ! root      665:         /*
        !           666:          * Now we have a message, set our semaphore, Post a WM_SEM2
        !           667:          * message to the Client window, and wait for the client to
        !           668:          * clear the semaphore.
        !           669:          */
        !           670:         DosSemSet((HSEM)(PULONG)&semThread);
        !           671:         WinPostMsg(hwndSpy, WM_SEM2, (MPARAM)1, (MPARAM)1);
        !           672:         DosSemWait((HSEM)(PULONG)&semThread, -1L);
1.1       root      673:     }
1.1.1.2 ! root      674: 
        !           675:     DosExit(EXIT_THREAD, 0);
1.1       root      676: }
                    677: 
                    678: 
                    679: 
1.1.1.2 ! root      680: 
        !           681: /***************************************************************************\
        !           682: * void ProcessQueueMsg(pqmsg)
1.1       root      683: *
1.1.1.2 ! root      684: *   This function will process the hook, by calling the hooks which get
        !           685: *   messages.  We will than post the message to the current output destinations.
1.1       root      686: \***************************************************************************/
1.1.1.2 ! root      687: 
        !           688: void ProcessQueueMsg(pqmsgspy)
        !           689:     QMSGSPY    *pqmsgspy;
1.1       root      690: {
1.1.1.2 ! root      691:     MSGI    *pmsgi;
        !           692:     SHORT   item;
        !           693:     CHAR    cSource;
        !           694:     CHAR    cThread;
        !           695:     char    szNextMessage[100];
        !           696:     char    szTime[12];
        !           697:     SHORT   cch;
        !           698:     CHAR    bAscii;
        !           699:     PSZ     prgData;
1.1       root      700: 
                    701: 
1.1.1.2 ! root      702: 
        !           703:     /*
        !           704:      * Now let's build the message to output
        !           705:      */
        !           706:     if (WinIsWindow(hab, pqmsgspy->qmsg.hwnd)) {
        !           707:         if (WinIsChild(pqmsgspy->qmsg.hwnd, hwndSpy))
        !           708:             return;     /* don't want endless loops */
        !           709:     }
        !           710: 
        !           711:     cThread = ':';
        !           712:     if (pqmsgspy->qmsg.time == (ULONG)-1) {
        !           713:         /* Sent message */
        !           714:         szTime[0] = '\0';
        !           715:         cSource = 'S';
        !           716:         if (pqmsgspy->fs)
        !           717:             cThread = '*';
        !           718:     } else {
        !           719:         cSource = 'I';
        !           720:         if (pqmsgspy->fs != PM_REMOVE)
        !           721:             cThread = '-';  /* Show different for non-remove */
        !           722: 
        !           723:         sprintf (szTime, "%-08lx", pqmsgspy->qmsg.time);
        !           724:     }
        !           725: 
        !           726:     if ((pmsgi = PmsgiFromMsg(pqmsgspy->qmsg.msg)) == NULL) {
        !           727:         /*
        !           728:          * Message not in list, use default
        !           729:          */
        !           730:         cch = sprintf(szNextMessage,
        !           731:             "%c%cMSG:0x%04x            H:%04x 1:%08lx 2:%08lx T:%s",
        !           732:             cSource, cThread, (SHORT)pqmsgspy->qmsg.msg, (SHORT)pqmsgspy->qmsg.hwnd,
        !           733:             pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
        !           734:     } else if (pmsgi->wOptions & MSGI_MOUSE) {
        !           735:         /*
        !           736:          * Mouse message, decode to mouse types
        !           737:          */
        !           738:         cch = sprintf(szNextMessage,
        !           739:             "%c%c%-20s H:%04x X:%-4d Y:%-4d HT:%04x T:%s",
        !           740:             cSource, cThread, pmsgi->szMsg, (SHORT)pqmsgspy->qmsg.hwnd,
        !           741:             SHORT1FROMMP(pqmsgspy->qmsg.mp1), SHORT2FROMMP(pqmsgspy->qmsg.mp1),
        !           742:             SHORT1FROMMP(pqmsgspy->qmsg.mp2), szTime);
        !           743:     } else if (pmsgi->wOptions & MSGI_KEY) {
1.1       root      744:         /*
1.1.1.2 ! root      745:          * Key messages, output special
1.1       root      746:          */
1.1.1.2 ! root      747:         bAscii = (CHAR)SHORT1FROMMP(pqmsgspy->qmsg.mp2);
        !           748:         if ((bAscii < ' ') || (bAscii > '~'))
        !           749:             bAscii = ' ';
1.1       root      750: 
1.1.1.2 ! root      751:         cch = sprintf(szNextMessage,
        !           752:             "%c%c%-20s H:%04x F:%04x R:%d S:%2x C:%04x(%c) V:%02x T:%s",
        !           753:             cSource, cThread, pmsgi->szMsg, (SHORT)pqmsgspy->qmsg.hwnd,
        !           754:             SHORT1FROMMP(pqmsgspy->qmsg.mp1),
        !           755:             CHAR3FROMMP(pqmsgspy->qmsg.mp1),  CHAR4FROMMP(pqmsgspy->qmsg.mp1),
        !           756:             SHORT1FROMMP(pqmsgspy->qmsg.mp2), bAscii,
        !           757:             SHORT2FROMMP(pqmsgspy->qmsg.mp2), szTime);
        !           758:     } else {
        !           759:         /* No special format */
        !           760:         cch = sprintf(szNextMessage,
        !           761:             "%c%c%-20s H:%04x 1:%08lx 2:%08lx T:%s",
        !           762:             cSource, cThread, pmsgi->szMsg, (SHORT)pqmsgspy->qmsg.hwnd,
        !           763:             pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
        !           764:     }
1.1       root      765: 
1.1.1.2 ! root      766:     OutputString(szNextMessage, cch);
1.1       root      767: 
1.1.1.2 ! root      768:     /*
        !           769:      * Now dump out any additional information associated with the
        !           770:      * message.  The processing depends of the type of message on
        !           771:      * how we are going to process the data.
        !           772:      */
        !           773:     if (spyopt.fSendExtend) {
        !           774:         prgData = DumpParam((PSZ)rgMsgData, pqmsgspy->qmsg.mp1,
        !           775:                 pqmsgspy->cbDataMP1, pqmsgspy->bMPType);
        !           776:         DumpParam(prgData, pqmsgspy->qmsg.mp2, pqmsgspy->cbDataMP2,
        !           777:                 (UCHAR)((pqmsgspy->bMPType) >> 3));
        !           778:     }
1.1       root      779: 
1.1.1.2 ! root      780:     /*
        !           781:      * If this is a send message, also display the call stack information
        !           782:      * of who called WinSendMsg
        !           783:      */
        !           784:     if (spyopt.fSendStack && (pqmsgspy->qmsg.time == (ULONG)-1)) {
        !           785:         cch = sprintf(szNextMessage,
        !           786:             "    PID: %-3d TID: %-2d   Stack:",
        !           787:             pqmsgspy->pidSend, pqmsgspy->tidSend);
1.1       root      788: 
1.1.1.2 ! root      789:         /* Now loop and add the stack info */
        !           790:         for (item=0; (item < MAXSTRACE) &&
        !           791:                 (pqmsgspy->pvoidStack[item] != NULL); item++) {
        !           792:             cch += sprintf(szTime, " %p", pqmsgspy->pvoidStack[item]);
        !           793:             strcat(szNextMessage, szTime);
        !           794:         }
1.1       root      795: 
1.1.1.2 ! root      796:         OutputString(szNextMessage, cch);
1.1       root      797:     }
                    798: 
                    799: }
                    800: 
                    801: 
                    802: 
                    803: 
1.1.1.2 ! root      804: /***************************************************************************\
        !           805: * PSZ DumpParam(PSZ prgData, MPARAM mp, SHORT cb, UCHAR bMPType)
1.1       root      806: *
1.1.1.2 ! root      807: * Dump the additional information that was captured for the message.
        !           808: *   using the currently defined types.
1.1       root      809: *
1.1.1.2 ! root      810: * Returns: PSZ - Pointer to next available byte after process DATA
1.1       root      811: \***************************************************************************/
1.1.1.2 ! root      812: PSZ DumpParam(prgData, mp, cb, bMPType)
        !           813: PSZ         prgData;
        !           814: MPARAM      mp;
        !           815: SHORT       cb;
        !           816: UCHAR       bMPType;
1.1       root      817: {
1.1.1.2 ! root      818:     char    szNextMessage[100];
        !           819:     SHORT   cch;
1.1       root      820: 
                    821: 
1.1.1.2 ! root      822:     if (FGuessValidPointer((PSZ)mp, cb)) {
        !           823:         /* Process by type */
        !           824:         switch (bMPType & 0x07) {
        !           825:         case MPT_SWP:
        !           826:             cch = sprintf(szNextMessage,
        !           827:                 "    SWP:               fs:%04x cx:%d cy:%d y:%d x:%d HB:%04x H:%04x",
        !           828:                 ((PSWP)prgData)->fs, ((PSWP)prgData)->cy, ((PSWP)prgData)->cx,
        !           829:                 ((PSWP)prgData)->y, ((PSWP)prgData)->x,
        !           830:                 (SHORT)((PSWP)prgData)->hwndInsertBehind,
        !           831:                 (SHORT)((PSWP)prgData)->hwnd);
1.1       root      832: 
                    833:             break;
                    834: 
1.1.1.2 ! root      835:         case MPT_RECTL:
        !           836:             cch = sprintf(szNextMessage,
        !           837:                 "    RECTL:             xLeft:%d yBottom:%d xRight:%d yTop:%d",
        !           838:                 ((PRECTL)prgData)->xLeft, ((PRECTL)prgData)->yBottom,
        !           839:                 ((PRECTL)prgData)->xRight, ((PRECTL)prgData)->yTop);
        !           840:             break;
        !           841: 
        !           842:         case MPT_QMSG:
        !           843:             cch = sprintf(szNextMessage,
        !           844:                 "    QMSG: H:%04x       M:%04x M1:%08lx M2:%08lx T:%08lx (%d, %d)",
        !           845:                 (SHORT)((PQMSG)prgData)->hwnd, ((PQMSG)prgData)->msg,
        !           846:                 ((PQMSG)prgData)->mp1,((PQMSG)prgData)->mp2,
        !           847:                 ((PQMSG)prgData)->time,
        !           848:                 ((PQMSG)prgData)->ptl.x, ((PQMSG)prgData)->ptl.y);
1.1       root      849:             break;
                    850: 
1.1.1.2 ! root      851:         default:
        !           852:             goto NoData;
1.1       root      853:         }
                    854: 
1.1.1.2 ! root      855:         OutputString(szNextMessage, cch);
1.1       root      856:     }
1.1.1.2 ! root      857: NoData:
        !           858:     return (prgData + cb);
1.1       root      859: }
                    860: 
                    861: 
                    862: 
                    863: 
1.1.1.2 ! root      864: /***************************************************************************\
1.1       root      865: * void OutputString(char szOut, SHORT cch);
                    866: *
1.1.1.2 ! root      867: *   This function will output the specified string to the
1.1       root      868: *   destinations.
                    869: \***************************************************************************/
                    870: 
                    871: void OutputString(szOut, cch)
                    872: char        szOut[];
                    873: SHORT       cch;
                    874: {
                    875:     SHORT   item;
                    876:     char    *psz;
                    877:     USHORT  cchWritten;
                    878: 
                    879: 
                    880: 
1.1.1.2 ! root      881:     /* Now display the new line on the screen */
1.1       root      882:     if (spyopt.fWindow) {
                    883:         item = (SHORT)WinSendMsg(hwndSpyList, LM_INSERTITEM,
                    884:             (MPARAM)LIT_END, (MPARAM)(PSZ)szOut);
                    885: 
                    886:         WinSendMsg(hwndSpyList, LM_SETTOPINDEX, (MPARAM)item, 0L);
                    887: 
1.1.1.2 ! root      888:         /* See if we have too many lines now */
1.1       root      889:         while (item >= spyopt.cWindowLines)
                    890:             item = (SHORT)WinSendMsg(hwndSpyList, LM_DELETEITEM,
                    891:                     (MPARAM)0, 0L);
                    892:     }
                    893: 
                    894:     /* now for file need cr/lf */
                    895:     psz = szOut + cch;    /* point to trailing null */
                    896:     *psz++ = '\r';
                    897:     *psz++ = '\n';
                    898:     *psz = '\0';
                    899: 
                    900:     if (spyopt.fFile)
                    901:         DosWrite(spyopt.hfileSpy, (PSZ)szOut, cch+2,
                    902:                 (PUSHORT)&cchWritten);
                    903: 
                    904: }
                    905: 
                    906: 
1.1.1.2 ! root      907: /***************************************************************************\
1.1       root      908: * MSGI  * PmsgiFromMsg(USHORT msg)
                    909: *
1.1.1.2 ! root      910: * Locate the msg in the array of message items
1.1       root      911: *
1.1.1.2 ! root      912: * Returns: pointer to item that has the specified msg, or NULL
1.1       root      913: \***************************************************************************/
                    914: MSGI *PmsgiFromMsg(msg)
                    915: USHORT msg;
                    916: {
                    917:     register MSGI   *pmsgi = rgmsgi;    /* Start at beginning */
                    918:     register USHORT i;
                    919: 
                    920:     /*
                    921:      * Currently is a simple linear search, should be made faster
1.1.1.2 ! root      922:      * probably by using binary search.
1.1       root      923:      */
                    924:     for (i=0; i< cmsgi; i++) {
                    925:         if (pmsgi->msg == msg)
                    926:             return (pmsgi);
                    927:         if (pmsgi->msg > msg)
                    928:             return (NULL);
                    929:         pmsgi++;
                    930:     };
                    931: 
                    932:     return (NULL);
                    933: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.