CVS: seamlessrdp/ServerExe/HookDll hookdll.c,1.1,1.2 hookdll.h,1.10,1.11

Pierre Ossman <[email protected]>
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/seamlessrdp/ServerExe/HookDll
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20281/HookDll

Modified Files:
	hookdll.c hookdll.h 
Log Message:
Big cleanup and reindentation of the code.


Index: hookdll.c
===================================================================
RCS file: /cvsroot/rdesktop/seamlessrdp/ServerExe/HookDll/hookdll.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** hookdll.c	9 Mar 2006 09:46:30 -0000	1.1
--- hookdll.c	9 Mar 2006 12:00:15 -0000	1.2
***************
*** 1,14 ****
! //
! // Copyright (C) 2004-2005 Martin Wickett
! //
  
- #include "hookdll.h"
- #include <windows.h>
- #include <winuser.h>
  #include <stdio.h>
  #include <stdarg.h>
  
! #include "wtsapi32.h"
! #include "cchannel.h"
  
  #define DLL_EXPORT __declspec(dllexport)
--- 1,35 ----
! /* -*- c-basic-offset: 8 -*-
!    rdesktop: A Remote Desktop Protocol client.
!    Seamless windows - Remote server hook DLL
! 
!    Based on code copyright (C) 2004-2005 Martin Wickett
! 
!    Copyright (C) Peter Åstrand <[email protected]> 2005-2006
!    Copyright (C) Pierre Ossman <[email protected]> 2006
! 
!    This program is free software; you can redistribute it and/or modify
!    it under the terms of the GNU General Public License as published by
!    the Free Software Foundation; either version 2 of the License, or
!    (at your option) any later version.
! 
!    This program is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
! 
!    You should have received a copy of the GNU General Public License
!    along with this program; if not, write to the Free Software
!    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! */
  
  #include <stdio.h>
  #include <stdarg.h>
  
! #include <windows.h>
! #include <winuser.h>
! #include <wtsapi32.h>
! #include <cchannel.h>
! 
! #include "hookdll.h"
  
  #define DLL_EXPORT __declspec(dllexport)
***************
*** 18,23 ****
  
  // this is the total number of processes this dll is currently attached to
! int iInstanceCount = 0;
! HWND hWnd = 0;
  
  #pragma data_seg ()
--- 39,43 ----
  
  // this is the total number of processes this dll is currently attached to
! int g_instance_count = 0;
  
  #pragma data_seg ()
***************
*** 25,460 ****
  #pragma comment(linker, "/section:SHAREDDATA,rws")
  
! #define snprintf _snprintf
! 
! HHOOK hCbtProc = 0;
! HHOOK hShellProc = 0;
! HHOOK hWndProc = 0;
! HINSTANCE hInst = 0;
! HANDLE m_vcHandle = 0;
! HANDLE hMutex = 0;
! 
! void SendDebug( char *format, ... )
! {
!     va_list argp;
!     char buf [ 256 ];
! 
!     sprintf( buf, "DEBUG1," );
! 
!     va_start( argp, format );
!     _vsnprintf( buf + sizeof( "DEBUG1," ) - 1,
!                sizeof( buf ) - sizeof( "DEBUG1," ) + 1, format, argp );
!     va_end( argp );
  
!     WriteToChannel( buf );
! }
  
  
  
! BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved )
  {
!     switch ( ul_reason_for_call ) {
!     case DLL_PROCESS_ATTACH:
!         // remember our instance handle
!         hInst = hinstDLL;
! 
!         hMutex = CreateMutex( NULL, FALSE, "Local\\Seamless" );
!         if (!hMutex)
!             return FALSE;
! 
!         WaitForSingleObject( hMutex, INFINITE );
!         ++iInstanceCount;
!         ReleaseMutex( hMutex );
! 
!         OpenVirtualChannel();
! 
!         break;
! 
!     case DLL_THREAD_ATTACH:
!         break;
! 
!     case DLL_THREAD_DETACH:
!         break;
! 
!     case DLL_PROCESS_DETACH:
!         WaitForSingleObject( hMutex, INFINITE );
!         --iInstanceCount;
!         ReleaseMutex( hMutex );
! 
!         CloseVirtualChannel();
  
!         CloseHandle( hMutex );
  
!         break;
!     }
  
!     return TRUE;
  }
  
