Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
nsNativeComponentLoader Class Reference

#include <nsNativeComponentLoader.h>

Inheritance diagram for nsNativeComponentLoader:
Inheritance graph
[legend]
Collaboration diagram for nsNativeComponentLoader:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSICOMPONENTLOADER 
nsNativeComponentLoader ()
nsIFactory getFactory (in nsIIDRef aCID, in string aLocation, in string aType)
 Get the factory for a given component.
void init (in nsIComponentManager aCompMgr, in nsISupports aRegistry)
 Initialize the loader.
void onRegister (in nsIIDRef aCID, in string aType, in string aClassName, in string aContractID, in string aLocation, in boolean aReplace, in boolean aPersist)
 Called when a component of the appropriate type is registered, to give the component loader an opportunity to do things like annotate the registry and such.
void autoRegisterComponents (in long aWhen, in nsIFile aDirectory)
 AutoRegister components in the given directory.
boolean autoRegisterComponent (in long aWhen, in nsIFile aComponent)
 AutoRegister the given component.
boolean autoUnregisterComponent (in long aWhen, in nsIFile aComponent)
 AutoUnregister the given component.
boolean registerDeferredComponents (in long aWhen)
 Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components.
void unloadAll (in long aWhen)
 Unload all components that are willing.

Public Attributes

nsIComponentManagermCompMgr
const long Startup = 0
 When is AutoRegistration occuring?
const long Component = 1
const long Timer = 2

Private Member Functions

 ~nsNativeComponentLoader ()
NS_IMETHOD RegisterComponentsInDir (PRInt32 when, nsIFile *dir)
nsresult CreateDll (nsIFile *aSpec, const char *aLocation, nsDll **aDll)
nsresult SelfRegisterDll (nsDll *dll, const char *registryLocation, PRBool deferred)
nsresult SelfUnregisterDll (nsDll *dll)
nsresult GetFactoryFromModule (nsDll *aDll, const nsCID &aCID, nsIFactory **aFactory)
nsresult DumpLoadError (nsDll *dll, const char *aCallerName, const char *aNsprErrorMsg)

Private Attributes

nsObjectHashtable mDllStore
nsVoidArray mDeferredComponents

Detailed Description

Definition at line 50 of file nsNativeComponentLoader.h.


Constructor & Destructor Documentation

Definition at line 65 of file nsNativeComponentLoader.h.

{}

Member Function Documentation

boolean nsIComponentLoader::autoRegisterComponent ( in long  aWhen,
in nsIFile  aComponent 
) [inherited]

AutoRegister the given component.

Returns true if the component was registered, false if it couldn't attempt to register the component (wrong type) and ``throws'' an NS_FAILED code if there was an error during registration.

void nsIComponentLoader::autoRegisterComponents ( in long  aWhen,
in nsIFile  aDirectory 
) [inherited]

AutoRegister components in the given directory.

boolean nsIComponentLoader::autoUnregisterComponent ( in long  aWhen,
in nsIFile  aComponent 
) [inherited]

AutoUnregister the given component.

Returns true if the component was unregistered, false if it coudln't attempt to unregister the component (not found, wrong type).

nsresult nsNativeComponentLoader::CreateDll ( nsIFile aSpec,
const char *  aLocation,
nsDll **  aDll 
) [private]

Definition at line 1000 of file nsNativeComponentLoader.cpp.

{
    nsDll *dll;
    nsCOMPtr<nsIFile> dllSpec;
    nsCOMPtr<nsIFile> spec;
    nsresult rv;

    nsCStringKey key(aLocation);
    dll = (nsDll *)mDllStore.Get(&key);
    if (dll)
    {
        *aDll = dll;
        return NS_OK;
    }

    if (!aSpec)
    {
        // what I want to do here is QI for a Component Registration Manager.  Since this 
        // has not been invented yet, QI to the obsolete manager.  Kids, don't do this at home.
        nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(mCompMgr, &rv);
        if (obsoleteManager)
            rv = obsoleteManager->SpecForRegistryLocation(aLocation,
                                                          getter_AddRefs(spec));
        if (NS_FAILED(rv))
            return rv;
    }
    else
    {
        spec = aSpec;
    }

    if (!dll)
    {
        dll = new nsDll(spec, this);
        if (!dll)
            return NS_ERROR_OUT_OF_MEMORY;
    }

    *aDll = dll;
    mDllStore.Put(&key, dll);
    return NS_OK;
}

