예제 #1
0
void
Library::Finalize(JSContext* cx, JSObject* obj)
{
  // unload the library
  PRLibrary* library = GetLibrary(cx, obj);
  if (library)
    PR_UnloadLibrary(library);
}
예제 #2
0
SECStatus
SECMOD_UnloadModule(SECMODModule *mod) {
    PRLibrary *library;
    char *disableUnload = NULL;

    if (!mod->loaded) {
	return SECFailure;
    }
    if (finalizeModules) {
        if (mod->functionList &&!mod->moduleDBOnly) {
	    PK11_GETTAB(mod)->C_Finalize(NULL);
	}
    }
    mod->moduleID = 0;
    mod->loaded = PR_FALSE;
    
    /* do we want the semantics to allow unloading the internal library?
     * if not, we should change this to SECFailure and move it above the
     * mod->loaded = PR_FALSE; */
    if (mod->internal) {
        if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) {
          if (softokenLib) {
              disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
              if (!disableUnload) {
                  PRStatus status = PR_UnloadLibrary(softokenLib);
                  PORT_Assert(PR_SUCCESS == status);
              }
              softokenLib = NULL;
          }
          loadSoftokenOnce = pristineCallOnce;
        }
	return SECSuccess;
    }

    library = (PRLibrary *)mod->library;
    /* paranoia */
    if (library == NULL) {
	return SECFailure;
    }

    disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
    if (!disableUnload) {
        PR_UnloadLibrary(library);
    }
    return SECSuccess;
}
예제 #3
0
// Unloads a plugin DLL.  "pluginType" is a handle to a plugin management data
// structure created during FE_RegisterPlugins().  There is no return val.
void FE_UnloadPlugin(void* pluginType, struct _np_handle* handle)
{
    NPPMgtBlk* pNPMgtBlk = (NPPMgtBlk*)pluginType;
    if (pNPMgtBlk == NULL)
        return;

    // XXX Note that we're double refcounting here. If we were rewriting this 
    // from scratch, we could eliminate this pNPMgtBlk and its refcount and just
    // rely on the one in the userPlugin.

    pNPMgtBlk->uRefCount--;   // another one bites the dust

    // if this DLL is the last one, call its shutdown entry point
    if (pNPMgtBlk->uRefCount == 0) {
        if (handle->userPlugin) {
            handle->userPlugin->Release();
        }
        else {
            // the NP_Shutdown entry point was misnamed as NP_PluginShutdown, early
            // in plugin project development.  Its correct name is documented
            // now, and new developers expect it to work.  However, I don't want
            // to  break the plugins already in the field, so I'll accept either
            // name
            NP_PLUGINSHUTDOWN npshutdown =
#ifndef NSPR20
                (NP_PLUGINSHUTDOWN)PR_FindSymbol("NP_Shutdown", pNPMgtBlk->pLibrary);
#else
                (NP_PLUGINSHUTDOWN)PR_FindSymbol(pNPMgtBlk->pLibrary, "NP_Shutdown");
#endif
            if (!npshutdown) {
                npshutdown =
#ifndef NSPR20
                    (NP_PLUGINSHUTDOWN)PR_FindSymbol("NP_PluginShutdown", pNPMgtBlk->pLibrary);
#else
                    (NP_PLUGINSHUTDOWN)PR_FindSymbol(pNPMgtBlk->pLibrary, "NP_PluginShutdown");
#endif
            }

            if (npshutdown != NULL) {
                NPError result = npshutdown();
            }
        }
    }

    // XXX Shouldn't the rest of this be inside the if statement, above?...

    PR_UnloadLibrary(pNPMgtBlk->pLibrary);
    pNPMgtBlk->pLibrary = NULL;
    
    if (handle->userPlugin) {
        PR_ASSERT(pNPMgtBlk->pPluginFuncs == (NPPluginFuncs*)-1);     // set in FE_LoadPlugin
        handle->userPlugin = NULL;
    }
    else {
        delete pNPMgtBlk->pPluginFuncs;
    }
    pNPMgtBlk->pPluginFuncs = NULL;
}
예제 #4
0
nsBidiKeyboard::~nsBidiKeyboard()
{
    if (gtklib) {
        PR_UnloadLibrary(gtklib);
        gtklib = nsnull;

        GdkKeymapHaveBidiLayouts = nsnull;
    }
}
static nsresult
LoadGtkModule(GnomeAccessibilityModule& aModule)
{
    NS_ENSURE_ARG(aModule.libName);

    if (!(aModule.lib = PR_LoadLibrary(aModule.libName))) {

        MAI_LOG_DEBUG(("Fail to load lib: %s in default path\n", aModule.libName));

        //try to load the module with "gtk-2.0/modules" appended
        char *curLibPath = PR_GetLibraryPath();
        nsCAutoString libPath(curLibPath);
        libPath.Append(":/usr/lib");
        MAI_LOG_DEBUG(("Current Lib path=%s\n", libPath.get()));
        PR_FreeLibraryName(curLibPath);

        PRInt16 loc1 = 0, loc2 = 0;
        PRInt16 subLen = 0;
        while (loc2 >= 0) {
            loc2 = libPath.FindChar(':', loc1);
            if (loc2 < 0)
                subLen = libPath.Length() - loc1;
            else
                subLen = loc2 - loc1;
            nsCAutoString sub(Substring(libPath, loc1, subLen));
            sub.Append("/gtk-2.0/modules/");
            sub.Append(aModule.libName);
            aModule.lib = PR_LoadLibrary(sub.get());
            if (aModule.lib) {
                MAI_LOG_DEBUG(("Ok, load %s from %s\n", aModule.libName, sub.get()));
                break;
            }
            loc1 = loc2+1;
        }
        if (!aModule.lib) {
            MAI_LOG_DEBUG(("Fail to load %s\n", aModule.libName));
            return NS_ERROR_FAILURE;
        }
    }

    //we have loaded the library, try to get the function ptrs
    if (!(aModule.init = PR_FindFunctionSymbol(aModule.lib,
                                               aModule.initName)) ||
        !(aModule.shutdown = PR_FindFunctionSymbol(aModule.lib,
                                                   aModule.shutdownName))) {

        //fail, :(
        MAI_LOG_DEBUG(("Fail to find symbol %s in %s",
                       aModule.init ? aModule.shutdownName : aModule.initName,
                       aModule.libName));
        PR_UnloadLibrary(aModule.lib);
        aModule.lib = NULL;
        return NS_ERROR_FAILURE;
    }
    return NS_OK;
}
예제 #6
0
void
nsFilePicker::Shutdown()
{
  if (mGTK24) {
    PR_UnloadLibrary(mGTK24);
    mGTK24 = nsnull;
  }

  NS_IF_RELEASE(mPrevDisplayDirectory);
}
예제 #7
0
 void GMPShutdown() override
 {
   if (mLib) {
     GMPShutdownFunc shutdownFunc = reinterpret_cast<GMPShutdownFunc>(PR_FindFunctionSymbol(mLib, "GMPShutdown"));
     if (shutdownFunc) {
       shutdownFunc();
     }
     PR_UnloadLibrary(mLib);
     mLib = nullptr;
   }
 }
