mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2024-11-23 23:21:08 +01:00
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)
This commit is contained in:
parent
8d74ffbedb
commit
ca8fbe010f
@ -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
|
||||
|
@ -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" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[New version available]]></text>\r\n"
|
||||
L" <text><![CDATA[%s available]]></text>\r\n"
|
||||
L" <text><![CDATA[You can update by right clicking the taskbar, choosing \"Properties\", then \"Updates\". Click here to learn more about this update.]]></text>\r\n"
|
||||
L" <text placement=\"attribution\"><![CDATA[ExplorerPatcher]]></text>\r\n"
|
||||
L" </binding>\r\n"
|
||||
L" </visual>\r\n"
|
||||
L" <audio src=\"ms-winsoundevent:Notification.Default\" loop=\"false\" silent=\"false\"/>\r\n"
|
||||
L"</toast>\r\n";
|
||||
swprintf_s(buf, TOAST_BUFSIZ, text, wszInfoURL);
|
||||
if (!dwLeftMost)
|
||||
{
|
||||
swprintf_s(buf, TOAST_BUFSIZ, text, wszInfoURL, L"New version");
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR wszVersionInfo[100];
|
||||
swprintf_s(wszVersionInfo, 100, L"Version %d.%d.%d.%d is", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
|
||||
swprintf_s(buf, TOAST_BUFSIZ, text, wszInfoURL, wszVersionInfo);
|
||||
}
|
||||
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
|
||||
String2IXMLDocument(
|
||||
buf,
|
||||
|
@ -297,7 +297,7 @@ void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize)
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ComputeFileHash(LPCWSTR filename, LPCSTR hash, DWORD dwHash)
|
||||
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash)
|
||||
{
|
||||
DWORD dwStatus = 0;
|
||||
BOOL bResult = FALSE;
|
||||
@ -409,6 +409,33 @@ int ComputeFileHash(LPCWSTR filename, LPCSTR hash, DWORD dwHash)
|
||||
return dwStatus;
|
||||
}
|
||||
|
||||
int ComputeFileHash2(HMODULE hModule, LPCWSTR filename, LPSTR hash, DWORD dwHash)
|
||||
{
|
||||
if (dwHash < 33)
|
||||
{
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
}
|
||||
if (!hModule)
|
||||
{
|
||||
return ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
DWORD dwLeftMost = 0;
|
||||
DWORD dwSecondLeft = 0;
|
||||
DWORD dwSecondRight = 0;
|
||||
DWORD dwRightMost = 0;
|
||||
QueryVersionInfo(hModule, VS_VERSION_INFO, &dwLeftMost, &dwSecondLeft, &dwSecondRight, &dwRightMost);
|
||||
|
||||
sprintf_s(hash, 33, "%d.%d.%d.%d.", dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
|
||||
|
||||
char real_hash[33];
|
||||
ComputeFileHash(filename, real_hash, 33);
|
||||
strncpy_s(hash + strlen(hash), dwHash, real_hash, 32 - strlen(hash));
|
||||
hash[33] = 0;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
void LaunchPropertiesGUI(HMODULE hModule)
|
||||
{
|
||||
//CreateThread(0, 0, ZZGUI, 0, 0, 0);
|
||||
|
@ -241,7 +241,9 @@ static BOOL AppsShouldUseDarkMode() { return TRUE; }
|
||||
|
||||
void* ReadFromFile(wchar_t* wszFileName, DWORD* dwSize);
|
||||
|
||||
int ComputeFileHash(LPCWSTR filename, LPCSTR hash, DWORD dwHash);
|
||||
int ComputeFileHash(LPCWSTR filename, LPSTR hash, DWORD dwHash);
|
||||
|
||||
int ComputeFileHash2(HMODULE hModule, LPCWSTR filename, LPSTR hash, DWORD dwHash);
|
||||
|
||||
void LaunchPropertiesGUI(HMODULE hModule);
|
||||
|
||||
|
@ -14,10 +14,12 @@ int WINAPI wWinMain(
|
||||
GetModuleFileNameW(GetModuleHandle(NULL), wszPath, MAX_PATH);
|
||||
PathRemoveFileSpecW(wszPath);
|
||||
wcscat_s(wszPath, MAX_PATH, L"\\" _T(PRODUCT_NAME) L".amd64.dll");
|
||||
HMODULE hModule = LoadLibraryExW(wszPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
|
||||
CHAR hash[100];
|
||||
ZeroMemory(hash, 100);
|
||||
ComputeFileHash(wszPath, hash, 100);
|
||||
ComputeFileHash2(hModule, wszPath, hash, 100);
|
||||
FreeLibrary(hModule);
|
||||
|
||||
PathRemoveFileSpecW(wszPath);
|
||||
wcscat_s(wszPath, MAX_PATH, L"\\" _T(SETUP_UTILITY_NAME));
|
||||
|
@ -1,7 +1,7 @@
|
||||
#define VER_MAJOR 22000
|
||||
#define VER_MINOR 434
|
||||
#define VER_BUILD_HI 41
|
||||
#define VER_BUILD_LO 11
|
||||
#define VER_BUILD_LO 12
|
||||
#define VER_FLAGS VS_FF_PRERELEASE
|
||||
|
||||
|
||||
@ -12,5 +12,5 @@
|
||||
#define VER_STR(arg) #arg
|
||||
|
||||
// The String form of the version numbers
|
||||
#define VER_FILE_STRING VALUE "FileVersion", "22000.434.41.11"
|
||||
#define VER_PRODUCT_STRING VALUE "ProductVersion", "22000.434.41.11"
|
||||
#define VER_FILE_STRING VALUE "FileVersion", "22000.434.41.12"
|
||||
#define VER_PRODUCT_STRING VALUE "ProductVersion", "22000.434.41.12"
|
||||
|
Loading…
Reference in New Issue
Block a user