Here is the call graph for this function:

nsresult nsNativeComponentLoader::DumpLoadError ( nsDll dll,
const char *  aCallerName,
const char *  aNsprErrorMsg 
) [private]

Definition at line 471 of file nsNativeComponentLoader.cpp.

{
    PR_ASSERT(aCallerName != NULL);
    
    if (nsnull == dll || nsnull == aNsprErrorMsg)
        return NS_OK;

    nsCAutoString errorMsg(aNsprErrorMsg);

#if defined(MOZ_DEMANGLE_SYMBOLS)
    // Demangle undefined symbols
    nsCAutoString undefinedMagicString("undefined symbol:");
    
    PRInt32 offset = errorMsg.Find(undefinedMagicString, PR_TRUE);
    
    if (offset != kNotFound)
    {
        nsCAutoString symbol(errorMsg);
        nsCAutoString demangledSymbol;
        
        symbol.Cut(0,offset);
        
        symbol.Cut(0,undefinedMagicString.Length());
        
        symbol.StripWhitespace();
        
        char demangled[4096] = "\0";
        
        nsTraceRefcntImpl::DemangleSymbol(symbol.get(),demangled,sizeof(demangled));
        
        if (demangled && *demangled != '\0')
            demangledSymbol = demangled;
        
        if (!demangledSymbol.IsEmpty())
        {
            nsCAutoString tmp(errorMsg);
            
            
            tmp.Cut(offset + undefinedMagicString.Length(),
                    tmp.Length() - offset - undefinedMagicString.Length());
            
            tmp += " \n";
            
            tmp += demangledSymbol;
            
            errorMsg = tmp;
        }    
    }
#endif // MOZ_DEMANGLE_SYMBOLS
    nsXPIDLCString displayPath;
    dll->GetDisplayPath(displayPath);

#ifdef DEBUG
    fprintf(stderr, 
            "nsNativeComponentLoader: %s(%s) Load FAILED with error: %s\n", 
            aCallerName,
            displayPath.get(), 
            errorMsg.get());
#endif

    // Do NSPR log
#ifdef PR_LOGGING
    PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
           ("nsNativeComponentLoader: %s(%s) Load FAILED with error: %s", 
            aCallerName,
            displayPath.get(), 
            errorMsg.get()));
#endif
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIFactory nsIComponentLoader::getFactory ( in nsIIDRef  aCID,
in string  aLocation,
in string  aType 
) [inherited]

Get the factory for a given component.

nsresult nsNativeComponentLoader::GetFactoryFromModule ( nsDll aDll,
const nsCID aCID,
nsIFactory **  aFactory 
) [private]

Definition at line 1046 of file nsNativeComponentLoader.cpp.

{
    nsresult rv;

    nsCOMPtr<nsIModule> module;
    rv = aDll->GetModule(mCompMgr, getter_AddRefs(module));

    if (NS_FAILED(rv))
        return rv;

    return module->GetClassObject(mCompMgr, aCID, NS_GET_IID(nsIFactory),
                                  (void **)aFactory);
}

Here is the call graph for this function:

void nsIComponentLoader::init ( in nsIComponentManager  aCompMgr,
in nsISupports  aRegistry 
) [inherited]

Initialize the loader.

We use nsISupports here because nsIRegistry isn't IDLized yet.

void nsIComponentLoader::onRegister ( in nsIIDRef  aCID,
in string  aType,
in string  aClassName,
in string  aContractID,
in string  aLocation,
in boolean  aReplace,
in boolean  aPersist 
) [inherited]

