Add support for marking connections as persistent

Persistent connections have openvpn.exe daemon started
external to the GUI (e.g., by the automatic service).
This patch adds support for attaching to the management
i/f of such daemons from the GUI and control the connection.

The GUI never stops or starts the openvpn.exe process in this
case. Instead, connect and disconnect buttons signal the
management interface of a running openvpn.exe process to start
the tunnel by attaching to mgmt i/f and sending hold-release if
needed  or stop it and wait in management-hold state
(see DisconnectDaemon()).

When the GUI process exits, persistent connections are left in their
current state using DetachOpenVPN().

No connections are marked as persistent as yet. That is done
in a following commit.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/519/head
Selva Nair 2022-07-03 16:30:31 -04:00
parent f8a1495667
commit 428ee29246
29 changed files with 224 additions and 12 deletions

24
main.c
View File

@ -351,10 +351,23 @@ StopAllOpenVPN()
{ {
int i; 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++) for (i = 0; i < o.num_configs; i++)
{ {
if (o.conn[i].state != disconnected) 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) */ /* 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) && ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_SERVICE_ACTIVE_EXIT) == IDNO)
return; return;
/* Show a message if any non-persistent connections are active */
for (i = 0; i < o.num_configs; i++) 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; continue;
}
/* Ask for confirmation if still connected */ /* Ask for confirmation if still connected */
if (ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_ACTIVE_CONN_EXIT) == IDNO) if (ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_ACTIVE_CONN_EXIT) == IDNO)
{
return; return;
}
break; /* show the above message box only once */
} }
DestroyWindow(hwnd); DestroyWindow(hwnd);

2
main.h
View File

@ -58,10 +58,12 @@
#define WM_OVPN_NOTIFY (WM_APP + 16) #define WM_OVPN_NOTIFY (WM_APP + 16)
#define WM_OVPN_EXIT (WM_APP + 17) #define WM_OVPN_EXIT (WM_APP + 17)
#define WM_OVPN_SILENT (WM_APP + 18) #define WM_OVPN_SILENT (WM_APP + 18)
#define WM_OVPN_RELEASE (WM_APP + 19)
#define WM_OVPN_IMPORT (WM_APP + 20) #define WM_OVPN_IMPORT (WM_APP + 20)
#define WM_OVPN_RESCAN (WM_APP + 21) #define WM_OVPN_RESCAN (WM_APP + 21)
#define WM_OVPN_ECHOMSG (WM_APP + 22) #define WM_OVPN_ECHOMSG (WM_APP + 22)
#define WM_OVPN_STATE (WM_APP + 23) #define WM_OVPN_STATE (WM_APP + 23)
#define WM_OVPN_DETACH (WM_APP + 24)
/* bool definitions */ /* bool definitions */
#define bool int #define bool int

View File

