/[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 1069 - (show annotations)
Thu Mar 9 09:46:30 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 11154 byte(s)
Use C instead of C++ since we don't depend on any C++ features anyway.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26