예제 #8
0
/*
 * clears our global state on shutdown. 
 */
void
pkix_pl_HttpCertStore_Shutdown(void *plContext)
{
    if (pkix_decodeFunc.smimeLib) {
	PR_UnloadLibrary(pkix_decodeFunc.smimeLib);
	pkix_decodeFunc.smimeLib = NULL;
    }
    /* the function pointer just need to be cleared, not freed */
    pkix_decodeFunc.func = NULL;
    pkix_decodeFunc.once = pkix_pristine;
}
static void
InitModuleFromLib(const char *modulesDir, const char *fileName)
{
    LOG(("InitModuleFromLib [%s]\n", fileName));

    static const ipcDaemonMethods gDaemonMethods =
    {
        IPC_DAEMON_METHODS_VERSION,
        IPC_DispatchMsg,
        IPC_SendMsg,
        IPC_GetClientByID,
        IPC_GetClientByName,
        IPC_EnumClients,
        IPC_GetClientID,
        IPC_ClientHasName,
        IPC_ClientHasTarget,
        IPC_EnumClientNames,
        IPC_EnumClientTargets
    };

    int dLen = strlen(modulesDir);
    int fLen = strlen(fileName);

    char *buf = (char *) malloc(dLen + 1 + fLen + 1);
    memcpy(buf, modulesDir, dLen);
    buf[dLen] = IPC_PATH_SEP_CHAR;
    memcpy(buf + dLen + 1, fileName, fLen);
    buf[dLen + 1 + fLen] = '\0';

    PRLibrary *lib = PR_LoadLibrary(buf);
    if (lib) {
        ipcGetModulesFunc func =
            (ipcGetModulesFunc) PR_FindFunctionSymbol(lib, "IPC_GetModules");

        LOG(("  func=%p\n", (void*) func));

        if (func) {
            const ipcModuleEntry *entries = NULL;
            int count = func(&gDaemonMethods, &entries);
            for (int i=0; i<count; ++i) {
                if (AddModule(entries[i].target, entries[i].methods, buf) == PR_SUCCESS) {
                    if (entries[i].methods->init)
                        entries[i].methods->init();
                }
            }
        }
        PR_UnloadLibrary(lib);
    }

    free(buf);
}
예제 #10
0
static SECStatus
ssl_ShutdownCngFunctions(void *appData, void *nssData)
{
    pNCryptSignHash = NULL;
    pNCryptFreeObject = NULL;
    if (ncrypt_library) {
        PR_UnloadLibrary(ncrypt_library);
        ncrypt_library = NULL;
    }

    cngFunctionsInitOnce = pristineCallOnce;

    return SECSuccess;
}
예제 #11
0
void
IPC_ShutdownModuleReg()
{
    //
    // shutdown modules in reverse order    
    //
    while (ipcModuleCount) {
        ipcModuleRegEntry &entry = ipcModules[--ipcModuleCount];
        if (entry.methods->shutdown)
            entry.methods->shutdown();
        if (entry.lib)
            PR_UnloadLibrary(entry.lib);
    }
}
예제 #12
0
static void InitPangoLib()
{
    static bool initialized = false;
    if (initialized)
        return;
    initialized = PR_TRUE;

    PRLibrary *pangoLib = nsnull;
    PTR_pango_font_description_get_size_is_absolute =
        (gboolean (*)(PangoFontDescription*))
        PR_FindFunctionSymbolAndLibrary("pango_font_description_get_size_is_absolute",
                                        &pangoLib);
    if (pangoLib)
        PR_UnloadLibrary(pangoLib);
}
예제 #13
0
// Removes a plugin DLL from memory, and frees its NPPMgtBlk management block.
// "pluginType" is a handle to the plugin management data structure created
// during FE_RegisterPlugins().  There is no return val.
void FE_UnregisterPlugin(void* pluginType)
{
    NPPMgtBlk* pNPMgtBlk = (NPPMgtBlk*)pluginType;
    if(pNPMgtBlk == NULL)
        return;
    
    if(pNPMgtBlk->pLibrary != NULL)
		PR_UnloadLibrary(pNPMgtBlk->pLibrary);
    
    delete [] (char*)*pNPMgtBlk->pPluginFilename;
    delete [] pNPMgtBlk->pPluginFilename;
    delete [] pNPMgtBlk->szMIMEType;
    delete pNPMgtBlk->pPluginFuncs;
    delete pNPMgtBlk;
}
예제 #14
0
nsIdleServiceGTK::~nsIdleServiceGTK()
{
    if (mXssInfo)
        XFree(mXssInfo);

// It is not safe to unload libXScrnSaver until each display is closed because
// the library registers callbacks through XESetCloseDisplay (Bug 397607).
// (Also the library and its functions are scoped for the file not the object.)
#if 0
    if (xsslib) {
        PR_UnloadLibrary(xsslib);
        xsslib = nullptr;
    }
#endif
}
예제 #15
0
nsIdleServiceQt::~nsIdleServiceQt()
{
#if !defined(MOZ_PLATFORM_MAEMO) && defined(MOZ_X11)
    if (mXssInfo)
        XFree(mXssInfo);

// It is not safe to unload libXScrnSaver until each display is closed because
// the library registers callbacks through XESetCloseDisplay (Bug 397607).
// (Also the library and its functions are scoped for the file not the object.)
#if 0
    if (xsslib) {
        PR_UnloadLibrary(xsslib);
        xsslib = nsnull;
    }
#endif
#endif
}
예제 #16
0
void LibraryNSPR::unload()
{
   if ( NULL == mLibrary )
   {
      throw vpr::IOException("No library to unload", VPR_LOCATION);
   }

   if ( PR_UnloadLibrary(mLibrary) == PR_FAILURE )
   {
      std::ostringstream msg_stream;
      vpr::NSPR_PrintError("Failed to unload library -- ", msg_stream);
      throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
   }
   else
   {
      mLibrary = NULL;
   }
}
예제 #17
0
DB *
rdbopen(const char *appName, const char *prefix,
        const char *type, int flags, int *status)
{
    PRLibrary *lib;
    DB *db;
    char *disableUnload = NULL;

    if (lg_rdbfunc) {
        db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
        if (!db && status && lg_rdbstatusfunc) {
            *status = (*lg_rdbstatusfunc)();
        }
        return db;
    }

    /*
     * try to open the library.
     */
    lib = PR_LoadLibrary(RDBLIB);

    if (!lib) {
        return NULL;
    }

    /* get the entry points */
    lg_rdbstatusfunc = (rdbstatusfunc)PR_FindSymbol(lib, "rdbstatus");
    lg_rdbfunc = (rdbfunc)PR_FindSymbol(lib, "rdbopen");
    if (lg_rdbfunc) {
        db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
        if (!db && status && lg_rdbstatusfunc) {
            *status = (*lg_rdbstatusfunc)();
        }
        return db;
    }

    /* couldn't find the entry point, unload the library and fail */
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (!disableUnload) {
        PR_UnloadLibrary(lib);
    }
    return NULL;
}
예제 #18
0
/* static */
void WebCL_LibCL::unload (WebCL_LibCL* aInstance)
{
  D_METHOD_START;

  if (!(aInstance && aInstance->m_libHandle))
    return;

  if (PR_UnloadLibrary (aInstance->m_libHandle) == PR_FAILURE)
  {
    char *errText = getPRErrorText ();
    D_LOG (LOG_LEVEL_WARNING, "Failed to unload library %s: %s", aInstance->m_libName, errText);
    D_LOG (LOG_LEVEL_DEBUG, "  (prerr: %d oserr: %d)", PR_GetError(), PR_GetOSError());
    PR_FREEIF (errText);
  }
  else
  {
    D_LOG (LOG_LEVEL_DEBUG, "Unloaded library %s", aInstance->m_libName);
  }
}
static nsresult
ensure_libgnome()
{
    if (!gTriedToLoadGnomeLibs) {
        gLibGnome = PR_LoadLibrary("libgnome-2.so.0");
        if (!gLibGnome)
            return NS_ERROR_NOT_AVAILABLE;

        _gnome_program_get = (_GnomeProgramGet_fn)PR_FindFunctionSymbol(gLibGnome, "gnome_program_get");
        if (!_gnome_program_get) {
            PR_UnloadLibrary(gLibGnome);
            gLibGnome = nullptr;
            return NS_ERROR_NOT_AVAILABLE;
        }
    }

    if (!gLibGnome)
        return NS_ERROR_NOT_AVAILABLE;

    return NS_OK;
}
static nsresult
ensure_libgnomevfs()
{
    if (!gTriedToLoadGnomeLibs) {
        gLibGnomeVFS = PR_LoadLibrary("libgnomevfs-2.so.0");
        if (!gLibGnomeVFS)
            return NS_ERROR_NOT_AVAILABLE;

        _gnome_vfs_get_file_info = (_GnomeVFSGetFileInfo_fn)PR_FindFunctionSymbol(gLibGnomeVFS, "gnome_vfs_get_file_info");
        _gnome_vfs_file_info_clear = (_GnomeVFSFileInfoClear_fn)PR_FindFunctionSymbol(gLibGnomeVFS, "gnome_vfs_file_info_clear");
        if (!_gnome_vfs_get_file_info || !_gnome_vfs_file_info_clear) {
            PR_UnloadLibrary(gLibGnomeVFS);
            gLibGnomeVFS = nullptr;
            return NS_ERROR_NOT_AVAILABLE;
        }
    }

    if (!gLibGnomeVFS)
        return NS_ERROR_NOT_AVAILABLE;

    return NS_OK;
}
void
BL_Unload(void)
{
  /* This function is not thread-safe, but doesn't need to be, because it is
   * only called from functions that are also defined as not thread-safe,
   * namely C_Finalize in softoken, and the SSL bypass shutdown callback called
   * from NSS_Shutdown. */
  char *disableUnload = NULL;
  vector = NULL;
  /* If an SSL socket is configured with SSL_BYPASS_PKCS11, but the application
   * never does a handshake on it, BL_Unload will be called even though freebl
   * was never loaded. So, don't assert blLib. */
  if (blLib) {
      disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
      if (!disableUnload) {
          PRStatus status = PR_UnloadLibrary(blLib);
          PORT_Assert(PR_SUCCESS == status);
      }
      blLib = NULL;
  }
  loadFreeBLOnce = pristineCallOnce;
}
/*  determine if hybrid platform, then actually load the DSO. */
static PRStatus
freebl_LoadDSO( void ) 
{
  PRLibrary *  handle;
  const char * name = getLibName();

  if (!name) {
    PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
    return PR_FAILURE;
  }

  handle = loader_LoadLibrary(name);
  if (handle) {
    PRFuncPtr address = PR_FindFunctionSymbol(handle, "FREEBL_GetVector");
    PRStatus status;
    if (address) {
      FREEBLGetVectorFn  * getVector = (FREEBLGetVectorFn *)address;
      const FREEBLVector * dsoVector = getVector();
      if (dsoVector) {
	unsigned short dsoVersion = dsoVector->version;
	unsigned short  myVersion = FREEBL_VERSION;
	if (MSB(dsoVersion) == MSB(myVersion) && 
	    LSB(dsoVersion) >= LSB(myVersion) &&
	    dsoVector->length >= sizeof(FREEBLVector)) {
          vector = dsoVector;
	  libraryName = name;
	  blLib = handle;
	  return PR_SUCCESS;
	}
      }
    }
    status = PR_UnloadLibrary(handle);
    PORT_Assert(PR_SUCCESS == status);
  }
  return PR_FAILURE;
}
const mozilla::Module*
nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
{
    nsresult rv;

    if (!NS_IsMainThread()) {
        // If this call is off the main thread, synchronously proxy it
        // to the main thread.
        nsRefPtr<LoadModuleMainThreadRunnable> r = new LoadModuleMainThreadRunnable(this, aFile);
        NS_DispatchToMainThread(r, NS_DISPATCH_SYNC);
        return r->mResult;
    }

    nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(aFile));
    if (!hashedFile) {
        NS_ERROR("nsIFile is not nsIHashable");
        return NULL;
    }

    nsCAutoString filePath;
    aFile->GetNativePath(filePath);

    NativeLoadData data;

    if (mLibraries.Get(hashedFile, &data)) {
        NS_ASSERTION(data.module, "Corrupt mLibraries hash");
        LOG(PR_LOG_DEBUG,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - found in cache",
             filePath.get()));
        return data.module;
    }

    // We haven't loaded this module before

    rv = aFile->Load(&data.library);

    if (NS_FAILED(rv)) {
        char errorMsg[1024] = "<unknown; can't get error from NSPR>";

        if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
            PR_GetErrorText(errorMsg);

        LOG(PR_LOG_ERROR,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - load FAILED, "
             "rv: %lx, error:\n\t%s\n",
             filePath.get(), rv, errorMsg));

