source: trunk/synergy/birdhacks/spy1.c@ 2766

Last change on this file since 2766 was 2766, checked in by bird, 19 years ago

a simple spy.

File size: 8.7 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * spy1 - the program.
5 *
6 * Copyright (c) 1997-2006 knut st. osmundsen <bird@anduin.net>
7 *
8 * GPL
9 *
10 */
11
12/*******************************************************************************
13* Header Files *
14*******************************************************************************/
15#define INCL_GPI
16#define INCL_DOS
17#define INCL_WIN
18#define INCL_ERRORS
19#include <os2.h>
20#include <string.h>
21#include <stdio.h>
22#include <stdint.h>
23#include <ctype.h>
24#include "spy1.h"
25
26
27/**
28 * Get the name of a virtual key.
29 * @returns the key name (readonly).
30 * @param ulVirtualKey The virtual key.
31 */
32const char *GetVirtualKeyName(ULONG ulVirtualKey)
33{
34 switch (ulVirtualKey) {
35#define CASE(vk) case vk: return #vk
36 CASE(VK_BUTTON1);
37 CASE(VK_BUTTON2);
38 CASE(VK_BUTTON3);
39 CASE(VK_BREAK);
40 CASE(VK_BACKSPACE);
41 CASE(VK_TAB);
42 CASE(VK_BACKTAB);
43 CASE(VK_NEWLINE);
44 CASE(VK_SHIFT);
45 CASE(VK_CTRL);
46 CASE(VK_ALT);
47 CASE(VK_ALTGRAF);
48 CASE(VK_PAUSE);
49 CASE(VK_CAPSLOCK);
50 CASE(VK_ESC);
51 CASE(VK_SPACE);
52 CASE(VK_PAGEUP);
53 CASE(VK_PAGEDOWN);
54 CASE(VK_END);
55 CASE(VK_HOME);
56 CASE(VK_LEFT);
57 CASE(VK_UP);
58 CASE(VK_RIGHT);
59 CASE(VK_DOWN);
60 CASE(VK_PRINTSCRN);
61 CASE(VK_INSERT);
62 CASE(VK_DELETE);
63 CASE(VK_SCRLLOCK);
64 CASE(VK_NUMLOCK);
65 CASE(VK_ENTER);
66 CASE(VK_SYSRQ);
67 CASE(VK_F1);
68 CASE(VK_F2);
69 CASE(VK_F3);
70 CASE(VK_F4);
71 CASE(VK_F5);
72 CASE(VK_F6);
73 CASE(VK_F7);
74 CASE(VK_F8);
75 CASE(VK_F9);
76 CASE(VK_F10);
77 CASE(VK_F11);
78 CASE(VK_F12);
79 CASE(VK_F13);
80 CASE(VK_F14);
81 CASE(VK_F15);
82 CASE(VK_F16);
83 CASE(VK_F17);
84 CASE(VK_F18);
85 CASE(VK_F19);
86 CASE(VK_F20);
87 CASE(VK_F21);
88 CASE(VK_F22);
89 CASE(VK_F23);
90 CASE(VK_F24);
91 CASE(VK_ENDDRAG);
92 CASE(VK_CLEAR);
93 CASE(VK_EREOF);
94 CASE(VK_PA1);
95 CASE(VK_ATTN);
96 CASE(VK_CRSEL);
97 CASE(VK_EXSEL);
98 CASE(VK_COPY);
99 CASE(VK_BLK1);
100 CASE(VK_BLK2);
101#undef CASE
102 default:
103 return "";
104 }
105}
106
107/**
108 * Prints the given KC flags.
109 * @param fKC The KC_* flags to print.
110 */
111void PrintKC(USHORT fKC)
112{
113#define PRINT_KC(kc) if (fKC & kc) printf(" " #kc);
114 PRINT_KC(KC_CHAR);
115 PRINT_KC(KC_VIRTUALKEY);
116 PRINT_KC(KC_SCANCODE);
117 PRINT_KC(KC_SHIFT);
118 PRINT_KC(KC_CTRL);
119 PRINT_KC(KC_ALT);
120 PRINT_KC(KC_KEYUP);
121 PRINT_KC(KC_PREVDOWN);
122 PRINT_KC(KC_LONEKEY);
123 PRINT_KC(KC_DEADKEY);
124 PRINT_KC(KC_COMPOSITE);
125 PRINT_KC(KC_INVALIDCOMP);
126 PRINT_KC(KC_TOGGLE);
127 PRINT_KC(KC_INVALIDCHAR);
128 PRINT_KC(KC_DBCSRSRVD1);
129 PRINT_KC(KC_DBCSRSRVD2);
130#undef PRINT_KC
131}
132
133
134/**
135 * Prints the given KDD flags.
136 * @param fKDD The KDD_* flags to print.
137 */
138void PrintKDD(USHORT fKDD)
139{
140 /* action */
141 switch (fKDD & KDD_ACTIONFIELD) {
142#define PRINT_KDD(kdd) case kdd: printf(" " #kdd); break
143 PRINT_KDD(KDD_PUTINKIB);
144 PRINT_KDD(KDD_ACK);
145 PRINT_KDD(KDD_PREFIXKEY);
146 PRINT_KDD(KDD_OVERRUN);
147 PRINT_KDD(KDD_RESEND);
148 PRINT_KDD(KDD_REBOOTKEY);
149 PRINT_KDD(KDD_DUMPKEY);
150 PRINT_KDD(KDD_SHIFTKEY);
151 PRINT_KDD(KDD_PAUSEKEY);
152 PRINT_KDD(KDD_PSEUDOPAUSE);
153 PRINT_KDD(KDD_WAKEUPKEY);
154 PRINT_KDD(KDD_BADACCENT);
155 PRINT_KDD(KDD_HOTKEY);
156 PRINT_KDD(KDD_ACCENTKEY);
157 PRINT_KDD(KDD_BREAKKEY);
158 PRINT_KDD(KDD_PSEUDOBREAK);
159 PRINT_KDD(KDD_PRTSCKEY);
160 PRINT_KDD(KDD_PRTECHOKEY);
161 PRINT_KDD(KDD_PSEUDOPRECH);
162 PRINT_KDD(KDD_STATUSCHG);
163 PRINT_KDD(KDD_WRITTENKEY);
164 PRINT_KDD(KDD_UNDEFINED);
165#undef PRINT_KDD
166 }
167 /* the flags */
168#define PRINT_KDD(kdd) if (fKDD & kdd) printf(" " #kdd);
169 PRINT_KDD(KDD_ACCENTED);
170 PRINT_KDD(KDD_MULTIMAKE);
171 PRINT_KDD(KDD_SECONDARY);
172 PRINT_KDD(KDD_BREAK);
173 PRINT_KDD(KDD_EXTENDEDKEY);
174 PRINT_KDD(KDD_KC_LONEKEY);
175 PRINT_KDD(KDD_KC_PREVDOWN);
176 PRINT_KDD(KDD_KC_KEYUP);
177 PRINT_KDD(KDD_KC_ALT);
178 PRINT_KDD(KDD_KC_CTRL);
179 PRINT_KDD(KDD_KC_SHIFT);
180#undef PRINT_KDD
181}
182
183/**
184 * Decods the message (if known to us).
185 *
186 * @param pQmsg The message.
187 */
188void PrintMsg(const QMSG *pQmsg)
189{
190 switch (pQmsg->msg) {
191 case WM_VIOCHAR:
192 printf("WM_VIOCHAR: fKC=%04x rep=%02x scan=%02x ",
193 SHORT1FROMMP(pQmsg->mp1), CHAR3FROMMP(pQmsg->mp1), CHAR4FROMMP(pQmsg->mp1));
194 printf("xlch=%02x(%c) xlscan=%02x fKDD=%04x ",
195 CHAR1FROMMP(pQmsg->mp2), isprint(CHAR1FROMMP(pQmsg->mp2)) ? CHAR1FROMMP(pQmsg->mp2) : '.',
196 CHAR2FROMMP(pQmsg->mp2), SHORT2FROMMP(pQmsg->mp2));
197 PrintKC(SHORT1FROMMP(pQmsg->mp1));
198 PrintKDD(SHORT2FROMMP(pQmsg->mp2));
199 printf("\n");
200 break;
201
202 case WM_CHAR:
203 printf(" WM_CHAR: fKC=%04x rep=%02x scan=%02x ",
204 SHORT1FROMMP(pQmsg->mp1), CHAR3FROMMP(pQmsg->mp1), CHAR4FROMMP(pQmsg->mp1));
205 printf("ch=%04x(%c) vk=%04x(%s) ",
206 SHORT1FROMMP(pQmsg->mp2), isprint(SHORT1FROMMP(pQmsg->mp2)) ? SHORT1FROMMP(pQmsg->mp2) : '.',
207 SHORT2FROMMP(pQmsg->mp2), GetVirtualKeyName(SHORT2FROMMP(pQmsg->mp2)));
208 PrintKC(SHORT1FROMMP(pQmsg->mp1));
209 printf("\n");
210 break;
211 }
212}
213
214
215/**
216 * Prints the message.
217 * @param pEvent The message to print.
218 */
219void PrintEvent(PSPY1EVENT pEvent)
220{
221 /* first line, raw data */
222 printf("p%04lx t%02lx", pEvent->pid, pEvent->tid);
223 switch (pEvent->ulHook) {
224 case HK_JOURNALRECORD: printf(" JR"); break;
225 case HK_INPUT: printf(" IN"); break;
226 default: printf(" %ld\n", pEvent->ulHook); break;
227 }
228 switch (pEvent->enmType) {
229 case SPY1EVENTTYPE_MSG_REMOVED: printf(" RM"); break;
230 case SPY1EVENTTYPE_MSG_PEEK: printf(" PK"); break;
231 default: printf(" invalid msg (%d)\n", pEvent->enmType); return;
232 }
233 switch (pEvent->enmType) {
234 case SPY1EVENTTYPE_MSG_REMOVED:
235 case SPY1EVENTTYPE_MSG_PEEK:
236 printf(" time=%08lx hwnd=%08lx msg=%04lx mp1=%08x mp2=%08x (%ld,%ld)\n",
237 pEvent->u.Msg.time,
238 pEvent->u.Msg.hwnd,
239 pEvent->u.Msg.msg,
240 (uintptr_t)pEvent->u.Msg.mp1,
241 (uintptr_t)pEvent->u.Msg.mp2,
242 pEvent->u.Msg.ptl.x,
243 pEvent->u.Msg.ptl.y);
244 PrintMsg(&pEvent->u.Msg);
245 break;
246 default: break; /* pedantic gcc */
247 }
248}
249
250/**
251 * Check if it's an event we'll ignore.
252 *
253 * @returns TRUE if we should ignore the event, otherwise FALSE.
254 * @param pEvent The event in question.
255 */
256BOOL IgnoreEvent(PSPY1EVENT pEvent)
257{
258 return pEvent->enmType == SPY1EVENTTYPE_MSG_REMOVED
259 && ( pEvent->u.Msg.msg == WM_TIMER
260 || pEvent->u.Msg.msg == WM_PAINT
261 || pEvent->u.Msg.msg >= WM_USER
262 || (pEvent->u.Msg.msg >= WM_SEM1 && pEvent->u.Msg.msg <= WM_SEM4)
263#if 1
264 || (pEvent->u.Msg.msg >= WM_MOUSEFIRST && pEvent->u.Msg.msg <= WM_MOUSELAST)
265 || (pEvent->u.Msg.msg >= WM_EXTMOUSEFIRST && pEvent->u.Msg.msg <= WM_MOUSETRANSLATELAST)
266#endif
267#if 1
268 || pEvent->u.Msg.msg == WM_JOURNALNOTIFY
269#endif
270 );
271}
272
273
274int main(void)
275{
276 HAB hab;
277 HMQ hmq;
278 PPIB pPib;
279 PTIB pTib;
280 int rc;
281
282 /*
283 * The PM prologue.
284 */
285 DosGetInfoBlocks(&pTib, &pPib);
286 pPib->pib_ultype = 3;
287
288 hab = WinInitialize(0);
289 hmq = WinCreateMsgQueue(hab, 0);
290
291 /*
292 * Install the hooks.
293 */
294 rc = SetHooks(hab);
295 if (rc == NO_ERROR) {
296 /*
297 * The event printing loop.
298 */
299 for (;;) {
300 SPY1EVENT Event;
301 rc = GetEvent(&Event, SEM_INDEFINITE_WAIT);
302 if (rc) {
303 printf("GetEvent failed, rc=%d\n", rc);
304 }
305 if (!IgnoreEvent(&Event)) {
306 PrintEvent(&Event);
307 }
308 }
309
310 /* cleanup */
311 ReleaseHooks(hab);
312 } else {
313 printf("InstallHooks failed with rc=%#x\n", rc);
314 }
315
316 /*
317 * The PM epilogue.
318 */
319 WinDestroyMsgQueue(hmq);
320 WinTerminate(hab);
321 return NO_ERROR;
322}
323
Note: See TracBrowser for help on using the repository browser.