diff --git a/mozilla/xpinstall/src/ScheduledTasks.cpp b/mozilla/xpinstall/src/ScheduledTasks.cpp index 4fb24d7342f..4b9fd559705 100644 --- a/mozilla/xpinstall/src/ScheduledTasks.cpp +++ b/mozilla/xpinstall/src/ScheduledTasks.cpp @@ -30,8 +30,11 @@ #include "nsInstall.h" // for error codes #include "prmem.h" #include "ScheduledTasks.h" +#include "InstallCleanupDefines.h" - +#include "nsSpecialSystemDirectory.h" +#include "nsDirectoryService.h" +#include "nsDirectoryServiceDefs.h" static nsresult GetPersistentStringFromSpec(nsIFile* inSpec, char **string) @@ -134,7 +137,33 @@ PRInt32 ReplaceExistingWindowsFile(nsIFile* currentSpec, nsIFile* finalSpec) } #endif +char* GetRegFilePath() +{ + nsresult rv; + nsCOMPtr iFileUtilityPath; + //Get the program directory + NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return nsnull; + directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), + getter_AddRefs(iFileUtilityPath)); + if (!iFileUtilityPath) + return nsnull; + +#if defined (XP_MAC) + iFileUtilityPath->Append(ESSENTIAL_FILES); +#endif + iFileUtilityPath->Append(CLEANUP_REGISTRY); + + //Yes, we know using GetPath is buggy on the Mac. + //When libreg is fixed to accept nsIFiles we'll change this to match. + char* regFilePath; + iFileUtilityPath->GetPath(®FilePath); + + return regFilePath; +} PRInt32 DeleteFileNowOrSchedule(nsIFile* filename) @@ -159,7 +188,11 @@ PRInt32 ScheduleFileForDeletion(nsIFile *filename) REGERR err; PRInt32 result = nsInstall::UNEXPECTED_ERROR; - err = NR_RegOpen("", ®) ; + char* regFilePath = GetRegFilePath(); + err = NR_RegOpen(regFilePath, ®); + if (regFilePath) + nsCRT::free(regFilePath); + if ( err == REGERR_OK ) { err = NR_RegAddKey(reg,ROOTKEY_PRIVATE,REG_DELETE_LIST_KEY,&newkey); @@ -328,7 +361,8 @@ PRInt32 ReplaceFileNowOrSchedule(nsIFile* replacementFile, nsIFile* doomedFile ) HREG reg; REGERR err; - if ( REGERR_OK == NR_RegOpen("", ®) ) + char* regFilePath = GetRegFilePath(); + if ( REGERR_OK == NR_RegOpen(regFilePath, ®) ) { err = NR_RegAddKey( reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY, &listkey ); if ( err == REGERR_OK ) @@ -373,9 +407,10 @@ PRInt32 ReplaceFileNowOrSchedule(nsIFile* replacementFile, nsIFile* doomedFile ) } } } - NR_RegClose(reg); } + if (regFilePath) + nsCRT::free(regFilePath); } return result; @@ -524,3 +559,5 @@ void ReplaceScheduledFiles( HREG reg ) } } } + + diff --git a/mozilla/xpinstall/src/ScheduledTasks.h b/mozilla/xpinstall/src/ScheduledTasks.h index 67e7b6f0634..ff2fc11afd5 100644 --- a/mozilla/xpinstall/src/ScheduledTasks.h +++ b/mozilla/xpinstall/src/ScheduledTasks.h @@ -38,6 +38,7 @@ PR_BEGIN_EXTERN_C PRInt32 DeleteFileNowOrSchedule(nsIFile* filename); PRInt32 ReplaceFileNowOrSchedule(nsIFile* tmpfile, nsIFile* target ); PRInt32 ScheduleFileForDeletion(nsIFile* filename); +char* GetRegFilePath(); void PerformScheduledTasks(HREG reg); diff --git a/mozilla/xpinstall/src/nsInstall.cpp b/mozilla/xpinstall/src/nsInstall.cpp index e287a38fa99..2a08a23a9b7 100644 --- a/mozilla/xpinstall/src/nsInstall.cpp +++ b/mozilla/xpinstall/src/nsInstall.cpp @@ -59,6 +59,7 @@ #include "nsXPIProxy.h" #include "nsRegisterItem.h" #include "nsNetUtil.h" +#include "ScheduledTasks.h" #include "nsIProxyObjectManager.h" #include "nsProxiedService.h" @@ -854,7 +855,10 @@ nsInstall::FinalizeInstall(PRInt32* aReturn) if ( result == SUCCESS ) { if ( rebootNeeded ) + { *aReturn = SaveError( REBOOT_NEEDED ); + nsSoftwareUpdate::mNeedCleanup = PR_TRUE; + } // XXX for now all successful installs will trigger an Autoreg. // We eventually want to do this only when flagged. diff --git a/mozilla/xpinstall/src/nsSoftwareUpdate.cpp b/mozilla/xpinstall/src/nsSoftwareUpdate.cpp index 5c257c25758..2f10afb990b 100644 --- a/mozilla/xpinstall/src/nsSoftwareUpdate.cpp +++ b/mozilla/xpinstall/src/nsSoftwareUpdate.cpp @@ -32,6 +32,7 @@ #include "nsICategoryManager.h" #include "nsCOMPtr.h" #include "nsCRT.h" +#include "nsIObserverService.h" #include "nspr.h" #include "prlock.h" @@ -48,12 +49,15 @@ #include "nsInstallTrigger.h" #include "nsInstallVersion.h" #include "ScheduledTasks.h" +#include "InstallCleanupDefines.h" #include "nsTopProgressNotifier.h" #include "nsLoggingProgressNotifier.h" #include "nsIRegistry.h" #include "nsBuildID.h" +#include "nsSpecialSystemDirectory.h" +#include "nsProcess.h" /* For Javascript Namespace Access */ #include "nsDOMCID.h" @@ -84,9 +88,12 @@ static NS_DEFINE_CID(kInstallVersion_CID, NS_SoftwareUpdateInstallVersion_CID); static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID); static NS_DEFINE_CID(knsRegistryCID, NS_REGISTRY_CID); +static NS_DEFINE_CID(kIProcessCID, NS_PROCESS_CID); + nsSoftwareUpdate* nsSoftwareUpdate::mInstance = nsnull; nsCOMPtr nsSoftwareUpdate::mProgramDir = nsnull; char* nsSoftwareUpdate::mLogName = nsnull; +PRBool nsSoftwareUpdate::mNeedCleanup = PR_FALSE; nsSoftwareUpdate * @@ -134,12 +141,17 @@ nsSoftwareUpdate::nsSoftwareUpdate() nsMemory::Free(nativePath); } + /***************************************/ + /* Add this as a shutdown observer */ + /***************************************/ + NS_WITH_SERVICE(nsIObserverService, observerService, + NS_OBSERVERSERVICE_CONTRACTID, &rv); + + if (NS_SUCCEEDED(rv)) + observerService->AddObserver(this, NS_LITERAL_STRING(NS_XPCOM_SHUTDOWN_OBSERVER_ID).get()); } - - - nsSoftwareUpdate::~nsSoftwareUpdate() { PR_Lock(mLock); @@ -170,10 +182,49 @@ nsSoftwareUpdate::~nsSoftwareUpdate() // nsISupports implementation //------------------------------------------------------------------------ -NS_IMPL_THREADSAFE_ISUPPORTS2(nsSoftwareUpdate, +NS_IMPL_THREADSAFE_ISUPPORTS3(nsSoftwareUpdate, nsISoftwareUpdate, - nsPIXPIStubHook); + nsPIXPIStubHook, + nsIObserver); +void +nsSoftwareUpdate::Shutdown() +{ + if (mNeedCleanup) + { + // Create a non-blocking process to run the native platform cleanup utility + nsresult rv; + nsCOMPtr pathToCleanupUtility; + //Get the program directory + NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), + getter_AddRefs(pathToCleanupUtility)); +#if defined (XP_MAC) + pathToCleanupUtility->Append(ESSENTIAL_FILES); +#endif + //Create the Process framework + pathToCleanupUtility->Append(CLEANUP_UTIL); + nsCOMPtr cleanupProcess = do_CreateInstance(kIProcessCID); + rv = cleanupProcess->Init(pathToCleanupUtility); + if (NS_SUCCEEDED(rv)) + { + //Run the cleanup utility as a NON-blocking process + rv = cleanupProcess->Run(PR_FALSE, nsnull, 0, nsnull); + } + } +} + +NS_IMETHODIMP nsSoftwareUpdate::Observe(nsISupports *aSubject, + const PRUnichar *aTopic, + const PRUnichar *aData) +{ + nsLiteralString topicString(aTopic); + if (topicString.Equals(NS_LITERAL_STRING(NS_XPCOM_SHUTDOWN_OBSERVER_ID))) + Shutdown(); + + return NS_OK; +} NS_IMETHODIMP nsSoftwareUpdate::RegisterListener(nsIXPIListener *aListener) diff --git a/mozilla/xpinstall/src/nsSoftwareUpdate.h b/mozilla/xpinstall/src/nsSoftwareUpdate.h index 4416937d8d4..93887ba304f 100644 --- a/mozilla/xpinstall/src/nsSoftwareUpdate.h +++ b/mozilla/xpinstall/src/nsSoftwareUpdate.h @@ -20,6 +20,7 @@ class nsInstallInfo; #include "nsIScriptExternalNameSet.h" #include "nsIAppShellComponent.h" #include "nsIDOMWindowInternal.h" +#include "nsIObserver.h" #include "nsPIXPIStubHook.h" #include "nsTopProgressNotifier.h" @@ -29,7 +30,8 @@ class nsInstallInfo; #define XPCOM_KEY "software/mozilla/XPCOM" class nsSoftwareUpdate: public nsISoftwareUpdate, - public nsPIXPIStubHook + public nsPIXPIStubHook, + public nsIObserver { public: @@ -50,6 +52,7 @@ class nsSoftwareUpdate: public nsISoftwareUpdate, NS_DECL_ISUPPORTS NS_DECL_NSPIXPISTUBHOOK + NS_DECL_NSIOBSERVER NS_IMETHOD InstallJar( nsIFile* localFile, const PRUnichar* URL, @@ -75,6 +78,7 @@ class nsSoftwareUpdate: public nsISoftwareUpdate, nsSoftwareUpdate(); virtual ~nsSoftwareUpdate(); + static PRBool mNeedCleanup; private: static nsSoftwareUpdate* mInstance; @@ -84,6 +88,7 @@ class nsSoftwareUpdate: public nsISoftwareUpdate, nsresult RunNextInstall(); nsresult RegisterNameset(); void CreateMasterListener(); + void Shutdown(); PRLock* mLock; PRBool mInstalling;