Bug 961676. r=rstrong. a=abillings
authorBrian R. Bondy <netzen@gmail.com>
Mon, 31 Mar 2014 11:40:14 -0400
changeset 192430 bfd99c9d0c474b0a40ad2d983a3924d7a6ec598b
parent 192429 0d716cd5c4dda00ebd81597a3473f20e52a5d380
child 192431 4f5c6684b319a507dcda24703601c8a5cd2459ac
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrstrong, abillings
bugs961676
milestone30.0a2
Bug 961676. r=rstrong. a=abillings
toolkit/mozapps/update/common/updatehelper.cpp
--- a/toolkit/mozapps/update/common/updatehelper.cpp
+++ b/toolkit/mozapps/update/common/updatehelper.cpp
@@ -19,16 +19,17 @@
 #include <tlhelp32.h>
 #ifndef ONLY_SERVICE_LAUNCHING
 
 #include <stdio.h>
 #include "shlobj.h"
 #include "updatehelper.h"
 #include "uachelper.h"
 #include "pathhash.h"
+#include "mozilla/Scoped.h"
 
 // Needed for PathAppendW
 #include <shlwapi.h>
 #pragma comment(lib, "shlwapi.lib")
 
 WCHAR* MakeCommandLine(int argc, WCHAR **argv);
 BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra);
 
@@ -212,36 +213,76 @@ StartServiceUpdate(LPCWSTR installDir)
 
   // Open the service
   SC_HANDLE svc = OpenServiceW(manager, SVC_NAME,
                                SERVICE_ALL_ACCESS);
   if (!svc) {
     CloseServiceHandle(manager);
     return FALSE;
   }
-  CloseServiceHandle(svc);
-  CloseServiceHandle(manager);
 
   // If we reach here, then the service is installed, so
   // proceed with upgrading it.
 
+  CloseServiceHandle(manager);
+
+  // The service exists and we opened it, get the config bytes needed
+  DWORD bytesNeeded;
+  if (!QueryServiceConfigW(svc, nullptr, 0, &bytesNeeded) &&
+      GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+    CloseServiceHandle(svc);
+    return FALSE;
+  }
+
+  // Get the service config information, in particular we want the binary
+  // path of the service.
+  mozilla::ScopedDeleteArray<char> serviceConfigBuffer(new char[bytesNeeded]);
+  if (!QueryServiceConfigW(svc,
+      reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()),
+      bytesNeeded, &bytesNeeded)) {
+    CloseServiceHandle(svc);
+    return FALSE;
+  }
+
+  CloseServiceHandle(svc);
+
+  QUERY_SERVICE_CONFIGW &serviceConfig =
+    *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get());
+
+  PathUnquoteSpacesW(serviceConfig.lpBinaryPathName);
+
+  // Obtain the temp path of the maintenance service binary
+  WCHAR tmpService[MAX_PATH + 1] = { L'\0' };
+  if (!PathGetSiblingFilePath(tmpService, serviceConfig.lpBinaryPathName,
+                              L"maintenanceservice_tmp.exe")) {
+    return FALSE;
+  }
+
+  // Get the new maintenance service path from the install dir
+  WCHAR newMaintServicePath[MAX_PATH + 1] = { L'\0' };
+  wcsncpy(newMaintServicePath, installDir, MAX_PATH);
+  PathAppendSafe(newMaintServicePath,
+                 L"maintenanceservice.exe");
+
+  // Copy the temp file in alongside the maintenace service.
+  // This is a requirement for maintenance service upgrades.
+  if (!CopyFileW(newMaintServicePath, tmpService, FALSE)) {
+    return FALSE;
+  }
+
+  // Start the upgrade comparison process
   STARTUPINFOW si = {0};
   si.cb = sizeof(STARTUPINFOW);
   // No particular desktop because no UI
   si.lpDesktop = L"";
   PROCESS_INFORMATION pi = {0};
-
-  WCHAR maintserviceInstallerPath[MAX_PATH + 1] = { L'\0' };
-  wcsncpy(maintserviceInstallerPath, installDir, MAX_PATH);
-  PathAppendSafe(maintserviceInstallerPath,
-                 L"maintenanceservice_installer.exe");
   WCHAR cmdLine[64] = { '\0' };
-  wcsncpy(cmdLine, L"dummyparam.exe /Upgrade",
+  wcsncpy(cmdLine, L"dummyparam.exe upgrade",
           sizeof(cmdLine) / sizeof(cmdLine[0]) - 1);
-  BOOL svcUpdateProcessStarted = CreateProcessW(maintserviceInstallerPath,
+  BOOL svcUpdateProcessStarted = CreateProcessW(tmpService,
                                                 cmdLine,
                                                 nullptr, nullptr, FALSE,
                                                 0,
                                                 nullptr, installDir, &si, &pi);
   if (svcUpdateProcessStarted) {
     CloseHandle(pi.hProcess);
     CloseHandle(pi.hThread);
   }