mirror of https://github.com/OpenVPN/openvpn-gui
Use a list instead of array for connections list
Currently we use an array of connection pointers which needs to be reallocated when space runs out. But, that happens from the main thread while the status thread may be referring to those pointers. Its very hard to fence against possible invalid memory access. Instead, use a list so that connection pointer never changes once created. The connection list is no longer recreated from scratch even when no connections are active. This means configs added while GUI is running will always appear at the bottom of the root group listing until the GUI is restarted. TODO: This behaviour could be improved by scanning through the groups to graft new configs at the right branch in the config-group tree. v2: removed unused references to SetMenuStatusById() Signed-off-by: Selva Nair <selva.nair@gmail.com>pull/589/head
parent
8a4fec9d13
commit
9417991168
109
main.c
109
main.c
|
@ -358,17 +358,17 @@ StopAllOpenVPN()
|
||||||
* at their current state. Use the disconnect menu to put them into
|
* at their current state. Use the disconnect menu to put them into
|
||||||
* hold state before exit, if desired.
|
* hold state before exit, if desired.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].state != disconnected && o.conn[i].state != detached)
|
if (c->state != disconnected && c->state != detached)
|
||||||
{
|
{
|
||||||
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
|
if (c->flags & FLAG_DAEMON_PERSISTENT)
|
||||||
{
|
{
|
||||||
DetachOpenVPN(&o.conn[i]);
|
DetachOpenVPN(c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StopOpenVPN(&o.conn[i]);
|
StopOpenVPN(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,12 +385,10 @@ StopAllOpenVPN()
|
||||||
static int
|
static int
|
||||||
AutoStartConnections()
|
AutoStartConnections()
|
||||||
{
|
{
|
||||||
int i;
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
|
|
||||||
for (i = 0; i < o.num_configs; i++)
|
|
||||||
{
|
{
|
||||||
if (o.conn[i].auto_connect && !(o.conn[i].flags & FLAG_DAEMON_PERSISTENT))
|
if (c->auto_connect && !(c->flags & FLAG_DAEMON_PERSISTENT))
|
||||||
StartOpenVPN(&o.conn[i]);
|
StartOpenVPN(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -400,15 +398,15 @@ AutoStartConnections()
|
||||||
static void
|
static void
|
||||||
ResumeConnections()
|
ResumeConnections()
|
||||||
{
|
{
|
||||||
int i;
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
for (i = 0; i < o.num_configs; i++) {
|
{
|
||||||
/* Restart suspend connections */
|
/* Restart suspend connections */
|
||||||
if (o.conn[i].state == suspended)
|
if (c->state == suspended)
|
||||||
StartOpenVPN(&o.conn[i]);
|
StartOpenVPN(c);
|
||||||
|
|
||||||
/* If some connection never reached SUSPENDED state */
|
/* If some connection never reached SUSPENDED state */
|
||||||
if (o.conn[i].state == suspending)
|
if (c->state == suspending)
|
||||||
StopOpenVPN(&o.conn[i]);
|
StopOpenVPN(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,19 +490,19 @@ ManagePersistent(HWND hwnd, UINT UNUSED msg, UINT_PTR id, DWORD UNUSED now)
|
||||||
CheckServiceStatus();
|
CheckServiceStatus();
|
||||||
if (o.service_state == service_connected)
|
if (o.service_state == service_connected)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT
|
if (c->flags & FLAG_DAEMON_PERSISTENT
|
||||||
&& o.conn[i].auto_connect
|
&& c->auto_connect
|
||||||
&& (o.conn[i].state == disconnected || o.conn[i].state == detached))
|
&& (c->state == disconnected || c->state == detached))
|
||||||
{
|
{
|
||||||
/* disable auto-connect to avoid repeated re-connect
|
/* disable auto-connect to avoid repeated re-connect
|
||||||
* after unrecoverable errors. Re-enabled on successful
|
* after unrecoverable errors. Re-enabled on successful
|
||||||
* connect.
|
* connect.
|
||||||
*/
|
*/
|
||||||
o.conn[i].auto_connect = false;
|
c->auto_connect = false;
|
||||||
o.conn[i].state = detached; /* this is required to retain management-hold on re-attach */
|
c->state = detached; /* this is required to retain management-hold on re-attach */
|
||||||
StartOpenVPN(&o.conn[i]); /* attach to the management i/f */
|
StartOpenVPN(c); /* attach to the management i/f */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -519,14 +517,14 @@ ManagePersistent(HWND hwnd, UINT UNUSED msg, UINT_PTR id, DWORD UNUSED now)
|
||||||
static void
|
static void
|
||||||
HandleSessionLock(void)
|
HandleSessionLock(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT
|
if (c->flags & FLAG_DAEMON_PERSISTENT
|
||||||
&& (o.conn[i].state != disconnected && o.conn[i].state != detached))
|
&& (c->state != disconnected && c->state != detached))
|
||||||
{
|
{
|
||||||
o.conn[i].auto_connect = false;
|
c->auto_connect = false;
|
||||||
DetachOpenVPN(&o.conn[i]);
|
DetachOpenVPN(c);
|
||||||
o.conn[i].flags |= FLAG_WAIT_UNLOCK;
|
c->flags |= FLAG_WAIT_UNLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,12 +534,12 @@ HandleSessionLock(void)
|
||||||
void
|
void
|
||||||
HandleSessionUnlock(void)
|
HandleSessionUnlock(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].flags & FLAG_WAIT_UNLOCK)
|
if (c->flags & FLAG_WAIT_UNLOCK)
|
||||||
{
|
{
|
||||||
o.conn[i].auto_connect = true; /* so that ManagePersistent will trigger attach */
|
c->auto_connect = true; /* so that ManagePersistent will trigger attach */
|
||||||
o.conn[i].flags &= ~ FLAG_WAIT_UNLOCK;
|
c->flags &= ~ FLAG_WAIT_UNLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,8 +548,8 @@ HandleSessionUnlock(void)
|
||||||
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static UINT s_uTaskbarRestart;
|
static UINT s_uTaskbarRestart;
|
||||||
int conn_id = 0;
|
|
||||||
MENUINFO minfo = {.cbSize = sizeof(MENUINFO)};
|
MENUINFO minfo = {.cbSize = sizeof(MENUINFO)};
|
||||||
|
connection_t *c = NULL;
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
|
@ -633,36 +631,37 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||||
else {
|
else {
|
||||||
minfo.fMask = MIM_MENUDATA;
|
minfo.fMask = MIM_MENUDATA;
|
||||||
GetMenuInfo((HMENU) lParam, &minfo);
|
GetMenuInfo((HMENU) lParam, &minfo);
|
||||||
conn_id = (INT) minfo.dwMenuData;
|
c = (connection_t *) minfo.dwMenuData;
|
||||||
if (conn_id < 0 || conn_id >= o.num_configs) break; /* ignore invalid connection id */
|
if (!c)
|
||||||
|
break; /* ignore invalid connection */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reach here only if the command did not match any global items and a valid connection id is available */
|
/* reach here only if the command did not match any global items and a valid connection id is available */
|
||||||
|
|
||||||
if (LOWORD(wParam) == IDM_CONNECTMENU) {
|
if (LOWORD(wParam) == IDM_CONNECTMENU) {
|
||||||
StartOpenVPN(&o.conn[conn_id]);
|
StartOpenVPN(c);
|
||||||
}
|
}
|
||||||
else if (LOWORD(wParam) == IDM_DISCONNECTMENU) {
|
else if (LOWORD(wParam) == IDM_DISCONNECTMENU) {
|
||||||
StopOpenVPN(&o.conn[conn_id]);
|
StopOpenVPN(c);
|
||||||
}
|
}
|
||||||
else if (LOWORD(wParam) == IDM_RECONNECTMENU) {
|
else if (LOWORD(wParam) == IDM_RECONNECTMENU) {
|
||||||
RestartOpenVPN(&o.conn[conn_id]);
|
RestartOpenVPN(c);
|
||||||
}
|
}
|
||||||
else if (LOWORD(wParam) == IDM_STATUSMENU) {
|
else if (LOWORD(wParam) == IDM_STATUSMENU) {
|
||||||
ShowWindow(o.conn[conn_id].hwndStatus, SW_SHOW);
|
ShowWindow(c->hwndStatus, SW_SHOW);
|
||||||
}
|
}
|
||||||
else if (LOWORD(wParam) == IDM_VIEWLOGMENU) {
|
else if (LOWORD(wParam) == IDM_VIEWLOGMENU) {
|
||||||
ViewLog(conn_id);
|
ViewLog(c);
|
||||||
}
|
}
|
||||||
else if (LOWORD(wParam) == IDM_EDITMENU) {
|
else if (LOWORD(wParam) == IDM_EDITMENU) {
|
||||||
EditConfig(conn_id);
|
EditConfig(c);
|
||||||
}
|
}
|
||||||
else if (LOWORD(wParam) == IDM_CLEARPASSMENU) {
|
else if (LOWORD(wParam) == IDM_CLEARPASSMENU) {
|
||||||
ResetSavePasswords(&o.conn[conn_id]);
|
ResetSavePasswords(c);
|
||||||
}
|
}
|
||||||
#ifndef DISABLE_CHANGE_PASSWORD
|
#ifndef DISABLE_CHANGE_PASSWORD
|
||||||
else if (LOWORD(wParam) == IDM_PASSPHRASEMENU) {
|
else if (LOWORD(wParam) == IDM_PASSPHRASEMENU) {
|
||||||
ShowChangePassphraseDialog(&o.conn[conn_id]);
|
ShowChangePassphraseDialog(c);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
@ -825,13 +824,11 @@ ShowSettingsDialog()
|
||||||
void
|
void
|
||||||
CloseApplication(HWND hwnd)
|
CloseApplication(HWND hwnd)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Show a message if any non-persistent connections are active */
|
/* Show a message if any non-persistent connections are active */
|
||||||
for (i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].state == disconnected
|
if (c->state == disconnected
|
||||||
|| o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
|
|| c->flags & FLAG_DAEMON_PERSISTENT)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +977,7 @@ SaveAutoRestartList()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int *active_conns = malloc((size_t) max_active*sizeof(int));
|
connection_t **active_conns = malloc((size_t) max_active*sizeof(connection_t *));
|
||||||
|
|
||||||
if (!active_conns)
|
if (!active_conns)
|
||||||
{
|
{
|
||||||
|
@ -988,16 +985,16 @@ SaveAutoRestartList()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c && nactive < max_active; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].state == disconnected
|
if (c->state == disconnected
|
||||||
|| o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
|
|| c->flags & FLAG_DAEMON_PERSISTENT)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* accumulate space needed for list of active connections */
|
/* accumulate space needed for list of active connections */
|
||||||
len += wcslen(o.conn[i].config_name) + 1;
|
len += wcslen(c->config_name) + 1;
|
||||||
active_conns[nactive++] = i;
|
active_conns[nactive++] = c;
|
||||||
}
|
}
|
||||||
len++; /* for double nul termination */
|
len++; /* for double nul termination */
|
||||||
|
|
||||||
|
@ -1015,7 +1012,7 @@ SaveAutoRestartList()
|
||||||
wchar_t *p = list;
|
wchar_t *p = list;
|
||||||
for (int i = 0; i < nactive; i++)
|
for (int i = 0; i < nactive; i++)
|
||||||
{
|
{
|
||||||
connection_t *c = &o.conn[active_conns[i]];
|
connection_t *c = active_conns[i];
|
||||||
wcscpy(p, c->config_name); /* wcscpy is safe here */
|
wcscpy(p, c->config_name); /* wcscpy is safe here */
|
||||||
p += wcslen(c->config_name) + 1;
|
p += wcslen(c->config_name) + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2681,12 +2681,6 @@ TerminateOpenVPN (connection_t *c)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SuspendOpenVPN(int config)
|
|
||||||
{
|
|
||||||
PostMessage(o.conn[config].hwndStatus, WM_OVPN_SUSPEND, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RestartOpenVPN(connection_t *c)
|
RestartOpenVPN(connection_t *c)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,22 +79,36 @@ CheckReadAccess (const TCHAR *dir, const TCHAR *file)
|
||||||
static int
|
static int
|
||||||
ConfigAlreadyExists(TCHAR *newconfig)
|
ConfigAlreadyExists(TCHAR *newconfig)
|
||||||
{
|
{
|
||||||
int i;
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
for (i = 0; i < o.num_configs; ++i)
|
|
||||||
{
|
{
|
||||||
if (_tcsicmp(o.conn[i].config_file, newconfig) == 0)
|
if (_tcsicmp(c->config_file, newconfig) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AddConfigFileToList(int config, const TCHAR *filename, const TCHAR *config_dir)
|
AddConfigFileToList(int group, const TCHAR *filename, const TCHAR *config_dir)
|
||||||
{
|
{
|
||||||
connection_t *c = &o.conn[config];
|
connection_t *c = calloc(1, sizeof(connection_t));
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(c, 0, sizeof(*c));
|
if (!c)
|
||||||
|
{
|
||||||
|
ErrorExit(1, L"Out of memory in AddConfigFileToList");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.ctail)
|
||||||
|
{
|
||||||
|
o.ctail->next = c;
|
||||||
|
o.ctail = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
o.chead = o.ctail = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->id = o.num_configs++;
|
||||||
|
c->group = group;
|
||||||
|
|
||||||
_tcsncpy(c->config_file, filename, _countof(c->config_file) - 1);
|
_tcsncpy(c->config_file, filename, _countof(c->config_file) - 1);
|
||||||
_tcsncpy(c->config_dir, config_dir, _countof(c->config_dir) - 1);
|
_tcsncpy(c->config_dir, config_dir, _countof(c->config_dir) - 1);
|
||||||
|
@ -105,7 +119,7 @@ AddConfigFileToList(int config, const TCHAR *filename, const TCHAR *config_dir)
|
||||||
c->manage.sk = INVALID_SOCKET;
|
c->manage.sk = INVALID_SOCKET;
|
||||||
c->manage.skaddr.sin_family = AF_INET;
|
c->manage.skaddr.sin_family = AF_INET;
|
||||||
c->manage.skaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
c->manage.skaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
c->manage.skaddr.sin_port = htons(o.mgmt_port_offset + config);
|
c->manage.skaddr.sin_port = htons(o.mgmt_port_offset + c->id);
|
||||||
|
|
||||||
#ifndef DISABLE_CHANGE_PASSWORD
|
#ifndef DISABLE_CHANGE_PASSWORD
|
||||||
if (CheckKeyFileWriteAccess (c))
|
if (CheckKeyFileWriteAccess (c))
|
||||||
|
@ -123,7 +137,7 @@ AddConfigFileToList(int config, const TCHAR *filename, const TCHAR *config_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if connection should be autostarted */
|
/* Check if connection should be autostarted */
|
||||||
for (i = 0; i < o.num_auto_connect; ++i)
|
for (int i = 0; i < o.num_auto_connect; ++i)
|
||||||
{
|
{
|
||||||
if (_tcsicmp(c->config_file, o.auto_connect[i]) == 0
|
if (_tcsicmp(c->config_file, o.auto_connect[i]) == 0
|
||||||
|| _tcsicmp(c->config_name, o.auto_connect[i]) == 0)
|
|| _tcsicmp(c->config_name, o.auto_connect[i]) == 0)
|
||||||
|
@ -211,9 +225,9 @@ ActivateConfigGroups(void)
|
||||||
/* count children of each group -- this includes groups
|
/* count children of each group -- this includes groups
|
||||||
* and configs which have it as parent
|
* and configs which have it as parent
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
CONFIG_GROUP(&o.conn[i])->children++;
|
CONFIG_GROUP(c)->children++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < o.num_groups; i++)
|
for (int i = 1; i < o.num_groups; i++)
|
||||||
|
@ -235,23 +249,23 @@ ActivateConfigGroups(void)
|
||||||
* script etc.) in a separate directory, without making the menu structure
|
* script etc.) in a separate directory, without making the menu structure
|
||||||
* too deeply nested.
|
* too deeply nested.
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
config_group_t *cg = CONFIG_GROUP(&o.conn[i]);
|
config_group_t *cg = CONFIG_GROUP(c);
|
||||||
|
|
||||||
/* if not root and has only this config as child -- squash it */
|
/* if not root and has only this config as child -- squash it */
|
||||||
if (PARENT_GROUP(cg) && cg->children == 1
|
if (PARENT_GROUP(cg) && cg->children == 1
|
||||||
&& !wcscmp(cg->name, o.conn[i].config_name))
|
&& !wcscmp(cg->name, c->config_name))
|
||||||
{
|
{
|
||||||
cg->children--;
|
cg->children--;
|
||||||
o.conn[i].group = cg->parent;
|
c->group = cg->parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* activate all groups that connect a config to the root */
|
/* activate all groups that connect a config to the root */
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
config_group_t *cg = CONFIG_GROUP(&o.conn[i]);
|
config_group_t *cg = CONFIG_GROUP(c);
|
||||||
|
|
||||||
while (cg)
|
while (cg)
|
||||||
{
|
{
|
||||||
|
@ -287,19 +301,6 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags)
|
||||||
/* Loop over each config file in config dir */
|
/* Loop over each config file in config dir */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!o.conn || o.num_configs == o.max_configs)
|
|
||||||
{
|
|
||||||
o.max_configs += 50;
|
|
||||||
void *tmp = realloc(o.conn, sizeof(*o.conn)*o.max_configs);
|
|
||||||
if (!tmp)
|
|
||||||
{
|
|
||||||
o.max_configs -= 50;
|
|
||||||
FindClose(find_handle);
|
|
||||||
ErrorExit(1, L"Out of memory while scanning configs");
|
|
||||||
}
|
|
||||||
o.conn = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
match_t match_type = match(&find_obj, o.ext_string);
|
match_t match_type = match(&find_obj, o.ext_string);
|
||||||
if (match_type == match_file)
|
if (match_type == match_file)
|
||||||
{
|
{
|
||||||
|
@ -312,8 +313,7 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags)
|
||||||
|
|
||||||
if (CheckReadAccess (config_dir, find_obj.cFileName))
|
if (CheckReadAccess (config_dir, find_obj.cFileName))
|
||||||
{
|
{
|
||||||
AddConfigFileToList(o.num_configs, find_obj.cFileName, config_dir);
|
AddConfigFileToList(group, find_obj.cFileName, config_dir);
|
||||||
o.conn[o.num_configs++].group = group;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (FindNextFile(find_handle, &find_obj));
|
} while (FindNextFile(find_handle, &find_obj));
|
||||||
|
@ -419,17 +419,12 @@ BuildFileList()
|
||||||
issue_warnings = false;
|
issue_warnings = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no connections are active reset num_configs and rescan
|
* If first time or no entries in the connection list reset groups and rescan
|
||||||
* to make a new list. Else we keep all current configs and
|
* to make a new list. Else we keep all current configs and
|
||||||
* rescan to add any new one's found.
|
* rescan to add any new one's found.
|
||||||
* Do the same when persistent connections are in auto-attach mode,
|
|
||||||
* to avoid over-writing their status info such as auto_connect=false
|
|
||||||
* after manual detach.
|
|
||||||
*/
|
*/
|
||||||
if (!o.num_groups
|
if (!o.num_configs)
|
||||||
|| (CountConnState(disconnected) == o.num_configs && o.enable_persistent != 2))
|
|
||||||
{
|
{
|
||||||
o.num_configs = 0;
|
|
||||||
o.num_groups = 0;
|
o.num_groups = 0;
|
||||||
flags |= FLAG_ADD_CONFIG_GROUPS;
|
flags |= FLAG_ADD_CONFIG_GROUPS;
|
||||||
root_gp = NewConfigGroup(L"ROOT", -1, flags); /* -1 indicates no parent */
|
root_gp = NewConfigGroup(L"ROOT", -1, flags); /* -1 indicates no parent */
|
||||||
|
|
20
options.c
20
options.c
|
@ -453,12 +453,11 @@ ProcessCommandLine(options_t *options, TCHAR *command_line)
|
||||||
int
|
int
|
||||||
CountConnState(conn_state_t check)
|
CountConnState(conn_state_t check)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (i = 0; i < o.num_configs; ++i)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].state == check)
|
if (c->state == check)
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,11 +467,10 @@ CountConnState(conn_state_t check)
|
||||||
connection_t*
|
connection_t*
|
||||||
GetConnByManagement(SOCKET sk)
|
GetConnByManagement(SOCKET sk)
|
||||||
{
|
{
|
||||||
int i;
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
for (i = 0; i < o.num_configs; ++i)
|
|
||||||
{
|
{
|
||||||
if (o.conn[i].manage.sk == sk)
|
if (c->manage.sk == sk)
|
||||||
return &o.conn[i];
|
return c;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -480,11 +478,11 @@ GetConnByManagement(SOCKET sk)
|
||||||
connection_t*
|
connection_t*
|
||||||
GetConnByName(const WCHAR *name)
|
GetConnByName(const WCHAR *name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < o.num_configs; ++i)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (wcsicmp (o.conn[i].config_file, name) == 0
|
if (wcsicmp (c->config_file, name) == 0
|
||||||
|| wcsicmp(o.conn[i].config_name, name) == 0)
|
|| wcsicmp(c->config_name, name) == 0)
|
||||||
return &o.conn[i];
|
return c;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,8 @@ struct connection {
|
||||||
struct echo_msg echo_msg; /* Message echo-ed from server or client config and related data */
|
struct echo_msg echo_msg; /* Message echo-ed from server or client config and related data */
|
||||||
struct pkcs11_list pkcs11_list;
|
struct pkcs11_list pkcs11_list;
|
||||||
char daemon_state[20]; /* state of openvpn.ex: WAIT, AUTH, GET_CONFIG etc.. */
|
char daemon_state[20]; /* state of openvpn.ex: WAIT, AUTH, GET_CONFIG etc.. */
|
||||||
|
int id; /* index of config -- treat as immutable once assigned */
|
||||||
|
connection_t *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* All options used within OpenVPN GUI */
|
/* All options used within OpenVPN GUI */
|
||||||
|
@ -175,7 +177,8 @@ typedef struct {
|
||||||
const TCHAR **auto_connect;
|
const TCHAR **auto_connect;
|
||||||
|
|
||||||
/* Connection parameters */
|
/* Connection parameters */
|
||||||
connection_t *conn; /* Array of connection structure */
|
connection_t *chead; /* Head of connection list */
|
||||||
|
connection_t *ctail; /* Tail of connection list */
|
||||||
config_group_t *groups; /* Array of nodes defining the config groups tree */
|
config_group_t *groups; /* Array of nodes defining the config groups tree */
|
||||||
int num_configs; /* Number of configs */
|
int num_configs; /* Number of configs */
|
||||||
int num_auto_connect; /* Number of auto-connect configs */
|
int num_auto_connect; /* Number of auto-connect configs */
|
||||||
|
|
|
@ -76,10 +76,6 @@ void SetMenuStatus(UNUSED connection_t *c, UNUSED conn_state_t state)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void SetMenuStatusById(UNUSED int id, UNUSED conn_state_t state)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void SetServiceMenuStatus(void)
|
void SetServiceMenuStatus(void)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -265,8 +265,9 @@ InitializeUI(HINSTANCE hinstance)
|
||||||
CheckServiceStatus();
|
CheckServiceStatus();
|
||||||
int num_persistent = 0;
|
int num_persistent = 0;
|
||||||
|
|
||||||
for (int i = 0; i < o.num_configs; i++) {
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT) num_persistent++;
|
{
|
||||||
|
if (c->flags & FLAG_DAEMON_PERSISTENT) num_persistent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o.service_state == service_disconnected && num_persistent > 0) {
|
if (o.service_state == service_disconnected && num_persistent > 0) {
|
||||||
|
@ -281,15 +282,14 @@ InitializeUI(HINSTANCE hinstance)
|
||||||
/* Returns number of PLAP enabled configs -- for now
|
/* Returns number of PLAP enabled configs -- for now
|
||||||
* same as autostarted (persistent) connections.
|
* same as autostarted (persistent) connections.
|
||||||
* The corresponding connection pointers are set in
|
* The corresponding connection pointers are set in
|
||||||
* the conn[] array.
|
* the conn[] array
|
||||||
*/
|
*/
|
||||||
DWORD
|
DWORD
|
||||||
FindPLAPConnections(connection_t *conn[], size_t max_count)
|
FindPLAPConnections(connection_t *conn[], size_t max_count)
|
||||||
{
|
{
|
||||||
DWORD count = 0;
|
DWORD count = 0;
|
||||||
for (int i = 0; i < o.num_configs && count < max_count; i++)
|
for (connection_t *c = o.chead; c && count < max_count; c = c->next)
|
||||||
{
|
{
|
||||||
connection_t *c = &o.conn[i];
|
|
||||||
if (!(c->flags & FLAG_DAEMON_PERSISTENT)
|
if (!(c->flags & FLAG_DAEMON_PERSISTENT)
|
||||||
|| !ParseManagementAddress(c))
|
|| !ParseManagementAddress(c))
|
||||||
{
|
{
|
||||||
|
@ -390,11 +390,11 @@ DetachAllOpenVPN()
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Detach from the mgmt i/f of all connections */
|
/* Detach from the mgmt i/f of all connections */
|
||||||
for (i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].state != disconnected)
|
if (c->state != disconnected)
|
||||||
{
|
{
|
||||||
DetachOpenVPN(&o.conn[i]);
|
DetachOpenVPN(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,12 +408,12 @@ DetachAllOpenVPN()
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
if (o.conn[i].hwndStatus)
|
if (c->hwndStatus)
|
||||||
{
|
{
|
||||||
/* Status thread still running? kill it */
|
/* Status thread still running? kill it */
|
||||||
WaitOnThread(&o.conn[i], 0);
|
WaitOnThread(c, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
90
tray.c
90
tray.c
|
@ -161,13 +161,13 @@ CreatePopupMenus()
|
||||||
CreateMenuBitmaps();
|
CreateMenuBitmaps();
|
||||||
MENUINFO minfo = {.cbSize = sizeof(MENUINFO)};
|
MENUINFO minfo = {.cbSize = sizeof(MENUINFO)};
|
||||||
|
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
hMenuConn[i] = CreatePopupMenu();
|
hMenuConn[c->id] = CreatePopupMenu();
|
||||||
/* Save the connection index in the menu.*/
|
/* Save the connection index in the menu.*/
|
||||||
minfo.fMask = MIM_MENUDATA;
|
minfo.fMask = MIM_MENUDATA;
|
||||||
minfo.dwMenuData = i;
|
minfo.dwMenuData = (UINT_PTR) c;
|
||||||
SetMenuInfo(hMenuConn[i], &minfo);
|
SetMenuInfo(hMenuConn[c->id], &minfo);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < o.num_groups; i++)
|
for (int i = 0; i < o.num_groups; i++)
|
||||||
{
|
{
|
||||||
|
@ -185,7 +185,7 @@ CreatePopupMenus()
|
||||||
minfo.dwStyle |= MNS_NOTIFYBYPOS;
|
minfo.dwStyle |= MNS_NOTIFYBYPOS;
|
||||||
SetMenuInfo(hMenu, &minfo);
|
SetMenuInfo(hMenu, &minfo);
|
||||||
|
|
||||||
if (o.num_configs == 1) {
|
if (o.num_configs == 1 && o.chead) {
|
||||||
/* Create Main menu with actions */
|
/* Create Main menu with actions */
|
||||||
AppendMenu(hMenu, MF_STRING, IDM_CONNECTMENU, LoadLocalizedString(IDS_MENU_CONNECT));
|
AppendMenu(hMenu, MF_STRING, IDM_CONNECTMENU, LoadLocalizedString(IDS_MENU_CONNECT));
|
||||||
AppendMenu(hMenu, MF_STRING, IDM_DISCONNECTMENU, LoadLocalizedString(IDS_MENU_DISCONNECT));
|
AppendMenu(hMenu, MF_STRING, IDM_DISCONNECTMENU, LoadLocalizedString(IDS_MENU_DISCONNECT));
|
||||||
|
@ -199,7 +199,7 @@ CreatePopupMenus()
|
||||||
AppendMenu(hMenu, MF_STRING, IDM_CLEARPASSMENU, LoadLocalizedString(IDS_MENU_CLEARPASS));
|
AppendMenu(hMenu, MF_STRING, IDM_CLEARPASSMENU, LoadLocalizedString(IDS_MENU_CLEARPASS));
|
||||||
|
|
||||||
#ifndef DISABLE_CHANGE_PASSWORD
|
#ifndef DISABLE_CHANGE_PASSWORD
|
||||||
if (o.conn[0].flags & FLAG_ALLOW_CHANGE_PASSPHRASE)
|
if (o.chead->flags & FLAG_ALLOW_CHANGE_PASSPHRASE)
|
||||||
AppendMenu(hMenu, MF_STRING, IDM_PASSPHRASEMENU, LoadLocalizedString(IDS_MENU_PASSPHRASE));
|
AppendMenu(hMenu, MF_STRING, IDM_PASSPHRASEMENU, LoadLocalizedString(IDS_MENU_PASSPHRASE));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ CreatePopupMenus()
|
||||||
AppendMenu(hMenu, MF_STRING ,IDM_SETTINGS, LoadLocalizedString(IDS_MENU_SETTINGS));
|
AppendMenu(hMenu, MF_STRING ,IDM_SETTINGS, LoadLocalizedString(IDS_MENU_SETTINGS));
|
||||||
AppendMenu(hMenu, MF_STRING ,IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE));
|
AppendMenu(hMenu, MF_STRING ,IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE));
|
||||||
|
|
||||||
SetMenuStatusById(0, o.conn[0].state);
|
SetMenuStatus(o.chead, o.chead->state);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* construct the submenu tree first */
|
/* construct the submenu tree first */
|
||||||
|
@ -240,9 +240,8 @@ CreatePopupMenus()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add config file (connection) entries */
|
/* add config file (connection) entries */
|
||||||
for (int i = 0; i < o.num_configs; i++)
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
{
|
{
|
||||||
connection_t *c = &o.conn[i];
|
|
||||||
config_group_t *parent = &o.groups[0]; /* by default config is added to the root */
|
config_group_t *parent = &o.groups[0]; /* by default config is added to the root */
|
||||||
|
|
||||||
if (USE_NESTED_CONFIG_MENU)
|
if (USE_NESTED_CONFIG_MENU)
|
||||||
|
@ -257,11 +256,11 @@ CreatePopupMenus()
|
||||||
assert(parent);
|
assert(parent);
|
||||||
|
|
||||||
/* Add config to the current sub menu */
|
/* Add config to the current sub menu */
|
||||||
AppendMenu(parent->menu, MF_POPUP, (UINT_PTR) hMenuConn[i], c->config_name);
|
AppendMenu(parent->menu, MF_POPUP, (UINT_PTR) hMenuConn[c->id], c->config_name);
|
||||||
c->pos = parent->children++;
|
c->pos = parent->children++;
|
||||||
|
|
||||||
PrintDebug(L"Config %d named %ls added to submenu %ls with position %d",
|
PrintDebug(L"Config %d named %ls added to submenu %ls with position %d",
|
||||||
i, c->config_name, parent->name, c->pos);
|
c->id, c->config_name, parent->name, c->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o.num_configs > 0)
|
if (o.num_configs > 0)
|
||||||
|
@ -277,7 +276,9 @@ CreatePopupMenus()
|
||||||
AppendMenu(hMenu, MF_STRING, IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE));
|
AppendMenu(hMenu, MF_STRING, IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE));
|
||||||
|
|
||||||
/* Create popup menus for every connection */
|
/* Create popup menus for every connection */
|
||||||
for (int i = 0; i < o.num_configs; i++) {
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
|
{
|
||||||
|
int i = c->id;
|
||||||
AppendMenu(hMenuConn[i], MF_STRING, IDM_CONNECTMENU, LoadLocalizedString(IDS_MENU_CONNECT));
|
AppendMenu(hMenuConn[i], MF_STRING, IDM_CONNECTMENU, LoadLocalizedString(IDS_MENU_CONNECT));
|
||||||
AppendMenu(hMenuConn[i], MF_STRING, IDM_DISCONNECTMENU, LoadLocalizedString(IDS_MENU_DISCONNECT));
|
AppendMenu(hMenuConn[i], MF_STRING, IDM_DISCONNECTMENU, LoadLocalizedString(IDS_MENU_DISCONNECT));
|
||||||
AppendMenu(hMenuConn[i], MF_STRING, IDM_RECONNECTMENU, LoadLocalizedString(IDS_MENU_RECONNECT));
|
AppendMenu(hMenuConn[i], MF_STRING, IDM_RECONNECTMENU, LoadLocalizedString(IDS_MENU_RECONNECT));
|
||||||
|
@ -290,11 +291,11 @@ CreatePopupMenus()
|
||||||
AppendMenu(hMenuConn[i], MF_STRING, IDM_CLEARPASSMENU, LoadLocalizedString(IDS_MENU_CLEARPASS));
|
AppendMenu(hMenuConn[i], MF_STRING, IDM_CLEARPASSMENU, LoadLocalizedString(IDS_MENU_CLEARPASS));
|
||||||
|
|
||||||
#ifndef DISABLE_CHANGE_PASSWORD
|
#ifndef DISABLE_CHANGE_PASSWORD
|
||||||
if (o.conn[i].flags & FLAG_ALLOW_CHANGE_PASSPHRASE)
|
if (c->flags & FLAG_ALLOW_CHANGE_PASSPHRASE)
|
||||||
AppendMenu(hMenuConn[i], MF_STRING, IDM_PASSPHRASEMENU, LoadLocalizedString(IDS_MENU_PASSPHRASE));
|
AppendMenu(hMenuConn[i], MF_STRING, IDM_PASSPHRASEMENU, LoadLocalizedString(IDS_MENU_PASSPHRASE));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SetMenuStatusById(i, o.conn[i].state);
|
SetMenuStatus(c, c->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,9 +305,10 @@ CreatePopupMenus()
|
||||||
static void
|
static void
|
||||||
DestroyPopupMenus()
|
DestroyPopupMenus()
|
||||||
{
|
{
|
||||||
int i;
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
for (i = 0; i < o.num_configs; i++)
|
{
|
||||||
DestroyMenu(hMenuConn[i]);
|
DestroyMenu(hMenuConn[c->id]);
|
||||||
|
}
|
||||||
|
|
||||||
DestroyMenu(hMenuImport);
|
DestroyMenu(hMenuImport);
|
||||||
DestroyMenu(hMenu);
|
DestroyMenu(hMenu);
|
||||||
|
@ -349,16 +351,16 @@ OnNotifyTray(LPARAM lParam)
|
||||||
RecreatePopupMenus();
|
RecreatePopupMenus();
|
||||||
|
|
||||||
/* Start connection if only one config exist */
|
/* Start connection if only one config exist */
|
||||||
if (o.num_configs == 1 && o.conn[0].state == disconnected)
|
if (o.num_configs == 1 && o.chead->state == disconnected)
|
||||||
StartOpenVPN(&o.conn[0]);
|
StartOpenVPN(o.chead);
|
||||||
/* show the status window of all connected/connecting profiles upto a max of 10 */
|
/* show the status window of all connected/connecting profiles upto a max of 10 */
|
||||||
else if (disconnected_conns < o.num_configs) {
|
else if (disconnected_conns < o.num_configs) {
|
||||||
int i;
|
|
||||||
int num_shown = 0;
|
int num_shown = 0;
|
||||||
for (i = 0; i < o.num_configs; i++) {
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
if (o.conn[i].state != disconnected) {
|
{
|
||||||
ShowWindow(o.conn[i].hwndStatus, SW_SHOW);
|
if (c->state != disconnected && c->hwndStatus) {
|
||||||
SetForegroundWindow(o.conn[i].hwndStatus);
|
ShowWindow(c->hwndStatus, SW_SHOW);
|
||||||
|
SetForegroundWindow(c->hwndStatus);
|
||||||
if (++num_shown >= 10) break;
|
if (++num_shown >= 10) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,47 +404,48 @@ SetTrayIcon(conn_state_t state)
|
||||||
TCHAR msg[500];
|
TCHAR msg[500];
|
||||||
TCHAR msg_connected[100];
|
TCHAR msg_connected[100];
|
||||||
TCHAR msg_connecting[100];
|
TCHAR msg_connecting[100];
|
||||||
int i, config = 0;
|
|
||||||
BOOL first_conn;
|
BOOL first_conn;
|
||||||
UINT icon_id;
|
UINT icon_id;
|
||||||
|
connection_t *cc = NULL; /* a connected config */
|
||||||
|
|
||||||
_tcsncpy(msg, LoadLocalizedString(IDS_TIP_DEFAULT), _countof(ni.szTip));
|
_tcsncpy(msg, LoadLocalizedString(IDS_TIP_DEFAULT), _countof(ni.szTip));
|
||||||
_tcsncpy(msg_connected, LoadLocalizedString(IDS_TIP_CONNECTED), _countof(msg_connected));
|
_tcsncpy(msg_connected, LoadLocalizedString(IDS_TIP_CONNECTED), _countof(msg_connected));
|
||||||
_tcsncpy(msg_connecting, LoadLocalizedString(IDS_TIP_CONNECTING), _countof(msg_connecting));
|
_tcsncpy(msg_connecting, LoadLocalizedString(IDS_TIP_CONNECTING), _countof(msg_connecting));
|
||||||
|
|
||||||
first_conn = TRUE;
|
first_conn = TRUE;
|
||||||
for (i = 0; i < o.num_configs; i++) {
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
if (o.conn[i].state == connected) {
|
{
|
||||||
|
if (c->state == connected) {
|
||||||
/* Append connection name to Icon Tip Msg */
|
/* Append connection name to Icon Tip Msg */
|
||||||
_tcsncat(msg, (first_conn ? msg_connected : _T(", ")), _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, (first_conn ? msg_connected : _T(", ")), _countof(msg) - _tcslen(msg) - 1);
|
||||||
_tcsncat(msg, o.conn[i].config_name, _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, c->config_name, _countof(msg) - _tcslen(msg) - 1);
|
||||||
first_conn = FALSE;
|
first_conn = FALSE;
|
||||||
config = i;
|
cc = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
first_conn = TRUE;
|
first_conn = TRUE;
|
||||||
for (i = 0; i < o.num_configs; i++) {
|
for (connection_t *c = o.chead; c; c = c->next)
|
||||||
if (o.conn[i].state == connecting || o.conn[i].state == resuming || o.conn[i].state == reconnecting) {
|
{
|
||||||
|
if (c->state == connecting || c->state == resuming || c->state == reconnecting) {
|
||||||
/* Append connection name to Icon Tip Msg */
|
/* Append connection name to Icon Tip Msg */
|
||||||
_tcsncat(msg, (first_conn ? msg_connecting : _T(", ")), _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, (first_conn ? msg_connecting : _T(", ")), _countof(msg) - _tcslen(msg) - 1);
|
||||||
_tcsncat(msg, o.conn[i].config_name, _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, c->config_name, _countof(msg) - _tcslen(msg) - 1);
|
||||||
first_conn = FALSE;
|
first_conn = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CountConnState(connected) == 1) {
|
if (CountConnState(connected) == 1 && cc) {
|
||||||
/* Append "Connected since and assigned IP" to message */
|
/* Append "Connected since and assigned IP" to message */
|
||||||
const connection_t *c = &o.conn[config];
|
|
||||||
TCHAR time[50];
|
TCHAR time[50];
|
||||||
|
|
||||||
LocalizedTime(o.conn[config].connected_since, time, _countof(time));
|
LocalizedTime(cc->connected_since, time, _countof(time));
|
||||||
_tcsncat(msg, LoadLocalizedString(IDS_TIP_CONNECTED_SINCE), _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, LoadLocalizedString(IDS_TIP_CONNECTED_SINCE), _countof(msg) - _tcslen(msg) - 1);
|
||||||
_tcsncat(msg, time, _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, time, _countof(msg) - _tcslen(msg) - 1);
|
||||||
|
|
||||||
/* concatenate ipv4 and ipv6 addresses into one string */
|
/* concatenate ipv4 and ipv6 addresses into one string */
|
||||||
WCHAR ip[64];
|
WCHAR ip[64];
|
||||||
wcs_concat2(ip, _countof(ip), c->ip, c->ipv6, L", ");
|
wcs_concat2(ip, _countof(ip), cc->ip, cc->ipv6, L", ");
|
||||||
WCHAR *assigned_ip = LoadLocalizedString(IDS_TIP_ASSIGNED_IP, ip);
|
WCHAR *assigned_ip = LoadLocalizedString(IDS_TIP_ASSIGNED_IP, ip);
|
||||||
_tcsncat(msg, assigned_ip, _countof(msg) - _tcslen(msg) - 1);
|
_tcsncat(msg, assigned_ip, _countof(msg) - _tcslen(msg) - 1);
|
||||||
}
|
}
|
||||||
|
@ -502,21 +505,8 @@ ShowTrayBalloon(TCHAR *infotitle_msg, TCHAR *info_msg)
|
||||||
void
|
void
|
||||||
SetMenuStatus(connection_t *c, conn_state_t state)
|
SetMenuStatus(connection_t *c, conn_state_t state)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < o.num_configs; ++i)
|
|
||||||
{
|
|
||||||
if (c == &o.conn[i])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SetMenuStatusById(i, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetMenuStatusById(int i, conn_state_t state)
|
|
||||||
{
|
|
||||||
connection_t *c = &o.conn[i];
|
|
||||||
int checked = 0;
|
int checked = 0;
|
||||||
|
int i = c->id;
|
||||||
|
|
||||||
if (state == connected || state == disconnecting) checked = 1;
|
if (state == connected || state == disconnecting) checked = 1;
|
||||||
else if (state != disconnected && state != detached && state != onhold) checked = 2;
|
else if (state != disconnected && state != detached && state != onhold) checked = 2;
|
||||||
|
|
1
tray.h
1
tray.h
|
@ -52,7 +52,6 @@ void OnDestroyTray(void);
|
||||||
void ShowTrayIcon();
|
void ShowTrayIcon();
|
||||||
void SetTrayIcon(conn_state_t);
|
void SetTrayIcon(conn_state_t);
|
||||||
void SetMenuStatus(connection_t *, conn_state_t);
|
void SetMenuStatus(connection_t *, conn_state_t);
|
||||||
void SetMenuStatusById(int, conn_state_t);
|
|
||||||
void SetServiceMenuStatus();
|
void SetServiceMenuStatus();
|
||||||
void ShowTrayBalloon(TCHAR *, TCHAR *);
|
void ShowTrayBalloon(TCHAR *, TCHAR *);
|
||||||
void CheckAndSetTrayIcon();
|
void CheckAndSetTrayIcon();
|
||||||
|
|
20
viewlog.c
20
viewlog.c
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
extern options_t o;
|
extern options_t o;
|
||||||
|
|
||||||
void ViewLog(int config)
|
void ViewLog(connection_t *c)
|
||||||
{
|
{
|
||||||
TCHAR filename[2*MAX_PATH];
|
TCHAR filename[2*MAX_PATH];
|
||||||
|
|
||||||
|
@ -54,15 +54,15 @@ void ViewLog(int config)
|
||||||
|
|
||||||
/* Try first using file association */
|
/* Try first using file association */
|
||||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */
|
||||||
status = ShellExecuteW (o.hWnd, L"open", o.conn[config].log_path, NULL, o.log_dir, SW_SHOWNORMAL);
|
status = ShellExecuteW (o.hWnd, L"open", c->log_path, NULL, o.log_dir, SW_SHOWNORMAL);
|
||||||
|
|
||||||
if (status > (HINSTANCE) 32) /* Success */
|
if (status > (HINSTANCE) 32) /* Success */
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
PrintDebug (L"Opening log file using ShellExecute with verb = open failed"
|
PrintDebug (L"Opening log file using ShellExecute with verb = open failed"
|
||||||
" for config '%ls' (status = %lu)", o.conn[config].config_name, status);
|
" for config '%ls' (status = %lu)", c->config_name, status);
|
||||||
|
|
||||||
_sntprintf_0(filename, _T("%ls \"%ls\""), o.log_viewer, o.conn[config].log_path);
|
_sntprintf_0(filename, _T("%ls \"%ls\""), o.log_viewer, c->log_path);
|
||||||
|
|
||||||
/* fill in STARTUPINFO struct */
|
/* fill in STARTUPINFO struct */
|
||||||
GetStartupInfo(&start_info);
|
GetStartupInfo(&start_info);
|
||||||
|
@ -92,7 +92,7 @@ void ViewLog(int config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EditConfig(int config)
|
void EditConfig(connection_t *c)
|
||||||
{
|
{
|
||||||
TCHAR filename[2*MAX_PATH];
|
TCHAR filename[2*MAX_PATH];
|
||||||
|
|
||||||
|
@ -108,17 +108,17 @@ void EditConfig(int config)
|
||||||
CLEAR (sd);
|
CLEAR (sd);
|
||||||
|
|
||||||
/* Try first using file association */
|
/* Try first using file association */
|
||||||
_sntprintf_0(filename, L"%ls\\%ls", o.conn[config].config_dir, o.conn[config].config_file);
|
_sntprintf_0(filename, L"%ls\\%ls", c->config_dir, c->config_file);
|
||||||
|
|
||||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */
|
||||||
status = ShellExecuteW (o.hWnd, L"open", filename, NULL, o.conn[config].config_dir, SW_SHOWNORMAL);
|
status = ShellExecuteW (o.hWnd, L"open", filename, NULL, c->config_dir, SW_SHOWNORMAL);
|
||||||
if (status > (HINSTANCE) 32)
|
if (status > (HINSTANCE) 32)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
PrintDebug (L"Opening config file using ShellExecute with verb = open failed"
|
PrintDebug (L"Opening config file using ShellExecute with verb = open failed"
|
||||||
" for config '%ls' (status = %lu)", o.conn[config].config_name, status);
|
" for config '%ls' (status = %lu)", c->config_name, status);
|
||||||
|
|
||||||
_sntprintf_0(filename, _T("%ls \"%ls\\%ls\""), o.editor, o.conn[config].config_dir, o.conn[config].config_file);
|
_sntprintf_0(filename, _T("%ls \"%ls\\%ls\""), o.editor, c->config_dir, c->config_file);
|
||||||
|
|
||||||
/* fill in STARTUPINFO struct */
|
/* fill in STARTUPINFO struct */
|
||||||
GetStartupInfo(&start_info);
|
GetStartupInfo(&start_info);
|
||||||
|
@ -135,7 +135,7 @@ void EditConfig(int config)
|
||||||
TRUE,
|
TRUE,
|
||||||
CREATE_NEW_CONSOLE,
|
CREATE_NEW_CONSOLE,
|
||||||
NULL,
|
NULL,
|
||||||
o.conn[config].config_dir, //start-up dir
|
c->config_dir, //start-up dir
|
||||||
&start_info,
|
&start_info,
|
||||||
&proc_info))
|
&proc_info))
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,5 +19,7 @@
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ViewLog(int config);
|
struct connection;
|
||||||
void EditConfig(int config);
|
|
||||||
|
void ViewLog(struct connection *c);
|
||||||
|
void EditConfig(struct connection *c);
|
||||||
|
|
Loading…
Reference in New Issue