mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-21 14:47:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
488
toolkit/mozapps/update/UpdateTelemetry.jsm
Normal file
488
toolkit/mozapps/update/UpdateTelemetry.jsm
Normal file
|
|
@ -0,0 +1,488 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"AUSTLMY"
|
||||
];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm", this);
|
||||
|
||||
this.AUSTLMY = {
|
||||
// Telemetry for the application update background update check occurs when
|
||||
// the background update timer fires after the update interval which is
|
||||
// determined by the app.update.interval preference and its telemetry
|
||||
// histogram IDs have the suffix '_NOTIFY'.
|
||||
// Telemetry for the externally initiated background update check occurs when
|
||||
// a call is made to |checkForBackgroundUpdates| which is typically initiated
|
||||
// by an application when it has determined that the application should have
|
||||
// received an update. This has separate telemetry so it is possible to
|
||||
// analyze using the telemetry data systems that have not been updating when
|
||||
// they should have.
|
||||
|
||||
// The update check was performed by the call to checkForBackgroundUpdates in
|
||||
// nsUpdateService.js.
|
||||
EXTERNAL: "EXTERNAL",
|
||||
// The update check was performed by the call to notify in nsUpdateService.js.
|
||||
NOTIFY: "NOTIFY",
|
||||
|
||||
/**
|
||||
* Values for the UPDATE_CHECK_CODE_NOTIFY and UPDATE_CHECK_CODE_EXTERNAL
|
||||
* Telemetry histograms.
|
||||
*/
|
||||
// No update found (no notification)
|
||||
CHK_NO_UPDATE_FOUND: 0,
|
||||
// Update will be downloaded in the background (background download)
|
||||
CHK_DOWNLOAD_UPDATE: 1,
|
||||
// Showing prompt due to the update.xml specifying showPrompt
|
||||
// (update notification)
|
||||
CHK_SHOWPROMPT_SNIPPET: 2,
|
||||
// Showing prompt due to preference (update notification)
|
||||
CHK_SHOWPROMPT_PREF: 3,
|
||||
// Already has an active update in progress (no notification)
|
||||
CHK_HAS_ACTIVEUPDATE: 8,
|
||||
// A background download is already in progress (no notification)
|
||||
CHK_IS_DOWNLOADING: 9,
|
||||
// An update is already staged (no notification)
|
||||
CHK_IS_STAGED: 10,
|
||||
// An update is already downloaded (no notification)
|
||||
CHK_IS_DOWNLOADED: 11,
|
||||
// Background checks disabled by preference (no notification)
|
||||
CHK_PREF_DISABLED: 12,
|
||||
// Update checks disabled by admin locked preference (no notification)
|
||||
CHK_ADMIN_DISABLED: 13,
|
||||
// Unable to check for updates per hasUpdateMutex() (no notification)
|
||||
CHK_NO_MUTEX: 14,
|
||||
// Unable to check for updates per gCanCheckForUpdates (no notification). This
|
||||
// should be covered by other codes and is recorded just in case.
|
||||
CHK_UNABLE_TO_CHECK: 15,
|
||||
// Background checks disabled for the current session (no notification)
|
||||
CHK_DISABLED_FOR_SESSION: 16,
|
||||
// Unable to perform a background check while offline (no notification)
|
||||
CHK_OFFLINE: 17,
|
||||
// Note: codes 18 - 21 were removed along with the certificate checking code.
|
||||
// General update check failure and threshold reached
|
||||
// (check failure notification)
|
||||
CHK_GENERAL_ERROR_PROMPT: 22,
|
||||
// General update check failure and threshold not reached (no notification)
|
||||
CHK_GENERAL_ERROR_SILENT: 23,
|
||||
// No compatible update found though there were updates (no notification)
|
||||
CHK_NO_COMPAT_UPDATE_FOUND: 24,
|
||||
// Update found for a previous version (no notification)
|
||||
CHK_UPDATE_PREVIOUS_VERSION: 25,
|
||||
// Update found for a version with the never preference set (no notification)
|
||||
CHK_UPDATE_NEVER_PREF: 26,
|
||||
// Update found without a type attribute (no notification)
|
||||
CHK_UPDATE_INVALID_TYPE: 27,
|
||||
// The system is no longer supported (system unsupported notification)
|
||||
CHK_UNSUPPORTED: 28,
|
||||
// Unable to apply updates (manual install to update notification)
|
||||
CHK_UNABLE_TO_APPLY: 29,
|
||||
// Unable to check for updates due to no OS version (no notification)
|
||||
CHK_NO_OS_VERSION: 30,
|
||||
// Unable to check for updates due to no OS ABI (no notification)
|
||||
CHK_NO_OS_ABI: 31,
|
||||
// Invalid url for app.update.url default preference (no notification)
|
||||
CHK_INVALID_DEFAULT_URL: 32,
|
||||
// Update elevation failures or cancelations threshold reached for this
|
||||
// version, OSX only (no notification)
|
||||
CHK_ELEVATION_DISABLED_FOR_VERSION: 35,
|
||||
// User opted out of elevated updates for the available update version, OSX
|
||||
// only (no notification)
|
||||
CHK_ELEVATION_OPTOUT_FOR_VERSION: 36,
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for the update check result code or a telemetry
|
||||
* ping for a count type histogram count when no update was found. The no
|
||||
* update found ping is separate since it is the typical result, is less
|
||||
* interesting than the other result codes, and it is easier to analyze the
|
||||
* other codes without including it.
|
||||
*
|
||||
* @param aSuffix
|
||||
* The histogram id suffix for histogram IDs:
|
||||
* UPDATE_CHECK_CODE_EXTERNAL
|
||||
* UPDATE_CHECK_CODE_NOTIFY
|
||||
* UPDATE_CHECK_NO_UPDATE_EXTERNAL
|
||||
* UPDATE_CHECK_NO_UPDATE_NOTIFY
|
||||
* @param aCode
|
||||
* An integer value as defined by the values that start with CHK_ in
|
||||
* the above section.
|
||||
*/
|
||||
pingCheckCode: function UT_pingCheckCode(aSuffix, aCode) {
|
||||
try {
|
||||
if (aCode == this.CHK_NO_UPDATE_FOUND) {
|
||||
let id = "UPDATE_CHECK_NO_UPDATE_" + aSuffix;
|
||||
// count type histogram
|
||||
Services.telemetry.getHistogramById(id).add();
|
||||
} else {
|
||||
let id = "UPDATE_CHECK_CODE_" + aSuffix;
|
||||
// enumerated type histogram
|
||||
Services.telemetry.getHistogramById(id).add(aCode);
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for a failed update check's unhandled error code
|
||||
* when the pingCheckCode is CHK_GENERAL_ERROR_SILENT. The histogram is a
|
||||
* keyed count type with key names that are prefixed with 'AUS_CHECK_EX_ERR_'.
|
||||
*
|
||||
* @param aSuffix
|
||||
* The histogram id suffix for histogram IDs:
|
||||
* UPDATE_CHK_EXTENDED_ERROR_EXTERNAL
|
||||
* UPDATE_CHK_EXTENDED_ERROR_NOTIFY
|
||||
* @param aCode
|
||||
* The extended error value return by a failed update check.
|
||||
*/
|
||||
pingCheckExError: function UT_pingCheckExError(aSuffix, aCode) {
|
||||
try {
|
||||
let id = "UPDATE_CHECK_EXTENDED_ERROR_" + aSuffix;
|
||||
let val = "AUS_CHECK_EX_ERR_" + aCode;
|
||||
// keyed count type histogram
|
||||
Services.telemetry.getKeyedHistogramById(id).add(val);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
// The state code and if present the status error code were read on startup.
|
||||
STARTUP: "STARTUP",
|
||||
// The state code and status error code if present were read after staging.
|
||||
STAGE: "STAGE",
|
||||
|
||||
// Patch type Complete
|
||||
PATCH_COMPLETE: "COMPLETE",
|
||||
// Patch type partial
|
||||
PATCH_PARTIAL: "PARTIAL",
|
||||
// Patch type unknown
|
||||
PATCH_UNKNOWN: "UNKNOWN",
|
||||
|
||||
/**
|
||||
* Values for the UPDATE_DOWNLOAD_CODE_COMPLETE and
|
||||
* UPDATE_DOWNLOAD_CODE_PARTIAL Telemetry histograms.
|
||||
*/
|
||||
DWNLD_SUCCESS: 0,
|
||||
DWNLD_RETRY_OFFLINE: 1,
|
||||
DWNLD_RETRY_NET_TIMEOUT: 2,
|
||||
DWNLD_RETRY_CONNECTION_REFUSED: 3,
|
||||
DWNLD_RETRY_NET_RESET: 4,
|
||||
DWNLD_ERR_NO_UPDATE: 5,
|
||||
DWNLD_ERR_NO_UPDATE_PATCH: 6,
|
||||
DWNLD_ERR_NO_PATCH_FILE: 7,
|
||||
DWNLD_ERR_PATCH_SIZE_LARGER: 8,
|
||||
DWNLD_ERR_PATCH_SIZE_NOT_EQUAL: 9,
|
||||
DWNLD_ERR_BINDING_ABORTED: 10,
|
||||
DWNLD_ERR_ABORT: 11,
|
||||
DWNLD_ERR_DOCUMENT_NOT_CACHED: 12,
|
||||
DWNLD_ERR_VERIFY_NO_REQUEST: 13,
|
||||
DWNLD_ERR_VERIFY_PATCH_SIZE_NOT_EQUAL: 14,
|
||||
DWNLD_ERR_VERIFY_NO_HASH_MATCH: 15,
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for the update download result code.
|
||||
*
|
||||
* @param aIsComplete
|
||||
* If true the histogram is for a patch type complete, if false the
|
||||
* histogram is for a patch type partial, and when undefined the
|
||||
* histogram is for an unknown patch type. This is used to determine
|
||||
* the histogram ID out of the following histogram IDs:
|
||||
* UPDATE_DOWNLOAD_CODE_COMPLETE
|
||||
* UPDATE_DOWNLOAD_CODE_PARTIAL
|
||||
* @param aCode
|
||||
* An integer value as defined by the values that start with DWNLD_ in
|
||||
* the above section.
|
||||
*/
|
||||
pingDownloadCode: function UT_pingDownloadCode(aIsComplete, aCode) {
|
||||
let patchType = this.PATCH_UNKNOWN;
|
||||
if (aIsComplete === true) {
|
||||
patchType = this.PATCH_COMPLETE;
|
||||
} else if (aIsComplete === false) {
|
||||
patchType = this.PATCH_PARTIAL;
|
||||
}
|
||||
try {
|
||||
let id = "UPDATE_DOWNLOAD_CODE_" + patchType;
|
||||
// enumerated type histogram
|
||||
Services.telemetry.getHistogramById(id).add(aCode);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for the update status state code.
|
||||
*
|
||||
* @param aSuffix
|
||||
* The histogram id suffix for histogram IDs:
|
||||
* UPDATE_STATE_CODE_COMPLETE_STARTUP
|
||||
* UPDATE_STATE_CODE_PARTIAL_STARTUP
|
||||
* UPDATE_STATE_CODE_UNKNOWN_STARTUP
|
||||
* UPDATE_STATE_CODE_COMPLETE_STAGE
|
||||
* UPDATE_STATE_CODE_PARTIAL_STAGE
|
||||
* UPDATE_STATE_CODE_UNKNOWN_STAGE
|
||||
* @param aCode
|
||||
* An integer value as defined by the values that start with STATE_ in
|
||||
* the above section for the update state from the update.status file.
|
||||
*/
|
||||
pingStateCode: function UT_pingStateCode(aSuffix, aCode) {
|
||||
try {
|
||||
let id = "UPDATE_STATE_CODE_" + aSuffix;
|
||||
// enumerated type histogram
|
||||
Services.telemetry.getHistogramById(id).add(aCode);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for the update status error code. This does not
|
||||
* submit a success value which can be determined from the state code.
|
||||
*
|
||||
* @param aSuffix
|
||||
* The histogram id suffix for histogram IDs:
|
||||
* UPDATE_STATUS_ERROR_CODE_COMPLETE_STARTUP
|
||||
* UPDATE_STATUS_ERROR_CODE_PARTIAL_STARTUP
|
||||
* UPDATE_STATUS_ERROR_CODE_UNKNOWN_STARTUP
|
||||
* UPDATE_STATUS_ERROR_CODE_COMPLETE_STAGE
|
||||
* UPDATE_STATUS_ERROR_CODE_PARTIAL_STAGE
|
||||
* UPDATE_STATUS_ERROR_CODE_UNKNOWN_STAGE
|
||||
* @param aCode
|
||||
* An integer value for the error code from the update.status file.
|
||||
*/
|
||||
pingStatusErrorCode: function UT_pingStatusErrorCode(aSuffix, aCode) {
|
||||
try {
|
||||
let id = "UPDATE_STATUS_ERROR_CODE_" + aSuffix;
|
||||
// enumerated type histogram
|
||||
Services.telemetry.getHistogramById(id).add(aCode);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit the interval in days since the last notification for this background
|
||||
* update check or a boolean if the last notification is in the future.
|
||||
*
|
||||
* @param aSuffix
|
||||
* The histogram id suffix for histogram IDs:
|
||||
* UPDATE_INVALID_LASTUPDATETIME_EXTERNAL
|
||||
* UPDATE_INVALID_LASTUPDATETIME_NOTIFY
|
||||
* UPDATE_LAST_NOTIFY_INTERVAL_DAYS_EXTERNAL
|
||||
* UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY
|
||||
*/
|
||||
pingLastUpdateTime: function UT_pingLastUpdateTime(aSuffix) {
|
||||
const PREF_APP_UPDATE_LASTUPDATETIME = "app.update.lastUpdateTime.background-update-timer";
|
||||
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_LASTUPDATETIME)) {
|
||||
let lastUpdateTimeSeconds = Services.prefs.getIntPref(PREF_APP_UPDATE_LASTUPDATETIME);
|
||||
if (lastUpdateTimeSeconds) {
|
||||
let currentTimeSeconds = Math.round(Date.now() / 1000);
|
||||
if (lastUpdateTimeSeconds > currentTimeSeconds) {
|
||||
try {
|
||||
let id = "UPDATE_INVALID_LASTUPDATETIME_" + aSuffix;
|
||||
// count type histogram
|
||||
Services.telemetry.getHistogramById(id).add();
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
} else {
|
||||
let intervalDays = (currentTimeSeconds - lastUpdateTimeSeconds) /
|
||||
(60 * 60 * 24);
|
||||
try {
|
||||
let id = "UPDATE_LAST_NOTIFY_INTERVAL_DAYS_" + aSuffix;
|
||||
// exponential type histogram
|
||||
Services.telemetry.getHistogramById(id).add(intervalDays);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for the last page displayed by the update wizard.
|
||||
*
|
||||
* @param aPageID
|
||||
* The page id for the last page displayed.
|
||||
*/
|
||||
pingWizLastPageCode: function UT_pingWizLastPageCode(aPageID) {
|
||||
let pageMap = { invalid: 0,
|
||||
dummy: 1,
|
||||
checking: 2,
|
||||
pluginupdatesfound: 3,
|
||||
noupdatesfound: 4,
|
||||
manualUpdate: 5,
|
||||
unsupported: 6,
|
||||
updatesfoundbasic: 8,
|
||||
updatesfoundbillboard: 9,
|
||||
downloading: 12,
|
||||
errors: 13,
|
||||
errorextra: 14,
|
||||
errorpatching: 15,
|
||||
finished: 16,
|
||||
finishedBackground: 17,
|
||||
installed: 18 };
|
||||
try {
|
||||
let id = "UPDATE_WIZ_LAST_PAGE_CODE";
|
||||
// enumerated type histogram
|
||||
Services.telemetry.getHistogramById(id).add(pageMap[aPageID] ||
|
||||
pageMap.invalid);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for a boolean type histogram that indicates if the
|
||||
* service is installed and a telemetry ping for a boolean type histogram that
|
||||
* indicates if the service was at some point installed and is now
|
||||
* uninstalled.
|
||||
*
|
||||
* @param aSuffix
|
||||
* The histogram id suffix for histogram IDs:
|
||||
* UPDATE_SERVICE_INSTALLED_EXTERNAL
|
||||
* UPDATE_SERVICE_INSTALLED_NOTIFY
|
||||
* UPDATE_SERVICE_MANUALLY_UNINSTALLED_EXTERNAL
|
||||
* UPDATE_SERVICE_MANUALLY_UNINSTALLED_NOTIFY
|
||||
* @param aInstalled
|
||||
* Whether the service is installed.
|
||||
*/
|
||||
pingServiceInstallStatus: function UT_PSIS(aSuffix, aInstalled) {
|
||||
// Report the error but don't throw since it is more important to
|
||||
// successfully update than to throw.
|
||||
if (!("@mozilla.org/windows-registry-key;1" in Cc)) {
|
||||
Cu.reportError(Cr.NS_ERROR_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let id = "UPDATE_SERVICE_INSTALLED_" + aSuffix;
|
||||
// boolean type histogram
|
||||
Services.telemetry.getHistogramById(id).add(aInstalled);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
let attempted = 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);
|
||||
// Was the service at some point installed, but is now uninstalled?
|
||||
attempted = wrk.readIntValue("Attempted");
|
||||
wrk.close();
|
||||
} catch (e) {
|
||||
// Since this will throw if the registry key doesn't exist (e.g. the
|
||||
// service has never been installed) don't report an error.
|
||||
}
|
||||
|
||||
try {
|
||||
let id = "UPDATE_SERVICE_MANUALLY_UNINSTALLED_" + aSuffix;
|
||||
if (!aInstalled && attempted) {
|
||||
// count type histogram
|
||||
Services.telemetry.getHistogramById(id).add();
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for a count type histogram when the expected value
|
||||
* does not equal the boolean value of a pref or if the pref isn't present
|
||||
* when the expected value does not equal default value. This lessens the
|
||||
* amount of data submitted to telemetry.
|
||||
*
|
||||
* @param aID
|
||||
* The histogram ID to report to.
|
||||
* @param aPref
|
||||
* The preference to check.
|
||||
* @param aDefault
|
||||
* The default value when the preference isn't present.
|
||||
* @param aExpected (optional)
|
||||
* If specified and the value is the same as the value that will be
|
||||
* added the value won't be added to telemetry.
|
||||
*/
|
||||
pingBoolPref: function UT_pingBoolPref(aID, aPref, aDefault, aExpected) {
|
||||
try {
|
||||
let val = aDefault;
|
||||
if (Services.prefs.getPrefType(aPref) != Ci.nsIPrefBranch.PREF_INVALID) {
|
||||
val = Services.prefs.getBoolPref(aPref);
|
||||
}
|
||||
if (val != aExpected) {
|
||||
// count type histogram
|
||||
Services.telemetry.getHistogramById(aID).add();
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for a histogram with the integer value of a
|
||||
* preference when it is not the expected value or the default value when it
|
||||
* is not the expected value. This lessens the amount of data submitted to
|
||||
* telemetry.
|
||||
*
|
||||
* @param aID
|
||||
* The histogram ID to report to.
|
||||
* @param aPref
|
||||
* The preference to check.
|
||||
* @param aDefault
|
||||
* The default value when the pref is not set.
|
||||
* @param aExpected (optional)
|
||||
* If specified and the value is the same as the value that will be
|
||||
* added the value won't be added to telemetry.
|
||||
*/
|
||||
pingIntPref: function UT_pingIntPref(aID, aPref, aDefault, aExpected) {
|
||||
try {
|
||||
let val = aDefault;
|
||||
if (Services.prefs.getPrefType(aPref) != Ci.nsIPrefBranch.PREF_INVALID) {
|
||||
val = Services.prefs.getIntPref(aPref);
|
||||
}
|
||||
if (aExpected === undefined || val != aExpected) {
|
||||
// enumerated or exponential type histogram
|
||||
Services.telemetry.getHistogramById(aID).add(val);
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for all histogram types that take a single
|
||||
* parameter to the telemetry add function and the count type histogram when
|
||||
* the aExpected parameter is specified. If the aExpected parameter is
|
||||
* specified and it equals the value specified by the aValue
|
||||
* parameter the telemetry submission will be skipped.
|
||||
*
|
||||
* @param aID
|
||||
* The histogram ID to report to.
|
||||
* @param aValue
|
||||
* The value to add when aExpected is not defined or the value to
|
||||
* check if it is equal to when aExpected is defined.
|
||||
* @param aExpected (optional)
|
||||
* If specified and the value is the same as the value specified by
|
||||
* aValue parameter the submission will be skipped.
|
||||
*/
|
||||
pingGeneric: function UT_pingGeneric(aID, aValue, aExpected) {
|
||||
try {
|
||||
if (aExpected === undefined) {
|
||||
Services.telemetry.getHistogramById(aID).add(aValue);
|
||||
} else if (aValue != aExpected) {
|
||||
// count type histogram
|
||||
Services.telemetry.getHistogramById(aID).add();
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
Object.freeze(AUSTLMY);
|
||||
12
toolkit/mozapps/update/common-standalone/moz.build
Normal file
12
toolkit/mozapps/update/common-standalone/moz.build
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Library('updatecommon-standalone')
|
||||
|
||||
srcdir = '../common'
|
||||
|
||||
include('../common/sources.mozbuild')
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
USE_STATIC_LIBS = True
|
||||
250
toolkit/mozapps/update/common/certificatecheck.cpp
Normal file
250
toolkit/mozapps/update/common/certificatecheck.cpp
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <softpub.h>
|
||||
#include <wintrust.h>
|
||||
|
||||
#include "certificatecheck.h"
|
||||
#include "updatecommon.h"
|
||||
|
||||
static const int ENCODING = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
||||
|
||||
/**
|
||||
* Checks to see if a file stored at filePath matches the specified info.
|
||||
*
|
||||
* @param filePath The PE file path to check
|
||||
* @param infoToMatch The acceptable information to match
|
||||
* @return ERROR_SUCCESS if successful, ERROR_NOT_FOUND if the info
|
||||
* does not match, or the last error otherwise.
|
||||
*/
|
||||
DWORD
|
||||
CheckCertificateForPEFile(LPCWSTR filePath,
|
||||
CertificateCheckInfo &infoToMatch)
|
||||
{
|
||||
HCERTSTORE certStore = nullptr;
|
||||
HCRYPTMSG cryptMsg = nullptr;
|
||||
PCCERT_CONTEXT certContext = nullptr;
|
||||
PCMSG_SIGNER_INFO signerInfo = nullptr;
|
||||
DWORD lastError = ERROR_SUCCESS;
|
||||
|
||||
// Get the HCERTSTORE and HCRYPTMSG from the signed file.
|
||||
DWORD encoding, contentType, formatType;
|
||||
BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
|
||||
filePath,
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
|
||||
CERT_QUERY_CONTENT_FLAG_ALL,
|
||||
0, &encoding, &contentType,
|
||||
&formatType, &certStore, &cryptMsg, nullptr);
|
||||
if (!result) {
|
||||
lastError = GetLastError();
|
||||
LOG_WARN(("CryptQueryObject failed. (%d)", lastError));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Pass in nullptr to get the needed signer information size.
|
||||
DWORD signerInfoSize;
|
||||
result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
|
||||
nullptr, &signerInfoSize);
|
||||
if (!result) {
|
||||
lastError = GetLastError();
|
||||
LOG_WARN(("CryptMsgGetParam failed. (%d)", lastError));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Allocate the needed size for the signer information.
|
||||
signerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, signerInfoSize);
|
||||
if (!signerInfo) {
|
||||
lastError = GetLastError();
|
||||
LOG_WARN(("Unable to allocate memory for Signer Info. (%d)", lastError));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get the signer information (PCMSG_SIGNER_INFO).
|
||||
// In particular we want the issuer and serial number.
|
||||
result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0,
|
||||
(PVOID)signerInfo, &signerInfoSize);
|
||||
if (!result) {
|
||||
lastError = GetLastError();
|
||||
LOG_WARN(("CryptMsgGetParam failed. (%d)", lastError));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Search for the signer certificate in the certificate store.
|
||||
CERT_INFO certInfo;
|
||||
certInfo.Issuer = signerInfo->Issuer;
|
||||
certInfo.SerialNumber = signerInfo->SerialNumber;
|
||||
certContext = CertFindCertificateInStore(certStore, ENCODING, 0,
|
||||
CERT_FIND_SUBJECT_CERT,
|
||||
(PVOID)&certInfo, nullptr);
|
||||
if (!certContext) {
|
||||
lastError = GetLastError();
|
||||
LOG_WARN(("CertFindCertificateInStore failed. (%d)", lastError));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!DoCertificateAttributesMatch(certContext, infoToMatch)) {
|
||||
lastError = ERROR_NOT_FOUND;
|
||||
LOG_WARN(("Certificate did not match issuer or name. (%d)", lastError));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (signerInfo) {
|
||||
LocalFree(signerInfo);
|
||||
}
|
||||
if (certContext) {
|
||||
CertFreeCertificateContext(certContext);
|
||||
}
|
||||
if (certStore) {
|
||||
CertCloseStore(certStore, 0);
|
||||
}
|
||||
if (cryptMsg) {
|
||||
CryptMsgClose(cryptMsg);
|
||||
}
|
||||
return lastError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a file stored at filePath matches the specified info.
|
||||
*
|
||||
* @param certContext The certificate context of the file
|
||||
* @param infoToMatch The acceptable information to match
|
||||
* @return FALSE if the info does not match or if any error occurs in the check
|
||||
*/
|
||||
BOOL
|
||||
DoCertificateAttributesMatch(PCCERT_CONTEXT certContext,
|
||||
CertificateCheckInfo &infoToMatch)
|
||||
{
|
||||
DWORD dwData;
|
||||
LPWSTR szName = nullptr;
|
||||
|
||||
if (infoToMatch.issuer) {
|
||||
// Pass in nullptr to get the needed size of the issuer buffer.
|
||||
dwData = CertGetNameString(certContext,
|
||||
CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||||
CERT_NAME_ISSUER_FLAG, nullptr,
|
||||
nullptr, 0);
|
||||
|
||||
if (!dwData) {
|
||||
LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Allocate memory for Issuer name buffer.
|
||||
szName = (LPWSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
|
||||
if (!szName) {
|
||||
LOG_WARN(("Unable to allocate memory for issuer name. (%d)",
|
||||
GetLastError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get Issuer name.
|
||||
if (!CertGetNameStringW(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||||
CERT_NAME_ISSUER_FLAG, nullptr, szName, dwData)) {
|
||||
LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
|
||||
LocalFree(szName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If the issuer does not match, return a failure.
|
||||
if (!infoToMatch.issuer ||
|
||||
wcscmp(szName, infoToMatch.issuer)) {
|
||||
LocalFree(szName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LocalFree(szName);
|
||||
szName = nullptr;
|
||||
}
|
||||
|
||||
if (infoToMatch.name) {
|
||||
// Pass in nullptr to get the needed size of the name buffer.
|
||||
dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE,
|
||||
0, nullptr, nullptr, 0);
|
||||
if (!dwData) {
|
||||
LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Allocate memory for the name buffer.
|
||||
szName = (LPWSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR));
|
||||
if (!szName) {
|
||||
LOG_WARN(("Unable to allocate memory for subject name. (%d)",
|
||||
GetLastError()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Obtain the name.
|
||||
if (!(CertGetNameStringW(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
|
||||
nullptr, szName, dwData))) {
|
||||
LOG_WARN(("CertGetNameString failed. (%d)", GetLastError()));
|
||||
LocalFree(szName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If the issuer does not match, return a failure.
|
||||
if (!infoToMatch.name ||
|
||||
wcscmp(szName, infoToMatch.name)) {
|
||||
LocalFree(szName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// We have a match!
|
||||
LocalFree(szName);
|
||||
}
|
||||
|
||||
// If there were any errors we would have aborted by now.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the trust of the specified file path.
|
||||
*
|
||||
* @param filePath The file path to check.
|
||||
* @return ERROR_SUCCESS if successful, or the last error code otherwise.
|
||||
*/
|
||||
DWORD
|
||||
VerifyCertificateTrustForFile(LPCWSTR filePath)
|
||||
{
|
||||
// Setup the file to check.
|
||||
WINTRUST_FILE_INFO fileToCheck;
|
||||
ZeroMemory(&fileToCheck, sizeof(fileToCheck));
|
||||
fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
|
||||
fileToCheck.pcwszFilePath = filePath;
|
||||
|
||||
// Setup what to check, we want to check it is signed and trusted.
|
||||
WINTRUST_DATA trustData;
|
||||
ZeroMemory(&trustData, sizeof(trustData));
|
||||
trustData.cbStruct = sizeof(trustData);
|
||||
trustData.pPolicyCallbackData = nullptr;
|
||||
trustData.pSIPClientData = nullptr;
|
||||
trustData.dwUIChoice = WTD_UI_NONE;
|
||||
trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
|
||||
trustData.dwUnionChoice = WTD_CHOICE_FILE;
|
||||
trustData.dwStateAction = 0;
|
||||
trustData.hWVTStateData = nullptr;
|
||||
trustData.pwszURLReference = nullptr;
|
||||
// no UI
|
||||
trustData.dwUIContext = 0;
|
||||
trustData.pFile = &fileToCheck;
|
||||
|
||||
GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
||||
// Check if the file is signed by something that is trusted.
|
||||
LONG ret = WinVerifyTrust(nullptr, &policyGUID, &trustData);
|
||||
if (ERROR_SUCCESS == ret) {
|
||||
// The hash that represents the subject is trusted and there were no
|
||||
// verification errors. No publisher nor time stamp chain errors.
|
||||
LOG(("The file \"%ls\" is signed and the signature was verified.",
|
||||
filePath));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD lastError = GetLastError();
|
||||
LOG_WARN(("There was an error validating trust of the certificate for file"
|
||||
" \"%ls\". Returned: %d. (%d)", filePath, ret, lastError));
|
||||
return ret;
|
||||
}
|
||||
22
toolkit/mozapps/update/common/certificatecheck.h
Normal file
22
toolkit/mozapps/update/common/certificatecheck.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _CERTIFICATECHECK_H_
|
||||
#define _CERTIFICATECHECK_H_
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
struct CertificateCheckInfo
|
||||
{
|
||||
LPCWSTR name;
|
||||
LPCWSTR issuer;
|
||||
};
|
||||
|
||||
BOOL DoCertificateAttributesMatch(PCCERT_CONTEXT pCertContext,
|
||||
CertificateCheckInfo &infoToMatch);
|
||||
DWORD VerifyCertificateTrustForFile(LPCWSTR filePath);
|
||||
DWORD CheckCertificateForPEFile(LPCWSTR filePath,
|
||||
CertificateCheckInfo &infoToMatch);
|
||||
|
||||
#endif
|
||||
110
toolkit/mozapps/update/common/errors.h
Normal file
110
toolkit/mozapps/update/common/errors.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef Errors_h__
|
||||
#define Errors_h__
|
||||
|
||||
#define OK 0
|
||||
|
||||
// Error codes that are no longer used should not be used again unless they
|
||||
// aren't used in client code (e.g. nsUpdateService.js, updates.js,
|
||||
// UpdatePrompt.js, etc.).
|
||||
|
||||
#define MAR_ERROR_EMPTY_ACTION_LIST 1
|
||||
#define LOADSOURCE_ERROR_WRONG_SIZE 2
|
||||
|
||||
// Error codes 3-16 are for general update problems.
|
||||
#define USAGE_ERROR 3
|
||||
#define CRC_ERROR 4
|
||||
#define PARSE_ERROR 5
|
||||
#define READ_ERROR 6
|
||||
#define WRITE_ERROR 7
|
||||
// #define UNEXPECTED_ERROR 8 // Replaced with errors 38-42
|
||||
#define ELEVATION_CANCELED 9
|
||||
#define READ_STRINGS_MEM_ERROR 10
|
||||
#define ARCHIVE_READER_MEM_ERROR 11
|
||||
#define BSPATCH_MEM_ERROR 12
|
||||
#define UPDATER_MEM_ERROR 13
|
||||
#define UPDATER_QUOTED_PATH_MEM_ERROR 14
|
||||
#define BAD_ACTION_ERROR 15
|
||||
#define STRING_CONVERSION_ERROR 16
|
||||
|
||||
// Error codes 17-23 are related to security tasks for MAR
|
||||
// signing and MAR protection.
|
||||
#define CERT_LOAD_ERROR 17
|
||||
#define CERT_HANDLING_ERROR 18
|
||||
#define CERT_VERIFY_ERROR 19
|
||||
#define ARCHIVE_NOT_OPEN 20
|
||||
#define COULD_NOT_READ_PRODUCT_INFO_BLOCK_ERROR 21
|
||||
#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
|
||||
#define WRITE_ERROR_CALLBACK_APP 37
|
||||
#define UNEXPECTED_BZIP_ERROR 39
|
||||
#define UNEXPECTED_MAR_ERROR 40
|
||||
#define UNEXPECTED_BSPATCH_ERROR 41
|
||||
#define UNEXPECTED_FILE_OPERATION_ERROR 42
|
||||
#define FILESYSTEM_MOUNT_READWRITE_ERROR 43
|
||||
#define DELETE_ERROR_EXPECTED_DIR 46
|
||||
#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
|
||||
#define WRITE_ERROR_PATCH_FILE 64
|
||||
#define WRITE_ERROR_APPLY_DIR_PATH 65
|
||||
#define WRITE_ERROR_CALLBACK_PATH 66
|
||||
#define WRITE_ERROR_FILE_ACCESS_DENIED 67
|
||||
#define WRITE_ERROR_DIR_ACCESS_DENIED 68
|
||||
#define WRITE_ERROR_DELETE_BACKUP 69
|
||||
#define WRITE_ERROR_EXTRACT 70
|
||||
#define REMOVE_FILE_SPEC_ERROR 71
|
||||
#define INVALID_APPLYTO_DIR_STAGED_ERROR 72
|
||||
#define LOCK_ERROR_PATCH_FILE 73
|
||||
#define INVALID_APPLYTO_DIR_ERROR 74
|
||||
#define INVALID_INSTALL_DIR_PATH_ERROR 75
|
||||
#define INVALID_WORKING_DIR_PATH_ERROR 76
|
||||
#define INVALID_CALLBACK_PATH_ERROR 77
|
||||
#define INVALID_CALLBACK_DIR_ERROR 78
|
||||
|
||||
// Error codes 80 through 99 are reserved for nsUpdateService.js
|
||||
|
||||
// The following error codes are only used by updater.exe
|
||||
// when a fallback key exists for tests.
|
||||
#define FALLBACKKEY_UNKNOWN_ERROR 100
|
||||
#define FALLBACKKEY_REGPATH_ERROR 101
|
||||
#define FALLBACKKEY_NOKEY_ERROR 102
|
||||
#define FALLBACKKEY_SERVICE_NO_STOP_ERROR 103
|
||||
#define FALLBACKKEY_LAUNCH_ERROR 104
|
||||
|
||||
#endif // Errors_h__
|
||||
32
toolkit/mozapps/update/common/moz.build
Normal file
32
toolkit/mozapps/update/common/moz.build
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS += [
|
||||
'readstrings.h',
|
||||
'updatecommon.h',
|
||||
'updatedefines.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
EXPORTS += [
|
||||
'pathhash.h',
|
||||
'uachelper.h',
|
||||
'updatehelper.cpp',
|
||||
'updatehelper.h',
|
||||
]
|
||||
if CONFIG['MOZ_MAINTENANCE_SERVICE']:
|
||||
EXPORTS += [
|
||||
'certificatecheck.h',
|
||||
'registrycertificates.h',
|
||||
]
|
||||
|
||||
Library('updatecommon')
|
||||
|
||||
DEFINES['NS_NO_XPCOM'] = True
|
||||
|
||||
srcdir = '.'
|
||||
|
||||
include('sources.mozbuild')
|
||||
139
toolkit/mozapps/update/common/pathhash.cpp
Normal file
139
toolkit/mozapps/update/common/pathhash.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include "pathhash.h"
|
||||
|
||||
|
||||
/**
|
||||
* Converts a binary sequence into a hex string
|
||||
*
|
||||
* @param hash The binary data sequence
|
||||
* @param hashSize The size of the binary data sequence
|
||||
* @param hexString A buffer to store the hex string, must be of
|
||||
* size 2 * @hashSize
|
||||
*/
|
||||
static void
|
||||
BinaryDataToHexString(const BYTE *hash, DWORD &hashSize,
|
||||
LPWSTR hexString)
|
||||
{
|
||||
WCHAR *p = hexString;
|
||||
for (DWORD i = 0; i < hashSize; ++i) {
|
||||
wsprintfW(p, L"%.2x", hash[i]);
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates an MD5 hash for the given input binary data
|
||||
*
|
||||
* @param data Any sequence of bytes
|
||||
* @param dataSize The number of bytes inside @data
|
||||
* @param hash Output buffer to store hash, must be freed by the caller
|
||||
* @param hashSize The number of bytes in the output buffer
|
||||
* @return TRUE on success
|
||||
*/
|
||||
static BOOL
|
||||
CalculateMD5(const char *data, DWORD dataSize,
|
||||
BYTE **hash, DWORD &hashSize)
|
||||
{
|
||||
HCRYPTPROV hProv = 0;
|
||||
HCRYPTHASH hHash = 0;
|
||||
|
||||
if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
if (NTE_BAD_KEYSET != GetLastError()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Maybe it doesn't exist, try to create it.
|
||||
if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(data),
|
||||
dataSize, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD dwCount = sizeof(DWORD);
|
||||
if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize,
|
||||
&dwCount, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*hash = new BYTE[hashSize];
|
||||
ZeroMemory(*hash, hashSize);
|
||||
if (!CryptGetHashParam(hHash, HP_HASHVAL, *hash, &hashSize, 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (hHash) {
|
||||
CryptDestroyHash(hHash);
|
||||
}
|
||||
|
||||
if (hProv) {
|
||||
CryptReleaseContext(hProv,0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a file path into a unique registry location for cert storage
|
||||
*
|
||||
* @param filePath The input file path to get a registry path from
|
||||
* @param registryPath A buffer to write the registry path to, must
|
||||
* be of size in WCHARs MAX_PATH + 1
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
BOOL
|
||||
CalculateRegistryPathFromFilePath(const LPCWSTR filePath,
|
||||
LPWSTR registryPath)
|
||||
{
|
||||
size_t filePathLen = wcslen(filePath);
|
||||
if (!filePathLen) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If the file path ends in a slash, ignore that character
|
||||
if (filePath[filePathLen -1] == L'\\' ||
|
||||
filePath[filePathLen - 1] == L'/') {
|
||||
filePathLen--;
|
||||
}
|
||||
|
||||
// Copy in the full path into our own buffer.
|
||||
// Copying in the extra slash is OK because we calculate the hash
|
||||
// based on the filePathLen which excludes the slash.
|
||||
// +2 to account for the possibly trailing slash and the null terminator.
|
||||
WCHAR *lowercasePath = new WCHAR[filePathLen + 2];
|
||||
memset(lowercasePath, 0, (filePathLen + 2) * sizeof(WCHAR));
|
||||
wcsncpy(lowercasePath, filePath, filePathLen + 1);
|
||||
_wcslwr(lowercasePath);
|
||||
|
||||
BYTE *hash;
|
||||
DWORD hashSize = 0;
|
||||
if (!CalculateMD5(reinterpret_cast<const char*>(lowercasePath),
|
||||
filePathLen * 2,
|
||||
&hash, hashSize)) {
|
||||
delete[] lowercasePath;
|
||||
return FALSE;
|
||||
}
|
||||
delete[] lowercasePath;
|
||||
|
||||
LPCWSTR baseRegPath = L"SOFTWARE\\Mozilla\\"
|
||||
L"MaintenanceService\\";
|
||||
wcsncpy(registryPath, baseRegPath, MAX_PATH);
|
||||
BinaryDataToHexString(hash, hashSize,
|
||||
registryPath + wcslen(baseRegPath));
|
||||
delete[] hash;
|
||||
return TRUE;
|
||||
}
|
||||
19
toolkit/mozapps/update/common/pathhash.h
Normal file
19
toolkit/mozapps/update/common/pathhash.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _PATHHASH_H_
|
||||
#define _PATHHASH_H_
|
||||
|
||||
/**
|
||||
* Converts a file path into a unique registry location for cert storage
|
||||
*
|
||||
* @param filePath The input file path to get a registry path from
|
||||
* @param registryPath A buffer to write the registry path to, must
|
||||
* be of size in WCHARs MAX_PATH + 1
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
BOOL CalculateRegistryPathFromFilePath(const LPCWSTR filePath,
|
||||
LPWSTR registryPath);
|
||||
|
||||
#endif
|
||||
236
toolkit/mozapps/update/common/readstrings.cpp
Normal file
236
toolkit/mozapps/update/common/readstrings.cpp
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "readstrings.h"
|
||||
#include "errors.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# define NS_tfopen _wfopen
|
||||
# define OPEN_MODE L"rb"
|
||||
#else
|
||||
# define NS_tfopen fopen
|
||||
# define OPEN_MODE "r"
|
||||
#endif
|
||||
|
||||
// stack based FILE wrapper to ensure that fclose is called.
|
||||
class AutoFILE {
|
||||
public:
|
||||
explicit AutoFILE(FILE *fp) : fp_(fp) {}
|
||||
~AutoFILE() { if (fp_) fclose(fp_); }
|
||||
operator FILE *() { return fp_; }
|
||||
private:
|
||||
FILE *fp_;
|
||||
};
|
||||
|
||||
class AutoCharArray {
|
||||
public:
|
||||
explicit AutoCharArray(size_t len) { ptr_ = new char[len]; }
|
||||
~AutoCharArray() { delete[] ptr_; }
|
||||
operator char *() { return ptr_; }
|
||||
private:
|
||||
char *ptr_;
|
||||
};
|
||||
|
||||
static const char kNL[] = "\r\n";
|
||||
static const char kEquals[] = "=";
|
||||
static const char kWhitespace[] = " \t";
|
||||
static const char kRBracket[] = "]";
|
||||
|
||||
static const char*
|
||||
NS_strspnp(const char *delims, const char *str)
|
||||
{
|
||||
const char *d;
|
||||
do {
|
||||
for (d = delims; *d != '\0'; ++d) {
|
||||
if (*str == *d) {
|
||||
++str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (*d);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static char*
|
||||
NS_strtok(const char *delims, char **str)
|
||||
{
|
||||
if (!*str)
|
||||
return nullptr;
|
||||
|
||||
char *ret = (char*) NS_strspnp(delims, *str);
|
||||
|
||||
if (!*ret) {
|
||||
*str = ret;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char *i = ret;
|
||||
do {
|
||||
for (const char *d = delims; *d != '\0'; ++d) {
|
||||
if (*i == *d) {
|
||||
*i = '\0';
|
||||
*str = ++i;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
} while (*i);
|
||||
|
||||
*str = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a key in a keyList containing zero-delimited keys ending with "\0\0".
|
||||
* Returns a zero-based index of the key in the list, or -1 if the key is not found.
|
||||
*/
|
||||
static int
|
||||
find_key(const char *keyList, char* key)
|
||||
{
|
||||
if (!keyList)
|
||||
return -1;
|
||||
|
||||
int index = 0;
|
||||
const char *p = keyList;
|
||||
while (*p)
|
||||
{
|
||||
if (strcmp(key, p) == 0)
|
||||
return index;
|
||||
|
||||
p += strlen(p) + 1;
|
||||
index++;
|
||||
}
|
||||
|
||||
// The key was not found if we came here
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very basic parser for updater.ini taken mostly from nsINIParser.cpp
|
||||
* that can be used by standalone apps.
|
||||
*
|
||||
* @param path Path to the .ini file to read
|
||||
* @param keyList List of zero-delimited keys ending with two zero characters
|
||||
* @param numStrings Number of strings to read into results buffer - must be equal to the number of keys
|
||||
* @param results Two-dimensional array of strings to be filled in the same order as the keys provided
|
||||
* @param section Optional name of the section to read; defaults to "Strings"
|
||||
*/
|
||||
int
|
||||
ReadStrings(const NS_tchar *path,
|
||||
const char *keyList,
|
||||
unsigned int numStrings,
|
||||
char results[][MAX_TEXT_LEN],
|
||||
const char *section)
|
||||
{
|
||||
AutoFILE fp(NS_tfopen(path, OPEN_MODE));
|
||||
|
||||
if (!fp)
|
||||
return READ_ERROR;
|
||||
|
||||
/* get file size */
|
||||
if (fseek(fp, 0, SEEK_END) != 0)
|
||||
return READ_ERROR;
|
||||
|
||||
long len = ftell(fp);
|
||||
if (len <= 0)
|
||||
return READ_ERROR;
|
||||
|
||||
size_t flen = size_t(len);
|
||||
AutoCharArray fileContents(flen + 1);
|
||||
if (!fileContents)
|
||||
return READ_STRINGS_MEM_ERROR;
|
||||
|
||||
/* read the file in one swoop */
|
||||
if (fseek(fp, 0, SEEK_SET) != 0)
|
||||
return READ_ERROR;
|
||||
|
||||
size_t rd = fread(fileContents, sizeof(char), flen, fp);
|
||||
if (rd != flen)
|
||||
return READ_ERROR;
|
||||
|
||||
fileContents[flen] = '\0';
|
||||
|
||||
char *buffer = fileContents;
|
||||
bool inStringsSection = false;
|
||||
|
||||
unsigned int read = 0;
|
||||
|
||||
while (char *token = NS_strtok(kNL, &buffer)) {
|
||||
if (token[0] == '#' || token[0] == ';') // it's a comment
|
||||
continue;
|
||||
|
||||
token = (char*) NS_strspnp(kWhitespace, token);
|
||||
if (!*token) // empty line
|
||||
continue;
|
||||
|
||||
if (token[0] == '[') { // section header!
|
||||
++token;
|
||||
char const * currSection = token;
|
||||
|
||||
char *rb = NS_strtok(kRBracket, &token);
|
||||
if (!rb || NS_strtok(kWhitespace, &token)) {
|
||||
// there's either an unclosed [Section or a [Section]Moretext!
|
||||
// we could frankly decide that this INI file is malformed right
|
||||
// here and stop, but we won't... keep going, looking for
|
||||
// a well-formed [section] to continue working with
|
||||
inStringsSection = false;
|
||||
}
|
||||
else {
|
||||
if (section)
|
||||
inStringsSection = strcmp(currSection, section) == 0;
|
||||
else
|
||||
inStringsSection = strcmp(currSection, "Strings") == 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!inStringsSection) {
|
||||
// If we haven't found a section header (or we found a malformed
|
||||
// section header), or this isn't the [Strings] section don't bother
|
||||
// parsing this line.
|
||||
continue;
|
||||
}
|
||||
|
||||
char *key = token;
|
||||
char *e = NS_strtok(kEquals, &token);
|
||||
if (!e)
|
||||
continue;
|
||||
|
||||
int keyIndex = find_key(keyList, key);
|
||||
if (keyIndex >= 0 && (unsigned int)keyIndex < numStrings)
|
||||
{
|
||||
strncpy(results[keyIndex], token, MAX_TEXT_LEN - 1);
|
||||
results[keyIndex][MAX_TEXT_LEN - 1] = '\0';
|
||||
read++;
|
||||
}
|
||||
}
|
||||
|
||||
return (read == numStrings) ? OK : PARSE_ERROR;
|
||||
}
|
||||
|
||||
// A wrapper function to read strings for the updater.
|
||||
// Added for compatibility with the original code.
|
||||
int
|
||||
ReadStrings(const NS_tchar *path, StringTable *results)
|
||||
{
|
||||
const unsigned int kNumStrings = 2;
|
||||
const char *kUpdaterKeys = "Title\0Info\0";
|
||||
char updater_strings[kNumStrings][MAX_TEXT_LEN];
|
||||
|
||||
int result = ReadStrings(path, kUpdaterKeys, kNumStrings, updater_strings);
|
||||
|
||||
strncpy(results->title, updater_strings[0], MAX_TEXT_LEN - 1);
|
||||
results->title[MAX_TEXT_LEN - 1] = '\0';
|
||||
strncpy(results->info, updater_strings[1], MAX_TEXT_LEN - 1);
|
||||
results->info[MAX_TEXT_LEN - 1] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
43
toolkit/mozapps/update/common/readstrings.h
Normal file
43
toolkit/mozapps/update/common/readstrings.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef READSTRINGS_H__
|
||||
#define READSTRINGS_H__
|
||||
|
||||
#define MAX_TEXT_LEN 600
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include <windows.h>
|
||||
typedef WCHAR NS_tchar;
|
||||
#else
|
||||
typedef char NS_tchar;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
struct StringTable
|
||||
{
|
||||
char title[MAX_TEXT_LEN];
|
||||
char info[MAX_TEXT_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* This function reads in localized strings from updater.ini
|
||||
*/
|
||||
int ReadStrings(const NS_tchar *path, StringTable *results);
|
||||
|
||||
/**
|
||||
* This function reads in localized strings corresponding to the keys from a given .ini
|
||||
*/
|
||||
int ReadStrings(const NS_tchar *path,
|
||||
const char *keyList,
|
||||
unsigned int numStrings,
|
||||
char results[][MAX_TEXT_LEN],
|
||||
const char *section = nullptr);
|
||||
|
||||
#endif // READSTRINGS_H__
|
||||
154
toolkit/mozapps/update/common/registrycertificates.cpp
Normal file
154
toolkit/mozapps/update/common/registrycertificates.cpp
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "registrycertificates.h"
|
||||
#include "pathhash.h"
|
||||
#include "updatecommon.h"
|
||||
#include "updatehelper.h"
|
||||
#define MAX_KEY_LENGTH 255
|
||||
|
||||
/**
|
||||
* Verifies if the file path matches any certificate stored in the registry.
|
||||
*
|
||||
* @param filePath The file path of the application to check if allowed.
|
||||
* @param allowFallbackKeySkip when this is TRUE the fallback registry key will
|
||||
* be used to skip the certificate check. This is the default since the
|
||||
* fallback registry key is located under HKEY_LOCAL_MACHINE which can't be
|
||||
* written to by a low integrity process.
|
||||
* Note: the maintenance service binary can be used to perform this check for
|
||||
* testing or troubleshooting.
|
||||
* @return TRUE if the binary matches any of the allowed certificates.
|
||||
*/
|
||||
BOOL
|
||||
DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate, LPCWSTR filePath,
|
||||
BOOL allowFallbackKeySkip)
|
||||
{
|
||||
WCHAR maintenanceServiceKey[MAX_PATH + 1];
|
||||
if (!CalculateRegistryPathFromFilePath(basePathForUpdate,
|
||||
maintenanceServiceKey)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// We use KEY_WOW64_64KEY to always force 64-bit view.
|
||||
// The user may have both x86 and x64 applications installed
|
||||
// which each register information. We need a consistent place
|
||||
// to put those certificate attributes in and hence why we always
|
||||
// force the non redirected registry under Wow6432Node.
|
||||
// This flag is ignored on 32bit systems.
|
||||
HKEY baseKey;
|
||||
LONG retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
maintenanceServiceKey, 0,
|
||||
KEY_READ | KEY_WOW64_64KEY, &baseKey);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not open key. (%d)", retCode));
|
||||
// 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.
|
||||
retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
TEST_ONLY_FALLBACK_KEY_PATH, 0,
|
||||
KEY_READ | KEY_WOW64_64KEY, &baseKey);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not open fallback key. (%d)", retCode));
|
||||
return FALSE;
|
||||
} else if (allowFallbackKeySkip) {
|
||||
LOG_WARN(("Fallback key present, skipping VerifyCertificateTrustForFile "
|
||||
"check and the certificate attribute registry matching "
|
||||
"check."));
|
||||
RegCloseKey(baseKey);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the number of subkeys.
|
||||
DWORD subkeyCount = 0;
|
||||
retCode = RegQueryInfoKeyW(baseKey, nullptr, nullptr, nullptr, &subkeyCount,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not query info key. (%d)", retCode));
|
||||
RegCloseKey(baseKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Enumerate the subkeys, each subkey represents an allowed certificate.
|
||||
for (DWORD i = 0; i < subkeyCount; i++) {
|
||||
WCHAR subkeyBuffer[MAX_KEY_LENGTH];
|
||||
DWORD subkeyBufferCount = MAX_KEY_LENGTH;
|
||||
retCode = RegEnumKeyExW(baseKey, i, subkeyBuffer,
|
||||
&subkeyBufferCount, nullptr,
|
||||
nullptr, nullptr, nullptr);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not enum certs. (%d)", retCode));
|
||||
RegCloseKey(baseKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Open the subkey for the current certificate
|
||||
HKEY subKey;
|
||||
retCode = RegOpenKeyExW(baseKey,
|
||||
subkeyBuffer,
|
||||
0,
|
||||
KEY_READ | KEY_WOW64_64KEY,
|
||||
&subKey);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not open subkey. (%d)", retCode));
|
||||
continue; // Try the next subkey
|
||||
}
|
||||
|
||||
const int MAX_CHAR_COUNT = 256;
|
||||
DWORD valueBufSize = MAX_CHAR_COUNT * sizeof(WCHAR);
|
||||
WCHAR name[MAX_CHAR_COUNT] = { L'\0' };
|
||||
WCHAR issuer[MAX_CHAR_COUNT] = { L'\0' };
|
||||
|
||||
// Get the name from the registry
|
||||
retCode = RegQueryValueExW(subKey, L"name", 0, nullptr,
|
||||
(LPBYTE)name, &valueBufSize);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not obtain name from registry. (%d)", retCode));
|
||||
RegCloseKey(subKey);
|
||||
continue; // Try the next subkey
|
||||
}
|
||||
|
||||
// Get the issuer from the registry
|
||||
valueBufSize = MAX_CHAR_COUNT * sizeof(WCHAR);
|
||||
retCode = RegQueryValueExW(subKey, L"issuer", 0, nullptr,
|
||||
(LPBYTE)issuer, &valueBufSize);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Could not obtain issuer from registry. (%d)", retCode));
|
||||
RegCloseKey(subKey);
|
||||
continue; // Try the next subkey
|
||||
}
|
||||
|
||||
CertificateCheckInfo allowedCertificate = {
|
||||
name,
|
||||
issuer,
|
||||
};
|
||||
|
||||
retCode = CheckCertificateForPEFile(filePath, allowedCertificate);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Error on certificate check. (%d)", retCode));
|
||||
RegCloseKey(subKey);
|
||||
continue; // Try the next subkey
|
||||
}
|
||||
|
||||
retCode = VerifyCertificateTrustForFile(filePath);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
LOG_WARN(("Error on certificate trust check. (%d)", retCode));
|
||||
RegCloseKey(subKey);
|
||||
continue; // Try the next subkey
|
||||
}
|
||||
|
||||
RegCloseKey(baseKey);
|
||||
// Raise the roof, we found a match!
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RegCloseKey(baseKey);
|
||||
// No certificates match, :'(
|
||||
return FALSE;
|
||||
}
|
||||
14
toolkit/mozapps/update/common/registrycertificates.h
Normal file
14
toolkit/mozapps/update/common/registrycertificates.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _REGISTRYCERTIFICATES_H_
|
||||
#define _REGISTRYCERTIFICATES_H_
|
||||
|
||||
#include "certificatecheck.h"
|
||||
|
||||
BOOL DoesBinaryMatchAllowedCertificates(LPCWSTR basePathForUpdate,
|
||||
LPCWSTR filePath,
|
||||
BOOL allowFallbackKeySkip = TRUE);
|
||||
|
||||
#endif
|
||||
28
toolkit/mozapps/update/common/sources.mozbuild
Normal file
28
toolkit/mozapps/update/common/sources.mozbuild
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
sources = []
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
sources += [
|
||||
'pathhash.cpp',
|
||||
'uachelper.cpp',
|
||||
'updatehelper.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_MAINTENANCE_SERVICE']:
|
||||
sources += [
|
||||
'certificatecheck.cpp',
|
||||
'registrycertificates.cpp',
|
||||
]
|
||||
OS_LIBS += [
|
||||
'crypt32',
|
||||
'wintrust',
|
||||
]
|
||||
|
||||
sources += [
|
||||
'readstrings.cpp',
|
||||
'updatecommon.cpp',
|
||||
]
|
||||
|
||||
SOURCES += sorted(['%s/%s' % (srcdir, s) for s in sources])
|
||||
222
toolkit/mozapps/update/common/uachelper.cpp
Normal file
222
toolkit/mozapps/update/common/uachelper.cpp
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include <wtsapi32.h>
|
||||
#include "uachelper.h"
|
||||
#include "updatecommon.h"
|
||||
|
||||
// See the MSDN documentation with title: Privilege Constants
|
||||
// At the time of this writing, this documentation is located at:
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb530716%28v=vs.85%29.aspx
|
||||
LPCTSTR UACHelper::PrivsToDisable[] = {
|
||||
SE_ASSIGNPRIMARYTOKEN_NAME,
|
||||
SE_AUDIT_NAME,
|
||||
SE_BACKUP_NAME,
|
||||
// CreateProcess will succeed but the app will fail to launch on some WinXP
|
||||
// machines if SE_CHANGE_NOTIFY_NAME is disabled. In particular this happens
|
||||
// for limited user accounts on those machines. The define is kept here as a
|
||||
// reminder that it should never be re-added.
|
||||
// This permission is for directory watching but also from MSDN: "This
|
||||
// privilege also causes the system to skip all traversal access checks."
|
||||
// SE_CHANGE_NOTIFY_NAME,
|
||||
SE_CREATE_GLOBAL_NAME,
|
||||
SE_CREATE_PAGEFILE_NAME,
|
||||
SE_CREATE_PERMANENT_NAME,
|
||||
SE_CREATE_SYMBOLIC_LINK_NAME,
|
||||
SE_CREATE_TOKEN_NAME,
|
||||
SE_DEBUG_NAME,
|
||||
SE_ENABLE_DELEGATION_NAME,
|
||||
SE_IMPERSONATE_NAME,
|
||||
SE_INC_BASE_PRIORITY_NAME,
|
||||
SE_INCREASE_QUOTA_NAME,
|
||||
SE_INC_WORKING_SET_NAME,
|
||||
SE_LOAD_DRIVER_NAME,
|
||||
SE_LOCK_MEMORY_NAME,
|
||||
SE_MACHINE_ACCOUNT_NAME,
|
||||
SE_MANAGE_VOLUME_NAME,
|
||||
SE_PROF_SINGLE_PROCESS_NAME,
|
||||
SE_RELABEL_NAME,
|
||||
SE_REMOTE_SHUTDOWN_NAME,
|
||||
SE_RESTORE_NAME,
|
||||
SE_SECURITY_NAME,
|
||||
SE_SHUTDOWN_NAME,
|
||||
SE_SYNC_AGENT_NAME,
|
||||
SE_SYSTEM_ENVIRONMENT_NAME,
|
||||
SE_SYSTEM_PROFILE_NAME,
|
||||
SE_SYSTEMTIME_NAME,
|
||||
SE_TAKE_OWNERSHIP_NAME,
|
||||
SE_TCB_NAME,
|
||||
SE_TIME_ZONE_NAME,
|
||||
SE_TRUSTED_CREDMAN_ACCESS_NAME,
|
||||
SE_UNDOCK_NAME,
|
||||
SE_UNSOLICITED_INPUT_NAME
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens a user token for the given session ID
|
||||
*
|
||||
* @param sessionID The session ID for the token to obtain
|
||||
* @return A handle to the token to obtain which will be primary if enough
|
||||
* permissions exist. Caller should close the handle.
|
||||
*/
|
||||
HANDLE
|
||||
UACHelper::OpenUserToken(DWORD sessionID)
|
||||
{
|
||||
HMODULE module = LoadLibraryW(L"wtsapi32.dll");
|
||||
HANDLE token = nullptr;
|
||||
decltype(WTSQueryUserToken)* wtsQueryUserToken =
|
||||
(decltype(WTSQueryUserToken)*) GetProcAddress(module, "WTSQueryUserToken");
|
||||
if (wtsQueryUserToken) {
|
||||
wtsQueryUserToken(sessionID, &token);
|
||||
}
|
||||
FreeLibrary(module);
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a linked token for the specified token.
|
||||
*
|
||||
* @param token The token to get the linked token from
|
||||
* @return A linked token or nullptr if one does not exist.
|
||||
* Caller should close the handle.
|
||||
*/
|
||||
HANDLE
|
||||
UACHelper::OpenLinkedToken(HANDLE token)
|
||||
{
|
||||
// Magic below...
|
||||
// UAC creates 2 tokens. One is the restricted token which we have.
|
||||
// the other is the UAC elevated one. Since we are running as a service
|
||||
// as the system account we have access to both.
|
||||
TOKEN_LINKED_TOKEN tlt;
|
||||
HANDLE hNewLinkedToken = nullptr;
|
||||
DWORD len;
|
||||
if (GetTokenInformation(token, (TOKEN_INFORMATION_CLASS)TokenLinkedToken,
|
||||
&tlt, sizeof(TOKEN_LINKED_TOKEN), &len)) {
|
||||
token = tlt.LinkedToken;
|
||||
hNewLinkedToken = token;
|
||||
}
|
||||
return hNewLinkedToken;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enables or disables a privilege for the specified token.
|
||||
*
|
||||
* @param token The token to adjust the privilege on.
|
||||
* @param priv The privilege to adjust.
|
||||
* @param enable Whether to enable or disable it
|
||||
* @return TRUE if the token was adjusted to the specified value.
|
||||
*/
|
||||
BOOL
|
||||
UACHelper::SetPrivilege(HANDLE token, LPCTSTR priv, BOOL enable)
|
||||
{
|
||||
LUID luidOfPriv;
|
||||
if (!LookupPrivilegeValue(nullptr, priv, &luidOfPriv)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TOKEN_PRIVILEGES tokenPriv;
|
||||
tokenPriv.PrivilegeCount = 1;
|
||||
tokenPriv.Privileges[0].Luid = luidOfPriv;
|
||||
tokenPriv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
if (!AdjustTokenPrivileges(token, false, &tokenPriv,
|
||||
sizeof(tokenPriv), nullptr, nullptr)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return GetLastError() == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each privilege that is specified, an attempt will be made to
|
||||
* drop the privilege.
|
||||
*
|
||||
* @param token The token to adjust the privilege on.
|
||||
* Pass nullptr for current token.
|
||||
* @param unneededPrivs An array of unneeded privileges.
|
||||
* @param count The size of the array
|
||||
* @return TRUE if there were no errors
|
||||
*/
|
||||
BOOL
|
||||
UACHelper::DisableUnneededPrivileges(HANDLE token,
|
||||
LPCTSTR *unneededPrivs,
|
||||
size_t count)
|
||||
{
|
||||
HANDLE obtainedToken = nullptr;
|
||||
if (!token) {
|
||||
// Note: This handle is a pseudo-handle and need not be closed
|
||||
HANDLE process = GetCurrentProcess();
|
||||
if (!OpenProcessToken(process, TOKEN_ALL_ACCESS_P, &obtainedToken)) {
|
||||
LOG_WARN(("Could not obtain token for current process, no "
|
||||
"privileges changed. (%d)", GetLastError()));
|
||||
return FALSE;
|
||||
}
|
||||
token = obtainedToken;
|
||||
}
|
||||
|
||||
BOOL result = TRUE;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (SetPrivilege(token, unneededPrivs[i], FALSE)) {
|
||||
LOG(("Disabled unneeded token privilege: %s.",
|
||||
unneededPrivs[i]));
|
||||
} else {
|
||||
LOG(("Could not disable token privilege value: %s. (%d)",
|
||||
unneededPrivs[i], GetLastError()));
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (obtainedToken) {
|
||||
CloseHandle(obtainedToken);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables privileges for the specified token.
|
||||
* The privileges to disable are in PrivsToDisable.
|
||||
* In the future there could be new privs and we are not sure if we should
|
||||
* explicitly disable these or not.
|
||||
*
|
||||
* @param token The token to drop the privilege on.
|
||||
* Pass nullptr for current token.
|
||||
* @return TRUE if there were no errors
|
||||
*/
|
||||
BOOL
|
||||
UACHelper::DisablePrivileges(HANDLE token)
|
||||
{
|
||||
static const size_t PrivsToDisableSize =
|
||||
sizeof(UACHelper::PrivsToDisable) / sizeof(UACHelper::PrivsToDisable[0]);
|
||||
|
||||
return DisableUnneededPrivileges(token, UACHelper::PrivsToDisable,
|
||||
PrivsToDisableSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user can elevate.
|
||||
*
|
||||
* @return true if the user can elevate.
|
||||
* false otherwise.
|
||||
*/
|
||||
bool
|
||||
UACHelper::CanUserElevate()
|
||||
{
|
||||
HANDLE token;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TOKEN_ELEVATION_TYPE elevationType;
|
||||
DWORD len;
|
||||
bool canElevate = GetTokenInformation(token, TokenElevationType,
|
||||
&elevationType,
|
||||
sizeof(elevationType), &len) &&
|
||||
(elevationType == TokenElevationTypeLimited);
|
||||
CloseHandle(token);
|
||||
|
||||
return canElevate;
|
||||
}
|
||||
23
toolkit/mozapps/update/common/uachelper.h
Normal file
23
toolkit/mozapps/update/common/uachelper.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _UACHELPER_H_
|
||||
#define _UACHELPER_H_
|
||||
|
||||
class UACHelper
|
||||
{
|
||||
public:
|
||||
static HANDLE OpenUserToken(DWORD sessionID);
|
||||
static HANDLE OpenLinkedToken(HANDLE token);
|
||||
static BOOL DisablePrivileges(HANDLE token);
|
||||
static bool CanUserElevate();
|
||||
|
||||
private:
|
||||
static BOOL SetPrivilege(HANDLE token, LPCTSTR privs, BOOL enable);
|
||||
static BOOL DisableUnneededPrivileges(HANDLE token,
|
||||
LPCTSTR *unneededPrivs, size_t count);
|
||||
static LPCTSTR PrivsToDisable[];
|
||||
};
|
||||
|
||||
#endif
|
||||
213
toolkit/mozapps/update/common/updatecommon.cpp
Normal file
213
toolkit/mozapps/update/common/updatecommon.cpp
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "updatecommon.h"
|
||||
|
||||
UpdateLog::UpdateLog() : logFP(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateLog::Init(NS_tchar* sourcePath,
|
||||
const NS_tchar* fileName)
|
||||
{
|
||||
if (logFP) {
|
||||
return;
|
||||
}
|
||||
|
||||
int dstFilePathLen = NS_tsnprintf(mDstFilePath,
|
||||
sizeof(mDstFilePath)/sizeof(mDstFilePath[0]),
|
||||
NS_T("%s/%s"), sourcePath, fileName);
|
||||
// If the destination path was over the length limit,
|
||||
// disable logging by skipping opening the file and setting logFP.
|
||||
if ((dstFilePathLen > 0) &&
|
||||
(dstFilePathLen <
|
||||
static_cast<int>(sizeof(mDstFilePath)/sizeof(mDstFilePath[0])))) {
|
||||
#ifdef XP_WIN
|
||||
if (GetTempFileNameW(sourcePath, L"log", 0, mTmpFilePath) != 0) {
|
||||
logFP = NS_tfopen(mTmpFilePath, NS_T("w"));
|
||||
|
||||
// Delete this file now so it is possible to tell from the unelevated
|
||||
// updater process if the elevated updater process has written the log.
|
||||
DeleteFileW(mDstFilePath);
|
||||
}
|
||||
#elif XP_MACOSX
|
||||
logFP = NS_tfopen(mDstFilePath, NS_T("w"));
|
||||
#else
|
||||
// On platforms that have an updates directory in the installation directory
|
||||
// (e.g. platforms other than Windows and Mac) the update log is written to
|
||||
// a temporary file and then to the update log file. This is needed since
|
||||
// the installation directory is moved during a replace request. This can be
|
||||
// removed when the platform's updates directory is located outside of the
|
||||
// installation directory.
|
||||
logFP = tmpfile();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateLog::Finish()
|
||||
{
|
||||
if (!logFP) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(XP_WIN) && !defined(XP_MACOSX)
|
||||
const int blockSize = 1024;
|
||||
char buffer[blockSize];
|
||||
fflush(logFP);
|
||||
rewind(logFP);
|
||||
|
||||
FILE *updateLogFP = NS_tfopen(mDstFilePath, NS_T("wb+"));
|
||||
while (!feof(logFP)) {
|
||||
size_t read = fread(buffer, 1, blockSize, logFP);
|
||||
if (ferror(logFP)) {
|
||||
fclose(logFP);
|
||||
logFP = nullptr;
|
||||
fclose(updateLogFP);
|
||||
updateLogFP = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t written = 0;
|
||||
|
||||
while (written < read) {
|
||||
size_t chunkWritten = fwrite(buffer, 1, read - written, updateLogFP);
|
||||
if (chunkWritten <= 0) {
|
||||
fclose(logFP);
|
||||
logFP = nullptr;
|
||||
fclose(updateLogFP);
|
||||
updateLogFP = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
written += chunkWritten;
|
||||
}
|
||||
}
|
||||
fclose(updateLogFP);
|
||||
updateLogFP = nullptr;
|
||||
#endif
|
||||
|
||||
fclose(logFP);
|
||||
logFP = nullptr;
|
||||
|
||||
#ifdef XP_WIN
|
||||
// When the log file already exists then the elevated updater has already
|
||||
// written the log file and the temp file for the log should be discarded.
|
||||
if (!NS_taccess(mDstFilePath, F_OK)) {
|
||||
DeleteFileW(mTmpFilePath);
|
||||
} else {
|
||||
MoveFileW(mTmpFilePath, mDstFilePath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpdateLog::Flush()
|
||||
{
|
||||
if (!logFP) {
|
||||
return;
|
||||
}
|
||||
|
||||
fflush(logFP);
|
||||
}
|
||||
|
||||
void UpdateLog::Printf(const char *fmt, ... )
|
||||
{
|
||||
if (!logFP) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(logFP, fmt, ap);
|
||||
fprintf(logFP, "\n");
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void UpdateLog::WarnPrintf(const char *fmt, ... )
|
||||
{
|
||||
if (!logFP) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fprintf(logFP, "*** Warning: ");
|
||||
vfprintf(logFP, fmt, ap);
|
||||
fprintf(logFP, "***\n");
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs checks of a full path for validity for this application.
|
||||
*
|
||||
* @param origFullPath
|
||||
* The full path to check.
|
||||
* @return true if the path is valid for this application and false otherwise.
|
||||
*/
|
||||
bool
|
||||
IsValidFullPath(NS_tchar* origFullPath)
|
||||
{
|
||||
// Subtract 1 from MAXPATHLEN for null termination.
|
||||
if (NS_tstrlen(origFullPath) > MAXPATHLEN - 1) {
|
||||
// The path is longer than acceptable for this application.
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
NS_tchar testPath[MAXPATHLEN] = {NS_T('\0')};
|
||||
// GetFullPathNameW will replace / with \ which PathCanonicalizeW requires.
|
||||
if (GetFullPathNameW(origFullPath, MAXPATHLEN, testPath, nullptr) == 0) {
|
||||
// Unable to get the full name for the path (e.g. invalid path).
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_tchar canonicalPath[MAXPATHLEN] = {NS_T('\0')};
|
||||
if (!PathCanonicalizeW(canonicalPath, testPath)) {
|
||||
// Path could not be canonicalized (e.g. invalid path).
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the path passed in resolves to a differerent path.
|
||||
if (NS_tstricmp(origFullPath, canonicalPath) != 0) {
|
||||
// Case insensitive string comparison between the supplied path and the
|
||||
// canonical path are not equal. This will prevent directory traversal and
|
||||
// the use of / in paths since they are converted to \.
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_tstrncpy(testPath, origFullPath, MAXPATHLEN);
|
||||
if (!PathStripToRootW(testPath)) {
|
||||
// It should always be possible to strip a valid path to its root.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (origFullPath[0] == NS_T('\\')) {
|
||||
// Only allow UNC server share paths.
|
||||
if (!PathIsUNCServerShareW(testPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Only allow full paths.
|
||||
if (origFullPath[0] != NS_T('/')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The path must not traverse directories
|
||||
if (NS_tstrstr(origFullPath, NS_T("..")) != nullptr ||
|
||||
NS_tstrstr(origFullPath, NS_T("./")) != nullptr) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
47
toolkit/mozapps/update/common/updatecommon.h
Normal file
47
toolkit/mozapps/update/common/updatecommon.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef UPDATECOMMON_H
|
||||
#define UPDATECOMMON_H
|
||||
|
||||
#include "updatedefines.h"
|
||||
#include <stdio.h>
|
||||
|
||||
class UpdateLog
|
||||
{
|
||||
public:
|
||||
static UpdateLog & GetPrimaryLog()
|
||||
{
|
||||
static UpdateLog primaryLog;
|
||||
return primaryLog;
|
||||
}
|
||||
|
||||
void Init(NS_tchar* sourcePath, const NS_tchar* fileName);
|
||||
void Finish();
|
||||
void Flush();
|
||||
void Printf(const char *fmt, ... );
|
||||
void WarnPrintf(const char *fmt, ... );
|
||||
|
||||
~UpdateLog()
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
|
||||
protected:
|
||||
UpdateLog();
|
||||
FILE *logFP;
|
||||
NS_tchar mTmpFilePath[MAXPATHLEN];
|
||||
NS_tchar mDstFilePath[MAXPATHLEN];
|
||||
};
|
||||
|
||||
bool IsValidFullPath(NS_tchar* fullPath);
|
||||
|
||||
#define LOG_WARN(args) UpdateLog::GetPrimaryLog().WarnPrintf args
|
||||
#define LOG(args) UpdateLog::GetPrimaryLog().Printf args
|
||||
#define LogInit(PATHNAME_, FILENAME_) \
|
||||
UpdateLog::GetPrimaryLog().Init(PATHNAME_, FILENAME_)
|
||||
#define LogFinish() UpdateLog::GetPrimaryLog().Finish()
|
||||
#define LogFlush() UpdateLog::GetPrimaryLog().Flush()
|
||||
|
||||
#endif
|
||||
142
toolkit/mozapps/update/common/updatedefines.h
Normal file
142
toolkit/mozapps/update/common/updatedefines.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef UPDATEDEFINES_H
|
||||
#define UPDATEDEFINES_H
|
||||
|
||||
#include "readstrings.h"
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# elif defined(MAX_PATH)
|
||||
# define MAXPATHLEN MAX_PATH
|
||||
# elif defined(_MAX_PATH)
|
||||
# define MAXPATHLEN _MAX_PATH
|
||||
# elif defined(CCHMAXPATH)
|
||||
# define MAXPATHLEN CCHMAXPATH
|
||||
# else
|
||||
# define MAXPATHLEN 1024
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include <windows.h>
|
||||
# include <shlwapi.h>
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# include <stdio.h>
|
||||
# include <stdarg.h>
|
||||
|
||||
# ifndef F_OK
|
||||
# define F_OK 00
|
||||
# endif
|
||||
# ifndef W_OK
|
||||
# define W_OK 02
|
||||
# endif
|
||||
# ifndef R_OK
|
||||
# define R_OK 04
|
||||
# endif
|
||||
# define S_ISDIR(s) (((s) & _S_IFMT) == _S_IFDIR)
|
||||
# define S_ISREG(s) (((s) & _S_IFMT) == _S_IFREG)
|
||||
|
||||
# define access _access
|
||||
|
||||
# define putenv _putenv
|
||||
# if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# define stat _stat
|
||||
# endif
|
||||
# define DELETE_DIR L"tobedeleted"
|
||||
# define CALLBACK_BACKUP_EXT L".moz-callback"
|
||||
|
||||
# define LOG_S "%S"
|
||||
# define NS_T(str) L ## str
|
||||
# define NS_SLASH NS_T('\\')
|
||||
|
||||
static inline int mywcsprintf(WCHAR* dest, size_t count, const WCHAR* fmt, ...)
|
||||
{
|
||||
size_t _count = count - 1;
|
||||
va_list varargs;
|
||||
va_start(varargs, fmt);
|
||||
int result = _vsnwprintf(dest, count - 1, fmt, varargs);
|
||||
va_end(varargs);
|
||||
dest[_count] = L'\0';
|
||||
return result;
|
||||
}
|
||||
#define NS_tsnprintf mywcsprintf
|
||||
# define NS_taccess _waccess
|
||||
# define NS_tchdir _wchdir
|
||||
# define NS_tchmod _wchmod
|
||||
# define NS_tfopen _wfopen
|
||||
# define NS_tmkdir(path, perms) _wmkdir(path)
|
||||
# define NS_tremove _wremove
|
||||
// _wrename is used to avoid the link tracking service.
|
||||
# define NS_trename _wrename
|
||||
# define NS_trmdir _wrmdir
|
||||
# define NS_tstat _wstat
|
||||
# define NS_tlstat _wstat // No symlinks on Windows
|
||||
# define NS_tstat_t _stat
|
||||
# define NS_tstrcat wcscat
|
||||
# define NS_tstrcmp wcscmp
|
||||
# define NS_tstricmp wcsicmp
|
||||
# define NS_tstrcpy wcscpy
|
||||
# define NS_tstrncpy wcsncpy
|
||||
# define NS_tstrlen wcslen
|
||||
# define NS_tstrchr wcschr
|
||||
# define NS_tstrrchr wcsrchr
|
||||
# define NS_tstrstr wcsstr
|
||||
# include "win_dirent.h"
|
||||
# define NS_tDIR DIR
|
||||
# define NS_tdirent dirent
|
||||
# define NS_topendir opendir
|
||||
# define NS_tclosedir closedir
|
||||
# define NS_treaddir readdir
|
||||
#else
|
||||
# include <sys/wait.h>
|
||||
# include <unistd.h>
|
||||
|
||||
#ifdef SOLARIS
|
||||
# include <sys/stat.h>
|
||||
#else
|
||||
# include <fts.h>
|
||||
#endif
|
||||
# include <dirent.h>
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
# define LOG_S "%s"
|
||||
# define NS_T(str) str
|
||||
# define NS_SLASH NS_T('/')
|
||||
# define NS_tsnprintf snprintf
|
||||
# define NS_taccess access
|
||||
# define NS_tchdir chdir
|
||||
# define NS_tchmod chmod
|
||||
# define NS_tfopen fopen
|
||||
# define NS_tmkdir mkdir
|
||||
# define NS_tremove remove
|
||||
# define NS_trename rename
|
||||
# define NS_trmdir rmdir
|
||||
# define NS_tstat stat
|
||||
# define NS_tstat_t stat
|
||||
# define NS_tlstat lstat
|
||||
# define NS_tstrcat strcat
|
||||
# define NS_tstrcmp strcmp
|
||||
# define NS_tstricmp strcasecmp
|
||||
# define NS_tstrcpy strcpy
|
||||
# define NS_tstrncpy strncpy
|
||||
# define NS_tstrlen strlen
|
||||
# define NS_tstrrchr strrchr
|
||||
# define NS_tstrstr strstr
|
||||
# define NS_tDIR DIR
|
||||
# define NS_tdirent dirent
|
||||
# define NS_topendir opendir
|
||||
# define NS_tclosedir closedir
|
||||
# define NS_treaddir readdir
|
||||
#endif
|
||||
|
||||
#define BACKUP_EXT NS_T(".moz-backup")
|
||||
|
||||
#endif
|
||||
609
toolkit/mozapps/update/common/updatehelper.cpp
Normal file
609
toolkit/mozapps/update/common/updatehelper.cpp
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Needed for CreateToolhelp32Snapshot
|
||||
#include <tlhelp32.h>
|
||||
#ifndef ONLY_SERVICE_LAUNCHING
|
||||
|
||||
#include <stdio.h>
|
||||
#include "shlobj.h"
|
||||
#include "updatehelper.h"
|
||||
#include "uachelper.h"
|
||||
#include "pathhash.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
// Needed for PathAppendW
|
||||
#include <shlwapi.h>
|
||||
|
||||
using mozilla::MakeUnique;
|
||||
using mozilla::UniquePtr;
|
||||
|
||||
BOOL PathAppendSafe(LPWSTR base, LPCWSTR extra);
|
||||
BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer,
|
||||
LPCWSTR siblingFilePath,
|
||||
LPCWSTR newFileName);
|
||||
|
||||
/**
|
||||
* Obtains the path of a file in the same directory as the specified file.
|
||||
*
|
||||
* @param destinationBuffer A buffer of size MAX_PATH + 1 to store the result.
|
||||
* @param siblingFIlePath The path of another file in the same directory
|
||||
* @param newFileName The filename of another file in the same directory
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
BOOL
|
||||
PathGetSiblingFilePath(LPWSTR destinationBuffer,
|
||||
LPCWSTR siblingFilePath,
|
||||
LPCWSTR newFileName)
|
||||
{
|
||||
if (wcslen(siblingFilePath) >= MAX_PATH) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wcsncpy(destinationBuffer, siblingFilePath, MAX_PATH);
|
||||
if (!PathRemoveFileSpecW(destinationBuffer)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (wcslen(destinationBuffer) + wcslen(newFileName) >= MAX_PATH) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return PathAppendSafe(destinationBuffer, newFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the upgrade process for update of the service if it is
|
||||
* already installed.
|
||||
*
|
||||
* @param installDir the installation directory where
|
||||
* maintenanceservice_installer.exe is located.
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
BOOL
|
||||
StartServiceUpdate(LPCWSTR installDir)
|
||||
{
|
||||
// Get a handle to the local computer SCM database
|
||||
SC_HANDLE manager = OpenSCManager(nullptr, nullptr,
|
||||
SC_MANAGER_ALL_ACCESS);
|
||||
if (!manager) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Open the service
|
||||
SC_HANDLE svc = OpenServiceW(manager, SVC_NAME,
|
||||
SERVICE_ALL_ACCESS);
|
||||
if (!svc) {
|
||||
CloseServiceHandle(manager);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 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.
|
||||
UniquePtr<char[]> serviceConfigBuffer = MakeUnique<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 cmdLine[64] = { '\0' };
|
||||
wcsncpy(cmdLine, L"dummyparam.exe upgrade",
|
||||
sizeof(cmdLine) / sizeof(cmdLine[0]) - 1);
|
||||
BOOL svcUpdateProcessStarted = CreateProcessW(tmpService,
|
||||
cmdLine,
|
||||
nullptr, nullptr, FALSE,
|
||||
0,
|
||||
nullptr, installDir, &si, &pi);
|
||||
if (svcUpdateProcessStarted) {
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
return svcUpdateProcessStarted;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Executes a maintenance service command
|
||||
*
|
||||
* @param argc The total number of arguments in argv
|
||||
* @param argv An array of null terminated strings to pass to the service,
|
||||
* @return ERROR_SUCCESS if the service command was started.
|
||||
* Less than 16000, a windows system error code from StartServiceW
|
||||
* More than 20000, 20000 + the last state of the service constant if
|
||||
* the last state is something other than stopped.
|
||||
* 17001 if the SCM could not be opened
|
||||
* 17002 if the service could not be opened
|
||||
*/
|
||||
DWORD
|
||||
StartServiceCommand(int argc, LPCWSTR* argv)
|
||||
{
|
||||
DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
|
||||
if (lastState != SERVICE_STOPPED) {
|
||||
return 20000 + lastState;
|
||||
}
|
||||
|
||||
// Get a handle to the SCM database.
|
||||
SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
|
||||
SC_MANAGER_CONNECT |
|
||||
SC_MANAGER_ENUMERATE_SERVICE);
|
||||
if (!serviceManager) {
|
||||
return 17001;
|
||||
}
|
||||
|
||||
// Get a handle to the service.
|
||||
SC_HANDLE service = OpenServiceW(serviceManager,
|
||||
SVC_NAME,
|
||||
SERVICE_START);
|
||||
if (!service) {
|
||||
CloseServiceHandle(serviceManager);
|
||||
return 17002;
|
||||
}
|
||||
|
||||
// Wait at most 5 seconds trying to start the service in case of errors
|
||||
// like ERROR_SERVICE_DATABASE_LOCKED or ERROR_SERVICE_REQUEST_TIMEOUT.
|
||||
const DWORD maxWaitMS = 5000;
|
||||
DWORD currentWaitMS = 0;
|
||||
DWORD lastError = ERROR_SUCCESS;
|
||||
while (currentWaitMS < maxWaitMS) {
|
||||
BOOL result = StartServiceW(service, argc, argv);
|
||||
if (result) {
|
||||
lastError = ERROR_SUCCESS;
|
||||
break;
|
||||
} else {
|
||||
lastError = GetLastError();
|
||||
}
|
||||
Sleep(100);
|
||||
currentWaitMS += 100;
|
||||
}
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(serviceManager);
|
||||
return lastError;
|
||||
}
|
||||
|
||||
#ifndef ONLY_SERVICE_LAUNCHING
|
||||
|
||||
/**
|
||||
* Launch a service initiated action for a software update with the
|
||||
* specified arguments.
|
||||
*
|
||||
* @param exePath The path of the executable to run
|
||||
* @param argc The total number of arguments in argv
|
||||
* @param argv An array of null terminated strings to pass to the exePath,
|
||||
* argv[0] must be the path to the updater.exe
|
||||
* @return ERROR_SUCCESS if successful
|
||||
*/
|
||||
DWORD
|
||||
LaunchServiceSoftwareUpdateCommand(int argc, LPCWSTR* argv)
|
||||
{
|
||||
// The service command is the same as the updater.exe command line except
|
||||
// it has 2 extra args: 1) The Path to udpater.exe, and 2) the command
|
||||
// being executed which is "software-update"
|
||||
LPCWSTR *updaterServiceArgv = new LPCWSTR[argc + 2];
|
||||
updaterServiceArgv[0] = L"MozillaMaintenance";
|
||||
updaterServiceArgv[1] = L"software-update";
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
updaterServiceArgv[i + 2] = argv[i];
|
||||
}
|
||||
|
||||
// Execute the service command by starting the service with
|
||||
// the passed in arguments.
|
||||
DWORD ret = StartServiceCommand(argc + 2, updaterServiceArgv);
|
||||
delete[] updaterServiceArgv;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins a base directory path with a filename.
|
||||
*
|
||||
* @param base The base directory path of size MAX_PATH + 1
|
||||
* @param extra The filename to append
|
||||
* @return TRUE if the file name was successful appended to base
|
||||
*/
|
||||
BOOL
|
||||
PathAppendSafe(LPWSTR base, LPCWSTR extra)
|
||||
{
|
||||
if (wcslen(base) + wcslen(extra) >= MAX_PATH) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return PathAppendW(base, extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets update.status to a specific failure code
|
||||
*
|
||||
* @param updateDirPath The path of the update directory
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
BOOL
|
||||
WriteStatusFailure(LPCWSTR updateDirPath, int errorCode)
|
||||
{
|
||||
// The temp file is not removed on failure since there is client code that
|
||||
// will remove it.
|
||||
WCHAR tmpUpdateStatusFilePath[MAX_PATH + 1] = { L'\0' };
|
||||
if (GetTempFileNameW(updateDirPath, L"svc", 0, tmpUpdateStatusFilePath) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE tmpStatusFile = CreateFileW(tmpUpdateStatusFilePath, GENERIC_WRITE, 0,
|
||||
nullptr, CREATE_ALWAYS, 0, nullptr);
|
||||
if (tmpStatusFile == INVALID_HANDLE_VALUE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char failure[32];
|
||||
sprintf(failure, "failed: %d", errorCode);
|
||||
DWORD toWrite = strlen(failure);
|
||||
DWORD wrote;
|
||||
BOOL ok = WriteFile(tmpStatusFile, failure,
|
||||
toWrite, &wrote, nullptr);
|
||||
CloseHandle(tmpStatusFile);
|
||||
|
||||
if (!ok || wrote != toWrite) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
|
||||
wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
|
||||
if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (MoveFileExW(tmpUpdateStatusFilePath, updateStatusFilePath,
|
||||
MOVEFILE_REPLACE_EXISTING) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Waits for a service to enter a stopped state.
|
||||
* This function does not stop the service, it just blocks until the service
|
||||
* is stopped.
|
||||
*
|
||||
* @param serviceName The service to wait for.
|
||||
* @param maxWaitSeconds The maximum number of seconds to wait
|
||||
* @return state of the service after a timeout or when stopped.
|
||||
* A value of 255 is returned for an error. Typical values are:
|
||||
* SERVICE_STOPPED 0x00000001
|
||||
* SERVICE_START_PENDING 0x00000002
|
||||
* SERVICE_STOP_PENDING 0x00000003
|
||||
* SERVICE_RUNNING 0x00000004
|
||||
* SERVICE_CONTINUE_PENDING 0x00000005
|
||||
* SERVICE_PAUSE_PENDING 0x00000006
|
||||
* SERVICE_PAUSED 0x00000007
|
||||
* last status not set 0x000000CF
|
||||
* Could no query status 0x000000DF
|
||||
* Could not open service, access denied 0x000000EB
|
||||
* Could not open service, invalid handle 0x000000EC
|
||||
* Could not open service, invalid name 0x000000ED
|
||||
* Could not open service, does not exist 0x000000EE
|
||||
* Could not open service, other error 0x000000EF
|
||||
* Could not open SCM, access denied 0x000000FD
|
||||
* Could not open SCM, database does not exist 0x000000FE;
|
||||
* Could not open SCM, other error 0x000000FF;
|
||||
* Note: The strange choice of error codes above SERVICE_PAUSED are chosen
|
||||
* in case Windows comes out with other service stats higher than 7, they
|
||||
* would likely call it 8 and above. JS code that uses this in TestAUSHelper
|
||||
* only handles values up to 255 so that's why we don't use GetLastError
|
||||
* directly.
|
||||
*/
|
||||
DWORD
|
||||
WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds)
|
||||
{
|
||||
// 0x000000CF is defined above to be not set
|
||||
DWORD lastServiceState = 0x000000CF;
|
||||
|
||||
// Get a handle to the SCM database.
|
||||
SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
|
||||
SC_MANAGER_CONNECT |
|
||||
SC_MANAGER_ENUMERATE_SERVICE);
|
||||
if (!serviceManager) {
|
||||
DWORD lastError = GetLastError();
|
||||
switch(lastError) {
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return 0x000000FD;
|
||||
case ERROR_DATABASE_DOES_NOT_EXIST:
|
||||
return 0x000000FE;
|
||||
default:
|
||||
return 0x000000FF;
|
||||
}
|
||||
}
|
||||
|
||||
// Get a handle to the service.
|
||||
SC_HANDLE service = OpenServiceW(serviceManager,
|
||||
serviceName,
|
||||
SERVICE_QUERY_STATUS);
|
||||
if (!service) {
|
||||
DWORD lastError = GetLastError();
|
||||
CloseServiceHandle(serviceManager);
|
||||
switch(lastError) {
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return 0x000000EB;
|
||||
case ERROR_INVALID_HANDLE:
|
||||
return 0x000000EC;
|
||||
case ERROR_INVALID_NAME:
|
||||
return 0x000000ED;
|
||||
case ERROR_SERVICE_DOES_NOT_EXIST:
|
||||
return 0x000000EE;
|
||||
default:
|
||||
return 0x000000EF;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD currentWaitMS = 0;
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
ssp.dwCurrentState = lastServiceState;
|
||||
while (currentWaitMS < maxWaitSeconds * 1000) {
|
||||
DWORD bytesNeeded;
|
||||
if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
|
||||
DWORD lastError = GetLastError();
|
||||
switch (lastError) {
|
||||
case ERROR_INVALID_HANDLE:
|
||||
ssp.dwCurrentState = 0x000000D9;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
ssp.dwCurrentState = 0x000000DA;
|
||||
break;
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
ssp.dwCurrentState = 0x000000DB;
|
||||
break;
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
ssp.dwCurrentState = 0x000000DC;
|
||||
break;
|
||||
case ERROR_INVALID_LEVEL:
|
||||
ssp.dwCurrentState = 0x000000DD;
|
||||
break;
|
||||
case ERROR_SHUTDOWN_IN_PROGRESS:
|
||||
ssp.dwCurrentState = 0x000000DE;
|
||||
break;
|
||||
// These 3 errors can occur when the service is not yet stopped but
|
||||
// it is stopping.
|
||||
case ERROR_INVALID_SERVICE_CONTROL:
|
||||
case ERROR_SERVICE_CANNOT_ACCEPT_CTRL:
|
||||
case ERROR_SERVICE_NOT_ACTIVE:
|
||||
currentWaitMS += 50;
|
||||
Sleep(50);
|
||||
continue;
|
||||
default:
|
||||
ssp.dwCurrentState = 0x000000DF;
|
||||
}
|
||||
|
||||
// We couldn't query the status so just break out
|
||||
break;
|
||||
}
|
||||
|
||||
// The service is already in use.
|
||||
if (ssp.dwCurrentState == SERVICE_STOPPED) {
|
||||
break;
|
||||
}
|
||||
currentWaitMS += 50;
|
||||
Sleep(50);
|
||||
}
|
||||
|
||||
lastServiceState = ssp.dwCurrentState;
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(serviceManager);
|
||||
return lastServiceState;
|
||||
}
|
||||
|
||||
#ifndef ONLY_SERVICE_LAUNCHING
|
||||
|
||||
/**
|
||||
* Determines if there is at least one process running for the specified
|
||||
* application. A match will be found across any session for any user.
|
||||
*
|
||||
* @param process The process to check for existance
|
||||
* @return ERROR_NOT_FOUND if the process was not found
|
||||
* ERROR_SUCCESS if the process was found and there were no errors
|
||||
* Other Win32 system error code for other errors
|
||||
**/
|
||||
DWORD
|
||||
IsProcessRunning(LPCWSTR filename)
|
||||
{
|
||||
// Take a snapshot of all processes in the system.
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (INVALID_HANDLE_VALUE == snapshot) {
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
PROCESSENTRY32W processEntry;
|
||||
processEntry.dwSize = sizeof(PROCESSENTRY32W);
|
||||
if (!Process32FirstW(snapshot, &processEntry)) {
|
||||
DWORD lastError = GetLastError();
|
||||
CloseHandle(snapshot);
|
||||
return lastError;
|
||||
}
|
||||
|
||||
do {
|
||||
if (wcsicmp(filename, processEntry.szExeFile) == 0) {
|
||||
CloseHandle(snapshot);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
} while (Process32NextW(snapshot, &processEntry));
|
||||
CloseHandle(snapshot);
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the specified applicaiton to exit.
|
||||
*
|
||||
* @param filename The application to wait for.
|
||||
* @param maxSeconds The maximum amount of seconds to wait for all
|
||||
* instances of the application to exit.
|
||||
* @return ERROR_SUCCESS if no instances of the application exist
|
||||
* WAIT_TIMEOUT if the process is still running after maxSeconds.
|
||||
* Any other Win32 system error code.
|
||||
*/
|
||||
DWORD
|
||||
WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds)
|
||||
{
|
||||
DWORD applicationRunningError = WAIT_TIMEOUT;
|
||||
for(DWORD i = 0; i < maxSeconds; i++) {
|
||||
DWORD applicationRunningError = IsProcessRunning(filename);
|
||||
if (ERROR_NOT_FOUND == applicationRunningError) {
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS == applicationRunningError) {
|
||||
return WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
return applicationRunningError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the fallback key exists or not
|
||||
*
|
||||
* @return TRUE if the fallback key exists and there was no error checking
|
||||
*/
|
||||
BOOL
|
||||
DoesFallbackKeyExist()
|
||||
{
|
||||
HKEY testOnlyFallbackKey;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
TEST_ONLY_FALLBACK_KEY_PATH, 0,
|
||||
KEY_READ | KEY_WOW64_64KEY,
|
||||
&testOnlyFallbackKey) != ERROR_SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey(testOnlyFallbackKey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Determines if the file system for the specified file handle is local
|
||||
* @param file path to check the filesystem type for, must be at most MAX_PATH
|
||||
* @param isLocal out parameter which will hold TRUE if the drive is local
|
||||
* @return TRUE if the call succeeded
|
||||
*/
|
||||
BOOL
|
||||
IsLocalFile(LPCWSTR file, BOOL &isLocal)
|
||||
{
|
||||
WCHAR rootPath[MAX_PATH + 1] = { L'\0' };
|
||||
if (wcslen(file) > MAX_PATH) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wcsncpy(rootPath, file, MAX_PATH);
|
||||
PathStripToRootW(rootPath);
|
||||
isLocal = GetDriveTypeW(rootPath) == DRIVE_FIXED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines the DWORD value of a registry key value
|
||||
*
|
||||
* @param key The base key to where the value name exists
|
||||
* @param valueName The name of the value
|
||||
* @param retValue Out parameter which will hold the value
|
||||
* @return TRUE on success
|
||||
*/
|
||||
static BOOL
|
||||
GetDWORDValue(HKEY key, LPCWSTR valueName, DWORD &retValue)
|
||||
{
|
||||
DWORD regDWORDValueSize = sizeof(DWORD);
|
||||
LONG retCode = RegQueryValueExW(key, valueName, 0, nullptr,
|
||||
reinterpret_cast<LPBYTE>(&retValue),
|
||||
®DWORDValueSize);
|
||||
return ERROR_SUCCESS == retCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the the system's elevation type allows
|
||||
* unprmopted elevation.
|
||||
*
|
||||
* @param isUnpromptedElevation Out parameter which specifies if unprompted
|
||||
* elevation is allowed.
|
||||
* @return TRUE if the user can actually elevate and the value was obtained
|
||||
* successfully.
|
||||
*/
|
||||
BOOL
|
||||
IsUnpromptedElevation(BOOL &isUnpromptedElevation)
|
||||
{
|
||||
if (!UACHelper::CanUserElevate()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LPCWSTR UACBaseRegKey =
|
||||
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
|
||||
HKEY baseKey;
|
||||
LONG retCode = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
UACBaseRegKey, 0,
|
||||
KEY_READ, &baseKey);
|
||||
if (retCode != ERROR_SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD consent, secureDesktop;
|
||||
BOOL success = GetDWORDValue(baseKey, L"ConsentPromptBehaviorAdmin",
|
||||
consent);
|
||||
success = success &&
|
||||
GetDWORDValue(baseKey, L"PromptOnSecureDesktop", secureDesktop);
|
||||
isUnpromptedElevation = !consent && !secureDesktop;
|
||||
|
||||
RegCloseKey(baseKey);
|
||||
return success;
|
||||
}
|
||||
29
toolkit/mozapps/update/common/updatehelper.h
Normal file
29
toolkit/mozapps/update/common/updatehelper.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
BOOL StartServiceUpdate(LPCWSTR installDir);
|
||||
DWORD LaunchServiceSoftwareUpdateCommand(int argc, LPCWSTR *argv);
|
||||
BOOL WriteStatusFailure(LPCWSTR updateDirPath, int errorCode);
|
||||
DWORD WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds);
|
||||
DWORD WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds);
|
||||
DWORD IsProcessRunning(LPCWSTR filename);
|
||||
BOOL DoesFallbackKeyExist();
|
||||
BOOL IsLocalFile(LPCWSTR file, BOOL &isLocal);
|
||||
DWORD StartServiceCommand(int argc, LPCWSTR* argv);
|
||||
BOOL IsUnpromptedElevation(BOOL &isUnpromptedElevation);
|
||||
|
||||
#define SVC_NAME L"MozillaMaintenance"
|
||||
|
||||
#define BASE_SERVICE_REG_KEY \
|
||||
L"SOFTWARE\\Mozilla\\MaintenanceService"
|
||||
|
||||
// The test only fallback key, as its name implies, is only present on machines
|
||||
// that will use automated tests. Since automated tests always run from a
|
||||
// different directory for each test, the presence of this key bypasses the
|
||||
// "This is a valid installation directory" check. This key also stores
|
||||
// the allowed name and issuer for cert checks so that the cert check
|
||||
// code can still be run unchanged.
|
||||
#define TEST_ONLY_FALLBACK_KEY_PATH \
|
||||
BASE_SERVICE_REG_KEY L"\\3932ecacee736d366d6436db0f55bce4"
|
||||
|
||||
32
toolkit/mozapps/update/common/win_dirent.h
Normal file
32
toolkit/mozapps/update/common/win_dirent.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef WINDIRENT_H__
|
||||
#define WINDIRENT_H__
|
||||
|
||||
#ifndef XP_WIN
|
||||
#error This library should only be used on Windows
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct DIR {
|
||||
explicit DIR(const WCHAR* path);
|
||||
~DIR();
|
||||
HANDLE findHandle;
|
||||
WCHAR name[MAX_PATH];
|
||||
};
|
||||
|
||||
struct dirent {
|
||||
dirent();
|
||||
WCHAR d_name[MAX_PATH];
|
||||
};
|
||||
|
||||
DIR* opendir(const WCHAR* path);
|
||||
int closedir(DIR* dir);
|
||||
dirent* readdir(DIR* dir);
|
||||
|
||||
#endif // WINDIRENT_H__
|
||||
70
toolkit/mozapps/update/content/history.js
Normal file
70
toolkit/mozapps/update/content/history.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
var gUpdateHistory = {
|
||||
_view: null,
|
||||
|
||||
/**
|
||||
* Initialize the User Interface
|
||||
*/
|
||||
onLoad: function() {
|
||||
this._view = document.getElementById("historyItems");
|
||||
|
||||
var um =
|
||||
Components.classes["@mozilla.org/updates/update-manager;1"].
|
||||
getService(Components.interfaces.nsIUpdateManager);
|
||||
var uc = um.updateCount;
|
||||
if (uc) {
|
||||
while (this._view.hasChildNodes())
|
||||
this._view.removeChild(this._view.firstChild);
|
||||
|
||||
var bundle = document.getElementById("updateBundle");
|
||||
|
||||
for (var i = 0; i < uc; ++i) {
|
||||
var update = um.getUpdateAt(i);
|
||||
if (!update || !update.name)
|
||||
continue;
|
||||
|
||||
// Don't display updates that are downloading since they don't have
|
||||
// valid statusText for the UI (bug 485493).
|
||||
if (!update.statusText)
|
||||
continue;
|
||||
|
||||
var element = document.createElementNS(NS_XUL, "update");
|
||||
this._view.appendChild(element);
|
||||
element.name = bundle.getFormattedString("updateFullName",
|
||||
[update.name, update.buildID]);
|
||||
element.type = bundle.getString("updateType_" + update.type);
|
||||
element.installDate = this._formatDate(update.installDate);
|
||||
if (update.detailsURL)
|
||||
element.detailsURL = update.detailsURL;
|
||||
else
|
||||
element.hideDetailsURL = true;
|
||||
element.status = update.statusText;
|
||||
}
|
||||
}
|
||||
var cancelbutton = document.documentElement.getButton("cancel");
|
||||
cancelbutton.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Formats a date into human readable form
|
||||
* @param seconds
|
||||
* A date in seconds since 1970 epoch
|
||||
* @returns A human readable date string
|
||||
*/
|
||||
_formatDate: function(seconds) {
|
||||
var date = new Date(seconds);
|
||||
const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
|
||||
.getService(Components.interfaces.nsIXULChromeRegistry)
|
||||
.getSelectedLocale("global", true);
|
||||
const dtOptions = { year: 'numeric', month: 'long', day: 'numeric',
|
||||
hour: 'numeric', minute: 'numeric', second: 'numeric' };
|
||||
return date.toLocaleString(locale, dtOptions);
|
||||
}
|
||||
};
|
||||
|
||||
39
toolkit/mozapps/update/content/history.xul
Normal file
39
toolkit/mozapps/update/content/history.xul
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!DOCTYPE dialog [
|
||||
<!ENTITY % historyDTD SYSTEM "chrome://mozapps/locale/update/history.dtd">
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%historyDTD;
|
||||
%brandDTD;
|
||||
]>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/content/update/updates.css"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/skin/update/updates.css"?>
|
||||
|
||||
<dialog id="history" windowtype="Update:History"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 35em;"
|
||||
buttons="cancel"
|
||||
defaultButton="cancel"
|
||||
buttonlabelcancel="&closebutton.label;"
|
||||
title="&history.title;"
|
||||
onload="gUpdateHistory.onLoad();">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mozapps/content/update/history.js"/>
|
||||
|
||||
<stringbundle id="updateBundle"
|
||||
src="chrome://mozapps/locale/update/updates.properties"/>
|
||||
|
||||
<label>&history.intro;</label>
|
||||
<separator class="thin"/>
|
||||
<richlistbox id="historyItems" flex="1">
|
||||
<label>&noupdates.label;</label>
|
||||
</richlistbox>
|
||||
<separator class="thin"/>
|
||||
</dialog>
|
||||
33
toolkit/mozapps/update/content/updates.css
Normal file
33
toolkit/mozapps/update/content/updates.css
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* Stop animations on pages that aren't on the current page (bug 341749). */
|
||||
#updates:not([currentpageid="checking"]) #checkingProgress,
|
||||
#updates:not([currentpageid="downloading"]) #downloadProgress {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide the wizard's header so the size of the billboard can size the window
|
||||
on creation. A custom header will be used in its place when a header is
|
||||
needed. */
|
||||
.wizard-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Display the custom header */
|
||||
.update-header {
|
||||
display: -moz-box !important;
|
||||
}
|
||||
|
||||
/* Custom header implementation based on the Wizard's header. This allows the
|
||||
size of the billboard's remotecontent to size the window since it does not
|
||||
have an updateheader on the billboard page. */
|
||||
updateheader {
|
||||
-moz-binding: url("chrome://mozapps/content/update/updates.xml#updateheader");
|
||||
display: -moz-box;
|
||||
-moz-box-orient: horizontal;
|
||||
}
|
||||
|
||||
/* Update History Window */
|
||||
update {
|
||||
-moz-binding: url("chrome://mozapps/content/update/updates.xml#update");
|
||||
display: -moz-box;
|
||||
-moz-box-orient: vertical;
|
||||
}
|
||||
1399
toolkit/mozapps/update/content/updates.js
Normal file
1399
toolkit/mozapps/update/content/updates.js
Normal file
File diff suppressed because it is too large
Load diff
83
toolkit/mozapps/update/content/updates.xml
Normal file
83
toolkit/mozapps/update/content/updates.xml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
|
||||
<!DOCTYPE bindings SYSTEM "chrome://mozapps/locale/update/updates.dtd">
|
||||
|
||||
<bindings id="updatesBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="updateheader" extends="chrome://global/content/bindings/wizard.xml#wizard-header">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/skin/wizard.css"/>
|
||||
</resources>
|
||||
<content>
|
||||
<xul:hbox class="wizard-header update-header" flex="1">
|
||||
<xul:vbox class="wizard-header-box-1">
|
||||
<xul:vbox class="wizard-header-box-text">
|
||||
<xul:label class="wizard-header-label" xbl:inherits="value=label"/>
|
||||
</xul:vbox>
|
||||
</xul:vbox>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="update" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||
<content>
|
||||
<xul:hbox>
|
||||
<xul:label class="update-name" xbl:inherits="value=name" flex="1" crop="right"/>
|
||||
<xul:label xbl:inherits="href=detailsURL,hidden=hideDetailsURL" class="text-link"
|
||||
value="&update.details.label;"/>
|
||||
</xul:hbox>
|
||||
<xul:label class="update-type" xbl:inherits="value=type"/>
|
||||
<xul:grid>
|
||||
<xul:columns>
|
||||
<xul:column class="update-label-column"/>
|
||||
<xul:column flex="1"/>
|
||||
</xul:columns>
|
||||
<xul:rows>
|
||||
<xul:row>
|
||||
<xul:label class="update-installedOn-label">&update.installedOn.label;</xul:label>
|
||||
<xul:label class="update-installedOn-value" xbl:inherits="value=installDate" flex="1" crop="right"/>
|
||||
</xul:row>
|
||||
<xul:row>
|
||||
<xul:label class="update-status-label">&update.status.label;</xul:label>
|
||||
<xul:description class="update-status-value" flex="1"/>
|
||||
</xul:row>
|
||||
</xul:rows>
|
||||
</xul:grid>
|
||||
</content>
|
||||
<implementation>
|
||||
<property name="name"
|
||||
onget="return this.getAttribute('name');"
|
||||
onset="this.setAttribute('name', val); return val;"/>
|
||||
<property name="detailsURL"
|
||||
onget="return this.getAttribute('detailsURL');"
|
||||
onset="this.setAttribute('detailsURL', val); return val;"/>
|
||||
<property name="installDate"
|
||||
onget="return this.getAttribute('installDate');"
|
||||
onset="this.setAttribute('installDate', val); return val;"/>
|
||||
<property name="type"
|
||||
onget="return this.getAttribute('type');"
|
||||
onset="this.setAttribute('type', val); return val;"/>
|
||||
<property name="hideDetailsURL"
|
||||
onget="return this.getAttribute('hideDetailsURL');"
|
||||
onset="this.setAttribute('hideDetailsURL', val); return val;"/>
|
||||
<property name="status"
|
||||
onget="return this.getAttribute('status');">
|
||||
<setter><![CDATA[
|
||||
this.setAttribute("status", val);
|
||||
var field = document.getAnonymousElementByAttribute(this, "class", "update-status-value");
|
||||
while (field.hasChildNodes())
|
||||
field.removeChild(field.firstChild);
|
||||
field.appendChild(document.createTextNode(val));
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
</implementation>
|
||||
</binding>
|
||||
</bindings>
|
||||
206
toolkit/mozapps/update/content/updates.xul
Normal file
206
toolkit/mozapps/update/content/updates.xul
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/content/update/updates.css"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/skin/update/updates.css"?>
|
||||
|
||||
<!DOCTYPE wizard [
|
||||
<!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/update/updates.dtd">
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%updateDTD;
|
||||
%brandDTD;
|
||||
]>
|
||||
|
||||
<wizard id="updates"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&updateWizard.title;"
|
||||
windowtype="Update:Wizard"
|
||||
style="width: auto; height: auto"
|
||||
onwizardfinish="gUpdates.onWizardFinish();"
|
||||
onwizardcancel="gUpdates.onWizardCancel();"
|
||||
onwizardnext="gUpdates.onWizardNext();"
|
||||
onload="gUpdates.onLoad();"
|
||||
onunload="gUpdates.onUnload();">
|
||||
|
||||
<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
|
||||
<script type="application/javascript" src="chrome://mozapps/content/update/updates.js"/>
|
||||
|
||||
<stringbundleset id="updateSet">
|
||||
<stringbundle id="brandStrings" src="chrome://branding/locale/brand.properties"/>
|
||||
<stringbundle id="updateStrings" src="chrome://mozapps/locale/update/updates.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<wizardpage id="dummy" pageid="dummy" firstpage="true"/>
|
||||
|
||||
<wizardpage id="checking" pageid="checking" next="noupdatesfound"
|
||||
object="gCheckingPage" onpageshow="gCheckingPage.onPageShow();">
|
||||
<updateheader label="&checking.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label>&updateCheck.label;</label>
|
||||
<separator class="thin"/>
|
||||
<progressmeter id="checkingProgress" mode="undetermined"/>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="noupdatesfound" pageid="noupdatesfound"
|
||||
object="gNoUpdatesPage" onpageshow="gNoUpdatesPage.onPageShow();">
|
||||
<updateheader label="&noupdatesfound.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label id="noUpdatesAutoEnabled" hidden="true">&noupdatesautoenabled.intro;</label>
|
||||
<label id="noUpdatesAutoDisabled" hidden="true">&noupdatesautodisabled.intro;</label>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="manualUpdate" pageid="manualUpdate" object="gManualUpdatePage"
|
||||
onpageshow="gManualUpdatePage.onPageShow();">
|
||||
<updateheader label="&manualUpdate.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label id="manualUpdateDesc">&manualUpdate.desc;</label>
|
||||
<label id="manualUpdateSpaceDesc"
|
||||
hidden="true">&manualUpdate.space.desc;</label>
|
||||
<separator class="thin"/>
|
||||
<label>&manualUpdateGetMsg.label;</label>
|
||||
<hbox>
|
||||
<label class="text-link" id="manualUpdateLinkLabel" value=""
|
||||
onclick="openUpdateURL(event);"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="unsupported" pageid="unsupported"
|
||||
object="gUnsupportedPage"
|
||||
onpageshow="gUnsupportedPage.onPageShow();">
|
||||
<updateheader label="&unsupported.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<description flex="1">&unsupported.label;
|
||||
<label id="unsupportedLinkLabel" class="text-link inline-link" onclick="openUpdateURL(event);">
|
||||
&unsupportedLink.label;
|
||||
</label>
|
||||
</description>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="updatesfoundbasic" pageid="updatesfoundbasic"
|
||||
object="gUpdatesFoundBasicPage" next="downloading"
|
||||
onpageshow="gUpdatesFoundBasicPage.onPageShow();"
|
||||
onextra1="gUpdatesFoundBasicPage.onExtra1();"
|
||||
onextra2="gUpdatesFoundBasicPage.onExtra2();">
|
||||
<updateheader id="updatesFoundBasicHeader" label=""/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label id="updatesFoundInto"/>
|
||||
<separator class="thin"/>
|
||||
<label id="updateName" crop="right" value=""/>
|
||||
<separator id="updateNameSep" class="thin"/>
|
||||
<label id="upgradeEvangelism">&evangelism.desc;</label>
|
||||
<separator id="upgradeEvangelismSep" flex="1"/>
|
||||
<vbox flex="1">
|
||||
<hbox id="moreInfoURL">
|
||||
<label class="text-link" id="updateMoreInfoURL"
|
||||
value="&clickHere.label;" onclick="openUpdateURL(event);"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="downloading" pageid="downloading"
|
||||
object="gDownloadingPage" onextra1="gDownloadingPage.onHide();"
|
||||
onpageshow="gDownloadingPage.onPageShow();">
|
||||
<updateheader label="&downloadPage.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<hbox id="downloadStatusProgress">
|
||||
<progressmeter id="downloadProgress" mode="undetermined" flex="1"/>
|
||||
<button id="pauseButton" oncommand="gDownloadingPage.onPause();"
|
||||
paused="false"/>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<hbox id="downloadStatusLine">
|
||||
<label id="downloadStatus" flex="1">&connecting.label;</label>
|
||||
</hbox>
|
||||
<separator/>
|
||||
<hbox id="verificationFailed" align="start" hidden="true">
|
||||
<image id="verificationFailedIcon"/>
|
||||
<label flex="1">&verificationFailedText.label;</label>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="errors" pageid="errors" object="gErrorsPage"
|
||||
onpageshow="gErrorsPage.onPageShow();">
|
||||
<updateheader label="&error.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label id="errorIntro">&error.label;</label>
|
||||
<separator/>
|
||||
<textbox class="plain" readonly="true" id="errorReason" multiline="true"
|
||||
rows="3"/>
|
||||
<separator/>
|
||||
<label id="errorManual">&errorManual.label;</label>
|
||||
<hbox>
|
||||
<label class="text-link" id="errorLinkLabel" value=""
|
||||
onclick="openUpdateURL(event);"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="errorextra" pageid="errorextra"
|
||||
object="gErrorExtraPage"
|
||||
onpageshow="gErrorExtraPage.onPageShow();">
|
||||
<updateheader label="&error.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label id="bgErrorLabel">&genericBackgroundError.label;</label>
|
||||
<hbox>
|
||||
<label id="errorExtraLinkLabel" class="text-link"
|
||||
value="" onclick="openUpdateURL(event);"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="errorpatching" pageid="errorpatching" next="downloading"
|
||||
object="gErrorPatchingPage"
|
||||
onpageshow="gErrorPatchingPage.onPageShow();">
|
||||
<updateheader label="&error.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label>&errorpatching.intro;</label>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="finished" pageid="finished" object="gFinishedPage"
|
||||
onpageshow="gFinishedPage.onPageShow();"
|
||||
onextra1="gFinishedPage.onExtra1()">
|
||||
<updateheader label="&finishedPage.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label>&finishedPage.text;</label>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="finishedBackground" pageid="finishedBackground"
|
||||
object="gFinishedPage" onextra1="gFinishedPage.onExtra1()"
|
||||
onextra2="gFinishedPage.onExtra2()"
|
||||
onpageshow="gFinishedPage.onPageShowBackground();">
|
||||
<updateheader label="&finishedPage.title;"/>
|
||||
<vbox class="update-content" flex="1">
|
||||
<label>&finishedBackgroundPage.text;</label>
|
||||
<separator/>
|
||||
<hbox align="center">
|
||||
<label>&finishedBackground.name;</label>
|
||||
<label id="updateFinishedName" flex="1" crop="right" value=""/>
|
||||
<label id="finishedBackgroundLink" class="text-link" disabled="true"
|
||||
value="&details.link;" onclick="openUpdateURL(event);"/>
|
||||
</hbox>
|
||||
<spacer flex="1"/>
|
||||
<label id="finishedBackgroundMore">&finishedBackground.more;</label>
|
||||
<label id="finishedBackgroundMoreElevated"
|
||||
hidden="true">&finishedBackground.moreElevated;</label>
|
||||
<label id="finishedBackgroundMoreElevatedLink"
|
||||
hidden="true">&errorManual.label;</label>
|
||||
<hbox>
|
||||
<label class="text-link" id="finishedBackgroundMoreElevatedLinkLabel"
|
||||
value="" onclick="openUpdateURL(event);" hidden="true"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
|
||||
</wizard>
|
||||
12
toolkit/mozapps/update/jar.mn
Normal file
12
toolkit/mozapps/update/jar.mn
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
toolkit.jar:
|
||||
% content mozapps %content/mozapps/
|
||||
content/mozapps/update/history.xul (content/history.xul)
|
||||
content/mozapps/update/history.js (content/history.js)
|
||||
content/mozapps/update/updates.css (content/updates.css)
|
||||
content/mozapps/update/updates.js (content/updates.js)
|
||||
content/mozapps/update/updates.xml (content/updates.xml)
|
||||
content/mozapps/update/updates.xul (content/updates.xul)
|
||||
33
toolkit/mozapps/update/moz.build
Normal file
33
toolkit/mozapps/update/moz.build
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_MODULE = 'update'
|
||||
|
||||
DIRS += [
|
||||
'common',
|
||||
'updater',
|
||||
]
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIUpdateService.idl',
|
||||
]
|
||||
|
||||
TEST_DIRS += ['tests']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsUpdateService.js',
|
||||
'nsUpdateService.manifest',
|
||||
'nsUpdateServiceStub.js',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'UpdateTelemetry.jsm',
|
||||
]
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Application Update')
|
||||
575
toolkit/mozapps/update/nsIUpdateService.idl
Normal file
575
toolkit/mozapps/update/nsIUpdateService.idl
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMDocument;
|
||||
interface nsIDOMElement;
|
||||
interface nsIDOMWindow;
|
||||
interface nsIRequest;
|
||||
interface nsIRequestObserver;
|
||||
interface nsISimpleEnumerator;
|
||||
interface nsIFile;
|
||||
|
||||
/**
|
||||
* An interface that describes an object representing a patch file that can
|
||||
* be downloaded and applied to a version of this application so that it
|
||||
* can be updated.
|
||||
*/
|
||||
[scriptable, uuid(dc8fb8a9-3a53-4031-9469-2a5197ea30e7)]
|
||||
interface nsIUpdatePatch : nsISupports
|
||||
{
|
||||
/**
|
||||
* The type of this patch:
|
||||
* "partial" A binary difference between two application versions
|
||||
* "complete" A complete patch containing all of the replacement files
|
||||
* to update to the new version
|
||||
*/
|
||||
attribute AString type;
|
||||
|
||||
/**
|
||||
* The URL this patch was being downloaded from
|
||||
*/
|
||||
attribute AString URL;
|
||||
|
||||
/**
|
||||
* The final URL this patch was being downloaded from
|
||||
*/
|
||||
attribute AString finalURL;
|
||||
|
||||
/**
|
||||
* The hash function to use when determining this file's integrity
|
||||
*/
|
||||
attribute AString hashFunction;
|
||||
|
||||
/**
|
||||
* The value of the hash function named above that should be computed if
|
||||
* this file is not corrupt.
|
||||
*/
|
||||
attribute AString hashValue;
|
||||
|
||||
/**
|
||||
* The size of this file, in bytes.
|
||||
*/
|
||||
attribute unsigned long size;
|
||||
|
||||
/**
|
||||
* The state of this patch
|
||||
*/
|
||||
attribute AString state;
|
||||
|
||||
/**
|
||||
* true if this patch is currently selected as the patch to be downloaded and
|
||||
* installed for this update transaction, false if another patch from this
|
||||
* update has been selected.
|
||||
*/
|
||||
attribute boolean selected;
|
||||
|
||||
/**
|
||||
* Serializes this patch object into a DOM Element
|
||||
* @param updates
|
||||
* The document to serialize into
|
||||
* @returns The DOM Element created by the serialization process
|
||||
*/
|
||||
nsIDOMElement serialize(in nsIDOMDocument updates);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface that describes an object representing an available update to
|
||||
* the current application - this update may have several available patches
|
||||
* from which one must be selected to download and install, for example we
|
||||
* might select a binary difference patch first and attempt to apply that,
|
||||
* then if the application process fails fall back to downloading a complete
|
||||
* file-replace patch. This object also contains information about the update
|
||||
* that the front end and other application services can use to learn more
|
||||
* about what is going on.
|
||||
*/
|
||||
[scriptable, uuid(e094c045-f4ff-41fd-92da-cd2effd2c7c9)]
|
||||
interface nsIUpdate : nsISupports
|
||||
{
|
||||
/**
|
||||
* The type of update:
|
||||
* "major" A major new version of the Application
|
||||
* "minor" A minor update to the Application (e.g. security update)
|
||||
*/
|
||||
attribute AString type;
|
||||
|
||||
/**
|
||||
* The name of the update, or "<Application Name> <Update Version>"
|
||||
*/
|
||||
attribute AString name;
|
||||
|
||||
/**
|
||||
* The string to display in the user interface for the version. If you want
|
||||
* a real version number use appVersion.
|
||||
*/
|
||||
attribute AString displayVersion;
|
||||
|
||||
/**
|
||||
* The Application version of this update.
|
||||
*/
|
||||
attribute AString appVersion;
|
||||
|
||||
/**
|
||||
* The Application version prior to the application being updated.
|
||||
*/
|
||||
attribute AString previousAppVersion;
|
||||
|
||||
/**
|
||||
* The Build ID of this update. Used to determine a particular build, down
|
||||
* to the hour, minute and second of its creation. This allows the system
|
||||
* to differentiate between several nightly builds with the same |version|
|
||||
* for example.
|
||||
*/
|
||||
attribute AString buildID;
|
||||
|
||||
/**
|
||||
* The URL to a page which offers details about the content of this
|
||||
* update. Ideally, this page is not the release notes but some other page
|
||||
* that summarizes the differences between this update and the previous,
|
||||
* which also links to the release notes.
|
||||
*/
|
||||
attribute AString detailsURL;
|
||||
|
||||
/**
|
||||
* The URL to the Update Service that supplied this update.
|
||||
*/
|
||||
attribute AString serviceURL;
|
||||
|
||||
/**
|
||||
* The channel used to retrieve this update from the Update Service.
|
||||
*/
|
||||
attribute AString channel;
|
||||
|
||||
/**
|
||||
* Whether to show the update prompt which requires user confirmation when an
|
||||
* update is found during a background update check. This overrides the
|
||||
* default setting to download the update in the background.
|
||||
*/
|
||||
attribute boolean showPrompt;
|
||||
|
||||
/**
|
||||
* Whether to show the "No Thanks" button in the update prompt. This allows
|
||||
* the user to never receive a notification for that specific update version
|
||||
* again.
|
||||
*/
|
||||
attribute boolean showNeverForVersion;
|
||||
|
||||
/**
|
||||
* Whether the update is no longer supported on this system.
|
||||
*/
|
||||
attribute boolean unsupported;
|
||||
|
||||
/**
|
||||
* Allows overriding the default amount of time in seconds before prompting the
|
||||
* user to apply an update. If not specified, the value of
|
||||
* app.update.promptWaitTime will be used.
|
||||
*/
|
||||
attribute long long promptWaitTime;
|
||||
|
||||
/**
|
||||
* Whether or not the update being downloaded is a complete replacement of
|
||||
* the user's existing installation or a patch representing the difference
|
||||
* between the new version and the previous version.
|
||||
*/
|
||||
attribute boolean isCompleteUpdate;
|
||||
|
||||
/**
|
||||
* Whether or not the update is a security update or not. If this is true,
|
||||
* then we present more serious sounding user interface messages to the
|
||||
* user.
|
||||
*/
|
||||
attribute boolean isSecurityUpdate;
|
||||
|
||||
/**
|
||||
* Whether or not the update being downloaded is an OS update. This is
|
||||
* generally only possible in Gonk right now.
|
||||
*/
|
||||
attribute boolean isOSUpdate;
|
||||
|
||||
/**
|
||||
* When the update was installed.
|
||||
*/
|
||||
attribute long long installDate;
|
||||
|
||||
/**
|
||||
* A message associated with this update, if any.
|
||||
*/
|
||||
attribute AString statusText;
|
||||
|
||||
/**
|
||||
* The currently selected patch for this update.
|
||||
*/
|
||||
readonly attribute nsIUpdatePatch selectedPatch;
|
||||
|
||||
/**
|
||||
* The state of the selected patch:
|
||||
* "downloading" The update is being downloaded.
|
||||
* "pending" The update is ready to be applied.
|
||||
* "pending-service" The update is ready to be applied with the service.
|
||||
* "pending-elevate" The update is ready to be applied but requires elevation.
|
||||
* "applying" The update is being applied.
|
||||
* "applied" The update is ready to be switched to.
|
||||
* "applied-os" The update is OS update and to be installed.
|
||||
* "applied-service" The update is ready to be switched to with the service.
|
||||
* "succeeded" The update was successfully applied.
|
||||
* "download-failed" The update failed to be downloaded.
|
||||
* "failed" The update failed to be applied.
|
||||
*/
|
||||
attribute AString state;
|
||||
|
||||
/**
|
||||
* A numeric error code that conveys additional information about the state
|
||||
* of a failed update or failed certificate attribute check during an update
|
||||
* check. If the update is not in the "failed" state or the certificate
|
||||
* attribute check has not failed the value is zero.
|
||||
*
|
||||
* TODO: Define typical error codes (for now, see updater/errors.h and the
|
||||
* CERT_ATTR_CHECK_FAILED_* values in nsUpdateService.js)
|
||||
*/
|
||||
attribute long errorCode;
|
||||
|
||||
/**
|
||||
* Whether an elevation failure has been encountered for this update.
|
||||
*/
|
||||
attribute boolean elevationFailure;
|
||||
|
||||
/**
|
||||
* The number of patches supplied by this update.
|
||||
*/
|
||||
readonly attribute unsigned long patchCount;
|
||||
|
||||
/**
|
||||
* Retrieves a patch.
|
||||
* @param index
|
||||
* The index of the patch to retrieve.
|
||||
* @returns The nsIUpdatePatch at the specified index.
|
||||
*/
|
||||
nsIUpdatePatch getPatchAt(in unsigned long index);
|
||||
|
||||
/**
|
||||
* Serializes this update object into a DOM Element
|
||||
* @param updates
|
||||
* The document to serialize into
|
||||
* @returns The DOM Element created by the serialization process
|
||||
*/
|
||||
nsIDOMElement serialize(in nsIDOMDocument updates);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface describing an object that listens to the progress of an update
|
||||
* check operation. This object is notified as the check continues, finishes
|
||||
* and if it has an error.
|
||||
*/
|
||||
[scriptable, uuid(4aa2b4bb-39ea-407b-98ff-89f19134d4c0)]
|
||||
interface nsIUpdateCheckListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* The update check was completed.
|
||||
* @param request
|
||||
* The XMLHttpRequest handling the update check.
|
||||
* @param updates
|
||||
* An array of nsIUpdate objects listing available updates.
|
||||
* @param updateCount
|
||||
* The size of the |updates| array.
|
||||
*/
|
||||
void onCheckComplete(in jsval request,
|
||||
[array, size_is(updateCount)] in nsIUpdate updates,
|
||||
in unsigned long updateCount);
|
||||
|
||||
/**
|
||||
* An error occurred while loading the remote update service file.
|
||||
* @param request
|
||||
* The XMLHttpRequest handling the update check.
|
||||
* @param update
|
||||
* A nsIUpdate object that contains details about the
|
||||
* error in its |statusText| property.
|
||||
*/
|
||||
void onError(in jsval request,
|
||||
in nsIUpdate update);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface describing an object that knows how to check for updates.
|
||||
*/
|
||||
[scriptable, uuid(877ace25-8bc5-452a-8586-9c1cf2871994)]
|
||||
interface nsIUpdateChecker : nsISupports
|
||||
{
|
||||
/**
|
||||
* Checks for available updates, notifying a listener of the results.
|
||||
* @param listener
|
||||
* An object implementing nsIUpdateCheckListener which is notified
|
||||
* of the results of an update check.
|
||||
* @param force
|
||||
* Forces the checker to check for updates, regardless of the
|
||||
* current value of the user's update settings. This is used by
|
||||
* any piece of UI that offers the user the imperative option to
|
||||
* check for updates now, regardless of their update settings.
|
||||
* force will not work if the system administrator has locked
|
||||
* the app.update.enabled preference.
|
||||
*/
|
||||
void checkForUpdates(in nsIUpdateCheckListener listener, in boolean force);
|
||||
|
||||
/**
|
||||
* Constants for the |stopChecking| function that tell the Checker how long
|
||||
* to stop checking:
|
||||
*
|
||||
* CURRENT_CHECK: Stops the current (active) check only
|
||||
* CURRENT_SESSION: Stops all checking for the current session
|
||||
* ANY_CHECKS: Stops all checking, any session from now on
|
||||
* (disables update checking preferences)
|
||||
*/
|
||||
const unsigned short CURRENT_CHECK = 1;
|
||||
const unsigned short CURRENT_SESSION = 2;
|
||||
const unsigned short ANY_CHECKS = 3;
|
||||
|
||||
/**
|
||||
* Ends any pending update check.
|
||||
* @param duration
|
||||
* A value representing the set of checks to stop doing.
|
||||
*/
|
||||
void stopChecking(in unsigned short duration);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface describing a global application service that handles performing
|
||||
* background update checks and provides utilities for selecting and
|
||||
* downloading update patches.
|
||||
*/
|
||||
[scriptable, uuid(1107d207-a263-403a-b268-05772ec10757)]
|
||||
interface nsIApplicationUpdateService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Checks for available updates in the background using the listener provided
|
||||
* by the application update service for background checks.
|
||||
*/
|
||||
void checkForBackgroundUpdates();
|
||||
|
||||
/**
|
||||
* The Update Checker used for background update checking.
|
||||
*/
|
||||
readonly attribute nsIUpdateChecker backgroundChecker;
|
||||
|
||||
/**
|
||||
* Selects the best update to install from a list of available updates.
|
||||
* @param updates
|
||||
* An array of updates that are available
|
||||
* @param updateCount
|
||||
* The length of the |updates| array
|
||||
*/
|
||||
nsIUpdate selectUpdate([array, size_is(updateCount)] in nsIUpdate updates,
|
||||
in unsigned long updateCount);
|
||||
|
||||
/**
|
||||
* Adds a listener that receives progress and state information about the
|
||||
* update that is currently being downloaded, e.g. to update a user
|
||||
* interface.
|
||||
* @param listener
|
||||
* An object implementing nsIRequestObserver and optionally
|
||||
* nsIProgressEventSink that is to be notified of state and
|
||||
* progress information as the update is downloaded.
|
||||
*/
|
||||
void addDownloadListener(in nsIRequestObserver listener);
|
||||
|
||||
/**
|
||||
* Removes a listener that is receiving progress and state information
|
||||
* about the update that is currently being downloaded.
|
||||
* @param listener
|
||||
* The listener object to remove.
|
||||
*/
|
||||
void removeDownloadListener(in nsIRequestObserver listener);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
AString downloadUpdate(in nsIUpdate update, in boolean background);
|
||||
|
||||
/**
|
||||
* Apply the OS update which has been downloaded and staged as applied.
|
||||
* @param update
|
||||
* The update has been downloaded and staged as applied.
|
||||
* @throws if the update object is not an OS update.
|
||||
*/
|
||||
void applyOsUpdate(in nsIUpdate update);
|
||||
|
||||
/**
|
||||
* Get the Active Updates directory
|
||||
* @returns An nsIFile for the active updates directory.
|
||||
*/
|
||||
nsIFile getUpdatesDirectory();
|
||||
|
||||
/**
|
||||
* Pauses the active update download process
|
||||
*/
|
||||
void pauseDownload();
|
||||
|
||||
/**
|
||||
* Whether or not there is an download happening at the moment.
|
||||
*/
|
||||
readonly attribute boolean isDownloading;
|
||||
|
||||
/**
|
||||
* Whether or not the Update Service can check for updates. This is a function
|
||||
* of whether or not application update is disabled by the application and the
|
||||
* platform the application is running on.
|
||||
*/
|
||||
readonly attribute boolean canCheckForUpdates;
|
||||
|
||||
/**
|
||||
* Whether or not the installation requires elevation. Currently only
|
||||
* implemented on OSX, returns false on other platforms.
|
||||
*/
|
||||
readonly attribute boolean elevationRequired;
|
||||
|
||||
/**
|
||||
* Whether or not the Update Service can download and install updates.
|
||||
* On Windows, this is a function of whether or not the maintenance service
|
||||
* is installed and enabled. On other systems, and as a fallback on Windows,
|
||||
* this depends on whether the current user has write access to the install
|
||||
* directory.
|
||||
*/
|
||||
readonly attribute boolean canApplyUpdates;
|
||||
|
||||
/**
|
||||
* Whether or not a different instance is handling updates of this
|
||||
* installation. This currently only ever returns true on Windows
|
||||
* when 2 instances of an application are open. Only one of the instances
|
||||
* will actually handle updates for the installation.
|
||||
*/
|
||||
readonly attribute boolean isOtherInstanceHandlingUpdates;
|
||||
|
||||
/**
|
||||
* Whether the Update Service is able to stage updates.
|
||||
*/
|
||||
readonly attribute boolean canStageUpdates;
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface describing a component which handles the job of processing
|
||||
* an update after it's been downloaded.
|
||||
*/
|
||||
[scriptable, uuid(74439497-d796-4915-8cef-3dfe43027e4d)]
|
||||
interface nsIUpdateProcessor : nsISupports
|
||||
{
|
||||
/**
|
||||
* Processes the update which has been downloaded.
|
||||
* This happens without restarting the application.
|
||||
* On Windows, this can also be used for switching to an applied
|
||||
* update request.
|
||||
* @param update The update being applied, or null if this is a switch
|
||||
* to updated application request. Must be non-null on GONK.
|
||||
*/
|
||||
void processUpdate(in nsIUpdate update);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface describing a global application service that maintains a list
|
||||
* of updates previously performed as well as the current active update.
|
||||
*/
|
||||
[scriptable, uuid(0f1098e9-a447-4af9-b030-6f8f35c85f89)]
|
||||
interface nsIUpdateManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Gets the update at the specified index
|
||||
* @param index
|
||||
* The index within the updates array
|
||||
* @returns The nsIUpdate object at the specified index
|
||||
*/
|
||||
nsIUpdate getUpdateAt(in long index);
|
||||
|
||||
/**
|
||||
* Gets the total number of updates in the history list.
|
||||
*/
|
||||
readonly attribute long updateCount;
|
||||
|
||||
/**
|
||||
* The active (current) update. The active update is not in the history list.
|
||||
*/
|
||||
attribute nsIUpdate activeUpdate;
|
||||
|
||||
/**
|
||||
* Saves all updates to disk.
|
||||
*/
|
||||
void saveUpdates();
|
||||
|
||||
/**
|
||||
* Refresh the update status based on the information in update.status.
|
||||
*/
|
||||
void refreshUpdateStatus();
|
||||
|
||||
/**
|
||||
* The user agreed to proceed with an elevated update and we are now
|
||||
* permitted to show an elevation prompt.
|
||||
*/
|
||||
void elevationOptedIn();
|
||||
|
||||
/**
|
||||
* Clean up and remove the active update without applying it.
|
||||
*/
|
||||
void cleanupActiveUpdate();
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface describing an object that can show various kinds of Update
|
||||
* notification UI to the user.
|
||||
*/
|
||||
[scriptable, uuid(cee3bd60-c564-42ff-a2bf-d442cb15f75c)]
|
||||
interface nsIUpdatePrompt : nsISupports
|
||||
{
|
||||
/**
|
||||
* Shows the application update checking user interface and checks if there
|
||||
* is an update available.
|
||||
*/
|
||||
void checkForUpdates();
|
||||
|
||||
/**
|
||||
* Shows the application update available user interface advising that an
|
||||
* update is available for download and install. If the app.update.silent
|
||||
* preference is true or the user interface is already displayed the call will
|
||||
* be a no-op.
|
||||
* @param update
|
||||
* The nsIUpdate object to be downloaded and installed
|
||||
*/
|
||||
void showUpdateAvailable(in nsIUpdate update);
|
||||
|
||||
/**
|
||||
* Shows the application update downloaded user interface advising that an
|
||||
* update has now been downloaded and a restart is necessary to complete the
|
||||
* update. If background is true (e.g. the download was not user initiated)
|
||||
* and the app.update.silent preference is true the call will be a no-op.
|
||||
* @param update
|
||||
* The nsIUpdate object that was downloaded
|
||||
* @param background
|
||||
* Less obtrusive UI, starting with a non-modal notification alert
|
||||
*/
|
||||
void showUpdateDownloaded(in nsIUpdate update,
|
||||
[optional] in boolean background);
|
||||
|
||||
/**
|
||||
* Shows the application update error user interface advising that an error
|
||||
* occurred while checking for or applying an update. If the app.update.silent
|
||||
* preference is true the call will be a no-op.
|
||||
* @param update
|
||||
* An nsIUpdate object representing the update that could not be
|
||||
* installed. The nsIUpdate object will not be the actual update when
|
||||
* the error occurred during an update check and will instead be an
|
||||
* nsIUpdate object with the error information for the update check.
|
||||
*/
|
||||
void showUpdateError(in nsIUpdate update);
|
||||
|
||||
/**
|
||||
* Shows a list of all updates installed to date.
|
||||
* @param parent
|
||||
* An nsIDOMWindow to set as the parent for this window. Can be null.
|
||||
*/
|
||||
void showUpdateHistory(in nsIDOMWindow parent);
|
||||
|
||||
/**
|
||||
* Shows the application update downloaded user interface advising that an
|
||||
* update, which requires elevation, has now been downloaded and a restart is
|
||||
* necessary to complete the update.
|
||||
*/
|
||||
void showUpdateElevationRequired();
|
||||
};
|
||||
4567
toolkit/mozapps/update/nsUpdateService.js
Normal file
4567
toolkit/mozapps/update/nsUpdateService.js
Normal file
File diff suppressed because it is too large
Load diff
12
toolkit/mozapps/update/nsUpdateService.manifest
Normal file
12
toolkit/mozapps/update/nsUpdateService.manifest
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
component {B3C290A6-3943-4B89-8BBE-C01EB7B3B311} nsUpdateService.js
|
||||
contract @mozilla.org/updates/update-service;1 {B3C290A6-3943-4B89-8BBE-C01EB7B3B311}
|
||||
category update-timer nsUpdateService @mozilla.org/updates/update-service;1,getService,background-update-timer,app.update.interval,43200,86400
|
||||
component {093C2356-4843-4C65-8709-D7DBCBBE7DFB} nsUpdateService.js
|
||||
contract @mozilla.org/updates/update-manager;1 {093C2356-4843-4C65-8709-D7DBCBBE7DFB}
|
||||
component {898CDC9B-E43F-422F-9CC4-2F6291B415A3} nsUpdateService.js
|
||||
contract @mozilla.org/updates/update-checker;1 {898CDC9B-E43F-422F-9CC4-2F6291B415A3}
|
||||
component {27ABA825-35B5-4018-9FDD-F99250A0E722} nsUpdateService.js
|
||||
contract @mozilla.org/updates/update-prompt;1 {27ABA825-35B5-4018-9FDD-F99250A0E722}
|
||||
component {e43b0010-04ba-4da6-b523-1f92580bc150} nsUpdateServiceStub.js
|
||||
contract @mozilla.org/updates/update-service-stub;1 {e43b0010-04ba-4da6-b523-1f92580bc150}
|
||||
category profile-after-change nsUpdateServiceStub @mozilla.org/updates/update-service-stub;1
|
||||
45
toolkit/mozapps/update/nsUpdateServiceStub.js
Normal file
45
toolkit/mozapps/update/nsUpdateServiceStub.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm", this);
|
||||
|
||||
const DIR_UPDATES = "updates";
|
||||
const FILE_UPDATE_STATUS = "update.status";
|
||||
|
||||
const KEY_UPDROOT = "UpdRootD";
|
||||
|
||||
/**
|
||||
* Gets the specified directory at the specified hierarchy under the update root
|
||||
* directory without creating it if it doesn't exist.
|
||||
* @param pathArray
|
||||
* An array of path components to locate beneath the directory
|
||||
* specified by |key|
|
||||
* @return nsIFile object for the location specified.
|
||||
*/
|
||||
function getUpdateDirNoCreate(pathArray) {
|
||||
return FileUtils.getDir(KEY_UPDROOT, pathArray, false);
|
||||
}
|
||||
|
||||
function UpdateServiceStub() {
|
||||
let statusFile = getUpdateDirNoCreate([DIR_UPDATES, "0"]);
|
||||
statusFile.append(FILE_UPDATE_STATUS);
|
||||
// If the update.status file exists then initiate post update processing.
|
||||
if (statusFile.exists()) {
|
||||
let aus = Cc["@mozilla.org/updates/update-service;1"].
|
||||
getService(Ci.nsIApplicationUpdateService).
|
||||
QueryInterface(Ci.nsIObserver);
|
||||
aus.observe(null, "post-update-processing", "");
|
||||
}
|
||||
}
|
||||
UpdateServiceStub.prototype = {
|
||||
observe: function() {},
|
||||
classID: Components.ID("{e43b0010-04ba-4da6-b523-1f92580bc150}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdateServiceStub]);
|
||||
39
toolkit/mozapps/update/tests/Makefile.in
Normal file
39
toolkit/mozapps/update/tests/Makefile.in
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPCSHELLTESTROOT = $(topobjdir)/_tests/xpcshell/$(relativesrcdir)
|
||||
|
||||
pp_const_file = $(srcdir)/data/xpcshellConstantsPP.js
|
||||
|
||||
PP_TARGETS += aus-test-const
|
||||
aus-test-const := $(pp_const_file)
|
||||
aus-test-const_PATH := $(XPCSHELLTESTROOT)/data
|
||||
aus-test-const_FLAGS := -Fsubstitution $(DEFINES) $(ACDEFINES)
|
||||
aus-test-const_TARGET := misc
|
||||
|
||||
INI_TEST_FILES = \
|
||||
TestAUSReadStrings1.ini \
|
||||
TestAUSReadStrings2.ini \
|
||||
TestAUSReadStrings3.ini \
|
||||
$(NULL)
|
||||
|
||||
MOZ_WINCONSOLE = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# TestAUSReadStrings runs during check in the following directory with a Unicode
|
||||
# char in order to test bug 473417 on Windows.
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
bug473417dir = test_bug473417-ó
|
||||
else
|
||||
bug473417dir = test_bug473417
|
||||
endif
|
||||
|
||||
check::
|
||||
$(RM) -rf $(DEPTH)/_tests/updater/ && $(NSINSTALL) -D $(DEPTH)/_tests/updater/$(bug473417dir)/
|
||||
for i in $(INI_TEST_FILES); do \
|
||||
$(INSTALL) $(srcdir)/$$i $(DEPTH)/_tests/updater/$(bug473417dir)/; \
|
||||
done
|
||||
$(INSTALL) $(FINAL_TARGET)/TestAUSReadStrings$(BIN_SUFFIX) $(DEPTH)/_tests/updater/$(bug473417dir)/
|
||||
@$(RUN_TEST_PROGRAM) $(DEPTH)/_tests/updater/$(bug473417dir)/TestAUSReadStrings$(BIN_SUFFIX)
|
||||
423
toolkit/mozapps/update/tests/TestAUSHelper.cpp
Normal file
423
toolkit/mozapps/update/tests/TestAUSHelper.cpp
Normal file
|
|
@ -0,0 +1,423 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include <windows.h>
|
||||
# include <wintrust.h>
|
||||
# include <tlhelp32.h>
|
||||
# include <softpub.h>
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
typedef WCHAR NS_tchar;
|
||||
# define NS_main wmain
|
||||
# ifndef F_OK
|
||||
# define F_OK 00
|
||||
# endif
|
||||
# ifndef W_OK
|
||||
# define W_OK 02
|
||||
# endif
|
||||
# ifndef R_OK
|
||||
# define R_OK 04
|
||||
# endif
|
||||
# if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# define stat _stat
|
||||
# endif
|
||||
# define NS_T(str) L ## str
|
||||
# define NS_tsnprintf(dest, count, fmt, ...) \
|
||||
{ \
|
||||
int _count = count - 1; \
|
||||
_snwprintf(dest, _count, fmt, ##__VA_ARGS__); \
|
||||
dest[_count] = L'\0'; \
|
||||
}
|
||||
# define NS_taccess _waccess
|
||||
# define NS_tchdir _wchdir
|
||||
# define NS_tfopen _wfopen
|
||||
# define NS_tstrcmp wcscmp
|
||||
# define NS_ttoi _wtoi
|
||||
# define NS_tstat _wstat
|
||||
# define NS_tgetcwd _wgetcwd
|
||||
# define LOG_S "%S"
|
||||
|
||||
#include "../common/updatehelper.h"
|
||||
#include "../common/certificatecheck.h"
|
||||
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# define NS_main main
|
||||
typedef char NS_tchar;
|
||||
# define NS_T(str) str
|
||||
# define NS_tsnprintf snprintf
|
||||
# define NS_taccess access
|
||||
# define NS_tchdir chdir
|
||||
# define NS_tfopen fopen
|
||||
# define NS_tstrcmp strcmp
|
||||
# define NS_ttoi atoi
|
||||
# define NS_tstat stat
|
||||
# define NS_tgetcwd getcwd
|
||||
# define NS_tfputs fputs
|
||||
# define LOG_S "%s"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# elif defined(MAX_PATH)
|
||||
# define MAXPATHLEN MAX_PATH
|
||||
# elif defined(_MAX_PATH)
|
||||
# define MAXPATHLEN _MAX_PATH
|
||||
# elif defined(CCHMAXPATH)
|
||||
# define MAXPATHLEN CCHMAXPATH
|
||||
# else
|
||||
# define MAXPATHLEN 1024
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static void
|
||||
WriteMsg(const NS_tchar *path, const char *status)
|
||||
{
|
||||
FILE* outFP = NS_tfopen(path, NS_T("wb"));
|
||||
if (!outFP) {
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(outFP, "%s\n", status);
|
||||
fclose(outFP);
|
||||
outFP = nullptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckMsg(const NS_tchar *path, const char *expected)
|
||||
{
|
||||
if (NS_taccess(path, F_OK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE *inFP = NS_tfopen(path, NS_T("rb"));
|
||||
if (!inFP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat ms;
|
||||
if (fstat(fileno(inFP), &ms)) {
|
||||
fclose(inFP);
|
||||
inFP = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
char *mbuf = (char *) malloc(ms.st_size + 1);
|
||||
if (!mbuf) {
|
||||
fclose(inFP);
|
||||
inFP = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t r = ms.st_size;
|
||||
char *rb = mbuf;
|
||||
size_t c = fread(rb, sizeof(char), 50, inFP);
|
||||
r -= c;
|
||||
rb += c;
|
||||
if (c == 0 && r) {
|
||||
free(mbuf);
|
||||
fclose(inFP);
|
||||
inFP = nullptr;
|
||||
return false;
|
||||
}
|
||||
mbuf[ms.st_size] = '\0';
|
||||
rb = mbuf;
|
||||
|
||||
bool isMatch = strcmp(rb, expected) == 0;
|
||||
free(mbuf);
|
||||
fclose(inFP);
|
||||
inFP = nullptr;
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
int NS_main(int argc, NS_tchar **argv)
|
||||
{
|
||||
if (argc == 2) {
|
||||
if (!NS_tstrcmp(argv[1], NS_T("post-update-async")) ||
|
||||
!NS_tstrcmp(argv[1], NS_T("post-update-sync"))) {
|
||||
NS_tchar exePath[MAXPATHLEN];
|
||||
#ifdef XP_WIN
|
||||
if (!::GetModuleFileNameW(0, exePath, MAXPATHLEN)) {
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
strcpy(exePath, argv[0]);
|
||||
#endif
|
||||
NS_tchar runFilePath[MAXPATHLEN];
|
||||
NS_tsnprintf(runFilePath, sizeof(runFilePath)/sizeof(runFilePath[0]),
|
||||
NS_T("%s.running"), exePath);
|
||||
#ifdef XP_WIN
|
||||
if (!NS_taccess(runFilePath, F_OK)) {
|
||||
// This makes it possible to check if the post update process was
|
||||
// launched twice which happens when the service performs an update.
|
||||
NS_tchar runFilePathBak[MAXPATHLEN];
|
||||
NS_tsnprintf(runFilePathBak, sizeof(runFilePathBak)/sizeof(runFilePathBak[0]),
|
||||
NS_T("%s.bak"), runFilePath);
|
||||
MoveFileExW(runFilePath, runFilePathBak, MOVEFILE_REPLACE_EXISTING);
|
||||
}
|
||||
#endif
|
||||
WriteMsg(runFilePath, "running");
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("post-update-sync"))) {
|
||||
#ifdef XP_WIN
|
||||
Sleep(2000);
|
||||
#else
|
||||
sleep(2);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_tchar logFilePath[MAXPATHLEN];
|
||||
NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
|
||||
NS_T("%s.log"), exePath);
|
||||
WriteMsg(logFilePath, "post-update");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, \
|
||||
"\n" \
|
||||
"Application Update Service Test Helper\n" \
|
||||
"\n" \
|
||||
"Usage: WORKINGDIR INFILE OUTFILE -s SECONDS [FILETOLOCK]\n" \
|
||||
" or: WORKINGDIR LOGFILE [ARG2 ARG3...]\n" \
|
||||
" or: signature-check filepath\n" \
|
||||
" or: setup-symlink dir1 dir2 file symlink\n" \
|
||||
" or: remove-symlink dir1 dir2 file symlink\n" \
|
||||
" or: check-symlink symlink\n" \
|
||||
" or: post-update\n" \
|
||||
"\n" \
|
||||
" WORKINGDIR \tThe relative path to the working directory to use.\n" \
|
||||
" INFILE \tThe relative path from the working directory for the file to\n" \
|
||||
" \tread actions to perform such as finish.\n" \
|
||||
" OUTFILE \tThe relative path from the working directory for the file to\n" \
|
||||
" \twrite status information.\n" \
|
||||
" SECONDS \tThe number of seconds to sleep.\n" \
|
||||
" FILETOLOCK \tThe relative path from the working directory to an existing\n" \
|
||||
" \tfile to open exlusively.\n" \
|
||||
" \tOnly available on Windows platforms and silently ignored on\n" \
|
||||
" \tother platforms.\n" \
|
||||
" LOGFILE \tThe relative path from the working directory to log the\n" \
|
||||
" \tcommand line arguments.\n" \
|
||||
" ARG2 ARG3...\tArguments to write to the LOGFILE after the preceding command\n" \
|
||||
" \tline arguments.\n" \
|
||||
"\n" \
|
||||
"Note: All paths must be relative.\n" \
|
||||
"\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("setup-symlink"))) {
|
||||
#ifdef XP_UNIX
|
||||
NS_tchar path[MAXPATHLEN];
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
|
||||
mkdir(path, 0755);
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3]);
|
||||
mkdir(path, 0755);
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3], argv[4]);
|
||||
FILE * file = NS_tfopen(path, NS_T("w"));
|
||||
if (file) {
|
||||
NS_tfputs(NS_T("test"), file);
|
||||
fclose(file);
|
||||
}
|
||||
if (symlink(path, argv[5]) != 0) {
|
||||
return 1;
|
||||
}
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
|
||||
if (argc > 6 && !NS_tstrcmp(argv[6], NS_T("change-perm"))) {
|
||||
chmod(path, 0644);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
// Not implemented on non-Unix platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("remove-symlink"))) {
|
||||
#ifdef XP_UNIX
|
||||
NS_tchar path[MAXPATHLEN];
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
|
||||
chmod(path, 0755);
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3], argv[4]);
|
||||
unlink(path);
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s/%s"), NS_T("/tmp"), argv[2], argv[3]);
|
||||
rmdir(path);
|
||||
NS_tsnprintf(path, sizeof(path)/sizeof(path[0]),
|
||||
NS_T("%s/%s"), NS_T("/tmp"), argv[2]);
|
||||
rmdir(path);
|
||||
return 0;
|
||||
#else
|
||||
// Not implemented on non-Unix platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("check-symlink"))) {
|
||||
#ifdef XP_UNIX
|
||||
struct stat ss;
|
||||
lstat(argv[2], &ss);
|
||||
return S_ISLNK(ss.st_mode) ? 0 : 1;
|
||||
#else
|
||||
// Not implemented on non-Unix platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("wait-for-service-stop"))) {
|
||||
#ifdef XP_WIN
|
||||
const int maxWaitSeconds = NS_ttoi(argv[3]);
|
||||
LPCWSTR serviceName = argv[2];
|
||||
DWORD serviceState = WaitForServiceStop(serviceName, maxWaitSeconds);
|
||||
if (SERVICE_STOPPED == serviceState) {
|
||||
return 0;
|
||||
} else {
|
||||
return serviceState;
|
||||
}
|
||||
#else
|
||||
// Not implemented on non-Windows platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("wait-for-application-exit"))) {
|
||||
#ifdef XP_WIN
|
||||
const int maxWaitSeconds = NS_ttoi(argv[3]);
|
||||
LPCWSTR application = argv[2];
|
||||
DWORD ret = WaitForProcessExit(application, maxWaitSeconds);
|
||||
if (ERROR_SUCCESS == ret) {
|
||||
return 0;
|
||||
} else if (WAIT_TIMEOUT == ret) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
#else
|
||||
// Not implemented on non-Windows platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("is-process-running"))) {
|
||||
#ifdef XP_WIN
|
||||
LPCWSTR application = argv[2];
|
||||
return (ERROR_NOT_FOUND == IsProcessRunning(application)) ? 0 : 1;
|
||||
#else
|
||||
// Not implemented on non-Windows platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NS_tstrcmp(argv[1], NS_T("launch-service"))) {
|
||||
#ifdef XP_WIN
|
||||
DWORD ret = LaunchServiceSoftwareUpdateCommand(argc - 2, (LPCWSTR *)argv + 2);
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
// 192 is used to avoid reusing a possible return value from the call to
|
||||
// WaitForServiceStop
|
||||
return 0x000000C0;
|
||||
}
|
||||
// Wait a maximum of 120 seconds.
|
||||
DWORD lastState = WaitForServiceStop(SVC_NAME, 120);
|
||||
if (SERVICE_STOPPED == lastState) {
|
||||
return 0;
|
||||
}
|
||||
return lastState;
|
||||
#else
|
||||
// Not implemented on non-Windows platforms
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (NS_tchdir(argv[1]) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// File in use test helper section
|
||||
if (!NS_tstrcmp(argv[4], NS_T("-s"))) {
|
||||
NS_tchar *cwd = NS_tgetcwd(nullptr, 0);
|
||||
NS_tchar inFilePath[MAXPATHLEN];
|
||||
NS_tsnprintf(inFilePath, sizeof(inFilePath)/sizeof(inFilePath[0]),
|
||||
NS_T("%s/%s"), cwd, argv[2]);
|
||||
NS_tchar outFilePath[MAXPATHLEN];
|
||||
NS_tsnprintf(outFilePath, sizeof(outFilePath)/sizeof(outFilePath[0]),
|
||||
NS_T("%s/%s"), cwd, argv[3]);
|
||||
|
||||
int seconds = NS_ttoi(argv[5]);
|
||||
#ifdef XP_WIN
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
if (argc == 7) {
|
||||
hFile = CreateFileW(argv[6],
|
||||
DELETE | GENERIC_WRITE, 0,
|
||||
nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
WriteMsg(outFilePath, "error_locking");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
WriteMsg(outFilePath, "sleeping");
|
||||
int i = 0;
|
||||
while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds) {
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
if (argc == 7) {
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
#else
|
||||
WriteMsg(outFilePath, "sleeping");
|
||||
int i = 0;
|
||||
while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds) {
|
||||
sleep(1);
|
||||
}
|
||||
#endif
|
||||
WriteMsg(outFilePath, "finished");
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
// Command line argument test helper section
|
||||
NS_tchar logFilePath[MAXPATHLEN];
|
||||
NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
|
||||
NS_T("%s"), argv[2]);
|
||||
|
||||
FILE* logFP = NS_tfopen(logFilePath, NS_T("wb"));
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
fprintf(logFP, LOG_S "\n", argv[i]);
|
||||
}
|
||||
|
||||
fclose(logFP);
|
||||
logFP = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
172
toolkit/mozapps/update/tests/TestAUSReadStrings.cpp
Normal file
172
toolkit/mozapps/update/tests/TestAUSReadStrings.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This binary tests the updater's ReadStrings ini parser and should run in a
|
||||
* directory with a Unicode character to test bug 473417.
|
||||
*/
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#define NS_main wmain
|
||||
#define NS_tstrrchr wcsrchr
|
||||
#define NS_T(str) L ## str
|
||||
#define PATH_SEPARATOR_CHAR L'\\'
|
||||
// On Windows, argv[0] can also have forward slashes instead
|
||||
#define ALT_PATH_SEPARATOR_CHAR L'/'
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define NS_main main
|
||||
#define NS_tstrrchr strrchr
|
||||
#define NS_T(str) str
|
||||
#define PATH_SEPARATOR_CHAR '/'
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "updater/resource.h"
|
||||
#include "updater/progressui.h"
|
||||
#include "common/readstrings.h"
|
||||
#include "common/errors.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# elif defined(MAX_PATH)
|
||||
# define MAXPATHLEN MAX_PATH
|
||||
# elif defined(_MAX_PATH)
|
||||
# define MAXPATHLEN _MAX_PATH
|
||||
# elif defined(CCHMAXPATH)
|
||||
# define MAXPATHLEN CCHMAXPATH
|
||||
# else
|
||||
# define MAXPATHLEN 1024
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define TEST_NAME "Updater ReadStrings"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static int gFailCount = 0;
|
||||
|
||||
/**
|
||||
* Prints the given failure message and arguments using printf, prepending
|
||||
* "TEST-UNEXPECTED-FAIL " for the benefit of the test harness and
|
||||
* appending "\n" to eliminate having to type it at each call site.
|
||||
*/
|
||||
void fail(const char* msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
printf("TEST-UNEXPECTED-FAIL | ");
|
||||
|
||||
va_start(ap, msg);
|
||||
vprintf(msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
putchar('\n');
|
||||
++gFailCount;
|
||||
}
|
||||
|
||||
int NS_main(int argc, NS_tchar **argv)
|
||||
{
|
||||
printf("Running TestAUSReadStrings tests\n");
|
||||
|
||||
int rv = 0;
|
||||
int retval;
|
||||
NS_tchar inifile[MAXPATHLEN];
|
||||
StringTable testStrings;
|
||||
|
||||
NS_tchar *slash = NS_tstrrchr(argv[0], PATH_SEPARATOR_CHAR);
|
||||
#ifdef ALT_PATH_SEPARATOR_CHAR
|
||||
NS_tchar *altslash = NS_tstrrchr(argv[0], ALT_PATH_SEPARATOR_CHAR);
|
||||
slash = (slash > altslash) ? slash : altslash;
|
||||
#endif // ALT_PATH_SEPARATOR_CHAR
|
||||
|
||||
if (!slash) {
|
||||
fail("%s | unable to find platform specific path separator (check 1)", TEST_NAME);
|
||||
return 20;
|
||||
}
|
||||
|
||||
*(++slash) = '\0';
|
||||
// Test success when the ini file exists with both Title and Info in the
|
||||
// Strings section and the values for Title and Info.
|
||||
NS_tsnprintf(inifile, ArrayLength(inifile), NS_T("%sTestAUSReadStrings1.ini"), argv[0]);
|
||||
retval = ReadStrings(inifile, &testStrings);
|
||||
if (retval == OK) {
|
||||
if (strcmp(testStrings.title, "Title Test - \xD0\x98\xD1\x81\xD0\xBF\xD1\x8B" \
|
||||
"\xD1\x82\xD0\xB0\xD0\xBD\xD0\xB8\xD0\xB5 " \
|
||||
"\xCE\x94\xCE\xBF\xCE\xBA\xCE\xB9\xCE\xBC\xCE\xAE " \
|
||||
"\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88 " \
|
||||
"\xE6\xB8\xAC\xE8\xA9\xA6 " \
|
||||
"\xE6\xB5\x8B\xE8\xAF\x95") != 0) {
|
||||
rv = 21;
|
||||
fail("%s | Title ini value incorrect (check 3)", TEST_NAME);
|
||||
}
|
||||
|
||||
if (strcmp(testStrings.info, "Info Test - \xD0\x98\xD1\x81\xD0\xBF\xD1\x8B" \
|
||||
"\xD1\x82\xD0\xB0\xD0\xBD\xD0\xB8\xD0\xB5 " \
|
||||
"\xCE\x94\xCE\xBF\xCE\xBA\xCE\xB9\xCE\xBC\xCE\xAE " \
|
||||
"\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88 " \
|
||||
"\xE6\xB8\xAC\xE8\xA9\xA6 " \
|
||||
"\xE6\xB5\x8B\xE8\xAF\x95\xE2\x80\xA6") != 0) {
|
||||
rv = 22;
|
||||
fail("%s | Info ini value incorrect (check 4)", TEST_NAME);
|
||||
}
|
||||
} else {
|
||||
fail("%s | ReadStrings returned %i (check 2)", TEST_NAME, retval);
|
||||
rv = 23;
|
||||
}
|
||||
|
||||
// Test failure when the ini file exists without Title and with Info in the
|
||||
// Strings section.
|
||||
NS_tsnprintf(inifile, ArrayLength(inifile), NS_T("%sTestAUSReadStrings2.ini"), argv[0]);
|
||||
retval = ReadStrings(inifile, &testStrings);
|
||||
if (retval != PARSE_ERROR) {
|
||||
rv = 24;
|
||||
fail("%s | ReadStrings returned %i (check 5)", TEST_NAME, retval);
|
||||
}
|
||||
|
||||
// Test failure when the ini file exists with Title and without Info in the
|
||||
// Strings section.
|
||||
NS_tsnprintf(inifile, ArrayLength(inifile), NS_T("%sTestAUSReadStrings3.ini"), argv[0]);
|
||||
retval = ReadStrings(inifile, &testStrings);
|
||||
if (retval != PARSE_ERROR) {
|
||||
rv = 25;
|
||||
fail("%s | ReadStrings returned %i (check 6)", TEST_NAME, retval);
|
||||
}
|
||||
|
||||
// Test failure when the ini file doesn't exist
|
||||
NS_tsnprintf(inifile, ArrayLength(inifile), NS_T("%sTestAUSReadStringsBogus.ini"), argv[0]);
|
||||
retval = ReadStrings(inifile, &testStrings);
|
||||
if (retval != READ_ERROR) {
|
||||
rv = 26;
|
||||
fail("%s | ini file doesn't exist (check 7)", TEST_NAME);
|
||||
}
|
||||
|
||||
// Test reading a non-default section name
|
||||
NS_tsnprintf(inifile, ArrayLength(inifile), NS_T("%sTestAUSReadStrings3.ini"), argv[0]);
|
||||
retval = ReadStrings(inifile, "Title\0", 1, &testStrings.title, "BogusSection2");
|
||||
if (retval == OK) {
|
||||
if (strcmp(testStrings.title, "Bogus Title") != 0) {
|
||||
rv = 27;
|
||||
fail("%s | Title ini value incorrect (check 9)", TEST_NAME);
|
||||
}
|
||||
} else {
|
||||
fail("%s | ReadStrings returned %i (check 8)", TEST_NAME, retval);
|
||||
rv = 28;
|
||||
}
|
||||
|
||||
|
||||
if (rv == 0) {
|
||||
printf("TEST-PASS | %s | all checks passed\n", TEST_NAME);
|
||||
} else {
|
||||
fail("%s | %i out of 9 checks failed", TEST_NAME, gFailCount);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
47
toolkit/mozapps/update/tests/TestAUSReadStrings1.ini
Normal file
47
toolkit/mozapps/update/tests/TestAUSReadStrings1.ini
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
; This file is in the UTF-8 encoding
|
||||
|
||||
[BogusSection1]
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Bogus Title
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Bogus Info
|
||||
|
||||
; Comment
|
||||
|
||||
[Strings]
|
||||
|
||||
Bogus1=Bogus1
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Title Test - Испытание Δοκιμή テスト 測試 测试
|
||||
|
||||
; Comment
|
||||
|
||||
Bogus2=Bogus2
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Info Test - Испытание Δοκιμή テスト 測試 测试…
|
||||
|
||||
; Comment
|
||||
|
||||
Bogus3=Bogus3
|
||||
|
||||
; Comment
|
||||
|
||||
[BogusSection2]
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Bogus Title
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Bogus Info
|
||||
|
||||
; Comment
|
||||
39
toolkit/mozapps/update/tests/TestAUSReadStrings2.ini
Normal file
39
toolkit/mozapps/update/tests/TestAUSReadStrings2.ini
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
; This file is in the UTF-8 encoding
|
||||
|
||||
[BogusSection1]
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Bogus Title
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Bogus Info
|
||||
|
||||
; Comment
|
||||
|
||||
[Strings]
|
||||
|
||||
Bogus1=Bogus1
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Info
|
||||
|
||||
; Comment
|
||||
|
||||
Bogus2=Bogus2
|
||||
|
||||
; Comment
|
||||
|
||||
[BogusSection2]
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Bogus Title
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Bogus Info
|
||||
|
||||
; Comment
|
||||
39
toolkit/mozapps/update/tests/TestAUSReadStrings3.ini
Normal file
39
toolkit/mozapps/update/tests/TestAUSReadStrings3.ini
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
; This file is in the UTF-8 encoding
|
||||
|
||||
[BogusSection1]
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Bogus Title
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Bogus Info
|
||||
|
||||
; Comment
|
||||
|
||||
[Strings]
|
||||
|
||||
Bogus1=Bogus1
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Title
|
||||
|
||||
; Comment
|
||||
|
||||
Bogus2=Bogus2
|
||||
|
||||
; Comment
|
||||
|
||||
[BogusSection2]
|
||||
|
||||
; Comment
|
||||
|
||||
Title=Bogus Title
|
||||
|
||||
; Comment
|
||||
|
||||
Info=Bogus Info
|
||||
|
||||
; Comment
|
||||
7
toolkit/mozapps/update/tests/chrome/.eslintrc.js
Normal file
7
toolkit/mozapps/update/tests/chrome/.eslintrc.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/mochitest/chrome.eslintrc.js"
|
||||
]
|
||||
};
|
||||
64
toolkit/mozapps/update/tests/chrome/chrome.ini
Normal file
64
toolkit/mozapps/update/tests/chrome/chrome.ini
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[DEFAULT]
|
||||
tags = appupdate
|
||||
support-files =
|
||||
utils.js
|
||||
update.sjs
|
||||
|
||||
; mochitest-chrome tests must start with "test_" and are executed in sorted
|
||||
; order and not in the order specified in the manifest.
|
||||
[test_0010_background_basic.xul]
|
||||
[test_0011_check_basic.xul]
|
||||
[test_0012_check_basic_staging.xul]
|
||||
skip-if = asan
|
||||
reason = Bug 1168003
|
||||
[test_0013_check_no_updates.xul]
|
||||
[test_0014_check_error_xml_malformed.xul]
|
||||
[test_0061_check_verifyFailPartial_noComplete.xul]
|
||||
[test_0062_check_verifyFailComplete_noPartial.xul]
|
||||
[test_0063_check_verifyFailPartialComplete.xul]
|
||||
[test_0064_check_verifyFailPartial_successComplete.xul]
|
||||
[test_0071_notify_verifyFailPartial_noComplete.xul]
|
||||
[test_0072_notify_verifyFailComplete_noPartial.xul]
|
||||
[test_0073_notify_verifyFailPartialComplete.xul]
|
||||
[test_0074_notify_verifyFailPartial_successComplete.xul]
|
||||
[test_0081_error_patchApplyFailure_partial_only.xul]
|
||||
[test_0082_error_patchApplyFailure_complete_only.xul]
|
||||
[test_0083_error_patchApplyFailure_partial_complete.xul]
|
||||
[test_0084_error_patchApplyFailure_verify_failed.xul]
|
||||
[test_0085_error_patchApplyFailure_partial_complete_staging.xul]
|
||||
skip-if = asan
|
||||
reason = Bug 1168003
|
||||
[test_0092_finishedBackground.xul]
|
||||
[test_0093_restartNotification.xul]
|
||||
[test_0094_restartNotification_remote.xul]
|
||||
[test_0095_restartNotification_remoteInvalidNumber.xul]
|
||||
[test_0096_restartNotification_stagedBackground.xul]
|
||||
skip-if = asan
|
||||
reason = Bug 1168003
|
||||
[test_0097_restartNotification_stagedServiceBackground.xul]
|
||||
skip-if = os != 'win'
|
||||
reason = only Windows has the maintenance service.
|
||||
[test_0101_background_restartNotification.xul]
|
||||
[test_0102_background_restartNotification_staging.xul]
|
||||
skip-if = asan
|
||||
reason = Bug 1168003
|
||||
[test_0103_background_restartNotification_stagingService.xul]
|
||||
skip-if = os != 'win'
|
||||
reason = only Windows has the maintenance service.
|
||||
[test_0111_neverButton_basic.xul]
|
||||
[test_0113_showNeverForVersionRemovedWithPref.xul]
|
||||
[test_0151_notify_backgroundCheckError.xul]
|
||||
[test_0152_notify_backgroundCheckOfflineRetry.xul]
|
||||
[test_0161_check_unsupported.xul]
|
||||
[test_0162_notify_unsupported.xul]
|
||||
[test_0171_check_noPerms_manual.xul]
|
||||
skip-if = os != 'win'
|
||||
reason = test must be able to prevent file deletion.
|
||||
[test_0172_notify_noPerms_manual.xul]
|
||||
skip-if = os != 'win'
|
||||
reason = test must be able to prevent file deletion.
|
||||
[test_9999_cleanup.xul]
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: basic, download, and finished"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_FINISHED,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&showPrompt=1" +
|
||||
getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gAUS.checkForBackgroundUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check, basic, download, and finished"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_FINISHED,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check, basic, download with staging, and finished"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_FINISHED,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
gUseTestUpdater = true;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check and no updates found"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_NO_UPDATES_FOUND,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?noUpdates=1";
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check and error (xml malformed)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?xmlMalformed=1";
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check, basic, download, and errors (partial patch with an invalid size)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&partialPatchOnly=1" +
|
||||
"&invalidPartialSize=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check, basic, download, and errors (complete patch with an invalid size)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&completePatchOnly=1" +
|
||||
"&invalidCompleteSize=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check, basic, download, and errors (partial and complete patches with invalid sizes)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&invalidPartialSize=1" +
|
||||
"&invalidCompleteSize=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check, basic, download, and finished (partial patch with an invalid size and successful complete patch)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_FINISHED,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&invalidPartialSize=1" +
|
||||
getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: errors (partial patch with an invalid size)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("partial", null, null, null, "1234", null,
|
||||
STATE_DOWNLOADING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version,
|
||||
Services.appinfo.platformVersion);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_DOWNLOADING);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: errors (complete patch with an invalid size)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, "1234", null,
|
||||
STATE_DOWNLOADING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_DOWNLOADING);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: errors (partial and complete patches with invalid sizes)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("partial", null, null, null, "1234", null,
|
||||
STATE_DOWNLOADING) +
|
||||
getLocalPatchString("complete", null, null, null, "1234",
|
||||
"false");
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, "false");
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_DOWNLOADING);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: finishedBackground (partial patch with an invalid size and successful complete patch)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("partial", null, null, null, "1234", null,
|
||||
STATE_DOWNLOADING) +
|
||||
getLocalPatchString("complete", null, null, null, null,
|
||||
"false");
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, "false");
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_DOWNLOADING);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: errors (partial only patch apply failure)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("partial", null, null, null, null, null,
|
||||
STATE_PENDING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, "false");
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_FAILED_CRC_ERROR);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: errors (complete only patch apply failure)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_PENDING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_FAILED_CRC_ERROR);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: error patching, download, and finished (partial failed and download complete)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERROR_PATCHING,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING,
|
||||
extraStartFunction: createContinueFile
|
||||
}, {
|
||||
pageid: PAGEID_FINISHED,
|
||||
buttonClick: "extra1",
|
||||
extraStartFunction: removeContinueFile
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
removeContinueFile();
|
||||
|
||||
// Specify the url to update.sjs with a slowDownloadMar param so the ui can
|
||||
// load before the download completes.
|
||||
let slowDownloadURL = URL_HTTP_UPDATE_XML + "?slowDownloadMar=1";
|
||||
let patches = getLocalPatchString("partial", null, null, null, null, null,
|
||||
STATE_PENDING) +
|
||||
getLocalPatchString("complete", slowDownloadURL, null, null,
|
||||
null, "false");
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, "false");
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_FAILED_CRC_ERROR);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: error patching, download, and errors (partial failed and download complete verification failure)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERROR_PATCHING,
|
||||
buttonClick: "next"
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING,
|
||||
extraStartFunction: createContinueFile
|
||||
}, {
|
||||
pageid: PAGEID_ERRORS,
|
||||
buttonClick: "finish",
|
||||
extraStartFunction: removeContinueFile
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
removeContinueFile();
|
||||
|
||||
// Specify the url to update.sjs with a slowDownloadMar param so the ui can
|
||||
// load before the download completes.
|
||||
let slowDownloadURL = URL_HTTP_UPDATE_XML + "?slowDownloadMar=1";
|
||||
let patches = getLocalPatchString("partial", null, null, null, null, null,
|
||||
STATE_PENDING) +
|
||||
getLocalPatchString("complete", slowDownloadURL, "MD5",
|
||||
null, "1234",
|
||||
"false");
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, "false");
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_FAILED_CRC_ERROR);
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: error patching, download with staging, and finished (partial failed and download complete), with fast MAR download"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
// This test forces the download to complete before the "next" button on the
|
||||
// errorpatching wizard page is clicked. This is done by creating the continue
|
||||
// file when the wizard loads to start the download, then clicking the "next"
|
||||
// button in the download's onStopRequest event listener.
|
||||
|
||||
const testDownloadListener = {
|
||||
onStartRequest(aRequest, aContext) { },
|
||||
|
||||
onProgress(aRequest, aContext, aProgress, aMaxProgress) { },
|
||||
|
||||
onStatus(aRequest, aContext, aStatus, aStatusText) { },
|
||||
|
||||
onStopRequest(aRequest, aContext, aStatus) {
|
||||
debugDump("clicking errorpatching page next button");
|
||||
gDocElem.getButton("next").click();
|
||||
gAUS.removeDownloadListener(this);
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
|
||||
Ci.nsIProgressEventSink])
|
||||
};
|
||||
|
||||
let TESTS = [ {
|
||||
pageid: PAGEID_ERROR_PATCHING,
|
||||
extraCheckFunction: createContinueFile
|
||||
}, {
|
||||
pageid: PAGEID_DOWNLOADING
|
||||
}, {
|
||||
pageid: PAGEID_FINISHED,
|
||||
buttonClick: "extra1",
|
||||
extraStartFunction: removeContinueFile
|
||||
} ];
|
||||
|
||||
gUseTestUpdater = true;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
removeContinueFile();
|
||||
|
||||
// Specify the url to update.sjs with a slowDownloadMar param so the ui can
|
||||
// load before the download completes.
|
||||
let slowDownloadURL = URL_HTTP_UPDATE_XML + "?slowDownloadMar=1";
|
||||
let patches = getLocalPatchString("partial", null, null, null, null, null,
|
||||
STATE_PENDING) +
|
||||
getLocalPatchString("complete", slowDownloadURL, null, null,
|
||||
null, "false");
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, "false");
|
||||
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_FAILED_READ_ERROR);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
testPostUpdateProcessing();
|
||||
|
||||
gAUS.addDownloadListener(testDownloadListener);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: finished background"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_PENDING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version,
|
||||
Services.appinfo.platformVersion);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_SUCCEEDED);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
is(gUpdateManager.activeUpdate.state, "pending",
|
||||
"The active update should have a state of pending");
|
||||
|
||||
gUP.showUpdateDownloaded(gUpdateManager.activeUpdate);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: restart notification pref promptWaitTime"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_PENDING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_SUCCEEDED);
|
||||
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
is(gUpdateManager.activeUpdate.state, STATE_PENDING,
|
||||
"The active update should have a state of " + STATE_PENDING);
|
||||
|
||||
ok(gUpdateManager.activeUpdate.promptWaitTime == 1, "Checking that the " +
|
||||
"update's promptWaitTime attribute value was set from the " +
|
||||
PREF_APP_UPDATE_PROMPTWAITTIME + " preference");
|
||||
|
||||
gUP.showUpdateDownloaded(gUpdateManager.activeUpdate, true);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: restart notification xml promptWaitTime"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_PENDING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version, null,
|
||||
null, null, null, null, false,
|
||||
null, false, false, false, 1);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_SUCCEEDED);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
is(gUpdateManager.activeUpdate.state, STATE_PENDING,
|
||||
"The active update should have a state of " + STATE_PENDING);
|
||||
|
||||
ok(gUpdateManager.activeUpdate.promptWaitTime == 1, "Checking that the " +
|
||||
"update's promptWaitTime attribute value was set by the XML");
|
||||
|
||||
gUP.showUpdateDownloaded(gUpdateManager.activeUpdate, true);
|
||||
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: restart notification xml promptWaitTime with invalid number"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_PENDING);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version,
|
||||
null, null,
|
||||
null, null, null,
|
||||
null, false, null,
|
||||
false, false,
|
||||
false, "invalidNumber");
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_SUCCEEDED);
|
||||
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
is(gUpdateManager.activeUpdate.state, STATE_PENDING,
|
||||
"The active update should have a state of " + STATE_PENDING);
|
||||
|
||||
ok(gUpdateManager.activeUpdate.promptWaitTime == 1, "Checking that the " +
|
||||
"update's promptWaitTime attribute value was set from the " +
|
||||
PREF_APP_UPDATE_PROMPTWAITTIME + " preference");
|
||||
|
||||
gUP.showUpdateDownloaded(gUpdateManager.activeUpdate, true);
|
||||
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: restart notification staged w/o service"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
gUseTestUpdater = true;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_APPLIED);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version,
|
||||
Services.appinfo.platformVersion);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_APPLIED);
|
||||
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, false);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
is(gUpdateManager.activeUpdate.state, STATE_APPLIED,
|
||||
"The active update should have a state of " + STATE_APPLIED);
|
||||
|
||||
ok(gUpdateManager.activeUpdate.promptWaitTime == 1, "Checking that the " +
|
||||
"update's promptWaitTime attribute value was set from the " +
|
||||
PREF_APP_UPDATE_PROMPTWAITTIME + " preference");
|
||||
|
||||
gUpdateManager.refreshUpdateStatus();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: restart notification staged with service"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
gUseTestUpdater = true;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let patches = getLocalPatchString("complete", null, null, null, null, null,
|
||||
STATE_APPLIED_SVC);
|
||||
let updates = getLocalUpdateString(patches, null, null, null,
|
||||
Services.appinfo.version,
|
||||
Services.appinfo.platformVersion);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(updates), true);
|
||||
writeUpdatesToXMLFile(getLocalUpdatesXMLString(""), false);
|
||||
writeStatusFile(STATE_APPLIED_SVC);
|
||||
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, true);
|
||||
|
||||
reloadUpdateManagerData();
|
||||
|
||||
is(gUpdateManager.activeUpdate.state, STATE_APPLIED_SVC,
|
||||
"The active update should have a state of " + STATE_APPLIED_SVC);
|
||||
|
||||
ok(gUpdateManager.activeUpdate.promptWaitTime == 1, "Checking that the " +
|
||||
"update's promptWaitTime attribute value was set from the " +
|
||||
PREF_APP_UPDATE_PROMPTWAITTIME + " preference");
|
||||
|
||||
gUpdateManager.refreshUpdateStatus();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: background finish with a background download"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gAUS.notify(null);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: background finish with a background download and update staging"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
gUseTestUpdater = true;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gAUS.notify(null);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: background finish with a background download and update staging and servicefs"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FINISHED_BKGRD,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
gUseTestUpdater = true;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, true);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_SERVICE_ENABLED, true);
|
||||
Services.prefs.setIntPref(PREF_APP_UPDATE_PROMPTWAITTIME, 1);
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gAUS.notify(null);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update check and basic (never button test)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
gPrefToCheck = PREFBRANCH_APP_UPDATE_NEVER + Services.appinfo.version;
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
extraDelayedCheckFunction: checkPrefHasUserValue,
|
||||
prefHasUserValue: false,
|
||||
neverButton: true,
|
||||
buttonClick: "extra2"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showNever=1&showDetails=1" +
|
||||
getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
// add the never preference for this version to verify that checking for
|
||||
// updates clears the preference.
|
||||
Services.prefs.setBoolPref(gPrefToCheck, true)
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
checkPrefHasUserValue(true);
|
||||
finishTestDefault();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: update available with never pref and without showNeverForVersion"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
gPrefToCheck = PREFBRANCH_APP_UPDATE_NEVER + Services.appinfo.version;
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
extraDelayedCheckFunction: checkPrefHasUserValue,
|
||||
prefHasUserValue: true,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&showPrompt=1" +
|
||||
getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
// add the never preference for this version to verify that checking for
|
||||
// updates clears the preference.
|
||||
Services.prefs.setBoolPref(gPrefToCheck, true)
|
||||
|
||||
gAUS.notify(null);
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
Services.prefs.clearUserPref(gPrefToCheck)
|
||||
finishTestDefault();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Test notification when multiple background check errors occur (bug 595455)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_ERROR_EXTRA,
|
||||
extraDelayedCheckFunction: checkErrorExtraPage,
|
||||
shouldBeHidden: false,
|
||||
displayedTextElem: "bgErrorLabel",
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?xmlMalformed=1";
|
||||
setUpdateURL(url);
|
||||
|
||||
errorsPrefObserver.init(PREF_APP_UPDATE_BACKGROUNDERRORS,
|
||||
PREF_APP_UPDATE_BACKGROUNDMAXERRORS);
|
||||
|
||||
gAUS.notify(null);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Test that an update check that fails due to being offline is performed after going online"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_FOUND_BASIC,
|
||||
buttonClick: "extra1"
|
||||
} ];
|
||||
|
||||
const NETWORK_ERROR_OFFLINE = 111;
|
||||
var gProxyPrefValue;
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_AUTO, false);
|
||||
|
||||
Services.io.offline = true;
|
||||
gProxyPrefValue = Services.prefs.getIntPref("network.proxy.type");
|
||||
Services.prefs.setIntPref("network.proxy.type", 0);
|
||||
|
||||
gUpdateChecker.checkForUpdates(updateCheckListener, true);
|
||||
}
|
||||
|
||||
function resetOffline() {
|
||||
Services.prefs.setIntPref("network.proxy.type", gProxyPrefValue);
|
||||
Services.io.offline = false;
|
||||
}
|
||||
|
||||
/* Update check listener */
|
||||
const updateCheckListener = {
|
||||
onProgress: function UCL_onProgress(aRequest, aPosition, aTotalSize) {
|
||||
},
|
||||
|
||||
onCheckComplete: function UCL_onCheckComplete(aRequest, aUpdates, aUpdateCount) {
|
||||
let status = aRequest.status;
|
||||
if (status == 0) {
|
||||
status = aRequest.channel.QueryInterface(Ci.nsIRequest).status;
|
||||
}
|
||||
debugDump("url = " + aRequest.channel.originalURI.spec + ", " +
|
||||
"request.status = " + status + ", " +
|
||||
"updateCount = " + aUpdateCount);
|
||||
ok(false, "Unexpected updateCheckListener::onCheckComplete called");
|
||||
},
|
||||
|
||||
onError: function UCL_onError(aRequest, aUpdate) {
|
||||
let status = aRequest.status;
|
||||
if (status == 0) {
|
||||
status = aRequest.channel.QueryInterface(Ci.nsIRequest).status;
|
||||
}
|
||||
is(status, Cr.NS_ERROR_OFFLINE,
|
||||
"checking the request status value");
|
||||
is(aUpdate.errorCode, NETWORK_ERROR_OFFLINE,
|
||||
"checking the update error code");
|
||||
debugDump("url = " + aRequest.channel.originalURI.spec + ", " +
|
||||
"request.status = " + status + ", " +
|
||||
"update.statusText = " +
|
||||
(aUpdate.statusText ? aUpdate.statusText : "null"));
|
||||
gAUS.onError(aRequest, aUpdate);
|
||||
// Use a timeout to allow the XHR to complete
|
||||
SimpleTest.executeSoon(resetOffline);
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener])
|
||||
};
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Test checking for updates when system is no longer supported (bug 843497)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_UNSUPPORTED,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
// When checking manually the unsupported page should still be shown even if
|
||||
// it was shown previously.
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED, true);
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?unsupported=1";
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Test notification of updates when system is no longer supported (bug 843497)"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_UNSUPPORTED,
|
||||
buttonClick: "finish"
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?unsupported=1";
|
||||
setUpdateURL(url);
|
||||
|
||||
gAUS.notify(null);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: manual"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_CHECKING
|
||||
}, {
|
||||
pageid: PAGEID_MANUAL_UPDATE,
|
||||
buttonClick: "finish",
|
||||
extraCheckFunction: getWriteTestFile
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let file = getWriteTestFile();
|
||||
file.create(file.NORMAL_FILE_TYPE, 0o444);
|
||||
file.fileAttributesWin |= file.WFA_READONLY;
|
||||
file.fileAttributesWin &= ~file.WFA_READWRITE;
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gUP.checkForUpdates();
|
||||
}
|
||||
|
||||
function getWriteTestFile() {
|
||||
let file = getAppBaseDir();
|
||||
file.append(FILE_UPDATE_TEST);
|
||||
file.QueryInterface(Ci.nsILocalFileWin);
|
||||
if (file.exists()) {
|
||||
file.fileAttributesWin |= file.WFA_READWRITE;
|
||||
file.fileAttributesWin &= ~file.WFA_READONLY;
|
||||
file.remove(true);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Update Wizard pages: manual"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTestDefault();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const TESTS = [ {
|
||||
pageid: PAGEID_MANUAL_UPDATE,
|
||||
buttonClick: "finish",
|
||||
extraCheckFunction: getWriteTestFile
|
||||
} ];
|
||||
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
let file = getWriteTestFile();
|
||||
file.create(file.NORMAL_FILE_TYPE, 0o444);
|
||||
file.fileAttributesWin |= file.WFA_READONLY;
|
||||
file.fileAttributesWin &= ~file.WFA_READWRITE;
|
||||
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1&showPrompt=1" +
|
||||
getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
gAUS.checkForBackgroundUpdates();
|
||||
}
|
||||
|
||||
function getWriteTestFile() {
|
||||
let file = getAppBaseDir();
|
||||
file.append(FILE_UPDATE_TEST);
|
||||
file.QueryInterface(Ci.nsILocalFileWin);
|
||||
if (file.exists()) {
|
||||
file.fileAttributesWin |= file.WFA_READWRITE;
|
||||
file.fileAttributesWin &= ~file.WFA_READONLY;
|
||||
file.remove(true);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
112
toolkit/mozapps/update/tests/chrome/test_9999_cleanup.xul
Normal file
112
toolkit/mozapps/update/tests/chrome/test_9999_cleanup.xul
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removes files and preferences for previous application update tests in case
|
||||
* any of them had a fatal error. The test name ensures that it will run after
|
||||
* all other tests as long as the test naming uses the same format as the
|
||||
* existing tests.
|
||||
*/
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Application Update test cleanup"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="runTest();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="utils.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/**
|
||||
* If the application update tests left behind any of the files it uses it could
|
||||
* be a very bad thing. The purpose of this test is to prevent that from
|
||||
* happening.
|
||||
*/
|
||||
function runTest() {
|
||||
debugDump("entering");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
if (DEBUG_AUS_TEST) {
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_LOG, true);
|
||||
}
|
||||
|
||||
closeUpdateWindow();
|
||||
|
||||
// Always leave the app.update.enabled and app.update.staging.enabled
|
||||
// preferences set to false when cleaning up.
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, false);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_STAGING_ENABLED, false);
|
||||
|
||||
resetFiles();
|
||||
removeUpdateDirsAndFiles();
|
||||
reloadUpdateManagerData();
|
||||
|
||||
let file = getUpdatesXMLFile(true);
|
||||
ok(!file.exists(), file.path + " should not exist");
|
||||
|
||||
file = getUpdatesXMLFile(false);
|
||||
ok(!file.exists(), file.path + " should not exist");
|
||||
|
||||
let dir = getUpdatesDir();
|
||||
|
||||
file = dir.clone();
|
||||
file.append(FILE_UPDATE_STATUS);
|
||||
ok(!file.exists(), file.path + " should not exist");
|
||||
|
||||
file = dir.clone();
|
||||
file.append(FILE_UPDATE_MAR);
|
||||
ok(!file.exists(), file.path + " should not exist");
|
||||
|
||||
cleanupRestoreUpdaterBackup();
|
||||
}
|
||||
|
||||
/**
|
||||
* After all tests finish this will repeatedly attempt to restore the real
|
||||
* updater if it exists and then call finishTest after the restore is
|
||||
* successful.
|
||||
*/
|
||||
function cleanupRestoreUpdaterBackup() {
|
||||
debugDump("entering");
|
||||
|
||||
try {
|
||||
// Windows debug builds keep the updater file in use for a short period of
|
||||
// time after the updater process exits.
|
||||
restoreUpdaterBackup();
|
||||
} catch (e) {
|
||||
logTestInfo("Attempt to restore the backed up updater failed... " +
|
||||
"will try again, Exception: " + e);
|
||||
SimpleTest.executeSoon(cleanupRestoreUpdaterBackup);
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleTest.executeSoon(finishTest);
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
debugDump("entering");
|
||||
|
||||
if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_LOG)) {
|
||||
Services.prefs.clearUserPref(PREF_APP_UPDATE_LOG);
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</window>
|
||||
194
toolkit/mozapps/update/tests/chrome/update.sjs
Normal file
194
toolkit/mozapps/update/tests/chrome/update.sjs
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Server side http server script for application update tests.
|
||||
*/
|
||||
|
||||
const { classes: Cc, interfaces: Ci } = Components;
|
||||
|
||||
const REL_PATH_DATA = "chrome/toolkit/mozapps/update/tests/data/";
|
||||
|
||||
function getTestDataFile(aFilename) {
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).get("CurWorkD", Ci.nsILocalFile);
|
||||
let pathParts = REL_PATH_DATA.split("/");
|
||||
for (let i = 0; i < pathParts.length; ++i) {
|
||||
file.append(pathParts[i]);
|
||||
}
|
||||
if (aFilename) {
|
||||
file.append(aFilename);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
function loadHelperScript() {
|
||||
let scriptFile = getTestDataFile("sharedUpdateXML.js");
|
||||
let io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2);
|
||||
let scriptSpec = io.newFileURI(scriptFile).spec;
|
||||
let scriptloader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
getService(Ci.mozIJSSubScriptLoader);
|
||||
scriptloader.loadSubScript(scriptSpec, this);
|
||||
}
|
||||
loadHelperScript();
|
||||
|
||||
const URL_HOST = "http://example.com";
|
||||
const URL_PATH_UPDATE_XML = "/chrome/toolkit/mozapps/update/tests/chrome/update.sjs";
|
||||
const URL_HTTP_UPDATE_SJS = URL_HOST + URL_PATH_UPDATE_XML;
|
||||
const SERVICE_URL = URL_HOST + "/" + REL_PATH_DATA + FILE_SIMPLE_MAR;
|
||||
|
||||
const SLOW_MAR_DOWNLOAD_INTERVAL = 100;
|
||||
var gTimer;
|
||||
|
||||
function handleRequest(aRequest, aResponse) {
|
||||
let params = { };
|
||||
if (aRequest.queryString) {
|
||||
params = parseQueryString(aRequest.queryString);
|
||||
}
|
||||
|
||||
let statusCode = params.statusCode ? parseInt(params.statusCode) : 200;
|
||||
let statusReason = params.statusReason ? params.statusReason : "OK";
|
||||
aResponse.setStatusLine(aRequest.httpVersion, statusCode, statusReason);
|
||||
aResponse.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// When a mar download is started by the update service it can finish
|
||||
// downloading before the ui has loaded. By specifying a serviceURL for the
|
||||
// update patch that points to this file and has a slowDownloadMar param the
|
||||
// mar will be downloaded asynchronously which will allow the ui to load
|
||||
// before the download completes.
|
||||
if (params.slowDownloadMar) {
|
||||
aResponse.processAsync();
|
||||
aResponse.setHeader("Content-Type", "binary/octet-stream");
|
||||
aResponse.setHeader("Content-Length", SIZE_SIMPLE_MAR);
|
||||
var continueFile = getTestDataFile("continue");
|
||||
var contents = readFileBytes(getTestDataFile(FILE_SIMPLE_MAR));
|
||||
gTimer = Cc["@mozilla.org/timer;1"].
|
||||
createInstance(Ci.nsITimer);
|
||||
gTimer.initWithCallback(function(aTimer) {
|
||||
if (continueFile.exists()) {
|
||||
gTimer.cancel();
|
||||
aResponse.write(contents);
|
||||
aResponse.finish();
|
||||
}
|
||||
}, SLOW_MAR_DOWNLOAD_INTERVAL, Ci.nsITimer.TYPE_REPEATING_SLACK);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.uiURL) {
|
||||
let remoteType = "";
|
||||
if (!params.remoteNoTypeAttr && params.uiURL == "BILLBOARD") {
|
||||
remoteType = " " + params.uiURL.toLowerCase() + "=\"1\"";
|
||||
}
|
||||
aResponse.write("<html><head><meta http-equiv=\"content-type\" content=" +
|
||||
"\"text/html; charset=utf-8\"></head><body" +
|
||||
remoteType + ">" + params.uiURL +
|
||||
"<br><br>this is a test mar that will not affect your " +
|
||||
"build.</body></html>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.xmlMalformed) {
|
||||
aResponse.write("xml error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.noUpdates) {
|
||||
aResponse.write(getRemoteUpdatesXMLString(""));
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.unsupported) {
|
||||
aResponse.write(getRemoteUpdatesXMLString(" <update type=\"major\" " +
|
||||
"unsupported=\"true\" " +
|
||||
"detailsURL=\"" + URL_HOST +
|
||||
"\"></update>\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
let size;
|
||||
let patches = "";
|
||||
if (!params.partialPatchOnly) {
|
||||
size = SIZE_SIMPLE_MAR + (params.invalidCompleteSize ? "1" : "");
|
||||
patches += getRemotePatchString("complete", SERVICE_URL, "SHA512",
|
||||
SHA512_HASH_SIMPLE_MAR, size);
|
||||
}
|
||||
|
||||
if (!params.completePatchOnly) {
|
||||
size = SIZE_SIMPLE_MAR + (params.invalidPartialSize ? "1" : "");
|
||||
patches += getRemotePatchString("partial", SERVICE_URL, "SHA512",
|
||||
SHA512_HASH_SIMPLE_MAR, size);
|
||||
}
|
||||
|
||||
let type = params.type ? params.type : "major";
|
||||
let name = params.name ? params.name : "App Update Test";
|
||||
let appVersion = params.appVersion ? params.appVersion : "999999.9";
|
||||
let displayVersion = params.displayVersion ? params.displayVersion
|
||||
: "version " + appVersion;
|
||||
let buildID = params.buildID ? params.buildID : "01234567890123";
|
||||
// XXXrstrong - not specifying a detailsURL will cause a leak due to bug 470244
|
||||
// let detailsURL = params.showDetails ? URL_HTTP_UPDATE_SJS + "?uiURL=DETAILS" : null;
|
||||
let detailsURL = URL_HTTP_UPDATE_SJS + "?uiURL=DETAILS";
|
||||
let showPrompt = params.showPrompt ? "true" : null;
|
||||
let showNever = params.showNever ? "true" : null;
|
||||
let promptWaitTime = params.promptWaitTime ? params.promptWaitTime : null;
|
||||
|
||||
let updates = getRemoteUpdateString(patches, type, "App Update Test",
|
||||
displayVersion, appVersion, buildID,
|
||||
detailsURL, showPrompt, showNever,
|
||||
promptWaitTime);
|
||||
aResponse.write(getRemoteUpdatesXMLString(updates));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create a JS object representing the url parameters from
|
||||
* the request's queryString.
|
||||
*
|
||||
* @param aQueryString
|
||||
* The request's query string.
|
||||
* @return A JS object representing the url parameters from the request's
|
||||
* queryString.
|
||||
*/
|
||||
function parseQueryString(aQueryString) {
|
||||
let paramArray = aQueryString.split("&");
|
||||
let regex = /^([^=]+)=(.*)$/;
|
||||
let params = {};
|
||||
for (let i = 0, sz = paramArray.length; i < sz; i++) {
|
||||
let match = regex.exec(paramArray[i]);
|
||||
if (!match) {
|
||||
throw "Bad parameter in queryString! '" + paramArray[i] + "'";
|
||||
}
|
||||
params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the binary contents of a file and returns it as a string.
|
||||
*
|
||||
* @param aFile
|
||||
* The file to read from.
|
||||
* @return The contents of the file as a string.
|
||||
*/
|
||||
function readFileBytes(aFile) {
|
||||
let fis = Cc["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Ci.nsIFileInputStream);
|
||||
fis.init(aFile, -1, -1, false);
|
||||
let bis = Cc["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Ci.nsIBinaryInputStream);
|
||||
bis.setInputStream(fis);
|
||||
let data = [];
|
||||
let count = fis.available();
|
||||
while (count > 0) {
|
||||
let bytes = bis.readByteArray(Math.min(65535, count));
|
||||
data.push(String.fromCharCode.apply(null, bytes));
|
||||
count -= bytes.length;
|
||||
if (bytes.length == 0) {
|
||||
throw "Nothing read from input stream!";
|
||||
}
|
||||
}
|
||||
data.join('');
|
||||
fis.close();
|
||||
return data.toString();
|
||||
}
|
||||
1011
toolkit/mozapps/update/tests/chrome/utils.js
Normal file
1011
toolkit/mozapps/update/tests/chrome/utils.js
Normal file
File diff suppressed because it is too large
Load diff
BIN
toolkit/mozapps/update/tests/data/complete.exe
Normal file
BIN
toolkit/mozapps/update/tests/data/complete.exe
Normal file
Binary file not shown.
BIN
toolkit/mozapps/update/tests/data/complete.mar
Normal file
BIN
toolkit/mozapps/update/tests/data/complete.mar
Normal file
Binary file not shown.
BIN
toolkit/mozapps/update/tests/data/complete.png
Normal file
BIN
toolkit/mozapps/update/tests/data/complete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 878 B |
332
toolkit/mozapps/update/tests/data/complete_log_success_mac
Normal file
332
toolkit/mozapps/update/tests/data/complete_log_success_mac
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
UPDATE TYPE complete
|
||||
PREPARE REMOVEFILE Contents/Resources/searchplugins/searchpluginstext0
|
||||
PREPARE REMOVEFILE Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
PREPARE REMOVEFILE Contents/Resources/removed-files
|
||||
PREPARE REMOVEFILE Contents/Resources/precomplete
|
||||
PREPARE REMOVEFILE Contents/Resources/2/20/20text0
|
||||
PREPARE REMOVEFILE Contents/Resources/2/20/20png0.png
|
||||
PREPARE REMOVEFILE Contents/Resources/0/0exe0.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/0/00/00text0
|
||||
PREPARE REMOVEFILE Contents/MacOS/exe0.exe
|
||||
PREPARE REMOVEDIR Contents/Resources/searchplugins/
|
||||
PREPARE REMOVEDIR Contents/Resources/defaults/pref/
|
||||
PREPARE REMOVEDIR Contents/Resources/defaults/
|
||||
PREPARE REMOVEDIR Contents/Resources/2/20/
|
||||
PREPARE REMOVEDIR Contents/Resources/2/
|
||||
PREPARE REMOVEDIR Contents/Resources/0/00/
|
||||
PREPARE REMOVEDIR Contents/Resources/0/
|
||||
PREPARE REMOVEDIR Contents/Resources/
|
||||
PREPARE REMOVEDIR Contents/MacOS/
|
||||
PREPARE REMOVEDIR Contents/
|
||||
PREPARE ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
PREPARE ADD Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
PREPARE ADD Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
PREPARE ADD Contents/Resources/removed-files
|
||||
PREPARE ADD Contents/Resources/precomplete
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
PREPARE ADD Contents/Resources/1/10/10text0
|
||||
PREPARE ADD Contents/Resources/0/0exe0.exe
|
||||
PREPARE ADD Contents/Resources/0/00/00text1
|
||||
PREPARE ADD Contents/Resources/0/00/00text0
|
||||
PREPARE ADD Contents/Resources/0/00/00png0.png
|
||||
PREPARE ADD Contents/MacOS/exe0.exe
|
||||
PREPARE REMOVEDIR Contents/Resources/9/99/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/99/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/98/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/970/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/971/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/96/96text0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/96/96text1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/96/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/95/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/95/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/94/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/94/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/93/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/92/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/91/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/90/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/90/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/89/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/89/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/88/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/870/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/871/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/86/86text0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/86/86text1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/86/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/85/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/85/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/84/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/84/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/83/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/82/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/81/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/80/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/80/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/70/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/71/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/7text0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/7text1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/
|
||||
PREPARE REMOVEDIR Contents/Resources/6/
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text1
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text0
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5test.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text0
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text1
|
||||
PREPARE REMOVEDIR Contents/Resources/5/
|
||||
PREPARE REMOVEFILE Contents/Resources/4/4text1
|
||||
PREPARE REMOVEFILE Contents/Resources/4/4text0
|
||||
PREPARE REMOVEDIR Contents/Resources/4/
|
||||
PREPARE REMOVEFILE Contents/Resources/3/3text1
|
||||
PREPARE REMOVEFILE Contents/Resources/3/3text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/searchplugins/searchpluginstext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
EXECUTE REMOVEFILE Contents/Resources/removed-files
|
||||
EXECUTE REMOVEFILE Contents/Resources/precomplete
|
||||
EXECUTE REMOVEFILE Contents/Resources/2/20/20text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/2/20/20png0.png
|
||||
EXECUTE REMOVEFILE Contents/Resources/0/0exe0.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/0/00/00text0
|
||||
EXECUTE REMOVEFILE Contents/MacOS/exe0.exe
|
||||
EXECUTE REMOVEDIR Contents/Resources/searchplugins/
|
||||
EXECUTE REMOVEDIR Contents/Resources/defaults/pref/
|
||||
EXECUTE REMOVEDIR Contents/Resources/defaults/
|
||||
EXECUTE REMOVEDIR Contents/Resources/2/20/
|
||||
EXECUTE REMOVEDIR Contents/Resources/2/
|
||||
EXECUTE REMOVEDIR Contents/Resources/0/00/
|
||||
EXECUTE REMOVEDIR Contents/Resources/0/
|
||||
EXECUTE REMOVEDIR Contents/Resources/
|
||||
EXECUTE REMOVEDIR Contents/MacOS/
|
||||
EXECUTE REMOVEDIR Contents/
|
||||
EXECUTE ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
EXECUTE ADD Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
EXECUTE ADD Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
EXECUTE ADD Contents/Resources/removed-files
|
||||
EXECUTE ADD Contents/Resources/precomplete
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
EXECUTE ADD Contents/Resources/1/10/10text0
|
||||
EXECUTE ADD Contents/Resources/0/0exe0.exe
|
||||
EXECUTE ADD Contents/Resources/0/00/00text1
|
||||
EXECUTE ADD Contents/Resources/0/00/00text0
|
||||
EXECUTE ADD Contents/Resources/0/00/00png0.png
|
||||
EXECUTE ADD Contents/MacOS/exe0.exe
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/99/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/99/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/98/
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/97/970/
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/97/971/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/97/
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/96/96text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/96/96text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/96/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/95/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/95/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/94/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/94/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/93/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/92/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/91/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/90/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/90/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/89/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/89/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/88/
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/87/870/
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/87/871/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/87/
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/86/86text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/86/86text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/86/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/85/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/85/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/84/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/84/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/83/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/82/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/81/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/80/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/80/
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/7/70/
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/7/71/
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/7text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/7text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/7/
|
||||
EXECUTE REMOVEDIR Contents/Resources/6/
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text1
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5test.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text0
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text1
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEDIR Contents/Resources/5/
|
||||
EXECUTE REMOVEFILE Contents/Resources/4/4text1
|
||||
EXECUTE REMOVEFILE Contents/Resources/4/4text0
|
||||
EXECUTE REMOVEDIR Contents/Resources/4/
|
||||
EXECUTE REMOVEFILE Contents/Resources/3/3text1
|
||||
EXECUTE REMOVEFILE Contents/Resources/3/3text0
|
||||
FINISH REMOVEFILE Contents/Resources/searchplugins/searchpluginstext0
|
||||
FINISH REMOVEFILE Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
FINISH REMOVEFILE Contents/Resources/removed-files
|
||||
FINISH REMOVEFILE Contents/Resources/precomplete
|
||||
FINISH REMOVEFILE Contents/Resources/2/20/20text0
|
||||
FINISH REMOVEFILE Contents/Resources/2/20/20png0.png
|
||||
FINISH REMOVEFILE Contents/Resources/0/0exe0.exe
|
||||
FINISH REMOVEFILE Contents/Resources/0/00/00text0
|
||||
FINISH REMOVEFILE Contents/MacOS/exe0.exe
|
||||
FINISH REMOVEDIR Contents/Resources/searchplugins/
|
||||
removing directory: Contents/Resources/searchplugins/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/defaults/pref/
|
||||
removing directory: Contents/Resources/defaults/pref/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/defaults/
|
||||
removing directory: Contents/Resources/defaults/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/2/20/
|
||||
FINISH REMOVEDIR Contents/Resources/2/
|
||||
FINISH REMOVEDIR Contents/Resources/0/00/
|
||||
removing directory: Contents/Resources/0/00/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/0/
|
||||
removing directory: Contents/Resources/0/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/
|
||||
removing directory: Contents/Resources/, rv: 0
|
||||
FINISH REMOVEDIR Contents/MacOS/
|
||||
removing directory: Contents/MacOS/, rv: 0
|
||||
FINISH REMOVEDIR Contents/
|
||||
removing directory: Contents/, rv: 0
|
||||
FINISH ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
FINISH ADD Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
FINISH ADD Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
FINISH ADD Contents/Resources/removed-files
|
||||
FINISH ADD Contents/Resources/precomplete
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
FINISH ADD Contents/Resources/1/10/10text0
|
||||
FINISH ADD Contents/Resources/0/0exe0.exe
|
||||
FINISH ADD Contents/Resources/0/00/00text1
|
||||
FINISH ADD Contents/Resources/0/00/00text0
|
||||
FINISH ADD Contents/Resources/0/00/00png0.png
|
||||
FINISH ADD Contents/MacOS/exe0.exe
|
||||
FINISH REMOVEDIR Contents/Resources/9/99/
|
||||
FINISH REMOVEDIR Contents/Resources/9/99/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/9/98/
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/9/97/970/
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/9/97/971/
|
||||
FINISH REMOVEDIR Contents/Resources/9/97/
|
||||
FINISH REMOVEFILE Contents/Resources/9/96/96text0
|
||||
FINISH REMOVEFILE Contents/Resources/9/96/96text1
|
||||
FINISH REMOVEDIR Contents/Resources/9/96/
|
||||
FINISH REMOVEDIR Contents/Resources/9/95/
|
||||
FINISH REMOVEDIR Contents/Resources/9/95/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/9/94/
|
||||
FINISH REMOVEDIR Contents/Resources/9/94/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/9/93/
|
||||
FINISH REMOVEDIR Contents/Resources/9/92/
|
||||
removing directory: Contents/Resources/9/92/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/9/91/
|
||||
removing directory: Contents/Resources/9/91/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/9/90/
|
||||
FINISH REMOVEDIR Contents/Resources/9/90/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/89/
|
||||
FINISH REMOVEDIR Contents/Resources/8/89/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/88/
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/8/87/870/
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/8/87/871/
|
||||
FINISH REMOVEDIR Contents/Resources/8/87/
|
||||
FINISH REMOVEFILE Contents/Resources/8/86/86text0
|
||||
FINISH REMOVEFILE Contents/Resources/8/86/86text1
|
||||
FINISH REMOVEDIR Contents/Resources/8/86/
|
||||
FINISH REMOVEDIR Contents/Resources/8/85/
|
||||
FINISH REMOVEDIR Contents/Resources/8/85/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/84/
|
||||
FINISH REMOVEDIR Contents/Resources/8/84/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/83/
|
||||
FINISH REMOVEDIR Contents/Resources/8/82/
|
||||
removing directory: Contents/Resources/8/82/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/8/81/
|
||||
removing directory: Contents/Resources/8/81/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/8/80/
|
||||
FINISH REMOVEDIR Contents/Resources/8/80/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/7/70/
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/7/71/
|
||||
FINISH REMOVEFILE Contents/Resources/7/7text0
|
||||
FINISH REMOVEFILE Contents/Resources/7/7text1
|
||||
FINISH REMOVEDIR Contents/Resources/7/
|
||||
FINISH REMOVEDIR Contents/Resources/6/
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text1
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text0
|
||||
FINISH REMOVEFILE Contents/Resources/5/5test.exe
|
||||
FINISH REMOVEDIR Contents/Resources/5/
|
||||
FINISH REMOVEFILE Contents/Resources/4/4text1
|
||||
FINISH REMOVEFILE Contents/Resources/4/4text0
|
||||
FINISH REMOVEDIR Contents/Resources/4/
|
||||
FINISH REMOVEFILE Contents/Resources/3/3text1
|
||||
FINISH REMOVEFILE Contents/Resources/3/3text0
|
||||
succeeded
|
||||
calling QuitProgressUI
|
||||
320
toolkit/mozapps/update/tests/data/complete_log_success_win
Normal file
320
toolkit/mozapps/update/tests/data/complete_log_success_win
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
UPDATE TYPE complete
|
||||
PREPARE REMOVEFILE searchplugins/searchpluginstext0
|
||||
PREPARE REMOVEFILE searchplugins/searchpluginspng0.png
|
||||
PREPARE REMOVEFILE removed-files
|
||||
PREPARE REMOVEFILE precomplete
|
||||
PREPARE REMOVEFILE exe0.exe
|
||||
PREPARE REMOVEFILE 2/20/20text0
|
||||
PREPARE REMOVEFILE 2/20/20png0.png
|
||||
PREPARE REMOVEFILE 0/0exe0.exe
|
||||
PREPARE REMOVEFILE 0/00/00text0
|
||||
PREPARE REMOVEDIR searchplugins/
|
||||
PREPARE REMOVEDIR defaults/pref/
|
||||
PREPARE REMOVEDIR defaults/
|
||||
PREPARE REMOVEDIR 2/20/
|
||||
PREPARE REMOVEDIR 2/
|
||||
PREPARE REMOVEDIR 0/00/
|
||||
PREPARE REMOVEDIR 0/
|
||||
PREPARE ADD searchplugins/searchpluginstext0
|
||||
PREPARE ADD searchplugins/searchpluginspng1.png
|
||||
PREPARE ADD searchplugins/searchpluginspng0.png
|
||||
PREPARE ADD removed-files
|
||||
PREPARE ADD precomplete
|
||||
PREPARE ADD exe0.exe
|
||||
PREPARE ADD distribution/extensions/extensions1/extensions1text0
|
||||
PREPARE ADD distribution/extensions/extensions1/extensions1png1.png
|
||||
PREPARE ADD distribution/extensions/extensions1/extensions1png0.png
|
||||
PREPARE ADD distribution/extensions/extensions0/extensions0text0
|
||||
PREPARE ADD distribution/extensions/extensions0/extensions0png1.png
|
||||
PREPARE ADD distribution/extensions/extensions0/extensions0png0.png
|
||||
PREPARE ADD 1/10/10text0
|
||||
PREPARE ADD 0/0exe0.exe
|
||||
PREPARE ADD 0/00/00text1
|
||||
PREPARE ADD 0/00/00text0
|
||||
PREPARE ADD 0/00/00png0.png
|
||||
PREPARE REMOVEDIR 9/99/
|
||||
PREPARE REMOVEDIR 9/99/
|
||||
PREPARE REMOVEDIR 9/98/
|
||||
PREPARE REMOVEFILE 9/97/970/97xtext0
|
||||
PREPARE REMOVEFILE 9/97/970/97xtext1
|
||||
PREPARE REMOVEDIR 9/97/970/
|
||||
PREPARE REMOVEFILE 9/97/971/97xtext0
|
||||
PREPARE REMOVEFILE 9/97/971/97xtext1
|
||||
PREPARE REMOVEDIR 9/97/971/
|
||||
PREPARE REMOVEDIR 9/97/
|
||||
PREPARE REMOVEFILE 9/96/96text0
|
||||
PREPARE REMOVEFILE 9/96/96text1
|
||||
PREPARE REMOVEDIR 9/96/
|
||||
PREPARE REMOVEDIR 9/95/
|
||||
PREPARE REMOVEDIR 9/95/
|
||||
PREPARE REMOVEDIR 9/94/
|
||||
PREPARE REMOVEDIR 9/94/
|
||||
PREPARE REMOVEDIR 9/93/
|
||||
PREPARE REMOVEDIR 9/92/
|
||||
PREPARE REMOVEDIR 9/91/
|
||||
PREPARE REMOVEDIR 9/90/
|
||||
PREPARE REMOVEDIR 9/90/
|
||||
PREPARE REMOVEDIR 8/89/
|
||||
PREPARE REMOVEDIR 8/89/
|
||||
PREPARE REMOVEDIR 8/88/
|
||||
PREPARE REMOVEFILE 8/87/870/87xtext0
|
||||
PREPARE REMOVEFILE 8/87/870/87xtext1
|
||||
PREPARE REMOVEDIR 8/87/870/
|
||||
PREPARE REMOVEFILE 8/87/871/87xtext0
|
||||
PREPARE REMOVEFILE 8/87/871/87xtext1
|
||||
PREPARE REMOVEDIR 8/87/871/
|
||||
PREPARE REMOVEDIR 8/87/
|
||||
PREPARE REMOVEFILE 8/86/86text0
|
||||
PREPARE REMOVEFILE 8/86/86text1
|
||||
PREPARE REMOVEDIR 8/86/
|
||||
PREPARE REMOVEDIR 8/85/
|
||||
PREPARE REMOVEDIR 8/85/
|
||||
PREPARE REMOVEDIR 8/84/
|
||||
PREPARE REMOVEDIR 8/84/
|
||||
PREPARE REMOVEDIR 8/83/
|
||||
PREPARE REMOVEDIR 8/82/
|
||||
PREPARE REMOVEDIR 8/81/
|
||||
PREPARE REMOVEDIR 8/80/
|
||||
PREPARE REMOVEDIR 8/80/
|
||||
PREPARE REMOVEFILE 7/70/7xtest.exe
|
||||
PREPARE REMOVEFILE 7/70/7xtext0
|
||||
PREPARE REMOVEFILE 7/70/7xtext1
|
||||
PREPARE REMOVEDIR 7/70/
|
||||
PREPARE REMOVEFILE 7/71/7xtest.exe
|
||||
PREPARE REMOVEFILE 7/71/7xtext0
|
||||
PREPARE REMOVEFILE 7/71/7xtext1
|
||||
PREPARE REMOVEDIR 7/71/
|
||||
PREPARE REMOVEFILE 7/7text0
|
||||
PREPARE REMOVEFILE 7/7text1
|
||||
PREPARE REMOVEDIR 7/
|
||||
PREPARE REMOVEDIR 6/
|
||||
PREPARE REMOVEFILE 5/5text1
|
||||
PREPARE REMOVEFILE 5/5text0
|
||||
PREPARE REMOVEFILE 5/5test.exe
|
||||
PREPARE REMOVEFILE 5/5text0
|
||||
PREPARE REMOVEFILE 5/5text1
|
||||
PREPARE REMOVEDIR 5/
|
||||
PREPARE REMOVEFILE 4/4text1
|
||||
PREPARE REMOVEFILE 4/4text0
|
||||
PREPARE REMOVEDIR 4/
|
||||
PREPARE REMOVEFILE 3/3text1
|
||||
PREPARE REMOVEFILE 3/3text0
|
||||
EXECUTE REMOVEFILE searchplugins/searchpluginstext0
|
||||
EXECUTE REMOVEFILE searchplugins/searchpluginspng0.png
|
||||
EXECUTE REMOVEFILE removed-files
|
||||
EXECUTE REMOVEFILE precomplete
|
||||
EXECUTE REMOVEFILE exe0.exe
|
||||
EXECUTE REMOVEFILE 2/20/20text0
|
||||
EXECUTE REMOVEFILE 2/20/20png0.png
|
||||
EXECUTE REMOVEFILE 0/0exe0.exe
|
||||
EXECUTE REMOVEFILE 0/00/00text0
|
||||
EXECUTE REMOVEDIR searchplugins/
|
||||
EXECUTE REMOVEDIR defaults/pref/
|
||||
EXECUTE REMOVEDIR defaults/
|
||||
EXECUTE REMOVEDIR 2/20/
|
||||
EXECUTE REMOVEDIR 2/
|
||||
EXECUTE REMOVEDIR 0/00/
|
||||
EXECUTE REMOVEDIR 0/
|
||||
EXECUTE ADD searchplugins/searchpluginstext0
|
||||
EXECUTE ADD searchplugins/searchpluginspng1.png
|
||||
EXECUTE ADD searchplugins/searchpluginspng0.png
|
||||
EXECUTE ADD removed-files
|
||||
EXECUTE ADD precomplete
|
||||
EXECUTE ADD exe0.exe
|
||||
EXECUTE ADD distribution/extensions/extensions1/extensions1text0
|
||||
EXECUTE ADD distribution/extensions/extensions1/extensions1png1.png
|
||||
EXECUTE ADD distribution/extensions/extensions1/extensions1png0.png
|
||||
EXECUTE ADD distribution/extensions/extensions0/extensions0text0
|
||||
EXECUTE ADD distribution/extensions/extensions0/extensions0png1.png
|
||||
EXECUTE ADD distribution/extensions/extensions0/extensions0png0.png
|
||||
EXECUTE ADD 1/10/10text0
|
||||
EXECUTE ADD 0/0exe0.exe
|
||||
EXECUTE ADD 0/00/00text1
|
||||
EXECUTE ADD 0/00/00text0
|
||||
EXECUTE ADD 0/00/00png0.png
|
||||
EXECUTE REMOVEDIR 9/99/
|
||||
EXECUTE REMOVEDIR 9/99/
|
||||
EXECUTE REMOVEDIR 9/98/
|
||||
EXECUTE REMOVEFILE 9/97/970/97xtext0
|
||||
EXECUTE REMOVEFILE 9/97/970/97xtext1
|
||||
EXECUTE REMOVEDIR 9/97/970/
|
||||
EXECUTE REMOVEFILE 9/97/971/97xtext0
|
||||
EXECUTE REMOVEFILE 9/97/971/97xtext1
|
||||
EXECUTE REMOVEDIR 9/97/971/
|
||||
EXECUTE REMOVEDIR 9/97/
|
||||
EXECUTE REMOVEFILE 9/96/96text0
|
||||
EXECUTE REMOVEFILE 9/96/96text1
|
||||
EXECUTE REMOVEDIR 9/96/
|
||||
EXECUTE REMOVEDIR 9/95/
|
||||
EXECUTE REMOVEDIR 9/95/
|
||||
EXECUTE REMOVEDIR 9/94/
|
||||
EXECUTE REMOVEDIR 9/94/
|
||||
EXECUTE REMOVEDIR 9/93/
|
||||
EXECUTE REMOVEDIR 9/92/
|
||||
EXECUTE REMOVEDIR 9/91/
|
||||
EXECUTE REMOVEDIR 9/90/
|
||||
EXECUTE REMOVEDIR 9/90/
|
||||
EXECUTE REMOVEDIR 8/89/
|
||||
EXECUTE REMOVEDIR 8/89/
|
||||
EXECUTE REMOVEDIR 8/88/
|
||||
EXECUTE REMOVEFILE 8/87/870/87xtext0
|
||||
EXECUTE REMOVEFILE 8/87/870/87xtext1
|
||||
EXECUTE REMOVEDIR 8/87/870/
|
||||
EXECUTE REMOVEFILE 8/87/871/87xtext0
|
||||
EXECUTE REMOVEFILE 8/87/871/87xtext1
|
||||
EXECUTE REMOVEDIR 8/87/871/
|
||||
EXECUTE REMOVEDIR 8/87/
|
||||
EXECUTE REMOVEFILE 8/86/86text0
|
||||
EXECUTE REMOVEFILE 8/86/86text1
|
||||
EXECUTE REMOVEDIR 8/86/
|
||||
EXECUTE REMOVEDIR 8/85/
|
||||
EXECUTE REMOVEDIR 8/85/
|
||||
EXECUTE REMOVEDIR 8/84/
|
||||
EXECUTE REMOVEDIR 8/84/
|
||||
EXECUTE REMOVEDIR 8/83/
|
||||
EXECUTE REMOVEDIR 8/82/
|
||||
EXECUTE REMOVEDIR 8/81/
|
||||
EXECUTE REMOVEDIR 8/80/
|
||||
EXECUTE REMOVEDIR 8/80/
|
||||
EXECUTE REMOVEFILE 7/70/7xtest.exe
|
||||
EXECUTE REMOVEFILE 7/70/7xtext0
|
||||
EXECUTE REMOVEFILE 7/70/7xtext1
|
||||
EXECUTE REMOVEDIR 7/70/
|
||||
EXECUTE REMOVEFILE 7/71/7xtest.exe
|
||||
EXECUTE REMOVEFILE 7/71/7xtext0
|
||||
EXECUTE REMOVEFILE 7/71/7xtext1
|
||||
EXECUTE REMOVEDIR 7/71/
|
||||
EXECUTE REMOVEFILE 7/7text0
|
||||
EXECUTE REMOVEFILE 7/7text1
|
||||
EXECUTE REMOVEDIR 7/
|
||||
EXECUTE REMOVEDIR 6/
|
||||
EXECUTE REMOVEFILE 5/5text1
|
||||
EXECUTE REMOVEFILE 5/5text0
|
||||
EXECUTE REMOVEFILE 5/5test.exe
|
||||
EXECUTE REMOVEFILE 5/5text0
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEFILE 5/5text1
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEDIR 5/
|
||||
EXECUTE REMOVEFILE 4/4text1
|
||||
EXECUTE REMOVEFILE 4/4text0
|
||||
EXECUTE REMOVEDIR 4/
|
||||
EXECUTE REMOVEFILE 3/3text1
|
||||
EXECUTE REMOVEFILE 3/3text0
|
||||
FINISH REMOVEFILE searchplugins/searchpluginstext0
|
||||
FINISH REMOVEFILE searchplugins/searchpluginspng0.png
|
||||
FINISH REMOVEFILE removed-files
|
||||
FINISH REMOVEFILE precomplete
|
||||
FINISH REMOVEFILE exe0.exe
|
||||
FINISH REMOVEFILE 2/20/20text0
|
||||
FINISH REMOVEFILE 2/20/20png0.png
|
||||
FINISH REMOVEFILE 0/0exe0.exe
|
||||
FINISH REMOVEFILE 0/00/00text0
|
||||
FINISH REMOVEDIR searchplugins/
|
||||
removing directory: searchplugins/, rv: 0
|
||||
FINISH REMOVEDIR defaults/pref/
|
||||
removing directory: defaults/pref/, rv: 0
|
||||
FINISH REMOVEDIR defaults/
|
||||
removing directory: defaults/, rv: 0
|
||||
FINISH REMOVEDIR 2/20/
|
||||
FINISH REMOVEDIR 2/
|
||||
FINISH REMOVEDIR 0/00/
|
||||
removing directory: 0/00/, rv: 0
|
||||
FINISH REMOVEDIR 0/
|
||||
removing directory: 0/, rv: 0
|
||||
FINISH ADD searchplugins/searchpluginstext0
|
||||
FINISH ADD searchplugins/searchpluginspng1.png
|
||||
FINISH ADD searchplugins/searchpluginspng0.png
|
||||
FINISH ADD removed-files
|
||||
FINISH ADD precomplete
|
||||
FINISH ADD exe0.exe
|
||||
FINISH ADD distribution/extensions/extensions1/extensions1text0
|
||||
FINISH ADD distribution/extensions/extensions1/extensions1png1.png
|
||||
FINISH ADD distribution/extensions/extensions1/extensions1png0.png
|
||||
FINISH ADD distribution/extensions/extensions0/extensions0text0
|
||||
FINISH ADD distribution/extensions/extensions0/extensions0png1.png
|
||||
FINISH ADD distribution/extensions/extensions0/extensions0png0.png
|
||||
FINISH ADD 1/10/10text0
|
||||
FINISH ADD 0/0exe0.exe
|
||||
FINISH ADD 0/00/00text1
|
||||
FINISH ADD 0/00/00text0
|
||||
FINISH ADD 0/00/00png0.png
|
||||
FINISH REMOVEDIR 9/99/
|
||||
FINISH REMOVEDIR 9/99/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 9/98/
|
||||
FINISH REMOVEFILE 9/97/970/97xtext0
|
||||
FINISH REMOVEFILE 9/97/970/97xtext1
|
||||
FINISH REMOVEDIR 9/97/970/
|
||||
FINISH REMOVEFILE 9/97/971/97xtext0
|
||||
FINISH REMOVEFILE 9/97/971/97xtext1
|
||||
FINISH REMOVEDIR 9/97/971/
|
||||
FINISH REMOVEDIR 9/97/
|
||||
FINISH REMOVEFILE 9/96/96text0
|
||||
FINISH REMOVEFILE 9/96/96text1
|
||||
FINISH REMOVEDIR 9/96/
|
||||
FINISH REMOVEDIR 9/95/
|
||||
FINISH REMOVEDIR 9/95/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 9/94/
|
||||
FINISH REMOVEDIR 9/94/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 9/93/
|
||||
FINISH REMOVEDIR 9/92/
|
||||
removing directory: 9/92/, rv: 0
|
||||
FINISH REMOVEDIR 9/91/
|
||||
removing directory: 9/91/, rv: 0
|
||||
FINISH REMOVEDIR 9/90/
|
||||
FINISH REMOVEDIR 9/90/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/89/
|
||||
FINISH REMOVEDIR 8/89/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/88/
|
||||
FINISH REMOVEFILE 8/87/870/87xtext0
|
||||
FINISH REMOVEFILE 8/87/870/87xtext1
|
||||
FINISH REMOVEDIR 8/87/870/
|
||||
FINISH REMOVEFILE 8/87/871/87xtext0
|
||||
FINISH REMOVEFILE 8/87/871/87xtext1
|
||||
FINISH REMOVEDIR 8/87/871/
|
||||
FINISH REMOVEDIR 8/87/
|
||||
FINISH REMOVEFILE 8/86/86text0
|
||||
FINISH REMOVEFILE 8/86/86text1
|
||||
FINISH REMOVEDIR 8/86/
|
||||
FINISH REMOVEDIR 8/85/
|
||||
FINISH REMOVEDIR 8/85/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/84/
|
||||
FINISH REMOVEDIR 8/84/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/83/
|
||||
FINISH REMOVEDIR 8/82/
|
||||
removing directory: 8/82/, rv: 0
|
||||
FINISH REMOVEDIR 8/81/
|
||||
removing directory: 8/81/, rv: 0
|
||||
FINISH REMOVEDIR 8/80/
|
||||
FINISH REMOVEDIR 8/80/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEFILE 7/70/7xtest.exe
|
||||
FINISH REMOVEFILE 7/70/7xtext0
|
||||
FINISH REMOVEFILE 7/70/7xtext1
|
||||
FINISH REMOVEDIR 7/70/
|
||||
FINISH REMOVEFILE 7/71/7xtest.exe
|
||||
FINISH REMOVEFILE 7/71/7xtext0
|
||||
FINISH REMOVEFILE 7/71/7xtext1
|
||||
FINISH REMOVEDIR 7/71/
|
||||
FINISH REMOVEFILE 7/7text0
|
||||
FINISH REMOVEFILE 7/7text1
|
||||
FINISH REMOVEDIR 7/
|
||||
FINISH REMOVEDIR 6/
|
||||
FINISH REMOVEFILE 5/5text1
|
||||
FINISH REMOVEFILE 5/5text0
|
||||
FINISH REMOVEFILE 5/5test.exe
|
||||
FINISH REMOVEDIR 5/
|
||||
FINISH REMOVEFILE 4/4text1
|
||||
FINISH REMOVEFILE 4/4text0
|
||||
FINISH REMOVEDIR 4/
|
||||
FINISH REMOVEFILE 3/3text1
|
||||
FINISH REMOVEFILE 3/3text0
|
||||
succeeded
|
||||
calling QuitProgressUI
|
||||
BIN
toolkit/mozapps/update/tests/data/complete_mac.mar
Normal file
BIN
toolkit/mozapps/update/tests/data/complete_mac.mar
Normal file
Binary file not shown.
18
toolkit/mozapps/update/tests/data/complete_precomplete
Normal file
18
toolkit/mozapps/update/tests/data/complete_precomplete
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
remove "searchplugins/searchpluginstext0"
|
||||
remove "searchplugins/searchpluginspng1.png"
|
||||
remove "searchplugins/searchpluginspng0.png"
|
||||
remove "removed-files"
|
||||
remove "precomplete"
|
||||
remove "exe0.exe"
|
||||
remove "1/10/10text0"
|
||||
remove "0/0exe0.exe"
|
||||
remove "0/00/00text1"
|
||||
remove "0/00/00text0"
|
||||
remove "0/00/00png0.png"
|
||||
rmdir "searchplugins/"
|
||||
rmdir "defaults/pref/"
|
||||
rmdir "defaults/"
|
||||
rmdir "1/10/"
|
||||
rmdir "1/"
|
||||
rmdir "0/00/"
|
||||
rmdir "0/"
|
||||
21
toolkit/mozapps/update/tests/data/complete_precomplete_mac
Normal file
21
toolkit/mozapps/update/tests/data/complete_precomplete_mac
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
remove "Contents/Resources/searchplugins/searchpluginstext0"
|
||||
remove "Contents/Resources/searchplugins/searchpluginspng1.png"
|
||||
remove "Contents/Resources/searchplugins/searchpluginspng0.png"
|
||||
remove "Contents/Resources/removed-files"
|
||||
remove "Contents/Resources/precomplete"
|
||||
remove "Contents/Resources/1/10/10text0"
|
||||
remove "Contents/Resources/0/0exe0.exe"
|
||||
remove "Contents/Resources/0/00/00text1"
|
||||
remove "Contents/Resources/0/00/00text0"
|
||||
remove "Contents/Resources/0/00/00png0.png"
|
||||
remove "Contents/MacOS/exe0.exe"
|
||||
rmdir "Contents/Resources/searchplugins/"
|
||||
rmdir "Contents/Resources/defaults/pref/"
|
||||
rmdir "Contents/Resources/defaults/"
|
||||
rmdir "Contents/Resources/1/10/"
|
||||
rmdir "Contents/Resources/1/"
|
||||
rmdir "Contents/Resources/0/00/"
|
||||
rmdir "Contents/Resources/0/"
|
||||
rmdir "Contents/Resources/"
|
||||
rmdir "Contents/MacOS/"
|
||||
rmdir "Contents/"
|
||||
41
toolkit/mozapps/update/tests/data/complete_removed-files
Normal file
41
toolkit/mozapps/update/tests/data/complete_removed-files
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
text0
|
||||
text1
|
||||
3/3text0
|
||||
3/3text1
|
||||
4/exe0.exe
|
||||
4/4text0
|
||||
4/4text1
|
||||
4/
|
||||
5/5text0
|
||||
5/5text1
|
||||
5/*
|
||||
6/
|
||||
7/*
|
||||
8/80/
|
||||
8/81/
|
||||
8/82/
|
||||
8/83/
|
||||
8/84/
|
||||
8/85/*
|
||||
8/86/*
|
||||
8/87/*
|
||||
8/88/*
|
||||
8/89/*
|
||||
8/80/
|
||||
8/84/*
|
||||
8/85/*
|
||||
8/89/
|
||||
9/90/
|
||||
9/91/
|
||||
9/92/
|
||||
9/93/
|
||||
9/94/
|
||||
9/95/*
|
||||
9/96/*
|
||||
9/97/*
|
||||
9/98/*
|
||||
9/99/*
|
||||
9/90/
|
||||
9/94/*
|
||||
9/95/*
|
||||
9/99/
|
||||
41
toolkit/mozapps/update/tests/data/complete_removed-files_mac
Normal file
41
toolkit/mozapps/update/tests/data/complete_removed-files_mac
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
Contents/Resources/text0
|
||||
Contents/Resources/text1
|
||||
Contents/Resources/3/3text0
|
||||
Contents/Resources/3/3text1
|
||||
Contents/Resources/4/exe0.exe
|
||||
Contents/Resources/4/4text0
|
||||
Contents/Resources/4/4text1
|
||||
Contents/Resources/4/
|
||||
Contents/Resources/5/5text0
|
||||
Contents/Resources/5/5text1
|
||||
Contents/Resources/5/*
|
||||
Contents/Resources/6/
|
||||
Contents/Resources/7/*
|
||||
Contents/Resources/8/80/
|
||||
Contents/Resources/8/81/
|
||||
Contents/Resources/8/82/
|
||||
Contents/Resources/8/83/
|
||||
Contents/Resources/8/84/
|
||||
Contents/Resources/8/85/*
|
||||
Contents/Resources/8/86/*
|
||||
Contents/Resources/8/87/*
|
||||
Contents/Resources/8/88/*
|
||||
Contents/Resources/8/89/*
|
||||
Contents/Resources/8/80/
|
||||
Contents/Resources/8/84/*
|
||||
Contents/Resources/8/85/*
|
||||
Contents/Resources/8/89/
|
||||
Contents/Resources/9/90/
|
||||
Contents/Resources/9/91/
|
||||
Contents/Resources/9/92/
|
||||
Contents/Resources/9/93/
|
||||
Contents/Resources/9/94/
|
||||
Contents/Resources/9/95/*
|
||||
Contents/Resources/9/96/*
|
||||
Contents/Resources/9/97/*
|
||||
Contents/Resources/9/98/*
|
||||
Contents/Resources/9/99/*
|
||||
Contents/Resources/9/90/
|
||||
Contents/Resources/9/94/*
|
||||
Contents/Resources/9/95/*
|
||||
Contents/Resources/9/99/
|
||||
59
toolkit/mozapps/update/tests/data/complete_update_manifest
Normal file
59
toolkit/mozapps/update/tests/data/complete_update_manifest
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
type "complete"
|
||||
add "precomplete"
|
||||
add "searchplugins/searchpluginstext0"
|
||||
add "searchplugins/searchpluginspng1.png"
|
||||
add "searchplugins/searchpluginspng0.png"
|
||||
add "removed-files"
|
||||
add-if "extensions/extensions1" "extensions/extensions1/extensions1text0"
|
||||
add-if "extensions/extensions1" "extensions/extensions1/extensions1png1.png"
|
||||
add-if "extensions/extensions1" "extensions/extensions1/extensions1png0.png"
|
||||
add-if "extensions/extensions0" "extensions/extensions0/extensions0text0"
|
||||
add-if "extensions/extensions0" "extensions/extensions0/extensions0png1.png"
|
||||
add-if "extensions/extensions0" "extensions/extensions0/extensions0png0.png"
|
||||
add "exe0.exe"
|
||||
add "1/10/10text0"
|
||||
add "0/0exe0.exe"
|
||||
add "0/00/00text1"
|
||||
add "0/00/00text0"
|
||||
add "0/00/00png0.png"
|
||||
remove "text1"
|
||||
remove "text0"
|
||||
rmrfdir "9/99/"
|
||||
rmdir "9/99/"
|
||||
rmrfdir "9/98/"
|
||||
rmrfdir "9/97/"
|
||||
rmrfdir "9/96/"
|
||||
rmrfdir "9/95/"
|
||||
rmrfdir "9/95/"
|
||||
rmrfdir "9/94/"
|
||||
rmdir "9/94/"
|
||||
rmdir "9/93/"
|
||||
rmdir "9/92/"
|
||||
rmdir "9/91/"
|
||||
rmdir "9/90/"
|
||||
rmdir "9/90/"
|
||||
rmrfdir "8/89/"
|
||||
rmdir "8/89/"
|
||||
rmrfdir "8/88/"
|
||||
rmrfdir "8/87/"
|
||||
rmrfdir "8/86/"
|
||||
rmrfdir "8/85/"
|
||||
rmrfdir "8/85/"
|
||||
rmrfdir "8/84/"
|
||||
rmdir "8/84/"
|
||||
rmdir "8/83/"
|
||||
rmdir "8/82/"
|
||||
rmdir "8/81/"
|
||||
rmdir "8/80/"
|
||||
rmdir "8/80/"
|
||||
rmrfdir "7/"
|
||||
rmdir "6/"
|
||||
remove "5/5text1"
|
||||
remove "5/5text0"
|
||||
rmrfdir "5/"
|
||||
remove "4/exe0.exe"
|
||||
remove "4/4text1"
|
||||
remove "4/4text0"
|
||||
rmdir "4/"
|
||||
remove "3/3text1"
|
||||
remove "3/3text0"
|
||||
BIN
toolkit/mozapps/update/tests/data/old_version.mar
Normal file
BIN
toolkit/mozapps/update/tests/data/old_version.mar
Normal file
Binary file not shown.
BIN
toolkit/mozapps/update/tests/data/partial.exe
Normal file
BIN
toolkit/mozapps/update/tests/data/partial.exe
Normal file
Binary file not shown.
BIN
toolkit/mozapps/update/tests/data/partial.mar
Normal file
BIN
toolkit/mozapps/update/tests/data/partial.mar
Normal file
Binary file not shown.
BIN
toolkit/mozapps/update/tests/data/partial.png
Normal file
BIN
toolkit/mozapps/update/tests/data/partial.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 776 B |
192
toolkit/mozapps/update/tests/data/partial_log_failure_mac
Normal file
192
toolkit/mozapps/update/tests/data/partial_log_failure_mac
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
UPDATE TYPE partial
|
||||
PREPARE ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
PREPARE PATCH Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
PREPARE PATCH Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
PREPARE ADD Contents/Resources/precomplete
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
PREPARE PATCH Contents/Resources/0/0exe0.exe
|
||||
PREPARE ADD Contents/Resources/0/00/00text0
|
||||
PREPARE PATCH Contents/Resources/0/00/00png0.png
|
||||
PREPARE PATCH Contents/MacOS/exe0.exe
|
||||
PREPARE ADD Contents/Resources/2/20/20text0
|
||||
PREPARE ADD Contents/Resources/2/20/20png0.png
|
||||
PREPARE ADD Contents/Resources/0/00/00text2
|
||||
PREPARE REMOVEFILE Contents/Resources/1/10/10text0
|
||||
PREPARE REMOVEFILE Contents/Resources/0/00/00text1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/99/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/99/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/98/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/970/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/971/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/96/96text0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/96/96text1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/96/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/95/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/95/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/94/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/94/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/93/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/92/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/91/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/90/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/90/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/89/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/89/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/88/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/870/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/871/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/86/86text0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/86/86text1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/86/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/85/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/85/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/84/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/84/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/83/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/82/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/81/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/80/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/80/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/70/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/71/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/7text0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/7text1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/
|
||||
PREPARE REMOVEDIR Contents/Resources/6/
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text1
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text0
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5test.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text0
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text1
|
||||
PREPARE REMOVEDIR Contents/Resources/5/
|
||||
PREPARE REMOVEFILE Contents/Resources/4/4text1
|
||||
PREPARE REMOVEFILE Contents/Resources/4/4text0
|
||||
PREPARE REMOVEDIR Contents/Resources/4/
|
||||
PREPARE REMOVEFILE Contents/Resources/3/3text1
|
||||
PREPARE REMOVEFILE Contents/Resources/3/3text0
|
||||
PREPARE REMOVEDIR Contents/Resources/1/10/
|
||||
PREPARE REMOVEDIR Contents/Resources/1/
|
||||
EXECUTE ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
EXECUTE PATCH Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
EXECUTE PATCH Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
EXECUTE ADD Contents/Resources/precomplete
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
EXECUTE PATCH Contents/Resources/0/0exe0.exe
|
||||
LoadSourceFile: destination file size 776 does not match expected size 79872
|
||||
LoadSourceFile failed
|
||||
### execution failed
|
||||
FINISH ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
FINISH PATCH Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
FINISH PATCH Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
FINISH ADD Contents/Resources/precomplete
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/distribution/extensions/extensions1/extensions1text0.moz-backup
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
FINISH PATCH Contents/Resources/0/0exe0.exe
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/0/0exe0.exe.moz-backup
|
||||
FINISH ADD Contents/Resources/0/00/00text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/0/00/00text0.moz-backup
|
||||
FINISH PATCH Contents/Resources/0/00/00png0.png
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/0/00/00png0.png.moz-backup
|
||||
FINISH PATCH Contents/MacOS/exe0.exe
|
||||
backup_restore: backup file doesn't exist: Contents/MacOS/exe0.exe.moz-backup
|
||||
FINISH ADD Contents/Resources/2/20/20text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/2/20/20text0.moz-backup
|
||||
FINISH ADD Contents/Resources/2/20/20png0.png
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/2/20/20png0.png.moz-backup
|
||||
FINISH ADD Contents/Resources/0/00/00text2
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/0/00/00text2.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/1/10/10text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/1/10/10text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/0/00/00text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/0/00/00text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/9/97/970/97xtext0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/9/97/970/97xtext1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/9/97/971/97xtext0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/9/97/971/97xtext1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/9/96/96text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/9/96/96text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/9/96/96text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/9/96/96text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/8/87/870/87xtext0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/8/87/870/87xtext1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/8/87/871/87xtext0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/8/87/871/87xtext1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/8/86/86text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/8/86/86text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/8/86/86text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/8/86/86text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/70/7xtest.exe.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/70/7xtext0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/70/7xtext1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/71/7xtest.exe.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/71/7xtext0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/71/7xtext1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/7text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/7text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/7/7text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/7/7text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/5/5text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/5/5text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/5/5test.exe
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/5/5test.exe.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/5/5text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/5/5text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/4/4text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/4/4text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/4/4text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/4/4text0.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/3/3text1
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/3/3text1.moz-backup
|
||||
FINISH REMOVEFILE Contents/Resources/3/3text0
|
||||
backup_restore: backup file doesn't exist: Contents/Resources/3/3text0.moz-backup
|
||||
failed: 2
|
||||
calling QuitProgressUI
|
||||
192
toolkit/mozapps/update/tests/data/partial_log_failure_win
Normal file
192
toolkit/mozapps/update/tests/data/partial_log_failure_win
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
UPDATE TYPE partial
|
||||
PREPARE ADD searchplugins/searchpluginstext0
|
||||
PREPARE PATCH searchplugins/searchpluginspng1.png
|
||||
PREPARE PATCH searchplugins/searchpluginspng0.png
|
||||
PREPARE ADD precomplete
|
||||
PREPARE PATCH exe0.exe
|
||||
PREPARE ADD distribution/extensions/extensions1/extensions1text0
|
||||
PREPARE PATCH distribution/extensions/extensions1/extensions1png1.png
|
||||
PREPARE PATCH distribution/extensions/extensions1/extensions1png0.png
|
||||
PREPARE ADD distribution/extensions/extensions0/extensions0text0
|
||||
PREPARE PATCH distribution/extensions/extensions0/extensions0png1.png
|
||||
PREPARE PATCH distribution/extensions/extensions0/extensions0png0.png
|
||||
PREPARE PATCH 0/0exe0.exe
|
||||
PREPARE ADD 0/00/00text0
|
||||
PREPARE PATCH 0/00/00png0.png
|
||||
PREPARE ADD 2/20/20text0
|
||||
PREPARE ADD 2/20/20png0.png
|
||||
PREPARE ADD 0/00/00text2
|
||||
PREPARE REMOVEFILE 1/10/10text0
|
||||
PREPARE REMOVEFILE 0/00/00text1
|
||||
PREPARE REMOVEDIR 9/99/
|
||||
PREPARE REMOVEDIR 9/99/
|
||||
PREPARE REMOVEDIR 9/98/
|
||||
PREPARE REMOVEFILE 9/97/970/97xtext0
|
||||
PREPARE REMOVEFILE 9/97/970/97xtext1
|
||||
PREPARE REMOVEDIR 9/97/970/
|
||||
PREPARE REMOVEFILE 9/97/971/97xtext0
|
||||
PREPARE REMOVEFILE 9/97/971/97xtext1
|
||||
PREPARE REMOVEDIR 9/97/971/
|
||||
PREPARE REMOVEDIR 9/97/
|
||||
PREPARE REMOVEFILE 9/96/96text0
|
||||
PREPARE REMOVEFILE 9/96/96text1
|
||||
PREPARE REMOVEDIR 9/96/
|
||||
PREPARE REMOVEDIR 9/95/
|
||||
PREPARE REMOVEDIR 9/95/
|
||||
PREPARE REMOVEDIR 9/94/
|
||||
PREPARE REMOVEDIR 9/94/
|
||||
PREPARE REMOVEDIR 9/93/
|
||||
PREPARE REMOVEDIR 9/92/
|
||||
PREPARE REMOVEDIR 9/91/
|
||||
PREPARE REMOVEDIR 9/90/
|
||||
PREPARE REMOVEDIR 9/90/
|
||||
PREPARE REMOVEDIR 8/89/
|
||||
PREPARE REMOVEDIR 8/89/
|
||||
PREPARE REMOVEDIR 8/88/
|
||||
PREPARE REMOVEFILE 8/87/870/87xtext0
|
||||
PREPARE REMOVEFILE 8/87/870/87xtext1
|
||||
PREPARE REMOVEDIR 8/87/870/
|
||||
PREPARE REMOVEFILE 8/87/871/87xtext0
|
||||
PREPARE REMOVEFILE 8/87/871/87xtext1
|
||||
PREPARE REMOVEDIR 8/87/871/
|
||||
PREPARE REMOVEDIR 8/87/
|
||||
PREPARE REMOVEFILE 8/86/86text0
|
||||
PREPARE REMOVEFILE 8/86/86text1
|
||||
PREPARE REMOVEDIR 8/86/
|
||||
PREPARE REMOVEDIR 8/85/
|
||||
PREPARE REMOVEDIR 8/85/
|
||||
PREPARE REMOVEDIR 8/84/
|
||||
PREPARE REMOVEDIR 8/84/
|
||||
PREPARE REMOVEDIR 8/83/
|
||||
PREPARE REMOVEDIR 8/82/
|
||||
PREPARE REMOVEDIR 8/81/
|
||||
PREPARE REMOVEDIR 8/80/
|
||||
PREPARE REMOVEDIR 8/80/
|
||||
PREPARE REMOVEFILE 7/70/7xtest.exe
|
||||
PREPARE REMOVEFILE 7/70/7xtext0
|
||||
PREPARE REMOVEFILE 7/70/7xtext1
|
||||
PREPARE REMOVEDIR 7/70/
|
||||
PREPARE REMOVEFILE 7/71/7xtest.exe
|
||||
PREPARE REMOVEFILE 7/71/7xtext0
|
||||
PREPARE REMOVEFILE 7/71/7xtext1
|
||||
PREPARE REMOVEDIR 7/71/
|
||||
PREPARE REMOVEFILE 7/7text0
|
||||
PREPARE REMOVEFILE 7/7text1
|
||||
PREPARE REMOVEDIR 7/
|
||||
PREPARE REMOVEDIR 6/
|
||||
PREPARE REMOVEFILE 5/5text1
|
||||
PREPARE REMOVEFILE 5/5text0
|
||||
PREPARE REMOVEFILE 5/5test.exe
|
||||
PREPARE REMOVEFILE 5/5text0
|
||||
PREPARE REMOVEFILE 5/5text1
|
||||
PREPARE REMOVEDIR 5/
|
||||
PREPARE REMOVEFILE 4/4text1
|
||||
PREPARE REMOVEFILE 4/4text0
|
||||
PREPARE REMOVEDIR 4/
|
||||
PREPARE REMOVEFILE 3/3text1
|
||||
PREPARE REMOVEFILE 3/3text0
|
||||
PREPARE REMOVEDIR 1/10/
|
||||
PREPARE REMOVEDIR 1/
|
||||
EXECUTE ADD searchplugins/searchpluginstext0
|
||||
EXECUTE PATCH searchplugins/searchpluginspng1.png
|
||||
EXECUTE PATCH searchplugins/searchpluginspng0.png
|
||||
EXECUTE ADD precomplete
|
||||
EXECUTE PATCH exe0.exe
|
||||
EXECUTE ADD distribution/extensions/extensions1/extensions1text0
|
||||
EXECUTE PATCH distribution/extensions/extensions1/extensions1png1.png
|
||||
EXECUTE PATCH distribution/extensions/extensions1/extensions1png0.png
|
||||
EXECUTE ADD distribution/extensions/extensions0/extensions0text0
|
||||
EXECUTE PATCH distribution/extensions/extensions0/extensions0png1.png
|
||||
EXECUTE PATCH distribution/extensions/extensions0/extensions0png0.png
|
||||
EXECUTE PATCH 0/0exe0.exe
|
||||
LoadSourceFile: destination file size 776 does not match expected size 79872
|
||||
LoadSourceFile failed
|
||||
### execution failed
|
||||
FINISH ADD searchplugins/searchpluginstext0
|
||||
FINISH PATCH searchplugins/searchpluginspng1.png
|
||||
FINISH PATCH searchplugins/searchpluginspng0.png
|
||||
FINISH ADD precomplete
|
||||
FINISH PATCH exe0.exe
|
||||
FINISH ADD distribution/extensions/extensions1/extensions1text0
|
||||
backup_restore: backup file doesn't exist: distribution/extensions/extensions1/extensions1text0.moz-backup
|
||||
FINISH PATCH distribution/extensions/extensions1/extensions1png1.png
|
||||
FINISH PATCH distribution/extensions/extensions1/extensions1png0.png
|
||||
FINISH ADD distribution/extensions/extensions0/extensions0text0
|
||||
FINISH PATCH distribution/extensions/extensions0/extensions0png1.png
|
||||
FINISH PATCH distribution/extensions/extensions0/extensions0png0.png
|
||||
FINISH PATCH 0/0exe0.exe
|
||||
backup_restore: backup file doesn't exist: 0/0exe0.exe.moz-backup
|
||||
FINISH ADD 0/00/00text0
|
||||
backup_restore: backup file doesn't exist: 0/00/00text0.moz-backup
|
||||
FINISH PATCH 0/00/00png0.png
|
||||
backup_restore: backup file doesn't exist: 0/00/00png0.png.moz-backup
|
||||
FINISH ADD 2/20/20text0
|
||||
backup_restore: backup file doesn't exist: 2/20/20text0.moz-backup
|
||||
FINISH ADD 2/20/20png0.png
|
||||
backup_restore: backup file doesn't exist: 2/20/20png0.png.moz-backup
|
||||
FINISH ADD 0/00/00text2
|
||||
backup_restore: backup file doesn't exist: 0/00/00text2.moz-backup
|
||||
FINISH REMOVEFILE 1/10/10text0
|
||||
backup_restore: backup file doesn't exist: 1/10/10text0.moz-backup
|
||||
FINISH REMOVEFILE 0/00/00text1
|
||||
backup_restore: backup file doesn't exist: 0/00/00text1.moz-backup
|
||||
FINISH REMOVEFILE 9/97/970/97xtext0
|
||||
backup_restore: backup file doesn't exist: 9/97/970/97xtext0.moz-backup
|
||||
FINISH REMOVEFILE 9/97/970/97xtext1
|
||||
backup_restore: backup file doesn't exist: 9/97/970/97xtext1.moz-backup
|
||||
FINISH REMOVEFILE 9/97/971/97xtext0
|
||||
backup_restore: backup file doesn't exist: 9/97/971/97xtext0.moz-backup
|
||||
FINISH REMOVEFILE 9/97/971/97xtext1
|
||||
backup_restore: backup file doesn't exist: 9/97/971/97xtext1.moz-backup
|
||||
FINISH REMOVEFILE 9/96/96text0
|
||||
backup_restore: backup file doesn't exist: 9/96/96text0.moz-backup
|
||||
FINISH REMOVEFILE 9/96/96text1
|
||||
backup_restore: backup file doesn't exist: 9/96/96text1.moz-backup
|
||||
FINISH REMOVEFILE 8/87/870/87xtext0
|
||||
backup_restore: backup file doesn't exist: 8/87/870/87xtext0.moz-backup
|
||||
FINISH REMOVEFILE 8/87/870/87xtext1
|
||||
backup_restore: backup file doesn't exist: 8/87/870/87xtext1.moz-backup
|
||||
FINISH REMOVEFILE 8/87/871/87xtext0
|
||||
backup_restore: backup file doesn't exist: 8/87/871/87xtext0.moz-backup
|
||||
FINISH REMOVEFILE 8/87/871/87xtext1
|
||||
backup_restore: backup file doesn't exist: 8/87/871/87xtext1.moz-backup
|
||||
FINISH REMOVEFILE 8/86/86text0
|
||||
backup_restore: backup file doesn't exist: 8/86/86text0.moz-backup
|
||||
FINISH REMOVEFILE 8/86/86text1
|
||||
backup_restore: backup file doesn't exist: 8/86/86text1.moz-backup
|
||||
FINISH REMOVEFILE 7/70/7xtest.exe
|
||||
backup_restore: backup file doesn't exist: 7/70/7xtest.exe.moz-backup
|
||||
FINISH REMOVEFILE 7/70/7xtext0
|
||||
backup_restore: backup file doesn't exist: 7/70/7xtext0.moz-backup
|
||||
FINISH REMOVEFILE 7/70/7xtext1
|
||||
backup_restore: backup file doesn't exist: 7/70/7xtext1.moz-backup
|
||||
FINISH REMOVEFILE 7/71/7xtest.exe
|
||||
backup_restore: backup file doesn't exist: 7/71/7xtest.exe.moz-backup
|
||||
FINISH REMOVEFILE 7/71/7xtext0
|
||||
backup_restore: backup file doesn't exist: 7/71/7xtext0.moz-backup
|
||||
FINISH REMOVEFILE 7/71/7xtext1
|
||||
backup_restore: backup file doesn't exist: 7/71/7xtext1.moz-backup
|
||||
FINISH REMOVEFILE 7/7text0
|
||||
backup_restore: backup file doesn't exist: 7/7text0.moz-backup
|
||||
FINISH REMOVEFILE 7/7text1
|
||||
backup_restore: backup file doesn't exist: 7/7text1.moz-backup
|
||||
FINISH REMOVEFILE 5/5text1
|
||||
backup_restore: backup file doesn't exist: 5/5text1.moz-backup
|
||||
FINISH REMOVEFILE 5/5text0
|
||||
backup_restore: backup file doesn't exist: 5/5text0.moz-backup
|
||||
FINISH REMOVEFILE 5/5test.exe
|
||||
backup_restore: backup file doesn't exist: 5/5test.exe.moz-backup
|
||||
FINISH REMOVEFILE 5/5text0
|
||||
backup_restore: backup file doesn't exist: 5/5text0.moz-backup
|
||||
FINISH REMOVEFILE 5/5text1
|
||||
backup_restore: backup file doesn't exist: 5/5text1.moz-backup
|
||||
FINISH REMOVEFILE 4/4text1
|
||||
backup_restore: backup file doesn't exist: 4/4text1.moz-backup
|
||||
FINISH REMOVEFILE 4/4text0
|
||||
backup_restore: backup file doesn't exist: 4/4text0.moz-backup
|
||||
FINISH REMOVEFILE 3/3text1
|
||||
backup_restore: backup file doesn't exist: 3/3text1.moz-backup
|
||||
FINISH REMOVEFILE 3/3text0
|
||||
backup_restore: backup file doesn't exist: 3/3text0.moz-backup
|
||||
failed: 2
|
||||
calling QuitProgressUI
|
||||
279
toolkit/mozapps/update/tests/data/partial_log_success_mac
Normal file
279
toolkit/mozapps/update/tests/data/partial_log_success_mac
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
UPDATE TYPE partial
|
||||
PREPARE ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
PREPARE PATCH Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
PREPARE PATCH Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
PREPARE ADD Contents/Resources/precomplete
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
PREPARE ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
PREPARE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
PREPARE PATCH Contents/Resources/0/0exe0.exe
|
||||
PREPARE ADD Contents/Resources/0/00/00text0
|
||||
PREPARE PATCH Contents/Resources/0/00/00png0.png
|
||||
PREPARE PATCH Contents/MacOS/exe0.exe
|
||||
PREPARE ADD Contents/Resources/2/20/20text0
|
||||
PREPARE ADD Contents/Resources/2/20/20png0.png
|
||||
PREPARE ADD Contents/Resources/0/00/00text2
|
||||
PREPARE REMOVEFILE Contents/Resources/1/10/10text0
|
||||
PREPARE REMOVEFILE Contents/Resources/0/00/00text1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/99/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/99/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/98/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/970/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/971/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/97/
|
||||
PREPARE REMOVEFILE Contents/Resources/9/96/96text0
|
||||
PREPARE REMOVEFILE Contents/Resources/9/96/96text1
|
||||
PREPARE REMOVEDIR Contents/Resources/9/96/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/95/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/95/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/94/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/94/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/93/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/92/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/91/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/90/
|
||||
PREPARE REMOVEDIR Contents/Resources/9/90/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/89/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/89/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/88/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/870/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/871/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/87/
|
||||
PREPARE REMOVEFILE Contents/Resources/8/86/86text0
|
||||
PREPARE REMOVEFILE Contents/Resources/8/86/86text1
|
||||
PREPARE REMOVEDIR Contents/Resources/8/86/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/85/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/85/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/84/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/84/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/83/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/82/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/81/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/80/
|
||||
PREPARE REMOVEDIR Contents/Resources/8/80/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/70/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/71/
|
||||
PREPARE REMOVEFILE Contents/Resources/7/7text0
|
||||
PREPARE REMOVEFILE Contents/Resources/7/7text1
|
||||
PREPARE REMOVEDIR Contents/Resources/7/
|
||||
PREPARE REMOVEDIR Contents/Resources/6/
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text1
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text0
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5test.exe
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text0
|
||||
PREPARE REMOVEFILE Contents/Resources/5/5text1
|
||||
PREPARE REMOVEDIR Contents/Resources/5/
|
||||
PREPARE REMOVEFILE Contents/Resources/4/4text1
|
||||
PREPARE REMOVEFILE Contents/Resources/4/4text0
|
||||
PREPARE REMOVEDIR Contents/Resources/4/
|
||||
PREPARE REMOVEFILE Contents/Resources/3/3text1
|
||||
PREPARE REMOVEFILE Contents/Resources/3/3text0
|
||||
PREPARE REMOVEDIR Contents/Resources/1/10/
|
||||
PREPARE REMOVEDIR Contents/Resources/1/
|
||||
EXECUTE ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
EXECUTE PATCH Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
EXECUTE PATCH Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
EXECUTE ADD Contents/Resources/precomplete
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
EXECUTE ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
EXECUTE PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
EXECUTE PATCH Contents/Resources/0/0exe0.exe
|
||||
EXECUTE ADD Contents/Resources/0/00/00text0
|
||||
EXECUTE PATCH Contents/Resources/0/00/00png0.png
|
||||
EXECUTE PATCH Contents/MacOS/exe0.exe
|
||||
EXECUTE ADD Contents/Resources/2/20/20text0
|
||||
EXECUTE ADD Contents/Resources/2/20/20png0.png
|
||||
EXECUTE ADD Contents/Resources/0/00/00text2
|
||||
EXECUTE REMOVEFILE Contents/Resources/1/10/10text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/0/00/00text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/99/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/99/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/98/
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/97/970/
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/97/971/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/97/
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/96/96text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/9/96/96text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/96/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/95/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/95/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/94/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/94/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/93/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/92/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/91/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/90/
|
||||
EXECUTE REMOVEDIR Contents/Resources/9/90/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/89/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/89/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/88/
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/87/870/
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/87/871/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/87/
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/86/86text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/8/86/86text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/86/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/85/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/85/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/84/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/84/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/83/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/82/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/81/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/80/
|
||||
EXECUTE REMOVEDIR Contents/Resources/8/80/
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/7/70/
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
EXECUTE REMOVEDIR Contents/Resources/7/71/
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/7text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/7/7text1
|
||||
EXECUTE REMOVEDIR Contents/Resources/7/
|
||||
EXECUTE REMOVEDIR Contents/Resources/6/
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text1
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text0
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5test.exe
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text0
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEFILE Contents/Resources/5/5text1
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEDIR Contents/Resources/5/
|
||||
EXECUTE REMOVEFILE Contents/Resources/4/4text1
|
||||
EXECUTE REMOVEFILE Contents/Resources/4/4text0
|
||||
EXECUTE REMOVEDIR Contents/Resources/4/
|
||||
EXECUTE REMOVEFILE Contents/Resources/3/3text1
|
||||
EXECUTE REMOVEFILE Contents/Resources/3/3text0
|
||||
EXECUTE REMOVEDIR Contents/Resources/1/10/
|
||||
EXECUTE REMOVEDIR Contents/Resources/1/
|
||||
FINISH ADD Contents/Resources/searchplugins/searchpluginstext0
|
||||
FINISH PATCH Contents/Resources/searchplugins/searchpluginspng1.png
|
||||
FINISH PATCH Contents/Resources/searchplugins/searchpluginspng0.png
|
||||
FINISH ADD Contents/Resources/precomplete
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions1/extensions1text0
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png1.png
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions1/extensions1png0.png
|
||||
FINISH ADD Contents/Resources/distribution/extensions/extensions0/extensions0text0
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png1.png
|
||||
FINISH PATCH Contents/Resources/distribution/extensions/extensions0/extensions0png0.png
|
||||
FINISH PATCH Contents/Resources/0/0exe0.exe
|
||||
FINISH ADD Contents/Resources/0/00/00text0
|
||||
FINISH PATCH Contents/Resources/0/00/00png0.png
|
||||
FINISH PATCH Contents/MacOS/exe0.exe
|
||||
FINISH ADD Contents/Resources/2/20/20text0
|
||||
FINISH ADD Contents/Resources/2/20/20png0.png
|
||||
FINISH ADD Contents/Resources/0/00/00text2
|
||||
FINISH REMOVEFILE Contents/Resources/1/10/10text0
|
||||
FINISH REMOVEFILE Contents/Resources/0/00/00text1
|
||||
FINISH REMOVEDIR Contents/Resources/9/99/
|
||||
FINISH REMOVEDIR Contents/Resources/9/99/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/9/98/
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/970/97xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/970/97xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/9/97/970/
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/971/97xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/9/97/971/97xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/9/97/971/
|
||||
FINISH REMOVEDIR Contents/Resources/9/97/
|
||||
FINISH REMOVEFILE Contents/Resources/9/96/96text0
|
||||
FINISH REMOVEFILE Contents/Resources/9/96/96text1
|
||||
FINISH REMOVEDIR Contents/Resources/9/96/
|
||||
FINISH REMOVEDIR Contents/Resources/9/95/
|
||||
FINISH REMOVEDIR Contents/Resources/9/95/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/9/94/
|
||||
FINISH REMOVEDIR Contents/Resources/9/94/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/9/93/
|
||||
FINISH REMOVEDIR Contents/Resources/9/92/
|
||||
removing directory: Contents/Resources/9/92/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/9/91/
|
||||
removing directory: Contents/Resources/9/91/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/9/90/
|
||||
FINISH REMOVEDIR Contents/Resources/9/90/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/89/
|
||||
FINISH REMOVEDIR Contents/Resources/8/89/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/88/
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/870/87xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/870/87xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/8/87/870/
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/871/87xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/8/87/871/87xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/8/87/871/
|
||||
FINISH REMOVEDIR Contents/Resources/8/87/
|
||||
FINISH REMOVEFILE Contents/Resources/8/86/86text0
|
||||
FINISH REMOVEFILE Contents/Resources/8/86/86text1
|
||||
FINISH REMOVEDIR Contents/Resources/8/86/
|
||||
FINISH REMOVEDIR Contents/Resources/8/85/
|
||||
FINISH REMOVEDIR Contents/Resources/8/85/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/84/
|
||||
FINISH REMOVEDIR Contents/Resources/8/84/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR Contents/Resources/8/83/
|
||||
FINISH REMOVEDIR Contents/Resources/8/82/
|
||||
removing directory: Contents/Resources/8/82/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/8/81/
|
||||
removing directory: Contents/Resources/8/81/, rv: 0
|
||||
FINISH REMOVEDIR Contents/Resources/8/80/
|
||||
FINISH REMOVEDIR Contents/Resources/8/80/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtest.exe
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/7/70/7xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/7/70/
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtest.exe
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtext0
|
||||
FINISH REMOVEFILE Contents/Resources/7/71/7xtext1
|
||||
FINISH REMOVEDIR Contents/Resources/7/71/
|
||||
FINISH REMOVEFILE Contents/Resources/7/7text0
|
||||
FINISH REMOVEFILE Contents/Resources/7/7text1
|
||||
FINISH REMOVEDIR Contents/Resources/7/
|
||||
FINISH REMOVEDIR Contents/Resources/6/
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text1
|
||||
FINISH REMOVEFILE Contents/Resources/5/5text0
|
||||
FINISH REMOVEFILE Contents/Resources/5/5test.exe
|
||||
FINISH REMOVEDIR Contents/Resources/5/
|
||||
FINISH REMOVEFILE Contents/Resources/4/4text1
|
||||
FINISH REMOVEFILE Contents/Resources/4/4text0
|
||||
FINISH REMOVEDIR Contents/Resources/4/
|
||||
FINISH REMOVEFILE Contents/Resources/3/3text1
|
||||
FINISH REMOVEFILE Contents/Resources/3/3text0
|
||||
FINISH REMOVEDIR Contents/Resources/1/10/
|
||||
FINISH REMOVEDIR Contents/Resources/1/
|
||||
succeeded
|
||||
calling QuitProgressUI
|
||||
279
toolkit/mozapps/update/tests/data/partial_log_success_win
Normal file
279
toolkit/mozapps/update/tests/data/partial_log_success_win
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
UPDATE TYPE partial
|
||||
PREPARE ADD searchplugins/searchpluginstext0
|
||||
PREPARE PATCH searchplugins/searchpluginspng1.png
|
||||
PREPARE PATCH searchplugins/searchpluginspng0.png
|
||||
PREPARE ADD precomplete
|
||||
PREPARE PATCH exe0.exe
|
||||
PREPARE ADD distribution/extensions/extensions1/extensions1text0
|
||||
PREPARE PATCH distribution/extensions/extensions1/extensions1png1.png
|
||||
PREPARE PATCH distribution/extensions/extensions1/extensions1png0.png
|
||||
PREPARE ADD distribution/extensions/extensions0/extensions0text0
|
||||
PREPARE PATCH distribution/extensions/extensions0/extensions0png1.png
|
||||
PREPARE PATCH distribution/extensions/extensions0/extensions0png0.png
|
||||
PREPARE PATCH 0/0exe0.exe
|
||||
PREPARE ADD 0/00/00text0
|
||||
PREPARE PATCH 0/00/00png0.png
|
||||
PREPARE ADD 2/20/20text0
|
||||
PREPARE ADD 2/20/20png0.png
|
||||
PREPARE ADD 0/00/00text2
|
||||
PREPARE REMOVEFILE 1/10/10text0
|
||||
PREPARE REMOVEFILE 0/00/00text1
|
||||
PREPARE REMOVEDIR 9/99/
|
||||
PREPARE REMOVEDIR 9/99/
|
||||
PREPARE REMOVEDIR 9/98/
|
||||
PREPARE REMOVEFILE 9/97/970/97xtext0
|
||||
PREPARE REMOVEFILE 9/97/970/97xtext1
|
||||
PREPARE REMOVEDIR 9/97/970/
|
||||
PREPARE REMOVEFILE 9/97/971/97xtext0
|
||||
PREPARE REMOVEFILE 9/97/971/97xtext1
|
||||
PREPARE REMOVEDIR 9/97/971/
|
||||
PREPARE REMOVEDIR 9/97/
|
||||
PREPARE REMOVEFILE 9/96/96text0
|
||||
PREPARE REMOVEFILE 9/96/96text1
|
||||
PREPARE REMOVEDIR 9/96/
|
||||
PREPARE REMOVEDIR 9/95/
|
||||
PREPARE REMOVEDIR 9/95/
|
||||
PREPARE REMOVEDIR 9/94/
|
||||
PREPARE REMOVEDIR 9/94/
|
||||
PREPARE REMOVEDIR 9/93/
|
||||
PREPARE REMOVEDIR 9/92/
|
||||
PREPARE REMOVEDIR 9/91/
|
||||
PREPARE REMOVEDIR 9/90/
|
||||
PREPARE REMOVEDIR 9/90/
|
||||
PREPARE REMOVEDIR 8/89/
|
||||
PREPARE REMOVEDIR 8/89/
|
||||
PREPARE REMOVEDIR 8/88/
|
||||
PREPARE REMOVEFILE 8/87/870/87xtext0
|
||||
PREPARE REMOVEFILE 8/87/870/87xtext1
|
||||
PREPARE REMOVEDIR 8/87/870/
|
||||
PREPARE REMOVEFILE 8/87/871/87xtext0
|
||||
PREPARE REMOVEFILE 8/87/871/87xtext1
|
||||
PREPARE REMOVEDIR 8/87/871/
|
||||
PREPARE REMOVEDIR 8/87/
|
||||
PREPARE REMOVEFILE 8/86/86text0
|
||||
PREPARE REMOVEFILE 8/86/86text1
|
||||
PREPARE REMOVEDIR 8/86/
|
||||
PREPARE REMOVEDIR 8/85/
|
||||
PREPARE REMOVEDIR 8/85/
|
||||
PREPARE REMOVEDIR 8/84/
|
||||
PREPARE REMOVEDIR 8/84/
|
||||
PREPARE REMOVEDIR 8/83/
|
||||
PREPARE REMOVEDIR 8/82/
|
||||
PREPARE REMOVEDIR 8/81/
|
||||
PREPARE REMOVEDIR 8/80/
|
||||
PREPARE REMOVEDIR 8/80/
|
||||
PREPARE REMOVEFILE 7/70/7xtest.exe
|
||||
PREPARE REMOVEFILE 7/70/7xtext0
|
||||
PREPARE REMOVEFILE 7/70/7xtext1
|
||||
PREPARE REMOVEDIR 7/70/
|
||||
PREPARE REMOVEFILE 7/71/7xtest.exe
|
||||
PREPARE REMOVEFILE 7/71/7xtext0
|
||||
PREPARE REMOVEFILE 7/71/7xtext1
|
||||
PREPARE REMOVEDIR 7/71/
|
||||
PREPARE REMOVEFILE 7/7text0
|
||||
PREPARE REMOVEFILE 7/7text1
|
||||
PREPARE REMOVEDIR 7/
|
||||
PREPARE REMOVEDIR 6/
|
||||
PREPARE REMOVEFILE 5/5text1
|
||||
PREPARE REMOVEFILE 5/5text0
|
||||
PREPARE REMOVEFILE 5/5test.exe
|
||||
PREPARE REMOVEFILE 5/5text0
|
||||
PREPARE REMOVEFILE 5/5text1
|
||||
PREPARE REMOVEDIR 5/
|
||||
PREPARE REMOVEFILE 4/4text1
|
||||
PREPARE REMOVEFILE 4/4text0
|
||||
PREPARE REMOVEDIR 4/
|
||||
PREPARE REMOVEFILE 3/3text1
|
||||
PREPARE REMOVEFILE 3/3text0
|
||||
PREPARE REMOVEDIR 1/10/
|
||||
PREPARE REMOVEDIR 1/
|
||||
EXECUTE ADD searchplugins/searchpluginstext0
|
||||
EXECUTE PATCH searchplugins/searchpluginspng1.png
|
||||
EXECUTE PATCH searchplugins/searchpluginspng0.png
|
||||
EXECUTE ADD precomplete
|
||||
EXECUTE PATCH exe0.exe
|
||||
EXECUTE ADD distribution/extensions/extensions1/extensions1text0
|
||||
EXECUTE PATCH distribution/extensions/extensions1/extensions1png1.png
|
||||
EXECUTE PATCH distribution/extensions/extensions1/extensions1png0.png
|
||||
EXECUTE ADD distribution/extensions/extensions0/extensions0text0
|
||||
EXECUTE PATCH distribution/extensions/extensions0/extensions0png1.png
|
||||
EXECUTE PATCH distribution/extensions/extensions0/extensions0png0.png
|
||||
EXECUTE PATCH 0/0exe0.exe
|
||||
EXECUTE ADD 0/00/00text0
|
||||
EXECUTE PATCH 0/00/00png0.png
|
||||
EXECUTE ADD 2/20/20text0
|
||||
EXECUTE ADD 2/20/20png0.png
|
||||
EXECUTE ADD 0/00/00text2
|
||||
EXECUTE REMOVEFILE 1/10/10text0
|
||||
EXECUTE REMOVEFILE 0/00/00text1
|
||||
EXECUTE REMOVEDIR 9/99/
|
||||
EXECUTE REMOVEDIR 9/99/
|
||||
EXECUTE REMOVEDIR 9/98/
|
||||
EXECUTE REMOVEFILE 9/97/970/97xtext0
|
||||
EXECUTE REMOVEFILE 9/97/970/97xtext1
|
||||
EXECUTE REMOVEDIR 9/97/970/
|
||||
EXECUTE REMOVEFILE 9/97/971/97xtext0
|
||||
EXECUTE REMOVEFILE 9/97/971/97xtext1
|
||||
EXECUTE REMOVEDIR 9/97/971/
|
||||
EXECUTE REMOVEDIR 9/97/
|
||||
EXECUTE REMOVEFILE 9/96/96text0
|
||||
EXECUTE REMOVEFILE 9/96/96text1
|
||||
EXECUTE REMOVEDIR 9/96/
|
||||
EXECUTE REMOVEDIR 9/95/
|
||||
EXECUTE REMOVEDIR 9/95/
|
||||
EXECUTE REMOVEDIR 9/94/
|
||||
EXECUTE REMOVEDIR 9/94/
|
||||
EXECUTE REMOVEDIR 9/93/
|
||||
EXECUTE REMOVEDIR 9/92/
|
||||
EXECUTE REMOVEDIR 9/91/
|
||||
EXECUTE REMOVEDIR 9/90/
|
||||
EXECUTE REMOVEDIR 9/90/
|
||||
EXECUTE REMOVEDIR 8/89/
|
||||
EXECUTE REMOVEDIR 8/89/
|
||||
EXECUTE REMOVEDIR 8/88/
|
||||
EXECUTE REMOVEFILE 8/87/870/87xtext0
|
||||
EXECUTE REMOVEFILE 8/87/870/87xtext1
|
||||
EXECUTE REMOVEDIR 8/87/870/
|
||||
EXECUTE REMOVEFILE 8/87/871/87xtext0
|
||||
EXECUTE REMOVEFILE 8/87/871/87xtext1
|
||||
EXECUTE REMOVEDIR 8/87/871/
|
||||
EXECUTE REMOVEDIR 8/87/
|
||||
EXECUTE REMOVEFILE 8/86/86text0
|
||||
EXECUTE REMOVEFILE 8/86/86text1
|
||||
EXECUTE REMOVEDIR 8/86/
|
||||
EXECUTE REMOVEDIR 8/85/
|
||||
EXECUTE REMOVEDIR 8/85/
|
||||
EXECUTE REMOVEDIR 8/84/
|
||||
EXECUTE REMOVEDIR 8/84/
|
||||
EXECUTE REMOVEDIR 8/83/
|
||||
EXECUTE REMOVEDIR 8/82/
|
||||
EXECUTE REMOVEDIR 8/81/
|
||||
EXECUTE REMOVEDIR 8/80/
|
||||
EXECUTE REMOVEDIR 8/80/
|
||||
EXECUTE REMOVEFILE 7/70/7xtest.exe
|
||||
EXECUTE REMOVEFILE 7/70/7xtext0
|
||||
EXECUTE REMOVEFILE 7/70/7xtext1
|
||||
EXECUTE REMOVEDIR 7/70/
|
||||
EXECUTE REMOVEFILE 7/71/7xtest.exe
|
||||
EXECUTE REMOVEFILE 7/71/7xtext0
|
||||
EXECUTE REMOVEFILE 7/71/7xtext1
|
||||
EXECUTE REMOVEDIR 7/71/
|
||||
EXECUTE REMOVEFILE 7/7text0
|
||||
EXECUTE REMOVEFILE 7/7text1
|
||||
EXECUTE REMOVEDIR 7/
|
||||
EXECUTE REMOVEDIR 6/
|
||||
EXECUTE REMOVEFILE 5/5text1
|
||||
EXECUTE REMOVEFILE 5/5text0
|
||||
EXECUTE REMOVEFILE 5/5test.exe
|
||||
EXECUTE REMOVEFILE 5/5text0
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEFILE 5/5text1
|
||||
file cannot be removed because it does not exist; skipping
|
||||
EXECUTE REMOVEDIR 5/
|
||||
EXECUTE REMOVEFILE 4/4text1
|
||||
EXECUTE REMOVEFILE 4/4text0
|
||||
EXECUTE REMOVEDIR 4/
|
||||
EXECUTE REMOVEFILE 3/3text1
|
||||
EXECUTE REMOVEFILE 3/3text0
|
||||
EXECUTE REMOVEDIR 1/10/
|
||||
EXECUTE REMOVEDIR 1/
|
||||
FINISH ADD searchplugins/searchpluginstext0
|
||||
FINISH PATCH searchplugins/searchpluginspng1.png
|
||||
FINISH PATCH searchplugins/searchpluginspng0.png
|
||||
FINISH ADD precomplete
|
||||
FINISH PATCH exe0.exe
|
||||
FINISH ADD distribution/extensions/extensions1/extensions1text0
|
||||
FINISH PATCH distribution/extensions/extensions1/extensions1png1.png
|
||||
FINISH PATCH distribution/extensions/extensions1/extensions1png0.png
|
||||
FINISH ADD distribution/extensions/extensions0/extensions0text0
|
||||
FINISH PATCH distribution/extensions/extensions0/extensions0png1.png
|
||||
FINISH PATCH distribution/extensions/extensions0/extensions0png0.png
|
||||
FINISH PATCH 0/0exe0.exe
|
||||
FINISH ADD 0/00/00text0
|
||||
FINISH PATCH 0/00/00png0.png
|
||||
FINISH ADD 2/20/20text0
|
||||
FINISH ADD 2/20/20png0.png
|
||||
FINISH ADD 0/00/00text2
|
||||
FINISH REMOVEFILE 1/10/10text0
|
||||
FINISH REMOVEFILE 0/00/00text1
|
||||
FINISH REMOVEDIR 9/99/
|
||||
FINISH REMOVEDIR 9/99/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 9/98/
|
||||
FINISH REMOVEFILE 9/97/970/97xtext0
|
||||
FINISH REMOVEFILE 9/97/970/97xtext1
|
||||
FINISH REMOVEDIR 9/97/970/
|
||||
FINISH REMOVEFILE 9/97/971/97xtext0
|
||||
FINISH REMOVEFILE 9/97/971/97xtext1
|
||||
FINISH REMOVEDIR 9/97/971/
|
||||
FINISH REMOVEDIR 9/97/
|
||||
FINISH REMOVEFILE 9/96/96text0
|
||||
FINISH REMOVEFILE 9/96/96text1
|
||||
FINISH REMOVEDIR 9/96/
|
||||
FINISH REMOVEDIR 9/95/
|
||||
FINISH REMOVEDIR 9/95/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 9/94/
|
||||
FINISH REMOVEDIR 9/94/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 9/93/
|
||||
FINISH REMOVEDIR 9/92/
|
||||
removing directory: 9/92/, rv: 0
|
||||
FINISH REMOVEDIR 9/91/
|
||||
removing directory: 9/91/, rv: 0
|
||||
FINISH REMOVEDIR 9/90/
|
||||
FINISH REMOVEDIR 9/90/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/89/
|
||||
FINISH REMOVEDIR 8/89/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/88/
|
||||
FINISH REMOVEFILE 8/87/870/87xtext0
|
||||
FINISH REMOVEFILE 8/87/870/87xtext1
|
||||
FINISH REMOVEDIR 8/87/870/
|
||||
FINISH REMOVEFILE 8/87/871/87xtext0
|
||||
FINISH REMOVEFILE 8/87/871/87xtext1
|
||||
FINISH REMOVEDIR 8/87/871/
|
||||
FINISH REMOVEDIR 8/87/
|
||||
FINISH REMOVEFILE 8/86/86text0
|
||||
FINISH REMOVEFILE 8/86/86text1
|
||||
FINISH REMOVEDIR 8/86/
|
||||
FINISH REMOVEDIR 8/85/
|
||||
FINISH REMOVEDIR 8/85/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/84/
|
||||
FINISH REMOVEDIR 8/84/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEDIR 8/83/
|
||||
FINISH REMOVEDIR 8/82/
|
||||
removing directory: 8/82/, rv: 0
|
||||
FINISH REMOVEDIR 8/81/
|
||||
removing directory: 8/81/, rv: 0
|
||||
FINISH REMOVEDIR 8/80/
|
||||
FINISH REMOVEDIR 8/80/
|
||||
directory no longer exists; skipping
|
||||
FINISH REMOVEFILE 7/70/7xtest.exe
|
||||
FINISH REMOVEFILE 7/70/7xtext0
|
||||
FINISH REMOVEFILE 7/70/7xtext1
|
||||
FINISH REMOVEDIR 7/70/
|
||||
FINISH REMOVEFILE 7/71/7xtest.exe
|
||||
FINISH REMOVEFILE 7/71/7xtext0
|
||||
FINISH REMOVEFILE 7/71/7xtext1
|
||||
FINISH REMOVEDIR 7/71/
|
||||
FINISH REMOVEFILE 7/7text0
|
||||
FINISH REMOVEFILE 7/7text1
|
||||
FINISH REMOVEDIR 7/
|
||||
FINISH REMOVEDIR 6/
|
||||
FINISH REMOVEFILE 5/5text1
|
||||
FINISH REMOVEFILE 5/5text0
|
||||
FINISH REMOVEFILE 5/5test.exe
|
||||
FINISH REMOVEDIR 5/
|
||||
FINISH REMOVEFILE 4/4text1
|
||||
FINISH REMOVEFILE 4/4text0
|
||||
FINISH REMOVEDIR 4/
|
||||
FINISH REMOVEFILE 3/3text1
|
||||
FINISH REMOVEFILE 3/3text0
|
||||
FINISH REMOVEDIR 1/10/
|
||||
FINISH REMOVEDIR 1/
|
||||
succeeded
|
||||
calling QuitProgressUI
|
||||
BIN
toolkit/mozapps/update/tests/data/partial_mac.mar
Normal file
BIN
toolkit/mozapps/update/tests/data/partial_mac.mar
Normal file
Binary file not shown.
19
toolkit/mozapps/update/tests/data/partial_precomplete
Normal file
19
toolkit/mozapps/update/tests/data/partial_precomplete
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
remove "searchplugins/searchpluginstext0"
|
||||
remove "searchplugins/searchpluginspng1.png"
|
||||
remove "searchplugins/searchpluginspng0.png"
|
||||
remove "removed-files"
|
||||
remove "precomplete"
|
||||
remove "exe0.exe"
|
||||
remove "2/20/20text0"
|
||||
remove "2/20/20png0.png"
|
||||
remove "0/0exe0.exe"
|
||||
remove "0/00/00text2"
|
||||
remove "0/00/00text0"
|
||||
remove "0/00/00png0.png"
|
||||
rmdir "searchplugins/"
|
||||
rmdir "defaults/pref/"
|
||||
rmdir "defaults/"
|
||||
rmdir "2/20/"
|
||||
rmdir "2/"
|
||||
rmdir "0/00/"
|
||||
rmdir "0/"
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue