From 983c2c086979679a991d663c50d585e7223cf5f1 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 30 May 2017 21:26:53 +0300 Subject: [PATCH] Support non-standard binary names in autoupdater. On Linux and Windows support non-standard application binary name. --- Telegram/SourceFiles/_other/updater.cpp | 44 +++++++++++++------ Telegram/SourceFiles/_other/updater_linux.cpp | 43 +++++++++++------- .../platform/linux/specific_linux.cpp | 23 +++++++++- .../SourceFiles/platform/win/specific_win.cpp | 2 +- 4 files changed, 80 insertions(+), 32 deletions(-) diff --git a/Telegram/SourceFiles/_other/updater.cpp b/Telegram/SourceFiles/_other/updater.cpp index df626b730c..dbcce31379 100644 --- a/Telegram/SourceFiles/_other/updater.cpp +++ b/Telegram/SourceFiles/_other/updater.cpp @@ -22,7 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org bool _debug = false; -wstring exeName, exeDir, updateTo; +wstring updaterName, updaterDir, updateTo, exeName; bool equal(const wstring &a, const wstring &b) { return !_wcsicmp(a.c_str(), b.c_str()); @@ -203,11 +203,16 @@ bool update() { } } else { wstring tofname = updateTo + fname.substr(updDir.size() + 1); - if (equal(tofname, exeName)) { // bad update - has Updater.exe - delete all dir - writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + exeName + L"'"); + if (equal(tofname, updaterName)) { // bad update - has Updater.exe - delete all dir + writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + updaterName + L"'"); delFolder(); return false; - } else if (equal(fname, readyFilePath)) { + } else if (equal(tofname, updateTo + L"Telegram.exe") && exeName != L"Telegram.exe") { + wstring fullBinaryPath = updateTo + exeName; + writeLog(L"Target binary found: '" + tofname + L"', changing to '" + fullBinaryPath + L"'"); + tofname = fullBinaryPath; + } + if (equal(fname, readyFilePath)) { writeLog(L"Skipped ready file '" + fname + L"'"); } else { from.push_back(fname); @@ -362,20 +367,31 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara updateTo[i] = L'\\'; } } + } else if (equal(args[i], L"-exename") && ++i < argsCount) { + exeName = args[i]; + for (int i = 0, l = exeName.size(); i < l; ++i) { + if (exeName[i] == L'/' || exeName[i] == L'\\') { + exeName = L"Telegram.exe"; + break; + } + } } } + if (exeName.empty()) { + exeName = L"Telegram.exe"; + } if (needupdate) writeLog(L"Need to update!"); if (autostart) writeLog(L"From autostart!"); if (writeprotected) writeLog(L"Write Protected folder!"); - exeName = args[0]; - writeLog(L"Exe name is: " + exeName); - if (exeName.size() > 11) { - if (equal(exeName.substr(exeName.size() - 11), L"Updater.exe")) { - exeDir = exeName.substr(0, exeName.size() - 11); - writeLog(L"Exe dir is: " + exeDir); + updaterName = args[0]; + writeLog(L"Updater name is: " + updaterName); + if (updaterName.size() > 11) { + if (equal(updaterName.substr(updaterName.size() - 11), L"Updater.exe")) { + updaterDir = updaterName.substr(0, updaterName.size() - 11); + writeLog(L"Updater dir is: " + updaterDir); if (!writeprotected) { - updateTo = exeDir; + updateTo = updaterDir; } writeLog(L"Update to: " + updateTo); if (needupdate && update()) { @@ -416,7 +432,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara if (SUCCEEDED(hres)) { IPersistFile* ppf; - wstring exe = updateTo + L"Telegram.exe", dir = updateTo; + wstring exe = updateTo + exeName, dir = updateTo; psl->SetArguments((targs.size() ? targs.substr(1) : targs).c_str()); psl->SetPath(exe.c_str()); psl->SetWorkingDirectory(dir.c_str()); @@ -453,10 +469,10 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara } } if (!executed) { - ShellExecute(0, 0, (updateTo + L"Telegram.exe").c_str(), (L"-noupdate" + targs).c_str(), 0, SW_SHOWNORMAL); + ShellExecute(0, 0, (updateTo + exeName).c_str(), (L"-noupdate" + targs).c_str(), 0, SW_SHOWNORMAL); } - writeLog(L"Executed Telegram.exe, closing log and quitting.."); + writeLog(L"Executed '" + exeName + L"', closing log and quitting.."); closeLog(); return 0; diff --git a/Telegram/SourceFiles/_other/updater_linux.cpp b/Telegram/SourceFiles/_other/updater_linux.cpp index 80ce976c1d..989e853df2 100644 --- a/Telegram/SourceFiles/_other/updater_linux.cpp +++ b/Telegram/SourceFiles/_other/updater_linux.cpp @@ -52,7 +52,10 @@ bool do_mkdir(const char *path) { // from http://stackoverflow.com/questions/675 } bool _debug = false; -string exeName, exeDir, workDir; +string updaterDir; +string updaterName; +string workDir; +string exeName; FILE *_logFile = 0; void openLog() { @@ -240,7 +243,7 @@ bool update() { string dir = dirs.front(); dirs.pop_front(); - string toDir = exeDir; + string toDir = updaterDir; if (dir.size() > updDir.size() + 1) { toDir += (dir.substr(updDir.size() + 1) + '/'); forcedirs.push_back(toDir); @@ -266,12 +269,16 @@ bool update() { dirs.push_back(fname); writeLog("Added dir '%s' in update tree..", fname.c_str()); } else { - string tofname = exeDir + fname.substr(updDir.size() + 1); - if (equal(tofname, exeName)) { // bad update - has Updater - delete all dir - writeLog("Error: bad update, has Updater! '%s' equal '%s'", tofname.c_str(), exeName.c_str()); + string tofname = updaterDir + fname.substr(updDir.size() + 1); + if (equal(tofname, updaterName)) { // bad update - has Updater - delete all dir + writeLog("Error: bad update, has Updater! '%s' equal '%s'", tofname.c_str(), updaterName.c_str()); delFolder(); return false; - } + } else if (equal(tofname, updaterDir + "Telegram") && exeName != "Telegram") { + string fullBinaryPath = updaterDir + exeName; + writeLog("Target binary found: '%s', changing to '%s'", tofname.c_str(), fullBinaryPath.c_str()); + tofname = fullBinaryPath; + } if (fname == readyFilePath) { writeLog("Skipped ready file '%s'", fname.c_str()); } else { @@ -344,9 +351,14 @@ int main(int argc, char *argv[]) { workDir = argv[i]; } else if (equal(argv[i], "-crashreport") && ++i < argc) { crashreport = argv[i]; + } else if (equal(argv[i], "-exename") && ++i < argc) { + exeName = argv[i]; } } - openLog(); + if (exeName.empty() || exeName.find('/') != string::npos) { + exeName = "Telegram"; + } + openLog(); writeLog("Updater started.."); for (int i = 0; i < argc; ++i) { @@ -355,12 +367,12 @@ int main(int argc, char *argv[]) { if (needupdate) writeLog("Need to update!"); if (autostart) writeLog("From autostart!"); - exeName = argv[0]; - writeLog("Exe name is: %s", exeName.c_str()); - if (exeName.size() >= 7) { - if (equal(exeName.substr(exeName.size() - 7), "Updater")) { - exeDir = exeName.substr(0, exeName.size() - 7); - writeLog("Exe dir is: %s", exeDir.c_str()); + updaterName = argv[0]; + writeLog("Updater binary name is: %s", updaterName.c_str()); + if (updaterName.size() >= 7) { + if (equal(updaterName.substr(updaterName.size() - 7), "Updater")) { + updaterDir = updaterName.substr(0, updaterName.size() - 7); + writeLog("Updater binary dir is: %s", updaterDir.c_str()); if (needupdate) { if (workDir.empty()) { // old app launched, update prepared in tupdates/ready (not in tupdates/temp) writeLog("No workdir, trying to figure it out"); @@ -378,7 +390,7 @@ int main(int argc, char *argv[]) { } } if (workDir.empty()) { - workDir = exeDir; + workDir = updaterDir; struct stat statbuf; writeLog("Trying to use current as workDir, getting stat() for tupdates/ready"); @@ -405,7 +417,8 @@ int main(int argc, char *argv[]) { static const int MaxLen = 65536, MaxArgsCount = 128; char path[MaxLen] = {0}; - strcpy(path, (exeDir + "Telegram").c_str()); + string fullBinaryPath = updaterDir + exeName; + strcpy(path, fullBinaryPath.c_str()); char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_startintray[] = "-startintray", p_testmode[] = "-testmode"; int argIndex = 0; diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 41531aacb3..5d4bf61794 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -541,8 +541,21 @@ bool _execUpdater(bool update = true, const QString &crashreport = QString()) { QByteArray data(QFile::encodeName(cExeDir() + (update ? "Updater" : gExeName))); memcpy(path, data.constData(), data.size()); - char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_path[] = "-workpath", p_startintray[] = "-startintray", p_testmode[] = "-testmode", p_crashreport[] = "-crashreport"; - char p_datafile[MaxLen] = {0}, p_pathbuf[MaxLen] = {0}, p_crashreportbuf[MaxLen] = {0}; + char *args[MaxArgsCount] = { 0 }; + char p_noupdate[] = "-noupdate"; + char p_autostart[] = "-autostart"; + char p_debug[] = "-debug"; + char p_tosettings[] = "-tosettings"; + char p_key[] = "-key"; + char p_datafile[MaxLen] = { 0 }; + char p_path[] = "-workpath"; + char p_pathbuf[MaxLen] = { 0 }; + char p_startintray[] = "-startintray"; + char p_testmode[] = "-testmode"; + char p_crashreport[] = "-crashreport"; + char p_crashreportbuf[MaxLen] = { 0 }; + char p_exe[] = "-exename"; + char p_exebuf[MaxLen] = { 0 }; int argIndex = 0; args[argIndex++] = path; if (!update) { @@ -575,6 +588,12 @@ bool _execUpdater(bool update = true, const QString &crashreport = QString()) { args[argIndex++] = p_crashreportbuf; } } + QByteArray exef = QFile::encodeName(cExeName()); + if (exef.size() > 0 && exef.size() < MaxLen) { + memcpy(p_exebuf, exef.constData(), exef.size()); + args[argIndex++] = p_exe; + args[argIndex++] = p_exebuf; + } Logs::closeMain(); SignalHandlers::finish(); diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp index 8115b3fbdb..d738c80ae4 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.cpp +++ b/Telegram/SourceFiles/platform/win/specific_win.cpp @@ -645,7 +645,7 @@ void psNewVersion() { } void psExecUpdater() { - QString targs = qsl("-update"); + QString targs = qsl("-update -exename \"") + cExeName() + '"'; if (cLaunchMode() == LaunchModeAutoStart) targs += qsl(" -autostart"); if (cDebug()) targs += qsl(" -debug"); if (cStartInTray()) targs += qsl(" -startintray");