/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1131 - (show annotations)
Wed Mar 15 12:15:23 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 6173 byte(s)
Change window creation so that POSITION is sent before STATE (as required by
the protocol). Also remove unnecessary z order comment.

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Seamless windows - Remote server hook DLL
4
5 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 #include <stdio.h>
26 #include <stdarg.h>
27
28 #include <windows.h>
29 #include <winuser.h>
30
31 #include "../vchannel.h"
32
33 #define DLL_EXPORT __declspec(dllexport)
34
35 // Shared DATA
36 #pragma data_seg ( "SHAREDDATA" )
37
38 // this is the total number of processes this dll is currently attached to
39 int g_instance_count = 0;
40
41 #pragma data_seg ()
42
43 #pragma comment(linker, "/section:SHAREDDATA,rws")
44
45 static HHOOK g_cbt_hook = NULL;
46 static HHOOK g_wndproc_hook = NULL;
47
48 static HINSTANCE g_instance = NULL;
49
50 static HANDLE g_mutex = NULL;
51
52 static void
53 update_position(HWND hwnd)
54 {
55 RECT rect;
56
57 if (!GetWindowRect(hwnd, &rect))
58 {
59 debug("GetWindowRect failed!\n");
60 return;
61 }
62
63 vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",
64 hwnd,
65 rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
66 }
67
68 static LRESULT CALLBACK
69 wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
70 {
71 HWND hwnd, parent;
72 UINT msg;
73 WPARAM wparam;
74 LPARAM lparam;
75
76 LONG style;
77
78 if (code < 0)
79 goto end;
80
81 hwnd = ((CWPSTRUCT *) details)->hwnd;
82 msg = ((CWPSTRUCT *) details)->message;
83 wparam = ((CWPSTRUCT *) details)->wParam;
84 lparam = ((CWPSTRUCT *) details)->lParam;
85
86 style = GetWindowLong(hwnd, GWL_STYLE);
87
88 /* Docs say that WS_CHILD and WS_POPUP is an illegal combination,
89 but they exist nonetheless. */
90 if ((style & WS_CHILD) && !(style & WS_POPUP))
91 goto end;
92
93 if (style & WS_POPUP)
94 {
95 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
96 if (!parent)
97 parent = (HWND) - 1;
98 }
99 else
100 parent = NULL;
101
102 switch (msg)
103 {
104
105 case WM_WINDOWPOSCHANGED:
106 {
107 WINDOWPOS *wp = (WINDOWPOS *) lparam;
108
109 if (wp->flags & SWP_SHOWWINDOW)
110 {
111 char title[150];
112 int state;
113
114 vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);
115
116 GetWindowText(hwnd, title, sizeof(title));
117
118 vchannel_write("TITLE,0x%x,%s,0x%x", hwnd,
119 vchannel_strfilter(title), 0);
120
121 if (style & WS_MAXIMIZE)
122 state = 2;
123 else if (style & WS_MINIMIZE)
124 state = 1;
125 else
126 state = 0;
127
128 update_position(hwnd);
129
130 vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);
131 }
132
133 if (wp->flags & SWP_HIDEWINDOW)
134 vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);
135
136 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
137 break;
138
139 if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
140 update_position(hwnd);
141
142 if (!(wp->flags & SWP_NOZORDER))
143 {
144 vchannel_write("ZCHANGE,0x%p,0x%p,0x%x",
145 hwnd,
146 wp->flags & SWP_NOACTIVATE ? wp->
147 hwndInsertAfter : 0, 0);
148 }
149
150 break;
151 }
152
153 case WM_SIZE:
154 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
155 break;
156 update_position(hwnd);
157 break;
158
159 case WM_MOVE:
160 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
161 break;
162 update_position(hwnd);
163 break;
164
165 case WM_SETTEXT:
166 {
167 char *title;
168 if (!(style & WS_VISIBLE))
169 break;
170 title = _strdup((char *) lparam);
171 vchannel_write("TITLE,0x%p,%s,0x%x", hwnd,
172 vchannel_strfilter(title), 0);
173 free(title);
174 break;
175 }
176
177 case WM_DESTROY:
178 if (!(style & WS_VISIBLE))
179 break;
180 vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);
181 break;
182
183 default:
184 break;
185 }
186
187 end:
188 return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
189 }
190
191 static LRESULT CALLBACK
192 cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
193 {
194 if (code < 0)
195 goto end;
196
197 switch (code)
198 {
199 case HCBT_MINMAX:
200 {
201 int show, state;
202
203 show = LOWORD(lparam);
204
205 if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL)
206 || (show == SW_RESTORE))
207 state = 0;
208 else if ((show == SW_MINIMIZE) || (show == SW_SHOWMINIMIZED))
209 state = 1;
210 else if ((show == SW_MAXIMIZE) || (show == SW_SHOWMAXIMIZED))
211 state = 2;
212 else
213 {
214 debug("Unexpected show: %d", show);
215 break;
216 }
217 vchannel_write("STATE,0x%p,0x%x,0x%x", (HWND) wparam, state, 0);
218 break;
219 }
220
221 default:
222 break;
223 }
224
225 end:
226 return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
227 }
228
229 DLL_EXPORT void
230 SetHooks(void)
231 {
232 if (!g_cbt_hook)
233 g_cbt_hook = SetWindowsHookEx(WH_CBT, cbt_hook_proc, g_instance, 0);
234
235 if (!g_wndproc_hook)
236 g_wndproc_hook = SetWindowsHookEx(WH_CALLWNDPROC, wndproc_hook_proc, g_instance, 0);
237 }
238
239 DLL_EXPORT void
240 RemoveHooks(void)
241 {
242 if (g_cbt_hook)
243 UnhookWindowsHookEx(g_cbt_hook);
244
245 if (g_wndproc_hook)
246 UnhookWindowsHookEx(g_wndproc_hook);
247 }
248
249 DLL_EXPORT int
250 GetInstanceCount()
251 {
252 return g_instance_count;
253 }
254
255 BOOL APIENTRY
256 DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
257 {
258 switch (ul_reason_for_call)
259 {
260 case DLL_PROCESS_ATTACH:
261 // remember our instance handle
262 g_instance = hinstDLL;
263
264 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");
265 if (!g_mutex)
266 return FALSE;
267
268 WaitForSingleObject(g_mutex, INFINITE);
269 ++g_instance_count;
270 ReleaseMutex(g_mutex);
271
272 vchannel_open();
273
274 break;
275
276 case DLL_THREAD_ATTACH:
277 break;
278
279 case DLL_THREAD_DETACH:
280 break;
281
282 case DLL_PROCESS_DETACH:
283 WaitForSingleObject(g_mutex, INFINITE);
284 --g_instance_count;
285 ReleaseMutex(g_mutex);
286
287 vchannel_close();
288
289 CloseHandle(g_mutex);
290
291 break;
292 }
293
294 return TRUE;
295 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26