/[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 1073 - (hide 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 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_ 1069
48 ossman_ 1071 static HINSTANCE g_instance = NULL;
49 ossman_ 1069
50 ossman_ 1071 static HANDLE g_mutex = NULL;
51 ossman_ 1069
52 ossman_ 1071 static LRESULT CALLBACK
53     wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
54 ossman_ 1069 {
55 ossman_ 1071 HWND hwnd = ((CWPSTRUCT *) details)->hwnd;
56     UINT msg = ((CWPSTRUCT *) details)->message;
57     WPARAM wparam = ((CWPSTRUCT *) details)->wParam;
58     LPARAM lparam = ((CWPSTRUCT *) details)->lParam;
59 ossman_ 1069
60 ossman_ 1071 LONG style = GetWindowLong(hwnd, GWL_STYLE);
61     WINDOWPOS *wp = (WINDOWPOS *) lparam;
62     RECT rect;
63 ossman_ 1069
64 ossman_ 1071 if (code < 0)
65     goto end;
66 ossman_ 1069
67 ossman_ 1071 switch (msg)
68     {
69 ossman_ 1069
70 ossman_ 1071 case WM_WINDOWPOSCHANGED:
71     if (style & WS_CHILD)
72     break;
73 ossman_ 1069
74    
75 ossman_ 1071 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 ossman_ 1069
81 ossman_ 1071 // FIXME: SETSTATE
82 ossman_ 1069
83 ossman_ 1071 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 ossman_ 1069
94    
95 ossman_ 1071 if (wp->flags & SWP_HIDEWINDOW)
96     vchannel_write("DESTROY1,0x%p,0x%x", hwnd, 0);
97 ossman_ 1069
98    
99 ossman_ 1071 if (!(style & WS_VISIBLE))
100     break;
101 ossman_ 1069
102 ossman_ 1071 if (wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE)
103     break;
104 ossman_ 1069
105 ossman_ 1071 if (!GetWindowRect(hwnd, &rect))
106     {
107     debug("GetWindowRect failed!\n");
108     break;
109     }
110 ossman_ 1069
111 ossman_ 1071 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 ossman_ 1069
116 ossman_ 1071 break;
117 ossman_ 1069
118    
119 ossman_ 1071 /* 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 ossman_ 1069
131 ossman_ 1071 if (!(style & WS_VISIBLE))
132     break;
133 ossman_ 1069
134 ossman_ 1071 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 ossman_ 1069
140 ossman_ 1071 break;
141 ossman_ 1069
142    
143    
144    
145 ossman_ 1071 case WM_DESTROY:
146     if (style & WS_CHILD)
147     break;
148 ossman_ 1069
149 ossman_ 1071 vchannel_write("DESTROY1,0x%p,0x%x", hwnd, 0);
150 ossman_ 1069
151 ossman_ 1071 break;
152 ossman_ 1069
153    
154 ossman_ 1071 default:
155     break;
156     }
157    
158     end:
159     return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
160 ossman_ 1069 }
161    
162 ossman_ 1071 static LRESULT CALLBACK
163     cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
164 ossman_ 1069 {
165 ossman_ 1071 char title[150];
166 ossman_ 1069
167 ossman_ 1071 if (code < 0)
168     goto end;
169 ossman_ 1069
170 ossman_ 1071 switch (code)
171     {
172     case HCBT_MINMAX:
173     {
174     int show;
175 ossman_ 1069
176 ossman_ 1071 show = LOWORD(lparam);
177 ossman_ 1069
178 ossman_ 1071 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 ossman_ 1069
186 ossman_ 1071 GetWindowText((HWND) wparam, title, sizeof(title));
187 ossman_ 1069
188 ossman_ 1071 /* FIXME: Strip title of dangerous characters */
189 ossman_ 1069
190 ossman_ 1071 vchannel_write("SETSTATE1,0x%p,%s,0x%x,0x%x",
191     (HWND) wparam, title, show, 0);
192     break;
193     }
194 ossman_ 1069
195 ossman_ 1071 default:
196     break;
197     }
198 ossman_ 1069
199 ossman_ 1071 end:
200     return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
201 ossman_ 1069 }
202    
203 ossman_ 1071 DLL_EXPORT void
204     SetHooks(void)
205 ossman_ 1069 {
206 ossman_ 1071 if (!g_cbt_hook)
207     g_cbt_hook = SetWindowsHookEx(WH_CBT, cbt_hook_proc, g_instance, 0);
208 ossman_ 1069
209 ossman_ 1071 if (!g_wndproc_hook)
210     g_wndproc_hook = SetWindowsHookEx(WH_CALLWNDPROC, wndproc_hook_proc, g_instance, 0);
211 ossman_ 1069 }
212    
213 ossman_ 1071 DLL_EXPORT void
214     RemoveHooks(void)
215 ossman_ 1069 {
216 ossman_ 1071 if (g_cbt_hook)
217     UnhookWindowsHookEx(g_cbt_hook);
218 ossman_ 1069
219 ossman_ 1071 if (g_wndproc_hook)
220     UnhookWindowsHookEx(g_wndproc_hook);
221 ossman_ 1069 }
222    
223 ossman_ 1071 DLL_EXPORT int
224     GetInstanceCount()
225 ossman_ 1069 {
226 ossman_ 1071 return g_instance_count;
227 ossman_ 1069 }
228    
229 ossman_ 1071 BOOL APIENTRY
230     DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
231 ossman_ 1069 {
232 ossman_ 1071 switch (ul_reason_for_call)
233     {
234     case DLL_PROCESS_ATTACH:
235     // remember our instance handle
236     g_instance = hinstDLL;
237 ossman_ 1069
238 ossman_ 1073 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");
239 ossman_ 1071 if (!g_mutex)
240     return FALSE;
241 ossman_ 1069
242 ossman_ 1071 WaitForSingleObject(g_mutex, INFINITE);
243     ++g_instance_count;
244     ReleaseMutex(g_mutex);
245 ossman_ 1069
246 ossman_ 1071 vchannel_open();
247 ossman_ 1069
248 ossman_ 1071 break;
249 ossman_ 1069
250 ossman_ 1071 case DLL_THREAD_ATTACH:
251     break;
252 ossman_ 1069
253 ossman_ 1071 case DLL_THREAD_DETACH:
254     break;
255 ossman_ 1069
256 ossman_ 1071 case DLL_PROCESS_DETACH:
257     WaitForSingleObject(g_mutex, INFINITE);
258     --g_instance_count;
259     ReleaseMutex(g_mutex);
260 ossman_ 1069
261 ossman_ 1071 vchannel_close();
262 ossman_ 1069
263 ossman_ 1071 CloseHandle(g_mutex);
264 ossman_ 1069
265 ossman_ 1071 break;
266     }
267 ossman_ 1069
268 ossman_ 1071 return TRUE;
269 ossman_ 1069 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26