/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/main.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

Diff of /sourceforge.net/trunk/seamlessrdp/ServerExe/main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1069 by ossman_, Thu Mar 9 09:46:30 2006 UTC revision 1071 by ossman_, Thu Mar 9 12:00:15 2006 UTC
# Line 1  Line 1 
1  //  /* -*- c-basic-offset: 8 -*-
2  // Copyright (C) 2004-2005 Martin Wickett     rdesktop: A Remote Desktop Protocol client.
3  //     Seamless windows - Remote server executable
4    
5       Based on code copyright (C) 2004-2005 Martin Wickett
6    
7       Copyright (C) Peter Åstrand <astrand@cendio.se> 2005-2006
8       Copyright (C) Pierre Ossman <ossman@cendio.se> 2006
9    
10       This program is free software; you can redistribute it and/or modify
11       it under the terms of the GNU General Public License as published by
12       the Free Software Foundation; either version 2 of the License, or
13       (at your option) any later version.
14    
15       This program is distributed in the hope that it will be useful,
16       but WITHOUT ANY WARRANTY; without even the implied warranty of
17       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18       GNU General Public License for more details.
19    
20       You should have received a copy of the GNU General Public License
21       along with this program; if not, write to the Free Software
22       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23    */
24    
25  #include <windows.h>  #include <windows.h>
26  #include <stdio.h>  #include <stdio.h>
27    
28  #include "resource.h"  #include "resource.h"
29    
30  #define snprintf _snprintf  #define APP_NAME "SeamlessRDP Shell"
31    
32  //  /* Global data */
33  // some global data  static HINSTANCE g_instance;
 //  
 HWND ghWnd;  
 NOTIFYICONDATA nid;  
 HINSTANCE hAppInstance;  
   
 #define WM_TRAY_NOTIFY ( WM_APP + 1000 )  
   
 static const char szAppName[] = "SeamlessRDP Shell";  
   
 typedef void ( *SetHooksProc ) ();  
 typedef void ( *RemoveHooksProc ) ();  
 typedef int ( *GetInstanceCountProc ) ();  
   
 //  
 // spawn a message box  
 //  
 void Message( const char *message )  
 {  
     MessageBox( GetDesktopWindow(), message, "SeamlessRDP Shell", MB_OK );  
 }  
   
 //  
 // manage the tray icon  
 //  
 BOOL InitTrayIcon()  
 {  
     nid.cbSize = sizeof( NOTIFYICONDATA );  
     nid.hWnd = ghWnd;  
     nid.uID = 0;  
     nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;  
     nid.uCallbackMessage = WM_TRAY_NOTIFY;  
     strcpy( nid.szTip, szAppName );  
     nid.hIcon = LoadIcon( hAppInstance, MAKEINTRESOURCE( IDI_TRAY ) );  
   
     if ( Shell_NotifyIcon( NIM_ADD, &nid ) != TRUE ) {  
         Message( "Unable to create tray icon." );  
         return FALSE;  
     }  
   
     return TRUE;  
 }  
   
 //  
 // Remove tray icon  
 //  
 BOOL RemoveTrayIcon()  
 {  
     if ( Shell_NotifyIcon( NIM_DELETE, &nid ) != TRUE ) {  
         Message( "Unable to remove tray icon." );  
         return FALSE;  
     }  
   
     return TRUE;  
   
 }  
   
 //  
 // manage the about dialog box  
 //  
 BOOL CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam,  
                           LPARAM lParam )  
 {  
     if ( uMsg == WM_COMMAND ) {  
         WORD wID = LOWORD( wParam );  
         if ( wID == IDOK )  
             DestroyWindow( hwndDlg );  
     }  
   
     return 0;  
 }  
   
 void AboutDlg()  
 {  
     DialogBox( hAppInstance, MAKEINTRESOURCE( IDD_ABOUT ), NULL, DialogProc );  
 }  
   
 //  
 // manage the context menu  
 //  
 void DoContextMenu()  
 {  
     HMENU hMenu, hSubMenu;  
     POINT pt;  
         int cmd;  
   
     hMenu = LoadMenu( hAppInstance, MAKEINTRESOURCE( IDR_TRAY ) );  
     if ( hMenu == NULL ) {  
         Message( "Unable to load menu ressource." );  
         return ;  
     }  
   
     hSubMenu = GetSubMenu( hMenu, 0 );  
     if ( hSubMenu == NULL ) {  
         Message( "Unable to find popup mennu." );  
         return ;  
     }  
   
     // get the cursor position  
     GetCursorPos( &pt );  
   
     SetForegroundWindow( ghWnd );  
     cmd = TrackPopupMenu( hSubMenu,  
                               TPM_RETURNCMD | TPM_LEFTALIGN | TPM_RIGHTBUTTON,  
                               pt.x, pt.y, 0, ghWnd, NULL );  
     DestroyMenu( hMenu );  
   
     switch ( cmd ) {  
     case ID_WMEXIT: {  
             PostQuitMessage( 0 );  
             break;  
         }  
     case ID_WMABOUT: {  
             AboutDlg();  
             break;  
         }  
     }  
 }  
   
 //  
 // manage the main window  
 //  
 LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )  
 {  
     switch ( uMsg ) {  
     case WM_DESTROY: {  
             PostQuitMessage( 0 );  
             return 0;  
         }  
     case WM_TRAY_NOTIFY: {  
             if ( lParam == WM_RBUTTONDOWN )  
                 DoContextMenu();  
             return 0;  
         }  
     }  
   
     return DefWindowProc( hWnd, uMsg, wParam, lParam );  
 }  
   
 //  
 //Init window  
 //  
 BOOL InitWindow()  
 {  
     // register the frame class  
     WNDCLASS wndclass;  
     wndclass.style = 0;  
     wndclass.lpfnWndProc = ( WNDPROC ) MainWndProc;  
     wndclass.cbClsExtra = 0;  
     wndclass.cbWndExtra = 0;  
     wndclass.hInstance = hAppInstance;  
     wndclass.hIcon = 0;  
     wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );  
     wndclass.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 );  
     wndclass.lpszMenuName = NULL;  
     wndclass.lpszClassName = szAppName;  
   
     if ( !RegisterClass( &wndclass ) ) {  
         Message( "Unable to register the window class." );  
         return FALSE;  
     }  
   
     // create the frame  
     ghWnd = CreateWindow( szAppName, szAppName,  
                           WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |  
                           WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 640,  
                           480, NULL, NULL, hAppInstance, NULL );  
   
     // make sure window was created  
     if ( !ghWnd ) {  
         Message( "Unable to create the window." );  
         return FALSE;  
     }  
   
     return TRUE;  
 }  
   
 //  
 // our main loop  
 //  
 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,  
                     LPSTR lpCmdLine, int nCmdShow )  
 {  
     HMODULE hHookDLL;  
     GetInstanceCountProc pfnInstanceCount;  
     SetHooksProc pfnSetHooks;  
     RemoveHooksProc pfnRemoveHooks;  
   
     hAppInstance = hInstance;  
   
     hHookDLL = LoadLibrary( "hookdll.dll" );  
     if ( !hHookDLL ) {  
         Message( "Could not load hook DLL. Unable to continue." );  
         return -1;  
     }  
   
     pfnInstanceCount = (GetInstanceCountProc) GetProcAddress( hHookDLL, "GetInstanceCount" );  
     pfnSetHooks = (SetHooksProc) GetProcAddress( hHookDLL, "SetHooks" );  
     pfnRemoveHooks = (RemoveHooksProc) GetProcAddress( hHookDLL, "RemoveHooks" );  
   
     if ( !pfnInstanceCount || !pfnSetHooks || !pfnRemoveHooks ) {  
         FreeLibrary( hHookDLL );  
         Message( "Hook DLL doesn't contain the correct functions. Unable to continue." );  
         return -1;  
     }  
   
     /* Check if the DLL is already loaded */  
     if ( pfnInstanceCount() != 1 ) {  
         FreeLibrary( hHookDLL );  
         Message( "Another running instance of Seamless RDP detected." );  
         return -1;  
     }  
   
     pfnSetHooks();  
   
     // if we have been specified an app to launch, we will wait until the app has closed and use that for  
     // our cue to exit  
     if ( strlen( lpCmdLine ) > 0 ) {  
         // Because we do not have a explorer.exe we need to make this application the replacement  
         // shell. We do this by calling SystemParametersInfo. If we don't do this, we won't get the WH_SHELL notifications.  
   
         MINIMIZEDMETRICS mmm;  
         PROCESS_INFORMATION procInfo;  
         STARTUPINFO startupInfo = {  
                                       0  
                                   };  
         char attr[] = "";  
         LPTSTR process = lpCmdLine;  
         DWORD dwExitCode;  
         BOOL m_create;  
   
         // From MSDN:  
         // Note that custom shell applications do not receive WH_SHELL messages. Therefore, any application that  
         // registers itself as the default shell must call the SystemParametersInfo function with SPI_SETMINIMIZEDMETRICS  
         // before it (or any other application) can receive WH_SHELL messages.  
   
         mmm.cbSize = sizeof( MINIMIZEDMETRICS );  
         SystemParametersInfo( SPI_SETMINIMIZEDMETRICS,  
                               sizeof( MINIMIZEDMETRICS ), &mmm, 0 );  
   
         // We require DragFullWindows  
         SystemParametersInfo( SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0 );  
   
         //set the current directory to that of the requested app .exe location  
         //tokenise lpCmdLine. first is the exe path. second (if exists) is the current directory to set.  
         //SetCurrentDirectory ();  
   
         //start process specified from command line arg.  
         startupInfo.cb = sizeof( STARTUPINFO );  
   
         m_create =  
             CreateProcess( NULL, process, NULL, NULL, FALSE, 0, NULL, NULL,  
                            &startupInfo, &procInfo );  
   
         if ( m_create != FALSE ) {  
             // A loop to watch the process.  
             GetExitCodeProcess( procInfo.hProcess, &dwExitCode );  
   
             while ( dwExitCode == STILL_ACTIVE ) {  
                 GetExitCodeProcess( procInfo.hProcess, &dwExitCode );  
                 Sleep( 1000 );  
             }  
   
             // Release handles  
             CloseHandle( procInfo.hProcess );  
             CloseHandle( procInfo.hThread );  
         } else {  
             // CreateProcess failed.  
             char msg[ 256 ];  
             snprintf( msg, sizeof( msg ), "Unable to launch the requested application:\n%s", process );  
             Message( msg );  
         }  
     } else  
         // we are launching without an app, therefore we will show the system tray app and wait for the user to close it  
     {  
         MSG msg;  
   
                 // create a dummy window to receive WM_QUIT message  
         InitWindow();  
   
         // create the tray icon  
         InitTrayIcon();  
   
         // just get and dispatch messages until we're killed  
         while ( GetMessage( &msg, 0, 0, 0 ) ) {  
             TranslateMessage( &msg );  
             DispatchMessage( &msg );  
         };  
   
         // remove our tray icon  
         RemoveTrayIcon();  
     }  
34    
35    typedef void (*set_hooks_proc_t) ();
36    typedef void (*remove_hooks_proc_t) ();
37    typedef int (*get_instance_count_proc_t) ();
38    
39    static void
40    message(const char *text)
41    {
42            MessageBox(GetDesktopWindow(), text, "SeamlessRDP Shell", MB_OK);
43    }
44    
45    int WINAPI
46    WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
47    {
48            HMODULE hookdll;
49    
50            set_hooks_proc_t set_hooks_fn;
51            remove_hooks_proc_t remove_hooks_fn;
52            get_instance_count_proc_t instance_count_fn;
53    
54            g_instance = instance;
55    
56            hookdll = LoadLibrary("hookdll.dll");
57            if (!hookdll)
58            {
59                    message("Could not load hook DLL. Unable to continue.");
60                    return -1;
61            }
62    
63            set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
64            remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
65            instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
66    
67            if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn)
68            {
69                    FreeLibrary(hookdll);
70                    message("Hook DLL doesn't contain the correct functions. Unable to continue.");
71                    return -1;
72            }
73    
74            /* Check if the DLL is already loaded */
75            if (instance_count_fn() != 1)
76            {
77                    FreeLibrary(hookdll);
78                    message("Another running instance of Seamless RDP detected.");
79                    return -1;
80            }
81    
82            set_hooks_fn();
83    
84            if (strlen(cmdline) == 0)
85            {
86                    message("No command line specified.");
87                    return -1;
88            }
89            else
90            {
91                    BOOL result;
92                    DWORD exitcode;
93                    PROCESS_INFORMATION proc_info;
94                    STARTUPINFO startup_info;
95    
96                    memset(&startup_info, 0, sizeof(STARTUPINFO));
97                    startup_info.cb = sizeof(STARTUPINFO);
98    
99                    result = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0,
100                                           NULL, NULL, &startup_info, &proc_info);
101    
102                    if (result)
103                    {
104                            do
105                            {
106                                    Sleep(1000);
107                                    GetExitCodeProcess(proc_info.hProcess, &exitcode);
108                            }
109                            while (exitcode == STILL_ACTIVE);
110    
111                            // Release handles
112                            CloseHandle(proc_info.hProcess);
113                            CloseHandle(proc_info.hThread);
114                    }
115                    else
116                    {
117                            // CreateProcess failed.
118                            char msg[256];
119                            _snprintf(msg, sizeof(msg),
120                                      "Unable to launch the requested application:\n%s", cmdline);
121                            message(msg);
122                    }
123            }
124    
125      // remove hook before saying goodbye          remove_hooks_fn();
     pfnRemoveHooks();  
126    
127      FreeLibrary( hHookDLL );          FreeLibrary(hookdll);
128    
129      return 1;          return 1;
130  }  }

Legend:
Removed from v.1069  
changed lines
  Added in v.1071

  ViewVC Help
Powered by ViewVC 1.1.26