diff --git a/mozilla/xpcom/components/nsComponentManager.cpp b/mozilla/xpcom/components/nsComponentManager.cpp index 03168445f53..36259afdf32 100644 --- a/mozilla/xpcom/components/nsComponentManager.cpp +++ b/mozilla/xpcom/components/nsComponentManager.cpp @@ -60,6 +60,7 @@ const char mozillaKeyName[]="Software/Mozilla"; const char classesKeyName[]="Classes"; const char classIDKeyName[]="CLSID"; const char classesClassIDKeyName[]="Classes/CLSID"; +const char componentLoadersKeyName[]="ComponentLoaders"; // Common Value Names const char classIDValueName[]="CLSID"; @@ -71,9 +72,7 @@ const char progIDValueName[]="ProgID"; const char classNameValueName[]="ClassName"; const char inprocServerValueName[]="InprocServer"; const char componentTypeValueName[]="ComponentType"; -const char nativeComponentType[]="application/x-moz-native"; -const char componentLoaderProgIDPrefix[]= - "component://mozilla/xpcom/component-loader?type="; +const char nativeComponentType[]="application/x-mozilla-native"; // We define a CID that is used to indicate the non-existence of a // progid in the hash table. @@ -279,7 +278,7 @@ nsComponentManagerImpl::~nsComponentManagerImpl() } -NS_IMPL_ISUPPORTS(nsComponentManagerImpl, nsIComponentManager::GetIID()); +NS_IMPL_ISUPPORTS(nsComponentManagerImpl, NS_GET_IID(nsIComponentManager)); //////////////////////////////////////////////////////////////////////////////// // nsComponentManagerImpl: Platform methods @@ -485,6 +484,11 @@ nsComponentManagerImpl::PlatformVersionCheck() ("nsComponentManager: platformVersionCheck() passed.")); } + rv = mRegistry->AddSubtree(xpcomKey, componentLoadersKeyName, + &mLoadersKey); + if (NS_FAILED(rv)) + return rv; + return NS_OK; } @@ -656,7 +660,9 @@ nsComponentManagerImpl::PlatformFind(const nsCID &aCID, nsFactoryEntry* *result) nsCOMPtr loader; - GetLoaderForType(componentType, getter_AddRefs(loader)); + rv = GetLoaderForType(componentType, getter_AddRefs(loader)); + if (NS_FAILED(rv)) + return rv; nsFactoryEntry *res = new nsFactoryEntry(aCID, library, componentType, loader); @@ -1116,7 +1122,7 @@ nsComponentManagerImpl::ProgIDToCLSID(const char *aProgID, nsCID *aClass) #endif /* USE_REGISTRY */ if (PR_LOG_TEST(nsComponentManagerLog, PR_LOG_ALWAYS)) { - char *buf; + char *buf = 0; if (NS_SUCCEEDED(res)) buf = aClass->ToString(); PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, @@ -1304,17 +1310,6 @@ nsComponentManagerImpl::RegisterComponent(const nsCID &aClass, PRBool aReplace, PRBool aPersist) { -#if 0 - nsresult rv; - nsCOMPtr iSpec; - - nsFileSpec spec(aPersistentDescriptor); - NS_NewFileSpecWithSpec(spec, getter_AddRefs(iSpec)); - - rv = RegisterComponentSpec(aClass, aClassName, aProgID, iSpec, - aReplace, aPersist); - return rv; -#endif char *registryName = nsCRT::strdup(aPersistentDescriptor); if (!registryName) return NS_ERROR_OUT_OF_MEMORY; @@ -1509,16 +1504,23 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType, return NS_OK; } + nsIRegistry::Key loaderKey; + rv = mRegistry->GetSubtreeRaw(mLoadersKey, aType, &loaderKey); + if (NS_FAILED(rv)) + return rv; + + char *progID; + rv = mRegistry->GetString(loaderKey, progIDValueName, &progID); + if (NS_FAILED(rv)) + return rv; + #ifdef DEBUG_shaver - fprintf(stderr, "nCMI: constructing loader for type %s\n", aType); + fprintf(stderr, "nCMI: constructing loader for type %s = %s\n", aType, progID); #endif - /* how many copies am I doing here? I don't really know. */ - nsString progID(componentLoaderProgIDPrefix, eOneByte); - progID += aType; + rv = CreateInstance(progID, nsnull, NS_GET_IID(nsIComponentLoader), (void **)&loader); + PR_FREEIF(progID); - rv = CreateInstance(progID.mStr, nsnull, NS_GET_IID(nsIComponentLoader), - (void **)&loader); if (NS_SUCCEEDED(rv)) { mLoaders->Put(&typeKey, loader); *aLoader = loader; @@ -1526,6 +1528,26 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType, return rv; } +nsresult +nsComponentManagerImpl::RegisterComponentLoader(const char *aType, const char *aProgID, + PRBool aReplace) +{ + nsIRegistry::Key loaderKey; + nsresult rv = mRegistry->AddSubtreeRaw(mLoadersKey, aType, &loaderKey); + if (NS_FAILED(rv)) + return rv; + + /* XXX honour aReplace */ + + rv = mRegistry->SetString(loaderKey, progIDValueName, aProgID); + +#ifdef DEBUG_shaver + fprintf(stderr, "nNCI: registered %s as component loader for %s\n", + aProgID, aType); +#endif + return rv; +} + nsresult nsComponentManagerImpl::AddComponentToRegistry(const nsCID &aClass, const char *aClassName, @@ -1796,6 +1818,50 @@ nsComponentManagerImpl::AutoRegister(RegistrationTime when, nsIFileSpec *inDirSp if (NS_FAILED(rv)) return rv; + /* XXX eagerly instantiate all known loaders */ + nsCOMPtr loaderEnum; + rv = mRegistry->EnumerateSubtrees(mLoadersKey, getter_AddRefs(loaderEnum)); + if (NS_FAILED(rv)) + return rv; + + rv = loaderEnum->First(); + if (NS_FAILED(rv)) + return rv; + + for (; NS_SUCCEEDED(rv) && !loaderEnum->IsDone(); + (rv = loaderEnum->Next())) { + nsCOMPtr base; + rv = loaderEnum->CurrentItem(getter_AddRefs(base)); + if (NS_FAILED(rv)) + return rv; + + // Narrow + nsCOMPtr node; + node = do_QueryInterface(base, &rv); + if (NS_FAILED(rv)) + continue; + + char *type; + rv = node->GetName(&type); + if (NS_FAILED(rv)) + continue; + autoStringFree del_type(type, autoStringFree::nsCRT_String_Delete); + + nsStringKey typeKey(type); + nsCOMPtr loader = + (nsIComponentLoader *)mLoaders->Get(&typeKey); + if (loader.get()) + continue; + +#ifdef DEBUG_shaver + fprintf(stderr, "nCMI: creating %s loader for enumeration\n", + type); +#endif + /* this will get it added to the hashtable and stuff */ + GetLoaderForType(type, getter_AddRefs(loader)); + continue; + } + /* iterate over all known loaders and ask them to autoregister. */ struct AutoReg_closure closure; /* XXX convert when to nsIComponentLoader::(when) properly */ diff --git a/mozilla/xpcom/components/nsComponentManager.h b/mozilla/xpcom/components/nsComponentManager.h index d2840ce0a06..c395bef41af 100644 --- a/mozilla/xpcom/components/nsComponentManager.h +++ b/mozilla/xpcom/components/nsComponentManager.h @@ -88,6 +88,11 @@ public: nsIFactory *aFactory, PRBool aReplace); + // Register the component loader for a given type. + NS_IMETHOD RegisterComponentLoader(const char *aType, + const char *aProgID, + PRBool aReplace); + // Manually register a dynamically loaded component. // The libraryPersistentDescriptor is what gets passed to the library // self register function from ComponentManager. The format of this string @@ -211,6 +216,7 @@ protected: nsIRegistry::Key mClassesKey; nsIRegistry::Key mCLSIDKey; PRBool mPrePopulationDone; + nsIRegistry::Key mLoadersKey; nsNativeComponentLoader *mNativeComponentLoader; }; @@ -290,7 +296,7 @@ public: } nsresult rv = loader->GetFactory(cid, location, type, aFactory); if (NS_SUCCEEDED(rv)) - factory = *aFactory; + factory = do_QueryInterface(*aFactory); return rv; } diff --git a/mozilla/xpcom/components/nsIComponentManager.h b/mozilla/xpcom/components/nsIComponentManager.h index 23a696c1cf7..c0c2b47cf97 100644 --- a/mozilla/xpcom/components/nsIComponentManager.h +++ b/mozilla/xpcom/components/nsIComponentManager.h @@ -120,6 +120,11 @@ public: nsIFactory *aFactory, PRBool aReplace) = 0; + // Register the component loader for a given type. + NS_IMETHOD RegisterComponentLoader(const char *aType, + const char *aProgID, + PRBool aReplace) = 0; + // Manually register a dynamically loaded component. // The libraryPersistentDescriptor is what gets passed to the library // self register function from ComponentManager. The format of this string diff --git a/mozilla/xpcom/components/nsNativeComponentLoader.cpp b/mozilla/xpcom/components/nsNativeComponentLoader.cpp index b9568ad2656..1e4a1396526 100644 --- a/mozilla/xpcom/components/nsNativeComponentLoader.cpp +++ b/mozilla/xpcom/components/nsNativeComponentLoader.cpp @@ -70,9 +70,6 @@ nsNativeComponentLoader::nsNativeComponentLoader() : mRegistry(nsnull), mCompMgr(nsnull), mDllStore(nsnull) { NS_INIT_REFCNT(); -#ifdef DEBUG_shaver - fprintf(stderr, "nsNCL: creating\n"); -#endif } static PRBool @@ -87,13 +84,9 @@ nsNativeComponentLoader::~nsNativeComponentLoader() { mRegistry = nsnull; mCompMgr = nsnull; - delete mComponentsDir; - /* XXX correct way to destroy mDllStore */ + delete mComponentsDir; delete mDllStore; -#ifdef DEBUG_shaver - fprintf(stderr, "nsNCL: destroying\n"); -#endif } NS_IMPL_ISUPPORTS(nsNativeComponentLoader, NS_GET_IID(nsIComponentLoader)); @@ -192,6 +185,10 @@ nsNativeComponentLoader::Init(nsISupports *aCompMgr, nsISupports *aReg) { nsresult rv; +#ifdef DEBUG_shaver + fprintf(stderr, "nNCL: Init()\n"); +#endif + mCompMgr = do_QueryInterface(aCompMgr); mRegistry = do_QueryInterface(aReg); if (!mCompMgr || !mRegistry) @@ -303,17 +300,14 @@ nsNativeComponentLoader::RegisterComponentsInDir(PRInt32 when, } if (NS_FAILED(rv)) { -#ifdef DEBUG_shaver - char *specName; - dirEntry->GetNativePath(&specName); - fprintf(stderr, "failure %x returned from autoreg of %s\n", - rv, specName); - nsAllocator::Free(specName); -#endif // This means either of AutoRegisterComponent or // SyncComponentsInDir failed. It could be because // the file isn't a component like initpref.js // So dont break on these errors. + + // Update: actually, we return NS_OK for the wrong file + // types, but we should never fail hard because just one + // component didn't work. } NS_RELEASE(dirEntry); @@ -860,14 +854,6 @@ nsNativeComponentLoader::OnRegister(const nsIID &aCID, const char *aType, const char *aProgID, const char *aLocation, PRBool aReplace, PRBool aPersist) { - /* XXX annotate registry with file time and size */ - -#ifdef DEBUG_shaver - char *cidString = aCID.ToString(); - fprintf(stderr, "nNCL:OnRegister(%s, %s, %s, %s, %d, %d)\n", - cidString, aClassName, aProgID, aLocation, aReplace, aPersist); - delete [] cidString; -#endif return NS_OK; } @@ -1065,11 +1051,6 @@ nsNativeComponentLoader::CreateDll(nsIFileSpec *aSpec, spec = aSpec; } -#ifdef DEBUG_shaver - fprintf(stderr, "nNCL:CreateDll(%s) -> %s\n", aLocation, - dll->GetNativePath()); -#endif - if (!dll) { rv = NS_OK; @@ -1080,6 +1061,7 @@ nsNativeComponentLoader::CreateDll(nsIFileSpec *aSpec, ("nsNativeComponentLoader: no registry, eep!")); dll = new nsDll(spec, aLocation, modificationTime, fileSize); } + if (!dll) return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/xpcom/components/xcDll.cpp b/mozilla/xpcom/components/xcDll.cpp index 9a54224de61..90a48d2a998 100644 --- a/mozilla/xpcom/components/xcDll.cpp +++ b/mozilla/xpcom/components/xcDll.cpp @@ -118,25 +118,6 @@ nsDll::Init(nsIFileSpec *dllSpec) m_status = DLL_INVALID_PARAM; return; } -#ifdef XP_UNIX - /* on Unix, symlinks are fair game too; XXX move to nsFileSpec? */ - if (!isFile) { -#ifdef DEBUG_shaver - char *pathName; - m_dllSpec->GetNativePath(&pathName); - fprintf(stderr, "%s is not a file ", pathName); - nsAllocator::Free(pathName); -#endif - if (NS_FAILED(m_dllSpec->IsSymlink(&isFile))) { - m_status = DLL_INVALID_PARAM; - return; - } -#ifdef DEBUG_shaver - fputs(isFile ? "but it's a symlink\n" : "and it's not a symlink\n", - stderr); -#endif - } -#endif /* XP_UNIX */ if (isFile == PR_FALSE) { @@ -251,10 +232,6 @@ nsDll::HasChanged() if (NS_FAILED(rv) || aSize != m_size) return PR_TRUE; -#ifdef DEBUG_shaver - fprintf(stderr, "%s not changed (%d/%d\n)", - GetNativePath(), m_modDate, m_size); -#endif return PR_FALSE; }