commit a9ccc52a47abcb55a1b39ca7aeb066dfcc861549 Author: Kathy Brade brade@pearlcrescent.com Date: Tue Nov 4 10:53:58 2014 -0500
Bug 13594: Windows updater depends on msvcr100.dll
On Windows, updater.exe failed to start if a copy of msvcr100.dll was not installed in the system directory. We now append to the PATH the directory that contains our copy of msvcr100.dll; that is, the Browser/ directory that contains firefox.exe. That same directory contains a copy of libssp-0.dll, which updater.exe also depends on; both DLL dependencies are now satisfied from the Browser/ directory. Previously, the libssp-0.dll dependency was being satisifed from the .../Browser/TorBrowser/Tor directory which Tor Launcher adds to the path (and typically the updater is run from within a browser session or after a restart during which the PATH is preserved). --- toolkit/xre/nsUpdateDriver.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp index f398aed..1188736 100644 --- a/toolkit/xre/nsUpdateDriver.cpp +++ b/toolkit/xre/nsUpdateDriver.cpp @@ -39,6 +39,7 @@ # include <windows.h> # include <shlwapi.h> # include "nsWindowsHelpers.h" +# include "prprf.h" # define getcwd(path, size) _getcwd(path, size) # define getpid() GetCurrentProcessId() #elif defined(XP_UNIX) @@ -133,6 +134,36 @@ GetCurrentWorkingDir(char *buf, size_t size) }
+#if defined(XP_WIN) +#define PATH_SEPARATOR ";" + +// In Tor Browser, updater.exe depends on some DLLs that are located in the +// app directory. To allow the updater to run when it has been copied into +// the update directory, we append the app directory to the PATH. +static nsresult +AdjustPathForUpdater(nsIFile *appDir) +{ + nsAutoCString appPath; + nsresult rv = appDir->GetNativePath(appPath); + NS_ENSURE_SUCCESS(rv, rv); + + char *s = nullptr; + char *pathValue = PR_GetEnv("PATH"); + if ((nullptr == pathValue) || ('\0' == *pathValue)) { + s = PR_smprintf("PATH=%s", appPath.get()); + } else { + s = PR_smprintf("PATH=%s" PATH_SEPARATOR "%s", pathValue, appPath.get()); + } + + // We intentionally leak the value that is passed into PR_SetEnv() because + // the environment will hold a pointer to it. + if ((nullptr == s) || (PR_SUCCESS != PR_SetEnv(s))) + return NS_ERROR_FAILURE; + + return NS_OK; +} +#endif + #ifdef DEBUG static void dump_argv(const char *aPrefix, char **argv, int argc) @@ -592,6 +623,13 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile, PR_SetEnv("MOZ_SAFE_MODE_RESTART=1"); }
+#if defined(XP_WIN) + nsresult rv2 = AdjustPathForUpdater(appDir); + if (NS_FAILED(rv2)) { + LOG(("SwitchToUpdatedApp -- AdjustPathForUpdater failed (0x%x)\n", rv2)); + } +#endif + LOG(("spawning updater process for replacing [%s]\n", updaterPath.get()));
#if defined(USE_EXECV) @@ -881,6 +919,14 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile, if (isOSUpdate) { PR_SetEnv("MOZ_OS_UPDATE=1"); } + +#if defined(XP_WIN) + nsresult rv2 = AdjustPathForUpdater(appDir); + if (NS_FAILED(rv2)) { + LOG(("ApplyUpdate -- AdjustPathForUpdater failed (0x%x)\n", rv2)); + } +#endif + #if defined(MOZ_WIDGET_GONK) // We want the updater to be CPU friendly and not subject to being killed by // the low memory killer, so we pass in some preferences to allow it to