mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 02:05:42 +00:00
Major repository upgrade to use a presistent regitry. We use libreg/ directly (NR_*() functions) for now.
This commit is contained in:
parent
2a44b3393f
commit
9c7afd4d32
@ -28,6 +28,7 @@
|
||||
#include "plstr.h"
|
||||
#include "prlink.h"
|
||||
#include "prsystem.h"
|
||||
#include "prprf.h"
|
||||
#include "nsRepository.h"
|
||||
|
||||
#ifdef USE_NSREG
|
||||
@ -50,65 +51,131 @@
|
||||
|
||||
nsHashtable *nsRepository::factories = NULL;
|
||||
PRMonitor *nsRepository::monitor = NULL;
|
||||
|
||||
/**
|
||||
* dllStore
|
||||
*
|
||||
* The dllStore maintains a collection of dlls that are hashed by the dll
|
||||
* name. The repository uses the DllStore only to store these dlls:
|
||||
*
|
||||
* 1. dlls that store components in them.
|
||||
* The inmemory nsDll that is stored here always reflects the values of
|
||||
* {lastModTime, fileSize} that are stored in the registry.
|
||||
* It is the job of the autoregistration mechanism to do the right
|
||||
* thing if the dll on disk is newer.
|
||||
* 2. dlls that dont store components in them.
|
||||
* This is for the purpose of the autoregistration mechanism only.
|
||||
* These are marked in the registry too so that unless they change
|
||||
* they wont have to loaded every session.
|
||||
*
|
||||
*/
|
||||
nsDllStore *nsRepository::dllStore = NULL;
|
||||
|
||||
static PRLogModuleInfo *logmodule = NULL;
|
||||
|
||||
static NS_DEFINE_IID(kFactory2IID, NS_IFACTORY2_IID);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/**
|
||||
* Class: FactoryEntry()
|
||||
*
|
||||
* There are two types of FactoryEntries.
|
||||
*
|
||||
* 1. {CID, dll} mapping.
|
||||
* Factory is a consequence of the dll. These can be either session
|
||||
* specific or persistent based on whether we write this
|
||||
* to the registry or not.
|
||||
*
|
||||
* 2. {CID, factory} mapping
|
||||
* These are strictly session specific and in memory only.
|
||||
*/
|
||||
|
||||
class FactoryEntry {
|
||||
public:
|
||||
nsCID cid;
|
||||
nsIFactory *factory;
|
||||
|
||||
|
||||
FactoryEntry(const nsCID &aClass, const char *aLibrary,
|
||||
PRTime lastModTime, PRUint64 fileSize);
|
||||
FactoryEntry(const nsCID &aClass, nsIFactory *aFactory);
|
||||
~FactoryEntry();
|
||||
// DO NOT DELETE THIS. Many FactoryEntry(s) could be sharing the same Dll.
|
||||
// This gets deleted from the dllStore going away.
|
||||
nsDll *dll;
|
||||
|
||||
FactoryEntry(const nsCID &aClass, nsIFactory *aFactory,
|
||||
const char *aLibrary)
|
||||
: cid(aClass), factory(aFactory), dll(NULL)
|
||||
};
|
||||
|
||||
FactoryEntry::FactoryEntry(const nsCID &aClass, const char *aLibrary,
|
||||
PRTime lastModTime, PRUint64 fileSize)
|
||||
: cid(aClass), factory(NULL), dll(NULL)
|
||||
{
|
||||
nsDllStore *dllCollection = nsRepository::dllStore;
|
||||
|
||||
if (aLibrary == NULL)
|
||||
{
|
||||
nsDllStore *dllCollection = nsRepository::dllStore;
|
||||
|
||||
if (aLibrary == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If dll not already in dllCollection, add it.
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dll = dllCollection->Get(aLibrary);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
|
||||
if (dll == NULL)
|
||||
{
|
||||
// Add a new Dll into the nsDllStore
|
||||
dll = new nsDll(aLibrary);
|
||||
if (dll->GetStatus() != DLL_OK)
|
||||
{
|
||||
// Cant create a nsDll. Backoff.
|
||||
delete dll;
|
||||
dll = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dllCollection->Put(aLibrary, dll);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
~FactoryEntry(void)
|
||||
// If dll not already in dllCollection, add it.
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dll = dllCollection->Get(aLibrary);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
|
||||
if (dll == NULL)
|
||||
{
|
||||
if (factory != NULL)
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: New dll \"%s\".", aLibrary));
|
||||
|
||||
// Add a new Dll into the nsDllStore
|
||||
dll = new nsDll(aLibrary, lastModTime, fileSize);
|
||||
if (dll->GetStatus() != DLL_OK)
|
||||
{
|
||||
factory->Release();
|
||||
// Cant create a nsDll. Backoff.
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: New dll status error. \"%s\".", aLibrary));
|
||||
delete dll;
|
||||
dll = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Adding New dll \"%s\" to dllStore.",
|
||||
aLibrary));
|
||||
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dllCollection->Put(aLibrary, dll);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
}
|
||||
// DO NOT DELETE nsDll *dll;
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Found in dllStore \"%s\".", aLibrary));
|
||||
// XXX We found the dll in the dllCollection.
|
||||
// XXX Consistency check: dll needs to have the same
|
||||
// XXX lastModTime and fileSize. If not that would mean
|
||||
// XXX that the dll wasn't registered properly.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FactoryEntry::FactoryEntry(const nsCID &aClass, nsIFactory *aFactory)
|
||||
: cid(aClass), factory(aFactory), dll(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FactoryEntry::~FactoryEntry(void)
|
||||
{
|
||||
if (factory != NULL)
|
||||
{
|
||||
factory->Release();
|
||||
}
|
||||
// DO NOT DELETE nsDll *dll;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class IDKey: public nsHashKey {
|
||||
private:
|
||||
@ -127,75 +194,315 @@ public:
|
||||
nsHashKey *Clone(void) const { return new IDKey(id); }
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef USE_NSREG
|
||||
#define USE_REGISTRY
|
||||
|
||||
static nsresult platformRegister(const nsCID &aCID, const char *aLibrary)
|
||||
static nsDll *platformCreateDll(const char *fullname)
|
||||
{
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
if (err == REGERR_OK)
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
RKEY key;
|
||||
err = NR_RegAddKey(hreg, ROOTKEY_COMMON,
|
||||
"Classes", &key);
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
char *cidString = aCID.ToString();
|
||||
err = NR_RegSetEntryString(hreg, key, cidString, (char *) aLibrary);
|
||||
delete [] cidString;
|
||||
}
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
err = NR_RegGetKey(hreg, xpcomKey, (char *)fullname, &key);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
PRTime lastModTime = LL_ZERO;
|
||||
PRUint64 fileSize = LL_ZERO;
|
||||
uint32 n = sizeof(lastModTime);
|
||||
NR_RegGetEntry(hreg, key, "LastModTimeStamp", &lastModTime, &n);
|
||||
n = sizeof(fileSize);
|
||||
NR_RegGetEntry(hreg, key, "FileSize", &fileSize, &n);
|
||||
|
||||
nsDll *dll = new nsDll(fullname, lastModTime, fileSize);
|
||||
|
||||
return (dll);
|
||||
}
|
||||
|
||||
/**
|
||||
* platformMarkNoComponents(nsDll)
|
||||
*
|
||||
* Stores the dll name, last modified time, size and 0 for number of
|
||||
* components in dll in the registry at location
|
||||
* ROOTKEY_COMMON/Software/Netscape/XPCOM/dllname
|
||||
*/
|
||||
static nsresult platformMarkNoComponents(nsDll *dll)
|
||||
{
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// XXX Gross. LongLongs dont have a serialization format. This makes
|
||||
// XXX the registry non-xp. Someone beat on the nspr people to get
|
||||
// XXX a longlong serialization function please!
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
err = NR_RegAddKey(hreg, xpcomKey, (char *)dll->GetFullPath(), &key);
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
PRTime lastModTime = dll->GetLastModifiedTime();
|
||||
PRUint64 fileSize = dll->GetSize();
|
||||
NR_RegSetEntry(hreg, key, "LastModTimeStamp", REGTYPE_ENTRY_BYTES,
|
||||
&lastModTime, sizeof(lastModTime));
|
||||
NR_RegSetEntry(hreg, key, "FileSize", REGTYPE_ENTRY_BYTES,
|
||||
&fileSize, sizeof(fileSize));
|
||||
|
||||
char *ncomponentsString = "0";
|
||||
|
||||
NR_RegSetEntryString(hreg, key, "ComponentsCount",
|
||||
ncomponentsString);
|
||||
|
||||
NR_RegClose(hreg);
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
static nsresult platformRegister(NSQuickRegisterData regd, nsDll *dll)
|
||||
{
|
||||
HREG hreg;
|
||||
// Preconditions
|
||||
PR_ASSERT(regd != NULL);
|
||||
PR_ASSERT(regd->CIDString != NULL);
|
||||
PR_ASSERT(dll != NULL);
|
||||
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY classesKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &classesKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
NR_RegAddKey(hreg, classesKey, "CLSID", &key);
|
||||
NR_RegAddKey(hreg, key, (char *)regd->CIDString, &key);
|
||||
|
||||
NR_RegSetEntryString(hreg, key, "ClassName", (char *)regd->className);
|
||||
if (regd->progID)
|
||||
NR_RegSetEntryString(hreg, key, "ProgID", (char *)(regd->progID));
|
||||
char *libName = (char *)dll->GetFullPath();
|
||||
NR_RegSetEntry(hreg, key, "InprocServer", REGTYPE_ENTRY_FILE, libName,
|
||||
strlen(libName) + 1);
|
||||
|
||||
if (regd->progID)
|
||||
{
|
||||
NR_RegAddKey(hreg, classesKey, (char *)regd->progID, &key);
|
||||
NR_RegSetEntryString(hreg, key, "CLSID", (char *)regd->CIDString);
|
||||
}
|
||||
|
||||
// XXX Gross. LongLongs dont have a serialization format. This makes
|
||||
// XXX the registry non-xp. Someone beat on the nspr people to get
|
||||
// XXX a longlong serialization function please!
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
// This aint a fatal error. It causes autoregistration to fail
|
||||
// and hence the dll would be registered again the next time
|
||||
// we startup. Let us run with it.
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
NR_RegAddKey(hreg, xpcomKey, (char *)dll->GetFullPath(), &key);
|
||||
|
||||
PRTime lastModTime = dll->GetLastModifiedTime();
|
||||
PRUint64 fileSize = dll->GetSize();
|
||||
|
||||
NR_RegSetEntry(hreg, key, "LastModTimeStamp", REGTYPE_ENTRY_BYTES,
|
||||
&lastModTime, sizeof(lastModTime));
|
||||
NR_RegSetEntry(hreg, key, "FileSize", REGTYPE_ENTRY_BYTES,
|
||||
&fileSize, sizeof(fileSize));
|
||||
|
||||
unsigned int nComponents = 0;
|
||||
char buf[MAXREGNAMELEN];
|
||||
uint32 len = sizeof(buf);
|
||||
|
||||
if (NR_RegGetEntryString(hreg, key, "ComponentsCount", buf, len) == REGERR_OK)
|
||||
{
|
||||
nComponents = atoi(buf);
|
||||
}
|
||||
nComponents++;
|
||||
PR_snprintf(buf, sizeof(buf), "%d", nComponents);
|
||||
NR_RegSetEntryString(hreg, key, "ComponentsCount", buf);
|
||||
|
||||
NR_RegClose(hreg);
|
||||
return err;
|
||||
}
|
||||
|
||||
static nsresult platformUnregister(const nsCID &aCID, const char *aLibrary)
|
||||
static nsresult platformUnregister(NSQuickRegisterData regd, const char *aLibrary)
|
||||
{
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
if (err == REGERR_OK)
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
RKEY key;
|
||||
err = NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &key);
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
char *cidString = aCID.ToString();
|
||||
err = NR_RegDeleteEntry(hreg, key, cidString);
|
||||
delete [] cidString;
|
||||
}
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
return err;
|
||||
|
||||
RKEY classesKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &classesKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
NR_RegAddKey(hreg, classesKey, "CLSID", &key);
|
||||
NR_RegDeleteKey(hreg, key, (char *)regd->CIDString);
|
||||
|
||||
if (regd->progID)
|
||||
NR_RegDeleteKey(hreg, classesKey, (char *)regd->progID);
|
||||
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
// This aint a fatal error. It causes autoregistration to fail
|
||||
// and hence the dll would be registered again the next time
|
||||
// we startup. Let us run with it.
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
NR_RegGetKey(hreg, xpcomKey, (char *)aLibrary, &key);
|
||||
|
||||
// We need to reduce the ComponentCount by 1.
|
||||
// If the ComponentCount hits 0, delete the entire key.
|
||||
int nComponents = 0;
|
||||
char buf[MAXREGNAMELEN];
|
||||
uint32 len = sizeof(buf);
|
||||
|
||||
if (NR_RegGetEntryString(hreg, key, "ComponentsCount", buf, len) == REGERR_OK)
|
||||
{
|
||||
nComponents = atoi(buf);
|
||||
nComponents--;
|
||||
}
|
||||
if (nComponents <= 0)
|
||||
{
|
||||
NR_RegDeleteKey(hreg, key, (char *)aLibrary);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_snprintf(buf, sizeof(buf), "%d", nComponents);
|
||||
NR_RegSetEntryString(hreg, key, "ComponentsCount", buf);
|
||||
}
|
||||
|
||||
NR_RegClose(hreg);
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
static FactoryEntry *platformFind(const nsCID &aCID)
|
||||
{
|
||||
FactoryEntry *res = NULL;
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
if (err == REGERR_OK)
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
RKEY key;
|
||||
err = NR_RegGetKey(hreg, ROOTKEY_COMMON, "Classes", &key);
|
||||
if (err == REGERR_OK) {
|
||||
char *cidString = aCID.ToString();
|
||||
char library[256];
|
||||
uint32 len = 256;
|
||||
err = NR_RegGetEntryString(hreg, key, cidString, library, len);
|
||||
|
||||
delete [] cidString;
|
||||
if (err == REGERR_OK) {
|
||||
res = new FactoryEntry(aCID, NULL, library);
|
||||
}
|
||||
}
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
return res;
|
||||
|
||||
RKEY classesKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &classesKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
NR_RegAddKey(hreg, classesKey, "CLSID", &key);
|
||||
|
||||
FactoryEntry *res = NULL;
|
||||
|
||||
RKEY cidKey;
|
||||
char *cidString = aCID.ToString();
|
||||
err = NR_RegGetKey(hreg, key, cidString, &cidKey);
|
||||
delete [] cidString;
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Get the library name, modifiedtime and size
|
||||
PRTime lastModTime = LL_ZERO;
|
||||
PRUint64 fileSize = LL_ZERO;
|
||||
|
||||
char buf[MAXREGNAMELEN];
|
||||
uint32 len = sizeof(buf);
|
||||
err = NR_RegGetEntry(hreg, cidKey, "InprocServer", buf, &len);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
// Registry inconsistent. No File name for CLSID.
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
char *library = buf;
|
||||
|
||||
// XXX Gross. LongLongs dont have a serialization format. This makes
|
||||
// XXX the registry non-xp. Someone beat on the nspr people to get
|
||||
// XXX a longlong serialization function please!
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) == REGERR_OK)
|
||||
{
|
||||
if (NR_RegGetKey(hreg, xpcomKey, library, &key) == REGERR_OK)
|
||||
{
|
||||
uint32 n = sizeof(lastModTime);
|
||||
NR_RegGetEntry(hreg, key, "LastModTimeStamp", &lastModTime, &n);
|
||||
PR_ASSERT(n == sizeof(lastModTime));
|
||||
n = sizeof(fileSize);
|
||||
NR_RegGetEntry(hreg, key, "FileSize", &fileSize, &n);
|
||||
PR_ASSERT(n == sizeof(fileSize));
|
||||
}
|
||||
}
|
||||
|
||||
res = new FactoryEntry(aCID, library, lastModTime, fileSize);
|
||||
|
||||
NR_RegClose(hreg);
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
#endif // USE_NSREG
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
nsresult nsRepository::loadFactory(FactoryEntry *aEntry,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
@ -204,6 +511,10 @@ nsresult nsRepository::loadFactory(FactoryEntry *aEntry,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aFactory = NULL;
|
||||
|
||||
// loadFactory() cannot be called for entries that are CID<->factory
|
||||
// mapping entries for the session.
|
||||
PR_ASSERT(aEntry->dll != NULL);
|
||||
|
||||
if (aEntry->dll->IsLoaded() == PR_FALSE)
|
||||
{
|
||||
@ -246,17 +557,11 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Finding Factory.");
|
||||
PR_LogPrint("nsRepository: + %s",
|
||||
buf);
|
||||
PR_LogPrint("nsRepository: FindFactory(%s)", buf);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
if (aFactory == NULL)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ERROR, ("nsRepository: !! NULL pointer."));
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
PR_ASSERT(aFactory != NULL);
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
@ -268,13 +573,19 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
#ifdef USE_REGISTRY
|
||||
if (entry == NULL)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tnot found in factory cache. Looking in registry"));
|
||||
entry = platformFind(aClass);
|
||||
// If we got one, cache it in our hashtable
|
||||
if (entry != NULL)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tfound in registry."));
|
||||
factories->Put(&key, entry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tfound in factory cache."));
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
@ -284,7 +595,8 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
if ((entry)->factory == NULL)
|
||||
{
|
||||
res = loadFactory(entry, aFactory);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
*aFactory = entry->factory;
|
||||
(*aFactory)->AddRef();
|
||||
@ -292,8 +604,8 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
}
|
||||
}
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("nsRepository: ! Find Factory %s",
|
||||
res == NS_OK ? "succeeded" : "failed"));
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("nsRepository: FindFactory() %s",
|
||||
res == NS_OK ? "succeeded" : "FAILED"));
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -347,8 +659,7 @@ nsresult nsRepository::CreateInstance(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Creating Instance.");
|
||||
PR_LogPrint("nsRepository: + %s", buf);
|
||||
PR_LogPrint("nsRepository: CreateInstance(%s)", buf);
|
||||
delete [] buf;
|
||||
}
|
||||
if (aResult == NULL)
|
||||
@ -363,13 +674,16 @@ nsresult nsRepository::CreateInstance(const nsCID &aClass,
|
||||
{
|
||||
res = factory->CreateInstance(aDelegate, aIID, aResult);
|
||||
factory->Release();
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tCreateInstance() succeeded."));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tCreateInstance() FAILED."));
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
nsresult nsRepository::CreateInstance2(const nsCID &aClass,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
@ -415,6 +729,8 @@ nsresult nsRepository::CreateInstance2(const nsCID &aClass,
|
||||
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
*/
|
||||
#endif /* 0 */
|
||||
|
||||
nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
nsIFactory *aFactory,
|
||||
@ -424,35 +740,37 @@ nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Registering Factory.");
|
||||
PR_LogPrint("nsRepository: + %s", buf);
|
||||
PR_LogPrint("nsRepository: + Replace = %d.", (int) aReplace);
|
||||
PR_LogPrint("nsRepository: RegisterFactory(%s, factory), replace = %d.", buf, (int)aReplace);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
|
||||
nsIFactory *old = NULL;
|
||||
FindFactory(aClass, &old);
|
||||
|
||||
|
||||
if (old != NULL)
|
||||
{
|
||||
old->Release();
|
||||
if (!aReplace)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory already registered."));
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("\t\tFactory already registered."));
|
||||
return NS_ERROR_FACTORY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("\t\tdeleting old Factory Entry."));
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
|
||||
nsIDKey key(aClass);
|
||||
factories->Put(&key, new FactoryEntry(aClass, aFactory, NULL));
|
||||
factories->Put(&key, new FactoryEntry(aClass, aFactory));
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory register succeeded."));
|
||||
("\t\tFactory register succeeded."));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -466,23 +784,26 @@ nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Registering Factory.");
|
||||
PR_LogPrint("nsRepository: + %s in \"%s\".", buf, aLibrary);
|
||||
PR_LogPrint("nsRepository: + Replace = %d, Persist = %d.",
|
||||
(int) aReplace, (int) aPersist);
|
||||
PR_LogPrint("nsRepository: RegisterFactory(%s, %s), replace = %d, persist = %d.", buf, aLibrary, (int)aReplace, (int)aPersist);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
nsIFactory *old = NULL;
|
||||
FindFactory(aClass, &old);
|
||||
|
||||
if (old != NULL)
|
||||
{
|
||||
old->Release();
|
||||
if (!aReplace) {
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory already registered."));
|
||||
if (!aReplace)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,("\t\tFactory already registered."));
|
||||
return NS_ERROR_FACTORY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,("\t\tdeleting registered Factory."));
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
@ -490,19 +811,30 @@ nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
#ifdef USE_REGISTRY
|
||||
if (aPersist == PR_TRUE)
|
||||
{
|
||||
platformRegister(aClass, aLibrary);
|
||||
// Add it to the registry
|
||||
nsDll *dll = new nsDll(aLibrary);
|
||||
// XXX temp hack until we get the dll to give us the entire
|
||||
// XXX NSQuickRegisterClassData
|
||||
NSQuickRegisterClassData cregd = {0};
|
||||
cregd.CIDString = aClass.ToString();
|
||||
platformRegister(&cregd, dll);
|
||||
delete [] (char *)cregd.CIDString;
|
||||
delete dll;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsDll *dll = new nsDll(aLibrary);
|
||||
nsIDKey key(aClass);
|
||||
factories->Put(&key, new FactoryEntry(aClass, NULL, aLibrary));
|
||||
factories->Put(&key, new FactoryEntry(aClass, aLibrary,
|
||||
dll->GetLastModifiedTime(), dll->GetSize()));
|
||||
delete dll;
|
||||
}
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory register succeeded."));
|
||||
("\t\tFactory register succeeded."));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -518,26 +850,22 @@ nsresult nsRepository::UnregisterFactory(const nsCID &aClass,
|
||||
PR_LogPrint("nsRepository: + %s.", buf);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
|
||||
nsIFactory *old = NULL;
|
||||
FindFactory(aClass, &old);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsresult res = NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
FactoryEntry *old = (FactoryEntry *) factories->Get(&key);
|
||||
if (old != NULL)
|
||||
{
|
||||
if (old == aFactory)
|
||||
if (old->factory == aFactory)
|
||||
{
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
FactoryEntry *entry = (FactoryEntry *) factories->Remove(&key);
|
||||
delete entry;
|
||||
|
||||
old = (FactoryEntry *) factories->Remove(&key);
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
delete old;
|
||||
res = NS_OK;
|
||||
}
|
||||
old->Release();
|
||||
|
||||
}
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
@ -566,7 +894,7 @@ nsresult nsRepository::UnregisterFactory(const nsCID &aClass,
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
if (old != NULL)
|
||||
if (old != NULL && old->dll != NULL)
|
||||
{
|
||||
if (old->dll->GetFullPath() != NULL &&
|
||||
#ifdef XP_UNIX
|
||||
@ -580,10 +908,15 @@ nsresult nsRepository::UnregisterFactory(const nsCID &aClass,
|
||||
delete entry;
|
||||
res = NS_OK;
|
||||
}
|
||||
}
|
||||
#ifdef USE_REGISTRY
|
||||
res = platformUnregister(aClass, aLibrary);
|
||||
// XXX temp hack until we get the dll to give us the entire
|
||||
// XXX NSQuickRegisterClassData
|
||||
NSQuickRegisterClassData cregd = {0};
|
||||
cregd.CIDString = aClass.ToString();
|
||||
res = platformUnregister(&cregd, aLibrary);
|
||||
delete [] (char *)cregd.CIDString;
|
||||
#endif
|
||||
}
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
@ -667,7 +1000,6 @@ nsresult nsRepository::AddToDefaultPathList(const char *pathlist)
|
||||
|
||||
nsresult nsRepository::SyncComponentsInPathList(const char *pathlist)
|
||||
{
|
||||
#ifndef XP_UNIX
|
||||
char *paths = PL_strdup(pathlist);
|
||||
|
||||
if (paths == NULL || *paths == '\0')
|
||||
@ -682,7 +1014,6 @@ nsresult nsRepository::SyncComponentsInPathList(const char *pathlist)
|
||||
paths = nextpath;
|
||||
}
|
||||
PL_strfree(pathsMem);
|
||||
#endif
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
@ -779,6 +1110,9 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
{
|
||||
// XXX Create nsDll for this from registry and
|
||||
// XXX add it to our dll cache dllStore.
|
||||
#ifdef USE_REGISTRY
|
||||
dll = platformCreateDll(fullname);
|
||||
#endif /* USE_REGISTRY */
|
||||
}
|
||||
|
||||
if (dll != NULL)
|
||||
@ -798,8 +1132,7 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
{
|
||||
// Dll hasn't changed. Skip.
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: + nsDll not changed and already "
|
||||
"registered \"%s\". Skipping...",
|
||||
("nsRepository: + nsDll not changed \"%s\". Skipping...",
|
||||
dll->GetFullPath()));
|
||||
return (NS_OK);
|
||||
}
|
||||
@ -837,6 +1170,16 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// dll doesn't have a CanUnload proc. Guess it is
|
||||
// ok to unload it.
|
||||
dll->Unload();
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: + Unloading \"%s\". (no CanUnloadProc).",
|
||||
dll->GetFullPath()));
|
||||
|
||||
}
|
||||
|
||||
} // dll isloaded
|
||||
|
||||
@ -873,10 +1216,12 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Autoregistration FAILED for "
|
||||
"\"%s\". Skipping...", dll->GetFullPath()));
|
||||
// XXX Mark dll as not xpcom dll along with modified time
|
||||
// XXX and size in the registry so that in the next
|
||||
// XXX session, we wont do all this again until
|
||||
// XXX the dll changes.
|
||||
// Mark dll as not xpcom dll along with modified time and size in
|
||||
// the registry so that we wont need to load the dll again every
|
||||
// session until the dll changes.
|
||||
#ifdef USE_REGISTRY
|
||||
platformMarkNoComponents(dll);
|
||||
#endif /* USE_REGISTRY */
|
||||
ret = NS_ERROR_FAILURE;
|
||||
}
|
||||
else
|
||||
@ -884,8 +1229,9 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Autoregistration Passed for "
|
||||
"\"%s\". Skipping...", dll->GetFullPath()));
|
||||
// XXX Mark dll along with modified time and size in the
|
||||
// XXX registry.
|
||||
// Marking dll along with modified time and size in the
|
||||
// registry happens at platformregister(). No need to do it
|
||||
// here again.
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -932,8 +1278,8 @@ nsresult nsRepository::SelfRegisterDll(nsDll *dll)
|
||||
{
|
||||
res = regproc(/* serviceMgr, */ dll->GetFullPath());
|
||||
}
|
||||
dll->Unload();
|
||||
}
|
||||
dll->Unload();
|
||||
return (res);
|
||||
}
|
||||
|
||||
@ -973,7 +1319,7 @@ nsresult nsRepository::SelfUnregisterDll(nsDll *dll)
|
||||
{
|
||||
res = unregproc(/* serviceMgr, */dll->GetFullPath());
|
||||
}
|
||||
dll->Unload();
|
||||
}
|
||||
dll->Unload();
|
||||
return (res);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "plstr.h"
|
||||
#include "prlink.h"
|
||||
#include "prsystem.h"
|
||||
#include "prprf.h"
|
||||
#include "nsRepository.h"
|
||||
|
||||
#ifdef USE_NSREG
|
||||
@ -50,65 +51,131 @@
|
||||
|
||||
nsHashtable *nsRepository::factories = NULL;
|
||||
PRMonitor *nsRepository::monitor = NULL;
|
||||
|
||||
/**
|
||||
* dllStore
|
||||
*
|
||||
* The dllStore maintains a collection of dlls that are hashed by the dll
|
||||
* name. The repository uses the DllStore only to store these dlls:
|
||||
*
|
||||
* 1. dlls that store components in them.
|
||||
* The inmemory nsDll that is stored here always reflects the values of
|
||||
* {lastModTime, fileSize} that are stored in the registry.
|
||||
* It is the job of the autoregistration mechanism to do the right
|
||||
* thing if the dll on disk is newer.
|
||||
* 2. dlls that dont store components in them.
|
||||
* This is for the purpose of the autoregistration mechanism only.
|
||||
* These are marked in the registry too so that unless they change
|
||||
* they wont have to loaded every session.
|
||||
*
|
||||
*/
|
||||
nsDllStore *nsRepository::dllStore = NULL;
|
||||
|
||||
static PRLogModuleInfo *logmodule = NULL;
|
||||
|
||||
static NS_DEFINE_IID(kFactory2IID, NS_IFACTORY2_IID);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/**
|
||||
* Class: FactoryEntry()
|
||||
*
|
||||
* There are two types of FactoryEntries.
|
||||
*
|
||||
* 1. {CID, dll} mapping.
|
||||
* Factory is a consequence of the dll. These can be either session
|
||||
* specific or persistent based on whether we write this
|
||||
* to the registry or not.
|
||||
*
|
||||
* 2. {CID, factory} mapping
|
||||
* These are strictly session specific and in memory only.
|
||||
*/
|
||||
|
||||
class FactoryEntry {
|
||||
public:
|
||||
nsCID cid;
|
||||
nsIFactory *factory;
|
||||
|
||||
|
||||
FactoryEntry(const nsCID &aClass, const char *aLibrary,
|
||||
PRTime lastModTime, PRUint64 fileSize);
|
||||
FactoryEntry(const nsCID &aClass, nsIFactory *aFactory);
|
||||
~FactoryEntry();
|
||||
// DO NOT DELETE THIS. Many FactoryEntry(s) could be sharing the same Dll.
|
||||
// This gets deleted from the dllStore going away.
|
||||
nsDll *dll;
|
||||
|
||||
FactoryEntry(const nsCID &aClass, nsIFactory *aFactory,
|
||||
const char *aLibrary)
|
||||
: cid(aClass), factory(aFactory), dll(NULL)
|
||||
};
|
||||
|
||||
FactoryEntry::FactoryEntry(const nsCID &aClass, const char *aLibrary,
|
||||
PRTime lastModTime, PRUint64 fileSize)
|
||||
: cid(aClass), factory(NULL), dll(NULL)
|
||||
{
|
||||
nsDllStore *dllCollection = nsRepository::dllStore;
|
||||
|
||||
if (aLibrary == NULL)
|
||||
{
|
||||
nsDllStore *dllCollection = nsRepository::dllStore;
|
||||
|
||||
if (aLibrary == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If dll not already in dllCollection, add it.
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dll = dllCollection->Get(aLibrary);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
|
||||
if (dll == NULL)
|
||||
{
|
||||
// Add a new Dll into the nsDllStore
|
||||
dll = new nsDll(aLibrary);
|
||||
if (dll->GetStatus() != DLL_OK)
|
||||
{
|
||||
// Cant create a nsDll. Backoff.
|
||||
delete dll;
|
||||
dll = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dllCollection->Put(aLibrary, dll);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
~FactoryEntry(void)
|
||||
// If dll not already in dllCollection, add it.
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dll = dllCollection->Get(aLibrary);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
|
||||
if (dll == NULL)
|
||||
{
|
||||
if (factory != NULL)
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: New dll \"%s\".", aLibrary));
|
||||
|
||||
// Add a new Dll into the nsDllStore
|
||||
dll = new nsDll(aLibrary, lastModTime, fileSize);
|
||||
if (dll->GetStatus() != DLL_OK)
|
||||
{
|
||||
factory->Release();
|
||||
// Cant create a nsDll. Backoff.
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: New dll status error. \"%s\".", aLibrary));
|
||||
delete dll;
|
||||
dll = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Adding New dll \"%s\" to dllStore.",
|
||||
aLibrary));
|
||||
|
||||
// PR_EnterMonitor(nsRepository::monitor);
|
||||
dllCollection->Put(aLibrary, dll);
|
||||
// PR_ExitMonitor(nsRepository::monitor);
|
||||
}
|
||||
// DO NOT DELETE nsDll *dll;
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Found in dllStore \"%s\".", aLibrary));
|
||||
// XXX We found the dll in the dllCollection.
|
||||
// XXX Consistency check: dll needs to have the same
|
||||
// XXX lastModTime and fileSize. If not that would mean
|
||||
// XXX that the dll wasn't registered properly.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FactoryEntry::FactoryEntry(const nsCID &aClass, nsIFactory *aFactory)
|
||||
: cid(aClass), factory(aFactory), dll(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FactoryEntry::~FactoryEntry(void)
|
||||
{
|
||||
if (factory != NULL)
|
||||
{
|
||||
factory->Release();
|
||||
}
|
||||
// DO NOT DELETE nsDll *dll;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
class IDKey: public nsHashKey {
|
||||
private:
|
||||
@ -127,75 +194,315 @@ public:
|
||||
nsHashKey *Clone(void) const { return new IDKey(id); }
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
#ifdef USE_NSREG
|
||||
#define USE_REGISTRY
|
||||
|
||||
static nsresult platformRegister(const nsCID &aCID, const char *aLibrary)
|
||||
static nsDll *platformCreateDll(const char *fullname)
|
||||
{
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
if (err == REGERR_OK)
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
RKEY key;
|
||||
err = NR_RegAddKey(hreg, ROOTKEY_COMMON,
|
||||
"Classes", &key);
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
char *cidString = aCID.ToString();
|
||||
err = NR_RegSetEntryString(hreg, key, cidString, (char *) aLibrary);
|
||||
delete [] cidString;
|
||||
}
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
err = NR_RegGetKey(hreg, xpcomKey, (char *)fullname, &key);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
PRTime lastModTime = LL_ZERO;
|
||||
PRUint64 fileSize = LL_ZERO;
|
||||
uint32 n = sizeof(lastModTime);
|
||||
NR_RegGetEntry(hreg, key, "LastModTimeStamp", &lastModTime, &n);
|
||||
n = sizeof(fileSize);
|
||||
NR_RegGetEntry(hreg, key, "FileSize", &fileSize, &n);
|
||||
|
||||
nsDll *dll = new nsDll(fullname, lastModTime, fileSize);
|
||||
|
||||
return (dll);
|
||||
}
|
||||
|
||||
/**
|
||||
* platformMarkNoComponents(nsDll)
|
||||
*
|
||||
* Stores the dll name, last modified time, size and 0 for number of
|
||||
* components in dll in the registry at location
|
||||
* ROOTKEY_COMMON/Software/Netscape/XPCOM/dllname
|
||||
*/
|
||||
static nsresult platformMarkNoComponents(nsDll *dll)
|
||||
{
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// XXX Gross. LongLongs dont have a serialization format. This makes
|
||||
// XXX the registry non-xp. Someone beat on the nspr people to get
|
||||
// XXX a longlong serialization function please!
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
err = NR_RegAddKey(hreg, xpcomKey, (char *)dll->GetFullPath(), &key);
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
PRTime lastModTime = dll->GetLastModifiedTime();
|
||||
PRUint64 fileSize = dll->GetSize();
|
||||
NR_RegSetEntry(hreg, key, "LastModTimeStamp", REGTYPE_ENTRY_BYTES,
|
||||
&lastModTime, sizeof(lastModTime));
|
||||
NR_RegSetEntry(hreg, key, "FileSize", REGTYPE_ENTRY_BYTES,
|
||||
&fileSize, sizeof(fileSize));
|
||||
|
||||
char *ncomponentsString = "0";
|
||||
|
||||
NR_RegSetEntryString(hreg, key, "ComponentsCount",
|
||||
ncomponentsString);
|
||||
|
||||
NR_RegClose(hreg);
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
static nsresult platformRegister(NSQuickRegisterData regd, nsDll *dll)
|
||||
{
|
||||
HREG hreg;
|
||||
// Preconditions
|
||||
PR_ASSERT(regd != NULL);
|
||||
PR_ASSERT(regd->CIDString != NULL);
|
||||
PR_ASSERT(dll != NULL);
|
||||
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY classesKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &classesKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
NR_RegAddKey(hreg, classesKey, "CLSID", &key);
|
||||
NR_RegAddKey(hreg, key, (char *)regd->CIDString, &key);
|
||||
|
||||
NR_RegSetEntryString(hreg, key, "ClassName", (char *)regd->className);
|
||||
if (regd->progID)
|
||||
NR_RegSetEntryString(hreg, key, "ProgID", (char *)(regd->progID));
|
||||
char *libName = (char *)dll->GetFullPath();
|
||||
NR_RegSetEntry(hreg, key, "InprocServer", REGTYPE_ENTRY_FILE, libName,
|
||||
strlen(libName) + 1);
|
||||
|
||||
if (regd->progID)
|
||||
{
|
||||
NR_RegAddKey(hreg, classesKey, (char *)regd->progID, &key);
|
||||
NR_RegSetEntryString(hreg, key, "CLSID", (char *)regd->CIDString);
|
||||
}
|
||||
|
||||
// XXX Gross. LongLongs dont have a serialization format. This makes
|
||||
// XXX the registry non-xp. Someone beat on the nspr people to get
|
||||
// XXX a longlong serialization function please!
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
// This aint a fatal error. It causes autoregistration to fail
|
||||
// and hence the dll would be registered again the next time
|
||||
// we startup. Let us run with it.
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
NR_RegAddKey(hreg, xpcomKey, (char *)dll->GetFullPath(), &key);
|
||||
|
||||
PRTime lastModTime = dll->GetLastModifiedTime();
|
||||
PRUint64 fileSize = dll->GetSize();
|
||||
|
||||
NR_RegSetEntry(hreg, key, "LastModTimeStamp", REGTYPE_ENTRY_BYTES,
|
||||
&lastModTime, sizeof(lastModTime));
|
||||
NR_RegSetEntry(hreg, key, "FileSize", REGTYPE_ENTRY_BYTES,
|
||||
&fileSize, sizeof(fileSize));
|
||||
|
||||
unsigned int nComponents = 0;
|
||||
char buf[MAXREGNAMELEN];
|
||||
uint32 len = sizeof(buf);
|
||||
|
||||
if (NR_RegGetEntryString(hreg, key, "ComponentsCount", buf, len) == REGERR_OK)
|
||||
{
|
||||
nComponents = atoi(buf);
|
||||
}
|
||||
nComponents++;
|
||||
PR_snprintf(buf, sizeof(buf), "%d", nComponents);
|
||||
NR_RegSetEntryString(hreg, key, "ComponentsCount", buf);
|
||||
|
||||
NR_RegClose(hreg);
|
||||
return err;
|
||||
}
|
||||
|
||||
static nsresult platformUnregister(const nsCID &aCID, const char *aLibrary)
|
||||
static nsresult platformUnregister(NSQuickRegisterData regd, const char *aLibrary)
|
||||
{
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
if (err == REGERR_OK)
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
RKEY key;
|
||||
err = NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &key);
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
char *cidString = aCID.ToString();
|
||||
err = NR_RegDeleteEntry(hreg, key, cidString);
|
||||
delete [] cidString;
|
||||
}
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
return err;
|
||||
|
||||
RKEY classesKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &classesKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
NR_RegAddKey(hreg, classesKey, "CLSID", &key);
|
||||
NR_RegDeleteKey(hreg, key, (char *)regd->CIDString);
|
||||
|
||||
if (regd->progID)
|
||||
NR_RegDeleteKey(hreg, classesKey, (char *)regd->progID);
|
||||
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
// This aint a fatal error. It causes autoregistration to fail
|
||||
// and hence the dll would be registered again the next time
|
||||
// we startup. Let us run with it.
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
NR_RegGetKey(hreg, xpcomKey, (char *)aLibrary, &key);
|
||||
|
||||
// We need to reduce the ComponentCount by 1.
|
||||
// If the ComponentCount hits 0, delete the entire key.
|
||||
int nComponents = 0;
|
||||
char buf[MAXREGNAMELEN];
|
||||
uint32 len = sizeof(buf);
|
||||
|
||||
if (NR_RegGetEntryString(hreg, key, "ComponentsCount", buf, len) == REGERR_OK)
|
||||
{
|
||||
nComponents = atoi(buf);
|
||||
nComponents--;
|
||||
}
|
||||
if (nComponents <= 0)
|
||||
{
|
||||
NR_RegDeleteKey(hreg, key, (char *)aLibrary);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_snprintf(buf, sizeof(buf), "%d", nComponents);
|
||||
NR_RegSetEntryString(hreg, key, "ComponentsCount", buf);
|
||||
}
|
||||
|
||||
NR_RegClose(hreg);
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
static FactoryEntry *platformFind(const nsCID &aCID)
|
||||
{
|
||||
FactoryEntry *res = NULL;
|
||||
HREG hreg;
|
||||
REGERR err = NR_RegOpen(NULL, &hreg);
|
||||
if (err == REGERR_OK)
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
RKEY key;
|
||||
err = NR_RegGetKey(hreg, ROOTKEY_COMMON, "Classes", &key);
|
||||
if (err == REGERR_OK) {
|
||||
char *cidString = aCID.ToString();
|
||||
char library[256];
|
||||
uint32 len = 256;
|
||||
err = NR_RegGetEntryString(hreg, key, cidString, library, len);
|
||||
|
||||
delete [] cidString;
|
||||
if (err == REGERR_OK) {
|
||||
res = new FactoryEntry(aCID, NULL, library);
|
||||
}
|
||||
}
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
return res;
|
||||
|
||||
RKEY classesKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Classes", &classesKey) != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
RKEY key;
|
||||
NR_RegAddKey(hreg, classesKey, "CLSID", &key);
|
||||
|
||||
FactoryEntry *res = NULL;
|
||||
|
||||
RKEY cidKey;
|
||||
char *cidString = aCID.ToString();
|
||||
err = NR_RegGetKey(hreg, key, cidString, &cidKey);
|
||||
delete [] cidString;
|
||||
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Get the library name, modifiedtime and size
|
||||
PRTime lastModTime = LL_ZERO;
|
||||
PRUint64 fileSize = LL_ZERO;
|
||||
|
||||
char buf[MAXREGNAMELEN];
|
||||
uint32 len = sizeof(buf);
|
||||
err = NR_RegGetEntry(hreg, cidKey, "InprocServer", buf, &len);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
// Registry inconsistent. No File name for CLSID.
|
||||
NR_RegClose(hreg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
char *library = buf;
|
||||
|
||||
// XXX Gross. LongLongs dont have a serialization format. This makes
|
||||
// XXX the registry non-xp. Someone beat on the nspr people to get
|
||||
// XXX a longlong serialization function please!
|
||||
RKEY xpcomKey;
|
||||
if (NR_RegAddKey(hreg, ROOTKEY_COMMON, "Software/Netscape/XPCOM", &xpcomKey) == REGERR_OK)
|
||||
{
|
||||
if (NR_RegGetKey(hreg, xpcomKey, library, &key) == REGERR_OK)
|
||||
{
|
||||
uint32 n = sizeof(lastModTime);
|
||||
NR_RegGetEntry(hreg, key, "LastModTimeStamp", &lastModTime, &n);
|
||||
PR_ASSERT(n == sizeof(lastModTime));
|
||||
n = sizeof(fileSize);
|
||||
NR_RegGetEntry(hreg, key, "FileSize", &fileSize, &n);
|
||||
PR_ASSERT(n == sizeof(fileSize));
|
||||
}
|
||||
}
|
||||
|
||||
res = new FactoryEntry(aCID, library, lastModTime, fileSize);
|
||||
|
||||
NR_RegClose(hreg);
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
#endif // USE_NSREG
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
nsresult nsRepository::loadFactory(FactoryEntry *aEntry,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
@ -204,6 +511,10 @@ nsresult nsRepository::loadFactory(FactoryEntry *aEntry,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aFactory = NULL;
|
||||
|
||||
// loadFactory() cannot be called for entries that are CID<->factory
|
||||
// mapping entries for the session.
|
||||
PR_ASSERT(aEntry->dll != NULL);
|
||||
|
||||
if (aEntry->dll->IsLoaded() == PR_FALSE)
|
||||
{
|
||||
@ -246,17 +557,11 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Finding Factory.");
|
||||
PR_LogPrint("nsRepository: + %s",
|
||||
buf);
|
||||
PR_LogPrint("nsRepository: FindFactory(%s)", buf);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
if (aFactory == NULL)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ERROR, ("nsRepository: !! NULL pointer."));
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
PR_ASSERT(aFactory != NULL);
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
@ -268,13 +573,19 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
#ifdef USE_REGISTRY
|
||||
if (entry == NULL)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tnot found in factory cache. Looking in registry"));
|
||||
entry = platformFind(aClass);
|
||||
// If we got one, cache it in our hashtable
|
||||
if (entry != NULL)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tfound in registry."));
|
||||
factories->Put(&key, entry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tfound in factory cache."));
|
||||
}
|
||||
#endif
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
@ -284,7 +595,8 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
if ((entry)->factory == NULL)
|
||||
{
|
||||
res = loadFactory(entry, aFactory);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
*aFactory = entry->factory;
|
||||
(*aFactory)->AddRef();
|
||||
@ -292,8 +604,8 @@ nsresult nsRepository::FindFactory(const nsCID &aClass,
|
||||
}
|
||||
}
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("nsRepository: ! Find Factory %s",
|
||||
res == NS_OK ? "succeeded" : "failed"));
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("nsRepository: FindFactory() %s",
|
||||
res == NS_OK ? "succeeded" : "FAILED"));
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -347,8 +659,7 @@ nsresult nsRepository::CreateInstance(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Creating Instance.");
|
||||
PR_LogPrint("nsRepository: + %s", buf);
|
||||
PR_LogPrint("nsRepository: CreateInstance(%s)", buf);
|
||||
delete [] buf;
|
||||
}
|
||||
if (aResult == NULL)
|
||||
@ -363,13 +674,16 @@ nsresult nsRepository::CreateInstance(const nsCID &aClass,
|
||||
{
|
||||
res = factory->CreateInstance(aDelegate, aIID, aResult);
|
||||
factory->Release();
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tCreateInstance() succeeded."));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS, ("\t\tCreateInstance() FAILED."));
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
nsresult nsRepository::CreateInstance2(const nsCID &aClass,
|
||||
nsISupports *aDelegate,
|
||||
const nsIID &aIID,
|
||||
@ -415,6 +729,8 @@ nsresult nsRepository::CreateInstance2(const nsCID &aClass,
|
||||
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
}
|
||||
*/
|
||||
#endif /* 0 */
|
||||
|
||||
nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
nsIFactory *aFactory,
|
||||
@ -424,35 +740,37 @@ nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Registering Factory.");
|
||||
PR_LogPrint("nsRepository: + %s", buf);
|
||||
PR_LogPrint("nsRepository: + Replace = %d.", (int) aReplace);
|
||||
PR_LogPrint("nsRepository: RegisterFactory(%s, factory), replace = %d.", buf, (int)aReplace);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
|
||||
nsIFactory *old = NULL;
|
||||
FindFactory(aClass, &old);
|
||||
|
||||
|
||||
if (old != NULL)
|
||||
{
|
||||
old->Release();
|
||||
if (!aReplace)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory already registered."));
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("\t\tFactory already registered."));
|
||||
return NS_ERROR_FACTORY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING, ("\t\tdeleting old Factory Entry."));
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
|
||||
nsIDKey key(aClass);
|
||||
factories->Put(&key, new FactoryEntry(aClass, aFactory, NULL));
|
||||
factories->Put(&key, new FactoryEntry(aClass, aFactory));
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory register succeeded."));
|
||||
("\t\tFactory register succeeded."));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -466,23 +784,26 @@ nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
if (PR_LOG_TEST(logmodule, PR_LOG_ALWAYS))
|
||||
{
|
||||
char *buf = aClass.ToString();
|
||||
PR_LogPrint("nsRepository: Registering Factory.");
|
||||
PR_LogPrint("nsRepository: + %s in \"%s\".", buf, aLibrary);
|
||||
PR_LogPrint("nsRepository: + Replace = %d, Persist = %d.",
|
||||
(int) aReplace, (int) aPersist);
|
||||
PR_LogPrint("nsRepository: RegisterFactory(%s, %s), replace = %d, persist = %d.", buf, aLibrary, (int)aReplace, (int)aPersist);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
nsIFactory *old = NULL;
|
||||
FindFactory(aClass, &old);
|
||||
|
||||
if (old != NULL)
|
||||
{
|
||||
old->Release();
|
||||
if (!aReplace) {
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory already registered."));
|
||||
if (!aReplace)
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,("\t\tFactory already registered."));
|
||||
return NS_ERROR_FACTORY_EXISTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,("\t\tdeleting registered Factory."));
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
@ -490,19 +811,30 @@ nsresult nsRepository::RegisterFactory(const nsCID &aClass,
|
||||
#ifdef USE_REGISTRY
|
||||
if (aPersist == PR_TRUE)
|
||||
{
|
||||
platformRegister(aClass, aLibrary);
|
||||
// Add it to the registry
|
||||
nsDll *dll = new nsDll(aLibrary);
|
||||
// XXX temp hack until we get the dll to give us the entire
|
||||
// XXX NSQuickRegisterClassData
|
||||
NSQuickRegisterClassData cregd = {0};
|
||||
cregd.CIDString = aClass.ToString();
|
||||
platformRegister(&cregd, dll);
|
||||
delete [] (char *)cregd.CIDString;
|
||||
delete dll;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsDll *dll = new nsDll(aLibrary);
|
||||
nsIDKey key(aClass);
|
||||
factories->Put(&key, new FactoryEntry(aClass, NULL, aLibrary));
|
||||
factories->Put(&key, new FactoryEntry(aClass, aLibrary,
|
||||
dll->GetLastModifiedTime(), dll->GetSize()));
|
||||
delete dll;
|
||||
}
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
("nsRepository: ! Factory register succeeded."));
|
||||
("\t\tFactory register succeeded."));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -518,26 +850,22 @@ nsresult nsRepository::UnregisterFactory(const nsCID &aClass,
|
||||
PR_LogPrint("nsRepository: + %s.", buf);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
|
||||
nsIFactory *old = NULL;
|
||||
FindFactory(aClass, &old);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsresult res = NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
FactoryEntry *old = (FactoryEntry *) factories->Get(&key);
|
||||
if (old != NULL)
|
||||
{
|
||||
if (old == aFactory)
|
||||
if (old->factory == aFactory)
|
||||
{
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
nsIDKey key(aClass);
|
||||
FactoryEntry *entry = (FactoryEntry *) factories->Remove(&key);
|
||||
delete entry;
|
||||
|
||||
old = (FactoryEntry *) factories->Remove(&key);
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
delete old;
|
||||
res = NS_OK;
|
||||
}
|
||||
old->Release();
|
||||
|
||||
}
|
||||
|
||||
PR_LOG(logmodule, PR_LOG_WARNING,
|
||||
@ -566,7 +894,7 @@ nsresult nsRepository::UnregisterFactory(const nsCID &aClass,
|
||||
|
||||
PR_EnterMonitor(monitor);
|
||||
|
||||
if (old != NULL)
|
||||
if (old != NULL && old->dll != NULL)
|
||||
{
|
||||
if (old->dll->GetFullPath() != NULL &&
|
||||
#ifdef XP_UNIX
|
||||
@ -580,10 +908,15 @@ nsresult nsRepository::UnregisterFactory(const nsCID &aClass,
|
||||
delete entry;
|
||||
res = NS_OK;
|
||||
}
|
||||
}
|
||||
#ifdef USE_REGISTRY
|
||||
res = platformUnregister(aClass, aLibrary);
|
||||
// XXX temp hack until we get the dll to give us the entire
|
||||
// XXX NSQuickRegisterClassData
|
||||
NSQuickRegisterClassData cregd = {0};
|
||||
cregd.CIDString = aClass.ToString();
|
||||
res = platformUnregister(&cregd, aLibrary);
|
||||
delete [] (char *)cregd.CIDString;
|
||||
#endif
|
||||
}
|
||||
|
||||
PR_ExitMonitor(monitor);
|
||||
|
||||
@ -667,7 +1000,6 @@ nsresult nsRepository::AddToDefaultPathList(const char *pathlist)
|
||||
|
||||
nsresult nsRepository::SyncComponentsInPathList(const char *pathlist)
|
||||
{
|
||||
#ifndef XP_UNIX
|
||||
char *paths = PL_strdup(pathlist);
|
||||
|
||||
if (paths == NULL || *paths == '\0')
|
||||
@ -682,7 +1014,6 @@ nsresult nsRepository::SyncComponentsInPathList(const char *pathlist)
|
||||
paths = nextpath;
|
||||
}
|
||||
PL_strfree(pathsMem);
|
||||
#endif
|
||||
return (NS_OK);
|
||||
}
|
||||
|
||||
@ -779,6 +1110,9 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
{
|
||||
// XXX Create nsDll for this from registry and
|
||||
// XXX add it to our dll cache dllStore.
|
||||
#ifdef USE_REGISTRY
|
||||
dll = platformCreateDll(fullname);
|
||||
#endif /* USE_REGISTRY */
|
||||
}
|
||||
|
||||
if (dll != NULL)
|
||||
@ -798,8 +1132,7 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
{
|
||||
// Dll hasn't changed. Skip.
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: + nsDll not changed and already "
|
||||
"registered \"%s\". Skipping...",
|
||||
("nsRepository: + nsDll not changed \"%s\". Skipping...",
|
||||
dll->GetFullPath()));
|
||||
return (NS_OK);
|
||||
}
|
||||
@ -837,6 +1170,16 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
return (NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// dll doesn't have a CanUnload proc. Guess it is
|
||||
// ok to unload it.
|
||||
dll->Unload();
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: + Unloading \"%s\". (no CanUnloadProc).",
|
||||
dll->GetFullPath()));
|
||||
|
||||
}
|
||||
|
||||
} // dll isloaded
|
||||
|
||||
@ -873,10 +1216,12 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Autoregistration FAILED for "
|
||||
"\"%s\". Skipping...", dll->GetFullPath()));
|
||||
// XXX Mark dll as not xpcom dll along with modified time
|
||||
// XXX and size in the registry so that in the next
|
||||
// XXX session, we wont do all this again until
|
||||
// XXX the dll changes.
|
||||
// Mark dll as not xpcom dll along with modified time and size in
|
||||
// the registry so that we wont need to load the dll again every
|
||||
// session until the dll changes.
|
||||
#ifdef USE_REGISTRY
|
||||
platformMarkNoComponents(dll);
|
||||
#endif /* USE_REGISTRY */
|
||||
ret = NS_ERROR_FAILURE;
|
||||
}
|
||||
else
|
||||
@ -884,8 +1229,9 @@ nsresult nsRepository::SyncComponentsInFile(const char *fullname)
|
||||
PR_LOG(logmodule, PR_LOG_ALWAYS,
|
||||
("nsRepository: Autoregistration Passed for "
|
||||
"\"%s\". Skipping...", dll->GetFullPath()));
|
||||
// XXX Mark dll along with modified time and size in the
|
||||
// XXX registry.
|
||||
// Marking dll along with modified time and size in the
|
||||
// registry happens at platformregister(). No need to do it
|
||||
// here again.
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@ -932,8 +1278,8 @@ nsresult nsRepository::SelfRegisterDll(nsDll *dll)
|
||||
{
|
||||
res = regproc(/* serviceMgr, */ dll->GetFullPath());
|
||||
}
|
||||
dll->Unload();
|
||||
}
|
||||
dll->Unload();
|
||||
return (res);
|
||||
}
|
||||
|
||||
@ -973,7 +1319,7 @@ nsresult nsRepository::SelfUnregisterDll(nsDll *dll)
|
||||
{
|
||||
res = unregproc(/* serviceMgr, */dll->GetFullPath());
|
||||
}
|
||||
dll->Unload();
|
||||
}
|
||||
dll->Unload();
|
||||
return (res);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user