Bug 711505 - Callback application should be locked when doing updates from the service. r=rstrong.
authorBrian R. Bondy <netzen@gmail.com>
Wed, 04 Jan 2012 23:19:16 -0500
changeset 85003 4b4c207842019b459af177a203fb3ca1094d74f6
parent 85002 d4043fc86503bac5192a9afb740d0f3ffd93d919
child 85004 8401a8217e98642dd40eac461d410cfa9e94ee5e
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrstrong
bugs711505
milestone12.0a1
Bug 711505 - Callback application should be locked when doing updates from the service. r=rstrong.
toolkit/components/maintenanceservice/workmonitor.cpp
toolkit/mozapps/update/common/updatehelper.cpp
toolkit/mozapps/update/updater/updater.cpp
--- a/toolkit/components/maintenanceservice/workmonitor.cpp
+++ b/toolkit/components/maintenanceservice/workmonitor.cpp
@@ -90,17 +90,17 @@ StartUpdateProcess(LPCWSTR updaterPath,
                    LPWSTR *argvTmp,
                    BOOL &processStarted)
 {
   STARTUPINFO si = {0};
   si.cb = sizeof(STARTUPINFO);
   si.lpDesktop = L"winsta0\\Default";
   PROCESS_INFORMATION pi = {0};
 
-  LOG(("Starting update process as the service in session 0."));
+  LOG(("Starting update process as the service in session 0.\n"));
 
   // The updater command line is of the form:
   // updater.exe update-dir apply [wait-pid [callback-dir callback-path args]]
   LPWSTR cmdLine = MakeCommandLine(argcTmp, argvTmp);
 
   // If we're about to start the update process from session 0,
   // then we should not show a GUI.  This only really needs to be done
   // on Vista and higher, but it's better to keep everything consistent
--- a/toolkit/mozapps/update/common/updatehelper.cpp
+++ b/toolkit/mozapps/update/common/updatehelper.cpp
@@ -417,18 +417,20 @@ WinLaunchServiceCommand(LPCWSTR exePath,
   DWORD commandID = 1, commandIDWrote;
   BOOL result = WriteFile(updateMetaFile, &commandID, 
                           sizeof(DWORD), 
                           &commandIDWrote, NULL);
 
   // Write out the command line arguments that are passed to updater.exe
   // updater.exe's command line arguments look like this normally:
   // updater.exe update-dir apply [wait-pid [callback-dir callback-path args]]
-  // We want everything except the callback application and its arguments.
-  LPWSTR commandLineBuffer = MakeCommandLine(min(argc, 4), argv);
+  // We pass everything including the callback application and its arguments.
+  // The only reason we pass the callback info though is to lock the exe so it
+  // is not launched during update.
+  LPWSTR commandLineBuffer = MakeCommandLine(argc, argv);
   if (!commandLineBuffer) {
     return FALSE;
   }
 
   WCHAR appBuffer[MAX_PATH + 1];
   ZeroMemory(appBuffer, sizeof(appBuffer));
   wcscpy(appBuffer, exePath);
   DWORD appBufferWrote;
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -1399,17 +1399,22 @@ LaunchCallbackApp(const NS_tchar *workin
     LOG(("Warning: chdir failed\n"));
   }
 
 #if defined(USE_EXECV)
   execv(argv[0], argv);
 #elif defined(XP_MACOSX)
   LaunchChild(argc, argv);
 #elif defined(XP_WIN)
-  WinLaunchChild(argv[0], argc, argv, NULL);
+  // Do not allow the callback to run when running an update through the
+  // service as session 0.  The unelevated updater.exe will do the launching.
+  WCHAR *usingService = _wgetenv(L"MOZ_USING_SERVICE");
+  if (!usingService) {
+    WinLaunchChild(argv[0], argc, argv, NULL);
+  }
 #else
 # warning "Need implementaton of LaunchCallbackApp"
 #endif
 }
 
 static void
 WriteStatusFile(int status)
 {
@@ -1667,21 +1672,22 @@ int NS_main(int argc, NS_tchar **argv)
   }
 
   // The callback is the remaining arguments starting at callbackIndex.
   // The argument specified by callbackIndex is the callback executable and the
   // argument prior to callbackIndex is the working directory.
   const int callbackIndex = 5;
 
 #if defined(XP_WIN)
+  WCHAR *usingService = _wgetenv(L"MOZ_USING_SERVICE");
   // Launch a second instance of the updater with the runas verb on Windows
   // when write access is denied to the installation directory.
   HANDLE updateLockFileHandle;
   NS_tchar elevatedLockFilePath[MAXPATHLEN];
-  if (argc > callbackIndex) {
+  if (argc > callbackIndex && !usingService) {
     NS_tchar updateLockFilePath[MAXPATHLEN];
     NS_tsnprintf(updateLockFilePath,
                  sizeof(updateLockFilePath)/sizeof(updateLockFilePath[0]),
                  NS_T("%s.update_in_progress.lock"), argv[callbackIndex]);
 
     // The update_in_progress.lock file should only exist during an update. In
     // case it exists attempt to remove it and exit if that fails to prevent
     // simultaneous updates occurring.
@@ -2004,17 +2010,16 @@ int NS_main(int argc, NS_tchar **argv)
     if (gSucceeded) {
       // The service update will only be executed if it is already installed.
       // For first time installs of the service, the install will happen from
       // the PostUpdate process. We do the service update process here 
       // because it's possible we are updating with updater.exe without the 
       // service if the service failed to apply the update. We want to update
       // the service to a newer version in that case. If we are not running
       // through the service, then MOZ_USING_SERVICE will not exist.
-      WCHAR *usingService = _wgetenv(L"MOZ_USING_SERVICE");
       if (!usingService) {
         if (!LaunchWinPostProcess(argv[2], gSourcePath, false, NULL)) {
           LOG(("NS_main: The post update process could not be launched.\n"));
         }
         StartServiceUpdate(argc, argv);
       }
     }
     EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 0);