/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/HookDll/hookdll.cpp
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.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1065 - (show annotations)
Wed Mar 8 16:12:49 2006 UTC (18 years, 2 months ago) by ossman_
File size: 11342 byte(s)
Run indent-all on the server source.

1 //
2 // Copyright (C) 2004-2005 Martin Wickett
3 //
4
5 #include "hookdll.h"
6 #include <windows.h>
7 #include <winuser.h>
8 #include <stdio.h>
9 #include <stdarg.h>
10
11 #include "wtsapi32.h"
12 #include "cchannel.h"
13
14 #define DLL_EXPORT extern "C" __declspec(dllexport)
15
16 // Shared DATA
17 #pragma data_seg ( "SHAREDDATA" )
18
19 // this is the total number of processes this dll is currently attached to
20 int iInstanceCount = 0;
21 HWND hWnd = 0;
22
23 #pragma data_seg ()
24
25 #pragma comment(linker, "/section:SHAREDDATA,rws")
26
27 #define snprintf _snprintf
28
29 HHOOK hCbtProc = 0;
30 HHOOK hShellProc = 0;
31 HHOOK hWndProc = 0;
32 HINSTANCE hInst = 0;
33 HANDLE m_vcHandle = 0;
34
35
36 void SendDebug( char *format, ... )
37 {
38 va_list argp;
39 char buf [ 256 ];
40
41 va_start( argp, format );
42 vsprintf( buf, format, argp );
43 va_end( argp );
44
45 WriteToChannel( "DEBUG1," );
46 WriteToChannel( buf );
47 WriteToChannel( "\n" );
48 }
49
50
51
52 extern "C" BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved )
53 {
54 switch ( ul_reason_for_call ) {
55 case DLL_PROCESS_ATTACH: {
56 // remember our instance handle
57 hInst = hinstDLL;
58 ++iInstanceCount;
59 OpenVirtualChannel();
60 break;
61 }
62
63 case DLL_THREAD_ATTACH:
64 break;
65 case DLL_THREAD_DETACH:
66 break;
67 case DLL_PROCESS_DETACH: {
68 --iInstanceCount;
69 CloseVirtualChannel();
70 }
71 break;
72 }
73
74 return TRUE;
75 }
76
77 LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
78 {
79 if ( nCode < 0 ) {
80 return CallNextHookEx( hWndProc, nCode, wParam, lParam );
81 }
82
83 char windowTitle[ 150 ] = { ""
84 };
85 HWND windowHandle = NULL;
86 HWND windowHandle2 = NULL;
87 char result[ 255 ] = { ""
88 };
89 CWPSTRUCT *details = ( CWPSTRUCT * ) lParam;
90 CREATESTRUCT *cs = ( CREATESTRUCT * ) details->lParam;
91 LONG dwStyle = GetWindowLong( details->hwnd, GWL_STYLE );
92 WINDOWPOS *wp = ( WINDOWPOS * ) details->lParam;
93 RECT rect;
94
95 switch ( details->message ) {
96
97 case WM_WINDOWPOSCHANGED:
98 if ( dwStyle & WS_CHILD)
99 break;
100
101
102 if ( wp->flags & SWP_SHOWWINDOW ) {
103 // FIXME: Now, just like create!
104 SendDebug("SWP_SHOWWINDOW for %p!", details->hwnd);
105
106 snprintf( result, sizeof( result ),
107 "CREATE1,0x%p,0x%x\n",
108 details->hwnd, 0 );
109 result[ sizeof( result ) - 1 ] = '\0';
110 WriteToChannel( result );
111
112 // FIXME: SETSTATE
113
114 if ( !GetWindowRect( details->hwnd, &rect ) ) {
115 SendDebug( "GetWindowRect failed!\n" );
116 break;
117 }
118 snprintf( result, sizeof( result ),
119 "POSITION1,0x%p,%d,%d,%d,%d,0x%x\n",
120 details->hwnd,
121 rect.left, rect.top,
122 rect.right - rect.left,
123 rect.bottom - rect.top,
124 0 );
125 result[ sizeof( result ) - 1 ] = '\0';
126 WriteToChannel( result );
127
128 }
129
130
131 if ( wp->flags & SWP_HIDEWINDOW ) {
132 snprintf( result, sizeof( result ),
133 "DESTROY1,0x%p,0x%x\n",
134 details->hwnd, 0 );
135 result[ sizeof( result ) - 1 ] = '\0';
136 WriteToChannel( result );
137
138 }
139
140
141 if ( !( dwStyle & WS_VISIBLE ) )
142 break;
143
144 if ( wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE )
145 break;
146
147 if ( !GetWindowRect( details->hwnd, &rect ) ) {
148 SendDebug( "GetWindowRect failed!\n" );
149 break;
150 }
151
152 snprintf( result, sizeof( result ),
153 "POSITION1,0x%p,%d,%d,%d,%d,0x%x\n",
154 details->hwnd,
155 rect.left, rect.top,
156 rect.right - rect.left,
157 rect.bottom - rect.top,
158 0 );
159 result[ sizeof( result ) - 1 ] = '\0';
160 WriteToChannel( result );
161
162 break;
163
164
165 /* Note: WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED are
166 strange. Sometimes, for example when bringing up the
167 Notepad About dialog, only an WM_WINDOWPOSCHANGING is
168 sent. In some other cases, for exmaple when opening
169 Format->Text in Notepad, both events are sent. Also, for
170 some reason, when closing the Notepad About dialog, an
171 WM_WINDOWPOSCHANGING event is sent which looks just like
172 the event that was sent when the About dialog was opened... */
173 case WM_WINDOWPOSCHANGING:
174 if ( dwStyle & WS_CHILD)
175 break;
176
177 if ( !( dwStyle & WS_VISIBLE ) )
178 break;
179
180 if ( !( wp->flags & SWP_NOZORDER ) ) {
181 snprintf( result, sizeof( result ),
182 "ZCHANGE1,0x%p,0x%p,0x%x\n",
183 details->hwnd,
184 wp->flags & SWP_NOACTIVATE ? wp->hwndInsertAfter : 0,
185 0 );
186 result[ sizeof( result ) - 1 ] = '\0';
187 WriteToChannel( result );
188 }
189 break;
190
191
192
193
194 case WM_DESTROY:
195 if ( dwStyle & WS_CHILD)
196 break;
197
198 snprintf( result, sizeof( result ),
199 "DESTROY1,0x%p,0x%x\n",
200 details->hwnd, 0 );
201 result[ sizeof( result ) - 1 ] = '\0';
202 WriteToChannel( result );
203
204 break;
205
206
207 default:
208 break;
209 }
210
211 return CallNextHookEx( hWndProc, nCode, wParam, lParam );
212 }
213
214 LRESULT CALLBACK CbtProc( int nCode, WPARAM wParam, LPARAM lParam )
215 {
216 if ( nCode < 0 ) {
217 return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
218 }
219
220 char windowTitle[ 150 ] = { ""
221 };
222 HWND windowHandle = NULL;
223 char result[ 255 ] = { ""
224 };
225 switch ( nCode ) {
226 case HCBT_MINMAX:
227
228 if ( ( LOWORD( lParam ) == SW_SHOWMINIMIZED )
229 || ( LOWORD( lParam ) == SW_MINIMIZE ) ) {
230 MessageBox( 0, "Minimizing windows is not allowed in this version. Sorry!", "SeamlessRDP", MB_OK );
231 return 1;
232 }
233
234 GetWindowText( ( HWND ) wParam, windowTitle, 150 );
235
236 snprintf( result, sizeof( result ),
237 "SETSTATE1,0x%p,%s,0x%x,0x%x\n",
238 ( HWND ) wParam,
239 windowTitle,
240 LOWORD( lParam ),
241 0 );
242 result[ sizeof( result ) - 1 ] = '\0';
243 WriteToChannel( result );
244 break;
245
246
247 default:
248 break;
249 }
250
251
252
253 return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
254 }
255
256
257 LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
258 {
259 if ( nCode < 0 ) {
260 return CallNextHookEx( hShellProc, nCode, wParam, lParam );
261 }
262
263 char windowTitle[ 150 ] = { ""
264 };
265 HWND windowHandle = NULL;
266 char result[ 255 ] = { ""
267 };
268 char strWindowId[ 25 ];
269 LONG b, t, l, r;
270 char strW[ 5 ];
271 char strY[ 5 ];
272 char strX[ 5 ];
273 char strH[ 5 ];
274 RECT rect;
275
276 switch ( nCode ) {
277 case HSHELL_WINDOWCREATED:
278
279 //get window id
280 windowHandle = ( HWND ) wParam;
281 itoa( ( int ) windowHandle, strWindowId, 10 );
282
283 //get coords
284 GetWindowRect( windowHandle, &rect );
285 b = rect.bottom;
286 t = rect.top;
287 l = rect.left;
288 r = rect.right;
289 ltoa( b - t, strH, 10 );
290 ltoa( t, strY, 10 );
291 ltoa( r - l, strW, 10 );
292 ltoa( l, strX, 10 );
293
294 //get name
295 GetWindowText( windowHandle, windowTitle, 150 );
296
297 ////setup return string
298 strcat( result, "MSG=HSHELL_WINDOWCREATED;OP=0;" );
299 strcat( result, "ID=" );
300 strcat( result, strWindowId );
301 strcat( result, ";" );
302 strcat( result, "TITLE=" );
303 strcat( result, windowTitle );
304 strcat( result, ";" );
305 strcat( result, "X=" );
306 strcat( result, strX );
307 strcat( result, ";" );
308 strcat( result, "Y=" );
309 strcat( result, strY );
310 strcat( result, ";" );
311 strcat( result, "H=" );
312 strcat( result, strH );
313 strcat( result, ";" );
314 strcat( result, "W=" );
315 strcat( result, strW );
316 strcat( result, "." );
317 WriteToChannel( result );
318 break;
319
320 case HSHELL_WINDOWDESTROYED:
321
322 //get window id
323 windowHandle = ( HWND ) wParam;
324 itoa( ( int ) windowHandle, strWindowId, 10 );
325
326 //get coords
327 GetWindowRect( windowHandle, &rect );
328 b = rect.bottom;
329 t = rect.top;
330 l = rect.left;
331 r = rect.right;
332 ltoa( b - t, strH, 10 );
333 ltoa( t, strY, 10 );
334 ltoa( r - l, strW, 10 );
335 ltoa( l, strX, 10 );
336
337 //get name
338 GetWindowText( windowHandle, windowTitle, 150 );
339
340 ////setup return string
341 strcat( result, "MSG=HSHELL_WINDOWDESTROYED;OP=1;" );
342 strcat( result, "ID=" );
343 strcat( result, strWindowId );
344 strcat( result, ";" );
345 strcat( result, "TITLE=" );
346 strcat( result, windowTitle );
347 strcat( result, ";" );
348 strcat( result, "X=" );
349 strcat( result, strX );
350 strcat( result, ";" );
351 strcat( result, "Y=" );
352 strcat( result, strY );
353 strcat( result, ";" );
354 strcat( result, "H=" );
355 strcat( result, strH );
356 strcat( result, ";" );
357 strcat( result, "W=" );
358 strcat( result, strW );
359 strcat( result, "." );
360 WriteToChannel( result );
361 break;
362
363
364 default:
365 break;
366 }
367
368
369 return CallNextHookEx( hShellProc, nCode, wParam, lParam );
370 }
371
372 DLL_EXPORT void SetHooks( void )
373 {
374 if ( !hCbtProc ) {
375 hCbtProc = SetWindowsHookEx( WH_CBT, ( HOOKPROC ) CbtProc, hInst, ( DWORD ) NULL );
376 }
377
378 #if 0
379 if ( !hShellProc ) {
380 hShellProc = SetWindowsHookEx( WH_SHELL, ( HOOKPROC ) ShellProc, hInst, ( DWORD ) NULL );
381 }
382 #endif
383
384 if ( !hWndProc ) {
385 hWndProc = SetWindowsHookEx( WH_CALLWNDPROC, ( HOOKPROC ) CallWndProc, hInst, ( DWORD ) NULL );
386 }
387 }
388
389 DLL_EXPORT void RemoveHooks( void )
390 {
391 if ( hCbtProc ) {
392 UnhookWindowsHookEx( hCbtProc );
393 }
394
395 if ( hShellProc ) {
396 UnhookWindowsHookEx( hShellProc );
397 }
398
399 if ( hWndProc ) {
400 UnhookWindowsHookEx( hWndProc );
401 }
402 }
403
404 DLL_EXPORT int GetInstanceCount()
405 {
406 return iInstanceCount;
407 }
408
409 int OpenVirtualChannel()
410 {
411 m_vcHandle = WTSVirtualChannelOpen( WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, CHANNELNAME );
412
413 if ( m_vcHandle == NULL ) {
414 return 0;
415 } else {
416 return 1;
417 }
418 }
419
420 int CloseVirtualChannel()
421 {
422 BOOL result = WTSVirtualChannelClose( m_vcHandle );
423
424 m_vcHandle = NULL;
425
426 if ( result ) {
427 return 1;
428 } else {
429 return 0;
430 }
431 }
432
433 int ChannelIsOpen()
434 {
435 if ( m_vcHandle == NULL ) {
436 return 0;
437 } else {
438 return 1;
439 }
440 }
441
442 int WriteToChannel( PCHAR buffer )
443 {
444 PULONG bytesRead = 0;
445 PULONG pBytesWritten = 0;
446
447 if ( !ChannelIsOpen() )
448 return 1;
449
450 BOOL result = WTSVirtualChannelWrite( m_vcHandle, buffer, ( ULONG ) strlen( buffer ), pBytesWritten );
451
452 if ( result ) {
453 return 1;
454 } else {
455 return 0;
456 }
457 }

  ViewVC Help
Powered by ViewVC 1.1.26