mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2024-11-28 01:10:55 +01:00
Option to receive pre-release versions via the updater
This commit is contained in:
parent
425efcbf67
commit
65aa7a732a
@ -13,11 +13,11 @@ Tested on build 22000.318.
|
||||
* Implemented support for Windows 7 battery flyout (#274)
|
||||
* Implemented `/extract` switch which unpacks the files from `ep_setup.exe` to disk (#396) (.1):
|
||||
* `ep_setup /extract` - extracts `ExplorerPatcher.IA-32.dll` and `ExplorerPatcher.amd64.dll` to current directory
|
||||
* `ep-setup /extract test` - extracts to `test` folder in current directory
|
||||
* `ep-setup /extract "C:\test with space"` - extracts to `C:\test with space` directory
|
||||
* `ep_setup /extract test` - extracts to `test` folder in current directory
|
||||
* `ep_setup /extract "C:\test with space"` - extracts to `C:\test with space` directory
|
||||
* Taskbar toolbar layouts are preserved when switching between Windows 10 and Windows 11 taskbars and in general (these will be reset when installing this update but should be subsequently remembered) (#395) (.2)
|
||||
* Implemented option to toggle taskbar auto-hide when double clicking the main taskbar (#389) (.3)
|
||||
* Running `ep-setup.exe` again while EP is already installed will now update the program to the latest version. To uninstall, as the previous behavior did, run `ep_setup.exe /uninstall` (.4)
|
||||
* Running `ep_setup.exe` again while EP is already installed will now update the program to the latest version. To uninstall, as the previous behavior did, run `ep_setup.exe /uninstall` (.4)
|
||||
* Implemented absolute height and width parameters for the Windows 10 switcher. These are especially useful for ultra wide monitors, in a scenario similar to the one described in [this post](https://github.com/valinet/ExplorerPatcher/discussions/110#discussioncomment-1673007) - to configure, set `MaxWidthAbs` and/or `MaxHeightAbs` DWORD values in `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ExplorerPatcher\sws` (#110) (.5)
|
||||
* Provides a simple mechanism for chainloading a custom library when the shell interface is created, from which you can execute your custom code (subject to change, see [this](https://github.com/valinet/ExplorerPatcher/discussions/408#discussioncomment-1674348) for more details) (#408) (.6)
|
||||
|
||||
@ -26,6 +26,7 @@ Tested on build 22000.318.
|
||||
|
||||
* Improved reliability when invoking Control Center (`Win`+`A`) when the taskbar icon is disabled (the icon should now not reappear anymore sometimes) (#242)
|
||||
* Small reorganization of some options in "Properties"
|
||||
* Option to receive pre-release versions, if available, when checking for updates (.9)
|
||||
|
||||
#### Fixes
|
||||
|
||||
|
@ -337,6 +337,8 @@
|
||||
;x 0 Prompt to install available updates
|
||||
;x 2 Do not check for updates
|
||||
"UpdatePolicy"=dword:00000001
|
||||
;b Receive pre-release versions, if available (not recommended)
|
||||
"UpdatePreferStaging"=dword:00000000
|
||||
;t ________________________
|
||||
;y Check for updates
|
||||
;;;EP_CHECK_FOR_UPDATES
|
||||
|
@ -55,13 +55,16 @@ void IsUpdateAvailableHelperCallback(
|
||||
}
|
||||
|
||||
BOOL IsUpdateAvailableHelper(
|
||||
char* url,
|
||||
char* szCheckAgainst,
|
||||
DWORD dwUpdateTimeout,
|
||||
char* url,
|
||||
char* szCheckAgainst,
|
||||
DWORD dwUpdateTimeout,
|
||||
BOOL* lpFail,
|
||||
__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,
|
||||
BOOL bUpdatePreferStaging,
|
||||
WCHAR* wszInfoURL,
|
||||
DWORD dwInfoURLLen
|
||||
)
|
||||
{
|
||||
BOOL bIsUpdateAvailable = FALSE;
|
||||
@ -73,17 +76,18 @@ BOOL IsUpdateAvailableHelper(
|
||||
return bIsUpdateAvailable;
|
||||
}
|
||||
|
||||
char* staging_buffer = NULL;
|
||||
HINTERNET hInternet = NULL;
|
||||
if (hInternet = InternetOpenA(
|
||||
UPDATES_USER_AGENT,
|
||||
INTERNET_OPEN_TYPE_PRECONFIG,
|
||||
NULL,
|
||||
NULL,
|
||||
0 //INTERNET_FLAG_ASYNC
|
||||
))
|
||||
|
||||
if (bUpdatePreferStaging)
|
||||
{
|
||||
//InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &dwUpdateTimeout, sizeof(DWORD));
|
||||
//if (InternetSetStatusCallbackA(hInternet, IsUpdateAvailableHelperCallback) != INTERNET_INVALID_STATUS_CALLBACK)
|
||||
if (hInternet = InternetOpenA(
|
||||
UPDATES_USER_AGENT,
|
||||
INTERNET_OPEN_TYPE_PRECONFIG,
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
))
|
||||
{
|
||||
HINTERNET hConnect = InternetOpenUrlA(
|
||||
hInternet,
|
||||
@ -99,201 +103,50 @@ BOOL IsUpdateAvailableHelper(
|
||||
INTERNET_FLAG_DONT_CACHE,
|
||||
¶ms
|
||||
);
|
||||
/*if (!hConnect && GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
if (WaitForSingleObject(params.hEvent, dwUpdateTimeout) == WAIT_OBJECT_0)
|
||||
{
|
||||
hConnect = params.hInternet;
|
||||
}
|
||||
}*/
|
||||
if (hConnect)
|
||||
{
|
||||
if (szCheckAgainst)
|
||||
DWORD dwSize = 5000;
|
||||
DWORD dwRead = dwSize;
|
||||
staging_buffer = calloc(dwSize, sizeof(char));
|
||||
if (staging_buffer)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
DWORD dwRead = 0;
|
||||
char hash[DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1];
|
||||
ZeroMemory(hash, DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1);
|
||||
if (bRet = InternetReadFile(
|
||||
hConnect,
|
||||
hash,
|
||||
DOSMODE_OFFSET + UPDATES_HASH_SIZE,
|
||||
staging_buffer,
|
||||
dwSize - 1,
|
||||
&dwRead
|
||||
) && dwRead == DOSMODE_OFFSET + UPDATES_HASH_SIZE)
|
||||
))
|
||||
{
|
||||
#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))
|
||||
char* a1 = strstr(staging_buffer, "\"browser_download_url\"");
|
||||
if (a1)
|
||||
{
|
||||
bIsUpdateAvailable = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Failed. Read %d bytes.\n");
|
||||
#endif
|
||||
if (lpFail) *lpFail = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR wszPath[MAX_PATH];
|
||||
ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR));
|
||||
SHGetFolderPathW(NULL, SPECIAL_FOLDER_LEGACY, NULL, SHGFP_TYPE_CURRENT, wszPath);
|
||||
wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH));
|
||||
BOOL bRet = CreateDirectoryW(wszPath, NULL);
|
||||
if (bRet || (!bRet && GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
wcscat_s(wszPath, MAX_PATH, L"\\Update for " _T(PRODUCT_NAME) L" from ");
|
||||
WCHAR wszURL[MAX_PATH];
|
||||
ZeroMemory(wszURL, MAX_PATH * sizeof(WCHAR));
|
||||
MultiByteToWideChar(
|
||||
CP_UTF8,
|
||||
MB_PRECOMPOSED,
|
||||
url,
|
||||
-1,
|
||||
wszURL,
|
||||
MAX_PATH
|
||||
);
|
||||
if (wszURL[95])
|
||||
{
|
||||
wszURL[94] = L'.';
|
||||
wszURL[95] = L'.';
|
||||
wszURL[96] = L'.';
|
||||
wszURL[97] = L'e';
|
||||
wszURL[98] = L'x';
|
||||
wszURL[99] = L'e';
|
||||
wszURL[100] = 0;
|
||||
}
|
||||
for (unsigned int i = 0; i < wszURL; ++i)
|
||||
{
|
||||
if (!wszURL[i])
|
||||
char* a2 = strchr(a1 + 24, '"');
|
||||
if (a2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (wszURL[i] == L'/')
|
||||
{
|
||||
wszURL[i] = L'\u2215';
|
||||
}
|
||||
else if (wszURL[i] == L':')
|
||||
{
|
||||
wszURL[i] = L'\ua789';
|
||||
}
|
||||
}
|
||||
wcscat_s(wszPath, MAX_PATH, wszURL);
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
wprintf(L"[Updates] Download path is \"%s\".\n", wszPath);
|
||||
#endif
|
||||
|
||||
BOOL bRet = DeleteFileW(wszPath);
|
||||
if (bRet || (!bRet && GetLastError() == ERROR_FILE_NOT_FOUND))
|
||||
{
|
||||
FILE* f = NULL;
|
||||
if (!_wfopen_s(
|
||||
&f,
|
||||
wszPath,
|
||||
L"wb"
|
||||
) && f)
|
||||
{
|
||||
BYTE* buffer = (BYTE*)malloc(UPDATES_BUFSIZ);
|
||||
if (buffer != NULL)
|
||||
a2[0] = 0;
|
||||
printf("[Updates] Prerelease update URL: \"%s\"\n", a1 + 24);
|
||||
url = a1 + 24;
|
||||
bUpdatePreferStaging = FALSE;
|
||||
if (wszInfoURL)
|
||||
{
|
||||
DWORD dwRead = 0;
|
||||
bRet = FALSE;
|
||||
while (bRet = InternetReadFile(
|
||||
hConnect,
|
||||
buffer,
|
||||
UPDATES_BUFSIZ,
|
||||
&dwRead
|
||||
))
|
||||
char* a3 = strstr(staging_buffer, "\"html_url\"");
|
||||
if (a3)
|
||||
{
|
||||
if (dwRead == 0)
|
||||
char* a4 = strchr(a3 + 12, '"');
|
||||
if (a4)
|
||||
{
|
||||
bIsUpdateAvailable = TRUE;
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Downloaded finished.\n");
|
||||
#endif
|
||||
break;
|
||||
a4[0] = 0;
|
||||
printf("[Updates] Release notes URL: \"%s\"\n", a3 + 12);
|
||||
MultiByteToWideChar(
|
||||
CP_UTF8,
|
||||
MB_PRECOMPOSED,
|
||||
a3 + 12,
|
||||
-1,
|
||||
wszInfoURL,
|
||||
dwInfoURLLen
|
||||
);
|
||||
}
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Downloaded %d bytes.\n", dwRead);
|
||||
#endif
|
||||
fwrite(
|
||||
buffer,
|
||||
sizeof(BYTE),
|
||||
dwRead,
|
||||
f
|
||||
);
|
||||
dwRead = 0;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
if (bIsUpdateAvailable)
|
||||
{
|
||||
bIsUpdateAvailable = FALSE;
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf(
|
||||
"[Updates] In order to install this update for the product \""
|
||||
PRODUCT_NAME
|
||||
"\", please allow the elevation request.\n"
|
||||
);
|
||||
#endif
|
||||
|
||||
if (*toast)
|
||||
{
|
||||
notifier->lpVtbl->Hide(notifier, *toast);
|
||||
(*toast)->lpVtbl->Release((*toast));
|
||||
(*toast) = NULL;
|
||||
}
|
||||
|
||||
SHELLEXECUTEINFO ShExecInfo = { 0 };
|
||||
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
ShExecInfo.hwnd = NULL;
|
||||
ShExecInfo.lpVerb = L"runas";
|
||||
ShExecInfo.lpFile = wszPath;
|
||||
ShExecInfo.lpParameters = L"/update_silent";
|
||||
ShExecInfo.lpDirectory = NULL;
|
||||
ShExecInfo.nShow = SW_SHOW;
|
||||
ShExecInfo.hInstApp = NULL;
|
||||
if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess)
|
||||
{
|
||||
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
|
||||
DWORD dwExitCode = 0;
|
||||
if (GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode) && !dwExitCode)
|
||||
{
|
||||
bIsUpdateAvailable = TRUE;
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update successful, File Explorer will probably restart momentarly.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(dwExitCode);
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update failed because the following error has occured: %d.\n", dwExitCode);
|
||||
#endif
|
||||
}
|
||||
CloseHandle(ShExecInfo.hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
if (dwError == ERROR_CANCELLED)
|
||||
{
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update failed because the elevation request was denied.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update failed because the following error has occured: %d.\n", GetLastError());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,20 +155,247 @@ BOOL IsUpdateAvailableHelper(
|
||||
}
|
||||
InternetCloseHandle(hConnect);
|
||||
}
|
||||
InternetCloseHandle(hInternet);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bUpdatePreferStaging && (hInternet = InternetOpenA(
|
||||
UPDATES_USER_AGENT,
|
||||
INTERNET_OPEN_TYPE_PRECONFIG,
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
)))
|
||||
{
|
||||
HINTERNET hConnect = InternetOpenUrlA(
|
||||
hInternet,
|
||||
url,
|
||||
NULL,
|
||||
0,
|
||||
INTERNET_FLAG_RAW_DATA |
|
||||
INTERNET_FLAG_RELOAD |
|
||||
INTERNET_FLAG_RESYNCHRONIZE |
|
||||
INTERNET_FLAG_NO_COOKIES |
|
||||
INTERNET_FLAG_NO_UI |
|
||||
INTERNET_FLAG_NO_CACHE_WRITE |
|
||||
INTERNET_FLAG_DONT_CACHE,
|
||||
¶ms
|
||||
);
|
||||
if (hConnect)
|
||||
{
|
||||
if (szCheckAgainst)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
DWORD dwRead = 0;
|
||||
char hash[DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1];
|
||||
ZeroMemory(hash, DOSMODE_OFFSET + UPDATES_HASH_SIZE + 1);
|
||||
if (bRet = InternetReadFile(
|
||||
hConnect,
|
||||
hash,
|
||||
DOSMODE_OFFSET + UPDATES_HASH_SIZE,
|
||||
&dwRead
|
||||
) && dwRead == DOSMODE_OFFSET + UPDATES_HASH_SIZE)
|
||||
{
|
||||
#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))
|
||||
{
|
||||
bIsUpdateAvailable = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Failed. Read %d bytes.\n");
|
||||
#endif
|
||||
if (lpFail) *lpFail = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpFail) *lpFail = TRUE;
|
||||
WCHAR wszPath[MAX_PATH];
|
||||
ZeroMemory(wszPath, MAX_PATH * sizeof(WCHAR));
|
||||
SHGetFolderPathW(NULL, SPECIAL_FOLDER_LEGACY, NULL, SHGFP_TYPE_CURRENT, wszPath);
|
||||
wcscat_s(wszPath, MAX_PATH, _T(APP_RELATIVE_PATH));
|
||||
BOOL bRet = CreateDirectoryW(wszPath, NULL);
|
||||
if (bRet || (!bRet && GetLastError() == ERROR_ALREADY_EXISTS))
|
||||
{
|
||||
wcscat_s(wszPath, MAX_PATH, L"\\Update for " _T(PRODUCT_NAME) L" from ");
|
||||
WCHAR wszURL[MAX_PATH];
|
||||
ZeroMemory(wszURL, MAX_PATH * sizeof(WCHAR));
|
||||
MultiByteToWideChar(
|
||||
CP_UTF8,
|
||||
MB_PRECOMPOSED,
|
||||
url,
|
||||
-1,
|
||||
wszURL,
|
||||
MAX_PATH
|
||||
);
|
||||
if (wszURL[97])
|
||||
{
|
||||
wszURL[96] = L'.';
|
||||
wszURL[97] = L'.';
|
||||
wszURL[98] = L'.';
|
||||
wszURL[99] = L'e';
|
||||
wszURL[100] = L'x';
|
||||
wszURL[101] = L'e';
|
||||
wszURL[102] = 0;
|
||||
}
|
||||
for (unsigned int i = 0; i < wszURL; ++i)
|
||||
{
|
||||
if (!wszURL[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (wszURL[i] == L'/')
|
||||
{
|
||||
wszURL[i] = L'\u2215';
|
||||
}
|
||||
else if (wszURL[i] == L':')
|
||||
{
|
||||
wszURL[i] = L'\ua789';
|
||||
}
|
||||
}
|
||||
wcscat_s(wszPath, MAX_PATH, wszURL);
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
wprintf(L"[Updates] Download path is \"%s\".\n", wszPath);
|
||||
#endif
|
||||
|
||||
BOOL bRet = DeleteFileW(wszPath);
|
||||
if (bRet || (!bRet && GetLastError() == ERROR_FILE_NOT_FOUND))
|
||||
{
|
||||
FILE* f = NULL;
|
||||
if (!_wfopen_s(
|
||||
&f,
|
||||
wszPath,
|
||||
L"wb"
|
||||
) && f)
|
||||
{
|
||||
BYTE* buffer = (BYTE*)malloc(UPDATES_BUFSIZ);
|
||||
if (buffer != NULL)
|
||||
{
|
||||
DWORD dwRead = 0;
|
||||
bRet = FALSE;
|
||||
while (bRet = InternetReadFile(
|
||||
hConnect,
|
||||
buffer,
|
||||
UPDATES_BUFSIZ,
|
||||
&dwRead
|
||||
))
|
||||
{
|
||||
if (dwRead == 0)
|
||||
{
|
||||
bIsUpdateAvailable = TRUE;
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Downloaded finished.\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Downloaded %d bytes.\n", dwRead);
|
||||
#endif
|
||||
fwrite(
|
||||
buffer,
|
||||
sizeof(BYTE),
|
||||
dwRead,
|
||||
f
|
||||
);
|
||||
dwRead = 0;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
if (bIsUpdateAvailable)
|
||||
{
|
||||
bIsUpdateAvailable = FALSE;
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf(
|
||||
"[Updates] In order to install this update for the product \""
|
||||
PRODUCT_NAME
|
||||
"\", please allow the elevation request.\n"
|
||||
);
|
||||
#endif
|
||||
|
||||
if (*toast)
|
||||
{
|
||||
notifier->lpVtbl->Hide(notifier, *toast);
|
||||
(*toast)->lpVtbl->Release((*toast));
|
||||
(*toast) = NULL;
|
||||
}
|
||||
|
||||
SHELLEXECUTEINFO ShExecInfo = { 0 };
|
||||
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
ShExecInfo.hwnd = NULL;
|
||||
ShExecInfo.lpVerb = L"runas";
|
||||
ShExecInfo.lpFile = wszPath;
|
||||
ShExecInfo.lpParameters = L"/update_silent";
|
||||
ShExecInfo.lpDirectory = NULL;
|
||||
ShExecInfo.nShow = SW_SHOW;
|
||||
ShExecInfo.hInstApp = NULL;
|
||||
if (ShellExecuteExW(&ShExecInfo) && ShExecInfo.hProcess)
|
||||
{
|
||||
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
|
||||
DWORD dwExitCode = 0;
|
||||
if (GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode) && !dwExitCode)
|
||||
{
|
||||
bIsUpdateAvailable = TRUE;
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update successful, File Explorer will probably restart momentarly.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(dwExitCode);
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update failed because the following error has occured: %d.\n", dwExitCode);
|
||||
#endif
|
||||
}
|
||||
CloseHandle(ShExecInfo.hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
if (dwError == ERROR_CANCELLED)
|
||||
{
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update failed because the elevation request was denied.\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Update failed because the following error has occured: %d.\n", GetLastError());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
InternetCloseHandle(hConnect);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpFail) *lpFail = TRUE;
|
||||
}
|
||||
InternetCloseHandle(hInternet);
|
||||
}
|
||||
|
||||
CloseHandle(params.hEvent);
|
||||
|
||||
if (staging_buffer)
|
||||
{
|
||||
free(staging_buffer);
|
||||
staging_buffer = NULL;
|
||||
}
|
||||
|
||||
return bIsUpdateAvailable;
|
||||
}
|
||||
|
||||
BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
|
||||
BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail, WCHAR* wszInfoURL, DWORD dwInfoURLLen)
|
||||
{
|
||||
HKEY hKey = NULL;
|
||||
DWORD dwSize = 0;
|
||||
@ -323,11 +403,12 @@ BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
|
||||
BOOL bIsPolicyMatch = FALSE;
|
||||
CHAR szUpdateURL[MAX_PATH];
|
||||
ZeroMemory(szUpdateURL, MAX_PATH * sizeof(CHAR));
|
||||
strcat_s(szUpdateURL, MAX_PATH, DEFAULT_UPDATE_URL);
|
||||
strcat_s(szUpdateURL, MAX_PATH, UPDATES_RELEASE_INFO_URL_STABLE);
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
printf("[Updates] Checking against hash \"%s\"\n", szCheckAgainst);
|
||||
#endif
|
||||
DWORD dwUpdateTimeout = UPDATES_DEFAULT_TIMEOUT;
|
||||
DWORD bUpdatePreferStaging = FALSE;
|
||||
|
||||
RegCreateKeyExW(
|
||||
HKEY_CURRENT_USER,
|
||||
@ -355,7 +436,20 @@ BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
|
||||
szUpdateURL,
|
||||
&dwSize
|
||||
);
|
||||
strcat_s(szUpdateURL, MAX_PATH, "/download/");
|
||||
strcat_s(szUpdateURL, MAX_PATH, SETUP_UTILITY_NAME);
|
||||
if (wszInfoURL)
|
||||
{
|
||||
dwSize = dwInfoURLLen;
|
||||
RegQueryValueExW(
|
||||
hKey,
|
||||
L"UpdateURL",
|
||||
0,
|
||||
NULL,
|
||||
wszInfoURL,
|
||||
&dwSize
|
||||
);
|
||||
}
|
||||
dwSize = sizeof(DWORD);
|
||||
RegQueryValueExA(
|
||||
hKey,
|
||||
@ -365,6 +459,29 @@ BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
|
||||
&dwUpdateTimeout,
|
||||
&dwSize
|
||||
);
|
||||
dwSize = sizeof(DWORD);
|
||||
RegQueryValueExA(
|
||||
hKey,
|
||||
"UpdatePreferStaging",
|
||||
0,
|
||||
NULL,
|
||||
&bUpdatePreferStaging,
|
||||
&dwSize
|
||||
);
|
||||
if (bUpdatePreferStaging)
|
||||
{
|
||||
ZeroMemory(szUpdateURL, MAX_PATH * sizeof(CHAR));
|
||||
strcat_s(szUpdateURL, MAX_PATH, UPDATES_RELEASE_INFO_URL_STAGING);
|
||||
dwSize = MAX_PATH;
|
||||
RegQueryValueExA(
|
||||
hKey,
|
||||
"UpdateURLStaging",
|
||||
0,
|
||||
NULL,
|
||||
szUpdateURL,
|
||||
&dwSize
|
||||
);
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
@ -375,7 +492,10 @@ BOOL IsUpdateAvailable(LPCWSTR wszDataStore, char* szCheckAgainst, BOOL* lpFail)
|
||||
szCheckAgainst,
|
||||
dwUpdateTimeout,
|
||||
lpFail,
|
||||
NULL, NULL, NULL
|
||||
NULL, NULL, NULL,
|
||||
bUpdatePreferStaging,
|
||||
wszInfoURL,
|
||||
dwInfoURLLen
|
||||
);
|
||||
}
|
||||
|
||||
@ -392,9 +512,10 @@ BOOL UpdateProduct(
|
||||
BOOL bIsPolicyMatch = FALSE;
|
||||
CHAR szUpdateURL[MAX_PATH];
|
||||
ZeroMemory(szUpdateURL, MAX_PATH * sizeof(CHAR));
|
||||
strcat_s(szUpdateURL, MAX_PATH, DEFAULT_UPDATE_URL);
|
||||
strcat_s(szUpdateURL, MAX_PATH, UPDATES_RELEASE_INFO_URL_STABLE);
|
||||
|
||||
DWORD dwUpdateTimeout = UPDATES_DEFAULT_TIMEOUT;
|
||||
DWORD bUpdatePreferStaging = FALSE;
|
||||
|
||||
RegCreateKeyExW(
|
||||
HKEY_CURRENT_USER,
|
||||
@ -422,6 +543,7 @@ BOOL UpdateProduct(
|
||||
szUpdateURL,
|
||||
&dwSize
|
||||
);
|
||||
strcat_s(szUpdateURL, MAX_PATH, "/download/");
|
||||
strcat_s(szUpdateURL, MAX_PATH, SETUP_UTILITY_NAME);
|
||||
dwSize = sizeof(DWORD);
|
||||
RegQueryValueExA(
|
||||
@ -432,6 +554,29 @@ BOOL UpdateProduct(
|
||||
&dwUpdateTimeout,
|
||||
&dwSize
|
||||
);
|
||||
dwSize = sizeof(DWORD);
|
||||
RegQueryValueExA(
|
||||
hKey,
|
||||
"UpdatePreferStaging",
|
||||
0,
|
||||
NULL,
|
||||
&bUpdatePreferStaging,
|
||||
&dwSize
|
||||
);
|
||||
if (bUpdatePreferStaging)
|
||||
{
|
||||
ZeroMemory(szUpdateURL, MAX_PATH * sizeof(CHAR));
|
||||
strcat_s(szUpdateURL, MAX_PATH, UPDATES_RELEASE_INFO_URL_STAGING);
|
||||
dwSize = MAX_PATH;
|
||||
RegQueryValueExA(
|
||||
hKey,
|
||||
"UpdateURLStaging",
|
||||
0,
|
||||
NULL,
|
||||
szUpdateURL,
|
||||
&dwSize
|
||||
);
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
#ifdef UPDATES_VERBOSE_OUTPUT
|
||||
@ -444,7 +589,9 @@ BOOL UpdateProduct(
|
||||
NULL,
|
||||
notifier,
|
||||
notifFactory,
|
||||
toast
|
||||
toast,
|
||||
bUpdatePreferStaging,
|
||||
NULL, 0
|
||||
);
|
||||
}
|
||||
|
||||
@ -459,6 +606,9 @@ BOOL InstallUpdatesIfAvailable(
|
||||
DWORD dwUpdatePolicy
|
||||
)
|
||||
{
|
||||
wchar_t wszInfoURL[MAX_PATH];
|
||||
ZeroMemory(wszInfoURL, MAX_PATH * sizeof(wchar_t));
|
||||
wcscat_s(wszInfoURL, MAX_PATH, _T(UPDATES_RELEASE_INFO_URL_STABLE));
|
||||
wchar_t buf[TOAST_BUFSIZ];
|
||||
DWORD dwLeftMost = 0;
|
||||
DWORD dwSecondLeft = 0;
|
||||
@ -471,7 +621,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
|
||||
const wchar_t text[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
|
||||
L"activationType=\"protocol\" launch=\"" _T(UPDATES_RELEASE_INFO_URL) L"\" duration=\"short\">\r\n"
|
||||
L" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[Update successful]]></text>\r\n"
|
||||
@ -568,7 +718,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
{
|
||||
const wchar_t text[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n"
|
||||
L"activationType=\"protocol\" launch=\"" _T(UPDATES_RELEASE_INFO_URL) L"\" duration=\"long\">\r\n"
|
||||
L" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[Downloading and installing updates]]></text>\r\n"
|
||||
@ -590,7 +740,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
{
|
||||
const wchar_t text[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n"
|
||||
L"activationType=\"protocol\" launch=\"" _T(UPDATES_RELEASE_INFO_URL) L"\" duration=\"long\">\r\n"
|
||||
L" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[Checking for updates]]></text>\r\n"
|
||||
@ -637,7 +787,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
ComputeFileHash(dllName, hash, 100);
|
||||
|
||||
BOOL bFail = FALSE;
|
||||
if (IsUpdateAvailable(_T(REGPATH), hash, &bFail))
|
||||
if (IsUpdateAvailable(_T(REGPATH), hash, &bFail, wszInfoURL, MAX_PATH))
|
||||
{
|
||||
printf("[Updates] An update is available.\n");
|
||||
if ((dwOperation == UPDATES_OP_DEFAULT && dwUpdatePolicy == UPDATE_POLICY_AUTO) || (dwOperation == UPDATES_OP_INSTALL))
|
||||
@ -650,7 +800,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
{
|
||||
const wchar_t text[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
|
||||
L"activationType=\"protocol\" launch=\"" _T(UPDATES_RELEASE_INFO_URL) L"\" duration=\"short\">\r\n"
|
||||
L" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[Update failed]]></text>\r\n"
|
||||
@ -691,7 +841,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
{
|
||||
const wchar_t text[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"long\">\r\n"
|
||||
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"
|
||||
@ -701,10 +851,11 @@ BOOL InstallUpdatesIfAvailable(
|
||||
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);
|
||||
__x_ABI_CWindows_CData_CXml_CDom_CIXmlDocument* inputXml = NULL;
|
||||
String2IXMLDocument(
|
||||
text,
|
||||
wcslen(text),
|
||||
buf,
|
||||
wcslen(buf),
|
||||
&inputXml,
|
||||
NULL
|
||||
);
|
||||
@ -741,7 +892,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
{
|
||||
const wchar_t text[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
|
||||
L"activationType=\"protocol\" launch=\"" _T(UPDATES_RELEASE_INFO_URL) L"\" duration=\"short\">\r\n"
|
||||
L" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[No updates are available]]></text>\r\n"
|
||||
@ -753,7 +904,7 @@ BOOL InstallUpdatesIfAvailable(
|
||||
L"</toast>\r\n";
|
||||
const wchar_t text2[] =
|
||||
L"<toast displayTimestamp=\"2021-08-29T00:00:00.000Z\" scenario=\"reminder\" "
|
||||
L"activationType=\"protocol\" launch=\"https://github.com/valinet/ExplorerPatcher/releases/latest\" duration=\"short\">\r\n"
|
||||
L"activationType=\"protocol\" launch=\"" _T(UPDATES_RELEASE_INFO_URL) L"\" duration=\"short\">\r\n"
|
||||
L" <visual>\r\n"
|
||||
L" <binding template=\"ToastGeneric\">\r\n"
|
||||
L" <text><![CDATA[Unable to check for updates]]></text>\r\n"
|
||||
|
@ -26,6 +26,10 @@ extern HMODULE hModule;
|
||||
#define UPDATES_BUFSIZ 10240
|
||||
#define UPDATES_DEFAULT_TIMEOUT 600
|
||||
|
||||
#define UPDATES_RELEASE_INFO_URL "https://github.com/valinet/ExplorerPatcher"
|
||||
#define UPDATES_RELEASE_INFO_URL_STABLE "https://github.com/valinet/ExplorerPatcher/releases/latest"
|
||||
#define UPDATES_RELEASE_INFO_URL_STAGING "https://api.github.com/repos/valinet/ExplorerPatcher/releases?per_page=1"
|
||||
|
||||
typedef struct IsUpdateAvailableParameters
|
||||
{
|
||||
HINTERNET hInternet;
|
||||
|
@ -28,7 +28,6 @@
|
||||
#define EP_CLSID "{D17F1E1A-5919-4427-8F89-A1A8503CA3EB}"
|
||||
#define DOSMODE_OFFSET 78
|
||||
#define SETUP_UTILITY_NAME "ep_setup.exe"
|
||||
#define DEFAULT_UPDATE_URL "https://github.com/valinet/ExplorerPatcher/releases/latest/download/"
|
||||
#define TOAST_BUFSIZ 1024
|
||||
#define SEH_REGPATH "Control Panel\\Quick Actions\\Control Center\\QuickActionsStateCapture\\ExplorerPatcher"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#define VER_MAJOR 22000
|
||||
#define VER_MINOR 318
|
||||
#define VER_BUILD_HI 38
|
||||
#define VER_BUILD_LO 8
|
||||
#define VER_BUILD_LO 9
|
||||
#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.318.38.8"
|
||||
#define VER_PRODUCT_STRING VALUE "ProductVersion", "22000.318.38.8"
|
||||
#define VER_FILE_STRING VALUE "FileVersion", "22000.318.38.9"
|
||||
#define VER_PRODUCT_STRING VALUE "ProductVersion", "22000.318.38.9"
|
||||
|
Loading…
Reference in New Issue
Block a user