/[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 1073 - (show annotations)
Thu Mar 9 12:26:31 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 5860 byte(s)
Put virtual channel handling into a separate file since both the DLL and
the main program will use it.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26