Called when a component of the appropriate type is registered, to give the component loader an opportunity to do things like annotate the registry and such.

Definition at line 193 of file nsNativeComponentLoader.cpp.

{
    nsresult rv = NS_ERROR_FAILURE;
    PRBool isDir = PR_FALSE;

#if 0
    // Going to many of these checks is a performance hit on the mac.
    // Since these routines are called relatively infrequently and
    // we will fail anyway down the line if a directory aint there,
    // we are commenting this check out.

    // Make sure we are dealing with a directory
    rv = dir->IsDirectory(&isDir);
    if (NS_FAILED(rv)) return rv;

    if (!isDir)
        return NS_ERROR_INVALID_ARG;
#endif /* 0 */

    // Create a directory iterator
    nsCOMPtr<nsISimpleEnumerator> dirIterator;
    rv = dir->GetDirectoryEntries(getter_AddRefs(dirIterator));
    
    if (NS_FAILED(rv)) return rv;
    
    // whip through the directory to register every file
    nsCOMPtr<nsIFile> dirEntry;
    PRBool more = PR_FALSE;

    rv = dirIterator->HasMoreElements(&more);
    if (NS_FAILED(rv)) return rv;
    while (more == PR_TRUE)
    {
        rv = dirIterator->GetNext((nsISupports**)getter_AddRefs(dirEntry));
        if (NS_SUCCEEDED(rv))
        {
            rv = dirEntry->IsDirectory(&isDir);
            if (NS_SUCCEEDED(rv))
            {
                if (isDir == PR_TRUE)
                {
                    // This is a directory. Grovel for components into the directory.
                    rv = RegisterComponentsInDir(when, dirEntry);
                }
                else
                {
                    PRBool registered;
                    // This is a file. Try to register it.
                    rv = AutoRegisterComponent(when, dirEntry, &registered);
                }
            }
        }
        rv = dirIterator->HasMoreElements(&more);
        if (NS_FAILED(rv)) return rv;
    }
    
    return rv;
}

Here is the call graph for this function:

Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components.

Return registered-any-components?

nsresult nsNativeComponentLoader::SelfRegisterDll ( nsDll dll,
const char *  registryLocation,
PRBool  deferred 
) [private]

Definition at line 372 of file nsNativeComponentLoader.cpp.

{
    // Precondition: dll is not loaded already, unless we're deferred
    PR_ASSERT(deferred || dll->IsLoaded() == PR_FALSE);

    nsresult res;
    nsCOMPtr<nsIServiceManager> serviceMgr;
    res = NS_GetServiceManager(getter_AddRefs(serviceMgr));
    if (NS_FAILED(res)) return res;

    if (dll->Load() == PR_FALSE)
    {
        // Cannot load. Probably not a dll.
        char errorMsg[1024] = "Cannot get error from nspr. Not enough memory.";
        if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
            PR_GetErrorText(errorMsg);

        DumpLoadError(dll, "SelfRegisterDll", errorMsg);

        return NS_ERROR_FAILURE;
    }

#ifdef PR_LOGGING
    nsXPIDLCString displayPath;
    dll->GetDisplayPath(displayPath);
    
    PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
           ("nsNativeComponentLoader: Loaded \"%s\".", displayPath.get()));