#ifdef DEBUG
        fprintf(stderr,
                "nsNativeModuleLoader::LoadModule(\"%s\") - load FAILED, "
                "rv: %lx, error:\n\t%s\n",
                filePath.get(), (unsigned long)rv, errorMsg);
#endif

        return NULL;
    }

#ifdef IMPLEMENT_BREAK_AFTER_LOAD
    nsCAutoString leafName;
    aFile->GetNativeLeafName(leafName);

    char *env = getenv("XPCOM_BREAK_ON_LOAD");
    char *blist;
    if (env && *env && (blist = strdup(env))) {
        char *nextTok = blist;
        while (char *token = NS_strtok(":", &nextTok)) {
            if (leafName.Find(token, PR_TRUE) != kNotFound) {
                NS_BREAK();
            }
        }

        free(blist);
    }
#endif

    void *module = PR_FindSymbol(data.library, "NSModule");
    if (module) {
        data.module = *(mozilla::Module const *const *) module;
        if (mLibraries.Put(hashedFile, data))
            return data.module;
    }
    else {
        LOG(PR_LOG_ERROR,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - "
             "Symbol NSModule not found", filePath.get()));
    }

    // at some point we failed, clean up
    data.module = nsnull;
    PR_UnloadLibrary(data.library);

    return NULL;
}
예제 #24
0
static nsresult
gssInit()
{
    nsXPIDLCString libPath;
    nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
    if (prefs) {
        prefs->GetCharPref(kNegotiateAuthGssLib, getter_Copies(libPath)); 
        prefs->GetBoolPref(kNegotiateAuthNativeImp, &gssNativeImp); 
    }

    PRLibrary *lib = NULL;

    if (!libPath.IsEmpty()) {
        LOG(("Attempting to load user specified library [%s]\n", libPath.get()));
        gssNativeImp = PR_FALSE;
        lib = PR_LoadLibrary(libPath.get());
    }
    else {
#ifdef XP_WIN
        char *libName = PR_GetLibraryName(NULL, "gssapi32");
        if (libName) {
            lib = PR_LoadLibrary("gssapi32");
            PR_FreeLibraryName(libName);
        }
#else
        
        const char *const libNames[] = {
            "gss",
            "gssapi_krb5",
            "gssapi"
        };
        
        const char *const verLibNames[] = {
            "libgssapi_krb5.so.2", /* MIT - FC, Suse10, Debian */
            "libgssapi.so.4",      /* Heimdal - Suse10, MDK */
            "libgssapi.so.1"       /* Heimdal - Suse9, CITI - FC, MDK, Suse10*/
        };

        for (size_t i = 0; i < NS_ARRAY_LENGTH(verLibNames) && !lib; ++i) {
            lib = PR_LoadLibrary(verLibNames[i]);
 
            /* The CITI libgssapi library calls exit() during
             * initialization if it's not correctly configured. Try to
             * ensure that we never use this library for our GSSAPI
             * support, as its just a wrapper library, anyway.
             * See Bugzilla #325433
             */
            if (lib &&
                PR_FindFunctionSymbol(lib, 
                                      "internal_krb5_gss_initialize") &&
                PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
                LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
                PR_UnloadLibrary(lib);
                lib = NULL;
            }
        }

        for (size_t i = 0; i < NS_ARRAY_LENGTH(libNames) && !lib; ++i) {
            char *libName = PR_GetLibraryName(NULL, libNames[i]);
            if (libName) {
                lib = PR_LoadLibrary(libName);
                PR_FreeLibraryName(libName);

                if (lib &&
                    PR_FindFunctionSymbol(lib, 
                                          "internal_krb5_gss_initialize") &&
                    PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
                    LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
                    PR_UnloadLibrary(lib);
                    lib = NULL;
                } 
            }
        }
#endif
    }
    
    if (!lib) {
        LOG(("Fail to load gssapi library\n"));
        return NS_ERROR_FAILURE;
    }

    LOG(("Attempting to load gss functions\n"));

    for (size_t i = 0; i < gssFuncItems; ++i) {
        gssFunPtr[i] = PR_FindFunctionSymbol(lib, gssFuncStr[i]);
        if (!gssFunPtr[i]) {
            LOG(("Fail to load %s function from gssapi library\n", gssFuncStr[i]));
            PR_UnloadLibrary(lib);
            return NS_ERROR_FAILURE;
        }
    }
#ifdef XP_MACOSX
    if (gssNativeImp &&
            !(KLCacheHasValidTicketsPtr =
               PR_FindFunctionSymbol(lib, "KLCacheHasValidTickets"))) {
        LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n"));
        PR_UnloadLibrary(lib);
        return NS_ERROR_FAILURE;
    }
#endif

    gssFunInit = PR_TRUE;
    return NS_OK;
}
예제 #25
0
/*
 * load a new module into our address space and initialize it.
 */
SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
    PRLibrary *library = NULL;
    CK_C_GetFunctionList entry = NULL;
    CK_INFO info;
    CK_ULONG slotCount = 0;
    SECStatus rv;
    PRBool alreadyLoaded = PR_FALSE;
    char *disableUnload = NULL;

    if (mod->loaded)
        return SECSuccess;

    /* internal modules get loaded from their internal list */
    if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_TEST_BUILD
        entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
#else
        /*
         * Loads softoken as a dynamic library,
         * even though the rest of NSS assumes this as the "internal" module.
         */
        if (!softokenLib &&
            PR_SUCCESS != PR_CallOnce(&loadSoftokenOnce, &softoken_LoadDSO))
            return SECFailure;

        PR_ATOMIC_INCREMENT(&softokenLoadCount);

        if (mod->isFIPS) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "FC_GetFunctionList");
        } else {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
        }

        if (!entry)
            return SECFailure;
#endif

        if (mod->isModuleDB) {
            mod->moduleDBFunc = (CK_C_GetFunctionList)
#ifdef NSS_TEST_BUILD
                NSC_ModuleDBFunc;
#else
                PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
#endif
        }

        if (mod->moduleDBOnly) {
            mod->loaded = PR_TRUE;
            return SECSuccess;
        }
    } else {
        /* Not internal, load the DLL and look up C_GetFunctionList */
        if (mod->dllName == NULL) {
            return SECFailure;
        }

        /* load the library. If this succeeds, then we have to remember to
         * unload the library if anything goes wrong from here on out...
         */
        library = PR_LoadLibrary(mod->dllName);
        mod->library = (void *)library;

        if (library == NULL) {
            return SECFailure;
        }

        /*
         * now we need to get the entry point to find the function pointers
         */
        if (!mod->moduleDBOnly) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(library, "C_GetFunctionList");
        }
        if (mod->isModuleDB) {
            mod->moduleDBFunc = (void *)
                PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
        }
        if (mod->moduleDBFunc == NULL)
            mod->isModuleDB = PR_FALSE;
        if (entry == NULL) {
            if (mod->isModuleDB) {
                mod->loaded = PR_TRUE;
                mod->moduleDBOnly = PR_TRUE;
                return SECSuccess;
            }
            PR_UnloadLibrary(library);
            return SECFailure;
        }
    }

    /*
     * We need to get the function list
     */
    if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
        goto fail;