! LRESULT CALLBACK CallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
  {
!     char windowTitle[ 150 ] = { ""
!                               };
!     HWND windowHandle = NULL;
!     HWND windowHandle2 = NULL;
!     char result[ 255 ] = { ""
!                          };
!     CWPSTRUCT *details = ( CWPSTRUCT * ) lParam;
!     CREATESTRUCT *cs = ( CREATESTRUCT * ) details->lParam;
!     LONG dwStyle = GetWindowLong( details->hwnd, GWL_STYLE );
!     WINDOWPOS *wp = ( WINDOWPOS * ) details->lParam;
!     RECT rect;
  
!     if ( nCode < 0 ) {
!         return CallNextHookEx( hWndProc, nCode, wParam, lParam );
!     }
  
!     switch ( details->message ) {
  
!     case WM_WINDOWPOSCHANGED:
!         if ( dwStyle & WS_CHILD)
!             break;
  
  
-         if ( wp->flags & SWP_SHOWWINDOW ) {
-             // FIXME: Now, just like create!
-             SendDebug("SWP_SHOWWINDOW for %p!", details->hwnd);
-             WriteToChannel( "CREATE1,0x%p,0x%x", details->hwnd, 0 );
  
!             // FIXME: SETSTATE
  
!             if ( !GetWindowRect( details->hwnd, &rect ) ) {
!                 SendDebug( "GetWindowRect failed!\n" );
!                 break;
!             }
!             WriteToChannel( "POSITION1,0x%p,%d,%d,%d,%d,0x%x",
!                             details->hwnd,
!                             rect.left, rect.top,
!                             rect.right - rect.left,
!                             rect.bottom - rect.top,
!                             0 );
!         }
  
  
-         if ( wp->flags & SWP_HIDEWINDOW )
-             WriteToChannel( "DESTROY1,0x%p,0x%x", details->hwnd, 0 );
  
  
-         if ( !( dwStyle & WS_VISIBLE ) )
-             break;
  
!         if ( wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE )
!             break;
  
!         if ( !GetWindowRect( details->hwnd, &rect ) ) {
!             SendDebug( "GetWindowRect failed!\n" );
!             break;
!         }
  
!         WriteToChannel( "POSITION1,0x%p,%d,%d,%d,%d,0x%x",
!                         details->hwnd,
!                         rect.left, rect.top,
!                         rect.right - rect.left,
!                         rect.bottom - rect.top,
!                         0 );
  
!         break;
  
  
-         /* Note: WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED are
-         strange. Sometimes, for example when bringing up the
-         Notepad About dialog, only an WM_WINDOWPOSCHANGING is
-         sent. In some other cases, for exmaple when opening
-         Format->Text in Notepad, both events are sent. Also, for
-         some reason, when closing the Notepad About dialog, an
-         WM_WINDOWPOSCHANGING event is sent which looks just like
-         the event that was sent when the About dialog was opened...  */
-     case WM_WINDOWPOSCHANGING:
-         if ( dwStyle & WS_CHILD)
-             break;
  
!         if ( !( dwStyle & WS_VISIBLE ) )
!             break;
  
!         if ( !( wp->flags & SWP_NOZORDER ) )
!             WriteToChannel( "ZCHANGE1,0x%p,0x%p,0x%x",
!                             details->hwnd,
!                             wp->flags & SWP_NOACTIVATE ? wp->hwndInsertAfter : 0,
!                             0 );
  
!         break;
  
  
  
  
-     case WM_DESTROY:
-         if ( dwStyle & WS_CHILD)
-             break;
  
!         WriteToChannel( "DESTROY1,0x%p,0x%x", details->hwnd, 0 );
  
!         break;
  
  
-     default:
-         break;
-     }
  
!     return CallNextHookEx( hWndProc, nCode, wParam, lParam );
  }
  
! LRESULT CALLBACK CbtProc( int nCode, WPARAM wParam, LPARAM lParam )
  {
!     char windowTitle[ 150 ] = { ""
!                               };
!     HWND windowHandle = NULL;
!     char result[ 255 ] = { ""
!                          };
! 
! 	if ( nCode < 0 ) {
!         return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
!     }
  
! 	switch ( nCode ) {
!     case HCBT_MINMAX:
  
!         if ( ( LOWORD( lParam ) == SW_SHOWMINIMIZED )
!                 || ( LOWORD( lParam ) == SW_MINIMIZE ) ) {
!             MessageBox( 0, "Minimizing windows is not allowed in this version. Sorry!", "SeamlessRDP", MB_OK );
!             return 1;
!         }
  
!         GetWindowText( ( HWND ) wParam, windowTitle, 150 );
  
!         WriteToChannel( "SETSTATE1,0x%p,%s,0x%x,0x%x",
!                         ( HWND ) wParam,
!                         windowTitle,
!                         LOWORD( lParam ),
!                         0 );
!         break;
  
  
!     default:
!         break;
!     }
  
  
  
!     return CallNextHookEx( hCbtProc, nCode, wParam, lParam );
  }
  