#endif

    // Tell the module to self register
    nsCOMPtr<nsIFile> fs;
    nsCOMPtr<nsIModule> mobj;
    res = dll->GetModule(mCompMgr, getter_AddRefs(mobj));
    if (NS_SUCCEEDED(res))
    {
        /*************************************************************
         * WARNING: Why are use introducing 'res2' here and then     *
         * later assigning it to 'res' rather than just using 'res'? *
         * This is because this code turns up a code-generation bug  *
         * in VC6 on NT. Assigning to 'res' on the next line causes  *
         * the value of 'dll' to get nulled out! The two seem to be  *
         * getting aliased together during compilation.              *
         *************************************************************/
        nsresult res2 = dll->GetDllSpec(getter_AddRefs(fs));    // don't change 'res2' -- see warning, above
        if (NS_SUCCEEDED(res2)) {
            res = mobj->RegisterSelf(mCompMgr, fs, registryLocation,
                                     nativeComponentType);
        }
        else
        {
            res = res2;         // don't take this out -- see warning, above

#ifdef PR_LOGGING
            nsXPIDLCString displayPath;
            dll->GetDisplayPath(displayPath);
            PR_LOG(nsComponentManagerLog, PR_LOG_ERROR, 
                   ("nsNativeComponentLoader: dll->GetDllSpec() on %s FAILED.",
                    displayPath.get()));
#endif
        }
        mobj = NULL;    // Force a release of the Module object before unload()
    }

    // Update the timestamp and size of the dll in registry
    // Don't enter deferred modules in the registry, because it might only be
    // able to register on some later autoreg, after another component has been
    // installed.
    if (res != NS_ERROR_FACTORY_REGISTER_AGAIN) {
        PRInt64 modTime;
        if (!fs)
            return res;
        
        fs->GetLastModifiedTime(&modTime);
        nsCOMPtr<nsIComponentLoaderManager> manager = do_QueryInterface(mCompMgr);
        if (!manager)
            return NS_ERROR_FAILURE;
        
        nsCOMPtr<nsIFile> fs;
        res = dll->GetDllSpec(getter_AddRefs(fs));
        if (NS_FAILED(res)) return res;
        
        manager->SaveFileInfo(fs, registryLocation, modTime);
    }

    return res;
}

Here is the call graph for this function:

Definition at line 545 of file nsNativeComponentLoader.cpp.

{
    nsresult res;
    nsCOMPtr<nsIServiceManager> serviceMgr;
    res = NS_GetServiceManager(getter_AddRefs(serviceMgr));
    if (NS_FAILED(res)) return res;

    if (dll->Load() == PR_FALSE)
    {
        // Cannot load. Probably not a dll.
        return(NS_ERROR_FAILURE);
    }
        
    // Tell the module to self register
    nsCOMPtr<nsIModule> mobj;
    res = dll->GetModule(mCompMgr, getter_AddRefs(mobj));
    if (NS_SUCCEEDED(res))
    {
#ifdef PR_LOGGING
        nsXPIDLCString displayPath;
        dll->GetDisplayPath(displayPath);

        PR_LOG(nsComponentManagerLog, PR_LOG_ERROR, 
               ("nsNativeComponentLoader: %s using nsIModule to unregister self.", displayPath.get()));
#endif
        nsCOMPtr<nsIFile> fs;
        res = dll->GetDllSpec(getter_AddRefs(fs));
        if (NS_FAILED(res)) return res;
        // Get registry location for spec
        nsXPIDLCString registryName;
                
        // what I want to do here is QI for a Component Registration Manager.  Since this 
        // has not been invented yet, QI to the obsolete manager.  Kids, don't do this at home.
        nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(mCompMgr, &res);
        if (obsoleteManager)
            res = obsoleteManager->RegistryLocationForSpec(fs, getter_Copies(registryName));

        if (NS_FAILED(res)) return res;
        mobj->UnregisterSelf(mCompMgr, fs, registryName);
    }
    return res;
}

Here is the call graph for this function:

void nsIComponentLoader::unloadAll ( in long  aWhen) [inherited]

Unload all components that are willing.


Member Data Documentation

Definition at line 74 of file nsIComponentLoader.idl.

Definition at line 59 of file nsNativeComponentLoader.h.

Definition at line 63 of file nsNativeComponentLoader.h.

nsObjectHashtable nsNativeComponentLoader::mDllStore [private]

Definition at line 62 of file nsNativeComponentLoader.h.

When is AutoRegistration occuring?

Definition at line 73 of file nsIComponentLoader.idl.

Definition at line 75 of file nsIComponentLoader.idl.


The documentation for this class was generated from the following files: