Fixes NS_InitEmbedding unconditionally calls AutoRegister. This also removes xpinstall from using component.reg which I believe is the last users of this file. r=chak,dveditz sr=bryner b=149208

This commit is contained in:
dougt%netscape.com 2002-08-12 22:09:25 +00:00
parent 91e8ca541e
commit c82b168650
5 changed files with 66 additions and 178 deletions

View File

@ -100,7 +100,7 @@ nsresult NS_InitEmbedding(nsILocalFile *mozBinDirectory,
NS_ASSERTION(PR_FALSE, "Could not QI to registrar");
return rv;
}
#ifdef DEBUG
rv = registrar->AutoRegister(nsnull);
if (NS_FAILED(rv))
@ -133,7 +133,7 @@ nsresult NS_InitEmbedding(nsILocalFile *mozBinDirectory,
}
}
}
#endif
sRegistryInitializedFlag = PR_TRUE;
}

View File

@ -197,6 +197,43 @@ RegisterGenericFactory(nsIComponentManager* compMgr,
return rv;
}
// in order to support the installer, we need
// to be told out of band if we should cause
// an autoregister. if a file exists named
// ".autoreg" next to the application, this
// will signal us to cause autoreg.
static PRBool CheckAndRemoveUpdateFile()
{
nsresult rv;
nsCOMPtr<nsIProperties> directoryService;
nsDirectoryService::Create(nsnull,
NS_GET_IID(nsIProperties),
getter_AddRefs(directoryService));
if (!directoryService)
return PR_FALSE;
nsCOMPtr<nsIFile> file;
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(file));
if (NS_FAILED(rv)) {
NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
return PR_FALSE;
}
file->AppendNative(nsDependentCString(".autoreg"));
PRBool exists = PR_FALSE;
file->Exists(&exists);
if (!exists)
return exists;
file->Remove(PR_FALSE);
return exists;
}
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
nsIProperties *gDirectoryService = NULL;
@ -482,12 +519,12 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
}
#endif
if ( NS_FAILED(rv) ) {
if ( NS_FAILED(rv) || CheckAndRemoveUpdateFile()) {
// if we find no persistent registry, we will try to autoregister
// the default components directory.
nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);
}
// Pay the cost at startup time of starting this singleton.
nsIInterfaceInfoManager* iim = XPTI_GetInterfaceInfoManager();
NS_IF_RELEASE(iim);
@ -501,6 +538,7 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
return rv;
}
static nsVoidArray* gExitRoutines;
static void CallExitRoutines()

View File

@ -1350,24 +1350,14 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
NS_ASSERTION(NS_SUCCEEDED(rv), "Initializing AppleEvents failed");
#endif
NS_TIMELINE_ENTER("setup registry");
// Ask XPInstall if we need to autoregister anything new.
PRBool needAutoReg = NS_SoftwareUpdateNeedsAutoReg();
#ifdef DEBUG
// _Always_ autoreg if we're in a debug build, under the assumption
// that people are busily modifying components and will be angry if
// their changes aren't noticed.
needAutoReg = PR_TRUE;
#endif
if (needAutoReg) {
nsComponentManager::AutoRegister(nsIComponentManagerObsolete::NS_Startup,
NULL /* default */);
// XXX ...and autoreg was successful?
NS_SoftwareUpdateDidAutoReg();
}
NS_TIMELINE_LEAVE("setup registry");
#endif
// remove the nativeApp as an XPCOM autoreg observer
if (obsService)

View File

@ -36,8 +36,8 @@
#include "nsIModule.h"
#include "nsIGenericFactory.h"
#include "nsIRegistry.h"
#include "nsIRegistryUtils.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#define NS_IXPINSTALLCOMPONENT_CONTRACTID "@mozilla.org/xpinstall;1"
#define NS_IXPINSTALLCOMPONENT_CLASSNAME "Mozilla XPInstall Component"
@ -87,83 +87,32 @@ class nsISoftwareUpdate : public nsISupports
};
#define XPI_ROOT_KEY "software/mozilla/xpinstall"
#define XPI_AUTOREG_VAL "Autoreg"
#define XPCOM_KEY "software/mozilla/XPCOM"
/**
* @return PR_TRUE if XPI has requested an autoreg be performed.
*/
inline PRBool
NS_SoftwareUpdateNeedsAutoReg()
{
nsresult rv;
// Conservatively assume that we'll need to autoreg.
PRBool needAutoReg = PR_TRUE;
nsCOMPtr<nsIRegistry> reg = do_GetService(NS_REGISTRY_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = reg->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_SUCCEEDED(rv)) {
nsRegistryKey idKey = 0;
rv = reg->GetSubtree(nsIRegistry::Common, XPI_ROOT_KEY, &idKey);
if (NS_SUCCEEDED(rv)) {
char* autoRegVal = nsnull;
rv = reg->GetStringUTF8(idKey, XPI_AUTOREG_VAL, &autoRegVal);
// If the string exists and isn't yes'', then we can avoid
// autoreg; otherwise, be conservative and autoregister.
if (NS_SUCCEEDED(rv) && (PL_strcmp(autoRegVal, "yes") != 0))
needAutoReg = PR_FALSE;
if (autoRegVal)
nsMemory::Free(autoRegVal);
}
}
}
return needAutoReg;
}
/**
* Notify XPI that autoreg was performed successfully.
*/
inline void
NS_SoftwareUpdateDidAutoReg()
{
nsresult rv;
nsCOMPtr<nsIRegistry> reg = do_GetService(NS_REGISTRY_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = reg->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_SUCCEEDED(rv)) {
nsRegistryKey idKey = 0;
rv = reg->AddSubtree(nsIRegistry::Common, XPI_ROOT_KEY, &idKey);
if (NS_SUCCEEDED(rv))
reg->SetStringUTF8(idKey, XPI_AUTOREG_VAL, "no");
}
}
}
/**
* Request that an autoreg be performed at next startup. (Used
* internally by XPI.)
* internally by XPI.) This basically drops a files next to the
* application. Next time XPCOM sees this file, it will cause
* an autoreg, then delete this file.
*/
inline void
static void
NS_SoftwareUpdateRequestAutoReg()
{
nsresult rv;
nsCOMPtr<nsIRegistry> reg = do_GetService(NS_REGISTRY_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = reg->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_SUCCEEDED(rv)) {
nsRegistryKey idKey = 0;
rv = reg->AddSubtree(nsIRegistry::Common, XPI_ROOT_KEY, &idKey);
if (NS_SUCCEEDED(rv))
reg->SetStringUTF8(idKey, XPI_AUTOREG_VAL, "yes");
}
nsCOMPtr<nsIFile> file;
NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
getter_AddRefs(file));
if (!file) {
NS_WARNING("Getting NS_XPCOM_CURRENT_PROCESS_DIR failed");
return;
}
file->AppendNative(nsDependentCString(".autoreg"));
rv = file->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
if (NS_FAILED(rv)) {
NS_WARNING("creating file failed");
return;
}
}

