/[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 1079 - (show annotations)
Thu Mar 9 15:48:55 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 5615 byte(s)
More cleanup and reorganisation.

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 LRESULT CALLBACK
53 wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
54 {
55 HWND hwnd;
56 UINT msg;
57 WPARAM wparam;
58 LPARAM lparam;
59
60 LONG style;
61
62 if (code < 0)
63 goto end;
64
65 hwnd = ((CWPSTRUCT *) details)->hwnd;
66 msg = ((CWPSTRUCT *) details)->message;
67 wparam = ((CWPSTRUCT *) details)->wParam;
68 lparam = ((CWPSTRUCT *) details)->lParam;
69
70 style = GetWindowLong(hwnd, GWL_STYLE);
71
72 if (style & WS_CHILD)
73 goto end;
74
75 switch (msg)
76 {
77
78 case WM_WINDOWPOSCHANGED:
79 {
80 RECT rect;
81 WINDOWPOS *wp = (WINDOWPOS *) lparam;
82
83 if (wp->flags & SWP_SHOWWINDOW)
84 {
85 // FIXME: Now, just like create!
86 debug("SWP_SHOWWINDOW for %p!", hwnd);
87 vchannel_write("CREATE1,0x%p,0x%x", hwnd, 0);
88
89 // FIXME: SETSTATE
90
91 if (!GetWindowRect(hwnd, &rect))
92 {
93 debug("GetWindowRect failed!\n");
94 break;
95 }
96 vchannel_write("POSITION1,0x%p,%d,%d,%d,%d,0x%x",
97 hwnd,
98 rect.left, rect.top,
99 rect.right - rect.left,
100 rect.bottom - rect.top, 0);
101 }
102
103 if (wp->flags & SWP_HIDEWINDOW)
104 vchannel_write("DESTROY1,0x%p,0x%x", hwnd, 0);
105
106 if (!(style & WS_VISIBLE))
107 break;
108
109 if (wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE)
110 break;
111
112 if (!GetWindowRect(hwnd, &rect))
113 {
114 debug("GetWindowRect failed!\n");
115 break;
116 }
117
118 vchannel_write("POSITION1,0x%p,%d,%d,%d,%d,0x%x",
119 hwnd,
120 rect.left, rect.top,
121 rect.right - rect.left, rect.bottom - rect.top, 0);
122
123 break;
124 }
125
126 case WM_WINDOWPOSCHANGING:
127 {
128 WINDOWPOS *wp = (WINDOWPOS *) lparam;
129
130 if (!(style & WS_VISIBLE))
131 break;
132
133 if (!(wp->flags & SWP_NOZORDER))
134 vchannel_write("ZCHANGE1,0x%p,0x%p,0x%x",
135 hwnd,
136 wp->flags & SWP_NOACTIVATE ? wp->
137 hwndInsertAfter : 0, 0);
138
139 break;
140 }
141
142 case WM_DESTROY:
143 vchannel_write("DESTROY1,0x%p,0x%x", hwnd, 0);
144 break;
145
146 default:
147 break;
148 }
149
150 end:
151 return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
152 }
153
154 static LRESULT CALLBACK
155 cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
156 {
157 char title[150];
158
159 if (code < 0)
160 goto end;
161
162 switch (code)
163 {
164 case HCBT_MINMAX:
165 {
166 int show, state;
167
168 show = LOWORD(lparam);
169
170 if ((show == SW_SHOWMINIMIZED) || (show == SW_MINIMIZE))
171 {
172 MessageBox(0,
173 "Minimizing windows is not allowed in this version. Sorry!",
174 "SeamlessRDP", MB_OK);
175 return 1;
176 }
177
178 GetWindowText((HWND) wparam, title, sizeof(title));
179
180 /* FIXME: Strip title of dangerous characters */
181
182 if (show == SW_SHOWNORMAL)
183 state = 0;
184 else if (show == SW_SHOWMINIMIZED)
185 state = 1;
186 else if (show == SW_SHOWMAXIMIZED)
187 state = 2;
188 vchannel_write("SETSTATE1,0x%p,%s,0x%x,0x%x",
189 (HWND) wparam, title, state, 0);
190 break;
191 }
192
193 default:
194 break;
195 }
196
197 end:
198 return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
199 }
200
201 DLL_EXPORT void
202 SetHooks(void)
203 {
204 if (!g_cbt_hook)
205 g_cbt_hook = SetWindowsHookEx(WH_CBT, cbt_hook_proc, g_instance, 0);
206
207 if (!g_wndproc_hook)
208 g_wndproc_hook = SetWindowsHookEx(WH_CALLWNDPROC, wndproc_hook_proc, g_instance, 0);
209 }
210
211 DLL_EXPORT void
212 RemoveHooks(void)
213 {
214 if (g_cbt_hook)
215 UnhookWindowsHookEx(g_cbt_hook);
216
217 if (g_wndproc_hook)
218 UnhookWindowsHookEx(g_wndproc_hook);
219 }
220
221 DLL_EXPORT int
222 GetInstanceCount()
223 {
224 return g_instance_count;
225 }
226
227 BOOL APIENTRY
228 DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
229 {
230 switch (ul_reason_for_call)
231 {
232 case DLL_PROCESS_ATTACH:
233 // remember our instance handle
234 g_instance = hinstDLL;
235
236 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");
237 if (!g_mutex)
238 return FALSE;
239
240 WaitForSingleObject(g_mutex, INFINITE);
241 ++g_instance_count;
242 ReleaseMutex(g_mutex);
243
244 vchannel_open();
245
246 break;
247
248 case DLL_THREAD_ATTACH:
249 break;
250
251 case DLL_THREAD_DETACH:
252 break;
253
254 case DLL_PROCESS_DETACH:
255 WaitForSingleObject(g_mutex, INFINITE);
256 --g_instance_count;
257 ReleaseMutex(g_mutex);
258
259 vchannel_close();
260
261 CloseHandle(g_mutex);
262
263 break;
264 }
265
266 return TRUE;
267 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26