diff --git a/main.c b/main.c index c1ee3d5..86ea3d6 100644 --- a/main.c +++ b/main.c @@ -351,10 +351,23 @@ StopAllOpenVPN() { int i; + /* Stop all connections started by us -- we leave persistent ones + * at their current state. Use the disconnect menu to put them into + * hold state before exit, if desired. + */ for (i = 0; i < o.num_configs; i++) { if (o.conn[i].state != disconnected) - StopOpenVPN(&o.conn[i]); + { + if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT) + { + DetachOpenVPN(&o.conn[i]); + } + else + { + StopOpenVPN(&o.conn[i]); + } + } } /* Wait for all connections to terminate (Max 5 sec) */ @@ -756,14 +769,21 @@ CloseApplication(HWND hwnd) && ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_SERVICE_ACTIVE_EXIT) == IDNO) return; + /* Show a message if any non-persistent connections are active */ for (i = 0; i < o.num_configs; i++) { - if (o.conn[i].state == disconnected) + if (o.conn[i].state == disconnected + || o.conn[i].flags & FLAG_DAEMON_PERSISTENT) + { continue; + } /* Ask for confirmation if still connected */ if (ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_ACTIVE_CONN_EXIT) == IDNO) + { return; + } + break; /* show the above message box only once */ } DestroyWindow(hwnd); diff --git a/main.h b/main.h index bd2ac89..ea9970c 100644 --- a/main.h +++ b/main.h @@ -58,10 +58,12 @@ #define WM_OVPN_NOTIFY (WM_APP + 16) #define WM_OVPN_EXIT (WM_APP + 17) #define WM_OVPN_SILENT (WM_APP + 18) +#define WM_OVPN_RELEASE (WM_APP + 19) #define WM_OVPN_IMPORT (WM_APP + 20) #define WM_OVPN_RESCAN (WM_APP + 21) #define WM_OVPN_ECHOMSG (WM_APP + 22) #define WM_OVPN_STATE (WM_APP + 23) +#define WM_OVPN_DETACH (WM_APP + 24) /* bool definitions */ #define bool int diff --git a/manage.c b/manage.c index 6ca6b21..be9c8d5 100644 --- a/manage.c +++ b/manage.c @@ -204,8 +204,12 @@ OnManagement(SOCKET sk, LPARAM lParam) case FD_CONNECT: if (WSAGETSELECTERROR(lParam)) { - if (time(NULL) < c->manage.timeout) + /* keep trying for connections with persistent daemons */ + if (c->flags & FLAG_DAEMON_PERSISTENT + || time(NULL) < c->manage.timeout) + { connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); + } else { /* Connection to MI timed out. */ diff --git a/openvpn-gui-res.h b/openvpn-gui-res.h index 62319ff..6674eb1 100644 --- a/openvpn-gui-res.h +++ b/openvpn-gui-res.h @@ -248,6 +248,7 @@ #define IDS_NFO_CONFIG_AUTH_PENDING 1256 #define IDS_ERR_ADD_USER_TO_ADMIN_GROUP 1257 #define IDS_NFO_BYTECOUNT 1258 +#define IDS_NFO_STATE_ONHOLD 1259 /* Program Startup Related */ #define IDS_ERR_OPEN_DEBUG_FILE 1301 diff --git a/openvpn.c b/openvpn.c index a0b414b..c11d542 100644 --- a/openvpn.c +++ b/openvpn.c @@ -121,6 +121,9 @@ OnReady(connection_t *c, UNUSED char *msg) ManagementCommand(c, "log on all", OnLogLine, combined); ManagementCommand(c, "echo on all", OnEcho, combined); ManagementCommand(c, "bytecount 5", NULL, regular); + + /* ask for the current state, especially useful when the daemon was prestarted */ + ManagementCommand(c, "state", OnStateChange, regular); } @@ -130,6 +133,19 @@ OnReady(connection_t *c, UNUSED char *msg) void OnHold(connection_t *c, UNUSED char *msg) { + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), TRUE); + if ((c->flags & FLAG_DAEMON_PERSISTENT) && (c->state == disconnecting)) + { + /* retain the hold state if we are here while disconnecting */ + c->state = onhold; + SetMenuStatus(c, onhold); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_ONHOLD)); + SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED); + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + CheckAndSetTrayIcon(); + return; + } + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), TRUE); ManagementCommand(c, "hold off", NULL, regular); ManagementCommand(c, "hold release", NULL, regular); } @@ -296,8 +312,11 @@ OnStateChange(connection_t *c, char *data) LoadLocalizedStringBuf(ip_txt, _countof(ip_txt), IDS_NFO_ASSIGN_IP, ip); /* Run Connect Script */ - if (c->state == connecting || c->state == resuming) + if (!(c->flags & FLAG_DAEMON_PERSISTENT) + && (c->state == connecting || c->state == resuming)) + { RunConnectScript(c, false); + } /* Show connection tray balloon */ if ((c->state == connecting && o.show_balloon != 0) @@ -1319,6 +1338,7 @@ OnStop(connection_t *c, UNUSED char *msg) c->failed_auth_attempts = 0; c->state = disconnected; CheckAndSetTrayIcon(); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED)); SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); break; @@ -1753,6 +1773,44 @@ OnNeedStr (connection_t *c, UNUSED char *msg) WriteStatusLog (c, L"GUI> ", L"Error: Received NEED-STR message -- not implemented", false); } +/* Parse the management port and password of a + * a running daemon -- useful when the daemon is externally + * started (persistent) and we need to use the cached + * management interface address parameters to connect to it. + */ +static BOOL +ParseManagementAddress(connection_t *c) +{ + /* Not implemented */ + return false; +} + +/* Stop the connection -- this sets the daemon to exit if + * started by us, else instructs the daemon to disconnect and + * and wait. + */ +static void +DisconnectDaemon(connection_t *c) +{ + if (c->flags & FLAG_DAEMON_PERSISTENT) + { + if (c->manage.connected) + { + ManagementCommand(c, "hold on", NULL, regular); + ManagementCommand(c, "signal SIGHUP", NULL, regular); + } + else + { + OnStop(c, NULL); + } + } + else + { + SetEvent(c->exit_event); + SetTimer(c->hwndStatus, IDT_STOP_TIMER, 15000, NULL); + } +} + /* * Close open handles */ @@ -1889,7 +1947,6 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) return TRUE; case ID_RESTART: - c->state = reconnecting; SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); RestartOpenVPN(c); return TRUE; @@ -1921,19 +1978,42 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) PostQuitMessage(0); break; + case WM_OVPN_RELEASE: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + c->state = reconnecting; + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING)); + SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L""); + SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING); + OnHold(c, ""); + break; + case WM_OVPN_STOP: c = (connection_t *) GetProp(hwndDlg, cfgProp); /* external messages can trigger when we are not ready -- check the state */ - if (!IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_DISCONNECT))) + if (!IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_DISCONNECT)) + || c->state == onhold) + { break; + } c->state = disconnecting; - RunDisconnectScript(c, false); + if (!(c->flags & FLAG_DAEMON_PERSISTENT)) + { + RunDisconnectScript(c, false); + } EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); SetMenuStatus(c, disconnecting); SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM)); - SetEvent(c->exit_event); - SetTimer(hwndDlg, IDT_STOP_TIMER, 15000, NULL); + DisconnectDaemon(c); + break; + + case WM_OVPN_DETACH: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + /* just stop the thread keeping openvpn.exe running */ + c->state = disconnecting; + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); + OnStop(c, NULL); break; case WM_OVPN_SUSPEND: @@ -1962,7 +2042,13 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) c = (connection_t *) GetProp(hwndDlg, cfgProp); /* external messages can trigger when we are not ready -- check the state */ if (IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_RESTART))) + { + c->state = reconnecting; ManagementCommand(c, "signal SIGHUP", NULL, regular); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING)); + SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L""); + SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING); + } if (!o.silent_connection) { SetForegroundWindow(c->hwndStatus); @@ -2037,7 +2123,21 @@ ThreadOpenVPNStatus(void *p) while (WM_QUIT != msg.message) { DWORD res; - if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + if (wait_event == NULL) /* for persistent connections there is no wait_event */ + { + res = GetMessage(&msg, NULL, 0, 0); + if (res == (DWORD) -1) /* log the error and continue */ + { + MsgToEventLog(EVENTLOG_WARNING_TYPE, L"GetMessage for <%ls> returned error (status=%lu)", + c->config_name, GetLastError()); + continue; + } + else if (res == 0) /* WM_QUIT */ + { + break; + } + } + else if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if ((res = MsgWaitForMultipleObjectsEx (1, &wait_event, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE)) == WAIT_OBJECT_0) @@ -2140,6 +2240,17 @@ out: } #endif +/* If state is on hold -- release */ +void +ReleaseOpenVPN(connection_t *c) +{ + if (c->state != onhold) + { + return; + } + PostMessage(c->hwndStatus, WM_OVPN_RELEASE, 0, 0); +} + /* Start a thread to monitor a connection and launch openvpn.exe if required */ BOOL StartOpenVPN(connection_t *c) @@ -2148,6 +2259,11 @@ StartOpenVPN(connection_t *c) if (c->hwndStatus) { + if (c->state == onhold) + { + ReleaseOpenVPN(c); + return true; + } PrintDebug(L"Connection request when already started -- ignored"); /* the tread can hang around after disconnect if user has not dismissed any popups */ if (c->state == disconnected) @@ -2175,8 +2291,16 @@ StartOpenVPN(connection_t *c) return false; } + if (c->flags & FLAG_DAEMON_PERSISTENT) + { + if (!ParseManagementAddress(c)) + { + TerminateThread(hThread, 1); + return false; + } + } /* Launch openvpn.exe using the service or directly */ - if (!LaunchOpenVPN(c)) + else if (!LaunchOpenVPN(c)) { TerminateThread(hThread, 1); return false; @@ -2388,6 +2512,20 @@ out: } +/* Close the status thread without disconnecting the tunnel. + * Meant to be used only on persistent connections which can + * stay connected without the GUI tending to it. + */ +void +DetachOpenVPN(connection_t *c) +{ + /* currently supported only for persistent connections */ + if (c->flags & FLAG_DAEMON_PERSISTENT) + { + PostMessage(c->hwndStatus, WM_OVPN_DETACH, 0, 0); + } +} + void StopOpenVPN(connection_t *c) { @@ -2431,10 +2569,18 @@ SuspendOpenVPN(int config) void RestartOpenVPN(connection_t *c) { - if (c->hwndStatus) + if (c->state == onhold) + { + ReleaseOpenVPN(c); + } + else if (c->hwndStatus) + { PostMessage(c->hwndStatus, WM_OVPN_RESTART, 0, 0); + } else /* Not started: treat this as a request to connect */ + { StartOpenVPN(c); + } } void diff --git a/openvpn.h b/openvpn.h index 8222a7e..a989ec0 100644 --- a/openvpn.h +++ b/openvpn.h @@ -27,8 +27,10 @@ BOOL StartOpenVPN(connection_t *); void StopOpenVPN(connection_t *); +void DetachOpenVPN(connection_t *); void SuspendOpenVPN(int config); void RestartOpenVPN(connection_t *); +void ReleaseOpenVPN(connection_t *); BOOL CheckVersion(); void SetStatusWinIcon(HWND hwndDlg, int IconID); diff --git a/options.h b/options.h index 5761655..c5fcf45 100644 --- a/options.h +++ b/options.h @@ -65,6 +65,7 @@ typedef enum { /* connection states */ typedef enum { disconnected, + onhold, connecting, reconnecting, connected, @@ -87,6 +88,7 @@ typedef struct { #define FLAG_SAVE_AUTH_PASS (1<<5) #define FLAG_DISABLE_SAVE_PASS (1<<6) #define FLAG_DISABLE_ECHO_MSG (1<<7) +#define FLAG_DAEMON_PERSISTENT (1<<8) #define CONFIG_VIEW_AUTO (0) #define CONFIG_VIEW_FLAT (1) diff --git a/res/openvpn-gui-res-cs.rc b/res/openvpn-gui-res-cs.rc index 4845e61..01b6d82 100644 --- a/res/openvpn-gui-res-cs.rc +++ b/res/openvpn-gui-res-cs.rc @@ -359,6 +359,7 @@ Prosím dokončete předchozí autorizační dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread k zobrazení stavu selhal." IDS_NFO_STATE_WAIT_TERM "Aktuální stav: Čekání, než se OpenVPN ukončí…" IDS_NFO_STATE_CONNECTED "Aktuální stav: Připojeno" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls je nyní připojeno." IDS_NFO_ASSIGN_IP "Přiřazená IP: %ls" IDS_ERR_CERT_EXPIRED "Spojení nelze navázat, protože certifikát expiroval, nebo není správně nastaven systémový čas." diff --git a/res/openvpn-gui-res-de.rc b/res/openvpn-gui-res-de.rc index 892e032..d76451b 100644 --- a/res/openvpn-gui-res-de.rc +++ b/res/openvpn-gui-res-de.rc @@ -361,6 +361,7 @@ Bitte vervollständigen Sie den vorhergehenden Autorisierungsdialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread zum Anzeigen des Status-Fensters ist fehlgeschlagen." IDS_NFO_STATE_WAIT_TERM "Aktueller Status: Wartet bis OpenVPN beendet ist…" IDS_NFO_STATE_CONNECTED "Aktueller Status: Verbunden" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls ist nun verbunden." IDS_NFO_ASSIGN_IP "Zugewiesene IP: %ls" IDS_ERR_CERT_EXPIRED "Es konnte keine Verbindung hergestellt werden, weil Ihr Zertifikat abgelaufen ist oder die Systemzeit nicht korrekt eingestellt ist." diff --git a/res/openvpn-gui-res-dk.rc b/res/openvpn-gui-res-dk.rc index 3f18e22..7cb8ffd 100644 --- a/res/openvpn-gui-res-dk.rc +++ b/res/openvpn-gui-res-dk.rc @@ -359,6 +359,7 @@ Please complete the previous authorization dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread for at vise statusvindue fejlramt." IDS_NFO_STATE_WAIT_TERM "Status: Venter på OpenVPN afslutning…" IDS_NFO_STATE_CONNECTED "Status: Forbundet" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls er forbundet." IDS_NFO_ASSIGN_IP "tildelt IP: %ls" IDS_ERR_CERT_EXPIRED "Kunne ikke forbinde, dit certifikat er for gammelt eller uret på din PC er forkert." diff --git a/res/openvpn-gui-res-en.rc b/res/openvpn-gui-res-en.rc index 8e7ffc3..1d80a41 100644 --- a/res/openvpn-gui-res-en.rc +++ b/res/openvpn-gui-res-en.rc @@ -373,6 +373,7 @@ Please complete the previous authorization dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_NFO_STATE_WAIT_TERM "Current State: Waiting for OpenVPN to terminate…" IDS_NFO_STATE_CONNECTED "Current State: Connected" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls is now connected." IDS_NFO_ASSIGN_IP "Assigned IP: %ls" IDS_ERR_CERT_EXPIRED "Unable to connect because your certificate has expired or the system time is incorrect." diff --git a/res/openvpn-gui-res-es.rc b/res/openvpn-gui-res-es.rc index ac15b64..7f29c66 100644 --- a/res/openvpn-gui-res-es.rc +++ b/res/openvpn-gui-res-es.rc @@ -357,6 +357,7 @@ Please complete the previous authorization dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread para mostrar la Ventana de Estado fallido." IDS_NFO_STATE_WAIT_TERM "Estado actual: Esperando que OpenVPN termine…" IDS_NFO_STATE_CONNECTED "Estado actual: Conectado." + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "Conectado a %ls." IDS_NFO_ASSIGN_IP "IP asignada: %ls" IDS_ERR_CERT_EXPIRED "Imposible conectar porque su certificado ha expirado o la hora del sistema no es correcta." diff --git a/res/openvpn-gui-res-fa.rc b/res/openvpn-gui-res-fa.rc index c370813..436f484 100644 --- a/res/openvpn-gui-res-fa.rc +++ b/res/openvpn-gui-res-fa.rc @@ -361,6 +361,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "ایجاد موضوع برای نمایش پنجره وضعیت ناموفق بود." IDS_NFO_STATE_WAIT_TERM "وضعیت اخیر: منتظر OpenVPN برای پایان دادن…" IDS_NFO_STATE_CONNECTED "وضعیت اخیر: متصل" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls متصل است." IDS_NFO_ASSIGN_IP "ّIP اختصاص داده شده: %ls" IDS_ERR_CERT_EXPIRED "اتصال امکان پذیر نیست زیرا گواهی شما منقضی شده است یا زمان سیستم نادرست است." diff --git a/res/openvpn-gui-res-fi.rc b/res/openvpn-gui-res-fi.rc index f4b3647..d8e8086 100644 --- a/res/openvpn-gui-res-fi.rc +++ b/res/openvpn-gui-res-fi.rc @@ -358,6 +358,7 @@ Ole hyvä ja suorita aiempi varmennus loppuun." IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_NFO_STATE_WAIT_TERM "Tila: odotetaan OpenVPN:n sammumista…" IDS_NFO_STATE_CONNECTED "Tila: yhdistetty" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls on nyt yhdistetty." IDS_NFO_ASSIGN_IP "IP-osoite: %ls" IDS_ERR_CERT_EXPIRED "Yhdistäminen epäonnistui, koska varmenne on vanhentunut tai tietokoneen kello on väärässä ajassa." diff --git a/res/openvpn-gui-res-fr.rc b/res/openvpn-gui-res-fr.rc index 6fc6121..a2ce81f 100644 --- a/res/openvpn-gui-res-fr.rc +++ b/res/openvpn-gui-res-fr.rc @@ -358,6 +358,7 @@ Veuillez compléter la boîte de dialogue d'autorisation précédente." IDS_ERR_CREATE_THREAD_STATUS "CreateThread échoué pour afficher la fenêtre de statut." IDS_NFO_STATE_WAIT_TERM "Etat actuel: Attente que OpenVPN se termine…" IDS_NFO_STATE_CONNECTED "Etat actuel: Connecté" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls est désormais connecté." IDS_NFO_ASSIGN_IP "Adresse IP assignée: %ls" IDS_ERR_CERT_EXPIRED "Connexion impossible car votre certificat a expiré ou la date de votre système est incorrecte." diff --git a/res/openvpn-gui-res-it.rc b/res/openvpn-gui-res-it.rc index 2372ced..df829e2 100644 --- a/res/openvpn-gui-res-it.rc +++ b/res/openvpn-gui-res-it.rc @@ -358,6 +358,7 @@ Completa la richiesta di autorizzazione precedente." IDS_ERR_CREATE_THREAD_STATUS "CreateThread fallito per visualizzare lo stato." IDS_NFO_STATE_WAIT_TERM "Stato corrente: In attesa che OpenVPN termini…" IDS_NFO_STATE_CONNECTED "Stato corrente: Connesso" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls è ora connesso." IDS_NFO_ASSIGN_IP "IP assegnato: %ls" IDS_ERR_CERT_EXPIRED "Non riesco a connettermi perché il tuo certificato è scaduto o l'orologio di sistema non è corretto." diff --git a/res/openvpn-gui-res-jp.rc b/res/openvpn-gui-res-jp.rc index f79fee4..690b583 100644 --- a/res/openvpn-gui-res-jp.rc +++ b/res/openvpn-gui-res-jp.rc @@ -359,6 +359,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_NFO_STATE_WAIT_TERM "現在の状況: OpenVPNの終了を待機中..." IDS_NFO_STATE_CONNECTED "現在の状況: 接続済み" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls に接続しました。" IDS_NFO_ASSIGN_IP "割り当てられたIP: %ls" IDS_ERR_CERT_EXPIRED "証明書の期限が切れているかシステム時刻が正しくないため、接続できません。" diff --git a/res/openvpn-gui-res-kr.rc b/res/openvpn-gui-res-kr.rc index 9b5dffa..4b585da 100644 --- a/res/openvpn-gui-res-kr.rc +++ b/res/openvpn-gui-res-kr.rc @@ -357,6 +357,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_NFO_STATE_WAIT_TERM "현재 상태: OpenVPN 종료 대기 중…" IDS_NFO_STATE_CONNECTED "현재 상태: 연결됨" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls 접속이 연결 되었습니다." IDS_NFO_ASSIGN_IP "할당된 IP: %ls" IDS_ERR_CERT_EXPIRED "인증서가 만료 되었거나, 시스템 시간이 잘못 설정 되어 연결할 수 없습니다." diff --git a/res/openvpn-gui-res-nl.rc b/res/openvpn-gui-res-nl.rc index 7a0e6c9..abad94a 100644 --- a/res/openvpn-gui-res-nl.rc +++ b/res/openvpn-gui-res-nl.rc @@ -359,6 +359,7 @@ Vul het voorgaande autorisatiescherm volledig in." IDS_ERR_CREATE_THREAD_STATUS "CreateThread om Statusvenster te tonen mislukt." IDS_NFO_STATE_WAIT_TERM "Huidige status: Wachten tot OpenVPN gestopt is…" IDS_NFO_STATE_CONNECTED "Huidige status: Verbonden" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls is nu verbonden." IDS_NFO_ASSIGN_IP "Toegewezen IP: %ls" IDS_ERR_CERT_EXPIRED "Kan geen verbinding maken, het certificaat is vervallen. Controleer eventueel de systeemtijd." diff --git a/res/openvpn-gui-res-no.rc b/res/openvpn-gui-res-no.rc index d2e4a8b..ba79bd5 100644 --- a/res/openvpn-gui-res-no.rc +++ b/res/openvpn-gui-res-no.rc @@ -356,6 +356,7 @@ Please complete the previous authorization dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread for å vise statusvindu feilet." IDS_NFO_STATE_WAIT_TERM "Status: Venter på at OpenVPN stopper…" IDS_NFO_STATE_CONNECTED "Status: Tilkoblet" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls er tilkoblet." IDS_NFO_ASSIGN_IP "Tildelt IP: %ls" IDS_ERR_CERT_EXPIRED "Kunne ikke koble til. Sertifikatet er ikke lenger gyldig. Eventuelt kan klokken på datamaskinen din gå feil." diff --git a/res/openvpn-gui-res-pl.rc b/res/openvpn-gui-res-pl.rc index d5da177..332a623 100644 --- a/res/openvpn-gui-res-pl.rc +++ b/res/openvpn-gui-res-pl.rc @@ -359,6 +359,7 @@ Proszę uzupełnić poprzednie okno autoryzacji." IDS_ERR_CREATE_THREAD_STATUS "Utworzenie wątku dla okna statusu zakończone niepowodzeniem." IDS_NFO_STATE_WAIT_TERM "Stan obecny: Oczekiwanie na zakończenie OpenVPN-a…" IDS_NFO_STATE_CONNECTED "Stan obecny: Połączony" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls jest teraz połączony." IDS_NFO_ASSIGN_IP "Przyznany IP: %ls" IDS_ERR_CERT_EXPIRED "Połączenie nie jest możliwe z powodu wygaśnięcia certyfikatu lub błędnie ustawionego czasu systemowego." diff --git a/res/openvpn-gui-res-pt.rc b/res/openvpn-gui-res-pt.rc index 12e2b04..89f0c5e 100644 --- a/res/openvpn-gui-res-pt.rc +++ b/res/openvpn-gui-res-pt.rc @@ -357,6 +357,7 @@ Por favor, complete o diálogo de autorização anterior." IDS_ERR_CREATE_THREAD_STATUS "CreateThread falhou ao mostrar janela de status." IDS_NFO_STATE_WAIT_TERM "Estado atual: Aguardando OpenVPN terminar…" IDS_NFO_STATE_CONNECTED "Estado atual: Conectado" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls está conectado." IDS_NFO_ASSIGN_IP "IP atribuído: %ls" IDS_ERR_CERT_EXPIRED "Impossível conectar porque seu certificado expirou ou a data do sistema está incorreta." diff --git a/res/openvpn-gui-res-ru.rc b/res/openvpn-gui-res-ru.rc index 4a4608c..314736a 100644 --- a/res/openvpn-gui-res-ru.rc +++ b/res/openvpn-gui-res-ru.rc @@ -360,6 +360,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "Ошибка выполнения CreateThread при отображении окна состояния." IDS_NFO_STATE_WAIT_TERM "Текущее состояние: ожидание завершения работы OpenVPN…" IDS_NFO_STATE_CONNECTED "Текущее состояние: подключено" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls сейчас подключено." IDS_NFO_ASSIGN_IP "Назначенный IP: %ls" IDS_ERR_CERT_EXPIRED "Невозможно подключиться, так как срок действия вашего сертификата истёк или системное время некорректно." diff --git a/res/openvpn-gui-res-se.rc b/res/openvpn-gui-res-se.rc index 658b19e..41ed2ca 100644 --- a/res/openvpn-gui-res-se.rc +++ b/res/openvpn-gui-res-se.rc @@ -357,6 +357,7 @@ Please complete the previous authorization dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread för att visa status fönstret misslyckades." IDS_NFO_STATE_WAIT_TERM "Status: Väntar på att OpenVPN skall avslutas…" IDS_NFO_STATE_CONNECTED "Status: Ansluten" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls är nu ansluten." IDS_NFO_ASSIGN_IP "Tilldelad IP: %ls" IDS_ERR_CERT_EXPIRED "Kunde inte ansluta för att ditt certifikat är för gammalt, eller för att klockan i din dator går fel." diff --git a/res/openvpn-gui-res-tr.rc b/res/openvpn-gui-res-tr.rc index 253f006..f19cdb7 100644 --- a/res/openvpn-gui-res-tr.rc +++ b/res/openvpn-gui-res-tr.rc @@ -359,6 +359,7 @@ Please complete the previous authorization dialog." IDS_ERR_CREATE_THREAD_STATUS "CreateThread anında durum penceresi gösterilemedi hatası." IDS_NFO_STATE_WAIT_TERM "Geçerli Durum: OpenVPN' in kapanması bekleniyor…" IDS_NFO_STATE_CONNECTED "Geçerli Durum: Bağlandı" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls şu an bağlı." IDS_NFO_ASSIGN_IP "Atanan IP: %ls" IDS_ERR_CERT_EXPIRED "Sertifikanız veya sistem tarih/zaman ayarlarınız geçersiz olduğundan bağlantı sağlanamadı." diff --git a/res/openvpn-gui-res-ua.rc b/res/openvpn-gui-res-ua.rc index 15bac69..3cd5f4b 100644 --- a/res/openvpn-gui-res-ua.rc +++ b/res/openvpn-gui-res-ua.rc @@ -359,6 +359,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "Робоча помилка CreateThread, а саме у час відображення вікна статусу." IDS_NFO_STATE_WAIT_TERM "У цей час статус: очікування зупинки роботи OpenVPN…" IDS_NFO_STATE_CONNECTED "У цей час статус: підключено." + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "%ls зараз підключено." IDS_NFO_ASSIGN_IP "Отримано IP: %ls" IDS_ERR_CERT_EXPIRED "Неможливо з'єднатися, бо час дії вашого сертифікату минув або системний час некорректний." diff --git a/res/openvpn-gui-res-zh-hans.rc b/res/openvpn-gui-res-zh-hans.rc index 35811dd..c91c0c7 100644 --- a/res/openvpn-gui-res-zh-hans.rc +++ b/res/openvpn-gui-res-zh-hans.rc @@ -361,6 +361,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "CreateThread 显示状态窗口时失败。" IDS_NFO_STATE_WAIT_TERM "当前状态: 等待中止 OpenVPN…" IDS_NFO_STATE_CONNECTED "当前状态: 已连接" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "已连接至 %ls。" IDS_NFO_ASSIGN_IP "分配 IP: %ls" IDS_ERR_CERT_EXPIRED "您的证书已过期,或是系统时间不正确,无法连接。" diff --git a/res/openvpn-gui-res-zh-hant.rc b/res/openvpn-gui-res-zh-hant.rc index 39eb643..7024413 100644 --- a/res/openvpn-gui-res-zh-hant.rc +++ b/res/openvpn-gui-res-zh-hant.rc @@ -361,6 +361,7 @@ BEGIN IDS_ERR_CREATE_THREAD_STATUS "CreateThread 以顯示狀態視窗時失敗。" IDS_NFO_STATE_WAIT_TERM "目前狀態: 等待中止 OpenVPN…" IDS_NFO_STATE_CONNECTED "目前狀態: 已連線" + IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)" IDS_NFO_NOW_CONNECTED "已連線至 %ls。" IDS_NFO_ASSIGN_IP "配發 IP: %ls" IDS_ERR_CERT_EXPIRED "您的憑證已過期,或是系統時間不正確,無法連線。" diff --git a/tray.c b/tray.c index bda59ec..fa8861d 100644 --- a/tray.c +++ b/tray.c @@ -576,6 +576,13 @@ SetMenuStatusById(int i, conn_state_t state) EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_GRAYED); EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED); } + else if (state == onhold) + { + EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_ENABLED); + EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED); + EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_ENABLED); + EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED); + } if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_ENABLED); else @@ -635,6 +642,13 @@ SetMenuStatusById(int i, conn_state_t state) EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU, MF_GRAYED); EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED); } + else if (state == onhold) + { + EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU, MF_ENABLED); + EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU, MF_GRAYED); + EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU, MF_ENABLED); + EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED); + } if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_ENABLED); else