bug# 101769 Stop loading plugins on startup r=av,sr=waterson
git-svn-id: svn://10.0.0.236/trunk@105700 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -39,6 +39,11 @@
|
||||
|
||||
/* nsPluginHostImpl.cpp - bulk of code for managing plugins */
|
||||
|
||||
/* XdpX Really really force prlogging*/
|
||||
#define FORCE_PR_LOG /* Allow logging in the release build */
|
||||
#define PR_LOGGING 1
|
||||
#include "prlog.h"
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsPluginHostImpl.h"
|
||||
#include "nsPluginProxyImpl.h"
|
||||
@@ -169,6 +174,13 @@
|
||||
|
||||
#define REL_PLUGIN_DLL "rel:" PLUGIN_DLL
|
||||
|
||||
// this is the name of the directory which will be created
|
||||
// to cache temporary files.
|
||||
static const char *kPluginTmpDirName = "plugtmp";
|
||||
|
||||
// Version of cached plugin info
|
||||
static const char *kPluginInfoVersion = "0.01";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// CID's && IID's
|
||||
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
|
||||
@@ -192,6 +204,19 @@ static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
|
||||
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Registry keys for caching plugin info
|
||||
static const char kPluginsRootKey[] = "software/plugins";
|
||||
static const char kPluginsNameKey[] = "name";
|
||||
static const char kPluginsDescKey[] = "description";
|
||||
static const char kPluginsFilenameKey[] = "filename";
|
||||
static const char kPluginsFullpathKey[] = "fullpath";
|
||||
static const char kPluginsModTimeKey[] = "lastModTimeStamp";
|
||||
static const char kPluginsVersionKey[] = "version";
|
||||
static const char kPluginsMimeTypeKey[] = "mimetype";
|
||||
static const char kPluginsMimeDescKey[] = "description";
|
||||
static const char kPluginsMimeExtKey[] = "extension";
|
||||
|
||||
#ifdef PLUGIN_LOGGING
|
||||
PRLogModuleInfo* nsPluginLogging::gNPNLog = nsnull;
|
||||
PRLogModuleInfo* nsPluginLogging::gNPPLog = nsnull;
|
||||
@@ -866,10 +891,12 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
|
||||
nsPluginTag::nsPluginTag(const char* aName,
|
||||
const char* aDescription,
|
||||
const char* aFileName,
|
||||
const char* aFullPath,
|
||||
const char* const* aMimeTypes,
|
||||
const char* const* aMimeDescriptions,
|
||||
const char* const* aExtensions,
|
||||
PRInt32 aVariants)
|
||||
PRInt32 aVariants,
|
||||
PRInt64 aLastModifiedTime)
|
||||
: mNext(nsnull),
|
||||
mVariants(aVariants),
|
||||
mMimeTypeArray(nsnull),
|
||||
@@ -879,13 +906,13 @@ nsPluginTag::nsPluginTag(const char* aName,
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
mEntryPoint(nsnull),
|
||||
mFlags(0),
|
||||
mXPConnected(PR_FALSE)
|
||||
|
||||
mXPConnected(PR_FALSE),
|
||||
mLastModifiedTime(aLastModifiedTime)
|
||||
{
|
||||
mName = new_str(aName);
|
||||
mDescription = new_str(aDescription);
|
||||
mFileName = new_str(aFileName);
|
||||
mFullPath = new_str(aFileName);
|
||||
mFullPath = new_str(aFullPath);
|
||||
|
||||
if (mVariants) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
@@ -2363,9 +2390,6 @@ nsresult nsPluginStreamListenerPeer::SetLocalFile(const char* aFilename)
|
||||
nsPluginHostImpl::nsPluginHostImpl()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
#ifdef NS_DEBUG
|
||||
printf("nsPluginHostImpl ctor\n");
|
||||
#endif
|
||||
mPluginsLoaded = PR_FALSE;
|
||||
mDontShowBadPluginMessage = PR_FALSE;
|
||||
mIsDestroyed = PR_FALSE;
|
||||
@@ -2387,8 +2411,11 @@ nsPluginHostImpl::nsPluginHostImpl()
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHostImpl::ctor)\n"));
|
||||
PR_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHostImpl::ctor\n"));
|
||||
PR_LogFlush();
|
||||
#endif
|
||||
mCachedPlugins = nsnull;
|
||||
mSyncCachedPlugins = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -2801,11 +2828,11 @@ NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
|
||||
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCAutoString path("software/plugins/");
|
||||
nsCAutoString path(kPluginsRootKey);
|
||||
char* cid = aCID.ToString();
|
||||
if (! cid)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
path += '/';
|
||||
path += cid;
|
||||
nsMemory::Free(cid);
|
||||
|
||||
@@ -2813,8 +2840,8 @@ NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
|
||||
rv = registry->AddSubtree(nsIRegistry::Common, path.get(), &pluginKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
registry->SetStringUTF8(pluginKey, "name", aPluginName);
|
||||
registry->SetStringUTF8(pluginKey, "description", aDescription);
|
||||
registry->SetStringUTF8(pluginKey, kPluginsNameKey, aPluginName);
|
||||
registry->SetStringUTF8(pluginKey, kPluginsDescKey, aDescription);
|
||||
|
||||
for (PRInt32 i = 0; i < aCount; ++i) {
|
||||
nsCAutoString mimepath;
|
||||
@@ -2823,9 +2850,9 @@ NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
|
||||
nsRegistryKey key;
|
||||
registry->AddSubtree(pluginKey, mimepath.get(), &key);
|
||||
|
||||
registry->SetStringUTF8(key, "mimetype", aMimeTypes[i]);
|
||||
registry->SetStringUTF8(key, "description", aMimeDescriptions[i]);
|
||||
registry->SetStringUTF8(key, "extension", aFileExtensions[i]);
|
||||
registry->SetStringUTF8(key, kPluginsMimeTypeKey, aMimeTypes[i]);
|
||||
registry->SetStringUTF8(key, kPluginsMimeDescKey, aMimeDescriptions[i]);
|
||||
registry->SetStringUTF8(key, kPluginsMimeExtKey, aFileExtensions[i]);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -3072,6 +3099,14 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
|
||||
mPlugins = temp;
|
||||
}
|
||||
|
||||
// Delete any remaining cached plugins list
|
||||
while (mCachedPlugins)
|
||||
{
|
||||
nsPluginTag *next = mCachedPlugins->mNext;
|
||||
delete mCachedPlugins;
|
||||
mCachedPlugins = next;
|
||||
}
|
||||
|
||||
CleanUnusedLibraries();
|
||||
|
||||
// Lets remove any of the temporary files that we created.
|
||||
@@ -4287,24 +4322,6 @@ static PRBool areTheSameFileNames(char * aPath1, char * aPath2)
|
||||
return (nsnull == PL_strncasecmp(filename1.get(), filename2.get(), PL_strlen(filename1.get())));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
static PRBool isJavaPlugin(nsPluginTag * tag)
|
||||
{
|
||||
if(tag->mFileName == nsnull)
|
||||
return PR_FALSE;
|
||||
|
||||
char * filename = PL_strrchr(tag->mFileName, '\\');
|
||||
|
||||
if(filename != nsnull)
|
||||
filename++;
|
||||
else
|
||||
filename = tag->mFileName;
|
||||
|
||||
return (nsnull == PL_strncasecmp(filename, "npjava", 6));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// currently 'unwanted' plugins are Java, and all other plugins except
|
||||
// RealPlayer, Acrobat, Flash
|
||||
@@ -4347,45 +4364,91 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsPluginsDir& pluginsDir,
|
||||
|
||||
for (nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++)
|
||||
{
|
||||
const nsFileSpec& file = iter;
|
||||
nsFileSpec file = iter;
|
||||
if (pluginsDir.IsPluginFile(file))
|
||||
{
|
||||
nsPluginFile pluginFile(file);
|
||||
PRLibrary* pluginLibrary = nsnull;
|
||||
// Look for it in our cache
|
||||
nsPluginTag *pluginTag = RemoveCachedPluginsInfo(file.GetCString());
|
||||
|
||||
// load the plugin's library so we can ask it some questions, but not for Windows
|
||||
#ifndef XP_WIN
|
||||
if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == nsnull)
|
||||
continue;
|
||||
#endif
|
||||
// Get file mod time
|
||||
// XXX if we use nsIFile we will get a 64 bit timestamp.
|
||||
// XXX filespec does only 32 bit. Grrr...
|
||||
PRUint32 shortFileModTime = 0;
|
||||
file.GetModDate(shortFileModTime);
|
||||
PRInt64 fileModTime;
|
||||
LL_UI2L(fileModTime, shortFileModTime);
|
||||
|
||||
// create a tag describing this plugin.
|
||||
nsPluginInfo info = { sizeof(info) };
|
||||
nsresult res = pluginFile.GetPluginInfo(info);
|
||||
if(NS_FAILED(res))
|
||||
continue;
|
||||
|
||||
// if we don't have mime type -- don't proceed, this is not a plugin
|
||||
if(!info.fMimeTypeArray) {
|
||||
pluginFile.FreePluginInfo(info);
|
||||
continue;
|
||||
if (pluginTag) {
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("ScanPluginsDirectory : Found plugin in cache : %s\n", pluginTag->mFileName));
|
||||
// If plugin changed, delete cachedPluginTag and dont use cache
|
||||
if (LL_NE(fileModTime, pluginTag->mLastModifiedTime)) {
|
||||
// Plugins has changed. Dont use cached plugin info.
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("ScanPluginsDirectory : timestamp check failed. Reloading plugin : %s\n", pluginTag->mFileName));
|
||||
delete pluginTag;
|
||||
pluginTag = nsnull;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("ScanPluginsDirectory : Plugin NOT found in cache : %s\n", file.GetCString()));
|
||||
}
|
||||
|
||||
nsPluginTag* pluginTag = new nsPluginTag(&info);
|
||||
pluginFile.FreePluginInfo(info);
|
||||
|
||||
if(pluginTag == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pluginTag->mLibrary = pluginLibrary;
|
||||
|
||||
if (!pluginTag) {
|
||||
nsPluginFile pluginFile(file);
|
||||
PRLibrary* pluginLibrary = nsnull;
|
||||
|
||||
// load the plugin's library so we can ask it some questions, but not for Windows
|
||||
#ifndef XP_WIN
|
||||
if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == nsnull)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
// create a tag describing this plugin.
|
||||
nsPluginInfo info = { sizeof(info) };
|
||||
nsresult res = pluginFile.GetPluginInfo(info);
|
||||
if(NS_FAILED(res))
|
||||
continue;
|
||||
// if we don't have mime type -- don't proceed, this is not a plugin
|
||||
if(!info.fMimeTypeArray) {
|
||||
pluginFile.FreePluginInfo(info);
|
||||
continue;
|
||||
}
|
||||
|
||||
pluginTag = new nsPluginTag(&info);
|
||||
pluginFile.FreePluginInfo(info);
|
||||
|
||||
if(pluginTag == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pluginTag->mLibrary = pluginLibrary;
|
||||
pluginTag->mLastModifiedTime = fileModTime;
|
||||
}
|
||||
|
||||
PRBool bAddIt = PR_TRUE;
|
||||
|
||||
|
||||
// check if there are specific plugins we don't want
|
||||
if(checkForUnwantedPlugins)
|
||||
{
|
||||
if(isUnwantedPlugin(pluginTag))
|
||||
if(isUnwantedPlugin(pluginTag)) {
|
||||
bAddIt = PR_FALSE;
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_UNWANTED);
|
||||
|
||||
// Add it to our cached plugins so we can cache the unwantedness of
|
||||
// this plugin when we sync cached plugins to registry
|
||||
pluginTag->mNext = mCachedPlugins;
|
||||
mCachedPlugins = pluginTag;
|
||||
|
||||
// If this plugin wasn't from our cache, we need to sync plugin info
|
||||
// to registry
|
||||
if (!(pluginTag->mFlags & NS_PLUGIN_FLAG_FROMCACHE))
|
||||
mSyncCachedPlugins = PR_TRUE;
|
||||
|
||||
// Clear plugintag so it wont get deleted
|
||||
pluginTag = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// check if we already have this plugin in the list which
|
||||
@@ -4410,9 +4473,16 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsPluginsDir& pluginsDir,
|
||||
|
||||
if(layoutPath)
|
||||
RegisterPluginMimeTypesWithLayout(pluginTag, compManager, layoutPath);
|
||||
|
||||
// Finally see if this was a plugin that was not in cache. If so,
|
||||
// we need to sync our cache
|
||||
if (!(pluginTag->mFlags & NS_PLUGIN_FLAG_FROMCACHE)) {
|
||||
mSyncCachedPlugins = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
delete pluginTag;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@@ -4420,6 +4490,7 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsPluginsDir& pluginsDir,
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#include "nsITimelineService.h"
|
||||
NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
|
||||
{
|
||||
// do not do anything if it is already done
|
||||
@@ -4427,15 +4498,31 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
|
||||
if(mPluginsLoaded)
|
||||
return NS_OK;
|
||||
|
||||
NS_TIMELINE_START_TIMER("LoadPlugins");
|
||||
|
||||
#ifdef CALL_SAFETY_ON
|
||||
// check preferences on whether or not we want to try safe calls to plugins
|
||||
NS_INIT_PLUGIN_SAFE_CALLS;
|
||||
#endif
|
||||
|
||||
// If the create instance failed, then it automatically disables all
|
||||
// our caching functions and we will just end up loading the plugins
|
||||
// on startup.
|
||||
nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
|
||||
nsresult rv;
|
||||
if (registry) {
|
||||
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationRegistry);
|
||||
if (NS_FAILED(rv)) {
|
||||
registry = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Load cached plugins info
|
||||
LoadCachedPluginsInfo(registry);
|
||||
|
||||
// retrieve a path for layout module. Needed for plugin mime types registration
|
||||
nsCOMPtr<nsIFile> path;
|
||||
PRBool isLayoutPath = PR_FALSE;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIComponentManager> compManager = do_GetService(kComponentManagerCID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && compManager)
|
||||
{
|
||||
@@ -4568,88 +4655,84 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
|
||||
ScanPluginsDirectory(pluginsDirJavaJRE, compManager, lpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check the windows registry for extra paths to scan for plugins
|
||||
//
|
||||
// We are going to get this registry key location from the pref:
|
||||
// browser.plugins.registry_plugins_folder_key_location
|
||||
// The key name is "Plugins Folders"
|
||||
//
|
||||
// So, for example, in winprefs.js put in this line:
|
||||
// pref ("browser.plugins.registry_plugins_folder_key_location","Software\\Mozilla\\Common");
|
||||
// Then, in HKEY_LOCAL_MACHINE\Software\Mozilla\Common
|
||||
// Make a string key "Plugins Folder" who's value is a list of paths sperated by semi-colons
|
||||
// Check the windows registry for extra paths to scan for plugins
|
||||
//
|
||||
// We are going to get this registry key location from the pref:
|
||||
// browser.plugins.registry_plugins_folder_key_location
|
||||
// The key name is "Plugins Folders"
|
||||
//
|
||||
// So, for example, in winprefs.js put in this line:
|
||||
// pref ("browser.plugins.registry_plugins_folder_key_location","Software\\Mozilla\\Common");
|
||||
// Then, in HKEY_LOCAL_MACHINE\Software\Mozilla\Common
|
||||
// Make a string key "Plugins Folder" who's value is a list of paths sperated by semi-colons
|
||||
|
||||
char * regkey;
|
||||
rv = theprefs->CopyCharPref(_NS_PREF_COMMON_PLUGIN_REG_KEY_,®key);
|
||||
if (NS_SUCCEEDED(rv) && regkey) {
|
||||
unsigned char valbuf[_MAXKEYVALUE_];
|
||||
char* pluginPath;
|
||||
HKEY newkey;
|
||||
LONG result;
|
||||
DWORD type = REG_SZ;
|
||||
DWORD length = _MAXKEYVALUE_;
|
||||
|
||||
// set up layout path (if not done above)
|
||||
nsCOMPtr<nsIFile> lpath = nsnull;
|
||||
if(isLayoutPath)
|
||||
lpath = path;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
|
||||
if (!prefs) return NS_OK; // if we can't get to the prefs, bail
|
||||
|
||||
char * regkey;
|
||||
rv = prefs->CopyCharPref(_NS_PREF_COMMON_PLUGIN_REG_KEY_,®key);
|
||||
if (!NS_SUCCEEDED(rv) || regkey == nsnull) return NS_OK; //if pref isn't set, bail
|
||||
|
||||
unsigned char valbuf[_MAXKEYVALUE_];
|
||||
char* pluginPath;
|
||||
HKEY newkey;
|
||||
LONG result;
|
||||
DWORD type = REG_SZ;
|
||||
DWORD length = _MAXKEYVALUE_;
|
||||
|
||||
// set up layout path (if not done above)
|
||||
nsCOMPtr<nsIFile> lpath = nsnull;
|
||||
if(isLayoutPath)
|
||||
lpath = path;
|
||||
|
||||
result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, regkey, NULL, KEY_QUERY_VALUE, &newkey );
|
||||
|
||||
if ( ERROR_SUCCESS == result ) {
|
||||
result = RegQueryValueEx( newkey, _NS_COMMON_PLUGIN_KEY_NAME_, nsnull, &type, valbuf, &length );
|
||||
RegCloseKey( newkey );
|
||||
result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, regkey, NULL, KEY_QUERY_VALUE, &newkey );
|
||||
|
||||
if ( ERROR_SUCCESS == result ) {
|
||||
result = RegQueryValueEx( newkey, _NS_COMMON_PLUGIN_KEY_NAME_, nsnull, &type, valbuf, &length );
|
||||
RegCloseKey( newkey );
|
||||
if ( ERROR_SUCCESS == result ) {
|
||||
// tokenize reg key value by semi-colons
|
||||
for ( pluginPath = strtok((char *)&valbuf, ";"); pluginPath; pluginPath = strtok(NULL, ";") ) {
|
||||
nsFileSpec winRegPluginPath (pluginPath);
|
||||
if (winRegPluginPath.Exists()) { // check for validity of path first
|
||||
for ( pluginPath = strtok((char *)&valbuf, ";"); pluginPath; pluginPath = strtok(NULL, ";") ) {
|
||||
nsFileSpec winRegPluginPath (pluginPath);
|
||||
if (winRegPluginPath.Exists()) { // check for validity of path first
|
||||
#ifdef DEBUG
|
||||
printf("found some more plugins at: %s\n", pluginPath);
|
||||
printf("found some more plugins at: %s\n", pluginPath);
|
||||
#endif
|
||||
ScanPluginsDirectory( (nsPluginsDir)winRegPluginPath,
|
||||
compManager,
|
||||
lpath,
|
||||
PR_FALSE); // check for even unwanted plugins
|
||||
}
|
||||
}
|
||||
}
|
||||
ScanPluginsDirectory( (nsPluginsDir)winRegPluginPath, compManager, lpath, PR_FALSE); // check for even unwanted plugins
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free (regkey); // clean up
|
||||
}
|
||||
}
|
||||
free (regkey); // clean up
|
||||
|
||||
#endif // !XP_WIN
|
||||
|
||||
// Update the plugins info cache
|
||||
if (mSyncCachedPlugins) {
|
||||
mSyncCachedPlugins = PR_FALSE;
|
||||
CachePluginsInfo(registry);
|
||||
}
|
||||
|
||||
// No more need for cached plugins. Clear it up.
|
||||
while (mCachedPlugins) {
|
||||
nsPluginTag *next = mCachedPlugins->mNext;
|
||||
delete mCachedPlugins;
|
||||
mCachedPlugins = next;
|
||||
}
|
||||
|
||||
NS_TIMELINE_STOP_TIMER("LoadPlugins");
|
||||
NS_TIMELINE_MARK_TIMER("LoadPlugins");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static nsresult
|
||||
LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
|
||||
nsIRegistry* aRegistry,
|
||||
const char* aCID,
|
||||
nsRegistryKey aPluginKey,
|
||||
nsPluginTag** aResult)
|
||||
cidToDllname(nsIComponentManager* aComponentManager, nsIRegistry* aRegistry,
|
||||
const char *aCID, char **dllName)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// The name, description, MIME types, MIME descriptions, and
|
||||
// supported file extensions will all hang off of the plugin's key
|
||||
// in the registry. Pull these out now.
|
||||
nsXPIDLCString name;
|
||||
aRegistry->GetStringUTF8(aPluginKey, "name", getter_Copies(name));
|
||||
|
||||
nsXPIDLCString description;
|
||||
aRegistry->GetStringUTF8(aPluginKey, "description", getter_Copies(description));
|
||||
|
||||
nsXPIDLCString filename;
|
||||
NS_ENSURE_ARG_POINTER(dllName);
|
||||
|
||||
// To figure out the filename of the plugin, we'll need to get the
|
||||
// plugin's CID, and then navigate through the XPCOM registry to
|
||||
@@ -4657,7 +4740,7 @@ LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
|
||||
nsAutoString path(NS_LITERAL_STRING("software/mozilla/XPCOM/classID/") + NS_ConvertASCIItoUCS2(aCID));
|
||||
|
||||
nsRegistryKey cidKey;
|
||||
rv = aRegistry->GetKey(nsIRegistry::Common, path.get(), &cidKey);
|
||||
nsresult rv = aRegistry->GetKey(nsIRegistry::Common, path.get(), &cidKey);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint8* library;
|
||||
@@ -4670,13 +4753,46 @@ LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
|
||||
getter_AddRefs(file));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
file->GetPath(getter_Copies(filename));
|
||||
file->GetPath(dllName);
|
||||
}
|
||||
|
||||
nsCRT::free(NS_REINTERPRET_CAST(char*, library));
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
LoadXPCOMPlugin(nsIRegistry* aRegistry,
|
||||
const char* aFilename,
|
||||
nsRegistryKey aPluginKey,
|
||||
nsPluginTag** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// The name, description, MIME types, MIME descriptions, and
|
||||
// supported file extensions will all hang off of the plugin's key
|
||||
// in the registry. Pull these out now.
|
||||
nsXPIDLCString name;
|
||||
aRegistry->GetStringUTF8(aPluginKey, kPluginsNameKey, getter_Copies(name));
|
||||
|
||||
nsXPIDLCString description;
|
||||
aRegistry->GetStringUTF8(aPluginKey, kPluginsDescKey, getter_Copies(description));
|
||||
|
||||
nsXPIDLCString filename;
|
||||
nsXPIDLCString fullpath;
|
||||
if (!aFilename) {
|
||||
// Look for a filename key
|
||||
aRegistry->GetStringUTF8(aPluginKey, kPluginsFilenameKey, getter_Copies(filename));
|
||||
aRegistry->GetStringUTF8(aPluginKey, kPluginsFullpathKey, getter_Copies(fullpath));
|
||||
}
|
||||
|
||||
PRInt64 lastmod = LL_ZERO;
|
||||
aRegistry->GetLongLong(aPluginKey, kPluginsModTimeKey, &lastmod);
|
||||
|
||||
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
rv = aRegistry->EnumerateAllSubtrees(aPluginKey, getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@@ -4738,9 +4854,9 @@ LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
|
||||
extensions = newextensions;
|
||||
}
|
||||
|
||||
aRegistry->GetStringUTF8(key, "mimetype", &mimetypes[count]);
|
||||
aRegistry->GetStringUTF8(key, "description", &mimedescriptions[count]);
|
||||
aRegistry->GetStringUTF8(key, "extension", &extensions[count]);
|
||||
aRegistry->GetStringUTF8(key, kPluginsMimeTypeKey, &mimetypes[count]);
|
||||
aRegistry->GetStringUTF8(key, kPluginsMimeDescKey, &mimedescriptions[count]);
|
||||
aRegistry->GetStringUTF8(key, kPluginsMimeExtKey, &extensions[count]);
|
||||
++count;
|
||||
}
|
||||
|
||||
@@ -4749,11 +4865,12 @@ LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
|
||||
nsPluginTag* tag
|
||||
= new nsPluginTag(name.get(),
|
||||
description.get(),
|
||||
filename.get(),
|
||||
aFilename ? aFilename : filename.get(),
|
||||
fullpath.get(),
|
||||
(const char* const*)mimetypes,
|
||||
(const char* const*)mimedescriptions,
|
||||
(const char* const*)extensions,
|
||||
count);
|
||||
count, lastmod);
|
||||
|
||||
if (! tag)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
@@ -4775,6 +4892,42 @@ LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
|
||||
}
|
||||
|
||||
|
||||
static nsresult
|
||||
AddPluginInfoToRegistry(nsIRegistry* registry, nsRegistryKey top,
|
||||
nsPluginTag *tag, const char *keyname)
|
||||
{
|
||||
nsRegistryKey pluginKey;
|
||||
nsresult rv = registry->AddSubtree(top, keyname, &pluginKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Add filename, name and description
|
||||
registry->SetStringUTF8(pluginKey, kPluginsFilenameKey, tag->mFileName);
|
||||
if (tag->mFullPath) {
|
||||
registry->SetStringUTF8(pluginKey, kPluginsFullpathKey, tag->mFullPath);
|
||||
}
|
||||
registry->SetStringUTF8(pluginKey, kPluginsNameKey, tag->mName);
|
||||
registry->SetStringUTF8(pluginKey, kPluginsDescKey, tag->mDescription);
|
||||
registry->SetLongLong(pluginKey, kPluginsModTimeKey, &(tag->mLastModifiedTime));
|
||||
|
||||
// Add in each mimetype this plugin supports
|
||||
for (int i=0; i<tag->mVariants; i++) {
|
||||
char mimetypeKeyName[16];
|
||||
nsRegistryKey mimetypeKey;
|
||||
PR_snprintf(mimetypeKeyName, sizeof (mimetypeKeyName), "mimetype-%d", i);
|
||||
rv = registry->AddSubtree(pluginKey, mimetypeKeyName, &mimetypeKey);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
registry->SetStringUTF8(mimetypeKey, kPluginsMimeTypeKey, tag->mMimeTypeArray[i]);
|
||||
registry->SetStringUTF8(mimetypeKey, kPluginsMimeDescKey, tag->mMimeDescriptionArray[i]);
|
||||
registry->SetStringUTF8(mimetypeKey, kPluginsMimeExtKey, tag->mExtensionsArray[i]);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = registry->RemoveSubtree(top, keyname);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsIFile* aPath)
|
||||
@@ -4795,7 +4948,7 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsIFi
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsRegistryKey pluginsKey;
|
||||
rv = registry->GetSubtree(nsIRegistry::Common, "software/plugins", &pluginsKey);
|
||||
rv = registry->GetSubtree(nsIRegistry::Common, kPluginsRootKey, &pluginsKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// XXX get rid nsIEnumerator someday!
|
||||
@@ -4829,8 +4982,13 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsIFi
|
||||
nsRegistryKey key;
|
||||
node->GetKey(&key);
|
||||
|
||||
nsXPIDLCString filename;
|
||||
rv = cidToDllname(aComponentManager, registry, cid, getter_Copies(filename));
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
nsPluginTag* tag = nsnull;
|
||||
rv = LoadXPCOMPlugin(aComponentManager, registry, cid, key, &tag);
|
||||
rv = LoadXPCOMPlugin(registry, filename, key, &tag);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
@@ -4864,6 +5022,148 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsIFi
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsPluginHostImpl::LoadCachedPluginsInfo(nsIRegistry* registry)
|
||||
{
|
||||
// Loads cached plugin info from registry
|
||||
//
|
||||
// Enumerate through that list now, creating an nsPluginTag for
|
||||
// each.
|
||||
if (! registry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRegistryKey pluginsKey;
|
||||
nsresult rv = registry->GetSubtree(nsIRegistry::Common, kPluginsRootKey, &pluginsKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Make sure we are dealing with the same version number of the plugin info
|
||||
nsXPIDLCString version;
|
||||
rv = registry->GetStringUTF8(pluginsKey, kPluginsVersionKey, getter_Copies(version));
|
||||
if (NS_FAILED(rv) || PL_strcmp(version.get(), kPluginInfoVersion)) {
|
||||
// Version mismatch
|
||||
// Nuke the subtree
|
||||
registry->RemoveSubtree(nsIRegistry::Common, kPluginsRootKey);
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("LoadCachedPluginsInfo : Version %s mismatch - Expected %s. Nuking cached info.\n",
|
||||
version.get(), kPluginInfoVersion));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// XXX get rid nsIEnumerator someday!
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
rv = registry->EnumerateSubtrees(pluginsKey, getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> plugins;
|
||||
rv = NS_NewAdapterEnumerator(getter_AddRefs(plugins), enumerator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for (;;) {
|
||||
PRBool hasMore;
|
||||
plugins->HasMoreElements(&hasMore);
|
||||
if (! hasMore)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsISupports> isupports;
|
||||
plugins->GetNext(getter_AddRefs(isupports));
|
||||
|
||||
nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
|
||||
NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
|
||||
if (! node)
|
||||
continue;
|
||||
|
||||
// Pull out the information for an individual plugin, and link it
|
||||
// in to the mCachedPlugins list.
|
||||
nsRegistryKey key;
|
||||
node->GetKey(&key);
|
||||
|
||||
nsPluginTag* tag = nsnull;
|
||||
rv = LoadXPCOMPlugin(registry, nsnull, key, &tag);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
// Mark plugin as loaded from cache
|
||||
tag->Mark(NS_PLUGIN_FLAG_FROMCACHE);
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName));
|
||||
tag->mNext = mCachedPlugins;
|
||||
mCachedPlugins = tag;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHostImpl::CachePluginsInfo(nsIRegistry* registry)
|
||||
{
|
||||
// Save plugin info from registry
|
||||
|
||||
if (! registry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// We dont want any old plugins that dont exist anymore hanging around
|
||||
// So remove and re-add the root of the plugins info
|
||||
nsresult rv = registry->RemoveSubtree(nsIRegistry::Common, kPluginsRootKey);
|
||||
|
||||
nsRegistryKey pluginsSubtreeKey;
|
||||
rv = registry->AddSubtree(nsIRegistry::Common, kPluginsRootKey, &pluginsSubtreeKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = registry->SetStringUTF8(pluginsSubtreeKey, kPluginsVersionKey, kPluginInfoVersion);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
int count = 0;
|
||||
|
||||
// Store all plugins in the mPlugins list - all plugins currently in use.
|
||||
char pluginKeyName[64];
|
||||
nsPluginTag *tag;
|
||||
for(tag=mPlugins; tag; tag=tag->mNext) {
|
||||
// store each plugin info into the registry
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("CachePluginsInfo : Caching plugininfo in registry for %s\n", tag->mFileName));
|
||||
PR_snprintf(pluginKeyName, sizeof(pluginKeyName), "plugin-%d", ++count);
|
||||
AddPluginInfoToRegistry(registry, pluginsSubtreeKey, tag, pluginKeyName);
|
||||
}
|
||||
|
||||
// Store any unwanted plugins info so that we wont have to load
|
||||
// them again the next time around
|
||||
tag = mCachedPlugins;
|
||||
for(tag=mCachedPlugins; tag; tag=tag->mNext) {
|
||||
// Look for unwanted plugins
|
||||
if (!(tag->mFlags & NS_PLUGIN_FLAG_UNWANTED))
|
||||
continue;
|
||||
|
||||
// store each plugin info into the registry
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("CachePluginsInfo : Caching unwanted plugininfo in registry for %s\n", tag->mFileName));
|
||||
PR_snprintf(pluginKeyName, sizeof(pluginKeyName), "plugin-%d", ++count);
|
||||
AddPluginInfoToRegistry(registry, pluginsSubtreeKey, tag, pluginKeyName);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPluginTag *
|
||||
nsPluginHostImpl::RemoveCachedPluginsInfo(const char *filename)
|
||||
{
|
||||
nsPluginTag **link = &mCachedPlugins;
|
||||
for (nsPluginTag *tag = *link; tag; link = &tag->mNext, tag = *link)
|
||||
{
|
||||
// compare filename or else the mFullPath if it exists. Mac seems to use
|
||||
// mFullPath for fullpath and mFileName for just the leafname of fullpath.
|
||||
// On win and unix, mFullPath is never used and mFileName is contains the
|
||||
// full pathname. All this should move to using nsIFile.
|
||||
if (!PL_strcmp(tag->mFileName, filename) ||
|
||||
(tag->mFullPath && !PL_strcmp(tag->mFullPath, filename)))
|
||||
{
|
||||
// Found it. Remove it from our list
|
||||
*link = tag->mNext;
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/* Called by GetURL and PostURL */
|
||||
NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
|
||||
|
||||
@@ -57,10 +57,7 @@ class nsFileSpec;
|
||||
class nsIComponentManager;
|
||||
class nsIFile;
|
||||
class nsIChannel;
|
||||
|
||||
// this is the name of the directory which will be created
|
||||
// to cache temporary files.
|
||||
static const char *kPluginTmpDirName = "plugtmp";
|
||||
class nsIRegistry;
|
||||
|
||||
/**
|
||||
* A linked-list of plugin information that is used for
|
||||
@@ -77,14 +74,17 @@ public:
|
||||
nsPluginTag(const char* aName,
|
||||
const char* aDescription,
|
||||
const char* aFileName,
|
||||
const char* aFullPath,
|
||||
const char* const* aMimeTypes,
|
||||
const char* const* aMimeDescriptions,
|
||||
const char* const* aExtensions,
|
||||
PRInt32 aVariants);
|
||||
PRInt32 aVariants,
|
||||
PRInt64 aLastModifiedTime = 0);
|
||||
|
||||
~nsPluginTag();
|
||||
|
||||
void TryUnloadPlugin(PRBool aForceShutdown = PR_FALSE);
|
||||
void Mark(PRUint32 mask) { mFlags |= mask; }
|
||||
|
||||
nsPluginTag *mNext;
|
||||
char *mName;
|
||||
@@ -100,6 +100,7 @@ public:
|
||||
PRBool mXPConnected;
|
||||
char *mFileName;
|
||||
char *mFullPath;
|
||||
PRInt64 mLastModifiedTime;
|
||||
};
|
||||
|
||||
struct nsActivePlugin
|
||||
@@ -165,6 +166,8 @@ public:
|
||||
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 //is this plugin enabled?
|
||||
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 //is this a pre-xpcom plugin?
|
||||
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
|
||||
#define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugins
|
||||
|
||||
class nsPluginHostImpl : public nsIPluginManager2,
|
||||
public nsIPluginHost,
|
||||
@@ -440,11 +443,21 @@ private:
|
||||
void AddToUnusedLibraryList(PRLibrary * aLibrary);
|
||||
void CleanUnusedLibraries();
|
||||
|
||||
// Loads all cached plugins info into mCachedPlugins
|
||||
nsresult LoadCachedPluginsInfo(nsIRegistry* registry);
|
||||
// Stores all plugins info into the registry
|
||||
nsresult CachePluginsInfo(nsIRegistry* registry);
|
||||
// Given a filename, returns the plugins info from our cache and removes
|
||||
// it from the cache.
|
||||
nsPluginTag* RemoveCachedPluginsInfo(const char *filename);
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
nsPluginTag *mCachedPlugins;
|
||||
PRBool mPluginsLoaded;
|
||||
PRBool mDontShowBadPluginMessage;
|
||||
PRBool mIsDestroyed;
|
||||
PRBool mSyncCachedPlugins;
|
||||
|
||||
nsActivePluginList mActivePluginList;
|
||||
nsUnusedLibrary *mUnusedLibraries;
|
||||
|
||||
Reference in New Issue
Block a user