mirror of https://github.com/OpenVPN/openvpn-gui
				
				
				
			
		
			
				
	
	
		
			296 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
/*
 | 
						|
 *  OpenVPN-GUI -- A Windows GUI for OpenVPN.
 | 
						|
 *
 | 
						|
 *  Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
 | 
						|
 *
 | 
						|
 *  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 (see the file COPYING included with this
 | 
						|
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 | 
						|
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
						|
 */
 | 
						|
 | 
						|
#include <windows.h>
 | 
						|
#include "tray.h"
 | 
						|
#include "service.h"
 | 
						|
#include "openvpn.h"
 | 
						|
#include "options.h"
 | 
						|
#include "scripts.h"
 | 
						|
#include "main.h"
 | 
						|
#include <stdio.h>
 | 
						|
#include "openvpn-gui-res.h"
 | 
						|
#include "localization.h"
 | 
						|
 | 
						|
extern struct options o;
 | 
						|
 | 
						|
int MyStartService()
 | 
						|
{
 | 
						|
 | 
						|
  SC_HANDLE schSCManager;
 | 
						|
  SC_HANDLE schService;
 | 
						|
  SERVICE_STATUS ssStatus; 
 | 
						|
  DWORD dwOldCheckPoint; 
 | 
						|
  DWORD dwStartTickCount;
 | 
						|
  DWORD dwWaitTime;
 | 
						|
  int i;
 | 
						|
 | 
						|
    /* Set Service Status = Connecting */
 | 
						|
    o.service_running = SERVICE_CONNECTING;
 | 
						|
    SetServiceMenuStatus();
 | 
						|
    CheckAndSetTrayIcon();
 | 
						|
 | 
						|
    // Open a handle to the SC Manager database. 
 | 
						|
    schSCManager = OpenSCManager( 
 | 
						|
       NULL,                    // local machine 
 | 
						|
       NULL,                    // ServicesActive database 
 | 
						|
       SC_MANAGER_CONNECT);     // Connect rights 
 | 
						|
   
 | 
						|
    if (NULL == schSCManager) {
 | 
						|
       /* open SC manager failed */
 | 
						|
       ShowLocalizedMsg(GUI_NAME, IDS_ERR_OPEN_SCMGR);
 | 
						|
       goto failed;
 | 
						|
    }
 | 
						|
 | 
						|
    schService = OpenService( 
 | 
						|
        schSCManager,          // SCM database 
 | 
						|
        "OpenVPNService",     // service name
 | 
						|
        SERVICE_START | SERVICE_QUERY_STATUS); 
 | 
						|
 
 | 
						|
    if (schService == NULL) {
 | 
						|
      /* can't open VPN service */
 | 
						|
      ShowLocalizedMsg(GUI_NAME, IDS_ERR_OPEN_VPN_SERVICE);
 | 
						|
      goto failed;
 | 
						|
    }
 | 
						|
 
 | 
						|
    /* Run Pre-connect script */
 | 
						|
    for (i=0; i<o.num_configs; i++)    
 | 
						|
        RunPreconnectScript(i);
 | 
						|
 | 
						|
    if (!StartService(
 | 
						|
            schService,  // handle to service 
 | 
						|
            0,           // number of arguments 
 | 
						|
            NULL) )      // no arguments 
 | 
						|
    {
 | 
						|
      /* can't start */
 | 
						|
      ShowLocalizedMsg(NULL, IDS_ERR_START_SERVICE);
 | 
						|
      goto failed;
 | 
						|
    }
 | 
						|
    else 
 | 
						|
    {
 | 
						|
        //printf("Service start pending.\n"); 
 | 
						|
    }
 | 
						|
 
 | 
						|
    // Check the status until the service is no longer start pending. 
 | 
						|
    if (!QueryServiceStatus( 
 | 
						|
            schService,   // handle to service 
 | 
						|
            &ssStatus) )  // address of status information structure
 | 
						|
    {
 | 
						|
      /* query failed */
 | 
						|
      ShowLocalizedMsg(GUI_NAME, IDS_ERR_QUERY_SERVICE);
 | 
						|
      goto failed;
 | 
						|
    }
 | 
						|
 
 | 
						|
    // Save the tick count and initial checkpoint.
 | 
						|
    dwStartTickCount = GetTickCount();
 | 
						|
    dwOldCheckPoint = ssStatus.dwCheckPoint;
 | 
						|
 | 
						|
    while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
 | 
						|
    { 
 | 
						|
        // Do not wait longer than the wait hint. A good interval is 
 | 
						|
        // one tenth the wait hint, but no less than 1 second and no 
 | 
						|
        // more than 5 seconds. 
 | 
						|
 
 | 
						|
        dwWaitTime = ssStatus.dwWaitHint / 10;
 | 
						|
 | 
						|
        if( dwWaitTime < 1000 )
 | 
						|
            dwWaitTime = 1000;
 | 
						|
        else if ( dwWaitTime > 5000 )
 | 
						|
            dwWaitTime = 5000;
 | 
						|
 | 
						|
        Sleep( dwWaitTime );
 | 
						|
 | 
						|
        // Check the status again. 
 | 
						|
        if (!QueryServiceStatus( 
 | 
						|
                schService,   // handle to service 
 | 
						|
                &ssStatus) )  // address of structure
 | 
						|
            break; 
 | 
						|
 
 | 
						|
        if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
 | 
						|
        {
 | 
						|
            // The service is making progress.
 | 
						|
            dwStartTickCount = GetTickCount();
 | 
						|
            dwOldCheckPoint = ssStatus.dwCheckPoint;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
 | 
						|
            {
 | 
						|
                // No progress made within the wait hint
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } 
 | 
						|
 | 
						|
    CloseServiceHandle(schService); 
 | 
						|
    CloseServiceHandle(schSCManager);
 | 
						|
 | 
						|
    if (ssStatus.dwCurrentState != SERVICE_RUNNING) 
 | 
						|
    { 
 | 
						|
        /* service hasn't started */
 | 
						|
        ShowLocalizedMsg(GUI_NAME, IDS_ERR_SERVICE_START_FAILED); 
 | 
						|
        goto failed;
 | 
						|
    } 
 | 
						|
 | 
						|
    /* Run Connect script */
 | 
						|
    for (i=0; i<o.num_configs; i++)    
 | 
						|
      RunConnectScript(i, true);
 | 
						|
 | 
						|
    /* Set Service Status = Connected */
 | 
						|
    o.service_running = SERVICE_CONNECTED;
 | 
						|
    SetServiceMenuStatus();
 | 
						|
    CheckAndSetTrayIcon();
 | 
						|
 | 
						|
    /* Show "OpenVPN Service Started" Tray Balloon msg */
 | 
						|
    ShowTrayBalloon(LoadLocalizedString(IDS_NFO_SERVICE_STARTED), " ");
 | 
						|
 | 
						|
    return(true);
 | 
						|
 | 
						|
failed:
 | 
						|
 | 
						|
    /* Set Service Status = Disconnecting */
 | 
						|
    o.service_running = SERVICE_DISCONNECTED;
 | 
						|
    SetServiceMenuStatus();
 | 
						|
    CheckAndSetTrayIcon();
 | 
						|
    return(false);
 | 
						|
}
 | 
						|
 | 
						|
int MyStopService()
 | 
						|
{
 | 
						|
 | 
						|
  SC_HANDLE schSCManager;
 | 
						|
  SC_HANDLE schService;
 | 
						|
  SERVICE_STATUS ssStatus; 
 | 
						|
  int i;
 | 
						|
 | 
						|
    // Open a handle to the SC Manager database. 
 | 
						|
    schSCManager = OpenSCManager( 
 | 
						|
       NULL,                    // local machine 
 | 
						|
       NULL,                    // ServicesActive database 
 | 
						|
       SC_MANAGER_CONNECT);     // Connect rights 
 | 
						|
   
 | 
						|
    if (NULL == schSCManager) {
 | 
						|
       /* can't open SCManager */
 | 
						|
       ShowLocalizedMsg(GUI_NAME, IDS_ERR_OPEN_SCMGR, (int) GetLastError());
 | 
						|
       return(false);
 | 
						|
    }
 | 
						|
 | 
						|
    schService = OpenService( 
 | 
						|
        schSCManager,          // SCM database 
 | 
						|
        "OpenVPNService",     // service name
 | 
						|
        SERVICE_STOP); 
 | 
						|
 
 | 
						|
    if (schService == NULL) {
 | 
						|
      /* can't open vpn service */
 | 
						|
      ShowLocalizedMsg(GUI_NAME, IDS_ERR_OPEN_VPN_SERVICE);
 | 
						|
      return(false);
 | 
						|
    }
 | 
						|
 | 
						|
    /* Run DisConnect script */
 | 
						|
    for (i=0; i<o.num_configs; i++)    
 | 
						|
      RunDisconnectScript(i, true);
 | 
						|
 | 
						|
    if (!ControlService( 
 | 
						|
            schService,   // handle to service 
 | 
						|
            SERVICE_CONTROL_STOP,   // control value to send 
 | 
						|
            &ssStatus) )  // address of status info 
 | 
						|
    {
 | 
						|
      /* stop failed */
 | 
						|
      ShowLocalizedMsg(GUI_NAME, IDS_ERR_STOP_SERVICE);
 | 
						|
      return(false);
 | 
						|
    }
 | 
						|
 | 
						|
    o.service_running = SERVICE_DISCONNECTED;
 | 
						|
    SetServiceMenuStatus();
 | 
						|
    CheckAndSetTrayIcon();
 | 
						|
    return(true);
 | 
						|
}
 | 
						|
 | 
						|
int MyReStartService()
 | 
						|
{
 | 
						|
 | 
						|
    MyStopService();
 | 
						|
    Sleep(1000);
 | 
						|
    if (MyStartService()) {
 | 
						|
       return(true);
 | 
						|
    }
 | 
						|
 | 
						|
    return(false);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int CheckServiceStatus()
 | 
						|
{
 | 
						|
 | 
						|
  SC_HANDLE schSCManager;
 | 
						|
  SC_HANDLE schService;
 | 
						|
  SERVICE_STATUS ssStatus; 
 | 
						|
 | 
						|
    // Open a handle to the SC Manager database. 
 | 
						|
    schSCManager = OpenSCManager( 
 | 
						|
      NULL,                    // local machine 
 | 
						|
      NULL,                    // ServicesActive database 
 | 
						|
      SC_MANAGER_CONNECT);     // Connect rights 
 | 
						|
   
 | 
						|
    if (NULL == schSCManager) {
 | 
						|
      o.service_running = SERVICE_NOACCESS;
 | 
						|
      SetServiceMenuStatus();
 | 
						|
      return(false);
 | 
						|
    }
 | 
						|
 | 
						|
    schService = OpenService( 
 | 
						|
      schSCManager,          // SCM database 
 | 
						|
      "OpenVPNService",     // service name
 | 
						|
      SERVICE_QUERY_STATUS); 
 | 
						|
 
 | 
						|
    if (schService == NULL) {
 | 
						|
      /* open vpn service failed */
 | 
						|
      ShowLocalizedMsg(GUI_NAME, IDS_ERR_OPEN_VPN_SERVICE);
 | 
						|
      o.service_running = SERVICE_NOACCESS;
 | 
						|
      SetServiceMenuStatus();
 | 
						|
      return(false);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!QueryServiceStatus( 
 | 
						|
            schService,   // handle to service 
 | 
						|
            &ssStatus) )  // address of status information structure
 | 
						|
    {
 | 
						|
      /* query failed */
 | 
						|
      ShowLocalizedMsg(GUI_NAME, IDS_ERR_QUERY_SERVICE);
 | 
						|
      return(false);
 | 
						|
    }
 | 
						|
 
 | 
						|
    if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
 | 
						|
    {
 | 
						|
        o.service_running = SERVICE_CONNECTED;
 | 
						|
        SetServiceMenuStatus(); 
 | 
						|
        SetTrayIcon(CONNECTED);
 | 
						|
        return(true);
 | 
						|
    }
 | 
						|
    else 
 | 
						|
    { 
 | 
						|
        o.service_running = SERVICE_DISCONNECTED;
 | 
						|
        SetServiceMenuStatus();
 | 
						|
        SetTrayIcon(DISCONNECTED);
 | 
						|
        return(false);
 | 
						|
    } 
 | 
						|
} 
 |