! 
! LRESULT CALLBACK ShellProc( int nCode, WPARAM wParam, LPARAM lParam )
  {
!     char windowTitle[ 150 ] = { ""
!                               };
!     HWND windowHandle = NULL;
!     char result[ 255 ] = { ""
!                          };
!     char strWindowId[ 25 ];
!     LONG b, t, l, r;
!     char strW[ 5 ];
!     char strY[ 5 ];
!     char strX[ 5 ];
!     char strH[ 5 ];
!     RECT rect;
! 
!     if ( nCode < 0 ) {
!         return CallNextHookEx( hShellProc, nCode, wParam, lParam );
!     }
! 
!     switch ( nCode ) {
!     case HSHELL_WINDOWCREATED:
! 
!         //get window id
!         windowHandle = ( HWND ) wParam;
!         itoa( ( int ) windowHandle, strWindowId, 10 );
  
!         //get coords
!         GetWindowRect( windowHandle, &rect );
!         b = rect.bottom;
!         t = rect.top;
!         l = rect.left;
!         r = rect.right;
!         ltoa( b - t, strH, 10 );
!         ltoa( t, strY, 10 );
!         ltoa( r - l, strW, 10 );
!         ltoa( l, strX, 10 );
  
!         //get name
!         GetWindowText( windowHandle, windowTitle, 150 );
  
!         ////setup return string
!         strcat( result, "MSG=HSHELL_WINDOWCREATED;OP=0;" );
!         strcat( result, "ID=" );
!         strcat( result, strWindowId );
!         strcat( result, ";" );
!         strcat( result, "TITLE=" );
!         strcat( result, windowTitle );
!         strcat( result, ";" );
!         strcat( result, "X=" );
!         strcat( result, strX );
!         strcat( result, ";" );
!         strcat( result, "Y=" );
!         strcat( result, strY );
!         strcat( result, ";" );
!         strcat( result, "H=" );
!         strcat( result, strH );
!         strcat( result, ";" );
!         strcat( result, "W=" );
!         strcat( result, strW );
!         strcat( result, "." );
!         WriteToChannel( result );
!         break;
  
!     case HSHELL_WINDOWDESTROYED:
  
!         //get window id
!         windowHandle = ( HWND ) wParam;
!         itoa( ( int ) windowHandle, strWindowId, 10 );
  
!         //get coords
!         GetWindowRect( windowHandle, &rect );
!         b = rect.bottom;
!         t = rect.top;
!         l = rect.left;
!         r = rect.right;
!         ltoa( b - t, strH, 10 );
!         ltoa( t, strY, 10 );
!         ltoa( r - l, strW, 10 );
!         ltoa( l, strX, 10 );
  
!         //get name
!         GetWindowText( windowHandle, windowTitle, 150 );
  
!         ////setup return string
!         strcat( result, "MSG=HSHELL_WINDOWDESTROYED;OP=1;" );
!         strcat( result, "ID=" );
!         strcat( result, strWindowId );
!         strcat( result, ";" );
!         strcat( result, "TITLE=" );
!         strcat( result, windowTitle );
!         strcat( result, ";" );
!         strcat( result, "X=" );
!         strcat( result, strX );
!         strcat( result, ";" );
!         strcat( result, "Y=" );
!         strcat( result, strY );
!         strcat( result, ";" );
!         strcat( result, "H=" );
!         strcat( result, strH );
!         strcat( result, ";" );
!         strcat( result, "W=" );
!         strcat( result, strW );
!         strcat( result, "." );
!         WriteToChannel( result );
!         break;
  
  
!     default:
!         break;
!     }
  
  
!     return CallNextHookEx( hShellProc, nCode, wParam, lParam );
  }
  
