Bug 578868: Only load plugin libraries into the main process when absolutely necessary. r=benwa sr=bsmedberg

This commit is contained in:
Josh Aas 2010-08-13 02:42:42 -04:00
Родитель 946ea510ae
Коммит e8f9c53806
14 изменённых файлов: 203 добавлений и 205 удалений

Просмотреть файл

@ -189,7 +189,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

Просмотреть файл

@ -266,8 +266,6 @@ nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
}
#endif
namespace {
#ifdef MOZ_IPC
#ifdef XP_MACOSX
@ -310,8 +308,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;
@ -394,7 +392,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);
}
}
@ -402,8 +400,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,
@ -411,6 +407,10 @@ nsNPAPIPlugin::CreatePlugin(const char* aFilePath, PRLibrary* aLibrary,
{
*aResult = nsnull;
if (!aFilePath || !aLibrary) {
return NS_ERROR_FAILURE;
}
CheckClassInitialized();
nsRefPtr<nsNPAPIPlugin> plugin = new nsNPAPIPlugin();
@ -432,14 +432,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;
@ -523,29 +515,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,24 @@ 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);
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
pLibrary = *outLibrary;
if (!pLibrary)
DisplayPR_LoadLibraryErrorMessage(libSpec.value.pathname);
}
#else
pLibrary = outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
*outLibrary = PR_LoadLibraryWithFlags(libSpec, 0);
pLibrary = *outLibrary;
#endif // MOZ_WIDGET_GTK2
#ifdef NS_DEBUG
@ -329,53 +333,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;