nsresult NS_COM NS_InitXPCOM3(nsIServiceManager* *result,
NS_InitXPCOM3(nsIServiceManager* *result,
nsresult NS_COM NS_InitXPCOM3(nsIServiceManager* *result,                              nsIFile* binDirectory,                              nsIDirectoryServiceProvider* appFileLocationProvider,                              nsStaticModuleInfo const *staticComponents,                              PRUint32 componentCount){    nsresult rv = NS_OK;#ifdef MOZ_ENABLE_LIBXUL    if (!staticComponents) {        staticComponents = kPStaticModules;        componentCount = kStaticModuleCount;    }#endif     // We are not shutting down    gXPCOMShuttingDown = PR_FALSE;#ifdef NS_BUILD_REFCNT_LOGGING    nsTraceRefcntImpl::Startup();#endif    // Establish the main thread here.    rv = nsIThread::SetMainThread();    if (NS_FAILED(rv)) return rv;    // Set up the timer globals/timer thread    rv = nsTimerImpl::Startup();    NS_ENSURE_SUCCESS(rv, rv);    // Startup the memory manager    rv = nsMemoryImpl::Startup();    if (NS_FAILED(rv)) return rv;#ifndef WINCE    // If the locale hasn't already been setup by our embedder,    // get us out of the "C" locale and into the system     if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)        setlocale(LC_ALL, "");#endif#if defined(XP_UNIX) || defined(XP_OS2)    NS_StartupNativeCharsetUtils();#endif    NS_StartupLocalFile();    StartupSpecialSystemDirectory();    rv = nsDirectoryService::RealInit();    if (NS_FAILED(rv))        return rv;    // Create the Component/Service Manager    nsComponentManagerImpl *compMgr = NULL;    if (nsComponentManagerImpl::gComponentManager == NULL)    {        compMgr = new nsComponentManagerImpl();        if (compMgr == NULL)            return NS_ERROR_OUT_OF_MEMORY;        NS_ADDREF(compMgr);                nsCOMPtr<nsIFile> xpcomLib;                        PRBool value;        if (binDirectory)        {            rv = binDirectory->IsDirectory(&value);            if (NS_SUCCEEDED(rv) && value) {                nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, binDirectory);                binDirectory->Clone(getter_AddRefs(xpcomLib));            }        }        else {            nsDirectoryService::gService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,                                               NS_GET_IID(nsIFile),                                               getter_AddRefs(xpcomLib));        }        if (xpcomLib) {            xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));            nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);        }                if (appFileLocationProvider) {            rv = nsDirectoryService::gService->RegisterProvider(appFileLocationProvider);            if (NS_FAILED(rv)) return rv;        }        rv = compMgr->Init(staticComponents, componentCount);        if (NS_FAILED(rv))        {            NS_RELEASE(compMgr);            return rv;        }        nsComponentManagerImpl::gComponentManager = compMgr;        if (result) {            nsIServiceManager *serviceManager =                NS_STATIC_CAST(nsIServiceManager*, compMgr);            NS_ADDREF(*result = serviceManager);        }    }    nsCOMPtr<nsIMemory> memory;    NS_GetMemoryManager(getter_AddRefs(memory));    rv = compMgr->RegisterService(kMemoryCID, memory);    if (NS_FAILED(rv)) return rv;    rv = compMgr->RegisterService(kComponentManagerCID, NS_STATIC_CAST(nsIComponentManager*, compMgr));    if (NS_FAILED(rv)) return rv;#ifdef GC_LEAK_DETECTOR  rv = NS_InitLeakDetector();    if (NS_FAILED(rv)) return rv;#endif    // 2. Register the global services with the component manager so that    //    clients can create new objects.    // Category Manager    {      nsCOMPtr<nsIFactory> categoryManagerFactory;      if ( NS_FAILED(rv = NS_CategoryManagerGetFactory(getter_AddRefs(categoryManagerFactory))) )        return rv;      NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);      rv = compMgr->RegisterFactory(kCategoryManagerCID,                                    NS_CATEGORYMANAGER_CLASSNAME,                                    NS_CATEGORYMANAGER_CONTRACTID,                                    categoryManagerFactory,                                    PR_TRUE);      if ( NS_FAILED(rv) ) return rv;    }    nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(        NS_STATIC_CAST(nsIComponentManager*,compMgr), &rv);    if (registrar) {        for (int i = 0; i < components_length; i++)            RegisterGenericFactory(registrar, &components[i]);        nsCOMPtr<nsIFactory> iniParserFactory(new nsINIParserFactory());        if (iniParserFactory)            registrar->RegisterFactory(kINIParserFactoryCID,                                        "nsINIParserFactory",                                       NS_INIPARSERFACTORY_CONTRACTID,                                        iniParserFactory);    }    rv = nsComponentManagerImpl::gComponentManager->ReadPersistentRegistry();#ifdef DEBUG        if (NS_FAILED(rv)) {        printf("No Persistent Registry Found.\n");            }#endif    if ( NS_FAILED(rv) || CheckUpdateFile()) {        // if we find no persistent registry, we will try to autoregister        // the default components directory.        nsComponentManagerImpl::gComponentManager->AutoRegister(nsnull);        // If the application is using a GRE, then,         // auto register components in the GRE directory as well.        //        // The application indicates that it's using an GRE by        // returning a valid nsIFile when queried (via appFileLocProvider)        // for the NS_GRE_DIR atom as shown below        //        if ( appFileLocationProvider ) {            nsCOMPtr<nsIFile> greDir;            PRBool persistent = PR_TRUE;            appFileLocationProvider->GetFile(NS_GRE_DIR, &persistent, getter_AddRefs(greDir));            if (greDir) {#ifdef DEBUG_dougt                printf("start - Registering GRE components\n");#endif                rv = nsDirectoryService::gService->Get(NS_GRE_COMPONENT_DIR,                                                       NS_GET_IID(nsIFile),                                                       getter_AddRefs(greDir));                if (NS_FAILED(rv)) {                    NS_ERROR("Could not get GRE components directory!");                    return rv;                }                // If the GRE contains any loaders, we want to know about it so that we can cause another                // autoregistration of the applications component directory.                int loaderCount = nsComponentManagerImpl::gComponentManager->GetLoaderCount();                rv = nsComponentManagerImpl::gComponentManager->AutoRegister(greDir);                                if (loaderCount != nsComponentManagerImpl::gComponentManager->GetLoaderCount())                     nsComponentManagerImpl::gComponentManager->AutoRegisterNonNativeComponents(nsnull);        #ifdef DEBUG_dougt                printf("end - Registering GRE components\n");#endif                          if (NS_FAILED(rv)) {                    NS_ERROR("Could not AutoRegister GRE components");                    return rv;                }            }        }        //        // If additional component directories have been specified, then        // register them as well.        //        nsCOMPtr<nsISimpleEnumerator> dirList;        nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_DIR_LIST,                                          NS_GET_IID(nsISimpleEnumerator),                                          getter_AddRefs(dirList));        if (dirList) {            PRBool hasMore;            while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {                nsCOMPtr<nsISupports> elem;                dirList->GetNext(getter_AddRefs(elem));                if (elem) {                    nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);                    if (dir)                        nsComponentManagerImpl::gComponentManager->AutoRegister(dir);                    // XXX should we worry about new component loaders being                    // XXX defined by this process?                }            }        }        // Make sure the compreg file's mod time is current.        nsCOMPtr<nsIFile> compregFile;        rv = nsDirectoryService::gService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE,                                               NS_GET_IID(nsIFile),                                               getter_AddRefs(compregFile));        compregFile->SetLastModifiedTime(PR_Now() / 1000);    }        // Pay the cost at startup time of starting this singleton.    nsIInterfaceInfoManager* iim = XPTI_GetInterfaceInfoManager();    NS_IF_RELEASE(iim);    // After autoreg, but before we actually instantiate any components,    // add any services listed in the "xpcom-directory-providers" category    // to the directory service.    nsDirectoryService::gService->RegisterCategoryProviders();    // Notify observers of xpcom autoregistration start    NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_OBSERVER_ID,                                   nsnull,                                  NS_XPCOM_STARTUP_OBSERVER_ID);        return NS_OK;}