From ca8fbe010ffb0264bb5c791624379b68afeaabc0 Mon Sep 17 00:00:00 2001 From: Valentin Radu Date: Sat, 22 Jan 2022 21:12:18 +0200 Subject: [PATCH] When an update is available, the notification displays the version of the update; The updater correctly detects when the current version is a pre-release but the user has switched the update channel to stable and does not suggest the older stable version as an update anymore (multiple reports, #540, #710) --- CHANGELOG.md | 2 + ExplorerPatcher/updates.c | 157 +++++++++++++++++++++++++++++--- ExplorerPatcher/utility.c | 29 +++++- ExplorerPatcher/utility.h | 4 +- ep_setup_patch/ep_setup_patch.c | 4 +- version.h | 6 +- 6 files changed, 183 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b44c05..b641d48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ Tested on OS build 22000.434. * Windows 10 * Simple Window Switcher now highlights windows that require user attention (windows that have their taskbar button flash and colored in orange) (.8) * Reliability improvements for the option that maps the `Win`+`C` shortcut to open the clock flyout instead of Microsoft Teams (eliminated dependency on symbol data) (.10) +* When an update is available, the notification displays the version of the update (.12) +* The updater correctly detects when the current version is a pre-release but the user has switched the update channel to stable and does not suggest the older stable version as an update anymore (multiple reports, #540, #710) (.12) #### Fixes diff --git a/ExplorerPatcher/updates.c b/ExplorerPatcher/updates.c index 92a2e9d..5c409f4 100644 --- a/ExplorerPatcher/updates.c +++ b/ExplorerPatcher/updates.c @@ -64,7 +64,9 @@ BOOL IsUpdateAvailableHelper( __x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast, BOOL bUpdatePreferStaging, WCHAR* wszInfoURL, - DWORD dwInfoURLLen + DWORD dwInfoURLLen, + HMODULE hModule, + DWORD* pLeftMost, DWORD* pSecondLeft, DWORD* pSecondRight, DWORD* pRightMost ) { BOOL bIsUpdateAvailable = FALSE; @@ -199,15 +201,127 @@ BOOL IsUpdateAvailableHelper( #ifdef UPDATES_VERBOSE_OUTPUT printf("[Updates] Hash of remote file is \"%s\" (%s).\n", DOSMODE_OFFSET + hash, (hash[0] == 0x4D && hash[1] == 0x5A) ? "valid" : "invalid"); #endif - if (hash[0] == 0x4D && hash[1] == 0x5A && _stricmp(DOSMODE_OFFSET + hash, szCheckAgainst)) + BOOL bOldType = TRUE; + char *szLeftMost = NULL, *szSecondLeft = NULL, *szSecondRight = NULL, *szRightMost = NULL, *szRealHash = NULL; + if (hModule) { - bIsUpdateAvailable = TRUE; + if (hash[0] == 0x4D && hash[1] == 0x5A) + { + if (strchr(DOSMODE_OFFSET + hash, '.')) + { + szLeftMost = DOSMODE_OFFSET + hash; + if (szSecondLeft = strchr(szLeftMost, '.')) + { + *szSecondLeft = 0; + szSecondLeft++; + if (szSecondRight = strchr(szSecondLeft, '.')) + { + *szSecondRight = 0; + szSecondRight++; + if (szRightMost = strchr(szSecondRight, '.')) + { + *szRightMost = 0; + szRightMost++; + if (szRealHash = strchr(szRightMost, '.')) + { + bOldType = FALSE; + + *szRealHash = 0; + szRealHash++; + DWORD dwRemoteLeftMost = atoi(szLeftMost); + if (pLeftMost) *pLeftMost = dwRemoteLeftMost; + DWORD dwRemoteSecondLeft = atoi(szSecondLeft); + if (pSecondLeft) *pSecondLeft = dwRemoteSecondLeft; + DWORD dwRemoteSecondRight = atoi(szSecondRight); + if (pSecondRight) *pSecondRight = dwRemoteSecondRight; + DWORD dwRemoteRightMost = atoi(szRightMost); + if (pRightMost) *pRightMost = dwRemoteRightMost; + DWORD dwLocalLeftMost = 0; + DWORD dwLocalSecondLeft = 0; + DWORD dwLocalSecondRight = 0; + DWORD dwLocalRightMost = 0; + QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLocalLeftMost, &dwLocalSecondLeft, &dwLocalSecondRight, &dwLocalRightMost); + + int res = 0; + if (!res) + { + if (dwLocalLeftMost < dwRemoteLeftMost) + { + res = -1; + } + if (dwLocalLeftMost > dwRemoteLeftMost) + { + res = 1; + } + if (!res) + { + if (dwLocalSecondLeft < dwRemoteSecondLeft) + { + res = -1; + } + if (dwLocalSecondLeft > dwRemoteSecondLeft) + { + res = 1; + } + if (!res) + { + if (dwLocalSecondRight < dwRemoteSecondRight) + { + res = -1; + } + if (dwLocalSecondRight > dwRemoteSecondRight) + { + res = 1; + } + if (!res) + { + if (dwLocalRightMost < dwRemoteRightMost) + { + res = -1; + } + if (dwLocalRightMost > dwRemoteRightMost) + { + res = 1; + } + } + } + } + } + if (res == -1) + { + bIsUpdateAvailable = TRUE; + } + else if (res == 0) + { + *(szSecondLeft - 1) = '.'; + *(szSecondRight - 1) = '.'; + *(szRightMost - 1) = '.'; + *(szRealHash - 1) = '.'; + if (_stricmp(DOSMODE_OFFSET + hash, szCheckAgainst)) + { + bIsUpdateAvailable = TRUE; + } + } + } + } + } + } + } + } + } + + if (bOldType) + { + if (hash[0] == 0x4D && hash[1] == 0x5A && _stricmp(DOSMODE_OFFSET + hash, szCheckAgainst)) + { + bIsUpdateAvailable = TRUE; + } } } else { #ifdef UPDATES_VERBOSE_OUTPUT - printf("[Updates] Failed. Read %d bytes.\n"); + printf("[Updates] Failed. Read %d bytes.\n", dwRead); #endif if (lpFail) *lpFail = TRUE; } @@ -439,7 +553,9 @@ BOOL IsUpdateAvailableHelper( return bIsUpdateAvailable; } -BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail, WCHAR* wszInfoURL, DWORD dwInfoURLLen) +BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail, WCHAR* wszInfoURL, DWORD dwInfoURLLen, HMODULE hModule, + DWORD* pLeftMost, DWORD* pSecondLeft, DWORD* pSecondRight, DWORD* pRightMost +) { HKEY hKey = NULL; DWORD dwSize = 0; @@ -539,7 +655,9 @@ BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail, NULL, NULL, NULL, bUpdatePreferStaging, wszInfoURL, - dwInfoURLLen + dwInfoURLLen, + hModule, + pLeftMost, pSecondLeft, pSecondRight, pRightMost ); } @@ -547,7 +665,8 @@ BOOL UpdateProduct( LPCWSTR wszDataStore, __x_ABI_CWindows_CUI_CNotifications_CIToastNotifier* notifier, __x_ABI_CWindows_CUI_CNotifications_CIToastNotificationFactory* notifFactory, - __x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast + __x_ABI_CWindows_CUI_CNotifications_CIToastNotification** toast, + HMODULE hModule ) { HKEY hKey = NULL; @@ -635,7 +754,9 @@ BOOL UpdateProduct( notifFactory, toast, bUpdatePreferStaging, - NULL, 0 + NULL, 0, + hModule, + NULL, NULL, NULL, NULL ); } @@ -819,16 +940,17 @@ BOOL InstallUpdatesIfAvailable( CHAR hash[100]; ZeroMemory(hash, 100 * sizeof(CHAR)); - ComputeFileHash(dllName, hash, 100); + ComputeFileHash2(hModule, dllName, hash, 100); BOOL bFail = FALSE; - if (IsUpdateAvailable(_T(REGPATH), hash, &bFail, wszInfoURL, MAX_PATH)) + dwLeftMost = 0; dwSecondLeft = 0; dwSecondRight = 0; dwRightMost = 0; + if (IsUpdateAvailable(_T(REGPATH), hash, &bFail, wszInfoURL, MAX_PATH, hModule, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost)) { printf("[Updates] An update is available.\n"); if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_AUTO) || (dwOperation == UPDATES_OP_INSTALL)) { __x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL; - BOOL bOk = UpdateProduct(_T(REGPATH), notifier, notifFactory, toast); + BOOL bOk = UpdateProduct(_T(REGPATH), notifier, notifFactory, toast, hModule); if (!bOk) { if (dwOperation == UPDATES_OP_INSTALL) @@ -885,14 +1007,23 @@ BOOL InstallUpdatesIfAvailable( L"activationType=\"protocol\" launch=\"%s\" duration=\"long\">\r\n" L" \r\n" L" \r\n" - L" \r\n" + L" \r\n" L" \r\n" L" \r\n" L" \r\n" L" \r\n" L"