summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/update
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/update')
-rw-r--r--toolkit/mozapps/update/common/errors.h23
-rw-r--r--toolkit/mozapps/update/common/moz.build5
-rw-r--r--toolkit/mozapps/update/common/sources.mozbuild9
-rw-r--r--toolkit/mozapps/update/nsUpdateService.js294
-rw-r--r--toolkit/mozapps/update/tests/TestAUSHelper.cpp10
-rw-r--r--toolkit/mozapps/update/tests/moz.build6
-rw-r--r--toolkit/mozapps/update/updater/updater.cpp281
7 files changed, 65 insertions, 563 deletions
diff --git a/toolkit/mozapps/update/common/errors.h b/toolkit/mozapps/update/common/errors.h
index aac029175..846118d55 100644
--- a/toolkit/mozapps/update/common/errors.h
+++ b/toolkit/mozapps/update/common/errors.h
@@ -42,18 +42,6 @@
#define MAR_CHANNEL_MISMATCH_ERROR 22
#define VERSION_DOWNGRADE_ERROR 23
-// Error codes 24-33 and 49-57 are for the Windows maintenance service.
-#define SERVICE_UPDATER_COULD_NOT_BE_STARTED 24
-#define SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS 25
-#define SERVICE_UPDATER_SIGN_ERROR 26
-#define SERVICE_UPDATER_COMPARE_ERROR 27
-#define SERVICE_UPDATER_IDENTITY_ERROR 28
-#define SERVICE_STILL_APPLYING_ON_SUCCESS 29
-#define SERVICE_STILL_APPLYING_ON_FAILURE 30
-#define SERVICE_UPDATER_NOT_FIXED_DRIVE 31
-#define SERVICE_COULD_NOT_LOCK_UPDATER 32
-#define SERVICE_INSTALLDIR_ERROR 33
-
#define NO_INSTALLDIR_ERROR 34
#define WRITE_ERROR_ACCESS_DENIED 35
// #define WRITE_ERROR_SHARING_VIOLATION 36 // Replaced with errors 46-48
@@ -67,17 +55,6 @@
#define DELETE_ERROR_EXPECTED_FILE 47
#define RENAME_ERROR_EXPECTED_FILE 48
-// Error codes 24-33 and 49-57 are for the Windows maintenance service.
-#define SERVICE_COULD_NOT_COPY_UPDATER 49
-#define SERVICE_STILL_APPLYING_TERMINATED 50
-#define SERVICE_STILL_APPLYING_NO_EXIT_CODE 51
-#define SERVICE_INVALID_APPLYTO_DIR_STAGED_ERROR 52
-#define SERVICE_CALC_REG_PATH_ERROR 53
-#define SERVICE_INVALID_APPLYTO_DIR_ERROR 54
-#define SERVICE_INVALID_INSTALL_DIR_PATH_ERROR 55
-#define SERVICE_INVALID_WORKING_DIR_PATH_ERROR 56
-#define SERVICE_INSTALL_DIR_REG_ERROR 57
-
#define WRITE_ERROR_FILE_COPY 61
#define WRITE_ERROR_DELETE_FILE 62
#define WRITE_ERROR_OPEN_PATCH_FILE 63
diff --git a/toolkit/mozapps/update/common/moz.build b/toolkit/mozapps/update/common/moz.build
index cacb0bad2..ca7c4c307 100644
--- a/toolkit/mozapps/update/common/moz.build
+++ b/toolkit/mozapps/update/common/moz.build
@@ -17,11 +17,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'updatehelper.cpp',
'updatehelper.h',
]
- if CONFIG['MOZ_MAINTENANCE_SERVICE']:
- EXPORTS += [
- 'certificatecheck.h',
- 'registrycertificates.h',
- ]
Library('updatecommon')
diff --git a/toolkit/mozapps/update/common/sources.mozbuild b/toolkit/mozapps/update/common/sources.mozbuild
index cde51e09b..339944640 100644
--- a/toolkit/mozapps/update/common/sources.mozbuild
+++ b/toolkit/mozapps/update/common/sources.mozbuild
@@ -10,15 +10,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'uachelper.cpp',
'updatehelper.cpp',
]
- if CONFIG['MOZ_MAINTENANCE_SERVICE']:
- sources += [
- 'certificatecheck.cpp',
- 'registrycertificates.cpp',
- ]
- OS_LIBS += [
- 'crypt32',
- 'wintrust',
- ]
sources += [
'readstrings.cpp',
diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js
index 0cf7b8938..4e2d66a5c 100644
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -35,15 +35,13 @@ const PREF_APP_UPDATE_LOG = "app.update.log";
const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED = "app.update.notifiedUnsupported";
const PREF_APP_UPDATE_POSTUPDATE = "app.update.postupdate";
const PREF_APP_UPDATE_PROMPTWAITTIME = "app.update.promptWaitTime";
-const PREF_APP_UPDATE_SERVICE_ENABLED = "app.update.service.enabled";
-const PREF_APP_UPDATE_SERVICE_ERRORS = "app.update.service.errors";
-const PREF_APP_UPDATE_SERVICE_MAXERRORS = "app.update.service.maxErrors";
const PREF_APP_UPDATE_SILENT = "app.update.silent";
const PREF_APP_UPDATE_SOCKET_MAXERRORS = "app.update.socket.maxErrors";
const PREF_APP_UPDATE_SOCKET_RETRYTIMEOUT = "app.update.socket.retryTimeout";
const PREF_APP_UPDATE_STAGING_ENABLED = "app.update.staging.enabled";
const PREF_APP_UPDATE_URL = "app.update.url";
const PREF_APP_UPDATE_URL_DETAILS = "app.update.url.details";
+const PREF_APP_UPDATE_URL_OVERRIDE = "app.update.url.override";
const PREFBRANCH_APP_UPDATE_NEVER = "app.update.never.";
@@ -72,12 +70,10 @@ const FILE_UPDATE_VERSION = "update.version";
const STATE_NONE = "null";
const STATE_DOWNLOADING = "downloading";
const STATE_PENDING = "pending";
-const STATE_PENDING_SERVICE = "pending-service";
const STATE_PENDING_ELEVATE = "pending-elevate";
const STATE_APPLYING = "applying";
const STATE_APPLIED = "applied";
const STATE_APPLIED_OS = "applied-os";
-const STATE_APPLIED_SERVICE = "applied-service";
const STATE_SUCCEEDED = "succeeded";
const STATE_DOWNLOAD_FAILED = "download-failed";
const STATE_FAILED = "failed";
@@ -85,22 +81,9 @@ const STATE_FAILED = "failed";
// The values below used by this code are from common/errors.h
const WRITE_ERROR = 7;
const ELEVATION_CANCELED = 9;
-const SERVICE_UPDATER_COULD_NOT_BE_STARTED = 24;
-const SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS = 25;
-const SERVICE_UPDATER_SIGN_ERROR = 26;
-const SERVICE_UPDATER_COMPARE_ERROR = 27;
-const SERVICE_UPDATER_IDENTITY_ERROR = 28;
-const SERVICE_STILL_APPLYING_ON_SUCCESS = 29;
-const SERVICE_STILL_APPLYING_ON_FAILURE = 30;
-const SERVICE_UPDATER_NOT_FIXED_DRIVE = 31;
-const SERVICE_COULD_NOT_LOCK_UPDATER = 32;
-const SERVICE_INSTALLDIR_ERROR = 33;
const WRITE_ERROR_ACCESS_DENIED = 35;
const WRITE_ERROR_CALLBACK_APP = 37;
const FILESYSTEM_MOUNT_READWRITE_ERROR = 43;
-const SERVICE_COULD_NOT_COPY_UPDATER = 49;
-const SERVICE_STILL_APPLYING_TERMINATED = 50;
-const SERVICE_STILL_APPLYING_NO_EXIT_CODE = 51;
const WRITE_ERROR_FILE_COPY = 61;
const WRITE_ERROR_DELETE_FILE = 62;
const WRITE_ERROR_OPEN_PATCH_FILE = 63;
@@ -127,21 +110,6 @@ const WRITE_ERRORS = [WRITE_ERROR,
WRITE_ERROR_DELETE_BACKUP,
WRITE_ERROR_EXTRACT];
-// Array of write errors to simplify checks for service errors
-const SERVICE_ERRORS = [SERVICE_UPDATER_COULD_NOT_BE_STARTED,
- SERVICE_NOT_ENOUGH_COMMAND_LINE_ARGS,
- SERVICE_UPDATER_SIGN_ERROR,
- SERVICE_UPDATER_COMPARE_ERROR,
- SERVICE_UPDATER_IDENTITY_ERROR,
- SERVICE_STILL_APPLYING_ON_SUCCESS,
- SERVICE_STILL_APPLYING_ON_FAILURE,
- SERVICE_UPDATER_NOT_FIXED_DRIVE,
- SERVICE_COULD_NOT_LOCK_UPDATER,
- SERVICE_INSTALLDIR_ERROR,
- SERVICE_COULD_NOT_COPY_UPDATER,
- SERVICE_STILL_APPLYING_TERMINATED,
- SERVICE_STILL_APPLYING_NO_EXIT_CODE];
-
// Error codes 80 through 99 are reserved for nsUpdateService.js and are not
// defined in common/errors.h
const FOTA_GENERAL_ERROR = 80;
@@ -164,10 +132,6 @@ const DOWNLOAD_FOREGROUND_INTERVAL = 0;
const UPDATE_WINDOW_NAME = "Update:Wizard";
-// The number of consecutive failures when updating using the service before
-// setting the app.update.service.enabled preference to false.
-const DEFAULT_SERVICE_MAX_ERRORS = 10;
-
// The number of consecutive socket errors to allow before falling back to
// downloading a different MAR file or failing if already downloading the full.
const DEFAULT_SOCKET_MAX_ERRORS = 10;
@@ -392,15 +356,7 @@ function getElevationRequired() {
* @return true if an update can be applied, false otherwise
*/
function getCanApplyUpdates() {
- let useService = false;
- if (shouldUseService()) {
- // No need to perform directory write checks, the maintenance service will
- // be able to write to all directories.
- LOG("getCanApplyUpdates - bypass the write checks because we'll use the service");
- useService = true;
- }
-
- if (!useService && AppConstants.platform != "macosx") {
+ if (AppConstants.platform != "macosx") {
try {
let updateTestFile = getUpdateFile([FILE_UPDATE_TEST]);
LOG("getCanApplyUpdates - testing write access " + updateTestFile.path);
@@ -478,7 +434,7 @@ function getCanApplyUpdates() {
// No write privileges to install directory
return false;
}
- } // if (!useService)
+ }
LOG("getCanApplyUpdates - able to apply updates");
return true;
@@ -544,13 +500,6 @@ function getCanStageUpdates() {
return false;
}
- if (AppConstants.platform == "win" && shouldUseService()) {
- // No need to perform directory write checks, the maintenance service will
- // be able to write to all directories.
- LOG("getCanStageUpdates - able to stage updates using the service");
- return true;
- }
-
if (!hasUpdateMutex()) {
LOG("getCanStageUpdates - unable to apply updates because another " +
"instance of the application is already handling updates for this " +
@@ -778,120 +727,6 @@ function writeVersionFile(dir, version) {
}
/**
- * Determines if the service should be used to attempt an update
- * or not.
- *
- * @return true if the service should be used for updates.
- */
-function shouldUseService() {
- // This function will return true if the mantenance service should be used if
- // all of the following conditions are met:
- // 1) This build was done with the maintenance service enabled
- // 2) The maintenance service is installed
- // 3) The pref for using the service is enabled
- // 4) The Windows version is XP Service Pack 3 or above (for SHA-2 support)
- // The maintenance service requires SHA-2 support because we sign our binaries
- // with a SHA-2 certificate and the certificate is verified before the binary
- // is launched.
- if (!AppConstants.MOZ_MAINTENANCE_SERVICE || !isServiceInstalled() ||
- !getPref("getBoolPref", PREF_APP_UPDATE_SERVICE_ENABLED, false) ||
- !AppConstants.isPlatformAndVersionAtLeast("win", "5.1") /* WinXP */) {
- return false;
- }
-
- // If it's newer than XP, then the service pack doesn't matter.
- if (Services.sysinfo.getProperty("version") != "5.1") {
- return true;
- }
-
- // If the Windows version is XP, we also need to check the service pack.
- // We'll return false if only < SP3 is installed, or if we can't tell.
- // Check the service pack level by calling GetVersionEx via ctypes.
- const BYTE = ctypes.uint8_t;
- const WORD = ctypes.uint16_t;
- const DWORD = ctypes.uint32_t;
- const WCHAR = ctypes.char16_t;
- const BOOL = ctypes.int;
- // This structure is described at:
- // http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
- const SZCSDVERSIONLENGTH = 128;
- const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
- [
- {dwOSVersionInfoSize: DWORD},
- {dwMajorVersion: DWORD},
- {dwMinorVersion: DWORD},
- {dwBuildNumber: DWORD},
- {dwPlatformId: DWORD},
- {szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
- {wServicePackMajor: WORD},
- {wServicePackMinor: WORD},
- {wSuiteMask: WORD},
- {wProductType: BYTE},
- {wReserved: BYTE}
- ]);
-
- let kernel32 = false;
- try {
- kernel32 = ctypes.open("Kernel32");
- } catch (e) {
- Cu.reportError("Unable to open kernel32! " + e);
- return false;
- }
-
- if (kernel32) {
- try {
- try {
- let GetVersionEx = kernel32.declare("GetVersionExW",
- ctypes.default_abi,
- BOOL,
- OSVERSIONINFOEXW.ptr);
- let winVer = OSVERSIONINFOEXW();
- winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
-
- if (0 !== GetVersionEx(winVer.address())) {
- return winVer.wServicePackMajor >= 3;
- }
- Cu.reportError("Unknown failure in GetVersionEX (returned 0)");
- return false;
- } catch (e) {
- Cu.reportError("Error getting service pack information. Exception: " + e);
- return false;
- }
- } finally {
- kernel32.close();
- }
- }
-
- // If the service pack check couldn't be done, assume we can't use the service.
- return false;
-}
-
-/**
- * Determines if the service is is installed.
- *
- * @return true if the service is installed.
- */
-function isServiceInstalled() {
- if (AppConstants.MOZ_MAINTENANCE_SERVICE && AppConstants.platform == "win") {
- let installed = 0;
- try {
- let wrk = Cc["@mozilla.org/windows-registry-key;1"].
- createInstance(Ci.nsIWindowsRegKey);
- wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
- "SOFTWARE\\Mozilla\\MaintenanceService",
- wrk.ACCESS_READ | wrk.WOW64_64);
- installed = wrk.readIntValue("Installed");
- wrk.close();
- } catch (e) {
- }
- installed = installed == 1; // convert to bool
- LOG("isServiceInstalled = " + installed);
- return installed;
- }
- return false;
-}
-
-/**
* Removes the contents of the updates patch directory and rotates the update
* logs when present. If the update.log exists in the patch directory this will
* move the last-update.log if it exists to backup-update.log in the parent
@@ -1102,35 +937,6 @@ function handleUpdateFailure(update, errorCode) {
Services.prefs.clearUserPref(PREF_APP_UPDATE_CANCELATIONS_OSX);
}
- // Replace with Array.prototype.includes when it has stabilized.
- if (SERVICE_ERRORS.indexOf(update.errorCode) != -1) {
- var failCount = getPref("getIntPref",
- PREF_APP_UPDATE_SERVICE_ERRORS, 0);
- var maxFail = getPref("getIntPref",
- PREF_APP_UPDATE_SERVICE_MAXERRORS,
- DEFAULT_SERVICE_MAX_ERRORS);
- // Prevent the preference from setting a value greater than 10.
- maxFail = Math.min(maxFail, 10);
- // As a safety, when the service reaches maximum failures, it will
- // disable itself and fallback to using the normal update mechanism
- // without the service.
- if (failCount >= maxFail) {
- Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, false);
- Services.prefs.clearUserPref(PREF_APP_UPDATE_SERVICE_ERRORS);
- } else {
- failCount++;
- Services.prefs.setIntPref(PREF_APP_UPDATE_SERVICE_ERRORS,
- failCount);
- }
-
- writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
- return true;
- }
-
- if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_SERVICE_ERRORS)) {
- Services.prefs.clearUserPref(PREF_APP_UPDATE_SERVICE_ERRORS);
- }
-
return false;
}
@@ -1189,9 +995,6 @@ function pingStateAndStatusCodes(aUpdate, aStartup, aStatus) {
case STATE_PENDING:
stateCode = 4;
break;
- case STATE_PENDING_SERVICE:
- stateCode = 5;
- break;
case STATE_APPLYING:
stateCode = 6;
break;
@@ -1201,9 +1004,6 @@ function pingStateAndStatusCodes(aUpdate, aStartup, aStatus) {
case STATE_APPLIED_OS:
stateCode = 8;
break;
- case STATE_APPLIED_SERVICE:
- stateCode = 9;
- break;
case STATE_SUCCEEDED:
stateCode = 10;
break;
@@ -1831,8 +1631,8 @@ UpdateService.prototype = {
// version and nsUpdateDriver.cpp skipped updating due to the version being
// older than the current version.
if (update && update.appVersion &&
- (status == STATE_PENDING || status == STATE_PENDING_SERVICE ||
- status == STATE_APPLIED || status == STATE_APPLIED_SERVICE ||
+ (status == STATE_PENDING ||
+ status == STATE_APPLIED ||
status == STATE_PENDING_ELEVATE)) {
if (Services.vc.compare(update.appVersion, Services.appinfo.version) < 0 ||
Services.vc.compare(update.appVersion, Services.appinfo.version) == 0 &&
@@ -1870,9 +1670,7 @@ UpdateService.prototype = {
// that state to "applying" and we just wait and hope for the best.
// If it's "applying", we know that we've already been here once, so
// we really want to start from a clean state.
- if (update &&
- (update.state == STATE_PENDING ||
- update.state == STATE_PENDING_SERVICE)) {
+ if (update && (update.state == STATE_PENDING)) {
LOG("UpdateService:_postUpdateProcessing - patch found in applying " +
"state for the first time");
update.state = STATE_APPLYING;
@@ -2121,27 +1919,13 @@ UpdateService.prototype = {
this._pingSuffix,
PREF_APP_UPDATE_CANCELATIONS_OSX, 0, 0);
}
- if (AppConstants.MOZ_MAINTENANCE_SERVICE) {
- // Histogram IDs:
- // UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_EXTERNAL
- // UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_NOTIFY
- AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_" +
- this._pingSuffix,
- PREF_APP_UPDATE_SERVICE_ENABLED, true);
- // Histogram IDs:
- // UPDATE_PREF_SERVICE_ERRORS_EXTERNAL
- // UPDATE_PREF_SERVICE_ERRORS_NOTIFY
- AUSTLMY.pingIntPref("UPDATE_PREF_SERVICE_ERRORS_" + this._pingSuffix,
- PREF_APP_UPDATE_SERVICE_ERRORS, 0, 0);
- if (AppConstants.platform == "win") {
- // Histogram IDs:
- // UPDATE_SERVICE_INSTALLED_EXTERNAL
- // UPDATE_SERVICE_INSTALLED_NOTIFY
- // UPDATE_SERVICE_MANUALLY_UNINSTALLED_EXTERNAL
- // UPDATE_SERVICE_MANUALLY_UNINSTALLED_NOTIFY
- AUSTLMY.pingServiceInstallStatus(this._pingSuffix, isServiceInstalled());
- }
- }
+ let prefType = Services.prefs.getPrefType(PREF_APP_UPDATE_URL_OVERRIDE);
+ let overridePrefHasValue = prefType != Ci.nsIPrefBranch.PREF_INVALID;
+ // Histogram IDs:
+ // UPDATE_HAS_PREF_URL_OVERRIDE_EXTERNAL
+ // UPDATE_HAS_PREF_URL_OVERRIDE_NOTIFY
+ AUSTLMY.pingGeneric("UPDATE_HAS_PREF_URL_OVERRIDE_" + this._pingSuffix,
+ overridePrefHasValue, false);
// If a download is in progress or the patch has been staged do nothing.
if (this.isDownloading) {
@@ -2151,7 +1935,7 @@ UpdateService.prototype = {
if (this._downloader && this._downloader.patchIsStaged) {
let readState = readStatusFile(getUpdatesDir());
- if (readState == STATE_PENDING || readState == STATE_PENDING_SERVICE ||
+ if (readState == STATE_PENDING ||
readState == STATE_PENDING_ELEVATE) {
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_IS_DOWNLOADED);
} else {
@@ -2173,8 +1957,18 @@ UpdateService.prototype = {
} else if (!UpdateUtils.ABI) {
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_OS_ABI);
} else if (!validUpdateURL) {
- AUSTLMY.pingCheckCode(this._pingSuffix,
- AUSTLMY.CHK_INVALID_DEFAULT_URL);
+ if (overridePrefHasValue) {
+ if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
+ AUSTLMY.pingCheckCode(this._pingSuffix,
+ AUSTLMY.CHK_INVALID_USER_OVERRIDE_URL);
+ } else {
+ AUSTLMY.pingCheckCode(this._pingSuffix,
+ AUSTLMY.CHK_INVALID_DEFAULT_OVERRIDE_URL);
+ }
+ } else {
+ AUSTLMY.pingCheckCode(this._pingSuffix,
+ AUSTLMY.CHK_INVALID_DEFAULT_URL);
+ }
} else if (!getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true)) {
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_PREF_DISABLED);
} else if (!hasUpdateMutex()) {
@@ -2885,8 +2679,8 @@ UpdateManager.prototype = {
for (let i = updates.length - 1; i >= 0; --i) {
let state = updates[i].state;
if (state == STATE_NONE || state == STATE_DOWNLOADING ||
- state == STATE_APPLIED || state == STATE_APPLIED_SERVICE ||
- state == STATE_PENDING || state == STATE_PENDING_SERVICE ||
+ state == STATE_APPLIED ||
+ state == STATE_PENDING ||
state == STATE_PENDING_ELEVATE) {
updates.splice(i, 1);
}
@@ -2931,9 +2725,6 @@ UpdateManager.prototype = {
update.QueryInterface(Ci.nsIWritablePropertyBag);
update.setProperty("stagingFailed", "true");
}
- if (update.state == STATE_APPLIED && shouldUseService()) {
- writeStatusFile(getUpdatesDir(), update.state = STATE_APPLIED_SERVICE);
- }
// Send an observer notification which the update wizard uses in
// order to update its UI.
@@ -2949,9 +2740,7 @@ UpdateManager.prototype = {
}
if (update.state == STATE_APPLIED ||
- update.state == STATE_APPLIED_SERVICE ||
update.state == STATE_PENDING ||
- update.state == STATE_PENDING_SERVICE ||
update.state == STATE_PENDING_ELEVATE) {
// Notify the user that an update has been staged and is ready for
// installation (i.e. that they should restart the application).
@@ -3023,11 +2812,16 @@ Checker.prototype = {
getUpdateURL: function UC_getUpdateURL(force) {
this._forced = force;
- let url;
- try {
- url = Services.prefs.getDefaultBranch(null).
- getCharPref(PREF_APP_UPDATE_URL);
- } catch (e) {
+ // Use the override URL if specified.
+ let url = getPref("getCharPref", PREF_APP_UPDATE_URL_OVERRIDE, null);
+
+ // Otherwise, construct the update URL from component parts.
+ if (!url) {
+ try {
+ url = Services.prefs.getDefaultBranch(null).
+ getCharPref(PREF_APP_UPDATE_URL);
+ } catch (e) {
+ }
}
if (!url || url == "") {
@@ -3309,9 +3103,9 @@ Downloader.prototype = {
// Note that if we decide to download and apply new updates after another
// update has been successfully applied in the background, we need to stop
// checking for the APPLIED state here.
- return readState == STATE_PENDING || readState == STATE_PENDING_SERVICE ||
+ return readState == STATE_PENDING ||
readState == STATE_PENDING_ELEVATE ||
- readState == STATE_APPLIED || readState == STATE_APPLIED_SERVICE;
+ readState == STATE_APPLIED;
},
/**
@@ -3428,7 +3222,7 @@ Downloader.prototype = {
return selectedPatch;
}
- if (state == STATE_PENDING || state == STATE_PENDING_SERVICE ||
+ if (state == STATE_PENDING ||
state == STATE_PENDING_ELEVATE) {
LOG("Downloader:_selectPatch - already downloaded and staged");
return null;
@@ -3721,9 +3515,7 @@ Downloader.prototype = {
"max fail: " + maxFail + ", " + "retryTimeout: " + retryTimeout);
if (Components.isSuccessCode(status)) {
if (this._verifyDownload()) {
- if (shouldUseService()) {
- state = STATE_PENDING_SERVICE;
- } else if (getElevationRequired()) {
+ if (getElevationRequired()) {
state = STATE_PENDING_ELEVATE;
} else {
state = STATE_PENDING;
@@ -3873,7 +3665,7 @@ Downloader.prototype = {
return;
}
- if (state == STATE_PENDING || state == STATE_PENDING_SERVICE ||
+ if (state == STATE_PENDING ||
state == STATE_PENDING_ELEVATE) {
if (getCanStageUpdates()) {
LOG("Downloader:onStopRequest - attempting to stage update: " +
diff --git a/toolkit/mozapps/update/tests/TestAUSHelper.cpp b/toolkit/mozapps/update/tests/TestAUSHelper.cpp
index f71103b7a..a20c4a79a 100644
--- a/toolkit/mozapps/update/tests/TestAUSHelper.cpp
+++ b/toolkit/mozapps/update/tests/TestAUSHelper.cpp
@@ -217,16 +217,8 @@ int NS_main(int argc, NS_tchar **argv)
}
if (!NS_tstrcmp(argv[1], NS_T("check-signature"))) {
-#if defined(XP_WIN) && defined(MOZ_MAINTENANCE_SERVICE)
- if (ERROR_SUCCESS == VerifyCertificateTrustForFile(argv[2])) {
- return 0;
- } else {
- return 1;
- }
-#else
- // Not implemented on non-Windows platforms
+ // Not implemented
return 1;
-#endif
}
if (!NS_tstrcmp(argv[1], NS_T("setup-symlink"))) {
diff --git a/toolkit/mozapps/update/tests/moz.build b/toolkit/mozapps/update/tests/moz.build
index 842ec7f90..94949b17f 100644
--- a/toolkit/mozapps/update/tests/moz.build
+++ b/toolkit/mozapps/update/tests/moz.build
@@ -15,9 +15,6 @@ XPCSHELL_TESTS_MANIFESTS += [
'unit_base_updater/xpcshell.ini'
]
-if CONFIG['MOZ_MAINTENANCE_SERVICE']:
- XPCSHELL_TESTS_MANIFESTS += ['unit_service_updater/xpcshell.ini']
-
SimplePrograms([
'TestAUSHelper',
'TestAUSReadStrings',
@@ -47,9 +44,6 @@ for var in ('MOZ_APP_NAME', 'MOZ_APP_BASENAME', 'MOZ_APP_DISPLAYNAME',
DEFINES['NS_NO_XPCOM'] = True
-if CONFIG['MOZ_MAINTENANCE_SERVICE']:
- DEFINES['MOZ_MAINTENANCE_SERVICE'] = CONFIG['MOZ_MAINTENANCE_SERVICE']
-
# For debugging purposes only
#DEFINES['DISABLE_UPDATER_AUTHENTICODE_CHECK'] = True
diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp
index dbf50329c..c0b01bfbc 100644
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -119,9 +119,6 @@ struct UpdateServerThreadArgs
#endif
#ifdef XP_WIN
-#ifdef MOZ_MAINTENANCE_SERVICE
-#include "registrycertificates.h"
-#endif
BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra);
BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer,
LPCWSTR siblingFilePath,
@@ -290,7 +287,6 @@ static ArchiveReader gArchiveReader;
static bool gSucceeded = false;
static bool sStagedUpdate = false;
static bool sReplaceRequest = false;
-static bool sUsingService = false;
static bool sIsOSUpdate = false;
#ifdef XP_WIN
@@ -1954,8 +1950,7 @@ PatchIfFile::Finish(int status)
/**
* Launch the post update application (helper.exe). It takes in the path of the
- * callback application to calculate the path of helper.exe. For service updates
- * this is called from both the system account and the current user account.
+ * callback application to calculate the path of helper.exe.
*
* @param installationDir The path to the callback application binary.
* @param updateInfoDir The directory where update info is stored.
@@ -2024,13 +2019,6 @@ LaunchWinPostProcess(const WCHAR *installationDir,
return false;
}
-#if !defined(TEST_UPDATER) && defined(MOZ_MAINTENANCE_SERVICE)
- if (sUsingService &&
- !DoesBinaryMatchAllowedCertificates(installationDir, exefullpath)) {
- return false;
- }
-#endif
-
WCHAR dlogFile[MAX_PATH + 1];
if (!PathGetSiblingFilePath(dlogFile, exefullpath, L"uninstall.update")) {
return false;
@@ -2054,12 +2042,6 @@ LaunchWinPostProcess(const WCHAR *installationDir,
wcsncpy(cmdline, dummyArg, len);
wcscat(cmdline, exearg);
- if (sUsingService ||
- !_wcsnicmp(exeasync, L"false", 6) ||
- !_wcsnicmp(exeasync, L"0", 2)) {
- async = false;
- }
-
// We want to launch the post update helper app to update the Windows
// registry even if there is a failure with removing the uninstall.update
// file or copying the update.log file.
@@ -2095,8 +2077,7 @@ LaunchWinPostProcess(const WCHAR *installationDir,
static void
LaunchCallbackApp(const NS_tchar *workingDir,
int argc,
- NS_tchar **argv,
- bool usingService)
+ NS_tchar **argv)
{
putenv(const_cast<char*>("NO_EM_RESTART="));
putenv(const_cast<char*>("MOZ_LAUNCHED_CHILD=1"));
@@ -2113,11 +2094,7 @@ LaunchCallbackApp(const NS_tchar *workingDir,
#elif defined(XP_MACOSX)
LaunchChild(argc, (const char**)argv);
#elif defined(XP_WIN)
- // 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.
- if (!usingService) {
- WinLaunchChild(argv[0], argc, argv, nullptr);
- }
+ WinLaunchChild(argv[0], argc, argv, nullptr);
#else
# warning "Need implementaton of LaunchCallbackApp"
#endif
@@ -2188,40 +2165,6 @@ WriteStatusFile(int status)
WriteStatusFile(text);
}
-#ifdef MOZ_MAINTENANCE_SERVICE
-/*
- * Read the update.status file and sets isPendingService to true if
- * the status is set to pending-service.
- *
- * @param isPendingService Out parameter for specifying if the status
- * is set to pending-service or not.
- * @return true if the information was retrieved and it is pending
- * or pending-service.
-*/
-static bool
-IsUpdateStatusPendingService()
-{
- NS_tchar filename[MAXPATHLEN];
- NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
- NS_T("%s/update.status"), gPatchDirPath);
-
- AutoFile file(NS_tfopen(filename, NS_T("rb")));
- if (file == nullptr)
- return false;
-
- char buf[32] = { 0 };
- fread(buf, sizeof(buf), 1, file);
-
- const char kPendingService[] = "pending-service";
- const char kAppliedService[] = "applied-service";
-
- return (strncmp(buf, kPendingService,
- sizeof(kPendingService) - 1) == 0) ||
- (strncmp(buf, kAppliedService,
- sizeof(kAppliedService) - 1) == 0);
-}
-#endif
-
#ifdef XP_WIN
/*
* Read the update.status file and sets isSuccess to true if
@@ -2601,7 +2544,7 @@ UpdateThreadFunc(void *param)
// updater application again in order to apply the update without
// staging.
if (sReplaceRequest) {
- WriteStatusFile(sUsingService ? "pending-service" : "pending");
+ WriteStatusFile("pending");
} else {
WriteStatusFile(rv);
}
@@ -2668,17 +2611,6 @@ int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv,
if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) {
fprintf(stderr, "The post update process was not launched");
}
-
- // 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.
- if (!sUsingService) {
- StartServiceUpdate(gInstallDirPath);
- }
}
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 0);
#elif XP_MACOSX
@@ -2690,8 +2622,7 @@ int LaunchCallbackAndPostProcessApps(int argc, NS_tchar** argv,
LaunchCallbackApp(argv[5],
argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ argv + callbackIndex);
#ifdef XP_MACOSX
} // if (!isElevated)
#endif /* XP_MACOSX */
@@ -2765,8 +2696,6 @@ int NS_main(int argc, NS_tchar **argv)
return 1;
}
- // This check is also performed in workmonitor.cpp since the maintenance
- // service can be called directly.
if (!IsValidFullPath(argv[1])) {
// Since the status file is written to the patch directory and the patch
// directory is invalid don't write the status file.
@@ -2783,8 +2712,6 @@ int NS_main(int argc, NS_tchar **argv)
// The directory containing the update information.
NS_tstrncpy(gPatchDirPath, argv[1], MAXPATHLEN);
- // This check is also performed in workmonitor.cpp since the maintenance
- // service can be called directly.
if (!IsValidFullPath(argv[2])) {
WriteStatusFile(INVALID_INSTALL_DIR_PATH_ERROR);
fprintf(stderr, "The install directory path is not valid for this " \
@@ -2809,23 +2736,7 @@ int NS_main(int argc, NS_tchar **argv)
}
#ifdef XP_WIN
- bool useService = false;
bool testOnlyFallbackKeyExists = false;
- bool noServiceFallback = false;
-
- // We never want the service to be used unless we build with
- // the maintenance service.
-#ifdef MOZ_MAINTENANCE_SERVICE
- useService = IsUpdateStatusPendingService();
-#ifdef TEST_UPDATER
- noServiceFallback = EnvHasValue("MOZ_NO_SERVICE_FALLBACK");
- putenv(const_cast<char*>("MOZ_NO_SERVICE_FALLBACK="));
- // Our tests run with a different apply directory for each test.
- // We use this registry key on our test slaves to store the
- // allowed name/issuers.
- testOnlyFallbackKeyExists = DoesFallbackKeyExist();
-#endif
-#endif
// Remove everything except close window from the context menu
{
@@ -2869,8 +2780,6 @@ int NS_main(int argc, NS_tchar **argv)
}
}
- // This check is also performed in workmonitor.cpp since the maintenance
- // service can be called directly.
if (!IsValidFullPath(argv[3])) {
WriteStatusFile(INVALID_WORKING_DIR_PATH_ERROR);
fprintf(stderr, "The working directory path is not valid for this " \
@@ -2894,8 +2803,6 @@ int NS_main(int argc, NS_tchar **argv)
*slash = NS_T('\0');
}
- // These checks are also performed in workmonitor.cpp since the maintenance
- // service can be called directly.
if (argc > callbackIndex) {
if (!IsValidFullPath(argv[callbackIndex])) {
WriteStatusFile(INVALID_CALLBACK_PATH_ERROR);
@@ -2977,8 +2884,6 @@ int NS_main(int argc, NS_tchar **argv)
LOG(("WORKING DIRECTORY " LOG_S, gWorkingDirPath));
#if defined(XP_WIN)
- // These checks are also performed in workmonitor.cpp since the maintenance
- // service can be called directly.
if (_wcsnicmp(gWorkingDirPath, gInstallDirPath, MAX_PATH) != 0) {
if (!sStagedUpdate && !sReplaceRequest) {
WriteStatusFile(INVALID_APPLYTO_DIR_ERROR);
@@ -3030,23 +2935,11 @@ int NS_main(int argc, NS_tchar **argv)
#endif
#ifdef XP_WIN
-#ifdef MOZ_MAINTENANCE_SERVICE
- sUsingService = EnvHasValue("MOZ_USING_SERVICE");
- putenv(const_cast<char*>("MOZ_USING_SERVICE="));
-#endif
- // lastFallbackError keeps track of the last error for the service not being
- // used, in case of an error when fallback is not enabled we write the
- // error to the update.status file.
- // When fallback is disabled (MOZ_NO_SERVICE_FALLBACK does not exist) then
- // we will instead fallback to not using the service and display a UAC prompt.
- int lastFallbackError = FALLBACKKEY_UNKNOWN_ERROR;
-
// Launch a second instance of the updater with the runas verb on Windows
// when write access is denied to the installation directory.
HANDLE updateLockFileHandle = INVALID_HANDLE_VALUE;
NS_tchar elevatedLockFilePath[MAXPATHLEN] = {NS_T('\0')};
- if (!sUsingService &&
- (argc > callbackIndex || sStagedUpdate || sReplaceRequest)) {
+ if (argc > callbackIndex || sStagedUpdate || sReplaceRequest) {
NS_tchar updateLockFilePath[MAXPATHLEN];
if (sStagedUpdate) {
// When staging an update, the lock file is:
@@ -3104,8 +2997,7 @@ int NS_main(int argc, NS_tchar **argv)
bool startedFromUnelevatedUpdater =
GetFileAttributesW(elevatedLockFilePath) != INVALID_FILE_ATTRIBUTES;
- // If we're running from the service, then we were started with the same
- // token as the service so the permissions are already dropped. If we're
+ // If we're
// running from an elevated updater that was started from an unelevated
// updater, then we drop the permissions here. We do not drop the
// permissions on the originally called updater because we use its token
@@ -3116,8 +3008,7 @@ int NS_main(int argc, NS_tchar **argv)
UACHelper::DisablePrivileges(nullptr);
}
- if (updateLockFileHandle == INVALID_HANDLE_VALUE ||
- (useService && testOnlyFallbackKeyExists && noServiceFallback)) {
+ if (updateLockFileHandle == INVALID_HANDLE_VALUE) {
if (!_waccess(elevatedLockFilePath, F_OK) &&
NS_tremove(elevatedLockFilePath) != 0) {
fprintf(stderr, "Unable to create elevated lock file! Exiting\n");
@@ -3144,105 +3035,11 @@ int NS_main(int argc, NS_tchar **argv)
return 1;
}
- // Make sure the path to the updater to use for the update is on local.
- // We do this check to make sure that file locking is available for
- // race condition security checks.
- if (useService) {
- BOOL isLocal = FALSE;
- useService = IsLocalFile(argv[0], isLocal) && isLocal;
- }
-
- // If we have unprompted elevation we should NOT use the service
- // for the update. Service updates happen with the SYSTEM account
- // which has more privs than we need to update with.
- // Windows 8 provides a user interface so users can configure this
- // behavior and it can be configured in the registry in all Windows
- // versions that support UAC.
- if (useService) {
- BOOL unpromptedElevation;
- if (IsUnpromptedElevation(unpromptedElevation)) {
- useService = !unpromptedElevation;
- }
- }
-
- // Make sure the service registry entries for the instsallation path
- // are available. If not don't use the service.
- if (useService) {
- WCHAR maintenanceServiceKey[MAX_PATH + 1];
- if (CalculateRegistryPathFromFilePath(gInstallDirPath,
- maintenanceServiceKey)) {
- HKEY baseKey = nullptr;
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- maintenanceServiceKey, 0,
- KEY_READ | KEY_WOW64_64KEY,
- &baseKey) == ERROR_SUCCESS) {
- RegCloseKey(baseKey);
- } else {
-#ifdef TEST_UPDATER
- useService = testOnlyFallbackKeyExists;
-#endif
- if (!useService) {
- lastFallbackError = FALLBACKKEY_NOKEY_ERROR;
- }
- }
- } else {
- useService = false;
- lastFallbackError = FALLBACKKEY_REGPATH_ERROR;
- }
- }
-
- // Originally we used to write "pending" to update.status before
- // launching the service command. This is no longer needed now
- // since the service command is launched from updater.exe. If anything
- // fails in between, we can fall back to using the normal update process
- // on our own.
-
- // If we still want to use the service try to launch the service
- // comamnd for the update.
- if (useService) {
- // If the update couldn't be started, then set useService to false so
- // we do the update the old way.
- DWORD ret = LaunchServiceSoftwareUpdateCommand(argc, (LPCWSTR *)argv);
- useService = (ret == ERROR_SUCCESS);
- // If the command was launched then wait for the service to be done.
- if (useService) {
- bool showProgressUI = false;
- // Never show the progress UI when staging updates.
- if (!sStagedUpdate) {
- // We need to call this separately instead of allowing ShowProgressUI
- // to initialize the strings because the service will move the
- // ini file out of the way when running updater.
- showProgressUI = !InitProgressUIStrings();
- }
- // Wait for the service to stop for 5 seconds. If the service
- // has still not stopped then show an indeterminate progress bar.
- DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
- if (lastState != SERVICE_STOPPED) {
- Thread t1;
- if (t1.Run(WaitForServiceFinishThread, nullptr) == 0 &&
- showProgressUI) {
- ShowProgressUI(true, false);
- }
- t1.Join();
- }
-
- lastState = WaitForServiceStop(SVC_NAME, 1);
- if (lastState != SERVICE_STOPPED) {
- // If the service doesn't stop after 10 minutes there is
- // something seriously wrong.
- lastFallbackError = FALLBACKKEY_SERVICE_NO_STOP_ERROR;
- useService = false;
- }
- } else {
- lastFallbackError = FALLBACKKEY_LAUNCH_ERROR;
- }
- }
-
- // If the service can't be used when staging an update, make sure that
+ // When staging an update, make sure that
// the UAC prompt is not shown! In this case, just set the status to
// pending and the update will be applied during the next startup.
- if (!useService && sStagedUpdate) {
+ if (sStagedUpdate) {
if (updateLockFileHandle != INVALID_HANDLE_VALUE) {
CloseHandle(updateLockFileHandle);
}
@@ -3250,32 +3047,10 @@ int NS_main(int argc, NS_tchar **argv)
return 0;
}
- // If we started the service command, and it finished, check the
- // update.status file to make sure it succeeded, and if it did
- // we need to manually start the PostUpdate process from the
- // current user's session of this unelevated updater.exe the
- // current process is running as.
- // Note that we don't need to do this if we're just staging the update,
- // as the PostUpdate step runs when performing the replacing in that case.
- if (useService && !sStagedUpdate) {
- bool updateStatusSucceeded = false;
- if (IsUpdateStatusSucceeded(updateStatusSucceeded) &&
- updateStatusSucceeded) {
- if (!LaunchWinPostProcess(gInstallDirPath, gPatchDirPath)) {
- fprintf(stderr, "The post update process which runs as the user"
- " for service update could not be launched.");
- }
- }
- }
-
- // If we didn't want to use the service at all, or if an update was
- // already happening, or launching the service command failed, then
- // launch the elevated updater.exe as we do without the service.
+ // If an update was already happening, launch the elevated updater.exe.
// We don't launch the elevated updater in the case that we did have
- // write access all along because in that case the only reason we're
- // using the service is because we are testing.
- if (!useService && !noServiceFallback &&
- updateLockFileHandle == INVALID_HANDLE_VALUE) {
+ // write access all along because in that case we are testing.
+ if (updateLockFileHandle == INVALID_HANDLE_VALUE) {
SHELLEXECUTEINFO sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
@@ -3301,32 +3076,21 @@ int NS_main(int argc, NS_tchar **argv)
if (argc > callbackIndex) {
LaunchCallbackApp(argv[5], argc - callbackIndex,
- argv + callbackIndex, sUsingService);
+ argv + callbackIndex);
}
CloseHandle(elevatedFileHandle);
- if (!useService && !noServiceFallback &&
- INVALID_HANDLE_VALUE == updateLockFileHandle) {
- // We didn't use the service and we did run the elevated updater.exe.
+ if (INVALID_HANDLE_VALUE == updateLockFileHandle) {
+ // We ran the elevated updater.exe.
// The elevated updater.exe is responsible for writing out the
// update.status file.
return 0;
- } else if (useService) {
- // The service command was launched. The service is responsible for
- // writing out the update.status file.
- if (updateLockFileHandle != INVALID_HANDLE_VALUE) {
- CloseHandle(updateLockFileHandle);
- }
- return 0;
} else {
- // Otherwise the service command was not launched at all.
// We are only reaching this code path because we had write access
// all along to the directory and a fallback key existed, and we
- // have fallback disabled (MOZ_NO_SERVICE_FALLBACK env var exists).
- // We only currently use this env var from XPCShell tests.
+ // have fallback disabled.
CloseHandle(updateLockFileHandle);
- WriteStatusFile(lastFallbackError);
return 0;
}
}
@@ -3386,7 +3150,7 @@ int NS_main(int argc, NS_tchar **argv)
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
if (argc > callbackIndex) {
LaunchCallbackApp(argv[5], argc - callbackIndex,
- argv + callbackIndex, sUsingService);
+ argv + callbackIndex);
}
return 1;
}
@@ -3440,8 +3204,7 @@ int NS_main(int argc, NS_tchar **argv)
if (argc > callbackIndex) {
LaunchCallbackApp(argv[5],
argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ argv + callbackIndex);
}
return 1;
}
@@ -3504,8 +3267,7 @@ int NS_main(int argc, NS_tchar **argv)
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
LaunchCallbackApp(argv[callbackIndex],
argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ argv + callbackIndex);
return 1;
}
@@ -3553,8 +3315,7 @@ int NS_main(int argc, NS_tchar **argv)
EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 1);
LaunchCallbackApp(argv[5],
argc - callbackIndex,
- argv + callbackIndex,
- sUsingService);
+ argv + callbackIndex);
return 1;
}
LOG(("NS_main: callback app file in use, continuing without " \