/[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 1066 - (show annotations)
Wed Mar 8 16:55:02 2006 UTC (18 years, 3 months ago) by ossman_
File size: 11706 byte(s)
Add a named mutex so that all hooks will write atomically into the virtual
channel.

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

  ViewVC Help
Powered by ViewVC 1.1.26