commit 94438b0c361590edb3ee667476e28ff83bdf87d5 Author: Brian R. Bondy netzen@gmail.com Date: Mon Mar 31 12:43:38 2014 -0400
Bug 961676. r=rstrong. a=abillings --- toolkit/mozapps/update/common/updatehelper.cpp | 60 ++++++++++++++++++++---- 1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/toolkit/mozapps/update/common/updatehelper.cpp b/toolkit/mozapps/update/common/updatehelper.cpp index 275b7dc..ab64c2d 100644 --- a/toolkit/mozapps/update/common/updatehelper.cpp +++ b/toolkit/mozapps/update/common/updatehelper.cpp @@ -23,6 +23,7 @@ #include "shlobj.h" #include "updatehelper.h" #include "pathhash.h" +#include "mozilla/Scoped.h"
// Needed for PathAppendW #include <shlwapi.h> @@ -216,26 +217,67 @@ StartServiceUpdate(LPCWSTR installDir) 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, NULL, NULL, FALSE, 0,
tbb-commits@lists.torproject.org