From 7d7f3572278dbc9234503ff7218ee5498272c53b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexander=20Steinh=C3=B6fer?= Date: Wed, 13 Apr 2022 20:38:17 +0200 Subject: [PATCH] WiFi muting with allow/blocklist. --- WinMute/Settings_WifiDlg.cpp | 15 ++++++++ WinMute/WMSettings.cpp | 10 ++++++ WinMute/WMSettings.h | 2 ++ WinMute/WiFiDetector.h | 9 ++++- WinMute/WifiDetector.cpp | 69 +++++++++++++++++++++++++++++++++--- WinMute/WinMute.cpp | 49 +++++++++++++++++++++++-- WinMute/WinMute.h | 2 ++ WinMute/WinMute.rc | 17 +++++---- WinMute/WinMute.vcxproj | 8 ++--- WinMute/common.h | 4 ++- WinMute/resource.h | 5 ++- 11 files changed, 169 insertions(+), 21 deletions(-) diff --git a/WinMute/Settings_WifiDlg.cpp b/WinMute/Settings_WifiDlg.cpp index a71f16d..73b31f8 100644 --- a/WinMute/Settings_WifiDlg.cpp +++ b/WinMute/Settings_WifiDlg.cpp @@ -134,6 +134,14 @@ INT_PTR CALLBACK Settings_GeneralWifiDlgProc(HWND hDlg, UINT msg, WPARAM wParam, assert(settings != nullptr); SetWindowLongPtr(hDlg, GWLP_USERDATA, reinterpret_cast(settings)); + DWORD enabled = settings->QueryValue(SettingsKey::MUTE_ON_WLAN); + Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE), + enabled ? BST_CHECKED : BST_UNCHECKED); + + enabled = settings->QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST); + Button_SetCheck(GetDlgItem(hDlg, IDC_IS_PERMITLIST), + enabled ? BST_CHECKED : BST_UNCHECKED); + Button_Enable(GetDlgItem(hDlg, IDC_WIFI_EDIT), FALSE); Button_Enable(GetDlgItem(hDlg, IDC_WIFI_REMOVE), FALSE); @@ -232,6 +240,13 @@ INT_PTR CALLBACK Settings_GeneralWifiDlgProc(HWND hDlg, UINT msg, WPARAM wParam, WMSettings* settings = reinterpret_cast(GetWindowLongPtr(hDlg, GWLP_USERDATA)); std::vector networks = ExportSsidListItems(GetDlgItem(hDlg, IDC_WIFI_LIST)); settings->StoreWifiNetworks(networks); + + DWORD checked = Button_GetCheck(GetDlgItem(hDlg, IDC_ENABLE_WIFI_MUTE)); + settings->SetValue(SettingsKey::MUTE_ON_WLAN, checked == BST_CHECKED); + + checked = Button_GetCheck(GetDlgItem(hDlg, IDC_IS_PERMITLIST)); + settings->SetValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST, checked == BST_CHECKED); + return 0; } default: diff --git a/WinMute/WMSettings.cpp b/WinMute/WMSettings.cpp index c502222..9b3349d 100644 --- a/WinMute/WMSettings.cpp +++ b/WinMute/WMSettings.cpp @@ -69,6 +69,12 @@ static LPCWSTR KeyToStr(SettingsKey key) case SettingsKey::MUTE_ON_LOGOUT: keyStr = _T("MuteOnLogout"); break; + case SettingsKey::MUTE_ON_WLAN: + keyStr = _T("MuteOnWlan"); + break; + case SettingsKey::MUTE_ON_WLAN_ALLOWLIST: + keyStr = _T("MuteOnWlanAllowList"); + break; case SettingsKey::QUIETHOURS_ENABLE: keyStr = _T("QuietHoursEnabled"); break; @@ -113,6 +119,10 @@ static DWORD GetDefaultSetting(SettingsKey key) return 0; case SettingsKey::MUTE_ON_LOGOUT: return 0; + case SettingsKey::MUTE_ON_WLAN: + return 0; + case SettingsKey::MUTE_ON_WLAN_ALLOWLIST: + return 0; case SettingsKey::QUIETHOURS_ENABLE: return 0; case SettingsKey::QUIETHOURS_FORCEUNMUTE: diff --git a/WinMute/WMSettings.h b/WinMute/WMSettings.h index a1b2d5a..c0b3722 100644 --- a/WinMute/WMSettings.h +++ b/WinMute/WMSettings.h @@ -44,6 +44,8 @@ enum class SettingsKey { , MUTE_ON_SUSPEND , MUTE_ON_SHUTDOWN , MUTE_ON_LOGOUT + , MUTE_ON_WLAN + , MUTE_ON_WLAN_ALLOWLIST , QUIETHOURS_ENABLE , QUIETHOURS_FORCEUNMUTE , QUIETHOURS_NOTIFICATIONS diff --git a/WinMute/WiFiDetector.h b/WinMute/WiFiDetector.h index c91fede..82e7524 100644 --- a/WinMute/WiFiDetector.h +++ b/WinMute/WiFiDetector.h @@ -35,6 +35,9 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" +/* wParam = Connected = 1 | Disconnected = 0. lParam = Pointer to Wifi Name */ +constexpr int WM_WIFISTATUSCHANGED = WM_USER + 400; + class WifiDetector { public: WifiDetector(); @@ -43,11 +46,15 @@ public: WifiDetector& operator=(const WifiDetector&) = delete; bool Init(HWND hNotifyWnd); - void SetNetworkList(const std::vector networks); + void Unload(); + void SetNetworkList(const std::vector networks, bool isMuteList); + + void WlanNotificationCallback(PWLAN_NOTIFICATION_DATA notifyData); private: HWND hNotifyWnd_; HANDLE wlanHandle_; + bool isMuteList_; bool initialized_; std::vector networks_; }; diff --git a/WinMute/WifiDetector.cpp b/WinMute/WifiDetector.cpp index fb020a9..2652ab3 100644 --- a/WinMute/WifiDetector.cpp +++ b/WinMute/WifiDetector.cpp @@ -35,8 +35,19 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" +static void WlanNotificationCallback( + PWLAN_NOTIFICATION_DATA unnamedParam1, + PVOID unnamedParam2) +{ + WifiDetector* wifiDetector = reinterpret_cast(unnamedParam2); + if (wifiDetector != nullptr) { + wifiDetector->WlanNotificationCallback(unnamedParam1); + } +} + + WifiDetector::WifiDetector() - : hNotifyWnd_(NULL), wlanHandle_(NULL), initialized_(false) + : hNotifyWnd_(NULL), wlanHandle_(NULL), isMuteList_(true), initialized_(false) { } @@ -44,13 +55,63 @@ WifiDetector::~WifiDetector() { } +void WifiDetector::Unload() +{ + if (initialized_) { + WlanRegisterNotification(wlanHandle_, WLAN_NOTIFICATION_SOURCE_NONE, + TRUE, NULL, NULL, NULL, NULL); + WlanCloseHandle(wlanHandle_, NULL); + initialized_ = false; + hNotifyWnd_ = NULL; + } +} + bool WifiDetector::Init(HWND hNotifyWnd) { - hNotifyWnd_ = hNotifyWnd; - return true; + if (!initialized_) { + DWORD vers = 2; + hNotifyWnd_ = hNotifyWnd; + DWORD wlErr = WlanOpenHandle(vers, NULL, &vers, &wlanHandle_); + if (wlErr != ERROR_SUCCESS) { + PrintWindowsError(_T("WlanOpenHandle"), wlErr); + } else { + wlErr = WlanRegisterNotification( + wlanHandle_, WLAN_NOTIFICATION_SOURCE_ACM, TRUE, + ::WlanNotificationCallback, this, NULL, NULL); + if (wlErr != ERROR_SUCCESS) { + PrintWindowsError(_T("WlanOpenHandle"), wlErr); + WlanCloseHandle(wlanHandle_, NULL); + } else { + initialized_ = true; + } + } + } + return initialized_; } -void WifiDetector::SetNetworkList(const std::vector networks) +void WifiDetector::SetNetworkList(const std::vector networks, bool isMuteList) { networks_ = networks; + isMuteList_ = isMuteList; +} + +void WifiDetector::WlanNotificationCallback(PWLAN_NOTIFICATION_DATA notifyData) +{ + if (notifyData->NotificationSource != WLAN_NOTIFICATION_SOURCE_ACM) { + return; + } + if (notifyData->NotificationCode == wlan_notification_acm_connection_complete + || notifyData->NotificationCode == wlan_notification_acm_disconnected) { + bool connected = notifyData->NotificationCode == wlan_notification_acm_connection_complete; + WLAN_CONNECTION_NOTIFICATION_DATA *wcnd = + reinterpret_cast(notifyData->pData); + const auto it = std::find(std::begin(networks_), std::end(networks_), + wcnd->strProfileName); + if (isMuteList_ && it != std::end(networks_)) { + SendMessage(hNotifyWnd_, WM_WIFISTATUSCHANGED, connected, + reinterpret_cast((*it).c_str())); + } else if (!isMuteList_ && it == std::end(networks_)) { + SendMessage(hNotifyWnd_, WM_WIFISTATUSCHANGED, connected, NULL); + } + } } diff --git a/WinMute/WinMute.cpp b/WinMute/WinMute.cpp index 797f468..5fe5c3d 100644 --- a/WinMute/WinMute.cpp +++ b/WinMute/WinMute.cpp @@ -247,6 +247,10 @@ bool WinMute::Init() #endif log.Write(_T("Starting new session...")); + if (!RegisterWindowClass() || !InitWindow()) { + return false; + } + if (!InitAudio()) { return false; } @@ -255,9 +259,7 @@ bool WinMute::Init() return false; } - if (!RegisterWindowClass() || - !InitWindow() || - !InitTrayMenu()) { + if (!InitTrayMenu()) { return false; } @@ -327,6 +329,15 @@ bool WinMute::LoadSettings() muteConfig_.quietHours.start = settings_.QueryValue(SettingsKey::QUIETHOURS_START); muteConfig_.quietHours.end = settings_.QueryValue(SettingsKey::QUIETHOURS_END); + muteConfig_.muteOnWlan = settings_.QueryValue(SettingsKey::MUTE_ON_WLAN); + if (muteConfig_.muteOnWlan) { + wifiDetector_.Init(hWnd_); + bool isMuteList = !settings_.QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST); + wifiDetector_.SetNetworkList(settings_.GetWifiNetworks(), isMuteList); + } else { + wifiDetector_.Unload(); + } + return true; } @@ -557,6 +568,38 @@ LRESULT CALLBACK WinMute::WindowProc( } return 0; } + case WM_WIFISTATUSCHANGED: + if (muteConfig_.muteOnWlan) { + if (wParam == 1) { // Connected + if (settings_.QueryValue(SettingsKey::NOTIFICATIONS_ENABLED)) { + TCHAR msgBuf[260] = { 0 }; + const TCHAR* wifiName = reinterpret_cast(lParam); + + if (settings_.QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST)) { + StringCchCopy( + msgBuf, + ARRAY_SIZE(msgBuf), + _T("Current WLAN network is not on allowed list for AutoMute")); + } else { +#ifdef _UNICODE + swprintf( + msgBuf, ARRAY_SIZE(msgBuf), + _T("WLAN network \"%s\" is configured for AutoMute."), + wifiName); +#else + sprintf_s( + msgBuf, + "WLAN network \"%s\" is configured for AutoMute.", + wifiName); +#endif + } + trayIcon_.ShowPopup(_T("Workstation muted"), msgBuf); + + } + muteCtrl_.SetMute(true); + } + } + return 0; case WM_SETTINGCHANGE: { if (lstrcmp(LPCTSTR(lParam), _T("ImmersiveColorSet")) == 0) { bool isDarkMode = true; diff --git a/WinMute/WinMute.h b/WinMute/WinMute.h index 88b2a72..f84f839 100644 --- a/WinMute/WinMute.h +++ b/WinMute/WinMute.h @@ -69,10 +69,12 @@ private: time_t start; time_t end; } quietHours; + bool muteOnWlan; } muteConfig_; TrayIcon trayIcon_; ScreensaverNotifier scrnSaverNoti_; + WifiDetector wifiDetector_; WMSettings settings_; MuteControl muteCtrl_; diff --git a/WinMute/WinMute.rc b/WinMute/WinMute.rc index e53c9f8..4a112c4 100644 --- a/WinMute/WinMute.rc +++ b/WinMute/WinMute.rc @@ -146,13 +146,16 @@ IDD_SETTINGS_WIFI DIALOGEX 0, 0, 242, 204 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LTEXT "WinMute can detect when you are connecting to a particular WiFi Network and mute your PC when it finishes connecting. \nHere you can manage SSIDs of networks that should trigger muting:",IDC_STATIC,7,7,228,35 - LISTBOX IDC_WIFI_LIST,7,40,170,134,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add",IDC_WIFI_ADD,179,40,56,16 - PUSHBUTTON "Edit",IDC_WIFI_EDIT,179,59,56,16 - PUSHBUTTON "Remove",IDC_WIFI_REMOVE,179,78,56,16 - PUSHBUTTON "Remove all",IDC_WIFI_REMOVEALL,179,98,56,16 - LTEXT "Note: This feature is currently experimental",IDC_STATIC,7,182,171,15 + LISTBOX IDC_WIFI_LIST,7,66,170,115,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_WIFI_ADD,179,65,56,16 + PUSHBUTTON "Edit",IDC_WIFI_EDIT,179,84,56,16 + PUSHBUTTON "Remove",IDC_WIFI_REMOVE,179,103,56,16 + PUSHBUTTON "Remove all",IDC_WIFI_REMOVEALL,179,123,56,16 + LTEXT "Note: This feature is currently experimental",IDC_STATIC,7,186,171,11 + CONTROL "Enable ""WLAN Mute"".",IDC_ENABLE_WIFI_MUTE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,26,228,14 + CONTROL "Mute workstation when WLAN network name is NOT in list\n(default: mute if in list).",IDC_IS_PERMITLIST, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,41,228,18 + LTEXT """WLAN Mute"" allows you to mute your workstation based on the name of the connected wireless network.",IDC_STATIC,7,7,228,19 END IDD_SETTINGS_WIFI_ADD DIALOGEX 0, 0, 201, 62 diff --git a/WinMute/WinMute.vcxproj b/WinMute/WinMute.vcxproj index 473bcd5..3a76e08 100644 --- a/WinMute/WinMute.vcxproj +++ b/WinMute/WinMute.vcxproj @@ -110,7 +110,7 @@ Windows true - strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Version.lib;%(AdditionalDependencies) + strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Wlanapi.lib;Version.lib;%(AdditionalDependencies) PerMonitorHighDPIAware @@ -136,7 +136,7 @@ true true true - strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Version.lib;%(AdditionalDependencies) + strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Wlanapi.lib;Version.lib;%(AdditionalDependencies) PerMonitorHighDPIAware @@ -157,7 +157,7 @@ Windows true - strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Version.lib;%(AdditionalDependencies) + strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Wlanapi.lib;Version.lib;%(AdditionalDependencies) PerMonitorHighDPIAware @@ -183,7 +183,7 @@ true true true - strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Version.lib;%(AdditionalDependencies) + strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Wlanapi.lib;Version.lib;%(AdditionalDependencies) PerMonitorHighDPIAware diff --git a/WinMute/common.h b/WinMute/common.h index 7613810..a0c354c 100644 --- a/WinMute/common.h +++ b/WinMute/common.h @@ -73,6 +73,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #pragma warning(disable : 4201) # include @@ -87,9 +88,10 @@ POSSIBILITY OF SUCH DAMAGE. #include "TrayIcon.h" #include "WinAudio.h" #include "MuteControl.h" +#include "WiFiDetector.h" #include "WinMute.h" #include "VersionHelper.h" -#include "WiFiDetector.h" + // Utility void PrintWindowsError(LPCWSTR lpszFunction, DWORD lastError = -1); diff --git a/WinMute/resource.h b/WinMute/resource.h index 8155bca..0ad7729 100644 --- a/WinMute/resource.h +++ b/WinMute/resource.h @@ -32,6 +32,7 @@ #define IDC_CHECK1 1011 #define IDC_RUNONSTARTUP 1011 #define IDC_MUTE_WHEN_WS_LOCKED 1011 +#define IDC_ENABLE_WIFI_MUTE 1011 #define IDC_ENABLELOGGING 1012 #define IDC_CHECK3 1013 #define IDC_OPENLOG 1014 @@ -54,6 +55,8 @@ #define IDC_MUTE_WHEN_SLEEP 1027 #define IDC_WIFI_REMOVE2 1027 #define IDC_WIFI_REMOVEALL 1027 +#define IDC_CHECK2 1028 +#define IDC_IS_PERMITLIST 1028 #define ID_TRAYMENU_INFO 40001 #define ID_TRAYMENU_ 40002 #define ID_TRAYMENU_MUTEON 40003 @@ -89,7 +92,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 131 #define _APS_NEXT_COMMAND_VALUE 40029 -#define _APS_NEXT_CONTROL_VALUE 1026 +#define _APS_NEXT_CONTROL_VALUE 1029 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif -- 2.43.0