From: lx-s Date: Sun, 1 Feb 2026 12:57:59 +0000 (+0100) Subject: Added settings migration to new quiet hours settings X-Git-Tag: 2.6.0.0~103^2~12 X-Git-Url: https://repos.lx-s.de/gitweb/?a=commitdiff_plain;h=e6b4345af1c57db12405c8b4b05cb94c6c7a97e0;p=winmute.git Added settings migration to new quiet hours settings --- diff --git a/Translations/lang-de.json b/Translations/lang-de.json index 9f57ac5..5d5054c 100644 --- a/Translations/lang-de.json +++ b/Translations/lang-de.json @@ -9,6 +9,8 @@ "init.error.winmute.text": "Ein kritischer Fehler trat beim starten von WinMute auf. Das Programm muss beendet werden.", "init.error.winmute.platform-support.title": "Nur Windows Vista and neuer werden unterstützt", "init.error.winmute.platform-support.text": "Für Windows XP Unterstützung, kann WinMute in der Version 1.4.2 oder älter installiert werden.", + "init.error.winmute.migrating-settings-error": "Fehler beim Migrieren der Einstellungen. Bitte konsultieren sie das Fehlerprotokoll und/oder erstellen sie ein Support-Ticket", + "init.error.winmute.quiet-hours-corrupted-settings": "QuietHours Einstellungen wurden beschädigt. Die QuietHour Zeiten wurden zurückgesetzt.", "general.error.winapi.text": "{} fehlgeschlagen mit Fehler {}: {}", "general.error.audio-service-shutdown.title": "Der Audioservice wurde beendet.", "general.error.audio-service-shutdown.text": "WinMute kann diese Situation nicht Beheben. Bitte starten Sie das Programm neu.", diff --git a/Translations/lang-en.json b/Translations/lang-en.json index 5cef550..33cd2d1 100644 --- a/Translations/lang-en.json +++ b/Translations/lang-en.json @@ -9,6 +9,8 @@ "init.error.winmute.text": "WinMute encountered a critical error while initializing and must shut down.", "init.error.winmute.platform-support.title": "Only Windows Vista and newer is supported", "init.error.winmute.platform-support.text": "If Windows XP support is needed, please download WinMute version 1.4.2 or lower.", + "init.error.winmute.migrating-settings-error": "Failed to migrate settings. Please review error log and/or create a support ticket", + "init.error.winmute.quiet-hours-corrupted-settings": "Quiet Hours settings are corrupted. Quiet Hour times have been reset", "general.error.winapi.text": "{} failed with error {}: {}", "general.error.audio-service-shutdown.title": "The audio service has been shut down.", "general.error.audio-service-shutdown.text": "WinMute is not able to recover from that condition.\nPlease try to restart the program.", diff --git a/WinMute/QuietHoursTimer.cpp b/WinMute/QuietHoursTimer.cpp index 3bffa1e..2c01972 100644 --- a/WinMute/QuietHoursTimer.cpp +++ b/WinMute/QuietHoursTimer.cpp @@ -130,8 +130,8 @@ bool QuietHoursTimer::LoadFromSettings(const WMSettings& settings) return true; } - qhStart_ = settings.QueryValue(SettingsKey::QUIETHOURS_START); - qhEnd_ = settings.QueryValue(SettingsKey::QUIETHOURS_END); + qhStart_ = settings.QueryValue(SettingsKey::QUIETHOURS_START_V0_DEPRECATED); + qhEnd_ = settings.QueryValue(SettingsKey::QUIETHOURS_END_V0_DEPRECATED); SYSTEMTIME now; SYSTEMTIME start; diff --git a/WinMute/Settings_QuietHoursDlg.cpp b/WinMute/Settings_QuietHoursDlg.cpp index 2785c8d..00c116f 100644 --- a/WinMute/Settings_QuietHoursDlg.cpp +++ b/WinMute/Settings_QuietHoursDlg.cpp @@ -76,8 +76,8 @@ static bool SaveQuietHours( if (!settings->SetValue(SettingsKey::QUIETHOURS_ENABLE, enabled) || !settings->SetValue(SettingsKey::QUIETHOURS_FORCEUNMUTE, forceUnmute) || !settings->SetValue(SettingsKey::QUIETHOURS_NOTIFICATIONS, showNotifications) - || !settings->SetValue(SettingsKey::QUIETHOURS_START, setStart) - || !settings->SetValue(SettingsKey::QUIETHOURS_END, setEnd)) { + || !settings->SetValue(SettingsKey::QUIETHOURS_START_V0_DEPRECATED, setStart) + || !settings->SetValue(SettingsKey::QUIETHOURS_END_V0_DEPRECATED, setEnd)) { WMi18n &i18n = WMi18n::GetInstance(); TaskDialog( @@ -143,8 +143,8 @@ INT_PTR CALLBACK Settings_QuietHoursDlgProc(HWND hDlg, UINT msg, WPARAM wParam, EnableWindow(hStart, qhEnabled); EnableWindow(hEnd, qhEnabled); - int setStart = settings->QueryValue(SettingsKey::QUIETHOURS_START); - int setEnd = settings->QueryValue(SettingsKey::QUIETHOURS_END); + int setStart = settings->QueryValue(SettingsKey::QUIETHOURS_START_V0_DEPRECATED); + int setEnd = settings->QueryValue(SettingsKey::QUIETHOURS_END_V0_DEPRECATED); SYSTEMTIME start; GetLocalTime(&start); diff --git a/WinMute/WMSettings.cpp b/WinMute/WMSettings.cpp index 176c07f..e7469e4 100644 --- a/WinMute/WMSettings.cpp +++ b/WinMute/WMSettings.cpp @@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" -static constexpr int CURRENT_SETTINGS_VERSION = 0; +static constexpr int CURRENT_SETTINGS_VERSION = 1; static const wchar_t *LX_SYSTEMS_SUBKEY = L"SOFTWARE\\lx-systems\\WinMute"; @@ -43,6 +43,8 @@ static const wchar_t* LX_SYSTEMS_BLUETOOTH_SUBKEY = L"SOFTWARE\\lx-systems\\WinMute\\BluetoothDevices"; static const wchar_t *LX_SYSTEMS_AUDIO_ENDPOINTS_SUBKEY = L"SOFTWARE\\lx-systems\\WinMute\\ManagedAudioEndpoints"; +static const wchar_t *LX_SYSTEMS_QUIET_HOUR_TIMES_SUBKEY += L"SOFTWARE\\lx-systems\\WinMute\\QuietHourTimes"; static const wchar_t* LX_SYSTEMS_AUTOSTART_KEY = L"LX-Systems WinMute"; @@ -113,10 +115,10 @@ static const wchar_t* KeyToStr(SettingsKey key) case SettingsKey::QUIETHOURS_NOTIFICATIONS: keyStr = L"QuietHoursNotifications"; break; - case SettingsKey::QUIETHOURS_START: + case SettingsKey::QUIETHOURS_START_V0_DEPRECATED: keyStr = L"QuietHoursStart"; break; - case SettingsKey::QUIETHOURS_END: + case SettingsKey::QUIETHOURS_END_V0_DEPRECATED: keyStr = L"QuietHoursEnd"; break; case SettingsKey::LOGGING_ENABLED: @@ -177,9 +179,9 @@ static DWORD GetDefaultSetting(SettingsKey key) return 0; case SettingsKey::QUIETHOURS_NOTIFICATIONS: return 0; - case SettingsKey::QUIETHOURS_START: + case SettingsKey::QUIETHOURS_START_V0_DEPRECATED: return 0; - case SettingsKey::QUIETHOURS_END: + case SettingsKey::QUIETHOURS_END_V0_DEPRECATED: return 0; case SettingsKey::LOGGING_ENABLED: return 0; @@ -250,9 +252,36 @@ WMSettings::~WMSettings() bool WMSettings::MigrateSettings() { + WMi18n &i18n = WMi18n::GetInstance(); DWORD version = QueryValue(SettingsKey::SETTINGS_VERSION); - if (version != CURRENT_SETTINGS_VERSION) { - WMLog::GetInstance().LogError(L"Unexpected settings version: %d", version); + if (version > CURRENT_SETTINGS_VERSION) { + WMLog::GetInstance().LogError( + L"Settings version %d is newer than application supports (%d). " + L"Some settings may not work correctly.", + version, + CURRENT_SETTINGS_VERSION); + } else if (version == 0) { + // Migrate Quiet Hours settings from old keys and update settings version + const auto quietHoursStart = QueryValue(SettingsKey::QUIETHOURS_START_V0_DEPRECATED); + const auto quietHoursEnd = QueryValue(SettingsKey::QUIETHOURS_END_V0_DEPRECATED); + + if (StoreQuietHoursTimes({ { quietHoursStart, quietHoursEnd } }) + && SetValue(SettingsKey::SETTINGS_VERSION, CURRENT_SETTINGS_VERSION)) { + // Remove old settings keys + RegDeleteValueW(hSettingsKey_, KeyToStr(SettingsKey::QUIETHOURS_START_V0_DEPRECATED)); + RegDeleteValueW(hSettingsKey_, KeyToStr(SettingsKey::QUIETHOURS_END_V0_DEPRECATED)); + } else { + WMLog::GetInstance().LogError(L"Error migrating Quiet Hours settings"); + TaskDialog( + nullptr, + nullptr, + PROGRAM_NAME, + i18n.GetTranslationW("init.error.winmute.title").c_str(), + i18n.GetTranslationW("init.error.winmute.migrating-settings-error").c_str(), + TDCBF_OK_BUTTON, + TD_ERROR_ICON, + nullptr); + } } return true; } @@ -336,6 +365,31 @@ bool WMSettings::Init() } } + if (hQuietHoursTimesKey_ == nullptr) { + DWORD regError = RegCreateKeyExW( + HKEY_CURRENT_USER, + LX_SYSTEMS_QUIET_HOUR_TIMES_SUBKEY, + 0, + nullptr, + 0, + KEY_READ | KEY_WRITE, + nullptr, + &hQuietHoursTimesKey_, + nullptr); + if (regError != ERROR_SUCCESS) { + ShowWindowsError(L"RegCreateKeyEx", regError); + RegCloseKey(hWifiKey_); + RegCloseKey(hSettingsKey_); + RegCloseKey(hBluetoothKey_); + RegCloseKey(hAudioEndpointsKey_); + hSettingsKey_ = nullptr; + hWifiKey_ = nullptr; + hBluetoothKey_ = nullptr; + hAudioEndpointsKey_ = nullptr; + return false; + } + } + MigrateSettings(); return true; @@ -703,6 +757,136 @@ std::vector WMSettings::GetBluetoothDevicesW() const return devices; } +bool WMSettings::StoreQuietHoursTimes(const std::vector> ×) +{ + // Clear all stored keys + for (;;) { + wchar_t valueName[260] = { 0 }; + DWORD valueSize = ARRAY_SIZE(valueName); + DWORD regError = RegEnumValueW( + hQuietHoursTimesKey_, + 0, + valueName, + &valueSize, + nullptr, + nullptr, + nullptr, + nullptr); + if (regError == ERROR_NO_MORE_ITEMS) { + break; + } else if (regError != ERROR_SUCCESS) { + ShowWindowsError(L"RegEnumValue", regError); + return false; + } else { + regError = RegDeleteValue(hQuietHoursTimesKey_, valueName); + if (regError != ERROR_SUCCESS) { + ShowWindowsError(L"RegDeleteValue", regError); + return false; + } + } + } + + for (size_t i = 0; i < times.size(); ++i) { + const std::wstring keyStart = L"Start" + std::to_wstring(i); + const std::wstring keyEnd = L"End" + std::to_wstring(i); + DWORD regError = RegSetValueExW( + hQuietHoursTimesKey_, + keyStart.c_str(), + 0, + REG_DWORD, + reinterpret_cast(×[i].first), + static_cast(sizeof(times[i].first))); + if (regError != ERROR_SUCCESS) { + ShowWindowsError(L"RegSetValueEx", regError); + return false; + } + regError = RegSetValueExW( + hQuietHoursTimesKey_, + keyEnd.c_str(), + 0, + REG_DWORD, + reinterpret_cast(×[i].second), + static_cast(sizeof(times[i].second))); + if (regError != ERROR_SUCCESS) { + ShowWindowsError(L"RegSetValueEx", regError); + return false; + } + } + return true; +} + +std::vector> WMSettings::GetQuietHoursTimes() +{ + WMi18n &i18n = WMi18n::GetInstance(); + + DWORD numEntries = 0; + auto regError = RegQueryInfoKeyW( + hQuietHoursTimesKey_, + nullptr, nullptr, + nullptr, nullptr, + nullptr, nullptr, + &numEntries, nullptr, + nullptr, nullptr, + nullptr); + if (regError != ERROR_SUCCESS) { + ShowWindowsError(L"ShowWindowsError", regError); + return {}; + } + + if (numEntries % 2 != 0) { + WMLog::GetInstance().LogError( + L"Corrupted Quiet Hours times in registry: odd number of entries (%d). Resetting QuietHours", numEntries); + TaskDialog( + nullptr, + nullptr, + PROGRAM_NAME, + i18n.GetTranslationW("init.error.winmute.title").c_str(), + i18n.GetTranslationW("init.error.winmute.migrating-settings-error").c_str(), + TDCBF_OK_BUTTON, + TD_ERROR_ICON, + nullptr); + StoreQuietHoursTimes({}); + return {}; + } + + std::vector> times; + for (DWORD valIdx = 0; valIdx < numEntries; valIdx += 2) { + const std::wstring keyStart = L"Start" + std::to_wstring(valIdx); + const std::wstring keyEnd = L"End" + std::to_wstring(valIdx); + + std::pair timeEntry{}; + DWORD size{}; + regError = RegQueryValueExW( + hQuietHoursTimesKey_, + keyStart.c_str(), + 0, + nullptr, + reinterpret_cast(&timeEntry.first), + &size); + if (regError != ERROR_SUCCESS) { + WMLog::GetInstance().LogError( + L"Failed to read entry \"%s\" while initializing quiet hours", + keyStart.c_str()); + continue; + } + regError = RegQueryValueExW( + hQuietHoursTimesKey_, + keyEnd.c_str(), + 0, + nullptr, + reinterpret_cast(&timeEntry.second), + &size); + if (regError != ERROR_SUCCESS) { + WMLog::GetInstance().LogError( + L"Failed to read entry \"%s\" while initializing quiet hours", + keyStart.c_str()); + continue; + } + times.push_back(std::move(timeEntry)); + } + return times; +} + bool WMSettings::StoreManagedAudioEndpoints(std::vector &endpoints) { diff --git a/WinMute/WMSettings.h b/WinMute/WMSettings.h index 1fb919d..be680de 100644 --- a/WinMute/WMSettings.h +++ b/WinMute/WMSettings.h @@ -62,8 +62,8 @@ enum class SettingsKey { , QUIETHOURS_ENABLE , QUIETHOURS_FORCEUNMUTE , QUIETHOURS_NOTIFICATIONS - , QUIETHOURS_START - , QUIETHOURS_END + , QUIETHOURS_START_V0_DEPRECATED // Settings v0 to v1. Migrated to Subkey + , QUIETHOURS_END_V0_DEPRECATED // Settings v0 to v1. Migrated to Subkey , NOTIFICATIONS_ENABLED , LOGGING_ENABLED , APP_LANGUAGE @@ -95,6 +95,9 @@ public: bool StoreManagedAudioEndpoints(std::vector &endpoints); std::vector GetManagedAudioEndpoints() const; + bool StoreQuietHoursTimes(const std::vector> ×); + std::vector> GetQuietHoursTimes(); + DWORD QueryValue(SettingsKey key) const; bool SetValue(SettingsKey key, DWORD value); @@ -102,10 +105,11 @@ public: bool SetValue(SettingsKey key, const std::wstring &value); private: - HKEY hSettingsKey_; - HKEY hWifiKey_; - HKEY hBluetoothKey_; - HKEY hAudioEndpointsKey_; + HKEY hSettingsKey_ = nullptr; + HKEY hWifiKey_ = nullptr; + HKEY hBluetoothKey_ = nullptr; + HKEY hAudioEndpointsKey_ = nullptr; + HKEY hQuietHoursTimesKey_ = nullptr; bool MigrateSettings(); HKEY OpenAutostartKey(REGSAM samDesired);