Moved abs:/rel: handling to ComponentManager.

Made nsIModule::GetClassObject and nsIFactory scriptable for JS components.
Added registryLocation param to nsIModule::(Un)RegisterSelf.
This commit is contained in:
shaver%netscape.com 1999-09-07 05:06:37 +00:00
parent f7bda6b5b3
commit c1950cee17
7 changed files with 172 additions and 152 deletions

View File

@ -74,6 +74,10 @@ const char inprocServerValueName[]="InprocServer";
const char componentTypeValueName[]="ComponentType";
const char nativeComponentType[]="application/x-mozilla-native";
const static char XPCOM_ABSCOMPONENT_PREFIX[] = "abs:";
const static char XPCOM_RELCOMPONENT_PREFIX[] = "rel:";
const char XPCOM_LIB_PREFIX[] = "lib:";
// We define a CID that is used to indicate the non-existence of a
// progid in the hash table.
#define NS_NO_CID { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
@ -375,6 +379,12 @@ nsComponentManagerImpl::PlatformInit(void)
rv = mRegistry->AddSubtree(nsIRegistry::Common, classIDKeyName, &mCLSIDKey);
if (NS_FAILED(rv)) return rv;
mComponentsDir =
new nsSpecialSystemDirectory(nsSpecialSystemDirectory::XPCOM_CurrentProcessComponentDirectory);
if (!mComponentsDir)
return NS_ERROR_OUT_OF_MEMORY;
mComponentsDirLen = strlen(mComponentsDir->GetNativePathCString());
if (mNativeComponentLoader) {
/* now that we have the registry, Init the native loader */
rv = mNativeComponentLoader->Init(this, mRegistry);
@ -1204,15 +1214,13 @@ nsComponentManagerImpl::CreateInstance(const nsCID &aClass,
}
/**
* CreateInstance()
* CreateInstanceByProgID()
*
* An overload of CreateInstance() that creates an instance of the object that
* A variant of CreateInstance() that creates an instance of the object that
* implements the interface aIID and whose implementation has a progID aProgID.
*
* This is only a convenience routine that turns around can calls the
* CreateInstance() with classid and iid.
*
* XXX This is a function overload. We need to remove it.
*/
nsresult
nsComponentManagerImpl::CreateInstanceByProgID(const char *aProgID,
@ -1226,6 +1234,115 @@ nsComponentManagerImpl::CreateInstanceByProgID(const char *aProgID,
return CreateInstance(clsid, aDelegate, aIID, aResult);
}
/*
* I want an efficient way to allocate a buffer to the right size
* and stick the prefix and dllName in, then be able to hand that buffer
* off to the FactoryEntry. Is that so wrong?
*
* *regName is allocated on success.
*
* This should live in nsNativeComponentLoader.cpp, I think.
*/
static nsresult
MakeRegistryName(const char *aDllName, const char *prefix, char **regName)
{
char *registryName;
PRUint32 len = nsCRT::strlen(prefix);
PRUint32 registryNameLen = nsCRT::strlen(aDllName) + len;
registryName = (char *)nsAllocator::Alloc(registryNameLen + 1);
// from here on it, we want len sans terminating NUL
if (!registryName)
return NS_ERROR_OUT_OF_MEMORY;
nsCRT::memcpy(registryName, prefix, len);
strcpy(registryName + len, aDllName); // no nsCRT::strcpy? for shame!
registryName[registryNameLen] = '\0';
*regName = registryName;
#ifdef DEBUG_shaver_off
fprintf(stderr, "MakeRegistryName(%s, %s, &[%s])\n",
aDllName, prefix, *regName);
#endif
return NS_OK;
}
nsresult
nsComponentManagerImpl::RegistryNameForLib(const char *aLibName,
char **aRegistryName)
{
return MakeRegistryName(aLibName, XPCOM_LIB_PREFIX, aRegistryName);
}
nsresult
nsComponentManagerImpl::RegistryLocationForSpec(nsIFileSpec *aSpec,
char **aRegistryName)
{
nsresult rv;
nsFileSpec spec;
if (NS_FAILED(rv = aSpec->GetFileSpec(&spec)))
return rv;
if (spec.IsChildOf(*mComponentsDir)){
/*
* According to sfraser, this sort of string magic is ``Mac-safe''.
* Who knew?
*/
const char *nativePath;
nativePath = spec.GetNativePathCString();
nativePath += mComponentsDirLen;
#ifdef XP_MAC // XXX move relativize-fragment logic to nsFileSpec?
if (nativePath[0] != ':')
nativePath--;
#else
char sep = PR_GetDirectorySeparator();
if (nativePath[0] == sep)
nativePath++;
#endif
rv = MakeRegistryName(nativePath, XPCOM_RELCOMPONENT_PREFIX,
aRegistryName);
} else {
/* absolute names include volume info on Mac, so persistent descriptor */
char *persistentDescriptor;
rv = aSpec->GetPersistentDescriptorString(&persistentDescriptor);
if (NS_FAILED(rv))
return rv;
rv = MakeRegistryName(persistentDescriptor, XPCOM_ABSCOMPONENT_PREFIX,
aRegistryName);
nsAllocator::Free(persistentDescriptor);
}
return rv;
}
nsresult
nsComponentManagerImpl::SpecForRegistryLocation(const char *aLocation,
nsIFileSpec **aSpec)
{
nsresult rv;
if (!aLocation || !aSpec)
return NS_ERROR_NULL_POINTER;
/* abs:/full/path/to/libcomponent.so */
if (!nsCRT::strncmp(aLocation, XPCOM_ABSCOMPONENT_PREFIX, 4)) {
if (NS_FAILED(rv = NS_NewFileSpec(aSpec)))
return rv;
return (*aSpec)->SetPersistentDescriptorString((char *)aLocation + 4);
}
if (!nsCRT::strncmp(aLocation, XPCOM_RELCOMPONENT_PREFIX, 4)) {
nsFileSpec compSpec = (*mComponentsDir);
compSpec += (aLocation + 4);
return NS_NewFileSpecWithSpec(compSpec, aSpec);
}
*aSpec = nsnull;
return NS_ERROR_INVALID_ARG;
}
/**
* RegisterFactory()
@ -1314,18 +1431,13 @@ nsComponentManagerImpl::RegisterComponentWithType(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
nsIFileSpec *aSpec,
const char *aLocation,
PRBool aReplace,
PRBool aPersist,
const char *aType)
{
nsresult rv = NS_OK;
char *registryName;
rv = mNativeComponentLoader->RegistryNameForSpec(aSpec, &registryName);
if (NS_FAILED(rv))
return rv;
return RegisterComponentCommon(aClass, aClassName, aProgID, registryName,
return RegisterComponentCommon(aClass, aClassName, aProgID,
nsCRT::strdup(aLocation),
aReplace, aPersist,
aType);
}
@ -1341,9 +1453,17 @@ nsComponentManagerImpl::RegisterComponentSpec(const nsCID &aClass,
PRBool aReplace,
PRBool aPersist)
{
return RegisterComponentWithType(aClass, aClassName, aProgID, aLibrarySpec,
aReplace, aPersist,
nativeComponentType);
char *registryName;
nsresult rv = RegistryLocationForSpec(aLibrarySpec, &registryName);
if (NS_FAILED(rv))
return rv;
rv = RegisterComponentWithType(aClass, aClassName, aProgID, aLibrarySpec,
registryName,
aReplace, aPersist,
nativeComponentType);
nsAllocator::Free(registryName);
return rv;
}
/*
@ -1362,8 +1482,7 @@ nsComponentManagerImpl::RegisterComponentLib(const nsCID &aClass,
PRBool aPersist)
{
char *registryName;
nsresult rv = mNativeComponentLoader->RegistryNameForLib(aDllName,
&registryName);
nsresult rv = RegistryNameForLib(aDllName, &registryName);
if (NS_FAILED(rv))
return rv;
return RegisterComponentCommon(aClass, aClassName, aProgID, registryName,

View File

@ -44,6 +44,7 @@ extern const char xpcomBaseName[];
extern const char xpcomKeyName[];
extern const char lastModValueName[];
extern const char fileSizeValueName[];
extern const char XPCOM_LIB_PREFIX[];
////////////////////////////////////////////////////////////////////////////////
@ -61,6 +62,7 @@ public:
nsresult PlatformPrePopulateRegistry();
protected:
nsresult RegistryNameForLib(const char *aLibName, char **aRegistryName);
nsresult RegisterComponentCommon(const nsCID &aClass,
const char *aClassName,
const char *aProgID, char *aRegistryName,
@ -104,6 +106,8 @@ protected:
PRBool mPrePopulationDone;
nsIRegistry::Key mLoadersKey;
nsNativeComponentLoader *mNativeComponentLoader;
nsSpecialSystemDirectory *mComponentsDir;
PRUint32 mComponentsDirLen;
};
#define NS_MAX_FILENAME_LEN 1024

View File

@ -39,7 +39,16 @@ interface nsIComponentManager : nsISupports
[noscript] voidStar createInstanceByProgID(in string aProgID,
in nsISupports aDelegate,
in nsIIDRef IID);
/**
* Produce a rel: or abs: registry location for a given spec.
*/
string registryLocationForSpec(in nsIFileSpec aSpec);
/**
* Create a full FileSpec for the rel:/abs: location provided.
*/
nsIFileSpec specForRegistryLocation(in string aLocation);
void registerFactory(in nsCIDRef aClass, in string aClassName,
in string aProgID, in nsIFactory aFactory,
in boolean aReplace);
@ -52,6 +61,7 @@ interface nsIComponentManager : nsISupports
in string aClassName,
in string aProgID,
in nsIFileSpec aSpec,
in string aLocation,
in boolean aReplace,
in boolean aPersist,
in string aType);

View File

@ -18,11 +18,11 @@
#include "nsISupports.idl"
[object, uuid(00000001-0000-0000-c000-000000000046)]
[scriptable, object, uuid(00000001-0000-0000-c000-000000000046)]
interface nsIFactory : nsISupports {
voidStar CreateInstance(in nsISupports aOuter,
in nsIIDRef iid);
void CreateInstance(in nsISupports aOuter, in nsIIDRef iid,
[retval, iid_is(iid)] out nsQIResult result);
void LockFactory(in PRBool lock);
};

View File

@ -29,12 +29,15 @@ interface nsIModule : nsISupports
// create new objects.
// SingletonFactory can be queried off the Class Object. Services can be created
// using the singletonfactory.
[noscript] void GetClassObject(in nsIComponentManager aCompMgr, in nsCIDRef aClass,
in nsIIDRef aIID, out voidStar return_ClassObject);
void GetClassObject(in nsIComponentManager aCompMgr, in nsCIDRef aClass,
in nsIIDRef aIID,
[retval, iid_is(aIID)] out nsQIResult result);
// Component registration
void RegisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location);
void UnregisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location);
void RegisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location,
in string registryLocation);
void UnregisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location,
in string registryLocation);
// Module load management
// okToUnload: indicates to the caller if the module can be unloaded.

