/[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 998 - (show annotations)
Tue Aug 30 09:15:44 2005 UTC (18 years, 9 months ago) by astrand
File size: 15985 byte(s)
Added a function for sending debug printouts to the other end.

Re-implemented the code on WM_SIZING/WM_MOVING: Now generating
messages according to the new protocol.

Do not catch WM_WINDOWPOSCHANGED; WM_WINDOWPOSCHANGING is enough. In
response, generate a ZCHANGE1 messages according to the new protocol.

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 bool bHooked = false;
30 bool bHooked2 = false;
31 bool bHooked3 = false;
32 HHOOK hhook = 0; //cbt
33 HHOOK hhook2 = 0; //shell
34 HHOOK hhook3 = 0; //wnd proc
35 HINSTANCE hInst = 0;
36 HANDLE m_vcHandle = 0;
37
38
39 void SendDebug( char *format, ... )
40 {
41 va_list argp;
42 char buf [ 256 ];
43
44 va_start( argp, format );
45 vsprintf( buf, format, argp );
46 va_end( argp );
47
48 if ( ChannelIsOpen() ) {
49 WriteToChannel( "DEBUG1," );
50 WriteToChannel( buf );
51 WriteToChannel( "\n" );
52 }
53 }
54
55
56
57 BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved )
58 {
59 switch ( ul_reason_for_call ) {
60 case DLL_PROCESS_ATTACH: {
61 // remember our instance handle
62 hInst = hinstDLL;
63 ++iInstanceCount;
64 OpenVirtualChannel();
65 break;
66 }
67
68 case DLL_THREAD_ATTACH:
69 break;
70 case DLL_THREAD_DETACH:
71 break;
72 case DLL_PROCESS_DETACH: {
73 --iInstanceCount;
74 CloseVirtualChannel();
75 }
76 break;
77 }
78
79 return TRUE;
80 }
81
82 LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
83 {
84 if ( nCode < 0 ) {
85 return CallNextHookEx( hhook3, nCode, wParam, lParam );
86 }
87
88 PCHAR buffer = NULL;
89 char windowTitle[ 150 ] = { ""
90 };
91 HWND windowHandle = NULL;
92 HWND windowHandle2 = NULL;
93 char result[ 255 ] = { ""
94 };
95 char strWindowId[ 25 ];
96 char type[ 25 ];
97
98 LONG b, t, l, r;
99 char strX[ 5 ];
100 char strY[ 5 ];
101 char strW[ 5 ];
102 char strH[ 5 ];
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 = ( RECT * ) details->lParam;
109
110 switch ( details->message ) {
111
112 case WM_SIZING:
113 case WM_MOVING:
114 snprintf( result, sizeof( result ),
115 "POSITION1,0x%x,%d,%d,%d,%d,0x%x",
116 ( int ) details->hwnd,
117 rect->left, rect->top,
118 rect->right - rect->left,
119 rect->bottom - rect->top,
120 0 );
121 result[ sizeof( result ) - 1 ] = '\0';
122 buffer = result;
123
124 break;
125
126 /* Note: WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED are
127 strange. Sometimes, for example when bringing up the
128 Notepad About dialog, only an WM_WINDOWPOSCHANGING is
129 sent. In some other cases, for exmaple when opening
130 Format->Text in Notepad, both events are sent. Also, for
131 some reason, when closing the Notepad About dialog, an
132 WM_WINDOWPOSCHANGING event is sent which looks just like
133 the event that was sent when the About dialog was opened... */
134 case WM_WINDOWPOSCHANGING:
135
136 if ( !( dwStyle & WS_VISIBLE ) )
137 break;
138
139 if ( !( dwStyle & WS_DLGFRAME ) )
140 break;
141
142 if ( !( wp->flags & SWP_NOZORDER ) ) {
143 snprintf( result, sizeof( result ),
144 "ZCHANGE1,0x%x,0x%x,0x%x\n",
145 details->hwnd,
146 wp->flags & SWP_NOACTIVATE ? wp->hwndInsertAfter : 0,
147 0 );
148 result[ sizeof( result ) - 1 ] = '\0';
149 }
150 buffer = result;
151
152 break;
153
154
155 case WM_CREATE:
156 if ( cs->style & WS_DLGFRAME ) {
157 sprintf( result, "DEBUG:WM_CREATE:%dx%d at %d,%d, title=%s, menu=%p, window=%p, WS_BORDER=%d, WS_DLGFRAME=%d, WS_POPUP=%d",
158 cs->cx, cs->cy, cs->x, cs->y, cs->lpszName, cs->hMenu, details->hwnd,
159 cs->style & WS_BORDER, cs->style & WS_DLGFRAME,
160 cs->style & WS_POPUP );
161 buffer = result;
162 }
163
164 break;
165
166
167 case WM_DESTROY:
168 if ( dwStyle & WS_DLGFRAME ) {
169 sprintf( result, "WM_DESTROY:%p", details->hwnd );
170 buffer = result;
171 }
172
173 break;
174
175 default:
176 break;
177 }
178
179 if ( ChannelIsOpen() ) {
180 if ( buffer != NULL ) {
181 WriteToChannel( buffer );
182 }
183 }
184
185 return CallNextHookEx( hhook3, nCode, wParam, lParam );
186 }
187
188 LRESULT CALLBACK CbtProc( int nCode, WPARAM wParam, LPARAM lParam )
189 {
190 if ( nCode < 0 ) {
191 return CallNextHookEx( hhook, nCode, wParam, lParam );
192 }
193
194
195 PCHAR buffer = NULL;
196
197
198 char windowTitle[ 150 ] = { ""
199 };
200 HWND windowHandle = NULL;
201 char result[ 255 ] = { ""
202 };
203 char strWindowId[ 25 ];
204 char type[ 25 ];
205
206
207 LONG b, t, l, r;
208 char strW[ 5 ];
209 char strY[ 5 ];
210 char strX[ 5 ];
211 char strH[ 5 ];
212 RECT rect;
213
214 int i = 0; //tmp
215
216 switch ( nCode ) {
217 case HCBT_MINMAX:
218
219 windowHandle = ( HWND ) wParam;
220 //get win name
221 GetWindowText( windowHandle, windowTitle, 150 );
222
223 //get an id for it
224 itoa( ( int ) windowHandle, strWindowId, 10 );
225
226 //get operation type(min,max). if max, do not clip at all,if min use window's previous coords
227 //codes are:
228
229 // SW_HIDE= 0 SW_SHOWNORMAL=1 SW_NORMAL=1 SW_SHOWMINIMIZED=2 SW_SHOWMAXIMIZED=3 SW_MAXIMIZE=3
230 // SW_SHOWNOACTIVATE=4 SW_SHOW=5 SW_MINIMIZE=6 SW_SHOWMINNOACTIVE=7 SW_SHOWNA=8 SW_RESTORE=9
231 // SW_SHOWDEFAULT=10 SW_FORCEMINIMIZE=11 SW_MAX=11
232
233 itoa( ( int ) lParam, type, 10 );
234
235 //get coords
236 GetWindowRect( windowHandle, &rect );
237 b = rect.bottom;
238 t = rect.top;
239 l = rect.left;
240 r = rect.right;
241 ltoa( b - t, strW, 10 );
242 ltoa( t, strY, 10 );
243 ltoa( r - l, strH, 10 );
244 ltoa( l, strX, 10 );
245
246 //get name
247 GetWindowText( windowHandle, windowTitle, 150 );
248
249 ////setup return string
250 strcat( result, "MSG=HCBT_MINMAX;OP=4;" );
251
252 // SW_SHOWNOACTIVATE=4 SW_SHOW=5 SW_MINIMIZE=6 SW_SHOWMINNOACTIVE=7 SW_SHOWNA=8 SW_RESTORE=9
253 // SW_SHOWDEFAULT=10 SW_FORCEMINIMIZE=11 SW_MAX=11
254 strcat( result, "ID=" );
255 strcat( result, strWindowId );
256 strcat( result, ";" );
257 strcat( result, "TITLE=" );
258 strcat( result, windowTitle );
259 strcat( result, ";" );
260 strcat( result, "X=" );
261 strcat( result, strX );
262 strcat( result, ";" );
263 strcat( result, "Y=" );
264 strcat( result, strY );
265 strcat( result, ";" );
266 strcat( result, "H=" );
267 strcat( result, strH );
268 strcat( result, ";" );
269 strcat( result, "W=" );
270 strcat( result, strW );
271 strcat( result, ";" );
272 strcat( result, "TYPE=" );
273 strcat( result, type );
274 strcat( result, "." );
275
276 //-------------------------------------------------------------------------------------------------
277 // code to prevent minimising windows (can be removed once minimise has been implemented)
278 //i = (int)lParam;
279 //if (i==0 || i==2 || i==6 || i==7 || i==8 || i==11)
280 //if ( i==2 || i==6 )
281 //{
282 // MessageBox(0,"Minimising windows is not allowed in this version. Sorry!","TS Window Clipper", MB_OK);
283 // return 1;
284 //}
285 //-----------------------------------------------------------------------------------------
286
287 //-------------------------------------------------------------------------------------------------
288 // code to prevent maximising windows (can be removed once maximise has been implemented)
289 //i = (int)lParam;
290 //if (i==3 || i==9 || i==11)
291 //if (i==3 || i==11)
292 //{
293 // MessageBox(0,"Maximising windows is not allowed in this version. Sorry!","TS Window Clipper", MB_OK);
294 // return 1;
295 //}
296 //-----------------------------------------------------------------------------------------
297
298 buffer = result;
299
300 break;
301
302 case HCBT_MOVESIZE:
303
304 windowHandle = ( HWND ) wParam;
305 //get win name
306 GetWindowText( windowHandle, windowTitle, 150 );
307
308 //get an id for it
309 itoa( ( int ) windowHandle, strWindowId, 10 );
310
311 //get coords
312 GetWindowRect( windowHandle, &rect );
313 b = rect.bottom;
314 t = rect.top;
315 l = rect.left;
316 r = rect.right;
317 ltoa( b - t, strH, 10 );
318 ltoa( t, strY, 10 );
319 ltoa( r - l, strW, 10 );
320 ltoa( l, strX, 10 );
321
322 //get name
323 GetWindowText( windowHandle, windowTitle, 150 );
324
325 ////setup return string
326 strcat( result, "MSG=HCBT_MOVESIZE;OP=5;" );
327 strcat( result, "ID=" );
328 strcat( result, strWindowId );
329 strcat( result, ";" );
330 strcat( result, "TITLE=" );
331 strcat( result, windowTitle );
332 strcat( result, ";" );
333 strcat( result, "X=" );
334 strcat( result, strX );
335 strcat( result, ";" );
336 strcat( result, "Y=" );
337 strcat( result, strY );
338 strcat( result, ";" );
339 strcat( result, "H=" );
340 strcat( result, strH );
341 strcat( result, ";" );
342 strcat( result, "W=" );
343 strcat( result, strW );
344 strcat( result, "." );
345
346 buffer = result;
347
348 break;
349 case HCBT_SETFOCUS:
350 //buffer = "HCBT_SETFOCUS";
351 //not needed yet
352 break;
353 default:
354 break;
355 }
356
357 if ( ChannelIsOpen() ) {
358 if ( buffer != NULL ) {
359 WriteToChannel( buffer );
360 }
361 }
362
363 return CallNextHookEx( hhook, nCode, wParam, lParam );
364 }
365
366
367 LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
368 {
369 if ( nCode < 0 ) {
370 return CallNextHookEx( hhook, nCode, wParam, lParam );
371 }
372
373 if ( ChannelIsOpen() ) {
374 PCHAR buffer = NULL;
375
376 char windowTitle[ 150 ] = { ""
377 };
378 HWND windowHandle = NULL;
379 char result[ 255 ] = { ""
380 };
381 char strWindowId[ 25 ];
382 LONG b, t, l, r;
383 char strW[ 5 ];
384 char strY[ 5 ];
385 char strX[ 5 ];
386 char strH[ 5 ];
387 RECT rect;
388
389 switch ( nCode ) {
390 case HSHELL_WINDOWCREATED:
391
392 //get window id
393 windowHandle = ( HWND ) wParam;
394 itoa( ( int ) windowHandle, strWindowId, 10 );
395
396 //get coords
397 GetWindowRect( windowHandle, &rect );
398 b = rect.bottom;
399 t = rect.top;
400 l = rect.left;
401 r = rect.right;
402 ltoa( b - t, strH, 10 );
403 ltoa( t, strY, 10 );
404 ltoa( r - l, strW, 10 );
405 ltoa( l, strX, 10 );
406
407 //get name
408 GetWindowText( windowHandle, windowTitle, 150 );
409
410 ////setup return string
411 strcat( result, "MSG=HSHELL_WINDOWCREATED;OP=0;" );
412 strcat( result, "ID=" );
413 strcat( result, strWindowId );
414 strcat( result, ";" );
415 strcat( result, "TITLE=" );
416 strcat( result, windowTitle );
417 strcat( result, ";" );
418 strcat( result, "X=" );
419 strcat( result, strX );
420 strcat( result, ";" );
421 strcat( result, "Y=" );
422 strcat( result, strY );
423 strcat( result, ";" );
424 strcat( result, "H=" );
425 strcat( result, strH );
426 strcat( result, ";" );
427 strcat( result, "W=" );
428 strcat( result, strW );
429 strcat( result, "." );
430
431 buffer = result;
432
433 break;
434
435 case HSHELL_WINDOWDESTROYED:
436
437 //get window id
438 windowHandle = ( HWND ) wParam;
439 itoa( ( int ) windowHandle, strWindowId, 10 );
440
441 //get coords
442 GetWindowRect( windowHandle, &rect );
443 b = rect.bottom;
444 t = rect.top;
445 l = rect.left;
446 r = rect.right;
447 ltoa( b - t, strH, 10 );
448 ltoa( t, strY, 10 );
449 ltoa( r - l, strW, 10 );
450 ltoa( l, strX, 10 );
451
452 //get name
453 GetWindowText( windowHandle, windowTitle, 150 );
454
455 ////setup return string
456 strcat( result, "MSG=HSHELL_WINDOWDESTROYED;OP=1;" );
457 strcat( result, "ID=" );
458 strcat( result, strWindowId );
459 strcat( result, ";" );
460 strcat( result, "TITLE=" );
461 strcat( result, windowTitle );
462 strcat( result, ";" );
463 strcat( result, "X=" );
464 strcat( result, strX );
465 strcat( result, ";" );
466 strcat( result, "Y=" );
467 strcat( result, strY );
468 strcat( result, ";" );
469 strcat( result, "H=" );
470 strcat( result, strH );
471 strcat( result, ";" );
472 strcat( result, "W=" );
473 strcat( result, strW );
474 strcat( result, "." );
475
476 buffer = result;
477
478 break;
479 default:
480 break;
481 }
482
483 if ( buffer != NULL ) {
484 WriteToChannel( buffer );
485 }
486 }
487
488 return CallNextHookEx( hhook, nCode, wParam, lParam );
489 }
490
491 DLL_EXPORT void SetCbtHook( void )
492 {
493 if ( !bHooked ) {
494 hhook = SetWindowsHookEx( WH_CBT, ( HOOKPROC ) CbtProc, hInst, ( DWORD ) NULL );
495 bHooked = true;
496 }
497
498 if ( !bHooked2 ) {
499 hhook2 = SetWindowsHookEx( WH_SHELL, ( HOOKPROC ) ShellProc, hInst, ( DWORD ) NULL );
500 bHooked2 = true;
501 }
502
503 if ( !bHooked3 ) {
504 hhook3 = SetWindowsHookEx( WH_CALLWNDPROC, ( HOOKPROC ) CallWndProc, hInst, ( DWORD ) NULL );
505 bHooked3 = true;
506 }
507 }
508
509 DLL_EXPORT void RemoveCbtHook( void )
510 {
511 if ( bHooked ) {
512 UnhookWindowsHookEx( hhook );
513 bHooked = false;
514 }
515
516 if ( bHooked2 ) {
517 UnhookWindowsHookEx( hhook2 );
518 bHooked2 = false;
519 }
520
521 if ( bHooked3 ) {
522 UnhookWindowsHookEx( hhook3 );
523 bHooked3 = false;
524 }
525 }
526
527 DLL_EXPORT int GetInstanceCount()
528 {
529 return iInstanceCount;
530 }
531
532 int OpenVirtualChannel()
533 {
534 m_vcHandle = WTSVirtualChannelOpen( WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, CHANNELNAME );
535
536 if ( m_vcHandle == NULL ) {
537 return 0;
538 } else {
539 return 1;
540 }
541 }
542
543 int CloseVirtualChannel()
544 {
545 BOOL result = WTSVirtualChannelClose( m_vcHandle );
546
547 m_vcHandle = NULL;
548
549 if ( result ) {
550 return 1;
551 } else {
552 return 0;
553 }
554 }
555
556 int ChannelIsOpen()
557 {
558 if ( m_vcHandle == NULL ) {
559 return 0;
560 } else {
561 return 1;
562 }
563 }
564
565 int WriteToChannel( PCHAR buffer )
566 {
567 PULONG bytesRead = 0;
568 PULONG pBytesWritten = 0;
569
570 BOOL result = WTSVirtualChannelWrite( m_vcHandle, buffer, ( ULONG ) strlen( buffer ), pBytesWritten );
571
572 if ( result ) {
573 return 1;
574 } else {
575 return 0;
576 }
577 }

  ViewVC Help
Powered by ViewVC 1.1.26