|
|
1.1 root 1:
2: /******************************************************************************\
3: * This is a part of the Microsoft Source Code Samples.
4: * Copyright (C) 1993 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, "Cannot load HOOK.DLL.");
237: return FALSE;
238: }
239: }
240:
241: if (!hhkGetMessage)
242: {
243: if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE,
244: GetProcAddress(hmodHook, "SpyGetMsgProc"), hmodHook, 0)))
245: {
246: return FALSE;
247: }
248: }
249:
250: if (!hhkCallWndProc)
251: {
252: if (!(hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC,
253: GetProcAddress(hmodHook, "SpyCallWndProc"), hmodHook, 0)))
254: {
255: UnhookWindowsHookEx(hhkGetMessage);
256: return FALSE;
257: }
258: }
259: }
260: else
261: {
262: if (hhkGetMessage)
263: {
264: UnhookWindowsHookEx(hhkGetMessage);
265: hhkGetMessage = NULL;
266: }
267:
268: if (hhkCallWndProc)
269: {
270: UnhookWindowsHookEx(hhkCallWndProc);
271: hhkCallWndProc = NULL;
272: }
273: }
274:
275: return TRUE;
276: }
277:
278:
279:
280: /*****************************************************************************\
281: * SetWindowToSpyOn
282: *
283: * Sets the current window to spy on to the specified hwnd. This hwnd can
284: * also be the special value HWND_ALL to specify that all windows should
285: * be spy'd upon.
286: *
287: * Arguments:
288: * HWND hwndSpyingOn - Window handle to spy on, or HWND_ALL for all windows.
289: *
290: * Returns:
291: * VOID
292: \*****************************************************************************/
293:
294: VOID
295: SetWindowToSpyOn(
296: HWND hwndSpyingOn
297: )
298: {
299: ghwndSpyingOn = hwndSpyingOn;
300: gfSpyAll = (ghwndSpyingOn == HWND_ALL) ? TRUE : FALSE;
301: SetWindowLong(ghwndSpyHook, 0, (LONG)ghwndSpyingOn);
302: SetSpyCaption();
303: }
304:
305:
306:
307: #ifdef DBG
308: /****************************************************************************
309: * DBGprintf
310: *
311: * This debugging function prints out a string to the debug output.
312: * An optional set of substitutional parameters can be specified,
313: * and the final output will be the processed result of these combined
314: * with the format string, just like printf. A newline is always
315: * output after every call to this function.
316: *
317: * Arguments:
318: * LPTSTR fmt - Format string (printf style).
319: * ... - Variable number of arguments.
320: *
321: * Returns:
322: * VOID
323: ****************************************************************************/
324:
325: VOID DbgPrintf(
326: LPTSTR fmt,
327: ...
328: )
329: {
330: va_list marker;
331: TCHAR szBuf[256];
332:
333: va_start(marker, fmt);
334: wvsprintf(szBuf, fmt, marker);
335: va_end(marker);
336:
337: OutputDebugString(szBuf);
338: OutputDebugString(TEXT("\r\n"));
339: }
340: #endif
341:
342:
343:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.