|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.