! DLL_EXPORT void SetHooks( void )
  {
!     if ( !hCbtProc ) {
!         hCbtProc = SetWindowsHookEx( WH_CBT, ( HOOKPROC ) CbtProc, hInst, ( DWORD ) NULL );
!     }
! 
! #if 0
!     if ( !hShellProc ) {
!         hShellProc = SetWindowsHookEx( WH_SHELL, ( HOOKPROC ) ShellProc, hInst, ( DWORD ) NULL );
!     }
! #endif
  
!     if ( !hWndProc ) {
!         hWndProc = SetWindowsHookEx( WH_CALLWNDPROC, ( HOOKPROC ) CallWndProc, hInst, ( DWORD ) NULL );
!     }
  }
  
! DLL_EXPORT void RemoveHooks( void )
  {
!     if ( hCbtProc ) {
!         UnhookWindowsHookEx( hCbtProc );
!     }
! 
!     if ( hShellProc ) {
!         UnhookWindowsHookEx( hShellProc );
!     }
  
!     if ( hWndProc ) {
!         UnhookWindowsHookEx( hWndProc );
!     }
  }
  
! DLL_EXPORT int GetInstanceCount()
  {
!     return iInstanceCount;
  }
  
! int OpenVirtualChannel()
  {
!     m_vcHandle = WTSVirtualChannelOpen( WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, CHANNELNAME );
  
!     if ( m_vcHandle == NULL ) {
!         return 0;
!     } else {
!         return 1;
!     }
! }
  
! int CloseVirtualChannel()
! {
!     BOOL result = WTSVirtualChannelClose( m_vcHandle );
  
!     m_vcHandle = NULL;
  
!     if ( result ) {
!         return 1;
!     } else {
!         return 0;
!     }
! }
  
! int ChannelIsOpen()
! {
!     if ( m_vcHandle == NULL ) {
!         return 0;
!     } else {
!         return 1;
!     }
! }
  
! int WriteToChannel( char *format, ... )
! {
!     BOOL result;
!     va_list argp;
!     char buf [ 1024 ];
!     int size;
!     PULONG bytesRead = 0;
!     PULONG pBytesWritten = 0;
  
!     if ( !ChannelIsOpen() )
!         return 1;
  
!     va_start( argp, format );
!     size = _vsnprintf( buf, sizeof( buf ), format, argp );
!     va_end( argp );
  
!     if ( size >= sizeof( buf ) )
!         return 0;
  
!     WaitForSingleObject( hMutex, INFINITE );
!     result = WTSVirtualChannelWrite( m_vcHandle, buf, ( ULONG ) strlen( buf ), pBytesWritten );
!     result = WTSVirtualChannelWrite( m_vcHandle, "\n", ( ULONG ) 1, pBytesWritten );
!     ReleaseMutex( hMutex );
  
!     if ( result ) {
!         return 1;
!     } else {
!         return 0;
!     }
  }
--- 45,354 ----
  #pragma comment(linker, "/section:SHAREDDATA,rws")
  
! static HHOOK g_cbt_hook = NULL;
! static HHOOK g_wndproc_hook = NULL;
  
! static HINSTANCE g_instance = NULL;
  
+ static HANDLE g_mutex = NULL;
  
+ static HANDLE g_vchannel = NULL;
  
! static void
! debug(char *format, ...)
  {
! 	va_list argp;
! 	char buf[256];
  
! 	sprintf(buf, "DEBUG1,");
  
! 	va_start(argp, format);
! 	_vsnprintf(buf + sizeof("DEBUG1,") - 1, sizeof(buf) - sizeof("DEBUG1,") + 1, format, argp);
! 	va_end(argp);
  
! 	vchannel_write(buf);
  }
  