View File

@ -55,7 +55,6 @@
#include "nsTopProgressNotifier.h"
#include "nsLoggingProgressNotifier.h"
#include "nsIRegistry.h"
#include "nsBuildID.h"
#include "nsSpecialSystemDirectory.h"
#include "nsProcess.h"
@ -86,8 +85,6 @@ static NS_DEFINE_CID(kInstallTrigger_CID, NS_SoftwareUpdateInstallTrigger_CID);
static NS_DEFINE_CID(kInstallVersion_CID, NS_SoftwareUpdateInstallVersion_CID);
static NS_DEFINE_CID(knsRegistryCID, NS_REGISTRY_CID);
static NS_DEFINE_CID(kIProcessCID, NS_PROCESS_CID);
nsSoftwareUpdate* nsSoftwareUpdate::mInstance = nsnull;
@ -394,92 +391,6 @@ nsSoftwareUpdate::InstallJarCallBack()
}
NS_IMETHODIMP
nsSoftwareUpdate::StartupTasks( PRBool *needAutoreg )
{
PRBool autoReg = PR_FALSE;
RKEY xpiRoot;
REGERR err;
*needAutoreg = PR_TRUE;
// First do any left-over file replacements and deletes
// NOTE: we leave the registry open until later to prevent
// having to load and unload it many times at startup
if ( REGERR_OK == NR_RegOpen("", &mReg) )
{
// XXX get a return val and if not all replaced autoreg again later
PerformScheduledTasks(mReg);
// now look for an autoreg flag left behind by XPInstall
err = NR_RegGetKey( mReg, ROOTKEY_COMMON, XPI_ROOT_KEY, &xpiRoot);
if ( err == REGERR_OK )
{
char buf[8];
err = NR_RegGetEntryString( mReg, xpiRoot, XPI_AUTOREG_VAL,
buf, sizeof(buf) );
if ( err == REGERR_OK && !strcmp( buf, "yes" ) )
autoReg = PR_TRUE;
}
}
// Also check for build number changes
nsresult rv;
PRInt32 buildID = -1;
nsRegistryKey idKey = 0;
nsCOMPtr<nsIRegistry> reg = do_GetService(knsRegistryCID,&rv);
if (NS_SUCCEEDED(rv))
{
rv = reg->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_SUCCEEDED(rv))
{
rv = reg->GetSubtree(nsIRegistry::Common,XPCOM_KEY,&idKey);
if (NS_SUCCEEDED(rv))
{
rv = reg->GetInt( idKey, XPI_AUTOREG_VAL, &buildID );
}
}
}
// Autoregister if we found the XPInstall flag, the stored BuildID
// is not the actual BuildID, or if we couldn't get the BuildID
if ( autoReg || NS_FAILED(rv) || buildID != NS_BUILD_ID )
{
nsCOMPtr<nsIServiceManager> servManager;
NS_GetServiceManager(getter_AddRefs(servManager));
nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servManager);
NS_ASSERTION(registrar, "No nsIComponentRegistrar from get service. see dougt");
rv = registrar->AutoRegister(nsnull);
if (NS_SUCCEEDED(rv))
{
*needAutoreg = PR_FALSE;
// Now store back into the registries so we don't do this again
if ( autoReg )
NR_RegSetEntryString( mReg, xpiRoot, XPI_AUTOREG_VAL, "no" );
if ( buildID != NS_BUILD_ID && idKey != 0 )
reg->SetInt( idKey, XPI_AUTOREG_VAL, NS_BUILD_ID );
}
}
else
{
//We don't need to autoreg, we're up to date
*needAutoreg = PR_FALSE;
#ifdef DEBUG
// debug (developer) builds should always autoreg
*needAutoreg = PR_TRUE;
#endif
}
return rv;
}
nsresult
nsSoftwareUpdate::RunNextInstall()
{