#ifdef DEBUG_MODULE
    if (PR_TRUE) {
        modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
        if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
            mod->functionList = (void *)nss_InsertDeviceLog(
                (CK_FUNCTION_LIST_PTR)mod->functionList);
        }
    }
#endif

    mod->isThreadSafe = PR_TRUE;

    /* Now we initialize the module */
    rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
    if (rv != SECSuccess) {
        goto fail;
    }

    /* module has been reloaded, this module itself is done,
     * return to the caller */
    if (mod->functionList == NULL) {
        mod->loaded = PR_TRUE; /* technically the module is loaded.. */
        return SECSuccess;
    }

    /* check the version number */
    if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK)
        goto fail2;
    if (info.cryptokiVersion.major != 2)
        goto fail2;
    /* all 2.0 are a priori *not* thread safe */
    if (info.cryptokiVersion.minor < 1) {
        if (!loadSingleThreadedModules) {
            PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
            goto fail2;
        } else {
            mod->isThreadSafe = PR_FALSE;
        }
    }
    mod->cryptokiVersion = info.cryptokiVersion;

    /* If we don't have a common name, get it from the PKCS 11 module */
    if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
        mod->commonName = PK11_MakeString(mod->arena, NULL,
                                          (char *)info.libraryDescription, sizeof(info.libraryDescription));
        if (mod->commonName == NULL)
            goto fail2;
    }

    /* initialize the Slots */
    if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
        CK_SLOT_ID *slotIDs;
        int i;
        CK_RV crv;

        mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
                                                      sizeof(PK11SlotInfo *) * slotCount);
        if (mod->slots == NULL)
            goto fail2;

        slotIDs = (CK_SLOT_ID *)PORT_Alloc(sizeof(CK_SLOT_ID) * slotCount);
        if (slotIDs == NULL) {
            goto fail2;
        }
        crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
        if (crv != CKR_OK) {
            PORT_Free(slotIDs);
            goto fail2;
        }

        /* Initialize each slot */
        for (i = 0; i < (int)slotCount; i++) {
            mod->slots[i] = PK11_NewSlotInfo(mod);
            PK11_InitSlot(mod, slotIDs[i], mod->slots[i]);
            /* look down the slot info table */
            PK11_LoadSlotList(mod->slots[i], mod->slotInfo, mod->slotInfoCount);
            SECMOD_SetRootCerts(mod->slots[i], mod);
            /* explicitly mark the internal slot as such if IsInternalKeySlot()
             * is set */
            if (secmod_IsInternalKeySlot(mod) && (i == (mod->isFIPS ? 0 : 1))) {
                pk11_SetInternalKeySlotIfFirst(mod->slots[i]);
            }
        }
        mod->slotCount = slotCount;
        mod->slotInfoCount = 0;
        PORT_Free(slotIDs);
    }

    mod->loaded = PR_TRUE;
    mod->moduleID = nextModuleID++;
    return SECSuccess;
fail2:
    if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
        PK11_GETTAB(mod)->C_Finalize(NULL);
    }
