www.pudn.com > rDUNclientBeta1.zip > main.cpp
//rDUN Client //Copyright (C) Robert Merrison 2002 //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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "main.h" #include//#include //// //WinMain - Application entry point //// int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { config = cfgParse( "rDUN.ini" ); memset( serverAddress, 0, sizeof( serverAddress )); strcpy( serverAddress, cfgGetString( config, "MAIN", "SERVER_ADDRESS", "127.0.0.1" )); serverPort = cfgGetInt( config, "MAIN", "SERVER_PORT", 2244 ); memset( password, 0, sizeof( password )); strcpy( password, cfgGetString( config, "MAIN", "PASSWORD", "" )); autoRedialTime = cfgGetInt( config, "MAIN", "AUTOREDIAL_TIME", -1 ); if( autoRedialTime != -1 ){ useAutoRedial = true; } else{ useAutoRedial = false; } appInstance = hInstance; connectionState = RCSTATE_UNKNOWN; notInitialState = false; expectingDisconnect = false; memset( debugFilename, 0, sizeof( debugFilename )); sprintf( debugFilename, "%s", cfgGetString( config, "MAIN", "DEBUG_FILE", "debug.txt" )); debugEngine.init( DBLEVEL_HIGH, debugFilename ); if ( !createWindow( hInstance, "rDUN Client", &debugEngine )){ debugEngine.kill(); return 0; } createSysTrayIcon( connectionState ); createPopupMenu( RCSTATE_UNKNOWN ); redialWindowHandle = NULL; if ( !server.connectTo( serverAddress, serverPort, windowHandle, password )){ debugEngine.log_message( MSG_CRITICAL, "Error connecting to %s on %d", serverAddress, serverPort ); } MSG msg; while( GetMessage( &msg, NULL, 0, 0 )){ TranslateMessage( &msg ); DispatchMessage( &msg ); } server.onClose(); removeSysTrayIcon(); server.disconnectFrom(); cfgRelease( config ); return 1; } //// //createWindow - Creates and registers the application's window //// bool createWindow( HINSTANCE hInstance, char* name, debug_engine* debugEngine ) { WNDCLASSEX windowClass; memset( &windowClass, 0, sizeof( windowClass )); windowClass.cbSize = sizeof( WNDCLASSEX ); windowClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; windowClass.lpfnWndProc = mainWindowProc; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = hInstance; windowClass.hIcon = LoadIcon( hInstance, "IDI_ICON1" ); windowClass.hCursor = LoadCursor( NULL, IDC_ARROW ); windowClass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); windowClass.lpszClassName = NULL; windowClass.lpszClassName = name; windowClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); if( !RegisterClassEx( &windowClass )){ if( debugEngine ){ debugEngine->log_message( MSG_CRITICAL, "Unable to register window class" ); } else{ MessageBox( NULL, "Unable to register window class", "Critical Error", MB_OK ); } return false; } if( debugEngine ){ debugEngine->log_message( MSG_NOTICE, "Registered window class" ); } windowHandle = CreateWindowEx( WS_EX_TOOLWINDOW, name, name, WS_POPUP | WS_ICONIC, 0, 0, 0, 0, NULL, NULL, hInstance, NULL ); if( !windowHandle ){ if( debugEngine ){ debugEngine->log_message( MSG_CRITICAL, "Error creating window" ); } else{ MessageBox( NULL, "Error creating window", "Critical error", MB_OK ); } return false; } return true; } //// //createPopupMenu - Creates the menu that pops up when the icon is right clicked bool createPopupMenu( int rConnectionState ) { DestroyMenu( popupMenu ); popupMenu = CreatePopupMenu(); if( !popupMenu ){ return false; } AppendMenu( popupMenu, MF_STRING, ID_CONTEXT_STATUS, "Status" ); if( rConnectionState == RCSTATE_CONNECTING || rConnectionState == RCSTATE_CONNECTED ){ AppendMenu( popupMenu, MF_STRING, ID_CONTEXT_DISCONNECT, "Disconnect" ); } if( rConnectionState == RCSTATE_DISCONNECTED || rConnectionState == RCSTATE_USERDISCONNECTED ){ AppendMenu( popupMenu, MF_STRING, ID_CONTEXT_CONNECT, "Connect" ); } AppendMenu( popupMenu, MF_SEPARATOR, 0, NULL ); AppendMenu( popupMenu, MF_STRING, ID_CONTEXT_CLOSE, "Close" ); DrawMenuBar( windowHandle ); return true; } //// //createStsTrayIcon - Creates an icon in the notification area of windows //// void createSysTrayIcon( int rConnectionState ) { NOTIFYICONDATA notifyIcon; memset( ¬ifyIcon, 0, sizeof( NOTIFYICONDATA )); notifyIcon.cbSize = sizeof( NOTIFYICONDATA ); notifyIcon.hWnd = windowHandle; notifyIcon.uID = 1; notifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; switch( rConnectionState ){ case RCSTATE_CONNECTING:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON4 )); sprintf( notifyIcon.szTip, "%s - Connecting", serverAddress ); break; } case RCSTATE_DISCONNECTING:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON4 )); sprintf( notifyIcon.szTip, "%s - Disconnecting", serverAddress ); break; } case RCSTATE_USERDISCONNECTING:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON4 )); sprintf( notifyIcon.szTip, "%s - Disconnecting", serverAddress ); break; } case RCSTATE_CONNECTED:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON2 )); sprintf( notifyIcon.szTip, "%s - Connected", serverAddress ); break; } case RCSTATE_DISCONNECTED:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON3 )); sprintf( notifyIcon.szTip, "%s - Disconnected", serverAddress ); break; } case RCSTATE_USERDISCONNECTED:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON3 )); sprintf( notifyIcon.szTip, "%s - Disconnected", serverAddress ); break; } default:{ notifyIcon.hIcon = LoadIcon( appInstance, MAKEINTRESOURCE( IDI_ICON5 )); sprintf( notifyIcon.szTip, "Unable to connect to %s", serverAddress ); break; } } notifyIcon.uCallbackMessage = WM_NOTIFYMSG; if( !Shell_NotifyIcon( NIM_MODIFY, ¬ifyIcon )){ if( !Shell_NotifyIcon( NIM_ADD, ¬ifyIcon )){ debugEngine.log_message( MSG_ERROR, "Error adding notify icon" ); return; } } } //// //removeSysTrayIcon - Removes the icon from the notification icon //// void removeSysTrayIcon() { NOTIFYICONDATA notifyIcon; memset( ¬ifyIcon, 0, sizeof( NOTIFYICONDATA )); notifyIcon.cbSize = sizeof( NOTIFYICONDATA ); notifyIcon.hWnd = windowHandle; notifyIcon.uID = 1; notifyIcon.uFlags = 0; Shell_NotifyIcon( NIM_DELETE, ¬ifyIcon ); return; } //// //showStatusWindow - Displays the connection status window //// void showStatusWindow( int rConnectionState, bool forceShow ) { if( forceShow ){ if( !statusWindowHandle ){ return; } } else{ if( statusWindowHandle ){ return; } statusWindowHandle = CreateDialog( appInstance, MAKEINTRESOURCE( IDD_DIALOG1 ), windowHandle, &statusWindowProc ); DWORD windowStyle = (DWORD) GetWindowLong( statusWindowHandle, GWL_STYLE ); RECT windowRect; GetWindowRect( statusWindowHandle, &windowRect ); int screenWidth = GetSystemMetrics( SM_CXSCREEN ); int screenHeight = GetSystemMetrics( SM_CYSCREEN ); SetWindowPos( statusWindowHandle, 0, (screenWidth/2) - ((windowRect.right - windowRect.left)/2), (screenHeight/2) - ((windowRect.bottom - windowRect.top)/2), 0, 0, SWP_NOSIZE | SWP_NOZORDER ); } ShowWindow( statusWindowHandle, SW_SHOW ); if( !statusWindowHandle ){ return; } switch( rConnectionState ){ case RCSTATE_UNKNOWN:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Cannot connect to remote DUN server. Please try again later" ); SetDlgItemText( statusWindowHandle, IDOK, "Retry" ); return; } case RCSTATE_CONNECTED:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Remote DUN server is connected to the internet" ); SetDlgItemText( statusWindowHandle, IDOK, "Disconnect" ); return; } case RCSTATE_CONNECTING:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Remote DUN server is dialling the internet" ); SetDlgItemText( statusWindowHandle, IDOK, "Abort" ); return; } case RCSTATE_DISCONNECTED:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Remote DUN server is not connected to the internet" ); SetDlgItemText( statusWindowHandle, IDOK, "Connect" ); return; } case RCSTATE_DISCONNECTING:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Remote DUN server is disconnecting from the internet" ); SetDlgItemText( statusWindowHandle, IDOK, "Ok" ); return; } case RCSTATE_USERDISCONNECTED:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Remote DUN server is not connected to the internet" ); SetDlgItemText( statusWindowHandle, IDOK, "Connect" ); return; } case RCSTATE_USERDISCONNECTING:{ SetDlgItemText( statusWindowHandle, IDC_STATUS, "Remote DUN server is disconnecting from the internet" ); SetDlgItemText( statusWindowHandle, IDOK, "Ok" ); return; } default:{ return; } } return; } //// //showConfirmWindow - Creates and shows the exit confirm dialog //// void showConfirmWindow() { if( !confirmWindowHandle ){ confirmWindowHandle = CreateDialog( appInstance, MAKEINTRESOURCE( IDD_DIALOG2 ), windowHandle, &confirmWindowProc ); } DWORD windowStyle = (DWORD) GetWindowLong( confirmWindowHandle, GWL_STYLE ); RECT windowRect; GetWindowRect( confirmWindowHandle, &windowRect ); int screenWidth = GetSystemMetrics( SM_CXSCREEN ); int screenHeight = GetSystemMetrics( SM_CYSCREEN ); SetWindowPos( confirmWindowHandle, 0, (screenWidth/2) - ((windowRect.right - windowRect.left)/2), (screenHeight/2) - ((windowRect.bottom - windowRect.top)/2), 0, 0, SWP_NOSIZE | SWP_NOZORDER ); ShowWindow( confirmWindowHandle, SW_SHOW ); return; } //// //showRedialWindow - Creates and shows the redial dialog //// void showRedialWindow() { if( redialWindowHandle ){ DestroyWindow( redialWindowHandle ); redialWindowHandle = NULL; } redialWindowHandle = CreateDialog( appInstance, MAKEINTRESOURCE( IDD_DIALOG3 ), windowHandle, &redialWindowProc ); DWORD windowStyle = (DWORD) GetWindowLong( redialWindowHandle, GWL_STYLE ); RECT windowRect; GetWindowRect( redialWindowHandle, &windowRect ); int screenWidth = GetSystemMetrics( SM_CXSCREEN ); int screenHeight = GetSystemMetrics( SM_CYSCREEN ); SetWindowPos( redialWindowHandle, 0, (screenWidth/2) - ((windowRect.right - windowRect.left)/2), (screenHeight/2) - ((windowRect.bottom - windowRect.top)/2), 0, 0, SWP_NOSIZE | SWP_NOZORDER ); if( useAutoRedial ){ autoRedialCountdown = autoRedialTime; KillTimer( redialWindowHandle, TIMER_REDIAL ); SetTimer( redialWindowHandle, TIMER_REDIAL, 1000, NULL ); SendMessage( redialWindowHandle, WM_TIMER, TIMER_REDIAL, NULL ); } ShowWindow( redialWindowHandle, SW_SHOW ); return; } //// //mainWindowProc - Message handler for the main window //// LRESULT CALLBACK mainWindowProc( HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam ) { switch (msg){ case WM_NOTIFYMSG:{ if( lParam == WM_RBUTTONDOWN ){ POINT mousePosition; GetCursorPos( &mousePosition ); SetForegroundWindow( windowHandle ); TrackPopupMenu( popupMenu, TPM_RIGHTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, mousePosition.x, mousePosition.y, 0, windowHandle, NULL ); PostMessage( windowHandle, WM_NULL, 0, 0 ); DestroyMenu( popupMenu ); createPopupMenu( connectionState ); } if( lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDOWN ){ if( statusWindowHandle ){ SetForegroundWindow( statusWindowHandle ); } else{ if( confirmWindowHandle ){ SetForegroundWindow( confirmWindowHandle ); } else{ showStatusWindow( connectionState, false ); } } } return NULL; } case WM_COMMAND:{ if( HIWORD( wParam ) == 0 && LOWORD( wParam ) == ID_CONTEXT_CLOSE ){ showConfirmWindow(); return NULL; } if( HIWORD( wParam ) == 0 && LOWORD( wParam ) == ID_CONTEXT_CONNECT ){ server.rCConnect(); return NULL; } if( HIWORD( wParam ) == 0 && LOWORD( wParam ) == ID_CONTEXT_DISCONNECT ){ server.rCDisconnect(); expectingDisconnect = true; return NULL; } if( HIWORD( wParam ) == 0 && LOWORD( wParam ) == ID_CONTEXT_STATUS ){ showStatusWindow( connectionState, false ); return NULL; } return NULL; } case WM_ONSOCKET:{ if ( WSAGETSELECTERROR( lParam )){ MessageBox( NULL, "Error", "Uh oh", MB_OK ); server.onClose(); } switch ( WSAGETSELECTEVENT( lParam )){ case FD_READ:{ server.onRead(); return NULL; } case FD_WRITE:{ server.onConnect(); return NULL; } case FD_CLOSE:{ server.onClose(); return NULL; } default: return NULL; } } case WM_RCSTATECHANGE:{ connectionState = (int)wParam; createPopupMenu( (int)wParam ); createSysTrayIcon( (int)wParam ); showStatusWindow( connectionState, true ); if( (int)wParam == RCSTATE_USERDISCONNECTED ){ expectingDisconnect = true; } if( expectingDisconnect && ((int)wParam == RCSTATE_DISCONNECTED) || ((int)wParam == RCSTATE_USERDISCONNECTED) ){ expectingDisconnect = false; notInitialState = false; } if((((int)wParam == RCSTATE_DISCONNECTED) || ((int)wParam == RCSTATE_USERDISCONNECTED)) && notInitialState ){ showRedialWindow(); } if((int)wParam == RCSTATE_CONNECTING || (int)wParam == RCSTATE_CONNECTED ){ if( redialWindowHandle ){ DestroyWindow( redialWindowHandle ); KillTimer( redialWindowHandle, TIMER_REDIAL ); redialWindowHandle = NULL; } } notInitialState = true; return NULL; } default: break; } return( DefWindowProc( windowHandle, msg, wParam, lParam )); } //// //statusWindowProc - Message handler for the status window dialog //// BOOL CALLBACK statusWindowProc( HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ){ case WM_INITDIALOG:{ return TRUE; } case WM_CLOSE:{ DestroyWindow( statusWindowHandle ); statusWindowHandle = NULL; return TRUE; } case WM_COMMAND:{ if( LOWORD( wParam ) == IDOK && (HIWORD( wParam ) == BN_CLICKED || BN_DOUBLECLICKED)){ switch( connectionState ){ case RCSTATE_UNKNOWN:{ server.connectTo( serverAddress, serverPort, windowHandle, password ); return FALSE; } case RCSTATE_DISCONNECTING:{ DestroyWindow( statusWindowHandle ); statusWindowHandle = NULL; return FALSE; } case RCSTATE_CONNECTED:{ server.rCDisconnect(); expectingDisconnect = true; return FALSE; } case RCSTATE_DISCONNECTED:{ server.rCConnect(); return FALSE; } case RCSTATE_CONNECTING:{ server.rCDisconnect(); expectingDisconnect = true; return FALSE; } default: return FALSE; } } if( LOWORD( wParam ) == IDC_CLOSE && (HIWORD( wParam ) == BN_CLICKED || BN_DOUBLECLICKED)){ DestroyWindow( statusWindowHandle ); statusWindowHandle = NULL; return FALSE; } } default:{ return FALSE; } } return FALSE; } //// //confirmWindowProc - Message handler for the exit confirmation window dialog //// BOOL CALLBACK confirmWindowProc( HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ){ case WM_INITDIALOG:{ return TRUE; } case WM_CLOSE:{ DestroyWindow( confirmWindowHandle ); confirmWindowHandle = NULL; return TRUE; } case WM_COMMAND:{ if( LOWORD( wParam ) == IDC_NO && (HIWORD( wParam ) == BN_CLICKED || BN_DOUBLECLICKED)){ DestroyWindow( confirmWindowHandle ); confirmWindowHandle = NULL; return TRUE; } if( LOWORD( wParam ) == IDC_YES && (HIWORD( wParam ) == BN_CLICKED || BN_DOUBLECLICKED)){ PostQuitMessage( 0 ); DestroyWindow( confirmWindowHandle ); confirmWindowHandle = NULL; return TRUE; } return FALSE; } default: break; } return FALSE; } //// //redialWindowProc - Message handler for the redial window dialog //// BOOL CALLBACK redialWindowProc( HWND windowHandle, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ){ case WM_INITDIALOG:{ return TRUE; } case WM_CLOSE:{ DestroyWindow( redialWindowHandle ); KillTimer( redialWindowHandle, TIMER_REDIAL ); redialWindowHandle = NULL; return TRUE; } case WM_COMMAND:{ if( LOWORD( wParam ) == IDCANCEL && (HIWORD( wParam ) == BN_CLICKED || BN_DOUBLECLICKED)){ DestroyWindow( redialWindowHandle ); KillTimer( redialWindowHandle, TIMER_REDIAL ); redialWindowHandle = NULL; return TRUE; } if( LOWORD( wParam ) == ID_REDIAL ){ server.rCConnect(); return TRUE; } return FALSE; } case WM_TIMER:{ if( wParam == TIMER_REDIAL ){ if( !useAutoRedial ){ KillTimer( redialWindowHandle, TIMER_REDIAL ); return TRUE; } else{ autoRedialCountdown -= 1; char redialString[256]; memset( redialString, 0, sizeof( redialString )); sprintf( redialString, "Redialling in %i seconds.", autoRedialCountdown ); SetDlgItemText( redialWindowHandle, IDC_STATIC2, redialString ); if( autoRedialCountdown <= 0 ){ server.rCConnect(); } return TRUE; } } }; default:break; } return FALSE; }