! static LRESULT CALLBACK
! wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
  {
! 	HWND hwnd = ((CWPSTRUCT *) details)->hwnd;
! 	UINT msg = ((CWPSTRUCT *) details)->message;
! 	WPARAM wparam = ((CWPSTRUCT *) details)->wParam;
! 	LPARAM lparam = ((CWPSTRUCT *) details)->lParam;
  
! 	LONG style = GetWindowLong(hwnd, GWL_STYLE);
! 	WINDOWPOS *wp = (WINDOWPOS *) lparam;
! 	RECT rect;
  
! 	if (code < 0)
! 		goto end;
  
! 	switch (msg)
! 	{
  
+ 		case WM_WINDOWPOSCHANGED:
+ 			if (style & WS_CHILD)
+ 				break;
  
  
! 			if (wp->flags & SWP_SHOWWINDOW)
! 			{
! 				// FIXME: Now, just like create!
! 				debug("SWP_SHOWWINDOW for %p!", hwnd);
! 				vchannel_write("CREATE1,0x%p,0x%x", hwnd, 0);
  
! 				// FIXME: SETSTATE
  
+ 				if (!GetWindowRect(hwnd, &rect))
+ 				{
+ 					debug("GetWindowRect failed!\n");
+ 					break;
+ 				}
+ 				vchannel_write("POSITION1,0x%p,%d,%d,%d,%d,0x%x",
+ 					       hwnd,
+ 					       rect.left, rect.top,
+ 					       rect.right - rect.left, rect.bottom - rect.top, 0);
+ 			}
  
  
+ 			if (wp->flags & SWP_HIDEWINDOW)
+ 				vchannel_write("DESTROY1,0x%p,0x%x", hwnd, 0);
  
  
! 			if (!(style & WS_VISIBLE))
! 				break;
  
! 			if (wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE)
! 				break;
  
! 			if (!GetWindowRect(hwnd, &rect))
! 			{
! 				debug("GetWindowRect failed!\n");
! 				break;
! 			}
  
! 			vchannel_write("POSITION1,0x%p,%d,%d,%d,%d,0x%x",
! 				       hwnd,
! 				       rect.left, rect.top,
! 				       rect.right - rect.left, rect.bottom - rect.top, 0);
  
+ 			break;
  
  
! 			/* Note: WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED are
! 			   strange. Sometimes, for example when bringing up the
! 			   Notepad About dialog, only an WM_WINDOWPOSCHANGING is
! 			   sent. In some other cases, for exmaple when opening
! 			   Format->Text in Notepad, both events are sent. Also, for
! 			   some reason, when closing the Notepad About dialog, an
! 			   WM_WINDOWPOSCHANGING event is sent which looks just like
! 			   the event that was sent when the About dialog was opened...  */
! 		case WM_WINDOWPOSCHANGING:
! 			if (style & WS_CHILD)
! 				break;
  
! 			if (!(style & WS_VISIBLE))
! 				break;
  
! 			if (!(wp->flags & SWP_NOZORDER))
! 				vchannel_write("ZCHANGE1,0x%p,0x%p,0x%x",
! 					       hwnd,
! 					       wp->flags & SWP_NOACTIVATE ? wp->hwndInsertAfter : 0,
! 					       0);
  
+ 			break;
  
  
  
  
! 		case WM_DESTROY:
! 			if (style & WS_CHILD)
! 				break;
  
! 			vchannel_write("DESTROY1,0x%p,0x%x", hwnd, 0);
  
+ 			break;
  
  
! 		default:
! 			break;
! 	}
! 
!       end:
! 	return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
  }
  
! static LRESULT CALLBACK
! cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
  {
! 	char title[150];
  
! 	if (code < 0)
! 		goto end;
  
! 	switch (code)
! 	{
! 		case HCBT_MINMAX:
! 			{
! 				int show;
  
! 				show = LOWORD(lparam);
  
! 				if ((show == SW_SHOWMINIMIZED) || (show == SW_MINIMIZE))
! 				{
! 					MessageBox(0,
! 						   "Minimizing windows is not allowed in this version. Sorry!",
! 						   "SeamlessRDP", MB_OK);
! 					return 1;
! 				}
  
+ 				GetWindowText((HWND) wparam, title, sizeof(title));
  
! 				/* FIXME: Strip title of dangerous characters */
  
+ 				vchannel_write("SETSTATE1,0x%p,%s,0x%x,0x%x",
+ 					       (HWND) wparam, title, show, 0);
+ 				break;
+ 			}
  
+ 		default:
+ 			break;
+ 	}
  
!       end:
! 	return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
  }
  
! int
! vchannel_open()
  {
! 	g_vchannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE,
! 					   WTS_CURRENT_SESSION, CHANNELNAME);
  
! 	if (g_vchannel == NULL)
! 		return 0;
! 	else
! 		return 1;
! }
  
! int
! vchannel_close()
! {
! 	BOOL result;
  
! 	result = WTSVirtualChannelClose(g_vchannel);
  
! 	g_vchannel = NULL;
  
! 	if (result)
! 		return 1;
! 	else
! 		return 0;
! }
  
! int
! vchannel_is_open()
! {
! 	if (g_vchannel == NULL)
! 		return 0;
! 	else
! 		return 1;
! }
  
