From: lx-s Date: Tue, 19 Dec 2023 13:53:22 +0000 (+0100) Subject: Fixed dialog tabs. Renamed log functions. New updater format to allow beta updates X-Git-Tag: 2.4.9.0~22 X-Git-Url: https://repos.lx-s.de/gitweb/?a=commitdiff_plain;h=5cf79f40c172b180c62979715028ccb170357468;p=winmute.git Fixed dialog tabs. Renamed log functions. New updater format to allow beta updates --- diff --git a/CURRENT_VERSION b/CURRENT_VERSION index 87199af..55d5810 100644 --- a/CURRENT_VERSION +++ b/CURRENT_VERSION @@ -1,4 +1,11 @@ { - "version": "2.4.1.0", - "versionPage": "https://github.com/lx-s/WinMute/releases/" + "version": 1, + "stable": { + "version": "2.4.1.0", + "downloadUrl": "https://github.com/lx-s/WinMute/releases/" + }, + "beta": { + "version": "2.9.0.0", + "downloadUrl": "https://github.com/lx-s/WinMute/releases/" + } } diff --git a/Translations/lang-en.json b/Translations/lang-en.json index 1f7638b..bf69122 100644 --- a/Translations/lang-en.json +++ b/Translations/lang-en.json @@ -14,6 +14,8 @@ "general.error.audio-service-shutdown.text": "WinMute is not able to recover from that condition.\nPlease try to restart the program.", "popup.update-available.title": "WinMute {} is available!", "popup.update-available.text": "Your current version is {}.\nClick on this message to open the download page.", + "popup.update-available-beta.title": "WinMute Beta {} is available!", + "popup.update-available-beta.text": "Your current version is {}.\nClick on this message to open the beta-download page.", "popup.error.update-check-failed.title": "Update check failed.", "pupup.error.update-check-failed.text": "Unable to check for a new version.\nPlease check/enable logging for further details.", "popup.remote-session-detected.title": "Remote Session detected", @@ -67,7 +69,8 @@ "settings.bluetooth.add-edit.edit-title": "Edit Bluetooth device", "settings.bluetooth.add-edit.device-name-label": "Bluetooth device name:", "settings.general.run-on-startup": "Run WinMute when this user logs on", - "settings.general.check-for-updates-on-start": "Check for updates on startup", + "settings.general.check-for-updates-on-start": "Check for new updates on startup", + "settings.general.check-for-beta-updates-on-start": "Also check for new beta versions", "settings.general.enable-logging": "Enable logging", "settings.general.btn-open-log-file": "Open log file...", "settings.general.select-language-label": "Language", diff --git a/WinMute/AboutDlg.cpp b/WinMute/AboutDlg.cpp index bc2bb77..70ca166 100644 --- a/WinMute/AboutDlg.cpp +++ b/WinMute/AboutDlg.cpp @@ -123,7 +123,7 @@ static void ResizeTabs(HWND hTabCtrl, std::span tabs) HDWP hdwp = BeginDeferWindowPos(static_cast(tabs.size())); if (hdwp == nullptr) { - PrintWindowsError(L"BeginDeferWindowPos", GetLastError()); + ShowWindowsError(L"BeginDeferWindowPos", GetLastError()); } else { for (auto hTab : tabs) { HDWP newHdwp = DeferWindowPos( @@ -136,7 +136,7 @@ static void ResizeTabs(HWND hTabCtrl, std::span tabs) tabCtrlRect.bottom - tabCtrlRect.top, 0); if (newHdwp == nullptr) { - PrintWindowsError(L"DeferWindowPos", GetLastError()); + ShowWindowsError(L"DeferWindowPos", GetLastError()); break; } else { hdwp = newHdwp; diff --git a/WinMute/BluetoothDetector.cpp b/WinMute/BluetoothDetector.cpp index 580e47c..9140584 100644 --- a/WinMute/BluetoothDetector.cpp +++ b/WinMute/BluetoothDetector.cpp @@ -65,7 +65,7 @@ bool BluetoothDetector::LoadRadioNotifications() const BLUETOOTH_FIND_RADIO_PARAMS bfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) }; HBLUETOOTH_RADIO_FIND hRadiosFind = BluetoothFindFirstRadio(&bfrp, &btHandle); if (hRadiosFind == nullptr) { - log.WriteWindowsError(L"BluetoothFindFirstRadio", GetLastError()); + log.LogWinError(L"BluetoothFindFirstRadio", GetLastError()); return false; } @@ -83,14 +83,14 @@ bool BluetoothDetector::LoadRadioNotifications() CloseHandle(btHandle); if (devNotify == nullptr) { - log.WriteWindowsError(L"RegisterDeviceNotification", GetLastError()); + log.LogWinError(L"RegisterDeviceNotification", GetLastError()); } else { notificationHandles_.push_back(devNotify); } } while (BluetoothFindNextRadio(hRadiosFind, &btHandle)); const DWORD dwLastError = GetLastError(); if (dwLastError != ERROR_NO_MORE_ITEMS) { - log.WriteWindowsError(L"BluetoothFindNextRadio", GetLastError()); + log.LogWinError(L"BluetoothFindNextRadio", GetLastError()); UnloadRadioNotifications(); } else { success = true; @@ -158,15 +158,15 @@ BluetoothDetector::BluetoothStatus BluetoothDetector::GetBluetoothStatus( if (useDeviceList_) { auto pos = std::find(begin(deviceNames_), end(deviceNames_), inRangeInfo->deviceInfo.name); if (pos == end(deviceNames_)) { - log.Write(L"Bluetooth device \"%S\" not in list.", inRangeInfo->deviceInfo.name); + log.LogInfo(L"Bluetooth device \"%S\" not in list.", inRangeInfo->deviceInfo.name); return BluetoothStatus::Unknown; } } if ((inRangeInfo->deviceInfo.flags & BDIF_CONNECTED) && !(inRangeInfo->previousDeviceFlags & BDIF_CONNECTED)) { - log.Write(L"Bluetooth Audio device \"%S\" connected.", inRangeInfo->deviceInfo.name); + log.LogInfo(L"Bluetooth Audio device \"%S\" connected.", inRangeInfo->deviceInfo.name); return BluetoothStatus::Connected; } else if (!(inRangeInfo->deviceInfo.flags & BDIF_CONNECTED) && (inRangeInfo->previousDeviceFlags & BDIF_CONNECTED)) { - log.Write(L"Bluetooth Audio device \"%S\" disconnected.", inRangeInfo->deviceInfo.name); + log.LogInfo(L"Bluetooth Audio device \"%S\" disconnected.", inRangeInfo->deviceInfo.name); return BluetoothStatus::Disconnected; } return BluetoothStatus::Unknown; diff --git a/WinMute/MMNotificationClient.cpp b/WinMute/MMNotificationClient.cpp index 529f175..63c008a 100644 --- a/WinMute/MMNotificationClient.cpp +++ b/WinMute/MMNotificationClient.cpp @@ -90,7 +90,7 @@ HRESULT STDMETHODCALLTYPE MMNotificationClient::OnDeviceAdded(LPCWSTR pwstrDevic { if (notifyParent_ && pwstrDeviceId != nullptr) { const auto deviceName = GetFriendlyDeviceName(pwstrDeviceId); - WMLog::GetInstance().GetInstance().Write(L"Device \"%s\" added", deviceName.c_str()); + WMLog::GetInstance().GetInstance().LogInfo(L"Device \"%s\" added", deviceName.c_str()); notifyParent_->ShouldReInit(); } return S_OK; @@ -100,7 +100,7 @@ HRESULT STDMETHODCALLTYPE MMNotificationClient::OnDeviceRemoved(LPCWSTR pwstrDev { if (notifyParent_ && pwstrDeviceId != nullptr) { const auto deviceName = GetFriendlyDeviceName(pwstrDeviceId); - WMLog::GetInstance().GetInstance().Write(L"Device \"%s\" removed", deviceName.c_str()); + WMLog::GetInstance().GetInstance().LogInfo(L"Device \"%s\" removed", deviceName.c_str()); notifyParent_->ShouldReInit(); } return S_OK; @@ -127,7 +127,7 @@ HRESULT STDMETHODCALLTYPE MMNotificationClient::OnDeviceStateChanged( if (notify && notifyParent_) { // TODO: Check if output device const auto deviceName = GetFriendlyDeviceName(pwstrDeviceId); - WMLog::GetInstance().GetInstance().Write( + WMLog::GetInstance().GetInstance().LogInfo( L"Device \"%s\" status changed to %s", deviceName.c_str(), what.c_str()); diff --git a/WinMute/MuteControl.cpp b/WinMute/MuteControl.cpp index 81cf9ae..27ad22f 100644 --- a/WinMute/MuteControl.cpp +++ b/WinMute/MuteControl.cpp @@ -109,7 +109,7 @@ bool MuteControl::Init(HWND hParent, const TrayIcon *trayIcon) wndClass.hInstance = hglobInstance; wndClass.lpszClassName = MUTECONTROL_CLASS_NAME; if (!RegisterClassExW(&wndClass)) { - WMLog::GetInstance().WriteWindowsError(L"RegisterClassEx"); + WMLog::GetInstance().LogWinError(L"RegisterClassEx"); return false; } hMuteCtrlWnd_ = CreateWindowEx( @@ -123,7 +123,7 @@ bool MuteControl::Init(HWND hParent, const TrayIcon *trayIcon) hglobInstance, this); if (hMuteCtrlWnd_ == nullptr) { - WMLog::GetInstance().WriteWindowsError(L"CreateWindowEx"); + WMLog::GetInstance().LogWinError(L"CreateWindowEx"); UnregisterClassW(MUTECONTROL_CLASS_NAME, hglobInstance); return false; } @@ -149,7 +149,7 @@ LRESULT CALLBACK MuteControl::WindowProc( void MuteControl::SetMute(bool mute) { - WMLog::GetInstance().Write(L"Manual muting: %s", mute ? L"on" : L"off"); + WMLog::GetInstance().LogInfo(L"Manual muting: %s", mute ? L"on" : L"off"); winAudio_->SetMute(mute); } @@ -164,9 +164,9 @@ void MuteControl::SaveMuteStatus() ); if (alreadySaved) { - WMLog::GetInstance().Write(L"Muting event already active. Skipping status save"); + WMLog::GetInstance().LogInfo(L"Muting event already active. Skipping status save"); } else { - WMLog::GetInstance().Write(L"Saving mute status"); + WMLog::GetInstance().LogInfo(L"Saving mute status"); winAudio_->SaveMuteStatus(); } } @@ -188,7 +188,7 @@ void MuteControl::MuteDelayed(int magic) if (magic != MUTE_DELAY_MAGIC_VALUE || delayedMuteTimerId_ == 0) { return; } - WMLog::GetInstance().Write(L"Muting workstation after delay"); + WMLog::GetInstance().LogInfo(L"Muting workstation after delay"); ShowNotification( WMi18n::GetInstance().GetTranslationW("popup.muting-workstation-after-delay.title"), WMi18n::GetInstance().GetTranslationW("popup.muting-workstation-after-delay.text")); @@ -205,7 +205,7 @@ bool MuteControl::StartDelayedMute() muteDelaySeconds_ * 1000, DelayedMuteTimerProc); if (delayedMuteTimerId_ == 0) { - WMLog::GetInstance().WriteWindowsError(L"SetTimer", GetLastError()); + WMLog::GetInstance().LogWinError(L"SetTimer", GetLastError()); } return delayedMuteTimerId_ != 0; } @@ -214,7 +214,7 @@ void MuteControl::RestoreVolume(bool withDelay) { WMLog& log = WMLog::GetInstance(); if (!restoreVolume_) { - log.Write(L"Volume Restore has been disabled"); + log.LogInfo(L"Volume Restore has been disabled"); return; } const bool restore = !std::any_of( @@ -225,13 +225,13 @@ void MuteControl::RestoreVolume(bool withDelay) } ); if (!restore) { - log.Write(L"Skipping restore since other mute event is currently active"); + log.LogInfo(L"Skipping restore since other mute event is currently active"); } else if (delayedMuteTimerId_ != 0) { KillTimer(hMuteCtrlWnd_, delayedMuteTimerId_); delayedMuteTimerId_ = 0; - log.Write(L"Skipping restore, since delayed mute was not triggered yet"); + log.LogInfo(L"Skipping restore, since delayed mute was not triggered yet"); } else { - log.Write(L"Restoring previous mute state"); + log.LogInfo(L"Restoring previous mute state"); ShowNotification( WMi18n::GetInstance().GetTranslationW("popup.volume-restored.title"), WMi18n::GetInstance().GetTranslationW("popup.volume-restored.text")); @@ -334,13 +334,13 @@ void MuteControl::NotifyRestoreCondition(int type, bool active, bool withDelay) muteConfig_[type].active = active; if (muteConfig_[type].shouldMute) { if (muteDelaySeconds_ == 0) { - WMLog::GetInstance().Write(L"Muting workstation"); + WMLog::GetInstance().LogInfo(L"Muting workstation"); ShowNotification( WMi18n::GetInstance().GetTranslationW("popup.muting-workstation.title"), WMi18n::GetInstance().GetTranslationW("popup.muting-workstation.text")); winAudio_->SetMute(true); } else { - WMLog::GetInstance().Write(L"Starting delayed mute timer..."); + WMLog::GetInstance().LogInfo(L"Starting delayed mute timer..."); StartDelayedMute(); } } @@ -356,14 +356,14 @@ void MuteControl::NotifyRestoreCondition(int type, bool active, bool withDelay) void MuteControl::NotifyWorkstationLock(bool active) { - WMLog::GetInstance().Write(L"Mute Event: Workstation Lock %s", + WMLog::GetInstance().LogInfo(L"Mute Event: Workstation Lock %s", active ? L"start" : L"stop"); NotifyRestoreCondition(MuteTypeWorkstationLock, active); } void MuteControl::NotifyRemoteSession(bool active) { - WMLog::GetInstance().Write(L"Mute Event: Remote Session %s", + WMLog::GetInstance().LogInfo(L"Mute Event: Remote Session %s", active ? L"start" : L"stop"); NotifyRestoreCondition(MuteTypeRemoteSession, active); } @@ -371,7 +371,7 @@ void MuteControl::NotifyRemoteSession(bool active) void MuteControl::NotifyDisplayStandby(bool active) { if (displayWasOffOnce_ || active) { - WMLog::GetInstance().Write(L"Mute Event: Display Standby %s", + WMLog::GetInstance().LogInfo(L"Mute Event: Display Standby %s", active ? L"start" : L"stop"); NotifyRestoreCondition(MuteTypeDisplayStandby, active); displayWasOffOnce_ = true; @@ -380,7 +380,7 @@ void MuteControl::NotifyDisplayStandby(bool active) void MuteControl::NotifyBluetoothConnected(bool connected) { - WMLog::GetInstance().Write( + WMLog::GetInstance().LogInfo( L"Mute Event: Bluetooth audio device %s", connected ? L"connected" : L"disconnected"); NotifyRestoreCondition(MuteTypeBluetoothDisconnect, !connected, true); @@ -388,7 +388,7 @@ void MuteControl::NotifyBluetoothConnected(bool connected) void MuteControl::NotifyLogout() { - WMLog::GetInstance().Write(L"Mute Event: Logout start"); + WMLog::GetInstance().LogInfo(L"Mute Event: Logout start"); if (muteConfig_[MuteTypeLogout].shouldMute) { winAudio_->SetMute(true); } @@ -396,7 +396,7 @@ void MuteControl::NotifyLogout() void MuteControl::NotifySuspend(bool /*active*/) { - WMLog::GetInstance().Write(L"Mute Event: Suspend start"); + WMLog::GetInstance().LogInfo(L"Mute Event: Suspend start"); if (muteConfig_[MuteTypeSuspend].shouldMute) { winAudio_->SetMute(true); } @@ -404,7 +404,7 @@ void MuteControl::NotifySuspend(bool /*active*/) void MuteControl::NotifyShutdown() { - WMLog::GetInstance().Write(L"Mute Event: Shutdown start"); + WMLog::GetInstance().LogInfo(L"Mute Event: Shutdown start"); if (muteConfig_[MuteTypeShutdown].shouldMute) { winAudio_->SetMute(true); } @@ -414,11 +414,11 @@ void MuteControl::NotifyQuietHours(bool active) { if (active) { SaveMuteStatus(); - WMLog::GetInstance().Write(L"Mute Event: Quiet Hours startet"); + WMLog::GetInstance().LogInfo(L"Mute Event: Quiet Hours startet"); winAudio_->SaveMuteStatus(); winAudio_->SetMute(true); } else { - WMLog::GetInstance().Write(L"Mute Event: Quiet Hours ended"); + WMLog::GetInstance().LogInfo(L"Mute Event: Quiet Hours ended"); RestoreVolume(); } } diff --git a/WinMute/QuietHoursTimer.cpp b/WinMute/QuietHoursTimer.cpp index 2de8ab5..fbf6cbc 100644 --- a/WinMute/QuietHoursTimer.cpp +++ b/WinMute/QuietHoursTimer.cpp @@ -149,7 +149,7 @@ bool QuietHoursTimer::LoadFromSettings(const WMSettings& settings) end.wHour = static_cast((qhEnd_ - end.wMinute - end.wSecond) / 3600); if (IsQuietHours(&now, &start, &end)) { - WMLog::GetInstance().Write(L"Mute: On | Quiet hours have already started"); + WMLog::GetInstance().LogInfo(L"Mute: On | Quiet hours have already started"); SendMessage(hParent_, WM_WINMUTE_QUIETHOURS_START, 0, 0); } else { int timerQhStart = GetDiffMillseconds(&start, &now); diff --git a/WinMute/SettingsDlg.cpp b/WinMute/SettingsDlg.cpp index 4e9eb77..42188ec 100644 --- a/WinMute/SettingsDlg.cpp +++ b/WinMute/SettingsDlg.cpp @@ -104,7 +104,7 @@ static void ResizeTabs(HWND hTabCtrl, HWND* hTabs, int tabCount) HDWP hdwp = BeginDeferWindowPos(tabCount); if (hdwp == nullptr) { - PrintWindowsError(L"BeginDeferWindowPos", GetLastError()); + ShowWindowsError(L"BeginDeferWindowPos", GetLastError()); } else { for (int i = 0; i < tabCount; ++i) { HDWP newHdwp = DeferWindowPos( @@ -117,7 +117,7 @@ static void ResizeTabs(HWND hTabCtrl, HWND* hTabs, int tabCount) tabCtrlRect.bottom - tabCtrlRect.top, 0); if (newHdwp == nullptr) { - PrintWindowsError(L"DeferWindowPos", GetLastError()); + ShowWindowsError(L"DeferWindowPos", GetLastError()); break; } else { hdwp = newHdwp; diff --git a/WinMute/Settings_BluetoothDlg.cpp b/WinMute/Settings_BluetoothDlg.cpp index e52a1db..b26e1c3 100644 --- a/WinMute/Settings_BluetoothDlg.cpp +++ b/WinMute/Settings_BluetoothDlg.cpp @@ -52,7 +52,7 @@ static bool GetPairedBtAudioDevices(std::vector& devices) btdi.dwSize = sizeof(btdi); HBLUETOOTH_DEVICE_FIND hBtDevFind = BluetoothFindFirstDevice(&bfrp, &btdi); if (hBtDevFind == nullptr) { - log.WriteWindowsError(L"BluetoothFindFirstDevice", GetLastError()); + log.LogWinError(L"BluetoothFindFirstDevice", GetLastError()); } else { do { if (GET_COD_MAJOR(btdi.ulClassofDevice) == COD_MAJOR_AUDIO) { diff --git a/WinMute/Settings_GeneralDlg.cpp b/WinMute/Settings_GeneralDlg.cpp index 02fb063..d6e55c2 100644 --- a/WinMute/Settings_GeneralDlg.cpp +++ b/WinMute/Settings_GeneralDlg.cpp @@ -51,7 +51,7 @@ static void FillLanguageList(HWND hLanguageList, const SettingsGeneralData& dlgD for (const auto &lang : dlgData.langModules) { const auto itemId = SendMessage(hLanguageList, CB_ADDSTRING, 0, reinterpret_cast(lang.langName.c_str())); if (itemId == CB_ERR || itemId == CB_ERRSPACE) { - WMLog::GetInstance().Write(L"Failed to add language %ls to language selector", lang.langName.c_str()); + WMLog::GetInstance().LogError(L"Failed to add language %ls to language selector", lang.langName.c_str()); } else { ComboBox_SetItemData(hLanguageList, itemId, lang.fileName.c_str()); } @@ -65,6 +65,7 @@ static void LoadSettingsGeneralDlgTranslation(HWND hDlg) i18n.SetItemText(hDlg, IDC_SELECT_LANGUAGE_LABEL, "settings.general.select-language-label"); i18n.SetItemText(hDlg, IDC_RUNONSTARTUP, "settings.general.run-on-startup"); i18n.SetItemText(hDlg, IDC_CHECK_FOR_UPDATES_ON_STARTUP, "settings.general.check-for-updates-on-start"); + i18n.SetItemText(hDlg, IDC_CHECK_FOR_BETA_UPDATES, "settings.general.check-for-beta-updates-on-start"); i18n.SetItemText(hDlg, IDC_ENABLELOGGING, "settings.general.enable-logging"); i18n.SetItemText(hDlg, IDC_OPENLOG, "settings.general.btn-open-log-file"); } @@ -75,6 +76,7 @@ INT_PTR CALLBACK Settings_GeneralDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPA case WM_INITDIALOG: { HWND hAutostart = GetDlgItem(hDlg, IDC_RUNONSTARTUP); HWND hUpdateCheck = GetDlgItem(hDlg, IDC_CHECK_FOR_UPDATES_ON_STARTUP); + HWND hBetaUpdateCheck = GetDlgItem(hDlg, IDC_CHECK_FOR_BETA_UPDATES); HWND hLogging = GetDlgItem(hDlg, IDC_ENABLELOGGING); HWND hOpenLog = GetDlgItem(hDlg, IDC_OPENLOG); @@ -99,6 +101,10 @@ INT_PTR CALLBACK Settings_GeneralDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPA enabled = !!dlgData->settings->QueryValue(SettingsKey::CHECK_FOR_UPDATE); Button_SetCheck(hUpdateCheck, enabled ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(hBetaUpdateCheck, enabled); + enabled = !!dlgData->settings->QueryValue(SettingsKey::CHECK_FOR_BETA_UPDATE); + Button_SetCheck(hBetaUpdateCheck, enabled ? BST_CHECKED : BST_UNCHECKED); + enabled = !!dlgData->settings->QueryValue(SettingsKey::LOGGING_ENABLED); Button_SetCheck(hLogging, enabled ? BST_CHECKED : BST_UNCHECKED); Button_Enable(hOpenLog, enabled); @@ -137,6 +143,9 @@ INT_PTR CALLBACK Settings_GeneralDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPA SendMessageW(GetDlgItem(hDlg, IDC_LOGFILEPATH), WM_SETTEXT, 0, reinterpret_cast(L"")); } + } else if (LOWORD(wParam) == IDC_CHECK_FOR_UPDATES_ON_STARTUP) { + const int enabled = Button_GetCheck(GetDlgItem(hDlg, IDC_CHECK_FOR_UPDATES_ON_STARTUP)); + EnableWindow(GetDlgItem(hDlg, IDC_CHECK_FOR_BETA_UPDATES), enabled); } else if (LOWORD(wParam) == IDC_OPENLOG) { WMLog& log = WMLog::GetInstance(); const std::wstring filePath = log.GetLogFilePath().c_str(); @@ -151,6 +160,7 @@ INT_PTR CALLBACK Settings_GeneralDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPA HWND hAutostart = GetDlgItem(hDlg, IDC_RUNONSTARTUP); HWND hLogging = GetDlgItem(hDlg, IDC_ENABLELOGGING); HWND hUpdateCheck = GetDlgItem(hDlg, IDC_CHECK_FOR_UPDATES_ON_STARTUP); + HWND hBetaUpdateCheck = GetDlgItem(hDlg, IDC_CHECK_FOR_BETA_UPDATES); const int enableLog = Button_GetCheck(hLogging) == BST_CHECKED; dlgData->settings->SetValue(SettingsKey::LOGGING_ENABLED, enableLog); @@ -180,6 +190,9 @@ INT_PTR CALLBACK Settings_GeneralDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPA const int enableUpdateCheck = Button_GetCheck(hUpdateCheck) == BST_CHECKED; dlgData->settings->SetValue(SettingsKey::CHECK_FOR_UPDATE, enableUpdateCheck); + const int enableBetaUpdateCheck = Button_GetCheck(hBetaUpdateCheck) == BST_CHECKED; + dlgData->settings->SetValue(SettingsKey::CHECK_FOR_BETA_UPDATE, enableBetaUpdateCheck); + if (Button_GetCheck(hAutostart) == BST_CHECKED) { dlgData->settings->EnableAutostart(true); } else { diff --git a/WinMute/Settings_ManageEndpointsDlg.cpp b/WinMute/Settings_ManageEndpointsDlg.cpp index b2535cd..9ea9062 100644 --- a/WinMute/Settings_ManageEndpointsDlg.cpp +++ b/WinMute/Settings_ManageEndpointsDlg.cpp @@ -73,20 +73,20 @@ static bool GetAudioEndpoints(std::vector& endpoints) for (UINT i = 0; i < epCount; ++i) { IMMDevicePtr device = nullptr; if (FAILED(audioEndpoints->Item(i, &device))) { - log.Write(L"Failed to get audio endpoint #%d", i); + log.LogError(L"Failed to get audio endpoint #%d", i); continue; } IPropertyStorePtr propStore = nullptr; if (FAILED(device->OpenPropertyStore(STGM_READ, &propStore))) { - log.Write(L"Failed to open property store for audio endpoint #%d", i); + log.LogError(L"Failed to open property store for audio endpoint #%d", i); continue; } PROPVARIANT value; PropVariantInit(&value); if (FAILED(propStore->GetValue(PKEY_Device_FriendlyName, &value))) { - log.Write(L"Failed to get device name for audio endpoint #%d", i); + log.LogError(L"Failed to get device name for audio endpoint #%d", i); continue; } diff --git a/WinMute/Settings_MuteDlg.cpp b/WinMute/Settings_MuteDlg.cpp index 0be463e..af6c0f9 100644 --- a/WinMute/Settings_MuteDlg.cpp +++ b/WinMute/Settings_MuteDlg.cpp @@ -130,7 +130,7 @@ INT_PTR CALLBACK Settings_MuteDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM hDlg, Settings_ManageEndpointsDlgProc, reinterpret_cast(settings)) == 0) { - PrintWindowsError(L"DialogBoxParam", GetLastError()); + ShowWindowsError(L"DialogBoxParam", GetLastError()); } } return 0; diff --git a/WinMute/Settings_WifiDlg.cpp b/WinMute/Settings_WifiDlg.cpp index 060b194..c45a1b8 100644 --- a/WinMute/Settings_WifiDlg.cpp +++ b/WinMute/Settings_WifiDlg.cpp @@ -153,7 +153,6 @@ static void LoadWifiDlgTranslation(HWND hDlg) i18n.SetItemText(hDlg, IDC_WIFI_INTRO, "settings.wifi.intro"); i18n.SetItemText(hDlg, IDC_ENABLE_WIFI_MUTE, "settings.wifi.enable"); - i18n.SetItemText(hDlg, IDC_IS_PERMITLIST, "settings.wifi.mute-when-not-in-list"); i18n.SetItemText(hDlg, IDC_WIFI_ADD, "settings.btn-add"); i18n.SetItemText(hDlg, IDC_WIFI_EDIT, "settings.btn-edit"); i18n.SetItemText(hDlg, IDC_WIFI_REMOVE, "settings.btn-remove"); diff --git a/WinMute/UpdateChecker.cpp b/WinMute/UpdateChecker.cpp index 9cc6eef..977bf3f 100644 --- a/WinMute/UpdateChecker.cpp +++ b/WinMute/UpdateChecker.cpp @@ -66,26 +66,66 @@ UpdateChecker::~UpdateChecker() { } +bool UpdateChecker::ParseVersionInfo(const nlohmann::json &json, UpdateVersionInfo &versInfo) const +{ + WMLog &log = WMLog::GetInstance(); + if (!json.contains("version") && !json.contains("downloadUrl")) { + log.LogError(L"Missing json fields in update file"); + return false; + } + versInfo.version = ConvertStringToWideString(json["version"]);; + versInfo.downloadUrl = ConvertStringToWideString(json["downloadUrl"]); + return true; +} + bool UpdateChecker::ParseVersionFile( const std::string &fileContents, UpdateInfo &updateInfo) const { // Structure // { - // "version": "2.4.1.0", - // "versionPage" : "https://github.com/lx-s/WinMute/releases/" + // "version": 1, + // "stable" : { + // "version": "2.4.1.0", + // "download_page" : "https://github.com/lx-s/WinMute/releases/" + // }, + // "beta" : { + // "version": "2.4.1.0", + // "download_page" : "https://github.com/lx-s/WinMute/releases/" + // } // } WMLog &log = WMLog::GetInstance(); try { auto json = nlohmann::json::parse(fileContents); - if (!json.contains("version") && !json.contains("versionPage")) { - log.Write(L"Missing json fields in update file"); + if (!json.contains("version")) { + log.LogError(L"Missing update-file version"); + return false; + } + const auto file_version = json["version"]; + if (!file_version.is_number() || file_version.get() != 1) { + log.LogError(L"Update file has incompatible version number"); + return false; + } + if (!json.contains("stable") || !json.contains("beta")) { + log.LogError(L"Missing stable and/or beta fields"); return false; } - updateInfo.newVersion = ConvertStringToWideString(json["version"]); - updateInfo.versionPageUrl = ConvertStringToWideString(json["versionPage"]); + const auto stableInfo = json["stable"]; + const auto betaInfo = json["beta"]; + + if (!stableInfo.is_structured() || !betaInfo.is_structured()) { + log.LogError(L"Missing stable and/or beta fields"); + return false; + } + + if (!ParseVersionInfo(stableInfo, updateInfo.stable) || + !ParseVersionInfo(betaInfo, updateInfo.beta)) { + log.LogError(L"Failed to parse stable and/or beta fields"); + return false; + } + } catch (const nlohmann::json::parse_error &pe) { - log.Write(L"Failed to parse update: %S", pe.what()); + log.LogError(L"Failed to parse update: %S", pe.what()); return false; } return true; @@ -115,13 +155,13 @@ std::optional UpdateChecker::IsVersionGreater(const std::wstring &newVers, std::vector curVersParsed; WMLog &log = WMLog::GetInstance(); if (!ParseVersion(newVers, newVersParsed)) { - log.Write(L"Failed to parse new version string \"%s\"", newVers.c_str()); + log.LogError(L"Failed to parse new version string \"%s\"", newVers.c_str()); return std::nullopt; } else if (!ParseVersion(curVers, curVersParsed)) { - log.Write(L"Failed to parse current version string \"%s\"", curVers.c_str()); + log.LogError(L"Failed to parse current version string \"%s\"", curVers.c_str()); return std::nullopt; } else if (newVersParsed.size() != curVersParsed.size()) { - log.Write(L"Version format mismatch \"%s\" / \"%s\"", curVers.c_str(), newVers.c_str()); + log.LogError(L"Version format mismatch \"%s\" / \"%s\"", curVers.c_str(), newVers.c_str()); return std::nullopt; } for (size_t i = 0; i < newVersParsed.size(); ++i) { @@ -147,12 +187,13 @@ bool UpdateChecker::GetUpdateInfo(UpdateInfo &updateInfo) const return false; } - const auto shouldUpdate = IsVersionGreater(updateInfo.newVersion, updateInfo.currentVersion); - if (!shouldUpdate) { + const auto shouldUpdateStable = IsVersionGreater(updateInfo.stable.version, updateInfo.currentVersion); + const auto shouldUpdateBeta = IsVersionGreater(updateInfo.beta.version, updateInfo.currentVersion); + if (!shouldUpdateStable || !shouldUpdateBeta) { return false; } - updateInfo.shouldUpdate = *shouldUpdate; - + updateInfo.stable.shouldUpdate = *shouldUpdateStable; + updateInfo.beta.shouldUpdate = *shouldUpdateBeta; return true; } @@ -166,7 +207,7 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const updateUrl.dwHostNameLength = (DWORD)-1; updateUrl.dwUrlPathLength = (DWORD)-1; if (!WinHttpCrackUrl(UPDATE_FILE_URL, 0, 0, &updateUrl)) { - log.WriteWindowsError(L"WinHttpCrackUrl", GetLastError()); + log.LogWinError(L"WinHttpCrackUrl", GetLastError()); return false; } @@ -177,7 +218,7 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_SECURE_DEFAULTS); if (hSession == nullptr) { - log.WriteWindowsError(L"WinHttpOpen", GetLastError()); + log.LogWinError(L"WinHttpOpen", GetLastError()); return false; } @@ -190,7 +231,7 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const (updateUrl.nScheme == INTERNET_SCHEME_HTTPS) ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0); if (hConnect == nullptr) { - log.WriteWindowsError(L"WinHttpConnect", GetLastError()); + log.LogWinError(L"WinHttpConnect", GetLastError()); return false; } @@ -207,27 +248,22 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE); if (hRequest == nullptr) { - log.WriteWindowsError(L"WinHttpConnect", GetLastError()); + log.LogWinError(L"WinHttpConnect", GetLastError()); return false; } bool result = WinHttpSendRequest( - hRequest, - WINHTTP_NO_ADDITIONAL_HEADERS, - 0, - WINHTTP_NO_REQUEST_DATA, - 0, - 0, - 0); + hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, + WINHTTP_NO_REQUEST_DATA, 0, 0, 0); if (!result) { - log.WriteWindowsError(L"WinHttpSendRequest", GetLastError()); + log.LogWinError(L"WinHttpSendRequest", GetLastError()); return false; } result = WinHttpReceiveResponse(hRequest, nullptr); if (!result) { - log.WriteWindowsError(L"WinHttpReceiveResponse", GetLastError()); + log.LogWinError(L"WinHttpReceiveResponse", GetLastError()); return false; } @@ -241,10 +277,10 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const &statusCodeSize, WINHTTP_NO_HEADER_INDEX); if (!result) { - log.WriteWindowsError(L"WinHttpQueryHeaders(WINHTTP_QUERY_STATUS_CODE)", GetLastError()); + log.LogWinError(L"WinHttpQueryHeaders(WINHTTP_QUERY_STATUS_CODE)", GetLastError()); return false; } else if (statusCode != HTTP_STATUS_OK) { - log.Write(L"Update-Server returned HTTP %d", HTTP_STATUS_OK); + log.LogError(L"Update-Server returned HTTP %d", HTTP_STATUS_OK); return false; } @@ -252,7 +288,7 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const for (;;) { DWORD availBytes = 0; if (!WinHttpQueryDataAvailable(hRequest, &availBytes)) { - log.WriteWindowsError(L"WinHttpQueryDataAvailable", GetLastError()); + log.LogWinError(L"WinHttpQueryDataAvailable", GetLastError()); return false; } if (availBytes == 0) { @@ -261,7 +297,7 @@ bool UpdateChecker::GetVersionFile(std::string &fileContents) const std::string chunk(availBytes, ' '); DWORD byRead = 0; if (!WinHttpReadData(hRequest, reinterpret_cast(&chunk[0]), availBytes, &byRead)) { - log.WriteWindowsError(L"WinHttpReadData", GetLastError()); + log.LogWinError(L"WinHttpReadData", GetLastError()); return false; } fileContents.append(chunk.begin(), chunk.begin() + byRead); @@ -281,7 +317,7 @@ bool UpdateChecker::IsUpdateCheckEnabled(const WMSettings &settings) const const DWORD thisExePathSize = ARRAY_SIZE(thisExePath); const DWORD thisPathLen = GetModuleFileNameW(nullptr, thisExePath, thisExePathSize); if (thisPathLen == 0 || (thisPathLen == thisExePathSize && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - WMLog::GetInstance().WriteWindowsError(L"GetModuleFileNameW", ERROR_INSUFFICIENT_BUFFER); + WMLog::GetInstance().LogWinError(L"GetModuleFileNameW", ERROR_INSUFFICIENT_BUFFER); return false; } fs::path updateDisableFile{ thisExePath }; diff --git a/WinMute/UpdateChecker.h b/WinMute/UpdateChecker.h index bbfb93f..33568d3 100644 --- a/WinMute/UpdateChecker.h +++ b/WinMute/UpdateChecker.h @@ -40,11 +40,16 @@ enum class UpdateCheckInterval : int { ON_STARTUP = 1, }; +struct UpdateVersionInfo { + std::wstring version; + std::wstring downloadUrl; + bool shouldUpdate = false; +}; + struct UpdateInfo { std::wstring currentVersion; - std::wstring newVersion; - std::wstring versionPageUrl; - bool shouldUpdate; + UpdateVersionInfo stable; + UpdateVersionInfo beta; }; class UpdateChecker { @@ -64,4 +69,5 @@ private: bool ParseVersionFile(const std::string &fileContents, UpdateInfo& updateInfo) const; std::optional IsVersionGreater(const std::wstring &newVers, const std::wstring &curVers) const; bool ParseVersion(const std::wstring &vers, std::vector& parsedVers) const; + bool ParseVersionInfo(const nlohmann::json &json, UpdateVersionInfo &versInfo) const; }; diff --git a/WinMute/Utility.cpp b/WinMute/Utility.cpp index 276687a..a99cbe1 100644 --- a/WinMute/Utility.cpp +++ b/WinMute/Utility.cpp @@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "Common.h" -void PrintWindowsError(const wchar_t *functionName, DWORD lastError) +void ShowWindowsError(const wchar_t *functionName, DWORD lastError) { // Retrieve the system error message for the last-error code if (lastError == -1) { diff --git a/WinMute/VistaAudio.cpp b/WinMute/VistaAudio.cpp index 203d4ff..af7337f 100644 --- a/WinMute/VistaAudio.cpp +++ b/WinMute/VistaAudio.cpp @@ -101,13 +101,13 @@ bool VistaAudio::LoadAllEndpoints() hr = audioEndpoints->Item(i, &device); if (FAILED(hr)) { - log.Write(L"Failed to get audio endpoint #%d", i); + log.LogError(L"Failed to get audio endpoint #%d", i); continue; } hr = device->OpenPropertyStore(STGM_READ, &propStore); if (FAILED(hr)) { - log.Write(L"Failed to open property store for audio endpoint #%d", i); + log.LogError(L"Failed to open property store for audio endpoint #%d", i); continue; } @@ -115,10 +115,10 @@ bool VistaAudio::LoadAllEndpoints() PropVariantInit(&value); hr = propStore->GetValue(PKEY_Device_FriendlyName, &value); if (FAILED(hr)) { - log.Write(L"Failed to get device name for audio endpoint #%d", i); + log.LogError(L"Failed to get device name for audio endpoint #%d", i); continue; } - log.Write(L"Found audio endpoint \"%s\"", value.pwszVal); + log.LogInfo(L"Found audio endpoint \"%s\"", value.pwszVal); StringCchCopy(ep->deviceName, sizeof(ep->deviceName)/sizeof(ep->deviceName[0]), value.pwszVal); @@ -129,14 +129,14 @@ bool VistaAudio::LoadAllEndpoints() if (FAILED(device->Activate( __uuidof(IAudioSessionManager2), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast(&sessionManager2)))) { - log.Write(L"Failed to retrieve audio session manager for \"%s\"", + log.LogError(L"Failed to retrieve audio session manager for \"%s\"", ep->deviceName); continue; } hr = sessionManager2->GetAudioSessionControl(nullptr, 0, &ep->sessionCtrl); if (FAILED(hr)) { - log.Write(L"Failed to retrieve audio session manager for \"%s\"", + log.LogError(L"Failed to retrieve audio session manager for \"%s\"", ep->deviceName); continue; } @@ -151,8 +151,8 @@ bool VistaAudio::LoadAllEndpoints() __uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast(&ep->endpointVolume)); if (FAILED(hr)) { - log.Write(L"Failed to active endpoint volume for device \"%s\"", - ep->deviceName); + log.LogError(L"Failed to active endpoint volume for device \"%s\"", + ep->deviceName); continue; } endpoints_.push_back(std::move(ep)); @@ -174,7 +174,7 @@ bool VistaAudio::Init(HWND hParent) __uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER))) { - log.Write(L"Failed to create instance of MMDeviceEnumerator"); + log.LogError(L"Failed to create instance of MMDeviceEnumerator"); return false; } @@ -223,7 +223,8 @@ bool VistaAudio::AllEndpointsMuted() for (auto& e : endpoints_) { BOOL isMuted = FALSE; if (FAILED(e->endpointVolume->GetMute(&isMuted))) { - log.Write(L"Failed to get mute status for \"%s\"", + log.LogError( + L"Failed to get mute status for \"%s\"", e->deviceName); allMuted = false; break; @@ -245,8 +246,9 @@ bool VistaAudio::SaveMuteStatus() for (auto& e : endpoints_) { BOOL isMuted = FALSE; if (FAILED(e->endpointVolume->GetMute(&isMuted))) { - log.Write(L"Failed to get mute status for \"%s\"", - e->deviceName); + log.LogError( + L"Failed to get mute status for \"%s\"", + e->deviceName); success = false; } else { e->wasMuted = isMuted; @@ -266,15 +268,15 @@ bool VistaAudio::RestoreMuteStatus() } for (auto& e : endpoints_) { if (!IsEndpointManaged(e->deviceName)) { - log.Write(L"Skipping Endpoint %s", e->deviceName); - continue; + log.LogInfo(L"Skipping Endpoint %s", e->deviceName); + continue; } - log.Write(L"Restoring: Mute %s for \"%s\"", + log.LogInfo(L"Restoring: Mute %s for \"%s\"", (e->wasMuted) ? L"true" : L"false", e->deviceName); if (e->wasMuted != true) { if (FAILED(e->endpointVolume->SetMute(false, nullptr))) { - log.Write(_T("Failed to restore mute status to %s for \"%s\""), + log.LogError(_T("Failed to restore mute status to %s for \"%s\""), (e->wasMuted) ? L"true" : L"false", e->deviceName); success = false; @@ -292,18 +294,20 @@ void VistaAudio::SetMute(bool mute) for (auto& e : endpoints_) { BOOL isMuted = !mute; if (!IsEndpointManaged(e->deviceName)) { - log.Write(L"Skipping Endpoint %s", e->deviceName); + log.LogInfo(L"Skipping Endpoint %s", e->deviceName); continue; } if (FAILED(e->endpointVolume->GetMute(&isMuted))) { - log.Write(L"Failed to get mute status for \"%s\"", - e->deviceName); + log.LogError( + L"Failed to get mute status for \"%s\"", + e->deviceName); } if (!!isMuted != mute) { if (FAILED(e->endpointVolume->SetMute(mute, nullptr))) { - log.Write(L"Failed to set mute status to %s for \"%s\"", - (e->wasMuted) ? L"true" : L"false", - e->deviceName); + log.LogError( + L"Failed to set mute status to %s for \"%s\"", + (e->wasMuted) ? L"true" : L"false", + e->deviceName); } } } diff --git a/WinMute/WMLog.cpp b/WinMute/WMLog.cpp index c23090e..e45f7c1 100644 --- a/WinMute/WMLog.cpp +++ b/WinMute/WMLog.cpp @@ -105,39 +105,77 @@ bool WMLog::IsEnabled() const return enabled_; } -void WMLog::WriteMessage(const wchar_t* msg) +void WMLog::WriteMessage(const wchar_t* level, const wchar_t* msg) { - struct tm tm = { 0 }; - auto now = std::chrono::system_clock::now(); - auto in_time_t = std::chrono::system_clock::to_time_t(now); - - std::wstringstream ss; - localtime_s(&tm, &in_time_t); - ss << L"[" << std::put_time(&tm, L"%Y-%m-%d %X") << L"] " - << msg << L"\n"; - const auto& logStr = ss.str(); + time_t rawtime; + struct tm timeinfo; + wchar_t buffer[30]; + + time(&rawtime); + localtime_s(&timeinfo, &rawtime); + + wcsftime(buffer, ARRAY_SIZE(buffer), L"%Y-%m-%d %H:%M:%S", &timeinfo); + const std::wstring logMsg = std::vformat( + L"[{} {}]: {}\n", + std::make_wformat_args( + buffer, + level, + msg) + ); const std::scoped_lock lock(logMutex_); - logFile_.write(logStr.c_str(), logStr.length()); + logFile_.write(logMsg.c_str(), logMsg.length()); logFile_.flush(); } -void WMLog::Write(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) +void WMLog::LogDebug(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) +{ + if (!enabled_) { + return; + } + + wchar_t buf[1024]; + va_list ap; + va_start(ap, fmt); + + vswprintf_s(buf, fmt, ap); + WriteMessage(L"Debug", buf); + + va_end(ap); +} + +void WMLog::LogInfo(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) +{ + if (!enabled_) { + return; + } + + wchar_t buf[1024]; + va_list ap; + va_start(ap, fmt); + + vswprintf_s(buf, fmt, ap); + WriteMessage(L"Info", buf); + + va_end(ap); +} + +void WMLog::LogError(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) { if (!enabled_) { return; } - wchar_t buf[200]; + wchar_t buf[1024]; va_list ap; va_start(ap, fmt); vswprintf_s(buf, fmt, ap); - WriteMessage(buf); + WriteMessage(L"Error", buf); va_end(ap); } -void WMLog::WriteWindowsError(const wchar_t *functionName, DWORD lastError) +void WMLog::LogWinError(const wchar_t *functionName, DWORD lastError) { // Retrieve the system error message for the last-error code if (lastError == -1) { @@ -160,6 +198,6 @@ void WMLog::WriteWindowsError(const wchar_t *functionName, DWORD lastError) functionName, lastError, reinterpret_cast(lpMsgBuf))); - WriteMessage(static_cast(lpMsgBuf)); + WriteMessage(L"Error", static_cast(lpMsgBuf)); LocalFree(lpMsgBuf); } diff --git a/WinMute/WMLog.h b/WinMute/WMLog.h index cd0811c..717b291 100644 --- a/WinMute/WMLog.h +++ b/WinMute/WMLog.h @@ -39,8 +39,10 @@ class WMLog { public: static WMLog& GetInstance(); - void Write(_In_z_ _Printf_format_string_ const wchar_t* fmt, ...); - void WriteWindowsError(const wchar_t *functionName, DWORD errorCode = -1); + void LogDebug(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...); + void LogInfo(_In_z_ _Printf_format_string_ const wchar_t* fmt, ...); + void LogError(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...); + void LogWinError(const wchar_t *functionName, DWORD errorCode = -1); void SetEnabled(bool enable); bool IsEnabled() const; @@ -52,7 +54,7 @@ private: WMLog(const WMLog&) = delete; WMLog& operator=(const WMLog&) = delete; - void WriteMessage(const wchar_t* msg); + void WriteMessage(const wchar_t *level, const wchar_t *msg); void DeleteLogFile(); std::mutex logMutex_; diff --git a/WinMute/WMSettings.cpp b/WinMute/WMSettings.cpp index 09438cc..53011ef 100644 --- a/WinMute/WMSettings.cpp +++ b/WinMute/WMSettings.cpp @@ -125,6 +125,9 @@ static const wchar_t* KeyToStr(SettingsKey key) case SettingsKey::CHECK_FOR_UPDATE: keyStr = L"CheckForUpdate"; break; + case SettingsKey::CHECK_FOR_BETA_UPDATE: + keyStr = L"CheckForBetaUpdate"; + break; } return keyStr; } @@ -176,6 +179,8 @@ static DWORD GetDefaultSetting(SettingsKey key) return 0; case SettingsKey::CHECK_FOR_UPDATE: return 0; + case SettingsKey::CHECK_FOR_BETA_UPDATE: + return 0; } return 0; } @@ -199,8 +204,8 @@ static bool ReadStringFromRegistry(HKEY hKey, const wchar_t *subKey, std::wstrin regError = RegQueryValueExW(hKey, subKey, nullptr, nullptr, nullptr, &bufSize); if (regError != ERROR_SUCCESS) { if (regError != ERROR_FILE_NOT_FOUND) { - PrintWindowsError(L"RegQueryValueExW", regError); - log.Write(L"[Registry] Failed to read key \"%s\".", subKey); + ShowWindowsError(L"RegQueryValueExW", regError); + log.LogError(L"[Registry] Failed to read key \"%s\".", subKey); } } else { bufSize += 1; // Trailing '\0' @@ -208,8 +213,8 @@ static bool ReadStringFromRegistry(HKEY hKey, const wchar_t *subKey, std::wstrin regError = RegQueryValueExW(hKey, subKey, nullptr, nullptr, reinterpret_cast(buf), &bufSize); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegQueryValueExW", regError); - log.Write(L"[Registry] Failed to query value for key \"%s\".", subKey); + ShowWindowsError(L"RegQueryValueExW", regError); + log.LogError(L"[Registry] Failed to query value for key \"%s\".", subKey); } else { success = true; val = buf; @@ -237,7 +242,7 @@ bool WMSettings::MigrateSettings() { DWORD version = QueryValue(SettingsKey::SETTINGS_VERSION); if (version != CURRENT_SETTINGS_VERSION) { - WMLog::GetInstance().Write(L"Unexpected settings version: %d", version); + WMLog::GetInstance().LogError(L"Unexpected settings version: %d", version); } return true; } @@ -256,7 +261,7 @@ bool WMSettings::Init() &hSettingsKey_, nullptr); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegCreateKeyEx", regError); + ShowWindowsError(L"RegCreateKeyEx", regError); return false; } } @@ -272,7 +277,7 @@ bool WMSettings::Init() &hWifiKey_, nullptr); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegCreateKeyEx", regError); + ShowWindowsError(L"RegCreateKeyEx", regError); RegCloseKey(hSettingsKey_); hSettingsKey_ = nullptr; return false; @@ -290,7 +295,7 @@ bool WMSettings::Init() &hBluetoothKey_, nullptr); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegCreateKeyEx", regError); + ShowWindowsError(L"RegCreateKeyEx", regError); RegCloseKey(hWifiKey_); RegCloseKey(hSettingsKey_); hSettingsKey_ = nullptr; @@ -310,7 +315,7 @@ bool WMSettings::Init() &hAudioEndpointsKey_, nullptr); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegCreateKeyEx", regError); + ShowWindowsError(L"RegCreateKeyEx", regError); RegCloseKey(hWifiKey_); RegCloseKey(hSettingsKey_); RegCloseKey(hBluetoothKey_); @@ -346,7 +351,7 @@ HKEY WMSettings::OpenAutostartKey(REGSAM samDesired) samDesired, &hRunKey); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegOpenKeyEx", regError); + ShowWindowsError(L"RegOpenKeyEx", regError); } return hRunKey; } @@ -357,14 +362,14 @@ bool WMSettings::IsAutostartEnabled() WMLog& log = WMLog::GetInstance(); wchar_t wmPath[MAX_PATH + 1]; if (GetModuleFileName(nullptr, wmPath, sizeof(wmPath) / sizeof(wmPath[0])) == 0) { - log.Write(L"Failed to get path of winmute"); + log.LogError(L"Failed to get path of winmute"); } else { HKEY hRunKey = OpenAutostartKey(KEY_READ); if (hRunKey != nullptr) { std::wstring path; if (ReadStringFromRegistry(hRunKey, LX_SYSTEMS_AUTOSTART_KEY, path)) { if (path != wmPath) { - log.Write(L"Autostart entry has wrong path"); + log.LogInfo(L"Autostart entry has wrong path"); } else { isEnabled = true; } @@ -383,7 +388,7 @@ void WMSettings::EnableAutostart(bool enable) if (enable) { wchar_t wmPath[MAX_PATH + 1]; if (GetModuleFileNameW(nullptr, wmPath, sizeof(wmPath) / sizeof(wmPath[0])) == 0) { - log.Write(L"Failed to get path of winmute"); + log.LogError(L"Failed to get path of winmute"); } else { DWORD regError = RegSetKeyValueW( hRunKey, @@ -393,13 +398,13 @@ void WMSettings::EnableAutostart(bool enable) wmPath, (lstrlen(wmPath) + 1) * sizeof(wchar_t)); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegSetKeyValue", regError); + ShowWindowsError(L"RegSetKeyValue", regError); } } } else { DWORD regError = RegDeleteKeyValueW(hRunKey, nullptr, LX_SYSTEMS_AUTOSTART_KEY); if (regError != ERROR_SUCCESS && regError != ERROR_FILE_NOT_FOUND) { - PrintWindowsError(L"RegDeleteKeyValue", regError); + ShowWindowsError(L"RegDeleteKeyValue", regError); } } RegCloseKey(hRunKey); @@ -422,9 +427,9 @@ DWORD WMSettings::QueryValue(SettingsKey key) const &size); if (regError != ERROR_SUCCESS) { if (regError != ERROR_FILE_NOT_FOUND) { - PrintWindowsError(L"RegQueryValueExW", regError); + ShowWindowsError(L"RegQueryValueExW", regError); WMLog &log = WMLog::GetInstance(); - log.Write(L"[Registry] Failed to query value for key \"%s\"", keyStr); + log.LogError(L"[Registry] Failed to query value for key \"%s\"", keyStr); } return GetDefaultSetting(key); } @@ -456,7 +461,7 @@ bool WMSettings::SetValue(SettingsKey key, DWORD value) reinterpret_cast(&value), sizeof(DWORD)); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegSetValueExW", regError); + ShowWindowsError(L"RegSetValueExW", regError); return false; } @@ -478,7 +483,7 @@ bool WMSettings::SetValue(SettingsKey key, const std::wstring &value) strValue, strLen); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegSetValueExW", regError); + ShowWindowsError(L"RegSetValueExW", regError); return false; } @@ -503,12 +508,12 @@ bool WMSettings::StoreWifiNetworks(std::vector& networks) if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return false; } else { regError = RegDeleteValue(hWifiKey_, valueName); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegDeleteValue", regError); + ShowWindowsError(L"RegDeleteValue", regError); return false; } } @@ -528,7 +533,7 @@ bool WMSettings::StoreWifiNetworks(std::vector& networks) reinterpret_cast(v.c_str()), static_cast(v.length() + 1) * sizeof(wchar_t)); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegSetValueEx", regError); + ShowWindowsError(L"RegSetValueEx", regError); return false; } } @@ -558,7 +563,7 @@ std::vector WMSettings::GetWifiNetworks() const if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return {}; } else { networks.push_back(dataBuf); @@ -586,12 +591,12 @@ bool WMSettings::StoreBluetoothDevices(std::vector& devices) if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return false; } else { regError = RegDeleteValue(hBluetoothKey_, valueName); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegDeleteValue", regError); + ShowWindowsError(L"RegDeleteValue", regError); return false; } } @@ -614,7 +619,7 @@ bool WMSettings::StoreBluetoothDevices(std::vector& devices) reinterpret_cast(v.c_str()), static_cast(v.length() + 1) * sizeof(wchar_t)); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegSetValueEx", regError); + ShowWindowsError(L"RegSetValueEx", regError); return false; } } @@ -644,7 +649,7 @@ std::vector WMSettings::GetBluetoothDevicesA() const if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return {}; } else { devices.push_back(dataBuf); @@ -676,7 +681,7 @@ std::vector WMSettings::GetBluetoothDevicesW() const if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return {}; } else { devices.push_back(dataBuf); @@ -705,12 +710,12 @@ bool WMSettings::StoreManagedAudioEndpoints(std::vector &endpoints if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return false; } else { regError = RegDeleteValue(hAudioEndpointsKey_, valueName); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegDeleteValue", regError); + ShowWindowsError(L"RegDeleteValue", regError); return false; } } @@ -733,7 +738,7 @@ bool WMSettings::StoreManagedAudioEndpoints(std::vector &endpoints reinterpret_cast(v.c_str()), static_cast(v.length() + 1) * sizeof(wchar_t)); if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegSetValueEx", regError); + ShowWindowsError(L"RegSetValueEx", regError); return false; } } @@ -763,7 +768,7 @@ std::vector WMSettings::GetManagedAudioEndpoints() const if (regError == ERROR_NO_MORE_ITEMS) { break; } else if (regError != ERROR_SUCCESS) { - PrintWindowsError(L"RegEnumValue", regError); + ShowWindowsError(L"RegEnumValue", regError); return {}; } else { devices.push_back(dataBuf); diff --git a/WinMute/WMSettings.h b/WinMute/WMSettings.h index c0e929d..7d731f2 100644 --- a/WinMute/WMSettings.h +++ b/WinMute/WMSettings.h @@ -66,6 +66,7 @@ enum class SettingsKey { , LOGGING_ENABLED , APP_LANGUAGE , CHECK_FOR_UPDATE + , CHECK_FOR_BETA_UPDATE }; class WMSettings { diff --git a/WinMute/WMi18n.cpp b/WinMute/WMi18n.cpp index a370adb..46e305b 100644 --- a/WinMute/WMi18n.cpp +++ b/WinMute/WMi18n.cpp @@ -41,7 +41,6 @@ WMi18n::WMi18n() noexcept WMi18n::~WMi18n() noexcept { - UnloadLanguage(); } WMi18n& WMi18n::GetInstance() @@ -59,7 +58,7 @@ std::optional WMi18n::GetLanguageFilesPath() const { wchar_t wmPath[MAX_PATH + 1]{ 0 }; if (GetModuleFileNameW(nullptr, wmPath, MAX_PATH) <= 0) { - WMLog::GetInstance().WriteWindowsError(L"GetModuleFileNameW", GetLastError()); + WMLog::GetInstance().LogWinError(L"GetModuleFileNameW", GetLastError()); return std::nullopt; } fs::path langPath = wmPath; @@ -93,7 +92,7 @@ std::vector WMi18n::GetAvailableLanguages() const langDlls.push_back(langMod); } } catch (const nlohmann::json::parse_error &pe) { - WMLog::GetInstance().Write(L"Failed to parse language file \"%ls\": %S", wfd.cFileName, pe.what()); + WMLog::GetInstance().LogError(L"Failed to parse language file \"%ls\": %S", wfd.cFileName, pe.what()); } } while (FindNextFileW(hFindFile, &wfd)); } @@ -135,7 +134,7 @@ bool WMi18n::LoadLanguage(const std::wstring &fileName, TranslationMap &strings) const fs::path loadFilePath{ fileName}; *langFilePath /= loadFilePath.filename(); // Sanitize if (!fs::exists(*langFilePath)) { - log.Write(L"Language module \"%ls\" does not exist", langFilePath->c_str()); + log.LogError(L"Language module \"%ls\" does not exist", langFilePath->c_str()); return false; } try { @@ -144,23 +143,23 @@ bool WMi18n::LoadLanguage(const std::wstring &fileName, TranslationMap &strings) TranslationMap translations_temp; for (auto it = json_data.begin(); it != json_data.end(); ++it) { if (it->is_structured()) { - log.Write(L"Language module \"%ls\" has nested elements", langFilePath->c_str()); + log.LogError(L"Language module \"%ls\" has nested elements", langFilePath->c_str()); return false; } const auto value = ConvertStringToWideString(it.value()); if (value == L"") { - log.Write(L"Unable to convert language element \"%S\"", it.key().c_str()); + log.LogError(L"Unable to convert language element \"%S\"", it.key().c_str()); return false; } if (translations_temp.contains(it.key())) { - log.Write(L"Double entry for language key \"%S\" found.", it.key().c_str()); + log.LogError(L"Double entry for language key \"%S\" found.", it.key().c_str()); return false; } translations_temp[it.key()] = value; } strings = std::move(translations_temp); } catch (const nlohmann::json::parse_error &pe) { - WMLog::GetInstance().Write( + log.LogError( L"Failed to parse language file \"%ls\": %S", langFilePath->filename().c_str(), pe.what()); @@ -179,7 +178,7 @@ bool WMi18n::LoadLanguage(const std::wstring &fileName) TranslationMap new_lang; if (!LoadLanguage(fileName, new_lang)) { - WMLog::GetInstance().Write(L"Failed to load language \"%ls\"", fileName.c_str()); + WMLog::GetInstance().LogError(L"Failed to load language \"%ls\"", fileName.c_str()); return false; } else { UnloadLanguage(); @@ -191,10 +190,6 @@ bool WMi18n::LoadLanguage(const std::wstring &fileName) void WMi18n::UnloadLanguage() { - if (langMutex_.try_lock()) { - langMutex_.unlock(); - throw "Lock was not acquired before unloading the language"; - } loadedLang_.clear(); } @@ -231,7 +226,7 @@ bool WMi18n::SetItemText(HWND hWnd, int dlgItem, const std::string& textId) { const auto text = GetTranslationW(textId); if (!SetDlgItemTextW(hWnd, dlgItem, text.c_str())) { - WMLog::GetInstance().WriteWindowsError(L"SetDlgItemTextW", GetLastError()); + WMLog::GetInstance().LogWinError(L"SetDlgItemTextW", GetLastError()); return false; } return true; @@ -241,7 +236,7 @@ bool WMi18n::SetItemText(HWND hItem, const std::string &textId) { const auto text = GetTranslationW(textId); if (!SetWindowTextW(hItem, text.c_str())) { - WMLog::GetInstance().WriteWindowsError(L"SetDlgItemTextW", GetLastError()); + WMLog::GetInstance().LogWinError(L"SetDlgItemTextW", GetLastError()); return false; } return true; diff --git a/WinMute/WifiDetector.cpp b/WinMute/WifiDetector.cpp index 428461b..070a49e 100644 --- a/WinMute/WifiDetector.cpp +++ b/WinMute/WifiDetector.cpp @@ -72,14 +72,14 @@ bool WifiDetector::Init(HWND hNotifyWnd) DWORD wlErr = WlanOpenHandle(vers, nullptr, &vers, &wlanHandle_); if (wlErr != ERROR_SUCCESS) { if (wlErr != ERROR_SERVICE_NOT_ACTIVE) { - PrintWindowsError(L"WlanOpenHandle", wlErr); + ShowWindowsError(L"WlanOpenHandle", wlErr); } } else { wlErr = WlanRegisterNotification( wlanHandle_, WLAN_NOTIFICATION_SOURCE_ACM, TRUE, ::WlanNotificationCallback, this, nullptr, nullptr); if (wlErr != ERROR_SUCCESS) { - PrintWindowsError(L"WlanOpenHandle", wlErr); + ShowWindowsError(L"WlanOpenHandle", wlErr); WlanCloseHandle(wlanHandle_, nullptr); } else { initialized_ = true; @@ -100,7 +100,7 @@ void WifiDetector::CheckNetwork() PWLAN_INTERFACE_INFO_LIST ifList; DWORD wlanErr = WlanEnumInterfaces(wlanHandle_, nullptr, &ifList); if (wlanErr != ERROR_SUCCESS) { - PrintWindowsError(L"WlanEnumInterfaces", wlanErr); + ShowWindowsError(L"WlanEnumInterfaces", wlanErr); } else { for (; ifList->dwIndex < ifList->dwNumberOfItems; ++ifList->dwIndex) { PWLAN_AVAILABLE_NETWORK_LIST availList = nullptr; @@ -111,7 +111,7 @@ void WifiDetector::CheckNetwork() nullptr, &availList); if (wlanErr != ERROR_SUCCESS) { - PrintWindowsError(L"WlanGetAvailableNetworkList", wlanErr); + ShowWindowsError(L"WlanGetAvailableNetworkList", wlanErr); } else { for (; availList->dwIndex < availList->dwNumberOfItems; ++availList->dwIndex) { const PWLAN_AVAILABLE_NETWORK net = &availList->Network[availList->dwIndex]; diff --git a/WinMute/WinMain.cpp b/WinMute/WinMain.cpp index e5f9a9f..02edaa6 100644 --- a/WinMute/WinMain.cpp +++ b/WinMute/WinMain.cpp @@ -63,10 +63,10 @@ static bool InitWindowsComponents() initComCtrl.dwSize = sizeof(INITCOMMONCONTROLSEX); initComCtrl.dwICC = ICC_LINK_CLASS; if (InitCommonControlsEx(&initComCtrl) == FALSE) { - WMLog::GetInstance().WriteWindowsError(L"InitCommonControlsEx", GetLastError()); + WMLog::GetInstance().LogWinError(L"InitCommonControlsEx", GetLastError()); return FALSE; } else if (CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED) != S_OK) { - WMLog::GetInstance().WriteWindowsError(L"CoInitializeEx", GetLastError()); + WMLog::GetInstance().LogWinError(L"CoInitializeEx", GetLastError()); return FALSE; } return TRUE; diff --git a/WinMute/WinMute.cpp b/WinMute/WinMute.cpp index 9c352ae..fa8123b 100644 --- a/WinMute/WinMute.cpp +++ b/WinMute/WinMute.cpp @@ -133,7 +133,7 @@ bool WinMute::RegisterWindowClass() wc.lpszClassName = WINMUTE_CLASS_NAME; if (!RegisterClassExW(&wc)) { - PrintWindowsError(L"RegisterClass"); + ShowWindowsError(L"RegisterClass"); return false; } return true; @@ -144,7 +144,7 @@ bool WinMute::InitWindow() hWnd_ = CreateWindowExW(WS_EX_TOOLWINDOW, WINMUTE_CLASS_NAME, PROGRAM_NAME, WS_POPUP, 0, 0, 0, 0, nullptr, 0, hglobInstance, this); if (hWnd_ == nullptr) { - PrintWindowsError(L"CreateWindowEx"); + ShowWindowsError(L"CreateWindowEx"); return false; } return true; @@ -179,7 +179,7 @@ bool WinMute::InitTrayMenu() if (hTrayMenu_ == nullptr) { hTrayMenu_ = LoadMenuW(hglobInstance, MAKEINTRESOURCE(IDR_TRAYMENU)); if (hTrayMenu_ == nullptr) { - PrintWindowsError(L"LoadMenu"); + ShowWindowsError(L"LoadMenu"); return false; } } @@ -208,7 +208,7 @@ bool WinMute::Init() #else WMLog::GetInstance().SetEnabled(settings_.QueryValue(SettingsKey::LOGGING_ENABLED)); #endif - log.Write(L"Starting new session..."); + log.LogInfo(L"Starting new session..."); if (!RegisterWindowClass() || !InitWindow()) { return false; @@ -227,25 +227,25 @@ bool WinMute::Init() } if (!WTSRegisterSessionNotification(hWnd_, NOTIFY_FOR_THIS_SESSION)) { - PrintWindowsError(L"WTSRegisterSessionNotification"); + ShowWindowsError(L"WTSRegisterSessionNotification"); return false; } if (!RegisterPowerSettingNotification(hWnd_, &GUID_CONSOLE_DISPLAY_STATE, 0)) { - PrintWindowsError(L"RegisterPowerSettingNotification"); + ShowWindowsError(L"RegisterPowerSettingNotification"); return false; } hTrayIcon_ = LoadIconW(hglobInstance, MAKEINTRESOURCE(IDI_APP)); if (hTrayIcon_ == nullptr) { - PrintWindowsError(_T("LoadIcon")); + ShowWindowsError(_T("LoadIcon")); return false; } trayIcon_.Init(hWnd_, 0, hTrayIcon_, L"WinMute", true); quietHours_.Init(hWnd_, settings_); - log.Write(L"WinMute initialized"); + log.LogInfo(L"WinMute initialized"); if (settings_.QueryValue(SettingsKey::MUTE_ON_RDP) && IsCurrentSessionRemoteable()) { @@ -267,21 +267,23 @@ bool WinMute::LoadSettings() if (log.IsEnabled()) { std::wstring versionNumber; GetWinMuteVersion(versionNumber); - log.Write(L"Starting WinMute %s", versionNumber.c_str()); - log.Write(L"Loading settings:"); - log.Write(L"\tRestore volume: %s", settings_.QueryValue(SettingsKey::RESTORE_AUDIO) ? L"Yes" : L"No"); - log.Write(L"\tMute delay: %d", settings_.QueryValue(SettingsKey::MUTE_DELAY)); - log.Write(L"\tMute on lock: %s", settings_.QueryValue(SettingsKey::MUTE_ON_LOCK) ? L"Yes" : L"No"); - log.Write(L"\tMute on display standby: %s", settings_.QueryValue(SettingsKey::MUTE_ON_DISPLAYSTANDBY) ? L"Yes" : L"No"); - log.Write(L"\tMute on logout: %s", settings_.QueryValue(SettingsKey::MUTE_ON_LOGOUT) ? L"Yes" : L"No"); - log.Write(L"\tMute on suspend: %s", settings_.QueryValue(SettingsKey::MUTE_ON_SUSPEND) ? L"Yes" : L"No"); - log.Write(L"\tMute on shutdown: %s", settings_.QueryValue(SettingsKey::MUTE_ON_SHUTDOWN) ? L"Yes" : L"No"); - log.Write(L"\tShow notifications: %s", settings_.QueryValue(SettingsKey::NOTIFICATIONS_ENABLED) ? L"Yes" : L"No"); - log.Write(L"\tMute on bluetooth: %s", settings_.QueryValue(SettingsKey::MUTE_ON_BLUETOOTH) ? L"Yes" : L"No"); - log.Write(L"\t\tUse devicelist: %s", settings_.QueryValue(SettingsKey::MUTE_ON_BLUETOOTH_DEVICELIST) ? L"Yes" : L"No"); - log.Write(L"\tMute on WLAN: %s", settings_.QueryValue(SettingsKey::MUTE_ON_WLAN) ? L"Yes" : L"No"); - log.Write(L"\t\tUse allowlist: %s", settings_.QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST) ? L"Yes" : L"No"); - log.Write(L"\tMute specific endpoints only: %s", settings_.QueryValue(SettingsKey::MUTE_INDIVIDUAL_ENDPOINTS) ? L"Yes" : L"No"); + log.LogInfo(L"Starting WinMute %s", versionNumber.c_str()); + log.LogInfo(L"Loading settings:"); + log.LogInfo(L"Check for updates: %s", settings_.QueryValue(SettingsKey::CHECK_FOR_UPDATE) ? L"Yes" : L"No"); + log.LogInfo(L"\tCheck for beta updates: %s", settings_.QueryValue(SettingsKey::CHECK_FOR_BETA_UPDATE) ? L"Yes" : L"No"); + log.LogInfo(L"\tRestore volume: %s", settings_.QueryValue(SettingsKey::RESTORE_AUDIO) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute delay: %d", settings_.QueryValue(SettingsKey::MUTE_DELAY)); + log.LogInfo(L"\tMute on lock: %s", settings_.QueryValue(SettingsKey::MUTE_ON_LOCK) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute on display standby: %s", settings_.QueryValue(SettingsKey::MUTE_ON_DISPLAYSTANDBY) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute on logout: %s", settings_.QueryValue(SettingsKey::MUTE_ON_LOGOUT) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute on suspend: %s", settings_.QueryValue(SettingsKey::MUTE_ON_SUSPEND) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute on shutdown: %s", settings_.QueryValue(SettingsKey::MUTE_ON_SHUTDOWN) ? L"Yes" : L"No"); + log.LogInfo(L"\tShow notifications: %s", settings_.QueryValue(SettingsKey::NOTIFICATIONS_ENABLED) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute on bluetooth: %s", settings_.QueryValue(SettingsKey::MUTE_ON_BLUETOOTH) ? L"Yes" : L"No"); + log.LogInfo(L"\t\tUse devicelist: %s", settings_.QueryValue(SettingsKey::MUTE_ON_BLUETOOTH_DEVICELIST) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute on WLAN: %s", settings_.QueryValue(SettingsKey::MUTE_ON_WLAN) ? L"Yes" : L"No"); + log.LogInfo(L"\t\tUse allowlist: %s", settings_.QueryValue(SettingsKey::MUTE_ON_WLAN_ALLOWLIST) ? L"Yes" : L"No"); + log.LogInfo(L"\tMute specific endpoints only: %s", settings_.QueryValue(SettingsKey::MUTE_INDIVIDUAL_ENDPOINTS) ? L"Yes" : L"No"); } if (!settings_.QueryValue(SettingsKey::MUTE_INDIVIDUAL_ENDPOINTS)) { @@ -395,6 +397,7 @@ void WinMute::CheckForUpdates() void WinMute::CheckForUpdatesAsync(std::unique_ptr updateChecker) { + const bool betaUpdates = settings_.QueryValue(SettingsKey::CHECK_FOR_BETA_UPDATE) != 0; if (!updateChecker) { return; } @@ -402,10 +405,18 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr updateChecker) trayIcon_.ShowPopup( i18n_.GetTranslationW("popup.error.update-check-failed.title"), i18n_.GetTranslationW("popup.error.update-check-failed.text")); - } else if (updateInfo_.shouldUpdate) { + } else if (updateInfo_.beta.shouldUpdate && betaUpdates) { + const std::wstring popupTitle = std::vformat( + i18n_.GetTranslationW("popup.update-available-beta.title"), + std::make_wformat_args(updateInfo_.beta.version)); + const std::wstring popupText = std::vformat( + i18n_.GetTranslationW("popup.update-available-beta.text"), + std::make_wformat_args(updateInfo_.currentVersion)); + trayIcon_.ShowPopup(popupTitle, popupText, WM_WINMUTE_UPDATE_POPUP); + } else if (updateInfo_.beta.shouldUpdate) { const std::wstring popupTitle = std::vformat( i18n_.GetTranslationW("popup.update-available.title"), - std::make_wformat_args(updateInfo_.newVersion)); + std::make_wformat_args(updateInfo_.beta.version)); const std::wstring popupText = std::vformat( i18n_.GetTranslationW("popup.update-available.text"), std::make_wformat_args(updateInfo_.currentVersion)); @@ -624,9 +635,16 @@ LRESULT WinMute::OnWifiStatusChange(HWND, WPARAM wParam, LPARAM lParam) LRESULT WinMute::OnUpdatePopup(HWND hWnd, WPARAM, LPARAM lParam) { if (lParam == NIN_BALLOONUSERCLICK) { - ShellExecuteW( - hWnd, L"open", updateInfo_.versionPageUrl.c_str(), - nullptr, nullptr, SW_SHOW); + const bool betaUpdates = settings_.QueryValue(SettingsKey::CHECK_FOR_BETA_UPDATE) != 0; + if (betaUpdates && updateInfo_.beta.shouldUpdate) { + ShellExecuteW( + hWnd, L"open", updateInfo_.beta.downloadUrl.c_str(), + nullptr, nullptr, SW_SHOW); + } else if (updateInfo_.stable.shouldUpdate) { + ShellExecuteW( + hWnd, L"open", updateInfo_.stable.downloadUrl.c_str(), + nullptr, nullptr, SW_SHOW); + } } return 0; } diff --git a/WinMute/WinMute.rc b/WinMute/WinMute.rc index ee9e616..0a1a12e 100644 --- a/WinMute/WinMute.rc +++ b/WinMute/WinMute.rc @@ -56,8 +56,8 @@ EXSTYLE WS_EX_CONTROLPARENT | WS_EX_APPWINDOW CAPTION "About WinMute" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - ICON IDI_APP,IDC_STATIC,13,7,20,20,SS_CENTERIMAGE - LTEXT "WinMute ",IDC_ABOUT_TITLE,41,7,193,23 + ICON IDI_APP,IDC_STATIC,13,7,21,20,SS_CENTERIMAGE + LTEXT "WinMute ",IDC_ABOUT_TITLE,45,7,193,23 CONTROL "",IDC_ABOUT_TAB,"SysTabControl32",0x0,7,34,299,202 PUSHBUTTON "OK",IDOK,242,246,64,16 END @@ -68,9 +68,9 @@ EXSTYLE WS_EX_CONTROLPARENT | WS_EX_APPWINDOW CAPTION "Settings" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN + CONTROL "",IDC_SETTINGS_TAB,"SysTabControl32",0x0,7,7,255,238 DEFPUSHBUTTON "OK",IDOK,158,246,50,14 PUSHBUTTON "Cancel",IDCANCEL,212,246,50,14 - CONTROL "",IDC_SETTINGS_TAB,"SysTabControl32",0x0,7,7,255,238 END IDD_SETTINGS_GENERAL DIALOGEX 0, 0, 233, 179 @@ -84,9 +84,11 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,34,219,17 CONTROL "Check for updates on startup",IDC_CHECK_FOR_UPDATES_ON_STARTUP, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,50,219,17 - CONTROL "Enable logging",IDC_ENABLELOGGING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,74,219,15 - PUSHBUTTON "Open log file...",IDC_OPENLOG,22,90,104,16 - LTEXT "[log file path]",IDC_LOGFILEPATH,23,110,203,27 + CONTROL "Also check for beta-updates",IDC_CHECK_FOR_BETA_UPDATES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,27,65,199,17 + CONTROL "Enable logging",IDC_ENABLELOGGING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,98,219,15 + PUSHBUTTON "Open log file...",IDC_OPENLOG,22,114,104,16 + LTEXT "[log file path]",IDC_LOGFILEPATH,23,134,203,27 END IDD_SETTINGS_QUIETHOURS DIALOGEX 0, 0, 246, 198 @@ -132,12 +134,17 @@ BEGIN GROUPBOX "General",IDC_GROUP_GENERAL,7,7,228,61 CONTROL "Show mute event notifications",IDC_SHOWNOTIFICATIONS, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,15,219,18 + CONTROL "Manage audio endpoints individually",IDC_MANAGE_AUDIO_ENDPOINTS_INDIVIDUALLY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,28,219,18 + PUSHBUTTON "Manage endpoints...",IDC_MANAGE_ENDPOINTS,26,46,97,15 GROUPBOX "Mute with volume restore, when...",IDC_GROUP_MUTE_WITH_RESTORE,7,71,228,71 CONTROL "... the workstation is locked.",IDC_MUTE_WHEN_WS_LOCKED, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,83,207,10 CONTROL "... the screen turns off.",IDC_MUTE_WHEN_SCREEN_OFF, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,97,205,10 CONTROL "Restore volume afterwards.",IDC_RESTOREVOLUME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,112,210,10 + EDITTEXT IDC_MUTEDELAY,13,124,30,13,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "seconds delay before muting.",IDC_DELAY_MUTING_LABEL,47,127,169,8 GROUPBOX "Mute without volume restore, when...",IDC_GROUP_MUTE_WITHOUT_RESTORE,7,145,228,67 CONTROL "... the computer shuts down.",IDC_MUTE_WHEN_SHUTDOWN, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,156,207,10 @@ -146,28 +153,23 @@ BEGIN CONTROL "... you log out.",IDC_MUTE_WHEN_LOGOUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,184,207,10 CONTROL "... when WinMute is started within a RDP session.",IDC_MUTE_WHEN_RDP_SESSION, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,198,208,10 - CONTROL "Manage audio endpoints individually",IDC_MANAGE_AUDIO_ENDPOINTS_INDIVIDUALLY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,28,219,18 - PUSHBUTTON "Manage endpoints...",IDC_MANAGE_ENDPOINTS,26,46,97,15 - LTEXT "seconds delay before muting.",IDC_DELAY_MUTING_LABEL,47,127,169,8 - EDITTEXT IDC_MUTEDELAY,13,124,30,13,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER END IDD_SETTINGS_WIFI DIALOGEX 0, 0, 242, 216 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LISTBOX IDC_WIFI_LIST,7,88,166,121,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add",IDC_WIFI_ADD,179,87,56,16 - PUSHBUTTON "Edit",IDC_WIFI_EDIT,179,106,56,16 - PUSHBUTTON "Remove",IDC_WIFI_REMOVE,179,125,56,16 - PUSHBUTTON "Remove all",IDC_WIFI_REMOVEALL,179,193,56,16 - CONTROL "Enable WLAN based muting",IDC_ENABLE_WIFI_MUTE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,44,228,14 LTEXT "Description\nDescription\nDescription\nDescription",IDC_WIFI_INTRO,7,7,228,37 + CONTROL "Enable WLAN based muting",IDC_ENABLE_WIFI_MUTE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,44,228,14 CONTROL "Mute if connected WLAN is in list",IDC_WLAN_LIST_IS_ALLOWLIST, "Button",BS_AUTORADIOBUTTON,17,60,209,10 CONTROL "Mute if connected WLAN is not in list",IDC_WLAN_LIST_IS_BLOCKLIST, "Button",BS_AUTORADIOBUTTON,17,73,207,10 + LISTBOX IDC_WIFI_LIST,7,88,166,121,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_WIFI_ADD,179,87,56,16 + PUSHBUTTON "Edit",IDC_WIFI_EDIT,179,106,56,16 + PUSHBUTTON "Remove",IDC_WIFI_REMOVE,179,125,56,16 + PUSHBUTTON "Remove all",IDC_WIFI_REMOVEALL,179,193,56,16 END IDD_SETTINGS_WIFI_ADD DIALOGEX 0, 0, 201, 62 @@ -175,10 +177,10 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Add WiFi" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "Save",IDOK,91,41,50,14 - PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 LTEXT "SSID/WiFi Name:",IDC_WIFI_NAME_LABEL,7,7,62,14 EDITTEXT IDC_WIFI_NAME,7,20,187,16,ES_AUTOHSCROLL + DEFPUSHBUTTON "Save",IDOK,91,41,50,14 + PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 END IDD_SETTINGS_BLUETOOTH DIALOGEX 0, 0, 244, 222 @@ -186,16 +188,16 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN + LTEXT "Description\nDescription\nDescription\nDescription\nDescription\nDescription",IDC_BLUETOOTH_DESCRIPTION_LABEL,7,7,230,51 + CONTROL "Enable Bluetooth based muting",IDC_ENABLE_BLUETOOTH_MUTE, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,62,228,14 + CONTROL "Enable only for these devices:",IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST, + "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,20,79,215,12 LISTBOX IDC_BLUETOOTH_LIST,7,95,168,120,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Add",IDC_BLUETOOTH_ADD,181,94,56,16 PUSHBUTTON "Edit",IDC_BLUETOOTH_EDIT,181,113,56,16 PUSHBUTTON "Remove",IDC_BLUETOOTH_REMOVE,181,132,56,16 PUSHBUTTON "Remove all",IDC_BLUETOOTH_REMOVEALL,181,199,56,16 - CONTROL "Enable Bluetooth based muting",IDC_ENABLE_BLUETOOTH_MUTE, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,62,228,14 - CONTROL "Enable only for these devices:",IDC_ENABLE_BLUETOOTH_MUTE_DEVICE_LIST, - "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,20,79,215,12 - LTEXT "Description\nDescription\nDescription\nDescription\nDescription\nDescription",IDC_BLUETOOTH_DESCRIPTION_LABEL,7,7,230,51 END IDD_SETTINGS_BLUETOOTH_ADD DIALOGEX 0, 0, 201, 62 @@ -203,10 +205,10 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Add Bluetooth device" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "Save",IDOK,91,41,50,14 - PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 LTEXT "Bluetooth device name:",IDC_LABEL_BT_DEVICE_NAME,7,7,187,14 COMBOBOX IDC_BT_DEVICE_NAME,7,22,187,17,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Save",IDOK,91,41,50,14 + PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 END IDD_MANAGE_ENDPOINTS DIALOGEX 0, 0, 241, 200 @@ -214,19 +216,19 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Manage Endpoints" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "Save",IDOK,133,179,50,14 - PUSHBUTTON "Cancel",IDCANCEL,184,179,50,14 - LISTBOX IDC_ENDPOINT_LIST,13,60,156,110,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add",IDC_ENDPOINT_ADD,175,60,56,16 - PUSHBUTTON "Edit",IDC_ENDPOINT_EDIT,175,78,56,16 - PUSHBUTTON "Remove",IDC_ENDPOINT_REMOVE,175,97,56,16 - PUSHBUTTON "Remove all",IDC_ENDPOINT_REMOVEALL,178,155,56,16 + GROUPBOX "List behaviour",IDC_GROUP_LIST_BEHAVIOUR,7,7,227,41 CONTROL "Mute only listed endpoints",IDC_ENDPOINT_LIST_IS_ALLOWLIST, "Button",BS_AUTORADIOBUTTON,13,19,209,10 CONTROL "Mute all but the listed endpoints",IDC_ENDPOINT_LIST_IS_BLOCKLIST, "Button",BS_AUTORADIOBUTTON,13,32,207,10 - GROUPBOX "List behaviour",IDC_GROUP_LIST_BEHAVIOUR,7,7,227,41 GROUPBOX "Endpoints",IDC_GROUP_ENDPOINTS,7,48,227,128 + LISTBOX IDC_ENDPOINT_LIST,13,60,156,110,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_ENDPOINT_ADD,175,60,56,16 + PUSHBUTTON "Edit",IDC_ENDPOINT_EDIT,175,78,56,16 + PUSHBUTTON "Remove",IDC_ENDPOINT_REMOVE,175,97,56,16 + PUSHBUTTON "Remove all",IDC_ENDPOINT_REMOVEALL,178,155,56,16 + DEFPUSHBUTTON "Save",IDOK,133,179,50,14 + PUSHBUTTON "Cancel",IDCANCEL,184,179,50,14 END IDD_MANAGE_ENDPOINTS_ADD DIALOGEX 0, 0, 201, 62 @@ -234,10 +236,10 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Add Endpoint" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "Save",IDOK,91,41,50,14 - PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 LTEXT "Endpoint name:",IDC_ENDPOINT_NAME_LABEL,7,7,187,14 COMBOBOX IDC_ENDPOINT_NAME,7,22,187,17,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Save",IDOK,91,41,50,14 + PUSHBUTTON "Cancel",IDCANCEL,144,41,50,14 END diff --git a/WinMute/common.h b/WinMute/common.h index 0f1b4fc..824c61e 100644 --- a/WinMute/common.h +++ b/WinMute/common.h @@ -134,7 +134,7 @@ constexpr int WM_WINMUTE_UPDATE_POPUP = WM_USER + 301; // ============================================================================= // Utility -void PrintWindowsError(const wchar_t *functionName, DWORD lastError = -1); +void ShowWindowsError(const wchar_t *functionName, DWORD lastError = -1); bool GetWinMuteVersion(std::wstring &versNumber); std::wstring ConvertStringToWideString(const std::string &ansiString); diff --git a/WinMute/resource.h b/WinMute/resource.h index ff23121..cac1163 100644 --- a/WinMute/resource.h +++ b/WinMute/resource.h @@ -42,10 +42,11 @@ #define IDC_ENABLE_WIFI_MUTE 1011 #define IDC_ENABLELOGGING 1012 #define IDC_CHECK3 1013 -#define IDC_RUNONSTARTUP2 1013 #define IDC_CHECK_FOR_UPDATES_ON_STARTUP 1013 #define IDC_OPENLOG 1014 #define IDC_LICENSETEXT 1015 +#define IDC_CHECK_FOR_UPDATES_ON_STARTUP2 1015 +#define IDC_CHECK_FOR_BETA_UPDATES 1015 #define IDC_ABOUT_TAB 1016 #define IDC_ABOUTTEXT 1019 #define IDC_TITLE 1020