fail:
    mod->functionList = NULL;
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (library && !disableUnload) {
        PR_UnloadLibrary(library);
    }
    return SECFailure;
}
PRBool
GConfProxy::Init()
{
    SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n"));
    if (!mSysPrefService)
        return PR_FALSE;
    if (mInitialized)
        return PR_TRUE;

    nsCOMPtr<nsIPref> pref = do_GetService(NS_PREF_CONTRACTID);
    if (!pref)
        return PR_FALSE;

    nsXPIDLCString gconfLibName;
    nsresult rv;

    //check if gconf-2 library is given in prefs
    rv = pref->GetCharPref(sPrefGConfKey, getter_Copies(gconfLibName));
    if (NS_SUCCEEDED(rv)) {
        //use the library name in the preference
        SYSPREF_LOG(("GConf library in prefs is %s\n", gconfLibName.get()));
        mGConfLib = PR_LoadLibrary(gconfLibName.get());
    }
    else {
        SYSPREF_LOG(("GConf library not specified in prefs, try the default: "
                     "%s and %s\n", sDefaultLibName1, sDefaultLibName2));
        mGConfLib = PR_LoadLibrary(sDefaultLibName1);
        if (!mGConfLib)
            mGConfLib = PR_LoadLibrary(sDefaultLibName2);
    }

    if (!mGConfLib) {
        SYSPREF_LOG(("Fail to load GConf library\n"));
        return PR_FALSE;
    }

    //check every func we need in the gconf library
    GConfFuncListType *funcList;
    PRFuncPtr func;
    for (funcList = sGConfFuncList; funcList->FuncName; ++funcList) {
        func = PR_FindFunctionSymbol(mGConfLib, funcList->FuncName);
        if (!func) {
            SYSPREF_LOG(("Check GConf Func Error: %s", funcList->FuncName));
            goto init_failed_unload;
        }
        funcList->FuncPtr = func;
    }

    InitFuncPtrs();

    mGConfClient = GConfClientGetDefault();

    // Don't unload past this point, since GConf's initialization of ORBit
    // causes atexit handlers to be registered.

    if (!mGConfClient) {
        SYSPREF_LOG(("Fail to Get default gconf client\n"));
        goto init_failed;
    }
    mInitialized = PR_TRUE;
    return PR_TRUE;

 init_failed_unload:
    PR_UnloadLibrary(mGConfLib);
 init_failed:
    mGConfLib = nsnull;
    return PR_FALSE;
}
NS_IMETHODIMP
nsNativeAppSupportUnix::Start(bool *aRetVal)
{
  NS_ASSERTION(gAppData, "gAppData must not be null.");

// The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService,
// from diffrent threads. This could lead to race conditions if the dbus is not
// initialized before making any other library calls.
#ifdef MOZ_ENABLE_DBUS
  dbus_threads_init_default();
#endif

#if (MOZ_WIDGET_GTK == 2)
  if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
      (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
    GtkWidget* versionErrDialog = gtk_message_dialog_new(NULL,
                     GtkDialogFlags(GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT),
                     GTK_MESSAGE_ERROR,
                     GTK_BUTTONS_OK,
                     UNSUPPORTED_GTK_MSG,
                     gtk_major_version,
                     gtk_minor_version,
                     MIN_GTK_MAJOR_VERSION,
                     MIN_GTK_MINOR_VERSION);
    gtk_dialog_run(GTK_DIALOG(versionErrDialog));
    gtk_widget_destroy(versionErrDialog);
    exit(0);
  }
#endif

  *aRetVal = true;

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)

  PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0");
  if (!gnomeuiLib)
    return NS_OK;

  PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0");
  if (!gnomeLib) {
    PR_UnloadLibrary(gnomeuiLib);
    return NS_OK;
  }

  _gnome_program_init_fn gnome_program_init =
    (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init");
  _gnome_program_get_fn gnome_program_get =
    (_gnome_program_get_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_get"); 
 _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get");
  if (!gnome_program_init || !gnome_program_get || !libgnomeui_module_info_get) {
    PR_UnloadLibrary(gnomeuiLib);
    PR_UnloadLibrary(gnomeLib);
    return NS_OK;
  }

#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  // We will load gail, atk-bridge by ourself later
  // We can't run atk-bridge init here, because gail get the control
  // Set GNOME_ACCESSIBILITY to 0 can avoid this
  static const char *accEnv = "GNOME_ACCESSIBILITY";
  const char *accOldValue = getenv(accEnv);
  setenv(accEnv, "0", 1);
#endif

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  if (!gnome_program_get()) {
    gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), gArgc, gArgv, NULL);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  if (accOldValue) { 
    setenv(accEnv, accOldValue, 1);
  } else {
    unsetenv(accEnv);
  }
#endif

  // Careful! These libraries cannot be unloaded after this point because
  // gnome_program_init causes atexit handlers to be registered. Strange
  // crashes will occur if these libraries are unloaded.

  // TODO GTK3 - see Bug 694570 - Stop using libgnome and libgnomeui on Linux
#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command");

  _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");

  GnomeClient *client = gnome_master_client();
  g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), NULL);
  g_signal_connect(client, "die", G_CALLBACK(die_cb), NULL);

  // Set the correct/requested restart command in any case.

  // Is there a request to suppress default binary launcher?
  nsAutoCString path;
  char* argv1 = getenv("MOZ_APP_LAUNCHER");

  if(!argv1) {
    // Tell the desktop the command for restarting us so that we can be part of XSMP session restore
    NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
    nsCOMPtr<nsIFile> executablePath;
    nsresult rv;

    bool dummy;
    rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));

    if (NS_SUCCEEDED(rv)) {
      // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
      nsAutoCString leafName;
      rv = executablePath->GetNativeLeafName(leafName);
      if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
        leafName.SetLength(leafName.Length() - strlen("-bin"));
        executablePath->SetNativeLeafName(leafName);
      }

      executablePath->GetNativePath(path);
      argv1 = (char*)(path.get());
    }
  }

  if (argv1) {
    gnome_client_set_restart_command(client, 1, &argv1);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

  return NS_OK;
}
const mozilla::Module*
nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
{
    nsresult rv;

    if (!NS_IsMainThread()) {
        // If this call is off the main thread, synchronously proxy it
        // to the main thread.
        nsRefPtr<LoadModuleMainThreadRunnable> r = new LoadModuleMainThreadRunnable(this, aFile);
        NS_DispatchToMainThread(r, NS_DISPATCH_SYNC);
        return r->mResult;
    }

    nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(aFile));
    if (!hashedFile) {
        NS_ERROR("nsIFile is not nsIHashable");
        return NULL;
    }

    nsCAutoString filePath;
    aFile->GetNativePath(filePath);

    NativeLoadData data;

    if (mLibraries.Get(hashedFile, &data)) {
        NS_ASSERTION(data.module, "Corrupt mLibraries hash");
        LOG(PR_LOG_DEBUG,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - found in cache",
             filePath.get()));
        return data.module;
    }

    // We haven't loaded this module before

    rv = aFile->Load(&data.library);

    if (NS_FAILED(rv)) {
        char errorMsg[1024] = "<unknown; can't get error from NSPR>";

        if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
            PR_GetErrorText(errorMsg);

        LogMessage("Failed to load native module at path '%s': (%lx) %s",
                   filePath.get(), rv, errorMsg);

        return NULL;
    }

