diff options
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib.cc | 197 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib.h | 56 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_list.cc | 232 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_list.h | 71 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.cc | 14 |
6 files changed, 286 insertions, 286 deletions
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() { |