/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/HookDll/hookdll.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/seamlessrdp/ServerExe/HookDll/hookdll.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1145 - (hide annotations)
Thu Mar 16 13:24:18 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 8176 byte(s)
Prevent moves we do ourself from generating a POSITION. We do this by storing
the coordinate we're moving to in a shared variable. Since SetWindowPos is
synchronous, we know that the variable will have valid data when the hook
is called.

1 ossman_ 1071 /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.
3     Seamless windows - Remote server hook DLL
4 ossman_ 1069
5 ossman_ 1071 Based on code copyright (C) 2004-2005 Martin Wickett
6    
7     Copyright (C) Peter Åstrand <astrand@cendio.se> 2005-2006
8     Copyright (C) Pierre Ossman <ossman@cendio.se> 2006
9    
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU General Public License for more details.
19    
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23     */
24    
25 ossman_ 1069 #include <stdio.h>
26     #include <stdarg.h>
27    
28 ossman_ 1071 #include <windows.h>
29     #include <winuser.h>
30 ossman_ 1069
31 ossman_ 1073 #include "../vchannel.h"
32 ossman_ 1071
33 ossman_ 1069 #define DLL_EXPORT __declspec(dllexport)
34    
35 ossman_ 1145 #ifdef __GNUC__
36     #define SHARED __attribute__((section ("SHAREDDATA"), shared))
37     #else
38     #define SHARED
39     #endif
40    
41 ossman_ 1069 // Shared DATA
42     #pragma data_seg ( "SHAREDDATA" )
43    
44     // this is the total number of processes this dll is currently attached to
45 ossman_ 1145 int g_instance_count SHARED = 0;
46 ossman_ 1069
47 ossman_ 1145 // blocks for locally generated events
48     RECT g_block_move SHARED = { 0, 0, 0, 0 };
49    
50 ossman_ 1069 #pragma data_seg ()
51    
52     #pragma comment(linker, "/section:SHAREDDATA,rws")
53    
54 ossman_ 1071 static HHOOK g_cbt_hook = NULL;
55     static HHOOK g_wndproc_hook = NULL;
56 ossman_ 1134 static HHOOK g_wndprocret_hook = NULL;
57 ossman_ 1069
58 ossman_ 1071 static HINSTANCE g_instance = NULL;
59 ossman_ 1069
60 ossman_ 1071 static HANDLE g_mutex = NULL;
61 ossman_ 1069
62 ossman_ 1081 static void
63     update_position(HWND hwnd)
64     {
65 ossman_ 1145 RECT rect, blocked;
66 ossman_ 1081
67     if (!GetWindowRect(hwnd, &rect))
68     {
69     debug("GetWindowRect failed!\n");
70     return;
71     }
72    
73 ossman_ 1145 WaitForSingleObject(g_mutex, INFINITE);
74     memcpy(&blocked, &g_block_move, sizeof(RECT));
75     ReleaseMutex(g_mutex);
76    
77     if ((rect.left == blocked.left) && (rect.top == blocked.top)
78     && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))
79     return;
80    
81 astrand 1091 vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",
82 ossman_ 1081 hwnd,
83     rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
84     }
85    
86 ossman_ 1071 static LRESULT CALLBACK
87     wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
88 ossman_ 1069 {
89 ossman_ 1097 HWND hwnd, parent;
90 ossman_ 1079 UINT msg;
91     WPARAM wparam;
92     LPARAM lparam;
93 ossman_ 1069
94 ossman_ 1079 LONG style;
95 ossman_ 1069
96 ossman_ 1071 if (code < 0)
97     goto end;
98 ossman_ 1069
99 ossman_ 1079 hwnd = ((CWPSTRUCT *) details)->hwnd;
100     msg = ((CWPSTRUCT *) details)->message;
101     wparam = ((CWPSTRUCT *) details)->wParam;
102     lparam = ((CWPSTRUCT *) details)->lParam;
103    
104     style = GetWindowLong(hwnd, GWL_STYLE);
105    
106 ossman_ 1082 /* Docs say that WS_CHILD and WS_POPUP is an illegal combination,
107     but they exist nonetheless. */
108     if ((style & WS_CHILD) && !(style & WS_POPUP))
109 ossman_ 1079 goto end;
110    
111 ossman_ 1097 if (style & WS_POPUP)
112 ossman_ 1109 {
113 ossman_ 1097 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
114 ossman_ 1109 if (!parent)
115     parent = (HWND) - 1;
116     }
117 ossman_ 1097 else
118     parent = NULL;
119    
120 ossman_ 1071 switch (msg)
121     {
122 ossman_ 1069
123 ossman_ 1071 case WM_WINDOWPOSCHANGED:
124 ossman_ 1079 {
125     WINDOWPOS *wp = (WINDOWPOS *) lparam;
126 ossman_ 1069
127 ossman_ 1079 if (wp->flags & SWP_SHOWWINDOW)
128     {
129 ossman_ 1134 unsigned short title[150];
130 ossman_ 1099 int state;
131    
132 ossman_ 1097 vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);
133 ossman_ 1069
134 ossman_ 1134 GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
135 ossman_ 1069
136 ossman_ 1113 vchannel_write("TITLE,0x%x,%s,0x%x", hwnd,
137 ossman_ 1134 vchannel_strfilter_unicode(title), 0);
138 ossman_ 1099
139     if (style & WS_MAXIMIZE)
140     state = 2;
141     else if (style & WS_MINIMIZE)
142     state = 1;
143     else
144     state = 0;
145    
146 ossman_ 1081 update_position(hwnd);
147 ossman_ 1099
148 ossman_ 1131 vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);
149 ossman_ 1079 }
150 ossman_ 1069
151 ossman_ 1079 if (wp->flags & SWP_HIDEWINDOW)
152 astrand 1091 vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);
153 ossman_ 1079
154 ossman_ 1108 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
155 ossman_ 1079 break;
156    
157 ossman_ 1080 if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
158 ossman_ 1081 update_position(hwnd);
159 ossman_ 1079
160     if (!(wp->flags & SWP_NOZORDER))
161 ossman_ 1080 {
162 astrand 1091 vchannel_write("ZCHANGE,0x%p,0x%p,0x%x",
163 ossman_ 1079 hwnd,
164     wp->flags & SWP_NOACTIVATE ? wp->
165     hwndInsertAfter : 0, 0);
166 ossman_ 1080 }
167 ossman_ 1069
168 ossman_ 1071 break;
169 ossman_ 1079 }
170 ossman_ 1069
171 ossman_ 1081 case WM_SIZE:
172 ossman_ 1108 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
173 ossman_ 1083 break;
174 ossman_ 1081 update_position(hwnd);
175     break;
176    
177     case WM_MOVE:
178 ossman_ 1108 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
179 ossman_ 1083 break;
180 ossman_ 1081 update_position(hwnd);
181     break;
182    
183 ossman_ 1134 case WM_DESTROY:
184     if (!(style & WS_VISIBLE))
185     break;
186     vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);
187     break;
188    
189     default:
190     break;
191     }
192    
193     end:
194     return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
195     }
196    
197     static LRESULT CALLBACK
198     wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details)
199     {
200     HWND hwnd, parent;
201     UINT msg;
202     WPARAM wparam;
203     LPARAM lparam;
204    
205     LONG style;
206    
207     if (code < 0)
208     goto end;
209    
210     hwnd = ((CWPRETSTRUCT *) details)->hwnd;
211     msg = ((CWPRETSTRUCT *) details)->message;
212     wparam = ((CWPRETSTRUCT *) details)->wParam;
213     lparam = ((CWPRETSTRUCT *) details)->lParam;
214    
215     style = GetWindowLong(hwnd, GWL_STYLE);
216    
217     /* Docs say that WS_CHILD and WS_POPUP is an illegal combination,
218     but they exist nonetheless. */
219     if ((style & WS_CHILD) && !(style & WS_POPUP))
220     goto end;
221    
222     switch (msg)
223     {
224 ossman_ 1102 case WM_SETTEXT:
225 ossman_ 1113 {
226 ossman_ 1134 unsigned short title[150];
227 ossman_ 1113 if (!(style & WS_VISIBLE))
228     break;
229 ossman_ 1134 /* We cannot use the string in lparam because
230     we need unicode. */
231     GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
232 ossman_ 1113 vchannel_write("TITLE,0x%p,%s,0x%x", hwnd,
233 ossman_ 1134 vchannel_strfilter_unicode(title), 0);
234 ossman_ 1102 break;
235 ossman_ 1113 }
236 ossman_ 1102
237 ossman_ 1071 default:
238     break;
239     }
240    
241     end:
242 ossman_ 1134 return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details);
243 ossman_ 1069 }
244    
245 ossman_ 1071 static LRESULT CALLBACK
246     cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
247 ossman_ 1069 {
248 ossman_ 1071 if (code < 0)
249     goto end;
250 ossman_ 1069
251 ossman_ 1071 switch (code)
252     {
253     case HCBT_MINMAX:
254     {
255 ossman_ 1079 int show, state;
256 ossman_ 1069
257 ossman_ 1071 show = LOWORD(lparam);
258 ossman_ 1069
259 ossman_ 1128 if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL)
260     || (show == SW_RESTORE))
261 ossman_ 1079 state = 0;
262 ossman_ 1106 else if ((show == SW_MINIMIZE) || (show == SW_SHOWMINIMIZED))
263 ossman_ 1079 state = 1;
264 ossman_ 1106 else if ((show == SW_MAXIMIZE) || (show == SW_SHOWMAXIMIZED))
265 ossman_ 1079 state = 2;
266 ossman_ 1100 else
267 ossman_ 1106 {
268     debug("Unexpected show: %d", show);
269 ossman_ 1100 break;
270 ossman_ 1106 }
271 ossman_ 1096 vchannel_write("STATE,0x%p,0x%x,0x%x", (HWND) wparam, state, 0);
272 ossman_ 1071 break;
273     }
274 ossman_ 1069
275 ossman_ 1071 default:
276     break;
277     }
278 ossman_ 1069
279 ossman_ 1071 end:
280     return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
281 ossman_ 1069 }
282    
283 ossman_ 1071 DLL_EXPORT void
284     SetHooks(void)
285 ossman_ 1069 {
286 ossman_ 1071 if (!g_cbt_hook)
287     g_cbt_hook = SetWindowsHookEx(WH_CBT, cbt_hook_proc, g_instance, 0);
288 ossman_ 1069
289 ossman_ 1071 if (!g_wndproc_hook)
290     g_wndproc_hook = SetWindowsHookEx(WH_CALLWNDPROC, wndproc_hook_proc, g_instance, 0);
291 ossman_ 1134
292     if (!g_wndprocret_hook)
293     g_wndprocret_hook =
294     SetWindowsHookEx(WH_CALLWNDPROCRET, wndprocret_hook_proc, g_instance, 0);
295 ossman_ 1069 }
296    
297 ossman_ 1071 DLL_EXPORT void
298     RemoveHooks(void)
299 ossman_ 1069 {
300 ossman_ 1071 if (g_cbt_hook)
301     UnhookWindowsHookEx(g_cbt_hook);
302 ossman_ 1069
303 ossman_ 1071 if (g_wndproc_hook)
304     UnhookWindowsHookEx(g_wndproc_hook);
305 ossman_ 1134
306     if (g_wndprocret_hook)
307     UnhookWindowsHookEx(g_wndprocret_hook);
308 ossman_ 1069 }
309    
310 ossman_ 1145 DLL_EXPORT void
311     SafeMoveWindow(HWND hwnd, int x, int y, int width, int height)
312     {
313     WaitForSingleObject(g_mutex, INFINITE);
314     g_block_move.left = x;
315     g_block_move.top = y;
316     g_block_move.right = x + width;
317     g_block_move.bottom = y + height;
318     ReleaseMutex(g_mutex);
319    
320     SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);
321    
322     WaitForSingleObject(g_mutex, INFINITE);
323     memset(&g_block_move, 0, sizeof(RECT));
324     ReleaseMutex(g_mutex);
325     }
326    
327 ossman_ 1071 DLL_EXPORT int
328     GetInstanceCount()
329 ossman_ 1069 {
330 ossman_ 1071 return g_instance_count;
331 ossman_ 1069 }
332    
333 ossman_ 1071 BOOL APIENTRY
334     DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
335 ossman_ 1069 {
336 ossman_ 1071 switch (ul_reason_for_call)
337     {
338     case DLL_PROCESS_ATTACH:
339     // remember our instance handle
340     g_instance = hinstDLL;
341 ossman_ 1069
342 ossman_ 1073 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");
343 ossman_ 1071 if (!g_mutex)
344     return FALSE;
345 ossman_ 1069
346 ossman_ 1071 WaitForSingleObject(g_mutex, INFINITE);
347     ++g_instance_count;
348     ReleaseMutex(g_mutex);
349 ossman_ 1069
350 ossman_ 1071 vchannel_open();
351 ossman_ 1069
352 ossman_ 1071 break;
353 ossman_ 1069
354 ossman_ 1071 case DLL_THREAD_ATTACH:
355     break;
356 ossman_ 1069
357 ossman_ 1071 case DLL_THREAD_DETACH:
358     break;
359 ossman_ 1069
360 ossman_ 1071 case DLL_PROCESS_DETACH:
361     WaitForSingleObject(g_mutex, INFINITE);
362     --g_instance_count;
363     ReleaseMutex(g_mutex);
364 ossman_ 1069
365 ossman_ 1071 vchannel_close();
366 ossman_ 1069
367 ossman_ 1071 CloseHandle(g_mutex);
368 ossman_ 1069
369 ossman_ 1071 break;
370     }
371 ossman_ 1069
372 ossman_ 1071 return TRUE;
373 ossman_ 1069 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26