/[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 1067 - (show annotations)
Wed Mar 8 17:14:42 2006 UTC (18 years, 3 months ago) by ossman_
File size: 11179 byte(s)
Make WriteToChannel() a variable argument function. Cleans up the code a lot.
Also add a newline implicitly in the function. It is unsupported to call it
multiple times for one line anyway (because of locking).

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 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 extern "C" 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 if ( nCode < 0 ) {
96 return CallNextHookEx( hWndProc, nCode, wParam, lParam );
97 }
98
99 char windowTitle[ 150 ] = { ""
100 };
101 HWND windowHandle = NULL;
102 HWND windowHandle2 = NULL;
103 char result[ 255 ] = { ""
104 };
105 CWPSTRUCT *details = ( CWPSTRUCT * ) lParam;
106 CREATESTRUCT *cs = ( CREATESTRUCT * ) details->lParam;
107 LONG dwStyle = GetWindowLong( details->hwnd, GWL_STYLE );
108 WINDOWPOS *wp = ( WINDOWPOS * ) details->lParam;
109 RECT rect;
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 if ( nCode < 0 ) {
208 return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
209 }
210
211 char windowTitle[ 150 ] = { ""
212 };
213 HWND windowHandle = NULL;
214 char result[ 255 ] = { ""
215 };
216 switch ( nCode ) {
217 case HCBT_MINMAX:
218
219 if ( ( LOWORD( lParam ) == SW_SHOWMINIMIZED )
220 || ( LOWORD( lParam ) == SW_MINIMIZE ) ) {
221 MessageBox( 0, "Minimizing windows is not allowed in this version. Sorry!", "SeamlessRDP", MB_OK );
222 return 1;
223 }
224
225 GetWindowText( ( HWND ) wParam, windowTitle, 150 );
226
227 WriteToChannel( "SETSTATE1,0x%p,%s,0x%x,0x%x",
228 ( HWND ) wParam,
229 windowTitle,
230 LOWORD( lParam ),
231 0 );
232 break;
233
234
235 default:
236 break;
237 }
238
239
240
241 return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
242 }
243
244
245 LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
246 {
247 if ( nCode < 0 ) {
248 return CallNextHookEx( hShellProc, nCode, wParam, lParam );
249 }
250
251 char windowTitle[ 150 ] = { ""
252 };
253 HWND windowHandle = NULL;
254 char result[ 255 ] = { ""
255 };
256 char strWindowId[ 25 ];
257 LONG b, t, l, r;
258 char strW[ 5 ];
259 char strY[ 5 ];
260 char strX[ 5 ];
261 char strH[ 5 ];
262 RECT rect;
263
264 switch ( nCode ) {
265 case HSHELL_WINDOWCREATED:
266
267 //get window id
268 windowHandle = ( HWND ) wParam;
269 itoa( ( int ) windowHandle, strWindowId, 10 );
270
271 //get coords
272 GetWindowRect( windowHandle, &rect );
273 b = rect.bottom;
274 t = rect.top;
275 l = rect.left;
276 r = rect.right;
277 ltoa( b - t, strH, 10 );
278 ltoa( t, strY, 10 );
279 ltoa( r - l, strW, 10 );
280 ltoa( l, strX, 10 );
281
282 //get name
283 GetWindowText( windowHandle, windowTitle, 150 );
284
285 ////setup return string
286 strcat( result, "MSG=HSHELL_WINDOWCREATED;OP=0;" );
287 strcat( result, "ID=" );
288 strcat( result, strWindowId );
289 strcat( result, ";" );
290 strcat( result, "TITLE=" );
291 strcat( result, windowTitle );
292 strcat( result, ";" );
293 strcat( result, "X=" );
294 strcat( result, strX );
295 strcat( result, ";" );
296 strcat( result, "Y=" );
297 strcat( result, strY );
298 strcat( result, ";" );
299 strcat( result, "H=" );
300 strcat( result, strH );
301 strcat( result, ";" );
302 strcat( result, "W=" );
303 strcat( result, strW );
304 strcat( result, "." );
305 WriteToChannel( result );
306 break;
307
308 case HSHELL_WINDOWDESTROYED:
309
310 //get window id
311 windowHandle = ( HWND ) wParam;
312 itoa( ( int ) windowHandle, strWindowId, 10 );
313
314 //get coords
315 GetWindowRect( windowHandle, &rect );
316 b = rect.bottom;
317 t = rect.top;
318 l = rect.left;
319 r = rect.right;
320 ltoa( b - t, strH, 10 );
321 ltoa( t, strY, 10 );
322 ltoa( r - l, strW, 10 );
323 ltoa( l, strX, 10 );
324
325 //get name
326 GetWindowText( windowHandle, windowTitle, 150 );
327
328 ////setup return string
329 strcat( result, "MSG=HSHELL_WINDOWDESTROYED;OP=1;" );
330 strcat( result, "ID=" );
331 strcat( result, strWindowId );
332 strcat( result, ";" );
333 strcat( result, "TITLE=" );
334 strcat( result, windowTitle );
335 strcat( result, ";" );
336 strcat( result, "X=" );
337 strcat( result, strX );
338 strcat( result, ";" );
339 strcat( result, "Y=" );
340 strcat( result, strY );
341 strcat( result, ";" );
342 strcat( result, "H=" );
343 strcat( result, strH );
344 strcat( result, ";" );
345 strcat( result, "W=" );
346 strcat( result, strW );
347 strcat( result, "." );
348 WriteToChannel( result );
349 break;
350
351
352 default:
353 break;
354 }
355
356
357 return CallNextHookEx( hShellProc, nCode, wParam, lParam );
358 }
359
360 DLL_EXPORT void SetHooks( void )
361 {
362 if ( !hCbtProc ) {
363 hCbtProc = SetWindowsHookEx( WH_CBT, ( HOOKPROC ) CbtProc, hInst, ( DWORD ) NULL );
364 }
365
366 #if 0
367 if ( !hShellProc ) {
368 hShellProc = SetWindowsHookEx( WH_SHELL, ( HOOKPROC ) ShellProc, hInst, ( DWORD ) NULL );
369 }
370 #endif
371
372 if ( !hWndProc ) {
373 hWndProc = SetWindowsHookEx( WH_CALLWNDPROC, ( HOOKPROC ) CallWndProc, hInst, ( DWORD ) NULL );
374 }
375 }
376
377 DLL_EXPORT void RemoveHooks( void )
378 {
379 if ( hCbtProc ) {
380 UnhookWindowsHookEx( hCbtProc );
381 }
382
383 if ( hShellProc ) {
384 UnhookWindowsHookEx( hShellProc );
385 }
386
387 if ( hWndProc ) {
388 UnhookWindowsHookEx( hWndProc );
389 }
390 }
391
392 DLL_EXPORT int GetInstanceCount()
393 {
394 return iInstanceCount;
395 }
396
397 int OpenVirtualChannel()
398 {
399 m_vcHandle = WTSVirtualChannelOpen( WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, CHANNELNAME );
400
401 if ( m_vcHandle == NULL ) {
402 return 0;
403 } else {
404 return 1;
405 }
406 }
407
408 int CloseVirtualChannel()
409 {
410 BOOL result = WTSVirtualChannelClose( m_vcHandle );
411
412 m_vcHandle = NULL;
413
414 if ( result ) {
415 return 1;
416 } else {
417 return 0;
418 }
419 }
420
421 int ChannelIsOpen()
422 {
423 if ( m_vcHandle == NULL ) {
424 return 0;
425 } else {
426 return 1;
427 }
428 }
429
430 int WriteToChannel( char *format, ... )
431 {
432 BOOL result;
433 va_list argp;
434 char buf [ 1024 ];
435 int size;
436 PULONG bytesRead = 0;
437 PULONG pBytesWritten = 0;
438
439 if ( !ChannelIsOpen() )
440 return 1;
441
442 va_start( argp, format );
443 size = vsnprintf( buf, sizeof( buf ), format, argp );
444 va_end( argp );
445
446 if ( size >= sizeof( buf ) )
447 return 0;
448
449 WaitForSingleObject( hMutex, INFINITE );
450 result = WTSVirtualChannelWrite( m_vcHandle, buf, ( ULONG ) strlen( buf ), pBytesWritten );
451 result = WTSVirtualChannelWrite( m_vcHandle, "\n", ( ULONG ) 1, pBytesWritten );
452 ReleaseMutex( hMutex );
453
454 if ( result ) {
455 return 1;
456 } else {
457 return 0;
458 }
459 }

  ViewVC Help
Powered by ViewVC 1.1.26