#ifdef IMPLEMENT_BREAK_AFTER_LOAD
    nsCAutoString leafName;
    aFile->GetNativeLeafName(leafName);

    char *env = getenv("XPCOM_BREAK_ON_LOAD");
    char *blist;
    if (env && *env && (blist = strdup(env))) {
        char *nextTok = blist;
        while (char *token = NS_strtok(":", &nextTok)) {
            if (leafName.Find(token, true) != kNotFound) {
                NS_BREAK();
            }
        }

        free(blist);
    }
#endif

    void *module = PR_FindSymbol(data.library, "NSModule");
    if (!module) {
        LogMessage("Native module at path '%s' doesn't export symbol `NSModule`.",
                   filePath.get());
        PR_UnloadLibrary(data.library);
        return NULL;
    }

    data.module = *(mozilla::Module const *const *) module;
    if (mozilla::Module::kVersion != data.module->mVersion) {
        LogMessage("Native module at path '%s' is incompatible with this version of Firefox, has version %i, expected %i.",
                   filePath.get(), data.module->mVersion,
                   mozilla::Module::kVersion);
        PR_UnloadLibrary(data.library);
        return NULL;
    }
        
    mLibraries.Put(hashedFile, data); // infallible
    return data.module;
}
static void InitTraceLog(void)
{
  if (gInitialized) return;
  gInitialized = true;

  bool defined;
  defined = InitLog("XPCOM_MEM_BLOAT_LOG", "bloat/leaks", &gBloatLog);
  if (!defined)
    gLogLeaksOnly = InitLog("XPCOM_MEM_LEAK_LOG", "leaks", &gBloatLog);
  if (defined || gLogLeaksOnly) {
    RecreateBloatView();
    if (!gBloatView) {
      NS_WARNING("out of memory");
      gBloatLog = nullptr;
      gLogLeaksOnly = false;
    }
  }

  (void)InitLog("XPCOM_MEM_REFCNT_LOG", "refcounts", &gRefcntsLog);

  (void)InitLog("XPCOM_MEM_ALLOC_LOG", "new/delete", &gAllocLog);

  defined = InitLog("XPCOM_MEM_LEAKY_LOG", "for leaky", &gLeakyLog);
  if (defined) {
    gLogToLeaky = true;
    PRFuncPtr p = nullptr, q = nullptr;
#ifdef HAVE_DLOPEN
    {
      PRLibrary *lib = nullptr;
      p = PR_FindFunctionSymbolAndLibrary("__log_addref", &lib);
      if (lib) {
        PR_UnloadLibrary(lib);
        lib = nullptr;
      }
      q = PR_FindFunctionSymbolAndLibrary("__log_release", &lib);
      if (lib) {
        PR_UnloadLibrary(lib);
      }
    }
#endif
    if (p && q) {
      leakyLogAddRef = (void (*)(void*,int,int)) p;
      leakyLogRelease = (void (*)(void*,int,int)) q;
    }
    else {
      gLogToLeaky = false;
      fprintf(stdout, "### ERROR: XPCOM_MEM_LEAKY_LOG defined, but can't locate __log_addref and __log_release symbols\n");
      fflush(stdout);
    }
  }

  const char* classes = getenv("XPCOM_MEM_LOG_CLASSES");

#ifdef HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR
  if (classes) {
    (void)InitLog("XPCOM_MEM_COMPTR_LOG", "nsCOMPtr", &gCOMPtrLog);
  } else {
    if (getenv("XPCOM_MEM_COMPTR_LOG")) {
      fprintf(stdout, "### XPCOM_MEM_COMPTR_LOG defined -- but XPCOM_MEM_LOG_CLASSES is not defined\n");
    }
  }
#else
  const char* comptr_log = getenv("XPCOM_MEM_COMPTR_LOG");
  if (comptr_log) {
    fprintf(stdout, "### XPCOM_MEM_COMPTR_LOG defined -- but it will not work without dynamic_cast\n");
  }
#endif

  if (classes) {
    // if XPCOM_MEM_LOG_CLASSES was set to some value, the value is interpreted
    // as a list of class names to track
    gTypesToLog = PL_NewHashTable(256,
                                  PL_HashString,
                                  PL_CompareStrings,
                                  PL_CompareValues,
                                  &typesToLogHashAllocOps, NULL);
    if (!gTypesToLog) {
      NS_WARNING("out of memory");
      fprintf(stdout, "### XPCOM_MEM_LOG_CLASSES defined -- unable to log specific classes\n");
    }
    else {
      fprintf(stdout, "### XPCOM_MEM_LOG_CLASSES defined -- only logging these classes: ");
      const char* cp = classes;
      for (;;) {
        char* cm = (char*) strchr(cp, ',');
        if (cm) {
          *cm = '\0';
        }
        PL_HashTableAdd(gTypesToLog, nsCRT::strdup(cp), (void*)1);
        fprintf(stdout, "%s ", cp);
        if (!cm) break;
        *cm = ',';
        cp = cm + 1;
      }
      fprintf(stdout, "\n");
    }

    gSerialNumbers = PL_NewHashTable(256,
                                     HashNumber,
                                     PL_CompareValues,
                                     PL_CompareValues,
                                     &serialNumberHashAllocOps, NULL);


  }

  const char* objects = getenv("XPCOM_MEM_LOG_OBJECTS");
  if (objects) {
    gObjectsToLog = PL_NewHashTable(256,
                                    HashNumber,
                                    PL_CompareValues,
                                    PL_CompareValues,
                                    NULL, NULL);

    if (!gObjectsToLog) {
      NS_WARNING("out of memory");
      fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- unable to log specific objects\n");
    }
    else if (! (gRefcntsLog || gAllocLog || gCOMPtrLog)) {
      fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- but none of XPCOM_MEM_(REFCNT|ALLOC|COMPTR)_LOG is defined\n");
    }
    else {
      fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- only logging these objects: ");
      const char* cp = objects;
      for (;;) {
        char* cm = (char*) strchr(cp, ',');
        if (cm) {
          *cm = '\0';
        }
        intptr_t top = 0;
        intptr_t bottom = 0;
        while (*cp) {
          if (*cp == '-') {
            bottom = top;
            top = 0;
            ++cp;
          }
          top *= 10;
          top += *cp - '0';
          ++cp;
        }
        if (!bottom) {
          bottom = top;
        }
        for (intptr_t serialno = bottom; serialno <= top; serialno++) {
          PL_HashTableAdd(gObjectsToLog, (const void*)serialno, (void*)1);
          fprintf(stdout, "%ld ", serialno);
        }
        if (!cm) break;
        *cm = ',';
        cp = cm + 1;
      }
      fprintf(stdout, "\n");
    }
  }


  if (gBloatLog || gRefcntsLog || gAllocLog || gLeakyLog || gCOMPtrLog) {
    gLogging = true;
  }

  gTraceLock = PR_NewLock();
}
NS_IMETHODIMP
nsNativeAppSupportUnix::Start(bool *aRetVal)
{
  NS_ASSERTION(gAppData, "gAppData must not be null.");

// The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService,
// from diffrent threads. This could lead to race conditions if the dbus is not
// initialized before making any other library calls.
#ifdef MOZ_ENABLE_DBUS
  dbus_threads_init_default();
#endif

#if (MOZ_WIDGET_GTK == 2)
  if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
      (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
    GtkWidget* versionErrDialog = gtk_message_dialog_new(NULL,
                     GtkDialogFlags(GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT),
                     GTK_MESSAGE_ERROR,
                     GTK_BUTTONS_OK,
                     UNSUPPORTED_GTK_MSG,
                     gtk_major_version,
                     gtk_minor_version,
                     MIN_GTK_MAJOR_VERSION,
                     MIN_GTK_MINOR_VERSION);
    gtk_dialog_run(GTK_DIALOG(versionErrDialog));
    gtk_widget_destroy(versionErrDialog);
    exit(0);
  }
#endif

#if (MOZ_PLATFORM_MAEMO == 5)
  /* zero state out. */
  memset(&m_hw_state, 0, sizeof(osso_hw_state_t));

  /* Initialize maemo application
     
     The initalization name will be of the form "Vendor.Name".
     If a Vendor isn't given, then we will just use "Name".
     
     Note that this value must match your X-Osso-Service name
     defined in your desktop file.  If it doesn't, the OSSO
     system will happily kill your process.
  */
  nsAutoCString applicationName;
  if (gAppData->vendor) {
      applicationName.Append(gAppData->vendor);
      applicationName.Append(".");
  }
  applicationName.Append(gAppData->name);
  ToLowerCase(applicationName);

  m_osso_context = osso_initialize(applicationName.get(), 
                                   gAppData->version ? gAppData->version : "1.0",
                                   true,
                                   nullptr);

  /* Check that initilialization was ok */
  if (m_osso_context == nullptr) {
      return NS_ERROR_FAILURE;
  }

  osso_hw_set_event_cb(m_osso_context, nullptr, OssoHardwareCallback, &m_hw_state);
  osso_hw_set_display_event_cb(m_osso_context, OssoDisplayCallback, m_osso_context);
  osso_rpc_set_default_cb_f(m_osso_context, OssoDbusCallback, nullptr);

  // Setup an MCE callback to monitor orientation
  DBusConnection *connnection = (DBusConnection*)osso_get_sys_dbus_connection(m_osso_context);
  dbus_bus_add_match(connnection, MCE_MATCH_RULE, nullptr);
  dbus_connection_add_filter(connnection, OssoModeControlCallback, nullptr, nullptr);
#endif

  *aRetVal = true;

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)

  PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0");
  if (!gnomeuiLib)
    return NS_OK;

  PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0");
  if (!gnomeLib) {
    PR_UnloadLibrary(gnomeuiLib);
    return NS_OK;
  }

  _gnome_program_init_fn gnome_program_init =
    (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init");
  _gnome_program_get_fn gnome_program_get =
    (_gnome_program_get_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_get"); 
 _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get");
  if (!gnome_program_init || !gnome_program_get || !libgnomeui_module_info_get) {
    PR_UnloadLibrary(gnomeuiLib);
    PR_UnloadLibrary(gnomeLib);
    return NS_OK;
  }

#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  // We will load gail, atk-bridge by ourself later
  // We can't run atk-bridge init here, because gail get the control
  // Set GNOME_ACCESSIBILITY to 0 can avoid this
  static const char *accEnv = "GNOME_ACCESSIBILITY";
  const char *accOldValue = getenv(accEnv);
  setenv(accEnv, "0", 1);
#endif

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  if (!gnome_program_get()) {
    gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), gArgc, gArgv, NULL);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  if (accOldValue) { 
    setenv(accEnv, accOldValue, 1);
  } else {
    unsetenv(accEnv);
  }
#endif

  // Careful! These libraries cannot be unloaded after this point because
  // gnome_program_init causes atexit handlers to be registered. Strange
  // crashes will occur if these libraries are unloaded.

  // TODO GTK3 - see Bug 694570 - Stop using libgnome and libgnomeui on Linux
#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command");

  _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");

  GnomeClient *client = gnome_master_client();
  g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), NULL);
  g_signal_connect(client, "die", G_CALLBACK(die_cb), NULL);

  // Set the correct/requested restart command in any case.

  // Is there a request to suppress default binary launcher?
  nsAutoCString path;
  char* argv1 = getenv("MOZ_APP_LAUNCHER");

  if(!argv1) {
    // Tell the desktop the command for restarting us so that we can be part of XSMP session restore
    NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
    nsCOMPtr<nsIFile> executablePath;
    nsresult rv;

    bool dummy;
    rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));

    if (NS_SUCCEEDED(rv)) {
      // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
      nsAutoCString leafName;
      rv = executablePath->GetNativeLeafName(leafName);
      if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
        leafName.SetLength(leafName.Length() - strlen("-bin"));
        executablePath->SetNativeLeafName(leafName);
      }

      executablePath->GetNativePath(path);
      argv1 = (char*)(path.get());
    }
  }

  if (argv1) {
    gnome_client_set_restart_command(client, 1, &argv1);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

  return NS_OK;
}