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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1069 - (hide 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 ossman_ 1069 //
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