/[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

Annotation of /sourceforge.net/trunk/seamlessrdp/ServerExe/HookDll/hookdll.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1064 - (hide annotations)
Wed Mar 8 15:52:38 2006 UTC (18 years, 3 months ago) by ossman_
File size: 11361 byte(s)
Change strategy to catch WM_WINDOWPOSCHANGED instead as that seems to work
better.

1 astrand 930 //
2 astrand 938 // Copyright (C) 2004-2005 Martin Wickett
3 astrand 930 //
4    
5     #include "hookdll.h"
6     #include <windows.h>
7     #include <winuser.h>
8 astrand 995 #include <stdio.h>
9 astrand 998 #include <stdarg.h>
10 astrand 930
11     #include "wtsapi32.h"
12 astrand 1061 #include "cchannel.h"
13 astrand 930
14 astrand 993 #define DLL_EXPORT extern "C" __declspec(dllexport)
15 astrand 930
16     // Shared DATA
17     #pragma data_seg ( "SHAREDDATA" )
18    
19 astrand 937 // this is the total number of processes this dll is currently attached to
20 astrand 933 int iInstanceCount = 0;
21     HWND hWnd = 0;
22 astrand 930
23     #pragma data_seg ()
24    
25     #pragma comment(linker, "/section:SHAREDDATA,rws")
26    
27 astrand 998 #define snprintf _snprintf
28    
29 astrand 1009 HHOOK hCbtProc = 0;
30 astrand 1008 HHOOK hShellProc = 0;
31     HHOOK hWndProc = 0;
32 astrand 933 HINSTANCE hInst = 0;
33     HANDLE m_vcHandle = 0;
34 astrand 930
35 astrand 998
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 astrand 1004 WriteToChannel( "DEBUG1," );
46     WriteToChannel( buf );
47     WriteToChannel( "\n" );
48 astrand 998 }
49    
50    
51    
52 astrand 1062 extern "C" BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved )
53 astrand 930 {
54 astrand 993 switch ( ul_reason_for_call ) {
55     case DLL_PROCESS_ATTACH: {
56 astrand 933 // remember our instance handle
57     hInst = hinstDLL;
58     ++iInstanceCount;
59     OpenVirtualChannel();
60     break;
61     }
62 astrand 993
63     case DLL_THREAD_ATTACH:
64 astrand 933 break;
65 astrand 993 case DLL_THREAD_DETACH:
66 astrand 933 break;
67 astrand 993 case DLL_PROCESS_DETACH: {
68 astrand 933 --iInstanceCount;
69     CloseVirtualChannel();
70     }
71     break;
72 astrand 930 }
73 astrand 993
74 astrand 930 return TRUE;
75     }
76    
77 astrand 993 LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
78 astrand 930 {
79 astrand 993 if ( nCode < 0 ) {
80 astrand 1008 return CallNextHookEx( hWndProc, nCode, wParam, lParam );
81 astrand 933 }
82 astrand 993
83     char windowTitle[ 150 ] = { ""
84     };
85 astrand 933 HWND windowHandle = NULL;
86 astrand 994 HWND windowHandle2 = NULL;
87 astrand 993 char result[ 255 ] = { ""
88     };
89     CWPSTRUCT *details = ( CWPSTRUCT * ) lParam;
90 astrand 995 CREATESTRUCT *cs = ( CREATESTRUCT * ) details->lParam;
91     LONG dwStyle = GetWindowLong( details->hwnd, GWL_STYLE );
92 astrand 998 WINDOWPOS *wp = ( WINDOWPOS * ) details->lParam;
93 astrand 1014 RECT rect;
94 astrand 993
95     switch ( details->message ) {
96 astrand 998
97 astrand 1014 case WM_WINDOWPOSCHANGED:
98 ossman_ 1064 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 astrand 1000
144 astrand 1014 if ( wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE )
145 astrand 1000 break;
146    
147 astrand 1014 if ( !GetWindowRect( details->hwnd, &rect ) ) {
148     SendDebug( "GetWindowRect failed!\n" );
149     break;
150     }
151    
152 astrand 998 snprintf( result, sizeof( result ),
153 astrand 1009 "POSITION1,0x%p,%d,%d,%d,%d,0x%x\n",
154 astrand 1002 details->hwnd,
155 astrand 1014 rect.left, rect.top,
156     rect.right - rect.left,
157     rect.bottom - rect.top,
158 astrand 998 0 );
159     result[ sizeof( result ) - 1 ] = '\0';
160 astrand 1005 WriteToChannel( result );
161 astrand 1014
162 astrand 933 break;
163 astrand 993
164 astrand 1000
165 astrand 998 /* 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 ossman_ 1064 if ( dwStyle & WS_CHILD)
175     break;
176    
177     if ( !( dwStyle & WS_VISIBLE ) )
178     break;
179 astrand 998
180     if ( !( wp->flags & SWP_NOZORDER ) ) {
181     snprintf( result, sizeof( result ),
182 astrand 1002 "ZCHANGE1,0x%p,0x%p,0x%x\n",
183 astrand 998 details->hwnd,
184     wp->flags & SWP_NOACTIVATE ? wp->hwndInsertAfter : 0,
185     0 );
186     result[ sizeof( result ) - 1 ] = '\0';
187 astrand 1005 WriteToChannel( result );
188 astrand 998 }
189 astrand 994 break;
190    
191 ossman_ 1064
192    
193 astrand 995
194     case WM_DESTROY:
195 ossman_ 1064 if ( dwStyle & WS_CHILD)
196     break;
197    
198 astrand 1001 snprintf( result, sizeof( result ),
199 astrand 1002 "DESTROY1,0x%p,0x%x\n",
200 astrand 1001 details->hwnd, 0 );
201 astrand 1005 result[ sizeof( result ) - 1 ] = '\0';
202     WriteToChannel( result );
203 astrand 995
204     break;
205 ossman_ 1064
206    
207 astrand 993 default:
208 astrand 933 break;
209     }
210 astrand 993
211 astrand 1008 return CallNextHookEx( hWndProc, nCode, wParam, lParam );
212 astrand 930 }
213    
214 astrand 993 LRESULT CALLBACK CbtProc( int nCode, WPARAM wParam, LPARAM lParam )
215 astrand 930 {
216 astrand 993 if ( nCode < 0 ) {
217 astrand 1008 return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
218 astrand 933 }
219 astrand 993
220     char windowTitle[ 150 ] = { ""
221     };
222 astrand 933 HWND windowHandle = NULL;
223 astrand 993 char result[ 255 ] = { ""
224     };
225     switch ( nCode ) {
226     case HCBT_MINMAX:
227    
228 astrand 1002 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 astrand 993
234 astrand 1002 GetWindowText( ( HWND ) wParam, windowTitle, 150 );
235 astrand 993
236 astrand 1002 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 astrand 1005 result[ sizeof( result ) - 1 ] = '\0';
243     WriteToChannel( result );
244 astrand 933 break;
245 astrand 993
246 astrand 1002
247 astrand 993 default:
248 astrand 933 break;
249     }
250 astrand 993
251    
252 astrand 1005
253 astrand 1008 return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
254 astrand 930 }
255    
256    
257 astrand 993 LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
258 astrand 930 {
259 astrand 993 if ( nCode < 0 ) {
260 astrand 1008 return CallNextHookEx( hShellProc, nCode, wParam, lParam );
261 astrand 933 }
262 astrand 993
263 astrand 1004 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 astrand 993
279 astrand 1004 //get window id
280     windowHandle = ( HWND ) wParam;
281     itoa( ( int ) windowHandle, strWindowId, 10 );
282 astrand 993
283 astrand 1004 //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 astrand 1005 WriteToChannel( result );
318 astrand 1004 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 astrand 1005 WriteToChannel( result );
361     break;
362 astrand 1004
363 astrand 1005
364 astrand 1004 default:
365     break;
366 astrand 933 }
367 astrand 993
368 astrand 1004
369 astrand 1008 return CallNextHookEx( hShellProc, nCode, wParam, lParam );
370 astrand 930 }
371    
372 astrand 1007 DLL_EXPORT void SetHooks( void )
373 astrand 930 {
374 astrand 1008 if ( !hCbtProc ) {
375     hCbtProc = SetWindowsHookEx( WH_CBT, ( HOOKPROC ) CbtProc, hInst, ( DWORD ) NULL );
376 astrand 933 }
377 astrand 993
378 astrand 1007 #if 0
379 astrand 1008 if ( !hShellProc ) {
380     hShellProc = SetWindowsHookEx( WH_SHELL, ( HOOKPROC ) ShellProc, hInst, ( DWORD ) NULL );
381 astrand 933 }
382 astrand 1007 #endif
383 astrand 993
384 astrand 1008 if ( !hWndProc ) {
385     hWndProc = SetWindowsHookEx( WH_CALLWNDPROC, ( HOOKPROC ) CallWndProc, hInst, ( DWORD ) NULL );
386 astrand 933 }
387 astrand 930 }
388    
389 astrand 1007 DLL_EXPORT void RemoveHooks( void )
390 astrand 930 {
391 astrand 1008 if ( hCbtProc ) {
392     UnhookWindowsHookEx( hCbtProc );
393 astrand 933 }
394 astrand 993
395 astrand 1008 if ( hShellProc ) {
396     UnhookWindowsHookEx( hShellProc );
397 astrand 933 }
398 astrand 993
399 astrand 1008 if ( hWndProc ) {
400     UnhookWindowsHookEx( hWndProc );
401 astrand 933 }
402 astrand 930 }
403    
404     DLL_EXPORT int GetInstanceCount()
405     {
406 astrand 933 return iInstanceCount;
407 astrand 930 }
408    
409     int OpenVirtualChannel()
410     {
411 astrand 994 m_vcHandle = WTSVirtualChannelOpen( WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, CHANNELNAME );
412    
413 astrand 993 if ( m_vcHandle == NULL ) {
414 astrand 933 return 0;
415 astrand 937 } else {
416 astrand 933 return 1;
417     }
418 astrand 930 }
419    
420     int CloseVirtualChannel()
421     {
422 astrand 993 BOOL result = WTSVirtualChannelClose( m_vcHandle );
423    
424 astrand 933 m_vcHandle = NULL;
425 astrand 993
426     if ( result ) {
427 astrand 933 return 1;
428 astrand 937 } else {
429 astrand 933 return 0;
430     }
431 astrand 930 }
432    
433     int ChannelIsOpen()
434     {
435 astrand 993 if ( m_vcHandle == NULL ) {
436 astrand 933 return 0;
437 astrand 937 } else {
438 astrand 933 return 1;
439     }
440 astrand 930 }
441    
442 astrand 993 int WriteToChannel( PCHAR buffer )
443 astrand 930 {
444 astrand 933 PULONG bytesRead = 0;
445     PULONG pBytesWritten = 0;
446 astrand 993
447 astrand 1004 if ( !ChannelIsOpen() )
448     return 1;
449    
450 astrand 994 BOOL result = WTSVirtualChannelWrite( m_vcHandle, buffer, ( ULONG ) strlen( buffer ), pBytesWritten );
451    
452 astrand 993 if ( result ) {
453 astrand 933 return 1;
454 astrand 937 } else {
455 astrand 933 return 0;
456     }
457 astrand 930 }

  ViewVC Help
Powered by ViewVC 1.1.26