mirror of https://github.com/OpenVPN/openvpn-gui
commit
135f177546
|
@ -296,4 +296,7 @@
|
|||
/* Save password related messages */
|
||||
#define IDS_NFO_DELETE_PASS 2001
|
||||
|
||||
/* Timer IDs */
|
||||
#define IDT_STOP_TIMER 2500 /* Timer used to trigger force termination */
|
||||
|
||||
#endif
|
||||
|
|
88
openvpn.c
88
openvpn.c
|
@ -54,6 +54,9 @@
|
|||
|
||||
extern options_t o;
|
||||
|
||||
static BOOL
|
||||
TerminateOpenVPN(connection_t *c);
|
||||
|
||||
const TCHAR *cfgProp = _T("conn");
|
||||
|
||||
typedef struct {
|
||||
|
@ -471,7 +474,8 @@ OnStop(connection_t *c, UNUSED char *msg)
|
|||
SetForegroundWindow(c->hwndStatus);
|
||||
ShowWindow(c->hwndStatus, SW_SHOW);
|
||||
}
|
||||
ShowLocalizedMsg(IDS_NFO_CONN_TERMINATED, c->config_name);
|
||||
MessageBox(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONN_TERMINATED, c->config_file),
|
||||
_T(PACKAGE_NAME), MB_OK);
|
||||
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
|
||||
|
@ -498,7 +502,7 @@ OnStop(connection_t *c, UNUSED char *msg)
|
|||
SetForegroundWindow(c->hwndStatus);
|
||||
ShowWindow(c->hwndStatus, SW_SHOW);
|
||||
}
|
||||
ShowLocalizedMsg(msg_id, msg_xtra);
|
||||
MessageBox(c->hwndStatus, LoadLocalizedString(msg_id, msg_xtra), _T(PACKAGE_NAME), MB_OK);
|
||||
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
|
||||
|
@ -658,10 +662,15 @@ HandleServiceIO (DWORD err, DWORD bytes, LPOVERLAPPED lpo)
|
|||
int len, capacity;
|
||||
|
||||
len = _countof(s->readbuf);
|
||||
capacity = len*sizeof(*(s->readbuf));
|
||||
capacity = (len-1)*sizeof(*(s->readbuf));
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
/* messages from the service are not nul terminated */
|
||||
int nchars = bytes/sizeof(s->readbuf[0]);
|
||||
s->readbuf[nchars] = L'\0';
|
||||
SetEvent (s->hEvent);
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
_snwprintf(s->readbuf, len, L"0x%08x\nInteractive Service disconnected\n", err);
|
||||
|
@ -714,6 +723,7 @@ static void
|
|||
OnService(connection_t *c, UNUSED char *msg)
|
||||
{
|
||||
DWORD err = 0;
|
||||
DWORD pid = 0;
|
||||
WCHAR *p, *buf, *next;
|
||||
DWORD len;
|
||||
const WCHAR *prefix = L"IService> ";
|
||||
|
@ -730,6 +740,17 @@ OnService(connection_t *c, UNUSED char *msg)
|
|||
}
|
||||
|
||||
p = buf + 11;
|
||||
if (!err && swscanf (p, L"0x%08x\nProcess ID", &pid) == 1 && pid != 0)
|
||||
{
|
||||
PrintDebug (L"Process ID of openvpn started by IService: %d", pid);
|
||||
c->hProcess = OpenProcess (PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, pid);
|
||||
if (!c->hProcess)
|
||||
PrintDebug (L"Failed to get process handle from pid of openvpn: error = %lu",
|
||||
GetLastError());
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
while (iswspace(*p)) ++p;
|
||||
|
||||
while (p && *p)
|
||||
|
@ -791,10 +812,11 @@ Cleanup (connection_t *c)
|
|||
|
||||
if (c->hProcess)
|
||||
CloseHandle (c->hProcess);
|
||||
else
|
||||
CloseServiceIO (&c->iserv);
|
||||
c->hProcess = NULL;
|
||||
|
||||
if (c->iserv.hEvent)
|
||||
CloseServiceIO (&c->iserv);
|
||||
|
||||
if (c->exit_event)
|
||||
CloseHandle (c->exit_event);
|
||||
c->exit_event = NULL;
|
||||
|
@ -926,6 +948,7 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
SetMenuStatus(c, disconnecting);
|
||||
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM));
|
||||
SetEvent(c->exit_event);
|
||||
SetTimer(hwndDlg, IDT_STOP_TIMER, 3000, NULL);
|
||||
break;
|
||||
|
||||
case WM_OVPN_SUSPEND:
|
||||
|
@ -936,6 +959,18 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
SetMenuStatus(c, disconnecting);
|
||||
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM));
|
||||
SetEvent(c->exit_event);
|
||||
SetTimer(hwndDlg, IDT_STOP_TIMER, 3000, NULL);
|
||||
break;
|
||||
|
||||
case WM_TIMER:
|
||||
PrintDebug(L"WM_TIMER message with wParam = %lu", wParam);
|
||||
c = (connection_t *) GetProp(hwndDlg, cfgProp);
|
||||
if (wParam == IDT_STOP_TIMER)
|
||||
{
|
||||
/* openvpn failed to respond to stop signal -- terminate */
|
||||
TerminateOpenVPN(c);
|
||||
KillTimer (hwndDlg, IDT_STOP_TIMER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -974,7 +1009,7 @@ ThreadOpenVPNStatus(void *p)
|
|||
PostMessage(c->hwndStatus, WM_CLOSE, 0, 0);
|
||||
|
||||
/* Start the async read loop for service and set it as the wait event */
|
||||
if (!c->hProcess)
|
||||
if (c->iserv.hEvent)
|
||||
{
|
||||
HandleServiceIO (0, 0, (LPOVERLAPPED) &c->iserv);
|
||||
wait_event = c->iserv.hEvent;
|
||||
|
@ -994,9 +1029,9 @@ ThreadOpenVPNStatus(void *p)
|
|||
if ((res = MsgWaitForMultipleObjectsEx (1, &wait_event, INFINITE, QS_ALLINPUT,
|
||||
MWMO_ALERTABLE)) == WAIT_OBJECT_0)
|
||||
{
|
||||
if (c->hProcess)
|
||||
if (wait_event == c->hProcess)
|
||||
OnProcess (c, NULL);
|
||||
else
|
||||
else if (wait_event == c->iserv.hEvent)
|
||||
OnService (c, NULL);
|
||||
}
|
||||
continue;
|
||||
|
@ -1011,6 +1046,7 @@ ThreadOpenVPNStatus(void *p)
|
|||
|
||||
/* release handles etc.*/
|
||||
Cleanup (c);
|
||||
c->hwndStatus = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1055,6 +1091,15 @@ StartOpenVPN(connection_t *c)
|
|||
|
||||
CLEAR(c->ip);
|
||||
|
||||
if (c->hwndStatus)
|
||||
{
|
||||
PrintDebug(L"Connection request when previous status window is still open -- ignored");
|
||||
WriteStatusLog(c, L"OpenVPN GUI> ",
|
||||
L"Complete the pending dialog before starting a new connection", false);
|
||||
SetForegroundWindow(c->hwndStatus);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RunPreconnectScript(c);
|
||||
|
||||
/* Create thread to show the connection's status dialog */
|
||||
|
@ -1219,6 +1264,33 @@ StopOpenVPN(connection_t *c)
|
|||
PostMessage(c->hwndStatus, WM_OVPN_STOP, 0, 0);
|
||||
}
|
||||
|
||||
/* force-kill as a last resort */
|
||||
static BOOL
|
||||
TerminateOpenVPN (connection_t *c)
|
||||
{
|
||||
DWORD exit_code = 0;
|
||||
BOOL retval = TRUE;
|
||||
|
||||
if (!c->hProcess)
|
||||
return retval;
|
||||
if (!GetExitCodeProcess (c->hProcess, &exit_code))
|
||||
{
|
||||
PrintDebug (L"In TerminateOpenVPN: failed to get process status: error = %lu", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (exit_code == STILL_ACTIVE)
|
||||
{
|
||||
retval = TerminateProcess (c->hProcess, 1);
|
||||
if (retval)
|
||||
PrintDebug (L"Openvpn Process for config '%s' terminated", c->config_name);
|
||||
else
|
||||
PrintDebug (L"Failed to terminate openvpn Process for config '%s'", c->config_name);
|
||||
}
|
||||
else
|
||||
PrintDebug(L"In TerminateOpenVPN: Process is not active");
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
SuspendOpenVPN(int config)
|
||||
|
|
Loading…
Reference in New Issue