/[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 1014 - (show annotations)
Tue Sep 13 13:08:16 2005 UTC (18 years, 8 months ago) by astrand
File size: 11597 byte(s)
Reporting size/position changes in response to WM_WINDOWPOSCHANGED,
instead of WM_SIZING/WM_MOVING. This is more reliable.

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

  ViewVC Help
Powered by ViewVC 1.1.26