/[winpt]/trunk/PTD/PTD.cpp
ViewVC logotype

Annotation of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 334 - (hide annotations)
Sun Nov 27 12:00:45 2011 UTC (13 years, 3 months ago) by twoaday
File size: 8020 byte(s)
2011-11-27  Timo Schulz <twoaday@gmx.net>

        * wptDNSKeys.{cpp,h}: Moved to source folder.
        * resource.h: Removed.
        * PTD.cpp: Several minor cleanups.
        * PTD.def: Removed unused exports.
				

1 werner 46 /* PTD.cpp - Privacy Tray Dynamic
2 twoaday 325 * Copyright (C) 2002-2009 Timo Schulz
3 werner 46 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     */
16     #ifdef HAVE_CONFIG_H
17     #include <config.h>
18     #endif
19    
20     #include <windows.h>
21     #include <stdio.h>
22    
23     HINSTANCE glob_hinst;
24    
25 werner 61 /* We need a special section in the DLL for storing our shared data.
26 twoaday 261 This shared data is required by the hook function because that
27 werner 61 function is called in the context of the actual thread running the
28     hook and thus we need a way to communicate the result of our hook
29     function back to us. We use a shared data segment for this. */
30     #ifdef __GNUC__
31     #define ATTR_SEC __attribute__((section (".SHARDAT"), shared))
32     #else
33     #define ATTR_SEC
34 werner 46 #pragma data_seg(".SHARDAT")
35 werner 61 #endif
36     static HHOOK cbt_hook ATTR_SEC = NULL; /* CTB hook handle. */
37     static DWORD tray_proc_id ATTR_SEC = 0; /* WinPT PID */
38     static HWND shell_traywnd ATTR_SEC = 0; /* Tray window handle. */
39     static HWND curr_focus ATTR_SEC = NULL; /* Current window focus handle. */
40     static HWND rebar_w32 ATTR_SEC = NULL;
41     static HWND mstask_swc ATTR_SEC = NULL;
42     static HWND systab_c32 ATTR_SEC = NULL;
43     #ifndef __GNUC__
44 werner 46 #pragma data_seg()
45 werner 61 #endif
46     #undef ATTR_SEC
47 werner 46
48     static unsigned *journ_keys = 0;
49 twoaday 305 static unsigned keyidx = 0;
50 werner 46 static unsigned nkeys = 0;
51 twoaday 273 static HHOOK journ_hook = NULL; /* Journaling hook handle. */
52 werner 46
53    
54 twoaday 248
55 werner 46 static LRESULT CALLBACK
56     PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)
57     {
58     HWND curr_hwnd = NULL;
59     DWORD proc_id = 0;
60    
61     if (code >= 0 && code == HCBT_SETFOCUS) {
62     /* A window is about to receive the keyboard focus */
63    
64     curr_hwnd = (HWND)wparam;
65 twoaday 273 GetWindowThreadProcessId (curr_hwnd, &proc_id);
66 werner 46 /* Only if the current window is different from this window list,
67     we set the new focus. For more information read the hint in
68     PTD_initialize. */
69     if ((proc_id != tray_proc_id)
70     && (curr_hwnd != NULL)
71     && (curr_hwnd != curr_focus)
72     && (curr_hwnd != shell_traywnd)
73     && (curr_hwnd != systab_c32)
74     && (curr_hwnd != mstask_swc)
75     && (curr_hwnd != rebar_w32)) {
76     curr_focus = curr_hwnd;
77     }
78     }
79    
80     return CallNextHookEx (cbt_hook , code, wparam, lparam);
81     }
82    
83    
84     /* Return the last selected window */
85     extern "C" HWND
86 twoaday 334 PTD_get_current_window (void)
87 werner 46 {
88     return curr_focus;
89     }
90    
91    
92     /* Initialize CTB hook and try to find the system windows. */
93     extern "C" BOOL
94     PTD_initialize (void)
95     {
96     tray_proc_id = GetCurrentProcessId ();
97     cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);
98     if (cbt_hook == NULL)
99     return FALSE;
100    
101     /* Okay, what are we doing here:
102     * In the past I used the Spy++ application to find out why the old current
103     * window doesn't work on so much systems. Now we try to use the computer
104     * based training hook, more precise the HCBT_SETFOCUS to find out the
105     * last window focus. But to succeed we need to ignore some windows
106     * because otherwise our own window or a window from the taskbar
107     * would be recognized.
108     *
109     * Here is what the Spy++ says about the windows order:
110     * Shell_TrayWnd
111     * \ ReBarWindow32
112     * \ MSTaskSwWClass
113     * \ SysTabControl32
114     *
115     * As a result we need to ignore those windows to prevent failured
116     * in the code.
117     */
118 twoaday 334
119     // FIXME: I doubt this is working for Windows 7
120 werner 46 shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);
121     rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);
122     mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);
123     systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);
124    
125 twoaday 305 /*debug ("tray_proc_id=%u cbt_hook=%p shell_traywnd=%p rebar_w32=%p "
126     "mstask_swc=%p systab_c32=%p",
127     tray_proc_id, cbt_hook, shell_traywnd, rebar_w32,
128     mstask_swc, systab_c32);*/
129 werner 46
130     return TRUE;
131     }
132    
133    
134     /* Remove the CTB hook from the system and reset all variables. */
135     extern "C" void
136 twoaday 334 PTD_delete_hook (void)
137 werner 46 {
138     if (!cbt_hook)
139     return;
140     UnhookWindowsHookEx (cbt_hook);
141     cbt_hook = NULL;
142     shell_traywnd = NULL;
143     tray_proc_id = 0;
144     }
145    
146    
147     /* Return if the CTB hook is currently used. */
148     extern "C" int
149 twoaday 334 PTD_is_hook_used (void)
150 werner 46 {
151     return shell_traywnd && cbt_hook;
152     }
153    
154 twoaday 334 /* From the MSDN:
155     * "Typically, an application uses this function to play back a series
156     * of mouse and keyboard messages recorded previously by the
157     * JournalRecordProc hook procedure. As long as a JournalPlaybackProc
158     * hook procedure is installed, regular mouse and keyboard input is disabled."
159     */
160 werner 46 static LRESULT CALLBACK
161     PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)
162     {
163     LPEVENTMSG em;
164    
165     if (code == HC_SKIP) {
166 twoaday 305 keyidx++;
167 twoaday 334 if (keyidx >= nkeys) {
168 werner 46 UnhookWindowsHookEx (journ_hook);
169     journ_hook = NULL;
170     }
171     return 0;
172     }
173     else if (code == HC_GETNEXT) {
174     /* Here is an overview what the event message struct can contain:
175     * message - WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN:
176     * paramL - specifies the virtual key code of the key that was pressed.
177     * paramH - specifies the scan code.
178     */
179     em = (LPEVENTMSG )lparam;
180 twoaday 305 if (journ_keys[keyidx] & 0x8000)
181     em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
182 werner 46 else
183 twoaday 305 em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;
184 twoaday 334 em->paramL = LOBYTE (journ_keys[keyidx])
185 twoaday 305 | (MapVirtualKey (LOBYTE (journ_keys[keyidx]), 0) << 8);
186 werner 46 em->paramH = 1;
187     em->time = GetTickCount ();
188     return 0;
189     }
190    
191     return CallNextHookEx (journ_hook, code, wparam, lparam);
192 twoaday 248 }
193 werner 46
194    
195    
196     extern "C" BOOL
197 twoaday 334 PTD_keyboard_send_keys (UINT *keys, UINT n_keys)
198 werner 46 {
199     MSG msg;
200     journ_keys = keys;
201 twoaday 305 keyidx = 0;
202 twoaday 334 nkeys = n_keys;
203 werner 46
204 twoaday 334 /* Return immediately if there is an active hook */
205 werner 46 if (journ_hook)
206     return FALSE;
207    
208 twoaday 334 while (GetAsyncKeyState (VK_MENU) & 0x8000 ||
209     GetAsyncKeyState (VK_SHIFT) & 0x8000 ||
210     GetAsyncKeyState (VK_CONTROL) & 0x8000) {
211 werner 46 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
212     if (msg.message == WM_QUIT) {
213     PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);
214     return FALSE;
215     }
216     TranslateMessage (&msg);
217     DispatchMessage (&msg);
218     }
219     }
220     journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,
221     (HOOKPROC)PTD_playback_proc,
222     glob_hinst, 0);
223     if (journ_hook == NULL)
224     return FALSE;
225    
226     while (journ_hook) {
227     if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
228     if (msg.message == WM_QUIT) {
229     if (journ_hook)
230     UnhookWindowsHookEx (journ_hook);
231     PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);
232     }
233     TranslateMessage (&msg);
234     DispatchMessage (&msg);
235     }
236     }
237    
238     return TRUE;
239     }
240    
241    
242 twoaday 334 /* Main entry point for the DLL */
243 twoaday 248 extern "C" BOOL WINAPI
244 werner 46 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
245     {
246     switch (reason) {
247 twoaday 334 case DLL_PROCESS_ATTACH:
248     /* Handle to the attached process */
249 twoaday 325 glob_hinst = hinst;
250 werner 46 break;
251 twoaday 325
252     case DLL_PROCESS_DETACH:
253     break;
254    
255 werner 46 case DLL_THREAD_ATTACH:
256     case DLL_THREAD_DETACH:
257     break;
258 twoaday 325
259 werner 46 }
260 twoaday 325
261 werner 46 return TRUE;
262     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26