View File

@ -35,10 +35,6 @@
extern PRLogModuleInfo *nsComponentManagerLog;
const static char XPCOM_ABSCOMPONENT_PREFIX[] = "abs:";
const static char XPCOM_RELCOMPONENT_PREFIX[] = "rel:";
const static char XPCOM_LIB_PREFIX[] = "lib:";
/* XXX consolidate with one in nsComponentManager.cpp */
//
// To prevent leaks, we are using this class. Typical use would be
@ -85,7 +81,6 @@ nsNativeComponentLoader::~nsNativeComponentLoader()
mRegistry = nsnull;
mCompMgr = nsnull;
delete mComponentsDir;
delete mDllStore;
}
@ -203,12 +198,6 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg)
return rv;
}
mComponentsDir =
new nsSpecialSystemDirectory(nsSpecialSystemDirectory::XPCOM_CurrentProcessComponentDirectory);
if (!mComponentsDir)
return NS_ERROR_OUT_OF_MEMORY;
mComponentsDirLen = strlen(mComponentsDir->GetNativePathCString());
if (!mDllStore) {
mDllStore = new nsObjectHashtable(nsnull, nsnull, // never copy
nsDll_Destroy, nsnull,
@ -445,7 +434,7 @@ nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, const char *registryLocatio
nsCOMPtr<nsIFileSpec> fs;
res = dll->GetDllSpec(getter_AddRefs(fs));
if (NS_SUCCEEDED(res))
res = mobj->RegisterSelf(mCompMgr, fs);
res = mobj->RegisterSelf(mCompMgr, fs, registryLocation);
else
{
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
@ -504,7 +493,7 @@ nsNativeComponentLoader::SelfUnregisterDll(nsDll *dll)
nsCOMPtr<nsIFileSpec> fs;
res = dll->GetDllSpec(getter_AddRefs(fs));
if (NS_SUCCEEDED(res))
res = mobj->UnregisterSelf(mCompMgr, fs);
res = mobj->UnregisterSelf(mCompMgr, fs, /* XXX location */ "");
else
{
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
@ -617,7 +606,7 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
* Pink would be so proud.
*/
char *persistentDescriptor;
rv = RegistryNameForSpec(component, &persistentDescriptor);
rv = mCompMgr->RegistryLocationForSpec(component, &persistentDescriptor);
if (NS_FAILED(rv))
return rv;
@ -805,92 +794,6 @@ nsNativeComponentLoader::UnloadAll(PRInt32 aWhen)
return NS_OK;
}
/*
* I want an efficient way to allocate a buffer to the right size
* and stick the prefix and dllName in, then be able to hand that buffer
* off to the FactoryEntry. Is that so wrong?
*
* *regName is allocated on success.
*
* This should live in nsNativeComponentLoader.cpp, I think.
*/
static nsresult
MakeRegistryName(const char *aDllName, const char *prefix, char **regName)
{
char *registryName;
PRUint32 len = nsCRT::strlen(prefix);
PRUint32 registryNameLen = nsCRT::strlen(aDllName) + len;
registryName = (char *)nsAllocator::Alloc(registryNameLen + 1);
// from here on it, we want len sans terminating NUL
if (!registryName)
return NS_ERROR_OUT_OF_MEMORY;
nsCRT::memcpy(registryName, prefix, len);
strcpy(registryName + len, aDllName); // no nsCRT::strcpy? for shame!
registryName[registryNameLen] = '\0';
*regName = registryName;
#ifdef DEBUG_shaver_off
fprintf(stderr, "MakeRegistryName(%s, %s, &[%s])\n",
aDllName, prefix, *regName);
#endif
return NS_OK;
}
nsresult
nsNativeComponentLoader::RegistryNameForLib(const char *aLibName,
char **aRegistryName)
{
return MakeRegistryName(aLibName, XPCOM_LIB_PREFIX, aRegistryName);
}
nsresult
nsNativeComponentLoader::RegistryNameForSpec(nsIFileSpec *aSpec,
char **aRegistryName)
{
nsresult rv;
nsFileSpec spec;
if (NS_FAILED(rv = aSpec->GetFileSpec(&spec)))
return rv;
if (spec.IsChildOf(*mComponentsDir)){
/*
* According to sfraser, this sort of string magic is ``Mac-safe''.
* Who knew?
*/
const char *nativePath;
nativePath = spec.GetNativePathCString();
nativePath += mComponentsDirLen;
#ifdef XP_MAC // XXX move relativize-fragment logic to nsFileSpec?
if (nativePath[0] != ':')
nativePath--;
#else
char sep = PR_GetDirectorySeparator();
if (nativePath[0] == sep)
nativePath++;
#endif
rv = MakeRegistryName(nativePath, XPCOM_RELCOMPONENT_PREFIX, aRegistryName);
} else {
/* absolute names include volume info on Mac, so use persistent descriptor */
char *persistentDescriptor;
rv = aSpec->GetPersistentDescriptorString(&persistentDescriptor);
if (NS_FAILED(rv))
return rv;
rv = MakeRegistryName(persistentDescriptor, XPCOM_ABSCOMPONENT_PREFIX,
aRegistryName);
nsAllocator::Free(persistentDescriptor);
}
return rv;
}
/*
* There are no interesting failures here, so we don't propagate errors back.
*/
@ -957,32 +860,15 @@ nsNativeComponentLoader::CreateDll(nsIFileSpec *aSpec,
if (!aSpec)
{
if (!nsCRT::strncmp(aLocation, XPCOM_LIB_PREFIX, 4))
{
dll = new nsDll(aLocation+4, 1 /* dumb magic flag */);
if (!dll) return NS_ERROR_OUT_OF_MEMORY;
}
else if (!nsCRT::strncmp(aLocation, XPCOM_ABSCOMPONENT_PREFIX, 4))
{
rv = NS_NewFileSpec(getter_AddRefs(spec));
if (NS_FAILED(rv)) return rv;
rv = spec->SetPersistentDescriptorString((char *)aLocation+4);
if (NS_FAILED(rv)) return rv;
}
else if (!nsCRT::strncmp(aLocation, XPCOM_RELCOMPONENT_PREFIX, 4))
{
dllSpec = (*mComponentsDir);
dllSpec += (aLocation + 4);
rv = NS_NewFileSpecWithSpec(dllSpec, getter_AddRefs(spec));
if (NS_FAILED(rv)) return rv;
}
else
{
/* no prefix, what's with that? */
fprintf(stderr, "unknown type for component location %s\n",
aLocation);
return NS_ERROR_INVALID_ARG;
}
if (!nsCRT::strncmp(aLocation, XPCOM_LIB_PREFIX, 4)) {
dll = new nsDll(aLocation+4, 1 /* dumb magic flag */);
if (!dll) return NS_ERROR_OUT_OF_MEMORY;
} else {
rv = mCompMgr->SpecForRegistryLocation(aLocation,
getter_AddRefs(spec));
if (NS_FAILED(rv))
return rv;
}
}
else
{

View File

@ -49,8 +49,6 @@ class nsNativeComponentLoader : public nsIComponentLoader {
nsObjectHashtable* mDllStore;
NS_IMETHOD RegisterComponentsInDir(PRInt32 when, nsIFileSpec *dir);
nsIRegistry::Key mXPCOMKey;
nsSpecialSystemDirectory *mComponentsDir;
PRUint32 mComponentsDirLen;
private:
nsresult CreateDll(nsIFileSpec *spec, const char *aLocation, nsDll **aDll);