summaryrefslogtreecommitdiffstats
path: root/webkit/glue
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-12 19:43:44 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-12 19:43:44 +0000
commitb734450b86e9d6bd7a07b381c119ca91803ae46b (patch)
tree5099af8aa485c96af0c487e434bca5a0212f424e /webkit/glue
parent64a02b8056c86576428022859baadbb9a7b929f1 (diff)
downloadchromium_src-b734450b86e9d6bd7a07b381c119ca91803ae46b.zip
chromium_src-b734450b86e9d6bd7a07b381c119ca91803ae46b.tar.gz
chromium_src-b734450b86e9d6bd7a07b381c119ca91803ae46b.tar.bz2
Get rid of lowercasing plugin filenames in order to determine if two paths point to the same plugin. Check plugin versions and load the latest version if multiple versions are found.I've also refactored and cleaned PluginList so that it doesn't depend on PluginLib, which only made sense a long time ago when plugins were loaded in process. Now PluginLib will only be loaded in the plugin process (and not in the browser process as well).
Review URL: http://codereview.chromium.org/17451 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7888 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r--webkit/glue/chromium_bridge_impl.cc4
-rw-r--r--webkit/glue/plugins/plugin_host.cc2
-rw-r--r--webkit/glue/plugins/plugin_lib.cc197
-rw-r--r--webkit/glue/plugins/plugin_lib.h56
-rw-r--r--webkit/glue/plugins/plugin_list.cc232
-rw-r--r--webkit/glue/plugins/plugin_list.h71
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc14
-rw-r--r--webkit/glue/webplugin.h7
8 files changed, 294 insertions, 289 deletions
diff --git a/webkit/glue/chromium_bridge_impl.cc b/webkit/glue/chromium_bridge_impl.cc
index 4e29dfc..fe18543 100644
--- a/webkit/glue/chromium_bridge_impl.cc
+++ b/webkit/glue/chromium_bridge_impl.cc
@@ -325,9 +325,9 @@ bool ChromiumBridge::plugins(bool refresh, Vector<PluginInfo*>* results) {
rv->desc = webkit_glue::StdWStringToString(plugin.desc);
rv->file =
#if defined(OS_WIN)
- webkit_glue::StdWStringToString(plugin.file.BaseName().value());
+ webkit_glue::StdWStringToString(plugin.path.BaseName().value());
#elif defined(OS_POSIX)
- webkit_glue::StdStringToString(plugin.file.BaseName().value());
+ webkit_glue::StdStringToString(plugin.path.BaseName().value());
#endif
for (size_t j = 0; j < plugin.mime_types.size(); ++ j) {
MimeClassInfo* new_mime = new MimeClassInfo();
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index 1181caa..8ef80da 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -759,7 +759,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) {
// to worry about future standard change that may conflict with the
// variable definition.
scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id);
- if (plugin->plugin_lib()->plugin_info().file.value() ==
+ if (plugin->plugin_lib()->plugin_info().path.value() ==
kDefaultPluginLibraryName) {
plugin->webplugin()->OnMissingPluginStatus(
variable - default_plugin::kMissingPluginStatusStart);
diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc
index e2c0f59..546c025 100644
--- a/webkit/glue/plugins/plugin_lib.cc
+++ b/webkit/glue/plugins/plugin_lib.cc
@@ -15,7 +15,6 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/task.h"
-#include "net/base/mime_util.h"
#include "webkit/activex_shim/npp_impl.h"
#include "webkit/default_plugin/plugin_main.h"
#include "webkit/glue/glue_util.h"
@@ -32,29 +31,10 @@ namespace NPAPI
const char kPluginLibrariesLoadedCounter[] = "PluginLibrariesLoaded";
const char kPluginInstancesActiveCounter[] = "PluginInstancesActive";
-PluginLib::PluginMap* PluginLib::loaded_libs_;
-
-PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
- // For Windows we have a bit of a problem in that we might have the same path
- // cased differently for two different plugin load paths. Therefore we do a
- // quick lowercase for canonicalization's sake. WARNING: If you clone this
- // file for other platforms, remove this lowercasing. This is *wrong* for
- // other platforms (and arguably the wrong way to do it for Windows too, but
- // let's not get into that here).
- FilePath filename_lc(StringToLowerASCII(filename.value()));
-
- // We can only have one PluginLib object per plugin as it controls the per
- // instance function calls (i.e. NP_Initialize and NP_Shutdown). So we keep
- // a (non-ref counted) map of PluginLib objects.
- if (!loaded_libs_)
- loaded_libs_ = new PluginMap();
-
- PluginMap::const_iterator iter = loaded_libs_->find(filename_lc);
- if (iter != loaded_libs_->end())
- return iter->second;
-
- static const InternalPluginInfo activex_shim_info_generic = {
+static const InternalPluginInfo g_internal_plugins[] = {
+ {
{kActiveXShimFileName,
+ kActiveXShimFileName,
L"ActiveX Plug-in",
L"ActiveX Plug-in provides a shim to support ActiveX controls",
L"1, 0, 0, 1",
@@ -65,11 +45,11 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
activex_shim::ActiveX_Shim_NP_GetEntryPoints,
activex_shim::ActiveX_Shim_NP_Initialize,
activex_shim::ActiveX_Shim_NP_Shutdown
- };
-
- static const InternalPluginInfo activex_shim_wmplayer = {
+ },
+ {
{kActivexShimFileNameForMediaPlayer,
kActivexShimFileNameForMediaPlayer,
+ kActivexShimFileNameForMediaPlayer,
L"Windows Media Player",
L"1, 0, 0, 1",
L"application/x-ms-wmp|application/asx|video/x-ms-asf-plugin|"
@@ -81,10 +61,10 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
activex_shim::ActiveX_Shim_NP_GetEntryPoints,
activex_shim::ActiveX_Shim_NP_Initialize,
activex_shim::ActiveX_Shim_NP_Shutdown
- };
-
- static const InternalPluginInfo default_plugin_info = {
+ },
+ {
{kDefaultPluginLibraryName,
+ kDefaultPluginLibraryName,
L"Default Plug-in",
L"Provides functionality for installing third-party plug-ins",
L"1, 0, 0, 1",
@@ -95,59 +75,50 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
default_plugin::NP_GetEntryPoints,
default_plugin::NP_Initialize,
default_plugin::NP_Shutdown
- };
-
- WebPluginInfo* info = NULL;
- const InternalPluginInfo* internal_plugin_info = NULL;
- if (!_wcsicmp(filename.value().c_str(),
- activex_shim_info_generic.version_info.file_name.c_str())) {
- info = CreateWebPluginInfo(activex_shim_info_generic.version_info);
- internal_plugin_info = &activex_shim_info_generic;
- } else if (!_wcsicmp(filename.value().c_str(),
- activex_shim_wmplayer.version_info.file_name.c_str())) {
- info = CreateWebPluginInfo(activex_shim_wmplayer.version_info);
- internal_plugin_info = &activex_shim_wmplayer;
- } else if (!_wcsicmp(
- filename.value().c_str(),
- default_plugin_info.version_info.file_name.c_str())) {
- info = CreateWebPluginInfo(default_plugin_info.version_info);
- internal_plugin_info = &default_plugin_info;
- } else {
- info = ReadWebPluginInfo(filename_lc);
- if (!info) {
- DLOG(INFO) << "This file isn't a valid NPAPI plugin: "
- << filename.value();
- return NULL;
- }
+ },
+};
+
+
+// A list of all the instantiated plugins.
+static std::vector<scoped_refptr<PluginLib> >* g_loaded_libs;
+
+PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) {
+ // We can only have one PluginLib object per plugin as it controls the per
+ // instance function calls (i.e. NP_Initialize and NP_Shutdown). So we keep
+ // a map of PluginLib objects.
+ if (!g_loaded_libs)
+ g_loaded_libs = new std::vector<scoped_refptr<PluginLib> >;
+
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
+ if ((*g_loaded_libs)[i]->plugin_info().path == filename)
+ return (*g_loaded_libs)[i];
}
- return new PluginLib(info, internal_plugin_info);
+ WebPluginInfo info;
+ if (!ReadWebPluginInfo(filename, &info))
+ return NULL;
+
+ return new PluginLib(info);
}
void PluginLib::UnloadAllPlugins() {
- if (loaded_libs_) {
- PluginMap::iterator lib_index;
- for (lib_index = loaded_libs_->begin(); lib_index != loaded_libs_->end();
- ++lib_index) {
- lib_index->second->Unload();
- }
- delete loaded_libs_;
- loaded_libs_ = NULL;
+ if (g_loaded_libs) {
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i)
+ (*g_loaded_libs)[i]->Unload();
+
+ delete g_loaded_libs;
+ g_loaded_libs = NULL;
}
}
void PluginLib::ShutdownAllPlugins() {
- if (loaded_libs_) {
- PluginMap::iterator lib_index;
- for (lib_index = loaded_libs_->begin(); lib_index != loaded_libs_->end();
- ++lib_index) {
- lib_index->second->Shutdown();
- }
+ if (g_loaded_libs) {
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i)
+ (*g_loaded_libs)[i]->Shutdown();
}
}
-PluginLib::PluginLib(WebPluginInfo* info,
- const InternalPluginInfo* internal_plugin_info)
+PluginLib::PluginLib(const WebPluginInfo& info)
: web_plugin_info_(info),
module_(0),
initialized_(false),
@@ -155,15 +126,18 @@ PluginLib::PluginLib(WebPluginInfo* info,
instance_count_(0) {
StatsCounter(kPluginLibrariesLoadedCounter).Increment();
memset((void*)&plugin_funcs_, 0, sizeof(plugin_funcs_));
-
- (*loaded_libs_)[info->file] = this;
- if (internal_plugin_info) {
- internal_ = true;
- NP_Initialize_ = internal_plugin_info->np_initialize;
- NP_GetEntryPoints_ = internal_plugin_info->np_getentrypoints;
- NP_Shutdown_ = internal_plugin_info->np_shutdown;
- } else {
- internal_ = false;
+ g_loaded_libs->push_back(this);
+
+ internal_ = false;
+ std::wstring wide_filename = UTF8ToWide(info.filename);
+ for (int i = 0; i < arraysize(g_internal_plugins); ++i) {
+ if (wide_filename == g_internal_plugins[i].version_info.filename) {
+ internal_ = true;
+ NP_Initialize_ = g_internal_plugins[i].np_initialize;
+ NP_GetEntryPoints_ = g_internal_plugins[i].np_getentrypoints;
+ NP_Shutdown_ = g_internal_plugins[i].np_shutdown;
+ break;
+ }
}
}
@@ -178,24 +152,6 @@ NPPluginFuncs *PluginLib::functions() {
return &plugin_funcs_;
}
-bool PluginLib::SupportsType(const std::string &mime_type,
- bool allow_wildcard) {
- // Webkit will ask for a plugin to handle empty mime types.
- if (mime_type.empty())
- return false;
-
- for (size_t i = 0; i < web_plugin_info_->mime_types.size(); ++i) {
- const WebPluginMimeType& mime_info = web_plugin_info_->mime_types[i];
- if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
- if (!allow_wildcard && (mime_info.mime_type == "*")) {
- continue;
- }
- return true;
- }
- }
- return false;
-}
-
NPError PluginLib::NP_Initialize() {
if (initialized_)
return NPERR_NO_ERROR;
@@ -233,10 +189,15 @@ void PluginLib::CloseInstance() {
if ((instance_count_ == 0) &&
webkit_glue::IsPluginRunningInRendererProcess()) {
Unload();
- loaded_libs_->erase(web_plugin_info_->file);
- if (loaded_libs_->empty()) {
- delete loaded_libs_;
- loaded_libs_ = NULL;
+ for (size_t i = 0; i < g_loaded_libs->size(); ++i) {
+ if ((*g_loaded_libs)[i].get() == this) {
+ g_loaded_libs->erase(g_loaded_libs->begin() + i);
+ break;
+ }
+ }
+ if (g_loaded_libs->empty()) {
+ delete g_loaded_libs;
+ g_loaded_libs = NULL;
}
}
}
@@ -249,7 +210,7 @@ bool PluginLib::Load() {
if (module_ != 0)
return rv;
- module = LoadPluginHelper(web_plugin_info_->file);
+ module = LoadPluginHelper(web_plugin_info_.path);
if (module == 0)
return rv;
@@ -370,7 +331,8 @@ void PluginLib::Shutdown() {
}
}
-WebPluginInfo* PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi) {
+bool PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi,
+ WebPluginInfo* info) {
std::vector<std::string> mime_types, file_extensions;
std::vector<std::wstring> descriptions;
SplitString(base::SysWideToNativeMB(pvi.mime_types), '|', &mime_types);
@@ -378,13 +340,13 @@ WebPluginInfo* PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi) {
SplitString(pvi.file_open_names, '|', &descriptions);
if (mime_types.empty())
- return NULL;
+ return false;
- WebPluginInfo *info = new WebPluginInfo();
info->name = pvi.product_name;
info->desc = pvi.file_description;
info->version = pvi.file_version;
- info->file = FilePath(pvi.file_name);
+ info->filename = WideToUTF8(pvi.filename);
+ info->path = FilePath(pvi.path);
for (size_t i = 0; i < mime_types.size(); ++i) {
WebPluginMimeType mime_type;
@@ -408,10 +370,17 @@ WebPluginInfo* PluginLib::CreateWebPluginInfo(const PluginVersionInfo& pvi) {
info->mime_types.push_back(mime_type);
}
- return info;
+ return true;
}
-WebPluginInfo* PluginLib::ReadWebPluginInfo(const FilePath &filename) {
+
+ bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
+ WebPluginInfo* info) {
+ for (int i = 0; i < arraysize(g_internal_plugins); ++i) {
+ if (filename.value() == g_internal_plugins[i].version_info.filename)
+ return CreateWebPluginInfo(g_internal_plugins[i].version_info, info);
+ }
+
// On windows, the way we get the mime types for the library is
// to check the version information in the DLL itself. This
// will be a string of the format: <type1>|<type2>|<type3>|...
@@ -420,7 +389,10 @@ WebPluginInfo* PluginLib::ReadWebPluginInfo(const FilePath &filename) {
scoped_ptr<FileVersionInfo> version_info(
FileVersionInfo::CreateFileVersionInfo(filename.value()));
if (!version_info.get())
- return NULL;
+ return false;
+
+ std::wstring original_filename = version_info->original_filename();
+ std::wstring file_version = version_info->file_version();
PluginVersionInfo pvi;
version_info->GetValue(L"MIMEType", &pvi.mime_types);
@@ -428,10 +400,11 @@ WebPluginInfo* PluginLib::ReadWebPluginInfo(const FilePath &filename) {
version_info->GetValue(L"FileOpenName", &pvi.file_open_names);
pvi.product_name = version_info->product_name();
pvi.file_description = version_info->file_description();
- pvi.file_version = version_info->file_version();
- pvi.file_name = filename.value();
+ pvi.file_version = file_version;
+ pvi.filename = original_filename;
+ pvi.path = filename.value();
- return CreateWebPluginInfo(pvi);
+ return CreateWebPluginInfo(pvi, info);
}
} // namespace NPAPI
diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h
index cd3db97..884f235 100644
--- a/webkit/glue/plugins/plugin_lib.h
+++ b/webkit/glue/plugins/plugin_lib.h
@@ -8,13 +8,14 @@
#include "build/build_config.h"
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/file_path.h"
-#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "webkit/glue/plugins/nphostapi.h"
+#include "webkit/glue/webplugin.h"
#include "third_party/npapi/bindings/npapi.h"
struct WebPluginInfo;
@@ -27,7 +28,8 @@ class PluginInstance;
// This struct fully describes a plugin. For external plugins, it's read in from
// the version info of the dll; For internal plugins, it's predefined.
struct PluginVersionInfo {
- std::wstring file_name;
+ std::wstring filename;
+ std::wstring path;
std::wstring product_name;
std::wstring file_description;
std::wstring file_version;
@@ -49,8 +51,13 @@ struct InternalPluginInfo {
// manager for new PluginInstances.
class PluginLib : public base::RefCounted<PluginLib> {
public:
+ static PluginLib* PluginLib::CreatePluginLib(const FilePath& filename);
virtual ~PluginLib();
- static PluginLib* CreatePluginLib(const FilePath& filename);
+
+ // Creates a WebPluginInfo structure given a plugin's path. On success
+ // returns true, with the information being put into "info". Returns false if
+ // the library couldn't be found, or if it's not a plugin.
+ static bool ReadWebPluginInfo(const FilePath &filename, WebPluginInfo* info);
// Unloads all the loaded plugin libraries and cleans up the plugin map.
static void UnloadAllPlugins();
@@ -61,10 +68,6 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Get the Plugin's function pointer table.
NPPluginFuncs *functions();
- // Returns true if this Plugin supports a given mime-type.
- // mime_type should be all lower case.
- bool SupportsType(const std::string &mime_type, bool allow_wildcard);
-
// Creates a new instance of this plugin.
PluginInstance *CreateInstance(const std::string &mime_type);
@@ -73,7 +76,7 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Gets information about this plugin and the mime types that it
// supports.
- const WebPluginInfo& plugin_info() { return *web_plugin_info_; }
+ const WebPluginInfo& plugin_info() { return web_plugin_info_; }
//
// NPAPI functions
@@ -95,11 +98,8 @@ class PluginLib : public base::RefCounted<PluginLib> {
int instance_count() const { return instance_count_; }
private:
- // Creates a new PluginLib. The WebPluginInfo object is owned by this
- // object. If internal_plugin_info is not NULL, this Lib is an internal
- // plugin thus doesn't need to load a library.
- PluginLib(WebPluginInfo* info,
- const InternalPluginInfo* internal_plugin_info);
+ // Creates a new PluginLib
+ PluginLib(const WebPluginInfo& info);
// Attempts to load the plugin from the library.
// Returns true if it is a legitimate plugin, false otherwise
@@ -111,31 +111,25 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Shutdown the plugin library.
void Shutdown();
- // Returns a WebPluginInfo structure given a plugin's path. Returns NULL if
- // the library couldn't be found, or if it's not a plugin.
- static WebPluginInfo* ReadWebPluginInfo(const FilePath &filename);
// Creates WebPluginInfo structure based on read in or built in
// PluginVersionInfo.
- static WebPluginInfo* CreateWebPluginInfo(const PluginVersionInfo& info);
+ static bool CreateWebPluginInfo(const PluginVersionInfo& pvi,
+ WebPluginInfo* info);
- bool internal_; // Whether this an internal plugin.
- scoped_ptr<WebPluginInfo> web_plugin_info_; // supported mime types, description
+ bool internal_; // Whether this an internal plugin.
+ WebPluginInfo web_plugin_info_; // supported mime types, description
#if defined(OS_WIN)
- HMODULE module_; // the opened DLL handle
+ HMODULE module_; // the opened DLL handle
#endif
- NPPluginFuncs plugin_funcs_; // the struct of plugin side functions
- bool initialized_; // is the plugin initialized
- NPSavedData *saved_data_; // persisted plugin info for NPAPI
- int instance_count_; // count of plugins in use
-
- // A map of all the instantiated plugins.
- typedef base::hash_map<FilePath, scoped_refptr<PluginLib> > PluginMap;
- static PluginMap* loaded_libs_;
+ NPPluginFuncs plugin_funcs_; // the struct of plugin side functions
+ bool initialized_; // is the plugin initialized
+ NPSavedData *saved_data_; // persisted plugin info for NPAPI
+ int instance_count_; // count of plugins in use
// C-style function pointers
- NP_InitializeFunc NP_Initialize_;
- NP_GetEntryPointsFunc NP_GetEntryPoints_;
- NP_ShutdownFunc NP_Shutdown_;
+ NP_InitializeFunc NP_Initialize_;
+ NP_GetEntryPointsFunc NP_GetEntryPoints_;
+ NP_ShutdownFunc NP_Shutdown_;
DISALLOW_EVIL_CONSTRUCTORS(PluginLib);
};
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index f969874..b4b3dcb 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -17,10 +17,11 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/time.h"
+#include "net/base/mime_util.h"
#include "webkit/activex_shim/activex_shared.h"
+#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webplugin.h"
-#include "webkit/glue/plugins/plugin_lib.h"
#include "googleurl/src/gurl.h"
using base::TimeDelta;
@@ -42,10 +43,10 @@ static const TCHAR kRegistryPath[] = _T("Path");
static const TCHAR kRegistryMozillaPlugins[] = _T("SOFTWARE\\MozillaPlugins");
static const TCHAR kRegistryFirefoxInstalled[] =
_T("SOFTWARE\\Mozilla\\Mozilla Firefox");
-static const TCHAR kMozillaActiveXPlugin[] = _T("npmozax.dll");
-static const TCHAR kNewWMPPlugin[] = _T("np-mswmp.dll");
-static const TCHAR kOldWMPPlugin[] = _T("npdsplay.dll");
-static const TCHAR kYahooApplicationStatePlugin[] = _T("npystate.dll");
+static const char kMozillaActiveXPlugin[] = "npmozax.dll";
+static const char kNewWMPPlugin[] = "np-mswmp.dll";
+static const char kOldWMPPlugin[] = "npdsplay.dll";
+static const char kYahooApplicationStatePlugin[] = "npystate.dll";
static const TCHAR kRegistryJava[] =
_T("Software\\JavaSoft\\Java Runtime Environment");
static const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
@@ -80,10 +81,6 @@ PluginList::PluginList() :
!command_line.HasSwitch(kNoNativeActiveXShimSwitch);
}
-PluginList::~PluginList() {
- plugins_.clear();
-}
-
void PluginList::LoadPlugins(bool refresh) {
if (plugins_loaded_ && !refresh)
return;
@@ -122,9 +119,11 @@ void PluginList::LoadPlugins(bool refresh) {
LoadWindowsMediaPlugins();
if (webkit_glue::IsDefaultPluginEnabled()) {
- scoped_refptr<PluginLib> default_plugin = PluginLib::CreatePluginLib(
- FilePath(kDefaultPluginLibraryName));
- plugins_.push_back(default_plugin);
+ WebPluginInfo info;
+ if (PluginLib::ReadWebPluginInfo(FilePath(kDefaultPluginLibraryName),
+ &info)) {
+ plugins_[WideToUTF8(kDefaultPluginLibraryName)] = info;
+ }
}
TimeTicks end_time = TimeTicks::Now();
@@ -155,15 +154,42 @@ void PluginList::LoadPlugins(const FilePath &path) {
FindClose(find_handle);
}
+
+// Compares Windows style version strings (i.e. 1,2,3,4). Returns true if b's
+// version is newer than a's, or false if it's equal or older.
+bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
+ std::vector<std::wstring> a_ver, b_ver;
+ SplitString(a, ',', &a_ver);
+ SplitString(b, ',', &b_ver);
+ if (a_ver.size() != b_ver.size())
+ return false;
+ for (size_t i = 0; i < a_ver.size(); i++) {
+ int cur_a = StringToInt(a_ver[i]);
+ int cur_b = StringToInt(b_ver[i]);
+ if (cur_a > cur_b)
+ return false;
+ if (cur_a < cur_b)
+ return true;
+ }
+ return false;
+}
+
void PluginList::LoadPlugin(const FilePath &path) {
- if (!ShouldLoadPlugin(path.BaseName()))
+ WebPluginInfo plugin_info;
+ if (!PluginLib::ReadWebPluginInfo(path, &plugin_info))
return;
- scoped_refptr<PluginLib> new_plugin = PluginLib::CreatePluginLib(path);
- if (!new_plugin.get())
+ // Canonicalize names on Windows in case different versions of the plugin
+ // have different case in the version string.
+ std::string filename_lc = StringToLowerASCII(plugin_info.filename);
+ if (!ShouldLoadPlugin(filename_lc))
return;
- const WebPluginInfo& plugin_info = new_plugin->plugin_info();
+ PluginMap::const_iterator iter = plugins_.find(filename_lc);
+ if (iter != plugins_.end() &&
+ !IsNewerVersion(iter->second.version, plugin_info.version))
+ return; // The loaded version is newer.
+
for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) {
// TODO: don't load global handlers for now.
// WebKit hands to the Plugin before it tries
@@ -172,50 +198,41 @@ void PluginList::LoadPlugin(const FilePath &path) {
if (mime_type == "*" ) {
#ifndef NDEBUG
// Make an exception for NPSPY.
- if (plugin_info.file.value().find(L"npspy.dll") != std::wstring::npos) {
- // Put it at the beginning so it's used before the real plugin.
- plugins_.insert(plugins_.begin(), new_plugin.get());
- }
+ if (filename_lc == "npspy.dll")
+ break;
#endif
- continue;
- }
-
- if (!SupportsType(mime_type)) {
- plugins_.push_back(new_plugin);
return;
}
}
+
+ plugins_[filename_lc] = plugin_info;
}
-bool PluginList::ShouldLoadPlugin(const FilePath& filename) {
- // Canonicalize names.
- std::wstring filename_lc = StringToLowerASCII(filename.value());
-
+bool PluginList::ShouldLoadPlugin(const std::string& filename) {
// Depends on XPCOM.
- if (filename_lc == kMozillaActiveXPlugin)
+ if (filename == kMozillaActiveXPlugin)
return false;
// Disable the yahoo application state plugin as it crashes the plugin
// process on return from NPObjectStub::OnInvoke. Please refer to
// http://b/issue?id=1372124 for more information.
- if (filename_lc == kYahooApplicationStatePlugin)
+ if (filename == kYahooApplicationStatePlugin)
return false;
// We will use activex shim to handle embeded wmp media.
if (use_internal_activex_shim_) {
- if (filename_lc == kNewWMPPlugin || filename_lc == kOldWMPPlugin)
+ if (filename == kNewWMPPlugin || filename == kOldWMPPlugin)
return false;
} else {
// If both the new and old WMP plugins exist, only load the new one.
- if (filename_lc == kNewWMPPlugin) {
+ if (filename == kNewWMPPlugin) {
if (dont_load_new_wmp_)
return false;
- int old_plugin = FindPluginFile(kOldWMPPlugin);
- if (old_plugin != -1)
- plugins_.erase(plugins_.begin() + old_plugin);
- } else if (filename_lc == kOldWMPPlugin) {
- if (FindPluginFile(kNewWMPPlugin) != -1)
+ if (plugins_.find(kOldWMPPlugin) != plugins_.end())
+ plugins_.erase(kOldWMPPlugin);
+ } else if (filename == kOldWMPPlugin) {
+ if (plugins_.find(kOldWMPPlugin) != plugins_.end())
return false;
}
}
@@ -224,73 +241,94 @@ bool PluginList::ShouldLoadPlugin(const FilePath& filename) {
}
void PluginList::LoadInternalPlugins() {
- if (use_internal_activex_shim_) {
- scoped_refptr<PluginLib> new_plugin = PluginLib::CreatePluginLib(
- FilePath(kActiveXShimFileName));
- plugins_.push_back(new_plugin);
-
- new_plugin = PluginLib::CreatePluginLib(
- FilePath(kActivexShimFileNameForMediaPlayer));
- plugins_.push_back(new_plugin);
- }
-}
+ if (!use_internal_activex_shim_)
+ return;
-int PluginList::FindPluginFile(const std::wstring& filename) {
- std::string filename_narrow = WideToASCII(filename);
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (LowerCaseEqualsASCII(
- plugins_[i]->plugin_info().file.BaseName().value(),
- filename_narrow.c_str())) {
- return static_cast<int>(i);
- }
+ WebPluginInfo info;
+ if (PluginLib::ReadWebPluginInfo(FilePath(kActiveXShimFileName),
+ &info)) {
+ plugins_[WideToUTF8(kActiveXShimFileName)] = info;
}
- return -1;
-}
+ if (PluginLib::ReadWebPluginInfo(FilePath(kActivexShimFileNameForMediaPlayer),
+ &info)) {
+ plugins_[WideToUTF8(kActivexShimFileNameForMediaPlayer)] = info;
+ }
+}
-PluginLib* PluginList::FindPlugin(const std::string& mime_type,
- const std::string& clsid,
- bool allow_wildcard) {
+bool PluginList::FindPlugin(const std::string& mime_type,
+ const std::string& clsid,
+ bool allow_wildcard,
+ WebPluginInfo* info) {
DCHECK(mime_type == StringToLowerASCII(mime_type));
- for (size_t idx = 0; idx < plugins_.size(); ++idx) {
- if (plugins_[idx]->SupportsType(mime_type, allow_wildcard)) {
- if (!clsid.empty() &&
- plugins_[idx]->plugin_info().file.value() == kActiveXShimFileName) {
+ PluginMap::const_iterator default_iter = plugins_.end();
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ if (SupportsType(iter->second, mime_type, allow_wildcard)) {
+ if (iter->second.path.value() == kDefaultPluginLibraryName) {
+ // Only use the default plugin if it's the only one that's found.
+ default_iter = iter;
+ continue;
+ }
+
+ if (!clsid.empty() && iter->second.path.value() == kActiveXShimFileName) {
// Special handling for ActiveX shim. If ActiveX is not installed, we
// should use the default plugin to show the installation UI.
if (!activex_shim::IsActiveXInstalled(clsid))
continue;
}
- return plugins_[idx];
+ *info = iter->second;
+ return true;
}
}
- return NULL;
+ if (default_iter != plugins_.end()) {
+ *info = default_iter->second;
+ return true;
+ }
+
+ return false;
}
-PluginLib* PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type) {
+bool PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type,
+ WebPluginInfo* info) {
std::wstring path = base::SysNativeMBToWide(url.path());
std::wstring extension_wide = file_util::GetFileExtensionFromPath(path);
if (extension_wide.empty())
- return NULL;
+ return false;
std::string extension =
StringToLowerASCII(base::SysWideToNativeMB(extension_wide));
- for (size_t idx = 0; idx < plugins_.size(); ++idx) {
- if (SupportsExtension(plugins_[idx]->plugin_info(), extension, actual_mime_type)) {
- return plugins_[idx];
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ if (SupportsExtension(iter->second, extension, actual_mime_type)) {
+ *info = iter->second;
+ return true;
}
}
- return NULL;
+ return false;
}
-bool PluginList::SupportsType(const std::string &mime_type) {
- DCHECK(mime_type == StringToLowerASCII(mime_type));
- bool allow_wildcard = true;
- return (FindPlugin(mime_type, "", allow_wildcard ) != 0);
+bool PluginList::SupportsType(const WebPluginInfo& info,
+ const std::string &mime_type,
+ bool allow_wildcard) {
+ // Webkit will ask for a plugin to handle empty mime types.
+ if (mime_type.empty())
+ return false;
+
+ for (size_t i = 0; i < info.mime_types.size(); ++i) {
+ const WebPluginMimeType& mime_info = info.mime_types[i];
+ if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
+ if (!allow_wildcard && mime_info.mime_type == "*") {
+ continue;
+ }
+ return true;
+ }
+ }
+ return false;
}
bool PluginList::SupportsExtension(const WebPluginInfo& info,
@@ -315,9 +353,12 @@ bool PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
if (refresh)
LoadPlugins(true);
+ int i = 0;
plugins->resize(plugins_.size());
- for (size_t i = 0; i < plugins->size(); ++i)
- (*plugins)[i] = plugins_[i]->plugin_info();
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ (*plugins)[i++] = iter->second;
+ }
return true;
}
@@ -328,32 +369,25 @@ bool PluginList::GetPluginInfo(const GURL& url,
bool allow_wildcard,
WebPluginInfo* info,
std::string* actual_mime_type) {
- scoped_refptr<PluginLib> plugin = FindPlugin(mime_type, clsid,
- allow_wildcard);
-
- if (plugin.get() == NULL ||
- (plugin->plugin_info().file.value() == kDefaultPluginLibraryName
- && clsid.empty())) {
- scoped_refptr<PluginLib> default_plugin = plugin;
- plugin = FindPlugin(url, actual_mime_type);
- // url matches may not return the default plugin if no match is found.
- if (plugin.get() == NULL && default_plugin.get() != NULL)
- plugin = default_plugin;
+ bool found = FindPlugin(mime_type, clsid, allow_wildcard, info);
+ if (!found ||
+ (info->path.value() == kDefaultPluginLibraryName && clsid.empty())) {
+ WebPluginInfo info2;
+ if (FindPlugin(url, actual_mime_type, &info2)) {
+ found = true;
+ *info = info2;
+ }
}
- if (plugin.get() == NULL)
- return false;
-
- *info = plugin->plugin_info();
- return true;
+ return found;
}
bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
WebPluginInfo* info) {
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (wcsicmp(plugins_[i]->plugin_info().file.value().c_str(),
- plugin_path.value().c_str()) == 0) {
- *info = plugins_[i]->plugin_info();
+ for (PluginMap::const_iterator iter = plugins_.begin();
+ iter != plugins_.end(); ++iter) {
+ if (iter->second.path == plugin_path) {
+ *info = iter->second;
return true;
}
}
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index ebdb687..6bb33aa 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -8,9 +8,9 @@
#define WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H__
#include <string>
-#include <vector>
#include "base/basictypes.h"
+#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "webkit/glue/webplugin.h"
@@ -33,7 +33,6 @@ namespace NPAPI
#define kDefaultPluginLibraryName L"default_plugin"
-class PluginLib;
class PluginInstance;
// The PluginList is responsible for loading our NPAPI based plugins. It does
@@ -58,35 +57,6 @@ class PluginList : public base::RefCounted<PluginList> {
// for plugins. Must be called before the plugins have been loaded.
static void AddExtraPluginPath(const FilePath& plugin_path);
- virtual ~PluginList();
-
- // Find a plugin to by mime type, and clsid.
- // If clsid is empty, we will just find the plugin that supports mime type.
- // Otherwise, if mime_type is application/x-oleobject etc that supported by
- // by our activex shim, we need to check if the specified ActiveX exists.
- // If not we will not return the activex shim, instead we will let the
- // default plugin handle activex installation.
- // The allow_wildcard parameter controls whether this function returns
- // plugins which support wildcard mime types (* as the mime type)
- PluginLib* FindPlugin(const std::string &mime_type, const std::string& clsid,
- bool allow_wildcard);
-
- // Find a plugin to by extension. Returns the corresponding mime type
- PluginLib* FindPlugin(const GURL &url, std::string* actual_mime_type);
-
- // Check if we have any plugin for a given type.
- // mime_type must be all lowercase.
- bool SupportsType(const std::string &mime_type);
-
- // Returns true if the given WebPluginInfo supports a given file extension.
- // extension should be all lower case.
- // If mime_type is not NULL, it will be set to the mime type if found.
- // The mime type which corresponds to the extension is optionally returned
- // back.
- static bool SupportsExtension(const WebPluginInfo& info,
- const std::string &extension,
- std::string* actual_mime_type);
-
// Shutdown all plugins. Should be called at process teardown.
void Shutdown();
@@ -123,14 +93,40 @@ class PluginList : public base::RefCounted<PluginList> {
void LoadPlugin(const FilePath& filename);
// Returns true if we should load the given plugin, or false otherwise.
- bool ShouldLoadPlugin(const FilePath& filename);
+ bool ShouldLoadPlugin(const std::string& filename);
// Load internal plugins. Right now there is only one: activex_shim.
void LoadInternalPlugins();
- // Find a plugin by filename. Returns -1 if it's not found, otherwise its
- // index in plugins_.
- int FindPluginFile(const std::wstring& filename);
+ // Find a plugin by mime type, and clsid.
+ // If clsid is empty, we will just find the plugin that supports mime type.
+ // Otherwise, if mime_type is application/x-oleobject etc that's supported by
+ // by our activex shim, we need to check if the specified ActiveX exists.
+ // If not we will not return the activex shim, instead we will let the
+ // default plugin handle activex installation.
+ // The allow_wildcard parameter controls whether this function returns
+ // plugins which support wildcard mime types (* as the mime type)
+ bool FindPlugin(const std::string &mime_type, const std::string& clsid,
+ bool allow_wildcard, WebPluginInfo* info);
+
+ // Find a plugin by extension. Returns the corresponding mime type.
+ bool FindPlugin(const GURL &url, std::string* actual_mime_type,
+ WebPluginInfo* info);
+
+ // Returns true if the given WebPluginInfo supports "mime-type".
+ // mime_type should be all lower case.
+ static bool SupportsType(const WebPluginInfo& info,
+ const std::string &mime_type,
+ bool allow_wildcard);
+
+ // Returns true if the given WebPluginInfo supports a given file extension.
+ // extension should be all lower case.
+ // If mime_type is not NULL, it will be set to the mime type if found.
+ // The mime type which corresponds to the extension is optionally returned
+ // back.
+ static bool SupportsExtension(const WebPluginInfo& info,
+ const std::string &extension,
+ std::string* actual_mime_type);
// The application path where we expect to find plugins.
static FilePath GetPluginAppDirectory();
@@ -169,7 +165,10 @@ class PluginList : public base::RefCounted<PluginList> {
static scoped_refptr<PluginList> singleton_;
bool plugins_loaded_;
- std::vector<scoped_refptr<PluginLib> > plugins_;
+
+ // Maps from the name of the plugin file (NOT path) to WebPluginInfo.
+ typedef base::hash_map<std::string, WebPluginInfo> PluginMap;
+ PluginMap plugins_;
DISALLOW_EVIL_CONSTRUCTORS(PluginList);
};
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index 364ae10..9819132 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -145,16 +145,16 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
memset(&window_, 0, sizeof(window_));
const WebPluginInfo& plugin_info = instance_->plugin_lib()->plugin_info();
- std::wstring filename = plugin_info.file.BaseName().value();
+ std::string filename = StringToLowerASCII(plugin_info.filename);
if (instance_->mime_type() == "application/x-shockwave-flash" ||
- filename == L"npswf32.dll") {
+ filename == "npswf32.dll") {
// Flash only requests windowless plugins if we return a Mozilla user
// agent.
instance_->set_use_mozilla_user_agent();
quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
- } else if (filename == L"nppdf32.dll") {
+ } else if (filename == "nppdf32.dll") {
// Check for the version number above or equal 9.
std::vector<std::wstring> version;
SplitString(plugin_info.version, L'.', &version);
@@ -169,7 +169,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
// Windows Media Player needs two NPP_SetWindow calls.
quirks_ |= PLUGIN_QUIRK_SETWINDOW_TWICE;
} else if (instance_->mime_type() == "audio/x-pn-realaudio-plugin" ||
- filename == L"nppl3260.dll") {
+ filename == "nppl3260.dll") {
quirks_ |= PLUGIN_QUIRK_DONT_CALL_WND_PROC_RECURSIVELY;
} else if (plugin_info.name.find(L"VLC Multimedia Plugin") !=
std::wstring::npos) {
@@ -178,14 +178,14 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY;
// VLC 0.8.6d and 0.8.6e crash if multiple instances are created.
quirks_ |= PLUGIN_QUIRK_DONT_ALLOW_MULTIPLE_INSTANCES;
- } else if (filename == L"npctrl.dll") {
+ } else if (filename == "npctrl.dll") {
// Explanation for this quirk can be found in
// WebPluginDelegateImpl::Initialize.
quirks_ |= PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU;
quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
}
- plugin_module_handle_ = ::GetModuleHandle(filename.c_str());
+ plugin_module_handle_ = ::GetModuleHandle(plugin_info.path.value().c_str());
}
WebPluginDelegateImpl::~WebPluginDelegateImpl() {
@@ -393,7 +393,7 @@ void WebPluginDelegateImpl::DidManualLoadFail() {
}
FilePath WebPluginDelegateImpl::GetPluginPath() {
- return instance()->plugin_lib()->plugin_info().file;
+ return instance()->plugin_lib()->plugin_info().path;
}
void WebPluginDelegateImpl::InstallMissingPlugin() {
diff --git a/webkit/glue/webplugin.h b/webkit/glue/webplugin.h
index 96807fb..a0ac200 100644
--- a/webkit/glue/webplugin.h
+++ b/webkit/glue/webplugin.h
@@ -39,8 +39,13 @@ struct WebPluginInfo {
// The name of the plugin (i.e. Flash).
std::wstring name;
+ // The UTF8 filename of the plugin, without the path. This may be in a
+ // different case than FilePath on some systems. On Windows this comes from
+ // the DLL's version information.
+ std::string filename;
+
// The path to the plugin file (DLL/bundle/library).
- FilePath file;
+ FilePath path;
// The version number of the plugin file (may be OS-specific)
std::wstring version;