mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 1171518 - cleanup maintenance service logging. r=bbondy
This commit is contained in:
parent
4baf551671
commit
7f05087707
@ -262,6 +262,62 @@ Section "Uninstall"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\update\updater.exe"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-1.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-2.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-3.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-4.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-5.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-6.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-7.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-8.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-9.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-10.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-install.log"
|
||||
Call un.RenameDelete
|
||||
Push "$INSTDIR\logs\maintenanceservice-uninstall.log"
|
||||
Call un.RenameDelete
|
||||
SetShellVarContext all
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-1.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-2.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-3.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-4.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-5.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-6.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-7.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-8.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-9.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-10.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-install.log"
|
||||
Call un.RenameDelete
|
||||
Push "$APPDATA\Mozilla\logs\maintenanceservice-uninstall.log"
|
||||
Call un.RenameDelete
|
||||
RMDir /REBOOTOK "$APPDATA\Mozilla\logs"
|
||||
RMDir /REBOOTOK "$APPDATA\Mozilla"
|
||||
RMDir /REBOOTOK "$INSTDIR\logs"
|
||||
RMDir /REBOOTOK "$INSTDIR\update"
|
||||
RMDir /REBOOTOK "$INSTDIR"
|
||||
|
||||
|
@ -130,18 +130,13 @@ wmain(int argc, WCHAR **argv)
|
||||
BOOL
|
||||
GetLogDirectoryPath(WCHAR *path)
|
||||
{
|
||||
HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA, nullptr,
|
||||
SHGFP_TYPE_CURRENT, path);
|
||||
if (FAILED(hr)) {
|
||||
if (!GetModuleFileNameW(nullptr, path, MAX_PATH)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!PathAppendSafe(path, L"Mozilla")) {
|
||||
if (!PathRemoveFileSpecW(path)) {
|
||||
return FALSE;
|
||||
}
|
||||
// The directory should already be created from the installer, but
|
||||
// just to be safe in case someone deletes.
|
||||
CreateDirectoryW(path, nullptr);
|
||||
|
||||
if (!PathAppendSafe(path, L"logs")) {
|
||||
return FALSE;
|
||||
|
@ -390,36 +390,6 @@ PathAppendSafe(LPWSTR base, LPCWSTR extra)
|
||||
return PathAppendW(base, extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets update.status to pending so that the next startup will not use
|
||||
* the service and instead will attempt an update the with a UAC prompt.
|
||||
*
|
||||
* @param updateDirPath The path of the update directory
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
BOOL
|
||||
WriteStatusPending(LPCWSTR updateDirPath)
|
||||
{
|
||||
WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
|
||||
wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
|
||||
if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const char pending[] = "pending";
|
||||
HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
|
||||
nullptr, CREATE_ALWAYS, 0, nullptr);
|
||||
if (statusFile == INVALID_HANDLE_VALUE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD wrote;
|
||||
BOOL ok = WriteFile(statusFile, pending,
|
||||
sizeof(pending) - 1, &wrote, nullptr);
|
||||
CloseHandle(statusFile);
|
||||
return ok && (wrote == sizeof(pending) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets update.status to a specific failure code
|
||||
*
|
||||
@ -429,26 +399,41 @@ WriteStatusPending(LPCWSTR updateDirPath)
|
||||
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' };
|
||||
GetTempFileNameW(updateDirPath, L"svc", 0, tmpUpdateStatusFilePath);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
|
||||
nullptr, CREATE_ALWAYS, 0, nullptr);
|
||||
if (statusFile == INVALID_HANDLE_VALUE) {
|
||||
if (MoveFileExW(tmpUpdateStatusFilePath, updateStatusFilePath,
|
||||
MOVEFILE_REPLACE_EXISTING) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
char failure[32];
|
||||
sprintf(failure, "failed: %d", errorCode);
|
||||
|
||||
DWORD toWrite = strlen(failure);
|
||||
DWORD wrote;
|
||||
BOOL ok = WriteFile(statusFile, failure,
|
||||
toWrite, &wrote, nullptr);
|
||||
CloseHandle(statusFile);
|
||||
return ok && wrote == toWrite;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -10,7 +10,6 @@ BOOL StartServiceUpdate(LPCWSTR installDir);
|
||||
BOOL GetUpdateDirectoryPath(LPWSTR path);
|
||||
DWORD LaunchServiceSoftwareUpdateCommand(int argc, LPCWSTR *argv);
|
||||
BOOL WriteStatusFailure(LPCWSTR updateDirPath, int errorCode);
|
||||
BOOL WriteStatusPending(LPCWSTR updateDirPath);
|
||||
DWORD WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds);
|
||||
DWORD WaitForProcessExit(LPCWSTR filename, DWORD maxSeconds);
|
||||
BOOL DoesFallbackKeyExist();
|
||||
|
@ -26,17 +26,32 @@ void UpdateLog::Init(NS_tchar* sourcePath,
|
||||
if (logFP)
|
||||
return;
|
||||
|
||||
this->sourcePath = sourcePath;
|
||||
NS_tchar logFile[MAXPATHLEN];
|
||||
NS_tsnprintf(logFile, sizeof(logFile)/sizeof(logFile[0]),
|
||||
NS_T("%s/%s"), sourcePath, fileName);
|
||||
#ifdef XP_WIN
|
||||
GetTempFileNameW(sourcePath, L"log", 0, mTmpFilePath);
|
||||
if (append) {
|
||||
NS_tsnprintf(mDstFilePath, sizeof(mDstFilePath)/sizeof(mDstFilePath[0]),
|
||||
NS_T("%s/%s"), sourcePath, alternateFileName);
|
||||
MoveFileExW(mDstFilePath, mTmpFilePath, MOVEFILE_REPLACE_EXISTING);
|
||||
} else {
|
||||
NS_tsnprintf(mDstFilePath, sizeof(mDstFilePath)/sizeof(mDstFilePath[0]),
|
||||
NS_T("%s/%s"), sourcePath, fileName);
|
||||
}
|
||||
|
||||
if (alternateFileName && NS_taccess(logFile, F_OK)) {
|
||||
NS_tsnprintf(logFile, sizeof(logFile)/sizeof(logFile[0]),
|
||||
logFP = NS_tfopen(mTmpFilePath, append ? NS_T("a") : 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);
|
||||
#else
|
||||
NS_tsnprintf(mDstFilePath, sizeof(mDstFilePath)/sizeof(mDstFilePath[0]),
|
||||
NS_T("%s/%s"), sourcePath, fileName);
|
||||
|
||||
if (alternateFileName && NS_taccess(mDstFilePath, F_OK)) {
|
||||
NS_tsnprintf(mDstFilePath, sizeof(mDstFilePath)/sizeof(mDstFilePath[0]),
|
||||
NS_T("%s/%s"), sourcePath, alternateFileName);
|
||||
}
|
||||
|
||||
logFP = NS_tfopen(logFile, append ? NS_T("a") : NS_T("w"));
|
||||
logFP = NS_tfopen(mDstFilePath, append ? NS_T("a") : NS_T("w"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpdateLog::Finish()
|
||||
@ -46,6 +61,16 @@ void UpdateLog::Finish()
|
||||
|
||||
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()
|
||||
|
@ -32,7 +32,8 @@ public:
|
||||
protected:
|
||||
UpdateLog();
|
||||
FILE *logFP;
|
||||
NS_tchar* sourcePath;
|
||||
NS_tchar mTmpFilePath[MAXPATHLEN];
|
||||
NS_tchar mDstFilePath[MAXPATHLEN];
|
||||
};
|
||||
|
||||
#define LOG_WARN(args) UpdateLog::GetPrimaryLog().WarnPrintf args
|
||||
|
@ -1272,6 +1272,41 @@ function getTestDirFile(aRelPath, aAllowNonExists) {
|
||||
return do_get_file(relpath, !!aAllowNonExists);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for getting the nsIFile for the maintenance service
|
||||
* directory on Windows.
|
||||
*
|
||||
* @return The nsIFile for the maintenance service directory.
|
||||
*/
|
||||
function getMaintSvcDir() {
|
||||
if (!IS_WIN) {
|
||||
do_throw("Windows only function called by a different platform!");
|
||||
}
|
||||
|
||||
const CSIDL_PROGRAM_FILES = 0x26;
|
||||
const CSIDL_PROGRAM_FILESX86 = 0x2A;
|
||||
// This will return an empty string on our Win XP build systems.
|
||||
let maintSvcDir = getSpecialFolderDir(CSIDL_PROGRAM_FILESX86);
|
||||
if (maintSvcDir) {
|
||||
maintSvcDir.append("Mozilla Maintenance Service");
|
||||
debugDump("using CSIDL_PROGRAM_FILESX86 - maintenance service install " +
|
||||
"directory path: " + maintSvcDir.path);
|
||||
}
|
||||
if (!maintSvcDir || !maintSvcDir.exists()) {
|
||||
maintSvcDir = getSpecialFolderDir(CSIDL_PROGRAM_FILES);
|
||||
if (maintSvcDir) {
|
||||
maintSvcDir.append("Mozilla Maintenance Service");
|
||||
debugDump("using CSIDL_PROGRAM_FILES - maintenance service install " +
|
||||
"directory path: " + maintSvcDir.path);
|
||||
}
|
||||
}
|
||||
if (!maintSvcDir) {
|
||||
do_throw("Unable to find the maintenance service install directory");
|
||||
}
|
||||
|
||||
return maintSvcDir;
|
||||
}
|
||||
|
||||
function getSpecialFolderDir(aCSIDL) {
|
||||
if (!IS_WIN) {
|
||||
do_throw("Windows only function called by a different platform!");
|
||||
@ -1933,26 +1968,7 @@ function copyFileToTestAppDir(aFileRelPath, aInGreDir) {
|
||||
* a unprivileged location.
|
||||
*/
|
||||
function attemptServiceInstall() {
|
||||
const CSIDL_PROGRAM_FILES = 0x26;
|
||||
const CSIDL_PROGRAM_FILESX86 = 0x2A;
|
||||
// This will return an empty string on our Win XP build systems.
|
||||
let maintSvcDir = getSpecialFolderDir(CSIDL_PROGRAM_FILESX86);
|
||||
if (maintSvcDir) {
|
||||
maintSvcDir.append("Mozilla Maintenance Service");
|
||||
debugDump("using CSIDL_PROGRAM_FILESX86 - maintenance service install " +
|
||||
"directory path: " + maintSvcDir.path);
|
||||
}
|
||||
if (!maintSvcDir || !maintSvcDir.exists()) {
|
||||
maintSvcDir = getSpecialFolderDir(CSIDL_PROGRAM_FILES);
|
||||
if (maintSvcDir) {
|
||||
maintSvcDir.append("Mozilla Maintenance Service");
|
||||
debugDump("using CSIDL_PROGRAM_FILES - maintenance service install " +
|
||||
"directory path: " + maintSvcDir.path);
|
||||
}
|
||||
}
|
||||
if (!maintSvcDir) {
|
||||
do_throw("Unable to find the maintenance service install directory");
|
||||
}
|
||||
let maintSvcDir = getMaintSvcDir();
|
||||
Assert.ok(maintSvcDir.exists(), MSG_SHOULD_EXIST);
|
||||
let oldMaintSvcBin = maintSvcDir.clone();
|
||||
oldMaintSvcBin.append(FILE_MAINTENANCE_SERVICE_BIN);
|
||||
@ -2013,10 +2029,7 @@ function runUpdateUsingService(aInitialStatus, aExpectedStatus, aCheckSvcLog) {
|
||||
"contain the successful launch string");
|
||||
}
|
||||
function readServiceLogFile() {
|
||||
let file = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties).
|
||||
get("CmAppData", Ci.nsIFile);
|
||||
file.append("Mozilla");
|
||||
let file = getMaintSvcDir();
|
||||
file.append("logs");
|
||||
file.append("maintenanceservice.log");
|
||||
return readFile(file);
|
||||
|
@ -64,7 +64,12 @@
|
||||
#define PROGRESS_FINISH_SIZE 5.0f
|
||||
|
||||
// Amount of time in ms to wait for the parent process to close
|
||||
#define PARENT_WAIT 5000
|
||||
#ifdef DEBUG
|
||||
// Use a large value for debug builds since the xpcshell tests take a long time.
|
||||
#define PARENT_WAIT 30000
|
||||
#else
|
||||
#define PARENT_WAIT 10000
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// These functions are defined in launchchild_osx.mm
|
||||
@ -1843,20 +1848,42 @@ LaunchCallbackApp(const NS_tchar *workingDir,
|
||||
static bool
|
||||
WriteStatusFile(const char* aStatus)
|
||||
{
|
||||
NS_tchar filename[MAXPATHLEN];
|
||||
NS_tchar filename[MAXPATHLEN] = {NS_T('\0')};
|
||||
#if defined(XP_WIN)
|
||||
// The temp file is not removed on failure since there is client code that
|
||||
// will remove it.
|
||||
GetTempFileNameW(gPatchDirPath, L"sta", 0, filename);
|
||||
#else
|
||||
NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
|
||||
NS_T("%s/update.status"), gPatchDirPath);
|
||||
#endif
|
||||
|
||||
// Make sure that the directory for the update status file exists
|
||||
if (ensure_parent_dir(filename))
|
||||
if (ensure_parent_dir(filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoFile file(NS_tfopen(filename, NS_T("wb+")));
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
// This is scoped to make the AutoFile close the file so it is possible to
|
||||
// move the temp file to the update.status file on Windows.
|
||||
{
|
||||
AutoFile file(NS_tfopen(filename, NS_T("wb+")));
|
||||
if (file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(aStatus, strlen(aStatus), 1, file) != 1)
|
||||
if (fwrite(aStatus, strlen(aStatus), 1, file) != 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
NS_tchar dstfilename[MAXPATHLEN] = {NS_T('\0')};
|
||||
NS_tsnprintf(dstfilename, sizeof(dstfilename)/sizeof(dstfilename[0]),
|
||||
NS_T("%s\\update.status"), gPatchDirPath);
|
||||
if (MoveFileExW(filename, dstfilename, MOVEFILE_REPLACE_EXISTING) == 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2777,14 +2804,14 @@ int NS_main(int argc, NS_tchar **argv)
|
||||
}
|
||||
}
|
||||
|
||||
// If the service can't be used when staging and update, make sure that
|
||||
// If the service can't be used when staging an update, make sure that
|
||||
// the UAC prompt is not shown! In this case, just set the status to
|
||||
// pending and the update will be applied during the next startup.
|
||||
if (!useService && sStagedUpdate) {
|
||||
if (updateLockFileHandle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(updateLockFileHandle);
|
||||
}
|
||||
WriteStatusPending(gPatchDirPath);
|
||||
WriteStatusFile("pending");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -101,10 +101,6 @@ BOOL
|
||||
WinLaunchChild(const wchar_t *exePath, int argc,
|
||||
char **argv, HANDLE userToken = nullptr,
|
||||
HANDLE *hProcess = nullptr);
|
||||
BOOL
|
||||
WriteStatusPending(LPCWSTR updateDirPath);
|
||||
BOOL
|
||||
WriteStatusApplied(LPCWSTR updateDirPath);
|
||||
#endif
|
||||
|
||||
#define NS_NATIVEAPPSUPPORT_CONTRACTID "@mozilla.org/toolkit/native-app-support;1"
|
||||
|
Loading…
Reference in New Issue
Block a user