@ -204,8 +204,12 @@ OnManagement(SOCKET sk, LPARAM lParam)
case FD_CONNECT: case FD_CONNECT:
if (WSAGETSELECTERROR(lParam)) 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)); connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr));
}
else else
{ {
/* Connection to MI timed out. */ /* Connection to MI timed out. */

View File

@ -248,6 +248,7 @@
#define IDS_NFO_CONFIG_AUTH_PENDING 1256 #define IDS_NFO_CONFIG_AUTH_PENDING 1256
#define IDS_ERR_ADD_USER_TO_ADMIN_GROUP 1257 #define IDS_ERR_ADD_USER_TO_ADMIN_GROUP 1257
#define IDS_NFO_BYTECOUNT 1258 #define IDS_NFO_BYTECOUNT 1258
#define IDS_NFO_STATE_ONHOLD 1259
/* Program Startup Related */ /* Program Startup Related */
#define IDS_ERR_OPEN_DEBUG_FILE 1301 #define IDS_ERR_OPEN_DEBUG_FILE 1301

164
openvpn.c
View File

@ -121,6 +121,9 @@ OnReady(connection_t *c, UNUSED char *msg)
ManagementCommand(c, "log on all", OnLogLine, combined); ManagementCommand(c, "log on all", OnLogLine, combined);
ManagementCommand(c, "echo on all", OnEcho, combined); ManagementCommand(c, "echo on all", OnEcho, combined);
ManagementCommand(c, "bytecount 5", NULL, regular); 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 void
OnHold(connection_t *c, UNUSED char *msg) 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 off", NULL, regular);
ManagementCommand(c, "hold release", 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); LoadLocalizedStringBuf(ip_txt, _countof(ip_txt), IDS_NFO_ASSIGN_IP, ip);
/* Run Connect Script */ /* 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); RunConnectScript(c, false);
}
/* Show connection tray balloon */ /* Show connection tray balloon */
if ((c->state == connecting && o.show_balloon != 0) 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->failed_auth_attempts = 0;
c->state = disconnected; c->state = disconnected;
CheckAndSetTrayIcon(); CheckAndSetTrayIcon();
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED));
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
break; 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); 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 * Close open handles
*/ */
@ -1889,7 +1947,6 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
return TRUE; return TRUE;
case ID_RESTART: case ID_RESTART:
c->state = reconnecting;
SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
RestartOpenVPN(c); RestartOpenVPN(c);
return TRUE; return TRUE;
@ -1921,19 +1978,42 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
PostQuitMessage(0); PostQuitMessage(0);
break; 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: case WM_OVPN_STOP:
c = (connection_t *) GetProp(hwndDlg, cfgProp); c = (connection_t *) GetProp(hwndDlg, cfgProp);
/* external messages can trigger when we are not ready -- check the state */ /* 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; break;
}
c->state = disconnecting; 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_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE);
SetMenuStatus(c, disconnecting); SetMenuStatus(c, disconnecting);
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM)); SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM));
SetEvent(c->exit_event); DisconnectDaemon(c);
SetTimer(hwndDlg, IDT_STOP_TIMER, 15000, NULL); 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; break;
case WM_OVPN_SUSPEND: case WM_OVPN_SUSPEND:
@ -1962,7 +2042,13 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
c = (connection_t *) GetProp(hwndDlg, cfgProp); c = (connection_t *) GetProp(hwndDlg, cfgProp);
/* external messages can trigger when we are not ready -- check the state */ /* external messages can trigger when we are not ready -- check the state */
if (IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_RESTART))) if (IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_RESTART)))
{
c->state = reconnecting;
ManagementCommand(c, "signal SIGHUP", NULL, regular); 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) if (!o.silent_connection)
{ {
SetForegroundWindow(c->hwndStatus); SetForegroundWindow(c->hwndStatus);
@ -2037,7 +2123,21 @@ ThreadOpenVPNStatus(void *p)
while (WM_QUIT != msg.message) while (WM_QUIT != msg.message)
{ {
DWORD res; 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, if ((res = MsgWaitForMultipleObjectsEx (1, &wait_event, INFINITE, QS_ALLINPUT,
MWMO_ALERTABLE)) == WAIT_OBJECT_0) MWMO_ALERTABLE)) == WAIT_OBJECT_0)
@ -2140,6 +2240,17 @@ out:
} }
#endif #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 */ /* Start a thread to monitor a connection and launch openvpn.exe if required */
BOOL BOOL
StartOpenVPN(connection_t *c) StartOpenVPN(connection_t *c)
@ -2148,6 +2259,11 @@ StartOpenVPN(connection_t *c)
if (c->hwndStatus) if (c->hwndStatus)
{ {
if (c->state == onhold)
{
ReleaseOpenVPN(c);
return true;
}
PrintDebug(L"Connection request when already started -- ignored"); PrintDebug(L"Connection request when already started -- ignored");
/* the tread can hang around after disconnect if user has not dismissed any popups */ /* the tread can hang around after disconnect if user has not dismissed any popups */
if (c->state == disconnected) if (c->state == disconnected)
@ -2175,8 +2291,16 @@ StartOpenVPN(connection_t *c)
return false; return false;
} }
if (c->flags & FLAG_DAEMON_PERSISTENT)
{
if (!ParseManagementAddress(c))
{
TerminateThread(hThread, 1);
return false;
}
}
/* Launch openvpn.exe using the service or directly */ /* Launch openvpn.exe using the service or directly */
if (!LaunchOpenVPN(c)) else if (!LaunchOpenVPN(c))
{ {
TerminateThread(hThread, 1); TerminateThread(hThread, 1);
return false; 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 void
StopOpenVPN(connection_t *c) StopOpenVPN(connection_t *c)
{ {
@ -2431,10 +2569,18 @@ SuspendOpenVPN(int config)
void void
RestartOpenVPN(connection_t *c) 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); PostMessage(c->hwndStatus, WM_OVPN_RESTART, 0, 0);
}
else /* Not started: treat this as a request to connect */ else /* Not started: treat this as a request to connect */
{
StartOpenVPN(c); StartOpenVPN(c);
}
} }
void void

View File

@ -27,8 +27,10 @@
BOOL StartOpenVPN(connection_t *); BOOL StartOpenVPN(connection_t *);
void StopOpenVPN(connection_t *); void StopOpenVPN(connection_t *);
void DetachOpenVPN(connection_t *);
void SuspendOpenVPN(int config); void SuspendOpenVPN(int config);
void RestartOpenVPN(connection_t *); void RestartOpenVPN(connection_t *);
void ReleaseOpenVPN(connection_t *);
BOOL CheckVersion(); BOOL CheckVersion();
void SetStatusWinIcon(HWND hwndDlg, int IconID); void SetStatusWinIcon(HWND hwndDlg, int IconID);

View File

@ -65,6 +65,7 @@ typedef enum {
/* connection states */ /* connection states */
typedef enum { typedef enum {
disconnected, disconnected,
onhold,
connecting, connecting,
reconnecting, reconnecting,
connected, connected,
@ -87,6 +88,7 @@ typedef struct {
#define FLAG_SAVE_AUTH_PASS (1<<5) #define FLAG_SAVE_AUTH_PASS (1<<5)
#define FLAG_DISABLE_SAVE_PASS (1<<6) #define FLAG_DISABLE_SAVE_PASS (1<<6)
#define FLAG_DISABLE_ECHO_MSG (1<<7) #define FLAG_DISABLE_ECHO_MSG (1<<7)
#define FLAG_DAEMON_PERSISTENT (1<<8)
#define CONFIG_VIEW_AUTO (0) #define CONFIG_VIEW_AUTO (0)
#define CONFIG_VIEW_FLAT (1) #define CONFIG_VIEW_FLAT (1)

View File

@ -359,6 +359,7 @@ Prosím dokončete předchozí autorizační dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread k zobrazení stavu selhal." 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_WAIT_TERM "Aktuální stav: Čekání, než se OpenVPN ukončí…"
IDS_NFO_STATE_CONNECTED "Aktuální stav: Připojeno" 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_NOW_CONNECTED "%ls je nyní připojeno."
IDS_NFO_ASSIGN_IP "Přiřazená IP: %ls" 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." IDS_ERR_CERT_EXPIRED "Spojení nelze navázat, protože certifikát expiroval, nebo není správně nastaven systémový čas."

View File

@ -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_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_WAIT_TERM "Aktueller Status: Wartet bis OpenVPN beendet ist…"
IDS_NFO_STATE_CONNECTED "Aktueller Status: Verbunden" 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_NOW_CONNECTED "%ls ist nun verbunden."
IDS_NFO_ASSIGN_IP "Zugewiesene IP: %ls" 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." IDS_ERR_CERT_EXPIRED "Es konnte keine Verbindung hergestellt werden, weil Ihr Zertifikat abgelaufen ist oder die Systemzeit nicht korrekt eingestellt ist."

View File

@ -359,6 +359,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread for at vise statusvindue fejlramt." IDS_ERR_CREATE_THREAD_STATUS "CreateThread for at vise statusvindue fejlramt."
IDS_NFO_STATE_WAIT_TERM "Status: Venter på OpenVPN afslutning…" IDS_NFO_STATE_WAIT_TERM "Status: Venter på OpenVPN afslutning…"
IDS_NFO_STATE_CONNECTED "Status: Forbundet" IDS_NFO_STATE_CONNECTED "Status: Forbundet"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls er forbundet." IDS_NFO_NOW_CONNECTED "%ls er forbundet."
IDS_NFO_ASSIGN_IP "tildelt IP: %ls" 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." IDS_ERR_CERT_EXPIRED "Kunne ikke forbinde, dit certifikat er for gammelt eller uret på din PC er forkert."

View File

@ -373,6 +373,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." 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_WAIT_TERM "Current State: Waiting for OpenVPN to terminate…"
IDS_NFO_STATE_CONNECTED "Current State: Connected" 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_NOW_CONNECTED "%ls is now connected."
IDS_NFO_ASSIGN_IP "Assigned IP: %ls" 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." IDS_ERR_CERT_EXPIRED "Unable to connect because your certificate has expired or the system time is incorrect."

View File

@ -357,6 +357,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread para mostrar la Ventana de Estado fallido." 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_WAIT_TERM "Estado actual: Esperando que OpenVPN termine…"
IDS_NFO_STATE_CONNECTED "Estado actual: Conectado." 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_NOW_CONNECTED "Conectado a %ls."
IDS_NFO_ASSIGN_IP "IP asignada: %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." IDS_ERR_CERT_EXPIRED "Imposible conectar porque su certificado ha expirado o la hora del sistema no es correcta."

View File

@ -361,6 +361,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "ایجاد موضوع برای نمایش پنجره وضعیت ناموفق بود." IDS_ERR_CREATE_THREAD_STATUS "ایجاد موضوع برای نمایش پنجره وضعیت ناموفق بود."
IDS_NFO_STATE_WAIT_TERM "وضعیت اخیر: منتظر OpenVPN برای پایان دادن…" IDS_NFO_STATE_WAIT_TERM "وضعیت اخیر: منتظر OpenVPN برای پایان دادن…"
IDS_NFO_STATE_CONNECTED "وضعیت اخیر: متصل" IDS_NFO_STATE_CONNECTED "وضعیت اخیر: متصل"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls متصل است." IDS_NFO_NOW_CONNECTED "%ls متصل است."
IDS_NFO_ASSIGN_IP "ّIP اختصاص داده شده: %ls" IDS_NFO_ASSIGN_IP "ّIP اختصاص داده شده: %ls"
IDS_ERR_CERT_EXPIRED "اتصال امکان پذیر نیست زیرا گواهی شما منقضی شده است یا زمان سیستم نادرست است." IDS_ERR_CERT_EXPIRED "اتصال امکان پذیر نیست زیرا گواهی شما منقضی شده است یا زمان سیستم نادرست است."

View File

@ -358,6 +358,7 @@ Ole hyvä ja suorita aiempi varmennus loppuun."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "Tila: odotetaan OpenVPN:n sammumista…" IDS_NFO_STATE_WAIT_TERM "Tila: odotetaan OpenVPN:n sammumista…"
IDS_NFO_STATE_CONNECTED "Tila: yhdistetty" 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_NOW_CONNECTED "%ls on nyt yhdistetty."
IDS_NFO_ASSIGN_IP "IP-osoite: %ls" 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." IDS_ERR_CERT_EXPIRED "Yhdistäminen epäonnistui, koska varmenne on vanhentunut tai tietokoneen kello on väärässä ajassa."

View File

@ -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_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_WAIT_TERM "Etat actuel: Attente que OpenVPN se termine…"
IDS_NFO_STATE_CONNECTED "Etat actuel: Connecté" 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_NOW_CONNECTED "%ls est désormais connecté."
IDS_NFO_ASSIGN_IP "Adresse IP assignée: %ls" 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." IDS_ERR_CERT_EXPIRED "Connexion impossible car votre certificat a expiré ou la date de votre système est incorrecte."

View File

@ -358,6 +358,7 @@ Completa la richiesta di autorizzazione precedente."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread fallito per visualizzare lo stato." 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_WAIT_TERM "Stato corrente: In attesa che OpenVPN termini…"
IDS_NFO_STATE_CONNECTED "Stato corrente: Connesso" 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_NOW_CONNECTED "%ls è ora connesso."
IDS_NFO_ASSIGN_IP "IP assegnato: %ls" 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." IDS_ERR_CERT_EXPIRED "Non riesco a connettermi perché il tuo certificato è scaduto o l'orologio di sistema non è corretto."

View File

@ -359,6 +359,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "現在の状況: OpenVPNの終了を待機中..." IDS_NFO_STATE_WAIT_TERM "現在の状況: OpenVPNの終了を待機中..."
IDS_NFO_STATE_CONNECTED "現在の状況: 接続済み" IDS_NFO_STATE_CONNECTED "現在の状況: 接続済み"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls に接続しました。" IDS_NFO_NOW_CONNECTED "%ls に接続しました。"
IDS_NFO_ASSIGN_IP "割り当てられたIP: %ls" IDS_NFO_ASSIGN_IP "割り当てられたIP: %ls"
IDS_ERR_CERT_EXPIRED "証明書の期限が切れているかシステム時刻が正しくないため、接続できません。" IDS_ERR_CERT_EXPIRED "証明書の期限が切れているかシステム時刻が正しくないため、接続できません。"

View File

@ -357,6 +357,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed." IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "현재 상태: OpenVPN 종료 대기 중…" IDS_NFO_STATE_WAIT_TERM "현재 상태: OpenVPN 종료 대기 중…"
IDS_NFO_STATE_CONNECTED "현재 상태: 연결됨" IDS_NFO_STATE_CONNECTED "현재 상태: 연결됨"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls 접속이 연결 되었습니다." IDS_NFO_NOW_CONNECTED "%ls 접속이 연결 되었습니다."
IDS_NFO_ASSIGN_IP "할당된 IP: %ls" IDS_NFO_ASSIGN_IP "할당된 IP: %ls"
IDS_ERR_CERT_EXPIRED "인증서가 만료 되었거나, 시스템 시간이 잘못 설정 되어 연결할 수 없습니다." IDS_ERR_CERT_EXPIRED "인증서가 만료 되었거나, 시스템 시간이 잘못 설정 되어 연결할 수 없습니다."

View File

@ -359,6 +359,7 @@ Vul het voorgaande autorisatiescherm volledig in."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread om Statusvenster te tonen mislukt." 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_WAIT_TERM "Huidige status: Wachten tot OpenVPN gestopt is…"
IDS_NFO_STATE_CONNECTED "Huidige status: Verbonden" 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_NOW_CONNECTED "%ls is nu verbonden."
IDS_NFO_ASSIGN_IP "Toegewezen IP: %ls" IDS_NFO_ASSIGN_IP "Toegewezen IP: %ls"
IDS_ERR_CERT_EXPIRED "Kan geen verbinding maken, het certificaat is vervallen. Controleer eventueel de systeemtijd." IDS_ERR_CERT_EXPIRED "Kan geen verbinding maken, het certificaat is vervallen. Controleer eventueel de systeemtijd."

View File

@ -356,6 +356,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread for å vise statusvindu feilet." IDS_ERR_CREATE_THREAD_STATUS "CreateThread for å vise statusvindu feilet."
IDS_NFO_STATE_WAIT_TERM "Status: Venter på at OpenVPN stopper…" IDS_NFO_STATE_WAIT_TERM "Status: Venter på at OpenVPN stopper…"
IDS_NFO_STATE_CONNECTED "Status: Tilkoblet" IDS_NFO_STATE_CONNECTED "Status: Tilkoblet"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls er tilkoblet." IDS_NFO_NOW_CONNECTED "%ls er tilkoblet."
IDS_NFO_ASSIGN_IP "Tildelt IP: %ls" 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." IDS_ERR_CERT_EXPIRED "Kunne ikke koble til. Sertifikatet er ikke lenger gyldig. Eventuelt kan klokken på datamaskinen din gå feil."

View File

@ -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_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_WAIT_TERM "Stan obecny: Oczekiwanie na zakończenie OpenVPN-a…"
IDS_NFO_STATE_CONNECTED "Stan obecny: Połączony" 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_NOW_CONNECTED "%ls jest teraz połączony."
IDS_NFO_ASSIGN_IP "Przyznany IP: %ls" 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." IDS_ERR_CERT_EXPIRED "Połączenie nie jest możliwe z powodu wygaśnięcia certyfikatu lub błędnie ustawionego czasu systemowego."

View File

@ -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_ERR_CREATE_THREAD_STATUS "CreateThread falhou ao mostrar janela de status."
IDS_NFO_STATE_WAIT_TERM "Estado atual: Aguardando OpenVPN terminar…" IDS_NFO_STATE_WAIT_TERM "Estado atual: Aguardando OpenVPN terminar…"
IDS_NFO_STATE_CONNECTED "Estado atual: Conectado" 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_NOW_CONNECTED "%ls está conectado."
IDS_NFO_ASSIGN_IP "IP atribuído: %ls" 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." IDS_ERR_CERT_EXPIRED "Impossível conectar porque seu certificado expirou ou a data do sistema está incorreta."

View File

@ -360,6 +360,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "Ошибка выполнения CreateThread при отображении окна состояния." IDS_ERR_CREATE_THREAD_STATUS "Ошибка выполнения CreateThread при отображении окна состояния."
IDS_NFO_STATE_WAIT_TERM "Текущее состояние: ожидание завершения работы OpenVPN…" IDS_NFO_STATE_WAIT_TERM "Текущее состояние: ожидание завершения работы OpenVPN…"
IDS_NFO_STATE_CONNECTED "Текущее состояние: подключено" IDS_NFO_STATE_CONNECTED "Текущее состояние: подключено"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls сейчас подключено." IDS_NFO_NOW_CONNECTED "%ls сейчас подключено."
IDS_NFO_ASSIGN_IP "Назначенный IP: %ls" IDS_NFO_ASSIGN_IP "Назначенный IP: %ls"
IDS_ERR_CERT_EXPIRED "Невозможно подключиться, так как срок действия вашего сертификата истёк или системное время некорректно." IDS_ERR_CERT_EXPIRED "Невозможно подключиться, так как срок действия вашего сертификата истёк или системное время некорректно."

View File

@ -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_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_WAIT_TERM "Status: Väntar på att OpenVPN skall avslutas…"
IDS_NFO_STATE_CONNECTED "Status: Ansluten" 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_NOW_CONNECTED "%ls är nu ansluten."
IDS_NFO_ASSIGN_IP "Tilldelad IP: %ls" 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." 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."

View File

@ -359,6 +359,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread anında durum penceresi gösterilemedi hatası." 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_WAIT_TERM "Geçerli Durum: OpenVPN' in kapanması bekleniyor…"
IDS_NFO_STATE_CONNECTED "Geçerli Durum: Bağlandı" 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_NOW_CONNECTED "%ls şu an bağlı."
IDS_NFO_ASSIGN_IP "Atanan IP: %ls" 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ı." IDS_ERR_CERT_EXPIRED "Sertifikanız veya sistem tarih/zaman ayarlarınız geçersiz olduğundan bağlantı sağlanamadı."

View File

@ -359,6 +359,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "Робоча помилка CreateThread, а саме у час відображення вікна статусу." IDS_ERR_CREATE_THREAD_STATUS "Робоча помилка CreateThread, а саме у час відображення вікна статусу."
IDS_NFO_STATE_WAIT_TERM "У цей час статус: очікування зупинки роботи OpenVPN…" IDS_NFO_STATE_WAIT_TERM "У цей час статус: очікування зупинки роботи OpenVPN…"
IDS_NFO_STATE_CONNECTED "У цей час статус: підключено." IDS_NFO_STATE_CONNECTED "У цей час статус: підключено."
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls зараз підключено." IDS_NFO_NOW_CONNECTED "%ls зараз підключено."
IDS_NFO_ASSIGN_IP "Отримано IP: %ls" IDS_NFO_ASSIGN_IP "Отримано IP: %ls"
IDS_ERR_CERT_EXPIRED "Неможливо з'єднатися, бо час дії вашого сертифікату минув або системний час некорректний." IDS_ERR_CERT_EXPIRED "Неможливо з'єднатися, бо час дії вашого сертифікату минув або системний час некорректний."

View File

@ -361,6 +361,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread 显示状态窗口时失败。" IDS_ERR_CREATE_THREAD_STATUS "CreateThread 显示状态窗口时失败。"
IDS_NFO_STATE_WAIT_TERM "当前状态: 等待中止 OpenVPN…" IDS_NFO_STATE_WAIT_TERM "当前状态: 等待中止 OpenVPN…"
IDS_NFO_STATE_CONNECTED "当前状态: 已连接" IDS_NFO_STATE_CONNECTED "当前状态: 已连接"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "已连接至 %ls。" IDS_NFO_NOW_CONNECTED "已连接至 %ls。"
IDS_NFO_ASSIGN_IP "分配 IP: %ls" IDS_NFO_ASSIGN_IP "分配 IP: %ls"
IDS_ERR_CERT_EXPIRED "您的证书已过期,或是系统时间不正确,无法连接。" IDS_ERR_CERT_EXPIRED "您的证书已过期,或是系统时间不正确,无法连接。"

View File

@ -361,6 +361,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread 以顯示狀態視窗時失敗。" IDS_ERR_CREATE_THREAD_STATUS "CreateThread 以顯示狀態視窗時失敗。"
IDS_NFO_STATE_WAIT_TERM "目前狀態: 等待中止 OpenVPN…" IDS_NFO_STATE_WAIT_TERM "目前狀態: 等待中止 OpenVPN…"
IDS_NFO_STATE_CONNECTED "目前狀態: 已連線" IDS_NFO_STATE_CONNECTED "目前狀態: 已連線"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "已連線至 %ls。" IDS_NFO_NOW_CONNECTED "已連線至 %ls。"
IDS_NFO_ASSIGN_IP "配發 IP: %ls" IDS_NFO_ASSIGN_IP "配發 IP: %ls"
IDS_ERR_CERT_EXPIRED "您的憑證已過期,或是系統時間不正確,無法連線。" IDS_ERR_CERT_EXPIRED "您的憑證已過期,或是系統時間不正確,無法連線。"

14
tray.c
View File

@ -576,6 +576,13 @@ SetMenuStatusById(int i, conn_state_t state)
EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_GRAYED); EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED); 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)) if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS))
EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_ENABLED); EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_ENABLED);
else else
@ -635,6 +642,13 @@ SetMenuStatusById(int i, conn_state_t state)
EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU, MF_GRAYED); EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED); 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)) if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS))
EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_ENABLED); EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_ENABLED);
else else