home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / spy / app / hook.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  9KB  |  342 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /*****************************************************************************\
  13. *
  14. * Module: hook.c
  15. *
  16. *   Contains the message hooking functions for the Windows debugging Spy
  17. *   SDK applet.
  18. *
  19. * Functions:
  20. *
  21. *   CreateHookThread()
  22. *   HookMain()
  23. *   HookWndProc()
  24. *   SetSpyHook()
  25. *   SetWindowToSpyOn()
  26. *   DbgPrintf()
  27. *
  28. * Comments:
  29. *
  30. \*****************************************************************************/
  31.  
  32. #include "spy.h"
  33.  
  34.  
  35. PRIVATE BOOL gfProcessHooks = TRUE;
  36.  
  37.  
  38. /*****************************************************************************\
  39. * CreateHookThread
  40. *
  41. *    Creates the hook thread.
  42. *
  43. * Arguments: 
  44. *    none
  45. *
  46. * Returns:
  47. *    BOOL - Whether or not hook create succeeeded.
  48. \*****************************************************************************/
  49.  
  50. BOOL
  51. CreateHookThread(
  52.     VOID
  53.     )
  54. {
  55.     WNDCLASS wc;
  56.     DWORD Id;
  57.  
  58.     //
  59.     // Register a class for the hook stuff to forward its messages to.
  60.     //
  61.     wc.hCursor        = NULL;    // this window never shown, so no
  62.     wc.hIcon          = NULL;    // cursor or icon are necessary
  63.     wc.lpszMenuName   = NULL;
  64.     wc.lpszClassName  = HOOKWINDOWCLASS;
  65.     wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  66.     wc.hInstance      = ghInst;
  67.     wc.style          = 0;
  68.     wc.lpfnWndProc    = HookWndProc;
  69.     wc.cbWndExtra     = sizeof(HWND) + sizeof(HWND);
  70.     wc.cbClsExtra     = 0;
  71.  
  72.     if (!RegisterClass(&wc))
  73.         return FALSE;
  74.  
  75.     //
  76.     // Now create another thread to handle the new queue
  77.     //
  78.     if (!(ghHookThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HookMain,
  79.         0L, STANDARD_RIGHTS_REQUIRED, &Id)))
  80.         return FALSE;
  81.  
  82.     return TRUE;
  83. }
  84.  
  85.  
  86.  
  87. /*****************************************************************************\
  88. * HookMain
  89. *
  90. *    Main window procedure for the Hook window
  91. *
  92. \*****************************************************************************/
  93.  
  94. DWORD
  95. HookMain(
  96.     LPVOID lpv
  97.     )
  98. {
  99.     MSG msg;
  100.  
  101.     //
  102.     // Create a hidden window for all to find, but not to see
  103.     //
  104.     ghwndSpyHook = CreateWindow(HOOKWINDOWCLASS, HOOKWINDOWNAME,
  105.         WS_OVERLAPPEDWINDOW,
  106.         0, 0, 0, 0,
  107.         (HWND) NULL,        /* no parent */
  108.         (HMENU) NULL,       /* use class menu */
  109.         (HANDLE) ghInst,    /* handle to window instance */
  110.         (LPSTR) NULL        /* no params to pass on */
  111.         );
  112.  
  113.     if (!ghwndSpyHook)
  114.     {
  115.         ExitThread(0);
  116.     }
  117.  
  118.     SetWindowToSpyOn(HWND_ALL);
  119.  
  120.     //
  121.     // Polling forwarded messages from hook's event queue
  122.     //
  123.     while (IsWindow(ghwndSpyHook) && GetMessage(&msg, ghwndSpyHook, 0, 0))
  124.     {
  125.         if (gfProcessHooks)
  126.         {
  127.             TranslateMessage(&msg);
  128.             DispatchMessage(&msg);
  129.         }
  130.     }
  131.  
  132.     ghwndSpyHook = NULL;
  133.  
  134.     return 0; // not reached
  135. }
  136.  
  137.  
  138.  
  139. /*****************************************************************************\
  140. * HookWndProc
  141. *
  142. * Window procedure for the spy hook.
  143. *
  144. * Arguments:
  145. *   HWND hwnd - handle to the hook window.   
  146. *   UINT msg - message sent to hook window.
  147. *   WPARAM wParam - message parameter.
  148. *   LPARAM lParam - message parameter.
  149. *
  150. * Returns:
  151. *   The value that the proc should return, based on the processing
  152. *   of the specific WM_COMMAND message received.
  153. \*****************************************************************************/
  154.  
  155. LRESULT CALLBACK
  156. HookWndProc(
  157.     HWND hwnd,
  158.     UINT msg,
  159.     WPARAM wParam,
  160.     LPARAM lParam
  161.     )
  162. {
  163.     switch (msg)
  164.     {
  165.         //
  166.         // New message for Win32 - allows the application to pass data to another application.
  167.         //      
  168.         case WM_COPYDATA:
  169.             {
  170.                 MSG msgT;
  171.  
  172.                 msgT.hwnd = (HWND)wParam;
  173.                 msgT.message = ((PCOPYDATASTRUCT)lParam)->dwData;
  174.                 msgT.wParam = ((PSPYMSGDATA)((PCOPYDATASTRUCT)lParam)->lpData)->wParam;
  175.                 msgT.lParam = ((PSPYMSGDATA)((PCOPYDATASTRUCT)lParam)->lpData)->lParam;
  176. //DbgPrintf("S Received Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
  177.                 PrintMsg(&msgT);
  178. //DbgPrintf("S Printed Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
  179.             }
  180.  
  181.             return TRUE;
  182.  
  183.         case WM_CREATE:
  184.             //
  185.             // Initialize the second HWND in the window words to be the
  186.             // window handle of the spy app.  This will be queried by
  187.             // the hook DLL.
  188.             //
  189.             SetWindowLong(hwnd, sizeof(HWND), (LONG)ghwndSpyApp);
  190.             return 0;
  191.  
  192.         case WM_DESTROY:
  193.             PostQuitMessage(0);
  194.             return 0;
  195.  
  196.         case WM_NCDESTROY:
  197.             gfProcessHooks = FALSE;
  198.             break;
  199.     }
  200.  
  201.     return DefWindowProc(hwnd, msg, wParam, lParam);
  202. }
  203.  
  204.  
  205.  
  206. /*****************************************************************************\
  207. * SetSpyHook
  208. *
  209. * Sets the windows hooks used to trap the messages.  After this
  210. * is called with a TRUE for fSet, the messages will start flowing
  211. * through the hook DLL.
  212. *
  213. * Arguments:
  214. *   BOOL fSet - TRUE to hook, FALSE to unhook.
  215. *
  216. * Returns:
  217. *   TRUE if successful.
  218. *
  219. \*****************************************************************************/
  220.  
  221. BOOL
  222. SetSpyHook(
  223.     BOOL fSet
  224.     )
  225. {
  226.     static HHOOK hhkGetMessage = NULL;
  227.     static HHOOK hhkCallWndProc = NULL;
  228.     static HANDLE hmodHook;
  229.  
  230.     if (fSet)
  231.     {
  232.         if (!hmodHook)
  233.         {
  234.             if (!(hmodHook = LoadLibrary("hook")))
  235.             {
  236.                 Message(MB_OK | MB_ICONEXCLAMATION, 
  237.                         LoadResourceString(IDS_ERROR_CANT_LOAD_DLL));
  238.                 return FALSE;
  239.             }
  240.         }
  241.  
  242.         if (!hhkGetMessage)
  243.         {
  244.             if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE,
  245.                 (HOOKPROC)GetProcAddress(hmodHook, "SpyGetMsgProc"), hmodHook, 0)))
  246.             {
  247.                 return FALSE;
  248.             }
  249.         }
  250.  
  251.         if (!hhkCallWndProc)
  252.         {
  253.             if (!(hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC,
  254.                 (HOOKPROC)GetProcAddress(hmodHook, "SpyCallWndProc"), hmodHook, 0)))
  255.             {
  256.                 UnhookWindowsHookEx(hhkGetMessage);
  257.                 return FALSE;
  258.             }
  259.         }
  260.     }
  261.     else
  262.     {
  263.         if (hhkGetMessage)
  264.         {
  265.             UnhookWindowsHookEx(hhkGetMessage);
  266.             hhkGetMessage = NULL;
  267.         }
  268.  
  269.         if (hhkCallWndProc)
  270.         {
  271.             UnhookWindowsHookEx(hhkCallWndProc);
  272.             hhkCallWndProc = NULL;
  273.         }
  274.     }
  275.  
  276.     return TRUE;
  277. }
  278.  
  279.  
  280.  
  281. /*****************************************************************************\
  282. * SetWindowToSpyOn
  283. *
  284. * Sets the current window to spy on to the specified hwnd.  This hwnd can
  285. * also be the special value HWND_ALL to specify that all windows should
  286. * be spy'd upon.
  287. *
  288. * Arguments:
  289. *   HWND hwndSpyingOn - Window handle to spy on, or HWND_ALL for all windows.
  290. *
  291. * Returns:
  292. *   VOID
  293. \*****************************************************************************/
  294.  
  295. VOID
  296. SetWindowToSpyOn(
  297.     HWND hwndSpyingOn
  298.     )
  299. {
  300.     ghwndSpyingOn = hwndSpyingOn;
  301.     gfSpyAll = (ghwndSpyingOn == HWND_ALL) ? TRUE : FALSE;
  302.     SetWindowLong(ghwndSpyHook, 0, (LONG)ghwndSpyingOn);
  303.     SetSpyCaption();
  304. }
  305.  
  306.  
  307.  
  308. #ifdef DBG
  309. /****************************************************************************
  310. * DBGprintf
  311. *
  312. * This debugging function prints out a string to the debug output.
  313. * An optional set of substitutional parameters can be specified,
  314. * and the final output will be the processed result of these combined
  315. * with the format string, just like printf.  A newline is always
  316. * output after every call to this function.
  317. *
  318. * Arguments:
  319. *   LPTSTR fmt - Format string (printf style).
  320. *   ...        - Variable number of arguments.
  321. *
  322. * Returns:
  323. *    VOID
  324. ****************************************************************************/
  325.  
  326. VOID DbgPrintf(
  327.     LPTSTR fmt,
  328.     ...
  329.     )
  330. {
  331.     va_list marker;
  332.     TCHAR szBuf[256];
  333.  
  334.     va_start(marker, fmt);
  335.     wvsprintf(szBuf, fmt, marker);
  336.     va_end(marker);
  337.  
  338.     OutputDebugString(szBuf);
  339.     OutputDebugString(TEXT("\r\n"));
  340. }
  341. #endif
  342.