diff --git a/src/modules/imageresizer/dll/ContextMenuHandler.cpp b/src/modules/imageresizer/dll/ContextMenuHandler.cpp index b257e62bae..b40286faad 100644 --- a/src/modules/imageresizer/dll/ContextMenuHandler.cpp +++ b/src/modules/imageresizer/dll/ContextMenuHandler.cpp @@ -37,7 +37,7 @@ HRESULT CContextMenuHandler::Initialize(_In_opt_ PCIDLIST_ABSOLUTE pidlFolder, _ { Uninitialize(); - if (!CSettings::GetEnabled()) + if (!CSettingsInstance().GetEnabled()) { return E_FAIL; } @@ -62,7 +62,7 @@ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, { return S_OK; } - if (!CSettings::GetEnabled()) + if (!CSettingsInstance().GetEnabled()) { return E_FAIL; } @@ -354,7 +354,7 @@ HRESULT __stdcall CContextMenuHandler::GetCanonicalName(GUID* pguidCommandName) HRESULT __stdcall CContextMenuHandler::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) { - if (!CSettings::GetEnabled()) + if (!CSettingsInstance().GetEnabled()) { *pCmdState = ECS_HIDDEN; return S_OK; diff --git a/src/modules/imageresizer/dll/Settings.cpp b/src/modules/imageresizer/dll/Settings.cpp index f3bf74f898..bdfcc91aa9 100644 --- a/src/modules/imageresizer/dll/Settings.cpp +++ b/src/modules/imageresizer/dll/Settings.cpp @@ -1,66 +1,116 @@ #include "pch.h" -#include #include "Settings.h" -const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer"; -const wchar_t c_enabled[] = L"Enabled"; -const bool c_enabledDefault = true; +#include +#include +#include +#include -bool CSettings::GetEnabled() +namespace { - return GetRegBoolValue(c_enabled, c_enabledDefault); -} + const wchar_t c_imageResizerDataFilePath[] = L"\\image-resizer-settings.json"; + const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer"; + const wchar_t c_enabled[] = L"Enabled"; -bool CSettings::SetEnabled(_In_ bool enabled) -{ - return SetRegBoolValue(c_enabled, enabled); -} - -bool CSettings::SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value) -{ - DWORD dwValue = value ? 1 : 0; - return SetRegDWORDValue(valueName, dwValue); -} - -bool CSettings::GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue) -{ - DWORD value = GetRegDWORDValue(valueName, (defaultValue == 0) ? false : true); - return (value == 0) ? false : true; -} - -bool CSettings::SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value) -{ - return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_DWORD, &value, sizeof(value))))); -} - -DWORD CSettings::GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue) -{ - DWORD retVal = defaultValue; - DWORD type = REG_DWORD; - DWORD dwEnabled = 0; - DWORD cb = sizeof(dwEnabled); - if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, &dwEnabled, &cb) == ERROR_SUCCESS) + unsigned int RegReadInteger(const std::wstring& valueName, unsigned int defaultValue) { - retVal = dwEnabled; + DWORD type = REG_DWORD; + DWORD data = 0; + DWORD size = sizeof(DWORD); + if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), &type, &data, &size) == ERROR_SUCCESS) + { + return data; + } + return defaultValue; } - return retVal; -} - -bool CSettings::SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value) -{ - ULONG cb = (DWORD)((wcslen(value) + 1) * sizeof(*value)); - return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_SZ, (const BYTE*)value, cb)))); -} - -bool CSettings::GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf) -{ - if (cchBuf > 0) + bool RegReadBoolean(const std::wstring& valueName, bool defaultValue) { - value[0] = L'\0'; + DWORD value = RegReadInteger(valueName.c_str(), defaultValue ? 1 : 0); + return (value == 0) ? false : true; } - DWORD type = REG_SZ; - ULONG cb = cchBuf * sizeof(*value); - return (SUCCEEDED(HRESULT_FROM_WIN32(SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, value, &cb) == ERROR_SUCCESS))); + bool LastModifiedTime(const std::wstring& filePath, FILETIME* lpFileTime) + { + WIN32_FILE_ATTRIBUTE_DATA attr{}; + if (GetFileAttributesExW(filePath.c_str(), GetFileExInfoStandard, &attr)) + { + *lpFileTime = attr.ftLastWriteTime; + return true; + } + return false; + } +} + +CSettings::CSettings() +{ + std::wstring result = PTSettingsHelper::get_module_save_folder_location(L"ImageResizer"); + jsonFilePath = result + std::wstring(c_imageResizerDataFilePath); + Load(); +} + +void CSettings::Save() +{ + json::JsonObject jsonData; + + jsonData.SetNamedValue(c_enabled, json::value(settings.enabled)); + + json::to_file(jsonFilePath, jsonData); + GetSystemTimeAsFileTime(&lastLoadedTime); +} + +void CSettings::Load() +{ + if (!std::filesystem::exists(jsonFilePath)) + { + MigrateFromRegistry(); + + Save(); + } + else + { + ParseJson(); + } +} + +void CSettings::Reload() +{ + // Load json settings from data file if it is modified in the meantime. + FILETIME lastModifiedTime{}; + if (LastModifiedTime(jsonFilePath, &lastModifiedTime) && + CompareFileTime(&lastModifiedTime, &lastLoadedTime) == 1) + { + Load(); + } +} + +void CSettings::MigrateFromRegistry() +{ + settings.enabled = RegReadBoolean(c_enabled, true); +} + +void CSettings::ParseJson() +{ + auto json = json::from_file(jsonFilePath); + if (json) + { + const json::JsonObject& jsonSettings = json.value(); + try + { + if (json::has(jsonSettings, c_enabled, json::JsonValueType::Boolean)) + { + settings.enabled = jsonSettings.GetNamedBoolean(c_enabled); + } + } + catch (const winrt::hresult_error&) + { + } + } + GetSystemTimeAsFileTime(&lastLoadedTime); +} + +CSettings& CSettingsInstance() +{ + static CSettings instance; + return instance; } \ No newline at end of file diff --git a/src/modules/imageresizer/dll/Settings.h b/src/modules/imageresizer/dll/Settings.h index aa00f9b30d..f0b51861df 100644 --- a/src/modules/imageresizer/dll/Settings.h +++ b/src/modules/imageresizer/dll/Settings.h @@ -3,14 +3,36 @@ class CSettings { public: - static bool GetEnabled(); - static bool SetEnabled(_In_ bool enabled); + CSettings(); + + inline bool GetEnabled() + { + Reload(); + return settings.enabled; + } + + inline void SetEnabled(bool enabled) + { + settings.enabled = enabled; + Save(); + } + + void Save(); + void Load(); private: - static bool GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue); - static bool SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value); - static bool SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value); - static DWORD GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue); - static bool SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value); - static bool GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf); -}; \ No newline at end of file + struct Settings + { + bool enabled{ true }; + }; + + void Reload(); + void MigrateFromRegistry(); + void ParseJson(); + + Settings settings; + std::wstring jsonFilePath; + FILETIME lastLoadedTime; +}; + +CSettings& CSettingsInstance(); \ No newline at end of file diff --git a/src/modules/imageresizer/dll/dllmain.cpp b/src/modules/imageresizer/dll/dllmain.cpp index 7353ac9ecc..337fdf4172 100644 --- a/src/modules/imageresizer/dll/dllmain.cpp +++ b/src/modules/imageresizer/dll/dllmain.cpp @@ -37,7 +37,7 @@ public: // Constructor ImageResizerModule() { - m_enabled = CSettings::GetEnabled(); + m_enabled = CSettingsInstance().GetEnabled(); app_name = GET_RESOURCE_STRING(IDS_IMAGERESIZER); }; @@ -87,7 +87,7 @@ public: virtual void enable() { m_enabled = true; - CSettings::SetEnabled(m_enabled); + CSettingsInstance().SetEnabled(m_enabled); Trace::EnableImageResizer(m_enabled); } @@ -95,7 +95,7 @@ public: virtual void disable() { m_enabled = false; - CSettings::SetEnabled(m_enabled); + CSettingsInstance().SetEnabled(m_enabled); Trace::EnableImageResizer(m_enabled); } diff --git a/src/modules/powerrename/lib/Settings.cpp b/src/modules/powerrename/lib/Settings.cpp index c8d8da7f9d..5eddcb910c 100644 --- a/src/modules/powerrename/lib/Settings.cpp +++ b/src/modules/powerrename/lib/Settings.cpp @@ -441,7 +441,6 @@ void CSettings::Reload() } } - void CSettings::MigrateFromRegistry() { settings.enabled = GetRegBoolean(c_enabled, true);