From 47cff8747762cdecaced5045daf6855c654ad7a0 Mon Sep 17 00:00:00 2001 From: Heiko Hund Date: Thu, 25 Apr 2013 17:53:16 +0200 Subject: [PATCH] make auth popups show when returning from suspend --- Makefile.am | 3 ++- main.c | 44 ++++++++++++++++++++++++++++++++++---------- misc.c | 22 +++++++++++++++++++++- misc.h | 3 ++- openvpn.c | 31 +++++++++++++++++++++---------- options.h | 4 +++- proxy.c | 10 +++++++--- tray.c | 8 ++++---- 8 files changed, 94 insertions(+), 31 deletions(-) diff --git a/Makefile.am b/Makefile.am index e5f1184..841ec4c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -93,7 +93,8 @@ openvpn_gui_LDADD = \ $(OPENSSL_CRYPTO_LIBS) \ -lws2_32 \ -lcomctl32 \ - -lwinhttp + -lwinhttp \ + -lwtsapi32 openvpn-gui-res.o: $(openvpn_gui_RESOURCES) $(srcdir)/openvpn-gui-res.h $(RCCOMPILE) -i $< -o $@ diff --git a/main.c b/main.c index 74632fb..a19a07c 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -274,6 +275,22 @@ AutoStartConnections() } +static void +ResumeConnections() +{ + int i; + for (i = 0; i < o.num_configs; i++) { + /* Restart suspend connections */ + if (o.conn[i].state == suspended) + StartOpenVPN(&o.conn[i]); + + /* If some connection never reached SUSPENDED state */ + if (o.conn[i].state == suspending) + StopOpenVPN(&o.conn[i]); + } +} + + /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -288,6 +305,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); + WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION); + /* Load application icon */ HICON hIcon = LoadLocalizedIcon(ID_ICO_APP); if (hIcon) { @@ -350,6 +369,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_DESTROY: + WTSUnRegisterSessionNotification(hwnd); StopAllOpenVPN(); OnDestroyTray(); /* Remove Tray Icon and destroy menus */ PostQuitMessage (0); /* Send a WM_QUIT to the message queue */ @@ -363,6 +383,18 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM OnDestroyTray(); break; + case WM_WTSSESSION_CHANGE: + switch (wParam) { + case WTS_SESSION_LOCK: + o.session_locked = TRUE; + break; + case WTS_SESSION_UNLOCK: + o.session_locked = FALSE; + if (CountConnState(suspended) != 0) + ResumeConnections(); + break; + } + case WM_POWERBROADCAST: switch (wParam) { case PBT_APMSUSPEND: @@ -383,16 +415,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case PBT_APMRESUMESUSPEND: case PBT_APMRESUMECRITICAL: - for (i=0; i + * Copyright (C) 2013 Heiko Hund * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -181,3 +181,23 @@ wcseq(LPCWSTR str1, LPCWSTR str2) { return (wcscmp(str1, str2) == 0); } + + +/* + * Force setting window as foreground window by simulating an ALT keypress + */ +BOOL +ForceForegroundWindow(HWND hWnd) +{ + BOOL ret = FALSE; + + if ((GetKeyState(VK_MENU) & 0x8000) == 0) + keybd_event(VK_MENU, 0, 0, 0); + + ret = SetForegroundWindow(hWnd); + + if (GetKeyState(VK_MENU) & 0x8000) + keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); + + return ret; +} diff --git a/misc.h b/misc.h index b67c1a7..d513591 100644 --- a/misc.h +++ b/misc.h @@ -1,7 +1,7 @@ /* * OpenVPN-GUI -- A Windows GUI for OpenVPN. * - * Copyright (C) 2012 Heiko Hund + * Copyright (C) 2013 Heiko Hund * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,4 +30,5 @@ BOOL streq(LPCSTR, LPCSTR); BOOL wcsbegins(LPCWSTR, LPCWSTR); BOOL wcseq(LPCWSTR, LPCWSTR); +BOOL ForceForegroundWindow(HWND); #endif diff --git a/openvpn.c b/openvpn.c index 209e4eb..ea09cb1 100644 --- a/openvpn.c +++ b/openvpn.c @@ -147,7 +147,7 @@ OnStateChange(connection_t *c, char *data) if (strcmp(state, "CONNECTED") == 0) { /* Run Connect Script */ - if (c->state == connecting) + if (c->state == connecting || c->state == resuming) RunConnectScript(c, false); /* Save the local IP address if available */ @@ -161,6 +161,7 @@ OnStateChange(connection_t *c, char *data) /* Show connection tray balloon */ if ((c->state == connecting && o.show_balloon[0] != '0') + || (c->state == resuming && o.show_balloon[0] != '0') || (c->state == reconnecting && o.show_balloon[0] == '2')) { TCHAR msg[256]; @@ -211,9 +212,13 @@ UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { case WM_INITDIALOG: - /* Set connection for this dialog */ - SetProp(hwndDlg, cfgProp, (HANDLE) lParam); - SetForegroundWindow(hwndDlg); + /* Set connection for this dialog and show it */ + c = (connection_t *) lParam; + SetProp(hwndDlg, cfgProp, (HANDLE) c); + if (c->state == resuming) + ForceForegroundWindow(hwndDlg); + else + SetForegroundWindow(hwndDlg); break; case WM_COMMAND: @@ -265,9 +270,14 @@ PrivKeyPassDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { case WM_INITDIALOG: - /* Set connection for this dialog */ - SetProp(hwndDlg, cfgProp, (HANDLE) lParam); - SetForegroundWindow(hwndDlg); + /* Set connection for this dialog and show it */ + c = (connection_t *) lParam; + SetProp(hwndDlg, cfgProp, (HANDLE) c); + if (c->state == resuming) + ForceForegroundWindow(hwndDlg); + else + SetForegroundWindow(hwndDlg); + break; case WM_COMMAND: c = (connection_t *) GetProp(hwndDlg, cfgProp); @@ -353,11 +363,12 @@ OnStop(connection_t *c, UNUSED char *msg) SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); break; + case resuming: case connecting: case reconnecting: /* We have failed to (re)connect */ - txt_id = c->state == connecting ? IDS_NFO_STATE_FAILED : IDS_NFO_STATE_FAILED_RECONN; - msg_id = c->state == connecting ? IDS_NFO_CONN_FAILED : IDS_NFO_RECONN_FAILED; + txt_id = c->state == reconnecting ? IDS_NFO_STATE_FAILED_RECONN : IDS_NFO_STATE_FAILED; + msg_id = c->state == reconnecting ? IDS_NFO_RECONN_FAILED : IDS_NFO_CONN_FAILED; c->state = disconnecting; CheckAndSetTrayIcon(); @@ -545,7 +556,7 @@ ThreadOpenVPNStatus(void *p) _tcsncpy(conn_name, c->config_file, _countof(conn_name)); conn_name[_tcslen(conn_name) - _tcslen(o.ext_string) - 1] = _T('\0'); - c->state = connecting; + c->state = (c->state == suspended ? resuming : connecting); /* Create and Show Status Dialog */ c->hwndStatus = CreateLocalizedDialogParam(ID_DLG_STATUS, StatusDialogFunc, (LPARAM) c); diff --git a/options.h b/options.h index cc49d2b..6165d67 100644 --- a/options.h +++ b/options.h @@ -66,7 +66,8 @@ typedef enum { connected, disconnecting, suspending, - suspended + suspended, + resuming } conn_state_t; /* Connections parameters */ @@ -149,6 +150,7 @@ typedef struct { HWND hWnd; HINSTANCE hInstance; + BOOL session_locked; } options_t; void InitOptions(options_t *); diff --git a/proxy.c b/proxy.c index b1478c8..cbdf1e2 100644 --- a/proxy.c +++ b/proxy.c @@ -335,9 +335,13 @@ ProxyAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { case WM_INITDIALOG: - /* Set connection for this dialog */ - SetProp(hwndDlg, cfgProp, (HANDLE) lParam); - SetForegroundWindow(hwndDlg); + /* Set connection for this dialog and show it */ + c = (connection_t *) lParam; + SetProp(hwndDlg, cfgProp, (HANDLE) c); + if (c->state == resuming) + ForceForegroundWindow(hwndDlg); + else + SetForegroundWindow(hwndDlg); break; case WM_COMMAND: diff --git a/tray.c b/tray.c index 3959ae5..018b00e 100644 --- a/tray.c +++ b/tray.c @@ -280,7 +280,7 @@ SetTrayIcon(conn_state_t state) first_conn = TRUE; for (i = 0; i < o.num_configs; i++) { - if (o.conn[i].state == connecting || o.conn[i].state == reconnecting) { + if (o.conn[i].state == connecting || o.conn[i].state == resuming || o.conn[i].state == reconnecting) { /* Append connection name to Icon Tip Msg */ _tcsncat(msg, (first_conn ? msg_connecting : _T(", ")), _countof(msg) - _tcslen(msg) - 1); _tcsncat(msg, o.conn[i].config_name, _countof(msg) - _tcslen(msg) - 1); @@ -336,7 +336,7 @@ CheckAndSetTrayIcon() else { if (CountConnState(connecting) != 0 || CountConnState(reconnecting) != 0 - || o.service_state == service_connecting) + || CountConnState(resuming) != 0 || o.service_state == service_connecting) SetTrayIcon(connecting); else SetTrayIcon(disconnected); @@ -371,7 +371,7 @@ SetMenuStatus(connection_t *c, conn_state_t state) EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED); EnableMenuItem(hMenu, IDM_STATUSMENU, MF_GRAYED); } - else if (state == connecting || state == connected) + else if (state == connecting || state == resuming || state == connected) { EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED); EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_ENABLED); @@ -402,7 +402,7 @@ SetMenuStatus(connection_t *c, conn_state_t state) EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU + i, MF_GRAYED); EnableMenuItem(hMenuConn[i], IDM_STATUSMENU + i, MF_GRAYED); } - else if (state == connecting || state == connected) + else if (state == connecting || state == resuming || state == connected) { EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU + i, MF_GRAYED); EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU + i, MF_ENABLED);