зеркало из https://github.com/mozilla/gecko-dev.git
Bug 578868: Only load plugin libraries into the main process when absolutely necessary. r=benwa sr=bsmedberg a=blocking-b5+
This commit is contained in:
Родитель
56e3e3cd66
Коммит
7c8d5f47f2
|
@ -193,7 +193,7 @@ PluginModuleChild::Init(const std::string& aPluginFilename,
|
|||
|
||||
nsPluginFile lib(pluginIfile);
|
||||
|
||||
nsresult rv = lib.LoadPlugin(mLibrary);
|
||||
nsresult rv = lib.LoadPlugin(&mLibrary);
|
||||
NS_ASSERTION(NS_OK == rv, "trouble with mPluginFile");
|
||||
NS_ASSERTION(mLibrary, "couldn't open shared object");
|
||||
|
||||
|
|
|
@ -267,12 +267,17 @@ typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */
|
|||
unsigned long dwProductVersionMS;
|
||||
unsigned long dwProductVersionLS;
|
||||
} NPPluginData;
|
||||
NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData);
|
||||
typedef NPError (*NP_GetPluginDataFunc)(NPPluginData*);
|
||||
NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData);
|
||||
#endif
|
||||
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||
NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||
NPError OSCALL NP_Shutdown();
|
||||
char* NP_GetMIMEDescription();
|
||||
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||
NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||
typedef NPError (*NP_ShutdownFunc)();
|
||||
NPError OSCALL NP_Shutdown();
|
||||
typedef char* (*NP_GetMIMEDescriptionFunc)();
|
||||
char* NP_GetMIMEDescription();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -286,15 +291,22 @@ char* NP_GetMIMEDescription();
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef char* (*NP_GetPluginVersionFunc)();
|
||||
NP_EXPORT(char*) NP_GetPluginVersion();
|
||||
typedef char* (*NP_GetMIMEDescriptionFunc)();
|
||||
NP_EXPORT(char*) NP_GetMIMEDescription();
|
||||
#ifdef XP_MACOSX
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||
#else
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
|
||||
#endif
|
||||
typedef NPError (*NP_ShutdownFunc)();
|
||||
NP_EXPORT(NPError) NP_Shutdown();
|
||||
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
|
||||
NP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
interface nsIPluginInstance;
|
||||
|
||||
[uuid(843D6092-2BB0-4A21-8827-0510A52CA795)]
|
||||
[uuid(94C32FEA-5C50-49D3-9D3D-9047CD342777)]
|
||||
interface nsIPlugin : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -66,29 +66,4 @@ interface nsIPlugin : nsISupports
|
|||
* @result - NS_OK if this operation was successful
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
* Returns the MIME description for the plugin. The MIME description
|
||||
* is a colon-separated string containg the plugin MIME type, plugin
|
||||
* data file extension, and plugin name, e.g.:
|
||||
*
|
||||
* "application/x-simple-plugin:smp:Simple Sample Plug-in"
|
||||
*
|
||||
* (Corresponds to NPP_GetMIMEDescription.)
|
||||
*
|
||||
* @param aMIMEDescription - the resulting MIME description
|
||||
* @result - NS_OK if this operation was successful
|
||||
*/
|
||||
void getMIMEDescription(out constCharPtr aMIMEDescription);
|
||||
|
||||
/**
|
||||
* Returns the value of a variable associated with the plugin.
|
||||
*
|
||||
* (Corresponds to NPP_GetValue.)
|
||||
*
|
||||
* @param aVariable - the plugin variable to get
|
||||
* @param aValue - the address of where to store the resulting value
|
||||
* @result - NS_OK if this operation was successful
|
||||
*/
|
||||
void getValue(in NPPVariable aVariable, in voidPtr aValue);
|
||||
};
|
||||
|
|
|
@ -137,17 +137,19 @@ nsresult
|
|||
PluginPRLibrary::NP_GetValue(void *future, NPPVariable aVariable,
|
||||
void *aValue, NPError* error)
|
||||
{
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
if (mNP_GetValue) {
|
||||
*error = mNP_GetValue(future, aVariable, aValue);
|
||||
} else {
|
||||
NP_GetValueFunc pfNP_GetValue = (NP_GetValueFunc)
|
||||
PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
|
||||
NP_GetValueFunc pfNP_GetValue = (NP_GetValueFunc)PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
|
||||
if (!pfNP_GetValue)
|
||||
return NS_ERROR_FAILURE;
|
||||
*error = pfNP_GetValue(future, aVariable, aValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
|
||||
|
|
|
@ -41,23 +41,12 @@
|
|||
|
||||
#include "mozilla/PluginLibrary.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "npfunctions.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class PluginPRLibrary : public PluginLibrary
|
||||
{
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
||||
#else
|
||||
typedef NPError (OSCALL *NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||
#endif
|
||||
typedef NPError (OSCALL *NP_ShutdownFunc)();
|
||||
typedef char* (*NP_GetMIMEDescriptionFunc)();
|
||||
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void*);
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
|
||||
typedef NPError (OSCALL *NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||
#endif
|
||||
|
||||
public:
|
||||
PluginPRLibrary(const char* aFilePath, PRLibrary* aLibrary) :
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
|
@ -67,7 +56,9 @@ public:
|
|||
#endif
|
||||
mNP_Shutdown(nsnull),
|
||||
mNP_GetMIMEDescription(nsnull),
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mNP_GetValue(nsnull),
|
||||
#endif
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
|
||||
mNP_GetEntryPoints(nsnull),
|
||||
#endif
|
||||
|
@ -103,9 +94,9 @@ public:
|
|||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
mNP_GetValue = (NP_GetValueFunc)
|
||||
PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
|
||||
#ifndef XP_MACOSX
|
||||
if (!mNP_GetValue)
|
||||
return false;
|
||||
#endif
|
||||
|
@ -146,7 +137,9 @@ private:
|
|||
NP_InitializeFunc mNP_Initialize;
|
||||
NP_ShutdownFunc mNP_Shutdown;
|
||||
NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
NP_GetValueFunc mNP_GetValue;
|
||||
#endif
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
|
||||
NP_GetEntryPointsFunc mNP_GetEntryPoints;
|
||||
#endif
|
||||
|
|
|
@ -267,8 +267,6 @@ nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
|
|||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
@ -311,8 +309,8 @@ static PRBool GMA9XXGraphics()
|
|||
}
|
||||
#endif
|
||||
|
||||
inline PRBool
|
||||
RunPluginOOP(const char* aFilePath, const nsPluginTag *aPluginTag)
|
||||
PRBool
|
||||
nsNPAPIPlugin::RunPluginOOP(const char* aFilePath, const nsPluginTag *aPluginTag)
|
||||
{
|
||||
if (PR_GetEnv("MOZ_DISABLE_OOP_PLUGINS")) {
|
||||
return PR_FALSE;
|
||||
|
@ -431,7 +429,7 @@ GetNewPluginLibrary(const char* aFilePath,
|
|||
nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
|
||||
nsPluginTag* tag = host->FindTagForLibrary(aLibrary);
|
||||
if (tag) {
|
||||
if (aFilePath && RunPluginOOP(aFilePath, tag)) {
|
||||
if (aFilePath && nsNPAPIPlugin::RunPluginOOP(aFilePath, tag)) {
|
||||
return PluginModuleParent::LoadModule(aFilePath);
|
||||
}
|
||||
}
|
||||
|
@ -439,8 +437,6 @@ GetNewPluginLibrary(const char* aFilePath,
|
|||
return new PluginPRLibrary(aFilePath, aLibrary);
|
||||
}
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
// Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
|
||||
nsresult
|
||||
nsNPAPIPlugin::CreatePlugin(const char* aFilePath, PRLibrary* aLibrary,
|
||||
|
@ -448,6 +444,10 @@ nsNPAPIPlugin::CreatePlugin(const char* aFilePath, PRLibrary* aLibrary,
|
|||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
if (!aFilePath || !aLibrary) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CheckClassInitialized();
|
||||
|
||||
nsRefPtr<nsNPAPIPlugin> plugin = new nsNPAPIPlugin();
|
||||
|
@ -469,14 +469,6 @@ nsNPAPIPlugin::CreatePlugin(const char* aFilePath, PRLibrary* aLibrary,
|
|||
plugin->mLibrary = pluginLib;
|
||||
pluginLib->SetPlugin(plugin);
|
||||
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
// Do not initialize if the file path is NULL.
|
||||
if (!aFilePath) {
|
||||
*aResult = plugin.forget().get();
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
NPError pluginCallError;
|
||||
nsresult rv;
|
||||
|
||||
|
@ -560,29 +552,6 @@ nsNPAPIPlugin::Shutdown()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPlugin::GetMIMEDescription(const char* *resultingDesc)
|
||||
{
|
||||
nsresult gmdResult = mLibrary->NP_GetMIMEDescription(resultingDesc);
|
||||
if (gmdResult != NS_OK) {
|
||||
return gmdResult;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPlugin::GetValue(NPPVariable variable, void *value)
|
||||
{
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsNPAPIPlugin::GetValue called: this=%p, variable=%d\n", this, variable));
|
||||
|
||||
NPError gvError;
|
||||
mLibrary->NP_GetValue(nsnull, variable, value, &gvError);
|
||||
|
||||
return gvError;
|
||||
}
|
||||
|
||||
// Create a new NPP GET or POST (given in the type argument) url
|
||||
// stream that may have a notify callback
|
||||
NPError
|
||||
|
|
|
@ -104,6 +104,8 @@ public:
|
|||
// minidump was written.
|
||||
void PluginCrashed(const nsAString& pluginDumpID,
|
||||
const nsAString& browserDumpID);
|
||||
|
||||
static PRBool RunPluginOOP(const char* aFilePath, const nsPluginTag *aPluginTag);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
|
|
@ -301,6 +301,22 @@ NS_IMETHODIMP nsPluginDocReframeEvent::Run() {
|
|||
return mDocs->Clear();
|
||||
}
|
||||
|
||||
static PRBool UnloadPluginsASAP()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool unloadPluginsASAP = PR_FALSE;
|
||||
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return unloadPluginsASAP;
|
||||
}
|
||||
}
|
||||
|
||||
NS_WARNING("Unable to retrieve pref: plugins.unloadASAP");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// helper struct for asynchronous handling of plugin unloading
|
||||
class nsPluginUnloadEvent : public nsRunnable {
|
||||
public:
|
||||
|
@ -417,9 +433,6 @@ PRBool nsPluginHost::IsRunningPlugin(nsPluginTag * plugin)
|
|||
if (!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!plugin->mLibrary)
|
||||
return PR_FALSE;
|
||||
|
||||
for (int i = 0; i < plugin->mVariants; i++) {
|
||||
nsNPAPIPluginInstance *instance = FindInstance(plugin->mMimeTypeArray[i]);
|
||||
if (instance && instance->IsRunning())
|
||||
|
@ -867,16 +880,8 @@ void nsPluginHost::OnPluginInstanceDestroyed(nsPluginTag* aPluginTag)
|
|||
}
|
||||
}
|
||||
|
||||
if (!hasInstance) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
PRBool unloadPluginsASAP = PR_FALSE;
|
||||
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
||||
if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
|
||||
aPluginTag->TryUnloadPlugin();
|
||||
if (!hasInstance && UnloadPluginsASAP()) {
|
||||
aPluginTag->TryUnloadPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1270,10 +1275,8 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|||
PR_LogFlush();
|
||||
#endif
|
||||
|
||||
|
||||
nsresult result = NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIPluginInstance> instance;
|
||||
nsCOMPtr<nsIPlugin> plugin;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
const char* mimetype = nsnull;
|
||||
|
||||
// if don't have a mimetype or no plugin can handle this mimetype
|
||||
|
@ -1300,8 +1303,10 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|||
|
||||
NS_ASSERTION(pluginTag, "Must have plugin tag here!");
|
||||
|
||||
nsCOMPtr<nsIPlugin> plugin;
|
||||
GetPlugin(mimetype, getter_AddRefs(plugin));
|
||||
|
||||
nsCOMPtr<nsIPluginInstance> instance;
|
||||
if (plugin) {
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
static BOOL firstJavaPlugin = FALSE;
|
||||
|
@ -1311,17 +1316,18 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|||
DWORD dw = GetCurrentDirectoryW(_MAX_PATH, origDir);
|
||||
NS_ASSERTION(dw <= _MAX_PATH, "Failed to obtain the current directory, which may lead to incorrect class loading");
|
||||
nsCOMPtr<nsIFile> binDirectory;
|
||||
result = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
getter_AddRefs(binDirectory));
|
||||
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
||||
getter_AddRefs(binDirectory));
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString path;
|
||||
binDirectory->GetPath(path);
|
||||
restoreOrigDir = SetCurrentDirectoryW(path.get());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
result = plugin->CreatePluginInstance(getter_AddRefs(instance));
|
||||
|
||||
rv = plugin->CreatePluginInstance(getter_AddRefs(instance));
|
||||
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
if (!firstJavaPlugin && restoreOrigDir) {
|
||||
|
@ -1332,8 +1338,8 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|||
#endif
|
||||
}
|
||||
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// it is adreffed here
|
||||
aOwner->SetInstance(instance);
|
||||
|
@ -1341,10 +1347,10 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|||
// this should not addref the instance or owner
|
||||
// except in some cases not Java, see bug 140931
|
||||
// our COM pointer will free the peer
|
||||
result = instance->Initialize(aOwner, mimetype);
|
||||
if (NS_FAILED(result)) {
|
||||
rv = instance->Initialize(aOwner, mimetype);
|
||||
if (NS_FAILED(rv)) {
|
||||
aOwner->SetInstance(nsnull);
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mInstances.AppendElement(static_cast<nsNPAPIPluginInstance*>(instance.get()));
|
||||
|
@ -1356,12 +1362,12 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|||
|
||||
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
||||
("nsPluginHost::TrySetupPluginInstance Finished mime=%s, rv=%d, owner=%p, url=%s\n",
|
||||
aMimeType, result, aOwner, urlSpec2.get()));
|
||||
aMimeType, rv, aOwner, urlSpec2.get()));
|
||||
|
||||
PR_LogFlush();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1693,9 +1699,29 @@ static nsresult ConvertToNative(nsIUnicodeEncoder *aEncoder,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult CreateNPAPIPlugin(const nsPluginTag *aPluginTag,
|
||||
static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag,
|
||||
nsIPlugin **aOutNPAPIPlugin)
|
||||
{
|
||||
// If this is an in-process plugin we'll need to load it here if we haven't already.
|
||||
#ifdef MOZ_IPC
|
||||
if (!aPluginTag->mLibrary &&
|
||||
!nsNPAPIPlugin::RunPluginOOP(aPluginTag->mFileName.get(), aPluginTag)) {
|
||||
#else
|
||||
if (!aPluginTag->mLibrary) {
|
||||
#endif
|
||||
if (aPluginTag->mFullPath.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
file->InitWithPath(NS_ConvertUTF8toUTF16(aPluginTag->mFullPath));
|
||||
nsPluginFile pluginFile(file);
|
||||
PRLibrary* pluginLibrary = NULL;
|
||||
|
||||
if (NS_FAILED(pluginFile.LoadPlugin(&pluginLibrary)) || !pluginLibrary)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
aPluginTag->mLibrary = pluginLibrary;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsIPlatformCharset> pcs =
|
||||
do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
||||
|
@ -1766,28 +1792,12 @@ NS_IMETHODIMP nsPluginHost::GetPlugin(const char *aMimeType, nsIPlugin** aPlugin
|
|||
printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName.get());
|
||||
#endif
|
||||
|
||||
if (!pluginTag->mLibrary) { // if we haven't done this yet
|
||||
if (pluginTag->mFullPath.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
file->InitWithPath(NS_ConvertUTF8toUTF16(pluginTag->mFullPath));
|
||||
nsPluginFile pluginFile(file);
|
||||
PRLibrary* pluginLibrary = NULL;
|
||||
|
||||
if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == NULL)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
pluginTag->mLibrary = pluginLibrary;
|
||||
}
|
||||
|
||||
// Create a plugin object if necessary
|
||||
nsCOMPtr<nsIPlugin> plugin = pluginTag->mEntryPoint;
|
||||
if (!plugin) {
|
||||
// Now lets try to get the entry point from an NPAPI plugin
|
||||
rv = CreateNPAPIPlugin(pluginTag, getter_AddRefs(plugin));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_ASSERTION(plugin, "CreateNPAPIPlugin succeeded without setting 'plugin'");
|
||||
pluginTag->mEntryPoint = plugin;
|
||||
}
|
||||
|
||||
|
@ -2041,18 +2051,12 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile * pluginsDir,
|
|||
// if it is not found in cache info list or has been changed, create a new one
|
||||
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.
|
||||
PRLibrary *library = nsnull;
|
||||
nsPluginInfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
nsresult res = pluginFile.GetPluginInfo(info);
|
||||
nsresult res = pluginFile.GetPluginInfo(info, &library);
|
||||
// if we don't have mime type don't proceed, this is not a plugin
|
||||
if (NS_FAILED(res) || !info.fMimeTypeArray) {
|
||||
pluginFile.FreePluginInfo(info);
|
||||
|
@ -2061,11 +2065,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile * pluginsDir,
|
|||
|
||||
pluginTag = new nsPluginTag(&info);
|
||||
pluginFile.FreePluginInfo(info);
|
||||
|
||||
if (pluginTag == nsnull)
|
||||
if (!pluginTag)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pluginTag->mLibrary = pluginLibrary;
|
||||
pluginTag->mLibrary = library;
|
||||
pluginTag->mLastModifiedTime = fileModTime;
|
||||
|
||||
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
|
||||
|
@ -2100,6 +2103,13 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile * pluginsDir,
|
|||
pluginTag->mNext = mCachedPlugins;
|
||||
mCachedPlugins = pluginTag;
|
||||
}
|
||||
|
||||
// Plugin unloading is tag-based. If we created a new tag and loaded
|
||||
// the library in the process then we want to attempt to unload it here.
|
||||
// Only do this if the pref is set for aggressive unloading.
|
||||
if (UnloadPluginsASAP()) {
|
||||
pluginTag->TryUnloadPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
// set the flag that we want to add this plugin to the list for now
|
||||
|
|
|
@ -93,12 +93,13 @@ public:
|
|||
* Loads the plugin into memory using NSPR's shared-library loading
|
||||
* mechanism. Handles platform differences in loading shared libraries.
|
||||
*/
|
||||
nsresult LoadPlugin(PRLibrary* &outLibrary);
|
||||
nsresult LoadPlugin(PRLibrary **outLibrary);
|
||||
|
||||
/**
|
||||
* Obtains all of the information currently available for this plugin.
|
||||
* Has a library outparam which will be non-null if a library load was required.
|
||||
*/
|
||||
nsresult GetPluginInfo(nsPluginInfo &outPluginInfo);
|
||||
nsresult GetPluginInfo(nsPluginInfo &outPluginInfo, PRLibrary **outLibrary);
|
||||
|
||||
/**
|
||||
* Should be called after GetPluginInfo to free all allocated stuff
|
||||
|
|
|
@ -139,14 +139,14 @@ nsPluginFile::~nsPluginFile()
|
|||
* Loads the plugin into memory using NSPR's shared-library loading
|
||||
* mechanism. Handles platform differences in loading shared libraries.
|
||||
*/
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
{
|
||||
nsCAutoString path;
|
||||
nsresult rv = mPlugin->GetNativePath(path);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
pLibrary = outLibrary = PR_LoadLibrary(path.get());
|
||||
pLibrary = *outLibrary = PR_LoadLibrary(path.get());
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
printf("LoadPlugin() %s returned %lx\n",path,(unsigned long)pLibrary);
|
||||
|
@ -161,8 +161,10 @@ typedef char* (*BeOS_Plugin_GetMIMEDescription)();
|
|||
/**
|
||||
* Obtains all of the information currently available for this plugin.
|
||||
*/
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
{
|
||||
*outLibrary = nsnull;
|
||||
|
||||
info.fVersion = nsnull;
|
||||
|
||||
nsCAutoString fullPath;
|
||||
|
|
|
@ -220,7 +220,7 @@ nsPluginFile::nsPluginFile(nsIFile *spec)
|
|||
|
||||
nsPluginFile::~nsPluginFile() {}
|
||||
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
{
|
||||
if (!mPlugin)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -261,9 +261,9 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
|||
const char *executablePath = bundlePath.get();
|
||||
#endif
|
||||
|
||||
outLibrary = PR_LoadLibrary(executablePath);
|
||||
pLibrary = outLibrary;
|
||||
if (!outLibrary) {
|
||||
*outLibrary = PR_LoadLibrary(executablePath);
|
||||
pLibrary = *outLibrary;
|
||||
if (!pLibrary) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
@ -350,17 +350,17 @@ private:
|
|||
/**
|
||||
* Obtains all of the information currently available for this plugin.
|
||||
*/
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
{
|
||||
*outLibrary = nsnull;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// clear out the info, except for the first field.
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
// First open up resource we can use to get plugin info.
|
||||
|
||||
#ifndef __LP64__
|
||||
// Try to open a resource fork.
|
||||
// Try to open a resource fork in case we have to use it.
|
||||
nsAutoCloseResourceObject resourceObject(mPlugin);
|
||||
bool resourceOpened = resourceObject.ResourceOpened();
|
||||
#endif
|
||||
|
@ -428,7 +428,7 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
|
|||
ParsePlistPluginInfo(info, bundle);
|
||||
::CFRelease(bundle);
|
||||
if (info.fVariantCount > 0)
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// It's possible that our plugin has 2 entry points that'll give us mime type
|
||||
|
@ -436,6 +436,11 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
|
|||
// change mime info in the resource fork. We need to use this info instead of
|
||||
// the resource. See bug 113464.
|
||||
|
||||
// Sadly we have to load the library for this to work.
|
||||
rv = LoadPlugin(outLibrary);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Try to get data from NP_GetMIMEDescription
|
||||
if (pLibrary) {
|
||||
NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME);
|
||||
|
|
|
@ -199,7 +199,7 @@ nsPluginFile::~nsPluginFile()
|
|||
{}
|
||||
|
||||
// Loads the plugin into memory using NSPR's shared-library loading
|
||||
nsresult nsPluginFile::LoadPlugin( PRLibrary *&outLibrary)
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
{
|
||||
if (!mPlugin)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -207,13 +207,15 @@ nsresult nsPluginFile::LoadPlugin( PRLibrary *&outLibrary)
|
|||
nsCAutoString temp;
|
||||
mPlugin->GetNativePath(temp);
|
||||
|
||||
outLibrary = PR_LoadLibrary(temp.get());
|
||||
return outLibrary == nsnull ? NS_ERROR_FAILURE : NS_OK;
|
||||
*outLibrary = PR_LoadLibrary(temp.get());
|
||||
return *outLibrary == nsnull ? NS_ERROR_FAILURE : NS_OK;
|
||||
}
|
||||
|
||||
// Obtains all of the information currently available for this plugin.
|
||||
nsresult nsPluginFile::GetPluginInfo( nsPluginInfo &info)
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo &info, PRLibrary **outLibrary)
|
||||
{
|
||||
*outLibrary = nsnull;
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
HMODULE hPlug = 0; // Need a HMODULE to query resource statements
|
||||
char failure[ CCHMAXPATH] = "";
|
||||
|
|
|
@ -272,7 +272,7 @@ nsPluginFile::~nsPluginFile()
|
|||
{
|
||||
}
|
||||
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
{
|
||||
PRLibSpec libSpec;
|
||||
libSpec.type = PR_LibSpec_Pathname;
|
||||
|
@ -305,20 +305,26 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
|||
|
||||
#if defined(SOLARIS) || defined(HPUX)
|
||||
// Acrobat/libXm: Lazy resolving might cause crash later (bug 211587)
|
||||
pLibrary = outLibrary = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW);
|
||||
*outLibrary = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW);
|
||||
pLibrary = *outLibrary;
|
||||
#else
|
||||
// Some dlopen() doesn't recover from a failed PR_LD_NOW (bug 223744)
|
||||
pLibrary = outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
|
||||
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
|
||||
pLibrary = *outLibrary;
|
||||
#endif
|
||||
if (!pLibrary) {
|
||||
LoadExtraSharedLibs();
|
||||
// try reload plugin once more
|
||||
pLibrary = outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
|
||||
if (!pLibrary)
|
||||
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
|
||||
pLibrary = *outLibrary;
|
||||
if (!pLibrary) {
|
||||
DisplayPR_LoadLibraryErrorMessage(libSpec.value.pathname);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
pLibrary = outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
|
||||
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
|
||||
pLibrary = *outLibrary;
|
||||
#endif // MOZ_WIDGET_GTK2
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -329,53 +335,72 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
{
|
||||
*outLibrary = nsnull;
|
||||
|
||||
info.fVersion = nsnull;
|
||||
|
||||
// Passing NULL for a file path will prevent a call to NP_Initialize.
|
||||
nsCOMPtr<nsIPlugin> plugin;
|
||||
nsresult rv = nsNPAPIPlugin::CreatePlugin(NULL, pLibrary, getter_AddRefs(plugin));
|
||||
// Sadly we have to load the library for this to work.
|
||||
nsresult rv = LoadPlugin(outLibrary);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
return rv;
|
||||
|
||||
const char* (*npGetPluginVersion)() =
|
||||
(const char* (*)()) PR_FindFunctionSymbol(pLibrary, "NP_GetPluginVersion");
|
||||
if (npGetPluginVersion) {
|
||||
info.fVersion = PL_strdup(npGetPluginVersion());
|
||||
}
|
||||
|
||||
if (plugin) {
|
||||
const char* (*npGetPluginVersion)() =
|
||||
(const char* (*)()) PR_FindFunctionSymbol(pLibrary, "NP_GetPluginVersion");
|
||||
if (npGetPluginVersion)
|
||||
info.fVersion = PL_strdup(npGetPluginVersion());
|
||||
const char* (*npGetMIMEDescription)() =
|
||||
(const char* (*)()) PR_FindFunctionSymbol(pLibrary, "NP_GetMIMEDescription");
|
||||
if (!npGetMIMEDescription) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const char *mimedescr = NULL;
|
||||
plugin->GetMIMEDescription(&mimedescr);
|
||||
#ifdef NS_DEBUG
|
||||
printf("GetMIMEDescription() returned \"%s\"\n", mimedescr);
|
||||
#endif
|
||||
if (NS_FAILED(rv = ParsePluginMimeDescription(mimedescr, info)))
|
||||
return rv;
|
||||
const char* mimedescr = npGetMIMEDescription();
|
||||
if (!mimedescr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCAutoString path;
|
||||
if (NS_FAILED(rv = mPlugin->GetNativePath(path)))
|
||||
return rv;
|
||||
info.fFullPath = PL_strdup(path.get());
|
||||
rv = ParsePluginMimeDescription(mimedescr, info);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCAutoString fileName;
|
||||
if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName)))
|
||||
return rv;
|
||||
info.fFileName = PL_strdup(fileName.get());
|
||||
nsCAutoString path;
|
||||
if (NS_FAILED(rv = mPlugin->GetNativePath(path)))
|
||||
return rv;
|
||||
info.fFullPath = PL_strdup(path.get());
|
||||
|
||||
const char *name = NULL;
|
||||
plugin->GetValue(NPPVpluginNameString, &name);
|
||||
if (name)
|
||||
info.fName = PL_strdup(name);
|
||||
else
|
||||
info.fName = PL_strdup(fileName.get());
|
||||
nsCAutoString fileName;
|
||||
if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName)))
|
||||
return rv;
|
||||
info.fFileName = PL_strdup(fileName.get());
|
||||
|
||||
const char *description = NULL;
|
||||
plugin->GetValue(NPPVpluginDescriptionString, &description);
|
||||
if (!description)
|
||||
description = "";
|
||||
NP_GetValueFunc npGetValue = (NP_GetValueFunc)PR_FindFunctionSymbol(pLibrary, "NP_GetValue");
|
||||
if (!npGetValue) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const char *name = NULL;
|
||||
NPError nperr = npGetValue(NULL, NPPVpluginNameString, &name);
|
||||
if (name) {
|
||||
info.fName = PL_strdup(name);
|
||||
}
|
||||
else {
|
||||
info.fName = PL_strdup(fileName.get());
|
||||
}
|
||||
|
||||
const char *description = NULL;
|
||||
nperr = npGetValue(NULL, NPPVpluginDescriptionString, &description);
|
||||
if (description) {
|
||||
info.fDescription = PL_strdup(description);
|
||||
}
|
||||
else {
|
||||
info.fDescription = "";
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ nsPluginFile::~nsPluginFile()
|
|||
* Loads the plugin into memory using NSPR's shared-library loading
|
||||
* mechanism. Handles platform differences in loading shared libraries.
|
||||
*/
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
||||
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> plugin = do_QueryInterface(mPlugin);
|
||||
|
||||
|
@ -287,9 +287,9 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
|||
}
|
||||
#endif
|
||||
|
||||
nsresult rv = plugin->Load(&outLibrary);
|
||||
nsresult rv = plugin->Load(outLibrary);
|
||||
if (NS_FAILED(rv))
|
||||
outLibrary = NULL;
|
||||
*outLibrary = NULL;
|
||||
|
||||
#ifndef WINCE
|
||||
if (restoreOrigDir) {
|
||||
|
@ -304,8 +304,10 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
|
|||
/**
|
||||
* Obtains all of the information currently available for this plugin.
|
||||
*/
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
|
||||
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
{
|
||||
*outLibrary = nsnull;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
DWORD zerome, versionsize;
|
||||
WCHAR* verbuf = nsnull;
|
||||
|
|
Загрузка…
Ссылка в новой задаче