/[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 1134 - (hide annotations)
Wed Mar 15 13:19:54 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 7257 byte(s)
Get window titles in unicode and send them over the channel in UTF-8. This
also meant that we had to catch WM_SETTEXT after it was handled (so that we
can use GetWindowTextW()).

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     // Shared DATA
36     #pragma data_seg ( "SHAREDDATA" )
37    
38     // this is the total number of processes this dll is currently attached to
39 ossman_ 1071 int g_instance_count = 0;
40 ossman_ 1069
41     #pragma data_seg ()
42    
43     #pragma comment(linker, "/section:SHAREDDATA,rws")
44    
45 ossman_ 1071 static HHOOK g_cbt_hook = NULL;
46     static HHOOK g_wndproc_hook = NULL;
47 ossman_ 1134 static HHOOK g_wndprocret_hook = NULL;
48 ossman_ 1069
49 ossman_ 1071 static HINSTANCE g_instance = NULL;
50 ossman_ 1069
51 ossman_ 1071 static HANDLE g_mutex = NULL;
52 ossman_ 1069
53 ossman_ 1081 static void
54     update_position(HWND hwnd)
55     {
56     RECT rect;
57    
58     if (!GetWindowRect(hwnd, &rect))
59     {
60     debug("GetWindowRect failed!\n");
61     return;
62     }
63    
64 astrand 1091 vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",
65 ossman_ 1081 hwnd,
66     rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
67     }
68    
69 ossman_ 1071 static LRESULT CALLBACK
70     wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
71 ossman_ 1069 {
72 ossman_ 1097 HWND hwnd, parent;
73 ossman_ 1079 UINT msg;
74     WPARAM wparam;
75     LPARAM lparam;
76 ossman_ 1069
77 ossman_ 1079 LONG style;
78 ossman_ 1069
79 ossman_ 1071 if (code < 0)
80     goto end;
81 ossman_ 1069
82 ossman_ 1079 hwnd = ((CWPSTRUCT *) details)->hwnd;
83     msg = ((CWPSTRUCT *) details)->message;
84     wparam = ((CWPSTRUCT *) details)->wParam;
85     lparam = ((CWPSTRUCT *) details)->lParam;
86    
87     style = GetWindowLong(hwnd, GWL_STYLE);
88    
89 ossman_ 1082 /* Docs say that WS_CHILD and WS_POPUP is an illegal combination,
90     but they exist nonetheless. */
91     if ((style & WS_CHILD) && !(style & WS_POPUP))
92 ossman_ 1079 goto end;
93    
94 ossman_ 1097 if (style & WS_POPUP)
95 ossman_ 1109 {
96 ossman_ 1097 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
97 ossman_ 1109 if (!parent)
98     parent = (HWND) - 1;
99     }
100 ossman_ 1097 else
101     parent = NULL;
102    
103 ossman_ 1071 switch (msg)
104     {
105 ossman_ 1069
106 ossman_ 1071 case WM_WINDOWPOSCHANGED:
107 ossman_ 1079 {
108     WINDOWPOS *wp = (WINDOWPOS *) lparam;
109 ossman_ 1069
110 ossman_ 1079 if (wp->flags & SWP_SHOWWINDOW)
111     {
112 ossman_ 1134 unsigned short title[150];
113 ossman_ 1099 int state;
114    
115 ossman_ 1097 vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);
116 ossman_ 1069
117 ossman_ 1134 GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
118 ossman_ 1069
119 ossman_ 1113 vchannel_write("TITLE,0x%x,%s,0x%x", hwnd,
120 ossman_ 1134 vchannel_strfilter_unicode(title), 0);
121 ossman_ 1099
122     if (style & WS_MAXIMIZE)
123     state = 2;
124     else if (style & WS_MINIMIZE)
125     state = 1;
126     else
127     state = 0;
128    
129 ossman_ 1081 update_position(hwnd);
130 ossman_ 1099
131 ossman_ 1131 vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);
132 ossman_ 1079 }
133 ossman_ 1069
134 ossman_ 1079 if (wp->flags & SWP_HIDEWINDOW)
135 astrand 1091 vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);
136 ossman_ 1079
137 ossman_ 1108 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
138 ossman_ 1079 break;
139    
140 ossman_ 1080 if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
141 ossman_ 1081 update_position(hwnd);
142 ossman_ 1079
143     if (!(wp->flags & SWP_NOZORDER))
144 ossman_ 1080 {
145 astrand 1091 vchannel_write("ZCHANGE,0x%p,0x%p,0x%x",
146 ossman_ 1079 hwnd,
147     wp->flags & SWP_NOACTIVATE ? wp->
148     hwndInsertAfter : 0, 0);
149 ossman_ 1080 }
150 ossman_ 1069
151 ossman_ 1071 break;
152 ossman_ 1079 }
153 ossman_ 1069
154 ossman_ 1081 case WM_SIZE:
155 ossman_ 1108 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
156 ossman_ 1083 break;
157 ossman_ 1081 update_position(hwnd);
158     break;
159    
160     case WM_MOVE:
161 ossman_ 1108 if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
162 ossman_ 1083 break;
163 ossman_ 1081 update_position(hwnd);
164     break;
165    
166 ossman_ 1134 case WM_DESTROY:
167     if (!(style & WS_VISIBLE))
168     break;
169     vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);
170     break;
171    
172     default:
173     break;
174     }
175    
176     end:
177     return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
178     }
179    
180     static LRESULT CALLBACK
181     wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details)
182     {
183     HWND hwnd, parent;
184     UINT msg;
185     WPARAM wparam;
186     LPARAM lparam;
187    
188     LONG style;
189    
190     if (code < 0)
191     goto end;
192    
193     hwnd = ((CWPRETSTRUCT *) details)->hwnd;
194     msg = ((CWPRETSTRUCT *) details)->message;
195     wparam = ((CWPRETSTRUCT *) details)->wParam;
196     lparam = ((CWPRETSTRUCT *) details)->lParam;
197    
198     style = GetWindowLong(hwnd, GWL_STYLE);
199    
200     /* Docs say that WS_CHILD and WS_POPUP is an illegal combination,
201     but they exist nonetheless. */
202     if ((style & WS_CHILD) && !(style & WS_POPUP))
203     goto end;
204    
205     switch (msg)
206     {
207 ossman_ 1102 case WM_SETTEXT:
208 ossman_ 1113 {
209 ossman_ 1134 unsigned short title[150];
210 ossman_ 1113 if (!(style & WS_VISIBLE))
211     break;
212 ossman_ 1134 /* We cannot use the string in lparam because
213     we need unicode. */
214     GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
215 ossman_ 1113 vchannel_write("TITLE,0x%p,%s,0x%x", hwnd,
216 ossman_ 1134 vchannel_strfilter_unicode(title), 0);
217 ossman_ 1102 break;
218 ossman_ 1113 }
219 ossman_ 1102
220 ossman_ 1071 default:
221     break;
222     }
223    
224     end:
225 ossman_ 1134 return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details);
226 ossman_ 1069 }
227    
228 ossman_ 1071 static LRESULT CALLBACK
229     cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
230 ossman_ 1069 {
231 ossman_ 1071 if (code < 0)
232     goto end;
233 ossman_ 1069
234 ossman_ 1071 switch (code)
235     {
236     case HCBT_MINMAX:
237     {
238 ossman_ 1079 int show, state;
239 ossman_ 1069
240 ossman_ 1071 show = LOWORD(lparam);
241 ossman_ 1069
242 ossman_ 1128 if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL)
243     || (show == SW_RESTORE))
244 ossman_ 1079 state = 0;
245 ossman_ 1106 else if ((show == SW_MINIMIZE) || (show == SW_SHOWMINIMIZED))
246 ossman_ 1079 state = 1;
247 ossman_ 1106 else if ((show == SW_MAXIMIZE) || (show == SW_SHOWMAXIMIZED))
248 ossman_ 1079 state = 2;
249 ossman_ 1100 else
250 ossman_ 1106 {
251     debug("Unexpected show: %d", show);
252 ossman_ 1100 break;
253 ossman_ 1106 }
254 ossman_ 1096 vchannel_write("STATE,0x%p,0x%x,0x%x", (HWND) wparam, state, 0);
255 ossman_ 1071 break;
256     }
257 ossman_ 1069
258 ossman_ 1071 default:
259     break;
260     }
261 ossman_ 1069
262 ossman_ 1071 end:
263     return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
264 ossman_ 1069 }
265    
266 ossman_ 1071 DLL_EXPORT void
267     SetHooks(void)
268 ossman_ 1069 {
269 ossman_ 1071 if (!g_cbt_hook)
270     g_cbt_hook = SetWindowsHookEx(WH_CBT, cbt_hook_proc, g_instance, 0);
271 ossman_ 1069
272 ossman_ 1071 if (!g_wndproc_hook)
273     g_wndproc_hook = SetWindowsHookEx(WH_CALLWNDPROC, wndproc_hook_proc, g_instance, 0);
274 ossman_ 1134
275     if (!g_wndprocret_hook)
276     g_wndprocret_hook =
277     SetWindowsHookEx(WH_CALLWNDPROCRET, wndprocret_hook_proc, g_instance, 0);
278 ossman_ 1069 }
279    
280 ossman_ 1071 DLL_EXPORT void
281     RemoveHooks(void)
282 ossman_ 1069 {
283 ossman_ 1071 if (g_cbt_hook)
284     UnhookWindowsHookEx(g_cbt_hook);
285 ossman_ 1069
286 ossman_ 1071 if (g_wndproc_hook)
287     UnhookWindowsHookEx(g_wndproc_hook);
288 ossman_ 1134
289     if (g_wndprocret_hook)
290     UnhookWindowsHookEx(g_wndprocret_hook);
291 ossman_ 1069 }
292    
293 ossman_ 1071 DLL_EXPORT int
294     GetInstanceCount()
295 ossman_ 1069 {
296 ossman_ 1071 return g_instance_count;
297 ossman_ 1069 }
298    
299 ossman_ 1071 BOOL APIENTRY
300     DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
301 ossman_ 1069 {
302 ossman_ 1071 switch (ul_reason_for_call)
303     {
304     case DLL_PROCESS_ATTACH:
305     // remember our instance handle
306     g_instance = hinstDLL;
307 ossman_ 1069
308 ossman_ 1073 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");
309 ossman_ 1071 if (!g_mutex)
310     return FALSE;
311 ossman_ 1069
312 ossman_ 1071 WaitForSingleObject(g_mutex, INFINITE);
313     ++g_instance_count;
314     ReleaseMutex(g_mutex);
315 ossman_ 1069
316 ossman_ 1071 vchannel_open();
317 ossman_ 1069
318 ossman_ 1071 break;
319 ossman_ 1069
320 ossman_ 1071 case DLL_THREAD_ATTACH:
321     break;
322 ossman_ 1069
323 ossman_ 1071 case DLL_THREAD_DETACH:
324     break;
325 ossman_ 1069
326 ossman_ 1071 case DLL_PROCESS_DETACH:
327     WaitForSingleObject(g_mutex, INFINITE);
328     --g_instance_count;
329     ReleaseMutex(g_mutex);
330 ossman_ 1069
331 ossman_ 1071 vchannel_close();
332 ossman_ 1069
333 ossman_ 1071 CloseHandle(g_mutex);
334 ossman_ 1069
335 ossman_ 1071 break;
336     }
337 ossman_ 1069
338 ossman_ 1071 return TRUE;
339 ossman_ 1069 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26