From: lx-s Date: Mon, 18 Dec 2023 19:29:30 +0000 (+0100) Subject: Started implementing updater X-Git-Tag: 2.4.9.0~36 X-Git-Url: https://repos.lx-s.de/gitweb/?a=commitdiff_plain;h=c170576bbd846d828270f5f612f8226d77b8db3b;p=winmute.git Started implementing updater --- diff --git a/WinMute/UpdateChecker.cpp b/WinMute/UpdateChecker.cpp new file mode 100644 index 0000000..131c378 --- /dev/null +++ b/WinMute/UpdateChecker.cpp @@ -0,0 +1,195 @@ +/* + WinMute + Copyright (c) 2023, Alexander Steinhoefer + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the author nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#include "common.h" + +class HInternetHolder { +public: + HInternetHolder(HINTERNET hInternet) + : hInternet_(hInternet) + {} + ~HInternetHolder() + { + if (hInternet_ != nullptr) { + WinHttpCloseHandle(hInternet_); + } + } + operator HINTERNET() + { + return hInternet_; + } +private: + HINTERNET hInternet_; +}; + + +UpdateChecker::UpdateChecker(const WMSettings &settings): + settings_(settings) +{ + +} + +UpdateChecker::~UpdateChecker() +{ + +} + +bool UpdateChecker::ShouldUpdate(std::wstring& , std::wstring& ) const +{ + //if (!IsUpdateCheckEnabled()) { + // return false; + //} + + WMLog &log = WMLog::GetInstance(); + HInternetHolder hSession = WinHttpOpen( + L"WinMute", + WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, + WINHTTP_FLAG_SECURE_DEFAULTS); + if (hSession == nullptr) { + log.WriteWindowsError(L"WinHttpOpen", GetLastError()); + return false; + } + + HInternetHolder hConnect = WinHttpConnect( + hSession, + L"raw.githubusercontent.com", + INTERNET_DEFAULT_HTTPS_PORT, + 0); + if (hConnect == nullptr) { + log.WriteWindowsError(L"WinHttpConnect", GetLastError()); + return false; + } + +#ifdef _DEBUG + const wchar_t *updateFileUrl = L"/lx-s/WinMute/dev/CURRENT_VERSION"; +#else + const wchar_t *updateFileUrl = L"/lx-s/WinMute/main/CURRENT_VERSION"; +#endif + HInternetHolder hRequest = WinHttpOpenRequest( + hConnect, + L"GET", + updateFileUrl, + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE); + + if (hRequest == nullptr) { + log.WriteWindowsError(L"WinHttpConnect", GetLastError()); + return false; + } + + bool result = WinHttpSendRequest( + hRequest, + WINHTTP_NO_ADDITIONAL_HEADERS, + 0, + WINHTTP_NO_REQUEST_DATA, + 0, + 0, + 0); + + if (!result) { + log.WriteWindowsError(L"WinHttpSendRequest", GetLastError()); + return false; + } + + result = WinHttpReceiveResponse(hRequest, nullptr); + if (!result) { + log.WriteWindowsError(L"WinHttpReceiveResponse", GetLastError()); + return false; + } + + DWORD statusCode = 0; + DWORD statusCodeSize = static_cast(sizeof(statusCode)); + result = WinHttpQueryHeaders( + hRequest, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + WINHTTP_HEADER_NAME_BY_INDEX, + reinterpret_cast(&statusCode), + &statusCodeSize, + WINHTTP_NO_HEADER_INDEX); + if (!result) { + log.WriteWindowsError(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); + return false; + } + + std::string versionFileContents; + for (;;) { + DWORD availBytes = 0; + if (!WinHttpQueryDataAvailable(hRequest, &availBytes)) { + log.WriteWindowsError(L"WinHttpQueryDataAvailable", GetLastError()); + return false; + } + if (availBytes == 0) { + break; + } + std::string chunk(availBytes, ' '); + DWORD byRead = 0; + if (!WinHttpReadData(hRequest, reinterpret_cast(&chunk[0]), availBytes, &byRead)) { + log.WriteWindowsError(L"WinHttpReadData", GetLastError()); + return false; + } + versionFileContents.append(chunk.begin(), chunk.begin() + byRead); + } + + // Check contents of version file + return true; +} + +bool UpdateChecker::IsUpdateCheckEnabled() const +{ + const auto updateCheckSetting = settings_.QueryValue(SettingsKey::CHECK_FOR_UPDATE); + if (updateCheckSetting == static_cast(UpdateCheckInterval::DISABLED)) { + return false; + } + + wchar_t thisExePath[MAX_PATH * 2]; + 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); + return false; + } + fs::path updateDisableFile{ thisExePath }; + updateDisableFile.replace_filename(L"update-check-disabled"); + if (fs::exists(updateDisableFile)) { + return false; + } + + return true; +} diff --git a/WinMute/UpdateChecker.h b/WinMute/UpdateChecker.h new file mode 100644 index 0000000..378760c --- /dev/null +++ b/WinMute/UpdateChecker.h @@ -0,0 +1,61 @@ +/* + WinMute + Copyright (c) 2023, Alexander Steinhoefer + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the author nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#pragma once + +#include "WMSettings.h" + +enum class UpdateCheckInterval : int { + DISABLED = 0, + ON_STARTUP = 1, +}; + +class UpdateChecker { +public: + explicit UpdateChecker(const WMSettings& settings); + ~UpdateChecker(); + + bool ShouldUpdate(std::wstring& curVersion, std::wstring& newVersion) const; + std::wstring GetUpdateURL() const; +private: + UpdateChecker(const UpdateChecker &) = delete; + UpdateChecker &operator=(const UpdateChecker &) = delete; + UpdateChecker(const UpdateChecker &&) = delete; + UpdateChecker &operator=(const UpdateChecker &&) = delete; + + bool IsUpdateCheckEnabled() const; + + bool ExtractVersion(HINTERNET hRequest) const; + + const WMSettings &settings_; +}; diff --git a/WinMute/WMSettings.cpp b/WinMute/WMSettings.cpp index aaf4c62..09438cc 100644 --- a/WinMute/WMSettings.cpp +++ b/WinMute/WMSettings.cpp @@ -122,6 +122,9 @@ static const wchar_t* KeyToStr(SettingsKey key) case SettingsKey::APP_LANGUAGE: keyStr = L"AppLanguage"; break; + case SettingsKey::CHECK_FOR_UPDATE: + keyStr = L"CheckForUpdate"; + break; } return keyStr; } @@ -171,6 +174,8 @@ static DWORD GetDefaultSetting(SettingsKey key) return 0; case SettingsKey::APP_LANGUAGE: return 0; + case SettingsKey::CHECK_FOR_UPDATE: + return 0; } return 0; } diff --git a/WinMute/WMSettings.h b/WinMute/WMSettings.h index af5b561..c0e929d 100644 --- a/WinMute/WMSettings.h +++ b/WinMute/WMSettings.h @@ -65,6 +65,7 @@ enum class SettingsKey { , NOTIFICATIONS_ENABLED , LOGGING_ENABLED , APP_LANGUAGE + , CHECK_FOR_UPDATE }; class WMSettings { diff --git a/WinMute/WinMain.cpp b/WinMute/WinMain.cpp index e5f9a9f..42ad448 100644 --- a/WinMute/WinMain.cpp +++ b/WinMute/WinMain.cpp @@ -97,6 +97,10 @@ int WINAPI wWinMain( return FALSE; } + UpdateChecker updateChecker(settings); + std::wstring w1, w2; + updateChecker.ShouldUpdate(w1, w2); + LoadLanguage(settings, i18n); HANDLE hMutex = CreateMutexW(nullptr, TRUE, L"LxSystemsWinMuteRunOnce"); diff --git a/WinMute/WinMute.vcxproj b/WinMute/WinMute.vcxproj index 52f2d23..1a2356a 100644 --- a/WinMute/WinMute.vcxproj +++ b/WinMute/WinMute.vcxproj @@ -120,7 +120,7 @@ Windows true - strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Wlanapi.lib;Version.lib;%(AdditionalDependencies) + Advapi32.lib;Winhttp.lib;Bthprops.lib;comsuppwd.lib;comctl32.lib;strsafe.lib;UxTheme.lib;Winmm.lib;Wlanapi.lib;WtsApi32.lib;Shell32.lib;Version.lib;Gdi32.lib PerMonitorHighDPIAware @@ -147,7 +147,7 @@ true true true - strsafe.lib;comctl32.lib;WtsApi32.lib;Winmm.lib;UxTheme.lib;comsuppwd.lib;Wlanapi.lib;Version.lib;%(AdditionalDependencies) + Advapi32.lib;Winhttp.lib;Bthprops.lib;comsuppwd.lib;comctl32.lib;strsafe.lib;UxTheme.lib;Winmm.lib;Wlanapi.lib;WtsApi32.lib;Shell32.lib;Version.lib;Gdi32.lib PerMonitorHighDPIAware @@ -168,7 +168,7 @@ Windows true - Bthprops.lib;comsuppwd.lib;comctl32.lib;strsafe.lib;UxTheme.lib;Winmm.lib;Wlanapi.lib;WtsApi32.lib;Version.lib;%(AdditionalDependencies) + Advapi32.lib;Winhttp.lib;Bthprops.lib;comsuppwd.lib;comctl32.lib;strsafe.lib;UxTheme.lib;Winmm.lib;Wlanapi.lib;WtsApi32.lib;Shell32.lib;Version.lib;Gdi32.lib PerMonitorHighDPIAware @@ -195,7 +195,7 @@ true true true - Bthprops.lib;comsuppwd.lib;comctl32.lib;strsafe.lib;UxTheme.lib;Winmm.lib;Wlanapi.lib;WtsApi32.lib;Version.lib;%(AdditionalDependencies) + Advapi32.lib;Winhttp.lib;Bthprops.lib;comsuppwd.lib;comctl32.lib;strsafe.lib;UxTheme.lib;Winmm.lib;Wlanapi.lib;WtsApi32.lib;Shell32.lib;Version.lib;Gdi32.lib PerMonitorHighDPIAware @@ -206,6 +206,7 @@ + @@ -239,6 +240,7 @@ + diff --git a/WinMute/WinMute.vcxproj.filters b/WinMute/WinMute.vcxproj.filters index 7514fe5..10f4ab5 100644 --- a/WinMute/WinMute.vcxproj.filters +++ b/WinMute/WinMute.vcxproj.filters @@ -111,6 +111,9 @@ Source Files\_External + + Source Files\Base\Settings + @@ -171,9 +174,6 @@ Source Files\UI\Dialogs\Settings - - Source Files\UI\Dialogs - Source Files\UI\Dialogs\Settings @@ -195,6 +195,12 @@ Source Files\Base\Settings + + Source Files\Base\Settings + + + Source Files\UI\Dialogs\Settings + diff --git a/WinMute/common.h b/WinMute/common.h index 6ef6ca7..eb2d327 100644 --- a/WinMute/common.h +++ b/WinMute/common.h @@ -58,19 +58,20 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include #include #include #include -#include #include #include #include +#include #include -#include +#include +#include #include +#include +#include #include -#include #include namespace fs = std::filesystem; @@ -79,6 +80,7 @@ namespace fs = std::filesystem; #include #include #include +#include #include #include #include @@ -103,6 +105,7 @@ namespace fs = std::filesystem; #include "WMi18n.h" #include "WMSettings.h" #include "WMLog.h" +#include "UpdateChecker.h" #include "TrayIcon.h" #include "WinAudio.h" #include "MuteControl.h" @@ -112,7 +115,6 @@ namespace fs = std::filesystem; #include "WinMute.h" #include "VersionHelper.h" - // Utility void PrintWindowsError(const wchar_t *functionName, DWORD lastError = -1); bool GetWinMuteVersion(std::wstring &versNumber);