|
|
|
@ -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) |
|
|
|
|