diff --git a/src/Setup/Setup.vcxproj b/src/Setup/Setup.vcxproj
index 800bf2121..3d4f5e20c 100644
--- a/src/Setup/Setup.vcxproj
+++ b/src/Setup/Setup.vcxproj
@@ -83,7 +83,7 @@
Windows
true
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;secur32.lib
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;secur32.lib;version.lib
compat.manifest
@@ -109,7 +109,7 @@
true
true
AsInvoker
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;secur32.lib
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;secur32.lib;version.lib
compat.manifest
@@ -137,7 +137,7 @@
true
true
AsInvoker
- kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;secur32.lib
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;urlmon.lib;secur32.lib;version.lib
compat.manifest
diff --git a/src/Setup/UpdateRunner.cpp b/src/Setup/UpdateRunner.cpp
index 50d3441a2..5967433db 100644
--- a/src/Setup/UpdateRunner.cpp
+++ b/src/Setup/UpdateRunner.cpp
@@ -3,6 +3,11 @@
#include "Resource.h"
#include "UpdateRunner.h"
#include
+#include
+#include
+#include
+#include
+#include
void CUpdateRunner::DisplayErrorMessage(CString& errorMessage, wchar_t* logFile)
{
@@ -15,7 +20,8 @@ void CUpdateRunner::DisplayErrorMessage(CString& errorMessage, wchar_t* logFile)
// TODO: Something about contacting support?
if (logFile == NULL) {
dlg.SetButtons(&buttons[1], 1, 1);
- } else {
+ }
+ else {
dlg.SetButtons(buttons, 2, 1);
}
@@ -138,13 +144,13 @@ bool CUpdateRunner::DirectoryExists(wchar_t* szPath)
bool CUpdateRunner::DirectoryIsWritable(wchar_t * szPath)
{
- wchar_t szTempFileName[MAX_PATH];
- UINT uRetVal = GetTempFileNameW(szPath, L"Squirrel", 0, szTempFileName);
- if (uRetVal == 0) {
- return false;
- }
- DeleteFile(szTempFileName);
- return true;
+ wchar_t szTempFileName[MAX_PATH];
+ UINT uRetVal = GetTempFileNameW(szPath, L"Squirrel", 0, szTempFileName);
+ if (uRetVal == 0) {
+ return false;
+ }
+ DeleteFile(szTempFileName);
+ return true;
}
int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallbackDir)
@@ -190,8 +196,10 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
gotADir:
+ CheckSpecialBuild(targetDir, lpCommandLine);
+
wcscat_s(targetDir, _countof(targetDir), L"\\SquirrelTemp");
-
+
if (!CreateDirectory(targetDir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
wchar_t err[4096];
_swprintf_c(err, _countof(err), L"Unable to write to %s - IT policies may be restricting access to this folder", targetDir);
@@ -275,7 +283,7 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
if (dwExitCode != 0) {
DisplayErrorMessage(CString(
- L"There was an error while installing the application. "
+ L"There was an error while installing the application. "
L"Check the setup log for more information and contact the author."), logFile);
}
@@ -285,7 +293,7 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
- return (int) dwExitCode;
+ return (int)dwExitCode;
failedExtract:
if (!useFallbackDir) {
@@ -294,5 +302,76 @@ int CUpdateRunner::ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallback
}
DisplayErrorMessage(CString(L"Failed to extract installer"), NULL);
- return (int) dwExitCode;
+ return (int)dwExitCode;
+}
+
+void CUpdateRunner::CheckSpecialBuild(wchar_t* targetDir, wchar_t* commandLine) {
+ CString specialBuild = CString();
+
+ std::wstringstream iss(commandLine);
+ std::vector v;
+ std::wstring s;
+
+ while (iss >> std::quoted(s)) {
+ v.push_back(s);
+ }
+
+ auto index = std::find(v.begin(), v.end(), std::wstring(L"--special-build"));
+ if (index != v.end()) {
+ index = std::next(index, 1);
+ if (index != v.end()) {
+ specialBuild = index->c_str();
+ }
+ }
+
+ if (specialBuild.IsEmpty()) {
+ HMODULE hLib = GetModuleHandle(NULL);
+
+ HRSRC hVersion = FindResource(hLib,
+ MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
+ if (hVersion != NULL)
+ {
+ HGLOBAL hGlobal = LoadResource(hLib, hVersion);
+ if (hGlobal != NULL)
+ {
+ LPVOID versionInfo = LockResource(hGlobal);
+ if (versionInfo != NULL)
+ {
+ DWORD vLen, langD;
+ BOOL retVal;
+
+ LPVOID retbuf = NULL;
+
+ static wchar_t fileEntry[256];
+
+ wsprintf(fileEntry, L"\\VarFileInfo\\Translation");
+ retVal = VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen);
+ if (retVal && vLen == 4)
+ {
+ memcpy(&langD, retbuf, 4);
+ wsprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%s",
+ (langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
+ (langD & 0xff0000) >> 16, L"SpecialBuild");
+ }
+ else
+ wsprintf(fileEntry, L"\\StringFileInfo\\%04X04B0\\%s",
+ GetUserDefaultLangID(), L"SpecialBuild");
+
+ if (VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen)) {
+ if (vLen > 0)
+ {
+ specialBuild = CString((wchar_t*)retbuf);
+ }
+ }
+ }
+ }
+
+ UnlockResource(hGlobal);
+ FreeResource(hGlobal);
+ }
+ }
+
+ if (!specialBuild.IsEmpty()) {
+ SetEnvironmentVariable(L"SQUIRREL_SPECIAL_BUILD", specialBuild);
+ }
}
\ No newline at end of file
diff --git a/src/Setup/UpdateRunner.h b/src/Setup/UpdateRunner.h
index 28129c6f7..3eec2099b 100644
--- a/src/Setup/UpdateRunner.h
+++ b/src/Setup/UpdateRunner.h
@@ -1,7 +1,6 @@
#pragma once
class CUpdateRunner
{
-
public:
static void DisplayErrorMessage(CString& errorMessage, wchar_t* logFile);
static HRESULT AreWeUACElevated();
@@ -9,4 +8,7 @@ class CUpdateRunner
static bool DirectoryExists(wchar_t* szPath);
static bool DirectoryIsWritable(wchar_t* szPath);
static int ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallbackDir);
+
+protected:
+ static void CheckSpecialBuild(wchar_t* targetDir, wchar_t* commandLine);
};