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_state = 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(IDS_ERR_OPEN_SCMGR);
       goto failed;
    }

    schService = OpenService( 
        schSCManager,          // SCM database 
        _T("OpenVPNService"),  // service name
        SERVICE_START | SERVICE_QUERY_STATUS); 
 
    if (schService == NULL) {
      /* can't open VPN service */
      ShowLocalizedMsg(IDS_ERR_OPEN_VPN_SERVICE);
      goto failed;
    }
 
    /* Run Pre-connect script */
    for (i=0; i<o.num_configs; i++)
        RunPreconnectScript(&o.conn[i]);

    if (!StartService(
            schService,  // handle to service 
            0,           // number of arguments 
            NULL) )      // no arguments 
    {
      /* can't start */
      ShowLocalizedMsg(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(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(IDS_ERR_SERVICE_START_FAILED);
        goto failed;
    } 

    /* Run Connect script */
    for (i=0; i<o.num_configs; i++)    
      RunConnectScript(&o.conn[i], true);

    /* Set Service Status = Connected */
    o.service_state = service_connected;
    SetServiceMenuStatus();
    CheckAndSetTrayIcon();

    /* Show "OpenVPN Service Started" Tray Balloon msg */
    ShowTrayBalloon(LoadLocalizedString(IDS_NFO_SERVICE_STARTED), _T(""));

    return(true);

failed:

    /* Set Service Status = Disconnecting */
    o.service_state = service_disconnected;
    SetServiceMenuStatus();
    CheckAndSetTrayIcon();
    return(false);
}
Exemple #2
0
/*
 * Handle a state change notification from the OpenVPN management interface
 * Format <TIMESTAMP>,<STATE>,[<MESSAGE>],[<LOCAL_IP>][,<REMOTE_IP>]
 */
void
OnStateChange(connection_t *c, char *data)
{
    char *pos, *state, *message;

    pos = strchr(data, ',');
    if (pos == NULL)
        return;
    *pos = '\0';

    state = pos + 1;
    pos = strchr(state, ',');
    if (pos == NULL)
        return;
    *pos = '\0';

    message = pos + 1;
    pos = strchr(message, ',');
    if (pos == NULL)
        return;
    *pos = '\0';

    if (strcmp(state, "CONNECTED") == 0)
    {
        /* Run Connect Script */
        if (c->state == connecting || c->state == resuming)
            RunConnectScript(c, false);

        /* Save the local IP address if available */
        char *local_ip = pos + 1;
        pos = strchr(local_ip, ',');
        if (pos != NULL)
            *pos = '\0';

        /* Convert the IP address to Unicode */
        MultiByteToWideChar(CP_ACP, 0, local_ip, -1, c->ip, _countof(c->ip));

        /* Show connection tray balloon */
        if ((c->state == connecting   && o.show_balloon != 0)
        ||  (c->state == resuming     && o.show_balloon != 0)
        ||  (c->state == reconnecting && o.show_balloon == 2))
        {
            TCHAR msg[256];
            LoadLocalizedStringBuf(msg, _countof(msg), IDS_NFO_NOW_CONNECTED, c->config_name);
            ShowTrayBalloon(msg, (_tcslen(c->ip) ? LoadLocalizedString(IDS_NFO_ASSIGN_IP, c->ip) : _T("")));
        }

        /* Save time when we got connected. */
        c->connected_since = atoi(data);
        c->failed_psw_attempts = 0;
        c->state = connected;

        SetMenuStatus(c, connected);
        SetTrayIcon(connected);

        SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONNECTED));
        SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTED);

        /* Hide Status Window */
        ShowWindow(c->hwndStatus, SW_HIDE);
    }
    else if (strcmp(state, "RECONNECTING") == 0)
    {
        if (strcmp(message, "auth-failure") == 0
        ||  strcmp(message, "private-key-password-failure") == 0)
            c->failed_psw_attempts++;

        if (strcmp(message, "auth-failure") == 0 && (c->flags & FLAG_SAVE_AUTH_PASS))
            SaveAuthPass(c->config_name, L"");
        else if (strcmp(message, "private-key-password-failure") == 0 && (c->flags & FLAG_SAVE_KEY_PASS))
            SaveKeyPass(c->config_name, L"");

        c->state = reconnecting;
        CheckAndSetTrayIcon();

        SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING));
        SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING);
    }
}