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); }
/* * 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); } }