! int
! vchannel_write(char *format, ...)
! {
! 	BOOL result;
! 	va_list argp;
! 	char buf[1024];
! 	int size;
! 	ULONG bytes_written;
  
! 	if (!vchannel_is_open())
! 		return 1;
  
+ 	va_start(argp, format);
+ 	size = _vsnprintf(buf, sizeof(buf), format, argp);
+ 	va_end(argp);
  
! 	if (size >= sizeof(buf))
! 		return 0;
  
+ 	WaitForSingleObject(g_mutex, INFINITE);
+ 	result = WTSVirtualChannelWrite(g_vchannel, buf, (ULONG) strlen(buf), &bytes_written);
+ 	result = WTSVirtualChannelWrite(g_vchannel, "\n", (ULONG) 1, &bytes_written);
+ 	ReleaseMutex(g_mutex);
  
! 	if (result)
! 		return 1;
! 	else
! 		return 0;
  }
  
! DLL_EXPORT void
! SetHooks(void)
  {
! 	if (!g_cbt_hook)
! 		g_cbt_hook = SetWindowsHookEx(WH_CBT, cbt_hook_proc, g_instance, 0);
  
! 	if (!g_wndproc_hook)
! 		g_wndproc_hook = SetWindowsHookEx(WH_CALLWNDPROC, wndproc_hook_proc, g_instance, 0);
  }
  
! DLL_EXPORT void
! RemoveHooks(void)
  {
! 	if (g_cbt_hook)
! 		UnhookWindowsHookEx(g_cbt_hook);
  
! 	if (g_wndproc_hook)
! 		UnhookWindowsHookEx(g_wndproc_hook);
  }
  
! DLL_EXPORT int
! GetInstanceCount()
  {
! 	return g_instance_count;
  }
  
! BOOL APIENTRY
! DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
  {
! 	switch (ul_reason_for_call)
! 	{
! 		case DLL_PROCESS_ATTACH:
! 			// remember our instance handle
! 			g_instance = hinstDLL;
  
! 			g_mutex = CreateMutex(NULL, FALSE, "Local\\Seamless");
! 			if (!g_mutex)
! 				return FALSE;
  
! 			WaitForSingleObject(g_mutex, INFINITE);
! 			++g_instance_count;
! 			ReleaseMutex(g_mutex);
  
! 			vchannel_open();
  
! 			break;
  
! 		case DLL_THREAD_ATTACH:
! 			break;
  
! 		case DLL_THREAD_DETACH:
! 			break;
  
! 		case DLL_PROCESS_DETACH:
! 			WaitForSingleObject(g_mutex, INFINITE);
! 			--g_instance_count;
! 			ReleaseMutex(g_mutex);
  
! 			vchannel_close();
  
! 			CloseHandle(g_mutex);
  
! 			break;
! 	}
  
! 	return TRUE;
  }

Index: hookdll.h
===================================================================
RCS file: /cvsroot/rdesktop/seamlessrdp/ServerExe/HookDll/hookdll.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** hookdll.h	9 Mar 2006 09:17:55 -0000	1.10
--- hookdll.h	9 Mar 2006 12:00:15 -0000	1.11
***************
*** 1,5 ****
! //
! // Copyright (C) 2004-2005 Martin Wickett
! //
  
  #include <windows.h>
--- 1,25 ----
! /* -*- c-basic-offset: 8 -*-
!    rdesktop: A Remote Desktop Protocol client.
!    Seamless windows - Remote server hook DLL
! 
!    Based on code copyright (C) 2004-2005 Martin Wickett
! 
!    Copyright (C) Peter Åstrand <[email protected]> 2005-2006
!    Copyright (C) Pierre Ossman <[email protected]> 2006
! 
!    This program is free software; you can redistribute it and/or modify
!    it under the terms of the GNU General Public License as published by
!    the Free Software Foundation; either version 2 of the License, or
!    (at your option) any later version.
! 
!    This program is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
! 
!    You should have received a copy of the GNU General Public License
!    along with this program; if not, write to the Free Software
!    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! */
  
  #include <windows.h>
***************
*** 10,20 ****
  #define CHANNELNAME "seamrdp"
  
- #pragma once
- 
  //Terminal Server
! int OpenVirtualChannel();
! int CloseVirtualChannel();
! int ChannelIsOpen();
! int WriteToChannel( char *format, ... );
  
  #endif
--- 30,38 ----
  #define CHANNELNAME "seamrdp"
  
  //Terminal Server
! int vchannel_open();
! int vchannel_close();
! int vchannel_is_open();
! int vchannel_write(char *format, ...);
  
  #endif



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.