summaryrefslogtreecommitdiffstats
path: root/webkit/glue
diff options
context:
space:
mode:
authoravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-15 21:49:54 +0000
committeravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-15 21:49:54 +0000
commitae4e20ac9d99988fb5b522acfaae08cb469a2ab7 (patch)
treeede89baf7be0f91f2fc9c1734a6060ce75fe648f /webkit/glue
parent022f42453b737577e9175eb279d507981ef40b30 (diff)
downloadchromium_src-ae4e20ac9d99988fb5b522acfaae08cb469a2ab7.zip
chromium_src-ae4e20ac9d99988fb5b522acfaae08cb469a2ab7.tar.gz
chromium_src-ae4e20ac9d99988fb5b522acfaae08cb469a2ab7.tar.bz2
New implementations of core plugin libraries.
Review URL: http://codereview.chromium.org/17427 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8122 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r--webkit/glue/SConscript10
-rw-r--r--webkit/glue/plugins/plugin_constants_win.h23
-rw-r--r--webkit/glue/plugins/plugin_host.cc2
-rw-r--r--webkit/glue/plugins/plugin_instance.cc2
-rw-r--r--webkit/glue/plugins/plugin_lib.cc210
-rw-r--r--webkit/glue/plugins/plugin_lib.h53
-rw-r--r--webkit/glue/plugins/plugin_lib_mac.mm367
-rw-r--r--webkit/glue/plugins/plugin_lib_win.cc185
-rw-r--r--webkit/glue/plugins/plugin_list.cc351
-rw-r--r--webkit/glue/plugins/plugin_list.h71
-rw-r--r--webkit/glue/plugins/plugin_list_mac.mm92
-rw-r--r--webkit/glue/plugins/plugin_list_win.cc343
-rw-r--r--webkit/glue/plugins/plugin_stream.cc2
-rw-r--r--webkit/glue/plugins/plugin_stream_posix.cc2
-rw-r--r--webkit/glue/plugins/plugin_stream_url.cc2
-rw-r--r--webkit/glue/plugins/plugin_string_stream.cc2
16 files changed, 1155 insertions, 562 deletions
diff --git a/webkit/glue/SConscript b/webkit/glue/SConscript
index 26a2d74..faf15c3 100644
--- a/webkit/glue/SConscript
+++ b/webkit/glue/SConscript
@@ -57,6 +57,8 @@ input_files = [
'password_form_dom_manager.cc',
'plugins/plugin_host.cc',
'plugins/plugin_instance.cc',
+ 'plugins/plugin_lib.cc',
+ 'plugins/plugin_list.cc',
'plugins/plugin_stream.cc',
'plugins/plugin_stream_url.cc',
'plugins/plugin_string_stream.cc',
@@ -88,8 +90,8 @@ if env.Bit('linux'):
'plugins/plugin_host.cc',
'plugins/plugin_instance.cc',
'plugins/plugin_stream.cc',
- 'plugins/plugin_string_stream.cc',
'plugins/plugin_stream_url.cc',
+ 'plugins/plugin_string_stream.cc',
]
for file in remove_files:
input_files.remove(file)
@@ -103,14 +105,14 @@ if env.Bit('windows'):
'$PENDING_DIR/AccessibleDocument.cpp',
'glue_accessibility.cc',
'plugins/mozilla_extensions.cc',
- 'plugins/plugin_lib.cc',
- 'plugins/plugin_list.cc',
'plugins/webplugin_delegate_impl.cc',
'webdropdata.cc',
])
if env.Bit('windows'):
input_files.extend([
+ 'plugins/plugin_lib_win.cc',
+ 'plugins/plugin_list_win.cc',
'plugins/plugin_stream_win.cc',
'webcursor_win.cc',
'webinputevent_win.cc',
@@ -124,6 +126,8 @@ elif env.Bit('linux'):
])
elif env.Bit('mac'):
input_files.extend([
+ 'plugins/plugin_lib_mac.mm',
+ 'plugins/plugin_list_mac.mm',
'webcursor_mac.mm',
])
diff --git a/webkit/glue/plugins/plugin_constants_win.h b/webkit/glue/plugins/plugin_constants_win.h
new file mode 100644
index 0000000..9b91335
--- /dev/null
+++ b/webkit/glue/plugins/plugin_constants_win.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_PLUGIN_CONSTANTS_WIN_H_
+#define WEBKIT_GLUE_PLUGIN_CONSTANTS_WIN_H_
+
+// Used by the plugins_test when testing the older WMP plugin to force the new
+// plugin to not get loaded.
+#define kUseOldWMPPluginSwitch L"use-old-wmp"
+// Used for testing the ActiveX shim. By default it's off. If this flag is
+// specified we will use the native ActiveX shim.
+#define kNoNativeActiveXShimSwitch L"no-activex"
+// Internal file name for the ActiveX shim, used as a unique identifier.
+#define kActiveXShimFileName L"activex-shim"
+// Internal file name for the ActiveX shim, registered as the Windows Media
+// Player. Some sites walk the plugin list and look for specifically-named
+// plugins, so we must oblige them with a very specific name. See
+// http://codereview.chromium.org/7234 .
+#define kActiveXShimFileNameForMediaPlayer \
+ L"Microsoft\xAE Windows Media Player Firefox Plugin"
+
+#endif // WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H_
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc
index 8ef80da..108537b 100644
--- a/webkit/glue/plugins/plugin_host.cc
+++ b/webkit/glue/plugins/plugin_host.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "config.h"
+
#include "webkit/glue/plugins/plugin_host.h"
#include "base/file_util.h"
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index 3a92aeb..4ba5c03 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "config.h"
+
#include "webkit/glue/plugins/plugin_instance.h"
#include "base/file_util.h"
diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc
index fee4055..d747d0e 100644
--- a/webkit/glue/plugins/plugin_lib.cc
+++ b/webkit/glue/plugins/plugin_lib.cc
@@ -6,24 +6,12 @@
#include "webkit/glue/plugins/plugin_lib.h"
-#include "base/file_util.h"
-#include "base/file_version_info.h"
#include "base/logging.h"
#include "base/message_loop.h"
-#include "base/path_service.h"
#include "base/stats_counters.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "base/task.h"
-#include "webkit/activex_shim/npp_impl.h"
-#include "webkit/default_plugin/plugin_main.h"
-#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webplugin.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/plugin_instance.h"
#include "webkit/glue/plugins/plugin_host.h"
-#include "webkit/glue/plugins/plugin_list.h"
-
namespace NPAPI
{
@@ -31,51 +19,6 @@ namespace NPAPI
const char kPluginLibrariesLoadedCounter[] = "PluginLibrariesLoaded";
const char kPluginInstancesActiveCounter[] = "PluginInstancesActive";
-static const InternalPluginInfo g_internal_plugins[] = {
- {
- {FilePath(kActiveXShimFileName),
- L"ActiveX Plug-in",
- L"ActiveX Plug-in provides a shim to support ActiveX controls",
- L"1, 0, 0, 1",
- L"application/x-oleobject|application/oleobject",
- L"*|*",
- L""
- },
- activex_shim::ActiveX_Shim_NP_GetEntryPoints,
- activex_shim::ActiveX_Shim_NP_Initialize,
- activex_shim::ActiveX_Shim_NP_Shutdown
- },
- {
- {FilePath(kActivexShimFileNameForMediaPlayer),
- kActivexShimFileNameForMediaPlayer,
- L"Windows Media Player",
- L"1, 0, 0, 1",
- L"application/x-ms-wmp|application/asx|video/x-ms-asf-plugin|"
- L"application/x-mplayer2|video/x-ms-asf|video/x-ms-wm|audio/x-ms-wma|"
- L"audio/x-ms-wax|video/x-ms-wmv|video/x-ms-wvx",
- L"*|*|*|*|asf,asx,*|wm,*|wma,*|wax,*|wmv,*|wvx,*",
- L""
- },
- activex_shim::ActiveX_Shim_NP_GetEntryPoints,
- activex_shim::ActiveX_Shim_NP_Initialize,
- activex_shim::ActiveX_Shim_NP_Shutdown
- },
- {
- {FilePath(kDefaultPluginLibraryName),
- L"Default Plug-in",
- L"Provides functionality for installing third-party plug-ins",
- L"1, 0, 0, 1",
- L"*",
- L"",
- L""
- },
- default_plugin::NP_GetEntryPoints,
- default_plugin::NP_Initialize,
- default_plugin::NP_Shutdown
- },
-};
-
-
// A list of all the instantiated plugins.
static std::vector<scoped_refptr<PluginLib> >* g_loaded_libs;
@@ -117,7 +60,7 @@ void PluginLib::ShutdownAllPlugins() {
PluginLib::PluginLib(const WebPluginInfo& info)
: web_plugin_info_(info),
- module_(0),
+ library_(0),
initialized_(false),
saved_data_(0),
instance_count_(0) {
@@ -125,13 +68,17 @@ PluginLib::PluginLib(const WebPluginInfo& info)
memset((void*)&plugin_funcs_, 0, sizeof(plugin_funcs_));
g_loaded_libs->push_back(this);
+ const InternalPluginInfo* internal_plugins;
+ size_t internal_plugin_count;
+ GetInternalPlugins(&internal_plugins, &internal_plugin_count);
+
internal_ = false;
- for (int i = 0; i < arraysize(g_internal_plugins); ++i) {
- if (info.path == g_internal_plugins[i].version_info.path) {
+ for (size_t i = 0; i < internal_plugin_count; ++i) {
+ if (info.path == internal_plugins[i].version_info.path) {
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;
+ NP_Initialize_ = internal_plugins[i].np_initialize;
+ NP_GetEntryPoints_ = internal_plugins[i].np_getentrypoints;
+ NP_Shutdown_ = internal_plugins[i].np_shutdown;
break;
}
}
@@ -200,30 +147,31 @@ void PluginLib::CloseInstance() {
bool PluginLib::Load() {
bool rv = false;
- HMODULE module = 0;
+ NativeLibrary library = 0;
if (!internal_) {
- if (module_ != 0)
+ if (library_ != 0)
return rv;
- module = LoadPluginHelper(web_plugin_info_.path);
- if (module == 0)
+ library = LoadNativeLibrary(web_plugin_info_.path);
+ if (library == 0)
return rv;
rv = true; // assume success now
- NP_Initialize_ = (NP_InitializeFunc)GetProcAddress(
- module, "NP_Initialize");
+ NP_Initialize_ = (NP_InitializeFunc)GetFunctionPointerFromNativeLibrary(
+ library, FUNCTION_NAME("NP_Initialize"));
if (NP_Initialize_ == 0)
rv = false;
- NP_GetEntryPoints_ = (NP_GetEntryPointsFunc)GetProcAddress(
- module, "NP_GetEntryPoints");
+ NP_GetEntryPoints_ =
+ (NP_GetEntryPointsFunc)GetFunctionPointerFromNativeLibrary(
+ library, FUNCTION_NAME("NP_GetEntryPoints"));
if (NP_GetEntryPoints_ == 0)
rv = false;
- NP_Shutdown_ = (NP_ShutdownFunc)GetProcAddress(
- module, "NP_Shutdown");
+ NP_Shutdown_ = (NP_ShutdownFunc)GetFunctionPointerFromNativeLibrary(
+ library, FUNCTION_NAME("NP_Shutdown"));
if (NP_Shutdown_ == 0)
rv = false;
} else {
@@ -239,39 +187,20 @@ bool PluginLib::Load() {
if (!internal_) {
if (rv)
- module_ = module;
+ library_ = library;
else
- FreeLibrary(module);
+ UnloadNativeLibrary(library);
}
return rv;
}
-HMODULE PluginLib::LoadPluginHelper(const FilePath plugin_file) {
- // Switch the current directory to the plugin directory as the plugin
- // may have dependencies on dlls in this directory.
- bool restore_directory = false;
- std::wstring current_directory;
- if (PathService::Get(base::DIR_CURRENT, &current_directory)) {
- FilePath plugin_path = plugin_file.DirName();
- if (!plugin_path.value().empty()) {
- PathService::SetCurrentDirectory(plugin_path.value());
- restore_directory = true;
- }
- }
-
- HMODULE module = LoadLibrary(plugin_file.value().c_str());
- if (restore_directory)
- PathService::SetCurrentDirectory(current_directory);
-
- return module;
-}
-
// This class implements delayed NP_Shutdown and FreeLibrary on the plugin dll.
class FreePluginLibraryTask : public Task {
public:
- FreePluginLibraryTask(HMODULE module, NP_ShutdownFunc shutdown_func)
- : module_(module),
+ FreePluginLibraryTask(PluginLib::NativeLibrary library,
+ NP_ShutdownFunc shutdown_func)
+ : library_(library),
NP_Shutdown_(shutdown_func) {
}
@@ -281,20 +210,20 @@ class FreePluginLibraryTask : public Task {
if (NP_Shutdown_)
NP_Shutdown_();
- if (module_) {
- FreeLibrary(module_);
- module_ = NULL;
+ if (library_) {
+ PluginLib::UnloadNativeLibrary(library_);
+ library_ = NULL;
}
}
private:
- HMODULE module_;
+ PluginLib::NativeLibrary library_;
NP_ShutdownFunc NP_Shutdown_;
DISALLOW_EVIL_CONSTRUCTORS(FreePluginLibraryTask);
};
void PluginLib::Unload() {
- if (!internal_ && module_) {
+ if (!internal_ && library_) {
// In case of single process mode, a plugin can delete itself
// by executing a script. So delay the unloading of the library
// so that the plugin will have a chance to unwind.
@@ -309,14 +238,14 @@ void PluginLib::Unload() {
if (defer_unload) {
FreePluginLibraryTask* free_library_task =
- new FreePluginLibraryTask(module_, NP_Shutdown_);
+ new FreePluginLibraryTask(library_, NP_Shutdown_);
MessageLoop::current()->PostTask(FROM_HERE, free_library_task);
} else {
Shutdown();
- FreeLibrary(module_);
+ UnloadNativeLibrary(library_);
}
- module_ = 0;
+ library_ = 0;
}
}
@@ -327,76 +256,5 @@ void PluginLib::Shutdown() {
}
}
-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);
- SplitString(base::SysWideToNativeMB(pvi.file_extents), '|', &file_extensions);
- SplitString(pvi.file_open_names, '|', &descriptions);
-
- if (mime_types.empty())
- return false;
-
- info->name = pvi.product_name;
- info->desc = pvi.file_description;
- info->version = pvi.file_version;
- info->path = FilePath(pvi.path);
-
- for (size_t i = 0; i < mime_types.size(); ++i) {
- WebPluginMimeType mime_type;
- mime_type.mime_type = StringToLowerASCII(mime_types[i]);
- if (file_extensions.size() > i)
- SplitString(file_extensions[i], ',', &mime_type.file_extensions);
-
- if (descriptions.size() > i) {
- mime_type.description = descriptions[i];
-
- // Remove the extension list from the description.
- size_t ext = mime_type.description.find(L"(*");
- if (ext != std::wstring::npos) {
- if (ext > 1 && mime_type.description[ext -1] == ' ')
- ext--;
-
- mime_type.description.erase(ext);
- }
- }
-
- info->mime_types.push_back(mime_type);
- }
-
- return true;
-}
-
-
- bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
- WebPluginInfo* info) {
- for (int i = 0; i < arraysize(g_internal_plugins); ++i) {
- if (filename == g_internal_plugins[i].version_info.path)
- 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>|...
- // For example:
- // video/quicktime|audio/aiff|image/jpeg
- scoped_ptr<FileVersionInfo> version_info(
- FileVersionInfo::CreateFileVersionInfo(filename.value()));
- if (!version_info.get())
- return false;
-
- PluginVersionInfo pvi;
- version_info->GetValue(L"MIMEType", &pvi.mime_types);
- version_info->GetValue(L"FileExtents", &pvi.file_extents);
- 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.path = filename;
-
- return CreateWebPluginInfo(pvi, info);
-}
-
} // namespace NPAPI
diff --git a/webkit/glue/plugins/plugin_lib.h b/webkit/glue/plugins/plugin_lib.h
index 3882da9..7878766 100644
--- a/webkit/glue/plugins/plugin_lib.h
+++ b/webkit/glue/plugins/plugin_lib.h
@@ -50,7 +50,7 @@ struct InternalPluginInfo {
// manager for new PluginInstances.
class PluginLib : public base::RefCounted<PluginLib> {
public:
- static PluginLib* PluginLib::CreatePluginLib(const FilePath& filename);
+ static PluginLib* CreatePluginLib(const FilePath& filename);
virtual ~PluginLib();
// Creates a WebPluginInfo structure given a plugin's path. On success
@@ -88,16 +88,10 @@ class PluginLib : public base::RefCounted<PluginLib> {
// NPAPI method to shutdown a Plugin.
void NP_Shutdown(void);
-#if defined(OS_WIN)
- // Helper function to load a plugin.
- // Returns the module handle on success.
- static HMODULE LoadPluginHelper(const FilePath plugin_file);
-#endif
-
int instance_count() const { return instance_count_; }
private:
- // Creates a new PluginLib
+ // Creates a new PluginLib.
PluginLib(const WebPluginInfo& info);
// Attempts to load the plugin from the library.
@@ -109,17 +103,42 @@ class PluginLib : public base::RefCounted<PluginLib> {
// Shutdown the plugin library.
void Shutdown();
-
- // Creates WebPluginInfo structure based on read in or built in
- // PluginVersionInfo.
- static bool CreateWebPluginInfo(const PluginVersionInfo& pvi,
- WebPluginInfo* info);
-
+
+ //
+ // Platform functions
+ //
+
+ // Gets the list of internal plugins.
+ static void GetInternalPlugins(const InternalPluginInfo** plugins,
+ size_t* count);
+
+ public:
+#if defined(OS_WIN)
+ typedef HMODULE NativeLibrary;
+ typedef char* NativeLibraryFunctionNameType;
+#define FUNCTION_NAME(x) x
+#elif defined(OS_MACOSX)
+ typedef CFBundleRef NativeLibrary;
+ typedef CFStringRef NativeLibraryFunctionNameType;
+#define FUNCTION_NAME(x) CFSTR(x)
+#endif // OS_*
+
+ // Loads a native library from disk. NOTE: You must release it with
+ // UnloadNativeLibrary when you're done.
+ static NativeLibrary LoadNativeLibrary(const FilePath& library_path);
+
+ // Unloads a native library.
+ static void UnloadNativeLibrary(NativeLibrary library);
+
+ private:
+ // Gets a function pointer from a native library.
+ static void* GetFunctionPointerFromNativeLibrary(
+ NativeLibrary library,
+ NativeLibraryFunctionNameType name);
+
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
-#endif
+ NativeLibrary library_; // the opened library reference
NPPluginFuncs plugin_funcs_; // the struct of plugin side functions
bool initialized_; // is the plugin initialized
NPSavedData *saved_data_; // persisted plugin info for NPAPI
diff --git a/webkit/glue/plugins/plugin_lib_mac.mm b/webkit/glue/plugins/plugin_lib_mac.mm
new file mode 100644
index 0000000..a8f53ad
--- /dev/null
+++ b/webkit/glue/plugins/plugin_lib_mac.mm
@@ -0,0 +1,367 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#import <Carbon/Carbon.h>
+
+#include "webkit/glue/plugins/plugin_lib.h"
+
+#include "base/scoped_cftyperef.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "webkit/glue/plugins/plugin_list.h"
+
+static const short kSTRTypeDefinitionResourceID = 128;
+static const short kSTRTypeDescriptionResourceID = 127;
+static const short kSTRPluginDescriptionResourceID = 126;
+
+namespace NPAPI
+{
+
+/* static */
+void PluginLib::GetInternalPlugins(const InternalPluginInfo** plugins,
+ size_t* count) {
+ *plugins = NULL;
+ *count = 0;
+}
+
+/* static */
+PluginLib::NativeLibrary PluginLib::LoadNativeLibrary(
+ const FilePath& library_path) {
+ scoped_cftyperef<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(
+ kCFAllocatorDefault,
+ (const UInt8*)library_path.value().c_str(),
+ library_path.value().length(),
+ true));
+ if (!url)
+ return NULL;
+
+ return CFBundleCreate(kCFAllocatorDefault, url.get());
+}
+
+/* static */
+void PluginLib::UnloadNativeLibrary(NativeLibrary library) {
+ CFRelease(library);
+}
+
+/* static */
+void* PluginLib::GetFunctionPointerFromNativeLibrary(
+ NativeLibrary library,
+ NativeLibraryFunctionNameType name) {
+ return CFBundleGetFunctionPointerForName(library, name);
+}
+
+namespace {
+
+NSDictionary* GetMIMETypes(CFBundleRef bundle) {
+ NSString* mime_filename =
+ (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
+ CFSTR("WebPluginMIMETypesFilename"));
+
+ if (mime_filename) {
+
+ // get the file
+
+ NSString* mime_path =
+ [NSString stringWithFormat:@"%@/Library/Preferences/%@",
+ NSHomeDirectory(), mime_filename];
+ NSDictionary* mime_file_dict =
+ [NSDictionary dictionaryWithContentsOfFile:mime_path];
+
+ // is it valid?
+
+ bool valid_file = false;
+ if (mime_file_dict) {
+ NSString* l10n_name =
+ [mime_file_dict objectForKey:@"WebPluginLocalizationName"];
+ NSString* preferred_l10n = [[NSLocale currentLocale] localeIdentifier];
+ if ([l10n_name isEqualToString:preferred_l10n])
+ valid_file = true;
+ }
+
+ if (valid_file)
+ return [mime_file_dict objectForKey:@"WebPluginMIMETypes"];
+
+ // dammit, I didn't want to have to do this
+
+ typedef void (*CreateMIMETypesPrefsPtr)(void);
+ CreateMIMETypesPrefsPtr create_prefs_file =
+ (CreateMIMETypesPrefsPtr)CFBundleGetFunctionPointerForName(
+ bundle, CFSTR("BP_CreatePluginMIMETypesPreferences"));
+ if (!create_prefs_file)
+ return nil;
+ create_prefs_file();
+
+ // one more time
+
+ mime_file_dict = [NSDictionary dictionaryWithContentsOfFile:mime_path];
+ if (mime_file_dict)
+ return [mime_file_dict objectForKey:@"WebPluginMIMETypes"];
+ else
+ return nil;
+
+ } else {
+ return (NSDictionary*)CFBundleGetValueForInfoDictionaryKey(bundle,
+ CFSTR("WebPluginMIMETypes"));
+ }
+}
+
+bool ReadPlistPluginInfo(const FilePath& filename, CFBundleRef bundle,
+ WebPluginInfo* info) {
+ NSDictionary* mime_types = GetMIMETypes(bundle);
+ if (!mime_types)
+ return false; // no type info here; try elsewhere
+
+ for (NSString* mime_type in [mime_types allKeys]) {
+ NSDictionary* mime_dict = [mime_types objectForKey:mime_type];
+ NSString* mime_desc = [mime_dict objectForKey:@"WebPluginTypeDescription"];
+ NSArray* mime_exts = [mime_dict objectForKey:@"WebPluginExtensions"];
+
+ WebPluginMimeType mime;
+ mime.mime_type = base::SysNSStringToUTF8([mime_type lowercaseString]);
+ if (mime_desc)
+ mime.description = base::SysNSStringToWide(mime_desc);
+ for (NSString* ext in mime_exts)
+ mime.file_extensions.push_back(
+ base::SysNSStringToUTF8([ext lowercaseString]));
+
+ info->mime_types.push_back(mime);
+ }
+
+ NSString* plugin_name =
+ (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
+ CFSTR("WebPluginName"));
+ NSString* plugin_vers =
+ (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
+ CFSTR("CFBundleShortVersionString"));
+ NSString* plugin_desc =
+ (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
+ CFSTR("WebPluginDescription"));
+
+ if (plugin_name)
+ info->name = base::SysNSStringToWide(plugin_name);
+ else
+ info->name = UTF8ToWide(filename.BaseName().value());
+ info->path = filename;
+ if (plugin_vers)
+ info->version = base::SysNSStringToWide(plugin_vers);
+ if (plugin_desc)
+ info->desc = base::SysNSStringToWide(plugin_desc);
+ else
+ info->desc = UTF8ToWide(filename.BaseName().value());
+
+ return true;
+}
+
+class ScopedBundleResourceFile {
+ public:
+ ScopedBundleResourceFile(CFBundleRef bundle) : bundle_(bundle) {
+ old_ref_num_ = CurResFile();
+ bundle_ref_num_ = CFBundleOpenBundleResourceMap(bundle);
+ UseResFile(bundle_ref_num_);
+ }
+ ~ScopedBundleResourceFile() {
+ UseResFile(old_ref_num_);
+ CFBundleCloseBundleResourceMap(bundle_, bundle_ref_num_);
+ }
+
+ private:
+ CFBundleRef bundle_;
+ CFBundleRefNum bundle_ref_num_;
+ ResFileRefNum old_ref_num_;
+};
+
+bool GetSTRResource(CFBundleRef bundle, short res_id,
+ std::vector<std::string>* contents) {
+ Handle res_handle = Get1Resource('STR#', res_id);
+ if (!res_handle || !*res_handle)
+ return false;
+
+ char* pointer = *res_handle;
+ short num_strings = *(short*)pointer;
+ pointer += sizeof(short);
+ for (short i = 0; i < num_strings; ++i) {
+ // Despite being 8-bits wide, these are legacy encoded. Make a round trip.
+ scoped_cftyperef<CFStringRef> str(CFStringCreateWithPascalStringNoCopy(
+ kCFAllocatorDefault,
+ (unsigned char*)pointer,
+ GetApplicationTextEncoding(), // is this right?
+ kCFAllocatorNull)); // perhaps CFStringGetSystemEncoding?
+ contents->push_back(base::SysCFStringRefToUTF8(str.get()));
+ pointer += 1+*pointer;
+ }
+
+ return true;
+}
+
+bool ReadSTRPluginInfo(const FilePath& filename, CFBundleRef bundle,
+ WebPluginInfo* info) {
+ ScopedBundleResourceFile res_file(bundle);
+
+ std::vector<std::string> type_strings;
+ if (!GetSTRResource(bundle, kSTRTypeDefinitionResourceID, &type_strings))
+ return false;
+
+ std::vector<std::string> type_descs;
+ bool have_type_descs = GetSTRResource(bundle,
+ kSTRTypeDescriptionResourceID,
+ &type_descs);
+
+ std::vector<std::string> plugin_descs;
+ bool have_plugin_descs = GetSTRResource(bundle,
+ kSTRPluginDescriptionResourceID,
+ &plugin_descs);
+
+ size_t num_types = type_strings.size()/2;
+
+ for (size_t i = 0; i < num_types; ++i) {
+ WebPluginMimeType mime;
+ mime.mime_type = StringToLowerASCII(type_strings[2*i]);
+ if (have_type_descs && i < type_descs.size())
+ mime.description = UTF8ToWide(type_descs[i]);
+ SplitString(StringToLowerASCII(type_strings[2*i+1]), ',',
+ &mime.file_extensions);
+
+ info->mime_types.push_back(mime);
+ }
+
+ NSString* plugin_vers =
+ (NSString*)CFBundleGetValueForInfoDictionaryKey(bundle,
+ CFSTR("CFBundleShortVersionString"));
+
+ if (have_plugin_descs && plugin_descs.size() > 1)
+ info->name = UTF8ToWide(plugin_descs[1]);
+ else
+ info->name = UTF8ToWide(filename.BaseName().value());
+ info->path = filename;
+ if (plugin_vers)
+ info->version = base::SysNSStringToWide(plugin_vers);
+ if (have_plugin_descs && plugin_descs.size() > 0)
+ info->desc = UTF8ToWide(plugin_descs[0]);
+ else
+ info->desc = UTF8ToWide(filename.BaseName().value());
+
+ return true;
+}
+
+} // anonymous namespace
+
+bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
+ WebPluginInfo* info) {
+ // TODO(avi): If an internal plugin is requested, immediately return with its
+ // info.
+ if (filename.value() == kDefaultPluginLibraryName)
+ return false; // TODO(avi): default plugin
+
+ // There are two ways to get information about plugin capabilities. One is an
+ // Info.plist set of keys, documented at
+ // http://developer.apple.com/documentation/InternetWeb/Conceptual/WebKit_PluginProgTopic/Concepts/AboutPlugins.html .
+ // The other is a set of STR# resources, documented at
+ // https://developer.mozilla.org/En/Gecko_Plugin_API_Reference/Plug-in_Development_Overview .
+ //
+ // Historically, the data was maintained in the STR# resources. Apple, with
+ // the introduction of WebKit, noted the weaknesses of resources and moved the
+ // information into the Info.plist. Mozilla had always supported a
+ // NP_GetMIMEDescription() entry point for Unix plugins and also supports it
+ // on the Mac to supplement the STR# format. WebKit does not support
+ // NP_GetMIMEDescription() and neither do we. (That entry point is documented
+ // at https://developer.mozilla.org/en/NP_GetMIMEDescription .) We prefer the
+ // Info.plist format because it's more extensible and has a defined encoding,
+ // but will fall back to the STR# format of the data if it is not present in
+ // the Info.plist.
+ //
+ // The parsing of the data lives in the two functions ReadSTRPluginInfo() and
+ // ReadPlistPluginInfo(), but a summary of the formats follows.
+ //
+ // Each data type handled by a plugin has several properties:
+ // - <<type0mimetype>>
+ // - <<type0fileextension0>>..<<type0fileextensionk>>
+ // - <<type0description>>
+ //
+ // Each plugin may have any number of types defined. In addition, the plugin
+ // itself has properties:
+ // - <<plugindescription>>
+ // - <<pluginname>>
+ //
+ // For the Info.plist version, the data is formatted as follows (in text plist
+ // format):
+ // {
+ // ... the usual plist keys ...
+ // WebPluginDescription = <<plugindescription>>;
+ // WebPluginMIMETypes = {
+ // <<type0mimetype>> = {
+ // WebPluginExtensions = (
+ // <<type0fileextension0>>,
+ // ...
+ // <<type0fileextensionk>>,
+ // );
+ // WebPluginTypeDescription = <<type0description>>;
+ // };
+ // <<type1mimetype>> = { ... };
+ // ...
+ // <<typenmimetype>> = { ... };
+ // };
+ // WebPluginName = <<pluginname>>;
+ // }
+ //
+ // Alternatively (and this is undocumented), rather than a WebPluginMIMETypes
+ // key, there may be a WebPluginMIMETypesFilename key. If it is present, then
+ // it is the name of a file in the user's preferences folder in which to find
+ // the WebPluginMIMETypes key. If the key is present but the file doesn't
+ // exist, we must load the plugin and call a specific function to have the
+ // plugin create the file.
+ //
+ // If we do not find those keys in the Info.plist, we fall back to the STR#
+ // resources. In them, the data is formatted as follows:
+ // STR# 128
+ // (1) <<type0mimetype>>
+ // (2) <<type0fileextension0>>,...,<<type0fileextensionk>>
+ // (3) <<type1mimetype>>
+ // (4) <<type1fileextension0>>,...,<<type1fileextensionk>>
+ // (...)
+ // (2n+1) <<typenmimetype>>
+ // (2n+2) <<typenfileextension0>>,...,<<typenfileextensionk>>
+ // STR# 127
+ // (1) <<type0description>>
+ // (2) <<type1description>>
+ // (...)
+ // (n+1) <<typendescription>>
+ // STR# 126
+ // (1) <<plugindescription>>
+ // (2) <<pluginname>>
+ //
+ // Strictly speaking, only STR# 128 is required.
+
+ scoped_cftyperef<CFBundleRef> bundle(LoadNativeLibrary(filename));
+ if (!bundle)
+ return false;
+
+ // preflight
+
+ OSType type = 0;
+ CFBundleGetPackageInfo(bundle.get(), &type, NULL);
+ if (type != FOUR_CHAR_CODE('BRPL'))
+ return false;
+
+ CFErrorRef error;
+ Boolean would_load = CFBundlePreflightExecutable(bundle.get(), &error);
+ if (!would_load)
+ return false;
+
+ // get the info
+
+ if (ReadPlistPluginInfo(filename, bundle.get(), info))
+ return true;
+
+ if (ReadSTRPluginInfo(filename, bundle.get(), info))
+ return true;
+
+ // ... or not
+
+ return false;
+}
+
+} // namespace NPAPI
+
diff --git a/webkit/glue/plugins/plugin_lib_win.cc b/webkit/glue/plugins/plugin_lib_win.cc
new file mode 100644
index 0000000..bc662ec
--- /dev/null
+++ b/webkit/glue/plugins/plugin_lib_win.cc
@@ -0,0 +1,185 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "webkit/glue/plugins/plugin_lib.h"
+
+#include "base/file_version_info.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "webkit/activex_shim/npp_impl.h"
+#include "webkit/default_plugin/plugin_main.h"
+#include "webkit/glue/plugins/plugin_constants_win.h"
+#include "webkit/glue/plugins/plugin_list.h"
+
+namespace NPAPI
+{
+
+static const InternalPluginInfo g_internal_plugins[] = {
+ {
+ {FilePath(kActiveXShimFileName),
+ L"ActiveX Plug-in",
+ L"ActiveX Plug-in provides a shim to support ActiveX controls",
+ L"1, 0, 0, 1",
+ L"application/x-oleobject|application/oleobject",
+ L"*|*",
+ L""
+ },
+ activex_shim::ActiveX_Shim_NP_GetEntryPoints,
+ activex_shim::ActiveX_Shim_NP_Initialize,
+ activex_shim::ActiveX_Shim_NP_Shutdown
+ },
+ {
+ {FilePath(kActiveXShimFileNameForMediaPlayer),
+ kActiveXShimFileNameForMediaPlayer,
+ L"Windows Media Player",
+ L"1, 0, 0, 1",
+ L"application/x-ms-wmp|application/asx|video/x-ms-asf-plugin|"
+ L"application/x-mplayer2|video/x-ms-asf|video/x-ms-wm|audio/x-ms-wma|"
+ L"audio/x-ms-wax|video/x-ms-wmv|video/x-ms-wvx",
+ L"*|*|*|*|asf,asx,*|wm,*|wma,*|wax,*|wmv,*|wvx,*",
+ L""
+ },
+ activex_shim::ActiveX_Shim_NP_GetEntryPoints,
+ activex_shim::ActiveX_Shim_NP_Initialize,
+ activex_shim::ActiveX_Shim_NP_Shutdown
+ },
+ {
+ {FilePath(kDefaultPluginLibraryName),
+ L"Default Plug-in",
+ L"Provides functionality for installing third-party plug-ins",
+ L"1, 0, 0, 1",
+ L"*",
+ L"",
+ L""
+ },
+ default_plugin::NP_GetEntryPoints,
+ default_plugin::NP_Initialize,
+ default_plugin::NP_Shutdown
+ },
+};
+
+static const size_t g_internal_plugins_size = arraysize(g_internal_plugins);
+
+/* static */
+void PluginLib::GetInternalPlugins(const InternalPluginInfo** plugins,
+ size_t* count) {
+ *plugins = g_internal_plugins;
+ *count = g_internal_plugins_size;
+}
+
+/* static */
+PluginLib::NativeLibrary PluginLib::LoadNativeLibrary(
+ const FilePath& library_path) {
+ // Switch the current directory to the plugin directory as the plugin
+ // may have dependencies on dlls in this directory.
+ bool restore_directory = false;
+ std::wstring current_directory;
+ if (PathService::Get(base::DIR_CURRENT, &current_directory)) {
+ FilePath plugin_path = library_path.DirName();
+ if (!plugin_path.value().empty()) {
+ PathService::SetCurrentDirectory(plugin_path.value());
+ restore_directory = true;
+ }
+ }
+
+ HMODULE module = LoadLibrary(library_path.value().c_str());
+ if (restore_directory)
+ PathService::SetCurrentDirectory(current_directory);
+
+ return module;
+}
+
+/* static */
+void PluginLib::UnloadNativeLibrary(NativeLibrary library) {
+ FreeLibrary(library);
+}
+
+/* static */
+void* PluginLib::GetFunctionPointerFromNativeLibrary(
+ NativeLibrary library,
+ NativeLibraryFunctionNameType name) {
+ return GetProcAddress(library, name);
+}
+
+namespace {
+
+// Creates WebPluginInfo structure based on read in or built in
+// PluginVersionInfo.
+bool 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);
+ SplitString(base::SysWideToNativeMB(pvi.file_extents), '|', &file_extensions);
+ SplitString(pvi.file_open_names, '|', &descriptions);
+
+ if (mime_types.empty())
+ return false;
+
+ info->name = pvi.product_name;
+ info->desc = pvi.file_description;
+ info->version = pvi.file_version;
+ info->path = FilePath(pvi.path);
+
+ for (size_t i = 0; i < mime_types.size(); ++i) {
+ WebPluginMimeType mime_type;
+ mime_type.mime_type = StringToLowerASCII(mime_types[i]);
+ if (file_extensions.size() > i)
+ SplitString(file_extensions[i], ',', &mime_type.file_extensions);
+
+ if (descriptions.size() > i) {
+ mime_type.description = descriptions[i];
+
+ // Remove the extension list from the description.
+ size_t ext = mime_type.description.find(L"(*");
+ if (ext != std::wstring::npos) {
+ if (ext > 1 && mime_type.description[ext -1] == ' ')
+ ext--;
+
+ mime_type.description.erase(ext);
+ }
+ }
+
+ info->mime_types.push_back(mime_type);
+ }
+
+ return true;
+}
+
+}
+
+bool PluginLib::ReadWebPluginInfo(const FilePath &filename,
+ WebPluginInfo* info) {
+ for (int i = 0; i < g_internal_plugins_size; ++i) {
+ if (filename == g_internal_plugins[i].version_info.path)
+ 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>|...
+ // For example:
+ // video/quicktime|audio/aiff|image/jpeg
+ scoped_ptr<FileVersionInfo> version_info(
+ FileVersionInfo::CreateFileVersionInfo(filename.value()));
+ if (!version_info.get())
+ return false;
+
+ PluginVersionInfo pvi;
+ version_info->GetValue(L"MIMEType", &pvi.mime_types);
+ version_info->GetValue(L"FileExtents", &pvi.file_extents);
+ 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.path = filename;
+
+ return CreateWebPluginInfo(pvi, info);
+}
+
+} // namespace NPAPI
+
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc
index fea4c30..4d48a9c 100644
--- a/webkit/glue/plugins/plugin_list.cc
+++ b/webkit/glue/plugins/plugin_list.cc
@@ -2,57 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <algorithm>
-#include <tchar.h>
+#include "config.h"
#include "webkit/glue/plugins/plugin_list.h"
-#include "base/command_line.h"
-#include "base/file_util.h"
#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/registry.h"
-#include "base/scoped_ptr.h"
-#include "base/string_piece.h"
#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 "googleurl/src/gurl.h"
-using base::TimeDelta;
-using base::TimeTicks;
+#if defined(OS_WIN)
+#include "webkit/activex_shim/activex_shared.h"
+#include "webkit/glue/plugins/plugin_constants_win.h"
+#endif
namespace NPAPI
{
scoped_refptr<PluginList> PluginList::singleton_;
-static const TCHAR kRegistryApps[] =
- _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths");
-static const TCHAR kRegistryFirefox[] = _T("firefox.exe");
-static const TCHAR kRegistryAcrobat[] = _T("Acrobat.exe");
-static const TCHAR kRegistryAcrobatReader[] = _T("AcroRd32.exe");
-static const TCHAR kRegistryWindowsMedia[] = _T("wmplayer.exe");
-static const TCHAR kRegistryQuickTime[] = _T("QuickTimePlayer.exe");
-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 TCHAR kRegistryJava[] =
- _T("Software\\JavaSoft\\Java Runtime Environment");
-static const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
-static const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion");
-static const TCHAR kRegistryJavaHome[] = _T("JavaHome");
-
// Extra paths to search.
static std::vector<FilePath>* extra_plugin_paths_ = NULL;
@@ -75,10 +46,7 @@ void PluginList::AddExtraPluginPath(const FilePath& plugin_path) {
PluginList::PluginList() :
plugins_loaded_(false) {
- CommandLine command_line;
- dont_load_new_wmp_ = command_line.HasSwitch(kUseOldWMPPluginSwitch);
- use_internal_activex_shim_ =
- !command_line.HasSwitch(kNoNativeActiveXShimSwitch);
+ PlatformInit();
}
void PluginList::LoadPlugins(bool refresh) {
@@ -88,34 +56,15 @@ void PluginList::LoadPlugins(bool refresh) {
plugins_.clear();
plugins_loaded_ = true;
- TimeTicks start_time = TimeTicks::Now();
+ base::TimeTicks start_time = base::TimeTicks::Now();
LoadInternalPlugins();
- std::set<FilePath> directories_to_scan;
-
- // Load from the application-specific area
- GetAppDirectory(&directories_to_scan);
-
- // Load from the executable area
- GetExeDirectory(&directories_to_scan);
+ std::vector<FilePath> directories_to_scan;
+ GetPluginDirectories(&directories_to_scan);
- // Load Java
- GetJavaDirectory(&directories_to_scan);
-
- // Load firefox plugins too. This is mainly to try to locate
- // a pre-installed Flash player.
- GetFirefoxDirectory(&directories_to_scan);
-
- // Firefox hard-codes the paths of some popular plugins to ensure that
- // the plugins are found. We are going to copy this as well.
- GetAcrobatDirectory(&directories_to_scan);
- GetQuicktimeDirectory(&directories_to_scan);
- GetWindowsMediaDirectory(&directories_to_scan);
-
- for (std::set<FilePath>::const_iterator iter = directories_to_scan.begin();
- iter != directories_to_scan.end(); ++iter) {
- LoadPluginsFromDir(*iter);
+ for (size_t i = 0; i < directories_to_scan.size(); ++i) {
+ LoadPluginsFromDir(directories_to_scan[i]);
}
if (extra_plugin_paths_) {
@@ -131,76 +80,26 @@ void PluginList::LoadPlugins(bool refresh) {
}
}
- TimeTicks end_time = TimeTicks::Now();
- TimeDelta elapsed = end_time - start_time;
+ base::TimeTicks end_time = base::TimeTicks::Now();
+ base::TimeDelta elapsed = end_time - start_time;
DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms.";
}
-void PluginList::LoadPluginsFromDir(const FilePath &path) {
- WIN32_FIND_DATA find_file_data;
- HANDLE find_handle;
-
- std::wstring dir = path.value();
- // FindFirstFile requires that you specify a wildcard for directories.
- dir.append(L"\\NP*.DLL");
-
- find_handle = FindFirstFile(dir.c_str(), &find_file_data);
- if (find_handle == INVALID_HANDLE_VALUE)
- return;
-
- do {
- if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- FilePath filename = path.Append(find_file_data.cFileName);
- LoadPlugin(filename);
- }
- } while (FindNextFile(find_handle, &find_file_data) != 0);
-
- DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
- 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) {
WebPluginInfo plugin_info;
if (!PluginLib::ReadWebPluginInfo(path, &plugin_info))
return;
- if (!ShouldLoadPlugin(plugin_info.path))
+ if (!ShouldLoadPlugin(plugin_info))
return;
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (plugins_[i].path.BaseName() == path.BaseName() &&
- !IsNewerVersion(plugins_[i].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
// to handle mimeTypes on its own.
const std::string &mime_type = plugin_info.mime_types[i].mime_type;
if (mime_type == "*" ) {
-#ifndef NDEBUG
+#if defined(OS_WIN) && !defined(NDEBUG)
// Make an exception for NPSPY.
if (path.BaseName().value() == L"npspy.dll")
break;
@@ -212,61 +111,6 @@ void PluginList::LoadPlugin(const FilePath &path) {
plugins_.push_back(plugin_info);
}
-bool PluginList::ShouldLoadPlugin(const FilePath& path) {
- std::wstring filename = StringToLowerASCII(path.BaseName().value());
- // Depends on XPCOM.
- 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 == kYahooApplicationStatePlugin)
- return false;
-
- // We will use activex shim to handle embeded wmp media.
- if (use_internal_activex_shim_) {
- if (filename == kNewWMPPlugin || filename == kOldWMPPlugin)
- return false;
- } else {
- // If both the new and old WMP plugins exist, only load the new one.
- if (filename == kNewWMPPlugin) {
- if (dont_load_new_wmp_)
- return false;
-
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (plugins_[i].path.BaseName().value() == kOldWMPPlugin) {
- plugins_.erase(plugins_.begin() + i);
- break;
- }
- }
- } else if (filename == kOldWMPPlugin) {
- for (size_t i = 0; i < plugins_.size(); ++i) {
- if (plugins_[i].path.BaseName().value() == kNewWMPPlugin)
- return false;
- }
- }
- }
-
- return true;
-}
-
-void PluginList::LoadInternalPlugins() {
- if (!use_internal_activex_shim_)
- return;
-
- WebPluginInfo info;
- if (PluginLib::ReadWebPluginInfo(FilePath(kActiveXShimFileName),
- &info)) {
- plugins_.push_back(info);
- }
-
- if (PluginLib::ReadWebPluginInfo(FilePath(kActivexShimFileNameForMediaPlayer),
- &info)) {
- plugins_.push_back(info);
- }
-}
-
bool PluginList::FindPlugin(const std::string& mime_type,
const std::string& clsid,
bool allow_wildcard,
@@ -275,12 +119,14 @@ bool PluginList::FindPlugin(const std::string& mime_type,
for (size_t i = 0; i < plugins_.size(); ++i) {
if (SupportsType(plugins_[i], mime_type, allow_wildcard)) {
+#if defined(OS_WIN)
if (!clsid.empty() && plugins_[i].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;
}
+#endif
*info = plugins_[i];
return true;
}
@@ -291,13 +137,12 @@ bool PluginList::FindPlugin(const std::string& 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())
+ std::string path = url.path();
+ std::string::size_type last_dot = path.rfind('.');
+ if (last_dot == std::string::npos)
return false;
-
- std::string extension =
- StringToLowerASCII(base::SysWideToNativeMB(extension_wide));
+
+ std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
for (size_t i = 0; i < plugins_.size(); ++i) {
if (SupportsExtension(plugins_[i], extension, actual_mime_type)) {
@@ -361,9 +206,15 @@ bool PluginList::GetPluginInfo(const GURL& url,
bool allow_wildcard,
WebPluginInfo* info,
std::string* actual_mime_type) {
- bool found = FindPlugin(mime_type, clsid, allow_wildcard, info);
- if (!found ||
- (info->path.value() == kDefaultPluginLibraryName && clsid.empty())) {
+ bool found = FindPlugin(mime_type,
+ clsid,
+ allow_wildcard, info);
+ if (!found
+ || (info->path.value() == kDefaultPluginLibraryName
+#if defined(OS_WIN)
+ && clsid.empty()
+#endif
+ )) {
WebPluginInfo info2;
if (FindPlugin(url, actual_mime_type, &info2)) {
found = true;
@@ -390,145 +241,5 @@ void PluginList::Shutdown() {
// TODO
}
-void PluginList::GetAppDirectory(std::set<FilePath>* plugin_dirs) {
- std::wstring app_path;
- // TODO(avi): use PathService directly
- if (!webkit_glue::GetApplicationDirectory(&app_path))
- return;
-
- app_path.append(L"\\plugins");
- plugin_dirs->insert(FilePath(app_path));
-}
-
-void PluginList::GetExeDirectory(std::set<FilePath>* plugin_dirs) {
- std::wstring exe_path;
- // TODO(avi): use PathService directly
- if (!webkit_glue::GetExeDirectory(&exe_path))
- return;
-
- exe_path.append(L"\\plugins");
- plugin_dirs->insert(FilePath(exe_path));
-}
-
-// Gets the installed path for a registered app.
-static bool GetInstalledPath(const TCHAR* app, FilePath* out) {
- std::wstring reg_path(kRegistryApps);
- reg_path.append(L"\\");
- reg_path.append(app);
-
- RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
- std::wstring path;
- if (key.ReadValue(kRegistryPath, &path)) {
- *out = FilePath(path);
- return true;
- }
-
- return false;
-}
-
-// Enumerate through the registry key to find all installed FireFox paths.
-// FireFox 3 beta and version 2 can coexist. See bug: 1025003
-static void GetFirefoxInstalledPaths(std::vector<FilePath>* out) {
- RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled);
- for (; it.Valid(); ++it) {
- std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" +
- it.Name() + L"\\Main";
- RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
- std::wstring install_dir;
- if (!key.ReadValue(L"Install Directory", &install_dir))
- continue;
- out->push_back(FilePath(install_dir));
- }
-}
-
-void PluginList::GetFirefoxDirectory(std::set<FilePath>* plugin_dirs) {
- std::vector<FilePath> paths;
- GetFirefoxInstalledPaths(&paths);
- for (unsigned int i = 0; i < paths.size(); ++i) {
- plugin_dirs->insert(paths[i].Append(L"plugins"));
- }
-
- GetPluginsInRegistryDirectory(
- HKEY_CURRENT_USER, kRegistryMozillaPlugins, plugin_dirs);
- GetPluginsInRegistryDirectory(
- HKEY_LOCAL_MACHINE, kRegistryMozillaPlugins, plugin_dirs);
-
- std::wstring firefox_app_data_plugin_path;
- if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
- firefox_app_data_plugin_path += L"\\Mozilla\\plugins";
- plugin_dirs->insert(FilePath(firefox_app_data_plugin_path));
- }
-}
-
-void PluginList::GetAcrobatDirectory(std::set<FilePath>* plugin_dirs) {
- FilePath path;
- if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
- !GetInstalledPath(kRegistryAcrobat, &path)) {
- return;
- }
-
- plugin_dirs->insert(path.Append(L"Browser"));
-}
-
-void PluginList::GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs) {
- FilePath path;
- if (GetInstalledPath(kRegistryQuickTime, &path))
- plugin_dirs->insert(path.Append(L"plugins"));
-}
-
-void PluginList::GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) {
- FilePath path;
- if (GetInstalledPath(kRegistryWindowsMedia, &path))
- plugin_dirs->insert(path);
-}
-
-void PluginList::GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
- // Load the new NPAPI Java plugin
- // 1. Open the main JRE key under HKLM
- RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE);
-
- // 2. Read the current Java version
- std::wstring java_version;
- if (!java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version))
- java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);
-
- if (!java_version.empty()) {
- java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);
-
- // 3. Install path of the JRE binaries is specified in "JavaHome"
- // value under the Java version key.
- std::wstring java_plugin_directory;
- if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {
-
- // 4. The new plugin resides under the 'bin/new_plugin'
- // subdirectory.
- DCHECK(!java_plugin_directory.empty());
- java_plugin_directory.append(L"\\bin\\new_plugin");
-
- // 5. We don't know the exact name of the DLL but it's in the form
- // NP*.dll so just invoke LoadPlugins on this path.
- plugin_dirs->insert(FilePath(java_plugin_directory));
- }
- }
-}
-
-void PluginList::GetPluginsInRegistryDirectory(
- HKEY root_key,
- const std::wstring& registry_folder,
- std::set<FilePath>* plugin_dirs) {
- for (RegistryKeyIterator iter(root_key, registry_folder.c_str());
- iter.Valid(); ++iter) {
- // Use the registry to gather plugin across the file system.
- std::wstring reg_path = registry_folder;
- reg_path.append(L"\\");
- reg_path.append(iter.Name());
- RegKey key(root_key, reg_path.c_str());
-
- std::wstring path;
- if (key.ReadValue(kRegistryPath, &path))
- plugin_dirs->insert(FilePath(path).DirName());
- }
-}
-
} // namespace NPAPI
diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h
index 0b3eba2..c425faa 100644
--- a/webkit/glue/plugins/plugin_list.h
+++ b/webkit/glue/plugins/plugin_list.h
@@ -12,6 +12,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/file_path.h"
#include "base/ref_counted.h"
#include "webkit/glue/webplugin.h"
@@ -20,19 +21,7 @@ class GURL;
namespace NPAPI
{
-// Used by plugins_test when testing the older WMP plugin to force the new
-// plugin to not get loaded.
-#define kUseOldWMPPluginSwitch L"use-old-wmp"
-// Used for testing ActiveX shim. By default it's off. If this flag is specified
-// we will use the native ActiveX shim.
-#define kNoNativeActiveXShimSwitch L"no-activex"
-// Internal file name for activex shim, used as a unique identifier.
-#define kActiveXShimFileName L"activex-shim"
-// Internal file name for windows media player.
-#define kActivexShimFileNameForMediaPlayer \
- L"Microsoft® Windows Media Player Firefox Plugin"
-
-#define kDefaultPluginLibraryName L"default_plugin"
+#define kDefaultPluginLibraryName FILE_PATH_LITERAL("default_plugin")
class PluginInstance;
@@ -68,7 +57,7 @@ class PluginList : public base::RefCounted<PluginList> {
// The mime type which corresponds to the URL is optionally returned
// back.
// The allow_wildcard parameter controls whether this function returns
- // plugins which support wildcard mime types (* as the mime type)
+ // plugins which support wildcard mime types (* as the mime type).
bool GetPluginInfo(const GURL& url,
const std::string& mime_type,
const std::string& clsid,
@@ -77,7 +66,7 @@ class PluginList : public base::RefCounted<PluginList> {
std::string* actual_mime_type);
// Get plugin info by plugin path. Returns true if the plugin is found and
- // WebPluginInfo has been filled in |info|
+ // WebPluginInfo has been filled in |info|.
bool GetPluginInfoByPath(const FilePath& plugin_path,
WebPluginInfo* info);
private:
@@ -94,9 +83,9 @@ 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& path);
+ bool ShouldLoadPlugin(const WebPluginInfo& info);
- // Load internal plugins. Right now there is only one: activex_shim.
+ // Load internal plugins.
void LoadInternalPlugins();
// Find a plugin by mime type, and clsid.
@@ -129,42 +118,32 @@ class PluginList : public base::RefCounted<PluginList> {
const std::string &extension,
std::string* actual_mime_type);
- // The application path where we expect to find plugins.
- static void GetAppDirectory(std::set<FilePath>* plugin_dirs);
-
- // The executable path where we expect to find plugins.
- static void GetExeDirectory(std::set<FilePath>* plugin_dirs);
-
- // Get plugin directory locations from the Firefox install path. This is kind
- // of a kludge, but it helps us locate the flash player for users that
- // already have it for firefox. Not having to download yet-another-plugin
- // is a good thing.
- void GetFirefoxDirectory(std::set<FilePath>* plugin_dirs);
-
- // Hardcoded logic to detect Acrobat plugins locations.
- void GetAcrobatDirectory(std::set<FilePath>* plugin_dirs);
-
- // Hardcoded logic to detect QuickTime plugin location.
- void GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs);
-
- // Hardcoded logic to detect Windows Media Player plugin location.
- void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs);
-
- // Hardcoded logic to detect Java plugin location.
- void GetJavaDirectory(std::set<FilePath>* plugin_dirs);
+ //
+ // Platform functions
+ //
+ // Do any initialization.
+ void PlatformInit();
+
+ // Get the ordered list of directories from which to load plugins
+ void GetPluginDirectories(std::vector<FilePath>* plugin_dirs);
+
+ //
+ // Command-line switches
+ //
+
#if defined(OS_WIN)
- // Search the registry at the given path and detect plugin directories.
- void GetPluginsInRegistryDirectory(HKEY root_key,
- const std::wstring& registry_folder,
- std::set<FilePath>* plugin_dirs);
-#endif
-
// true if we shouldn't load the new WMP plugin.
bool dont_load_new_wmp_;
+ // true if we should use our internal ActiveX shim
bool use_internal_activex_shim_;
+#endif
+ //
+ // Internals
+ //
+
static scoped_refptr<PluginList> singleton_;
bool plugins_loaded_;
diff --git a/webkit/glue/plugins/plugin_list_mac.mm b/webkit/glue/plugins/plugin_list_mac.mm
new file mode 100644
index 0000000..0ebdb6c
--- /dev/null
+++ b/webkit/glue/plugins/plugin_list_mac.mm
@@ -0,0 +1,92 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "webkit/glue/plugins/plugin_list.h"
+
+#include "base/file_util.h"
+#include "base/mac_util.h"
+#include "webkit/glue/plugins/plugin_lib.h"
+
+namespace {
+
+void GetPluginCommonDirectory(std::vector<FilePath>* plugin_dirs,
+ bool user) {
+ // Note that there are no NSSearchPathDirectory constants for these
+ // directories so we can't use Cocoa's NSSearchPathForDirectoriesInDomains().
+ // Interestingly, Safari hard-codes the location (see
+ // WebKit/WebKit/mac/Plugins/WebPluginDatabase.mm's +_defaultPlugInPaths).
+ FSRef ref;
+ OSErr err = FSFindFolder(user ? kLocalDomain : kUserDomain,
+ kInternetPlugInFolderType, false, &ref);
+
+ if (err)
+ return;
+
+ plugin_dirs->push_back(FilePath(mac_util::PathFromFSRef(ref)));
+}
+
+void GetPluginPrivateDirectory(std::vector<FilePath>* plugin_dirs) {
+ NSString* plugin_path = [[NSBundle mainBundle] builtInPlugInsPath];
+ if (!plugin_path)
+ return;
+
+ plugin_dirs->push_back(FilePath([plugin_path fileSystemRepresentation]));
+}
+
+} // namespace
+
+namespace NPAPI
+{
+
+PluginList::PluginList() :
+ plugins_loaded_(false) {
+}
+
+void PluginList::PlatformInit() {
+}
+
+void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
+ // Load from the user's area
+ GetPluginCommonDirectory(plugin_dirs, true);
+
+ // Load from the machine-wide area
+ GetPluginCommonDirectory(plugin_dirs, false);
+
+ // Load any bundled plugins
+ GetPluginPrivateDirectory(plugin_dirs);
+}
+
+void PluginList::LoadPluginsFromDir(const FilePath &path) {
+ file_util::FileEnumerator enumerator(path,
+ false, // not recursive
+ file_util::FileEnumerator::DIRECTORIES);
+ for (FilePath path = enumerator.Next(); !path.value().empty();
+ path = enumerator.Next()) {
+ LoadPlugin(path);
+ }
+}
+
+bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) {
+
+ // Hierarchy check
+ // (we're loading plugins hierarchically from Library folders, so plugins we
+ // encounter earlier must override plugins we encounter later)
+
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (plugins_[i].path.BaseName() == info.path.BaseName()) {
+ return false; // We already have a loaded plugin higher in the hierarchy.
+ }
+ }
+
+ return true;
+}
+
+void PluginList::LoadInternalPlugins() {
+ // none for now
+}
+
+} // namespace NPAPI
+
diff --git a/webkit/glue/plugins/plugin_list_win.cc b/webkit/glue/plugins/plugin_list_win.cc
new file mode 100644
index 0000000..208211f
--- /dev/null
+++ b/webkit/glue/plugins/plugin_list_win.cc
@@ -0,0 +1,343 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <tchar.h>
+
+#include "webkit/glue/plugins/plugin_list.h"
+
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "base/registry.h"
+#include "base/string_util.h"
+#include "webkit/glue/plugins/plugin_constants_win.h"
+#include "webkit/glue/plugins/plugin_lib.h"
+#include "webkit/glue/webkit_glue.h"
+
+namespace {
+
+const TCHAR kRegistryApps[] =
+ _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths");
+const TCHAR kRegistryFirefox[] = _T("firefox.exe");
+const TCHAR kRegistryAcrobat[] = _T("Acrobat.exe");
+const TCHAR kRegistryAcrobatReader[] = _T("AcroRd32.exe");
+const TCHAR kRegistryWindowsMedia[] = _T("wmplayer.exe");
+const TCHAR kRegistryQuickTime[] = _T("QuickTimePlayer.exe");
+const TCHAR kRegistryPath[] = _T("Path");
+const TCHAR kRegistryMozillaPlugins[] = _T("SOFTWARE\\MozillaPlugins");
+const TCHAR kRegistryFirefoxInstalled[] =
+ _T("SOFTWARE\\Mozilla\\Mozilla Firefox");
+const TCHAR kMozillaActiveXPlugin[] = _T("npmozax.dll");
+const TCHAR kNewWMPPlugin[] = _T("np-mswmp.dll");
+const TCHAR kOldWMPPlugin[] = _T("npdsplay.dll");
+const TCHAR kYahooApplicationStatePlugin[] = _T("npystate.dll");
+const TCHAR kRegistryJava[] =
+ _T("Software\\JavaSoft\\Java Runtime Environment");
+const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
+const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion");
+const TCHAR kRegistryJavaHome[] = _T("JavaHome");
+
+// The application path where we expect to find plugins.
+void GetAppDirectory(std::set<FilePath>* plugin_dirs) {
+ std::wstring app_path;
+ // TODO(avi): use PathService directly
+ if (!webkit_glue::GetApplicationDirectory(&app_path))
+ return;
+
+ app_path.append(L"\\plugins");
+ plugin_dirs->insert(FilePath(app_path));
+}
+
+// The executable path where we expect to find plugins.
+void GetExeDirectory(std::set<FilePath>* plugin_dirs) {
+ std::wstring exe_path;
+ // TODO(avi): use PathService directly
+ if (!webkit_glue::GetExeDirectory(&exe_path))
+ return;
+
+ exe_path.append(L"\\plugins");
+ plugin_dirs->insert(FilePath(exe_path));
+}
+
+// Gets the installed path for a registered app.
+bool GetInstalledPath(const TCHAR* app, FilePath* out) {
+ std::wstring reg_path(kRegistryApps);
+ reg_path.append(L"\\");
+ reg_path.append(app);
+
+ RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
+ std::wstring path;
+ if (key.ReadValue(kRegistryPath, &path)) {
+ *out = FilePath(path);
+ return true;
+ }
+
+ return false;
+}
+
+// Search the registry at the given path and detect plugin directories.
+void GetPluginsInRegistryDirectory(
+ HKEY root_key,
+ const std::wstring& registry_folder,
+ std::set<FilePath>* plugin_dirs) {
+ for (RegistryKeyIterator iter(root_key, registry_folder.c_str());
+ iter.Valid(); ++iter) {
+ // Use the registry to gather plugin across the file system.
+ std::wstring reg_path = registry_folder;
+ reg_path.append(L"\\");
+ reg_path.append(iter.Name());
+ RegKey key(root_key, reg_path.c_str());
+
+ std::wstring path;
+ if (key.ReadValue(kRegistryPath, &path))
+ plugin_dirs->insert(FilePath(path).DirName());
+ }
+}
+
+// Enumerate through the registry key to find all installed FireFox paths.
+// FireFox 3 beta and version 2 can coexist. See bug: 1025003
+void GetFirefoxInstalledPaths(std::vector<FilePath>* out) {
+ RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled);
+ for (; it.Valid(); ++it) {
+ std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" +
+ it.Name() + L"\\Main";
+ RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
+ std::wstring install_dir;
+ if (!key.ReadValue(L"Install Directory", &install_dir))
+ continue;
+ out->push_back(FilePath(install_dir));
+ }
+}
+
+// Get plugin directory locations from the Firefox install path. This is kind
+// of a kludge, but it helps us locate the flash player for users that
+// already have it for firefox. Not having to download yet-another-plugin
+// is a good thing.
+void GetFirefoxDirectory(std::set<FilePath>* plugin_dirs) {
+ std::vector<FilePath> paths;
+ GetFirefoxInstalledPaths(&paths);
+ for (unsigned int i = 0; i < paths.size(); ++i) {
+ plugin_dirs->insert(paths[i].Append(L"plugins"));
+ }
+
+ GetPluginsInRegistryDirectory(
+ HKEY_CURRENT_USER, kRegistryMozillaPlugins, plugin_dirs);
+ GetPluginsInRegistryDirectory(
+ HKEY_LOCAL_MACHINE, kRegistryMozillaPlugins, plugin_dirs);
+
+ std::wstring firefox_app_data_plugin_path;
+ if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
+ firefox_app_data_plugin_path += L"\\Mozilla\\plugins";
+ plugin_dirs->insert(FilePath(firefox_app_data_plugin_path));
+ }
+}
+
+// Hardcoded logic to detect Acrobat plugins locations.
+void GetAcrobatDirectory(std::set<FilePath>* plugin_dirs) {
+ FilePath path;
+ if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
+ !GetInstalledPath(kRegistryAcrobat, &path)) {
+ return;
+ }
+
+ plugin_dirs->insert(path.Append(L"Browser"));
+}
+
+// Hardcoded logic to detect QuickTime plugin location.
+void GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs) {
+ FilePath path;
+ if (GetInstalledPath(kRegistryQuickTime, &path))
+ plugin_dirs->insert(path.Append(L"plugins"));
+}
+
+// Hardcoded logic to detect Windows Media Player plugin location.
+void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) {
+ FilePath path;
+ if (GetInstalledPath(kRegistryWindowsMedia, &path))
+ plugin_dirs->insert(path);
+}
+
+// Hardcoded logic to detect Java plugin location.
+void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
+ // Load the new NPAPI Java plugin
+ // 1. Open the main JRE key under HKLM
+ RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE);
+
+ // 2. Read the current Java version
+ std::wstring java_version;
+ if (!java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version))
+ java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);
+
+ if (!java_version.empty()) {
+ java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);
+
+ // 3. Install path of the JRE binaries is specified in "JavaHome"
+ // value under the Java version key.
+ std::wstring java_plugin_directory;
+ if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {
+
+ // 4. The new plugin resides under the 'bin/new_plugin'
+ // subdirectory.
+ DCHECK(!java_plugin_directory.empty());
+ java_plugin_directory.append(L"\\bin\\new_plugin");
+
+ // 5. We don't know the exact name of the DLL but it's in the form
+ // NP*.dll so just invoke LoadPlugins on this path.
+ plugin_dirs->insert(FilePath(java_plugin_directory));
+ }
+ }
+}
+
+}
+
+namespace NPAPI
+{
+
+void PluginList::PlatformInit() {
+ CommandLine command_line;
+ dont_load_new_wmp_ = command_line.HasSwitch(kUseOldWMPPluginSwitch);
+ use_internal_activex_shim_ =
+ !command_line.HasSwitch(kNoNativeActiveXShimSwitch);
+}
+
+void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
+ // We use a set for uniqueness, which we require, over order, which we do not.
+ std::set<FilePath> dirs;
+
+ // Load from the application-specific area
+ GetAppDirectory(&dirs);
+
+ // Load from the executable area
+ GetExeDirectory(&dirs);
+
+ // Load Java
+ GetJavaDirectory(&dirs);
+
+ // Load firefox plugins too. This is mainly to try to locate
+ // a pre-installed Flash player.
+ GetFirefoxDirectory(&dirs);
+
+ // Firefox hard-codes the paths of some popular plugins to ensure that
+ // the plugins are found. We are going to copy this as well.
+ GetAcrobatDirectory(&dirs);
+ GetQuicktimeDirectory(&dirs);
+ GetWindowsMediaDirectory(&dirs);
+
+ for (std::set<FilePath>::iterator i = dirs.begin(); i != dirs.end(); ++i)
+ plugin_dirs->push_back(*i);
+}
+
+void PluginList::LoadPluginsFromDir(const FilePath &path) {
+ WIN32_FIND_DATA find_file_data;
+ HANDLE find_handle;
+
+ std::wstring dir = path.value();
+ // FindFirstFile requires that you specify a wildcard for directories.
+ dir.append(L"\\NP*.DLL");
+
+ find_handle = FindFirstFile(dir.c_str(), &find_file_data);
+ if (find_handle == INVALID_HANDLE_VALUE)
+ return;
+
+ do {
+ if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ FilePath filename = path.Append(find_file_data.cFileName);
+ LoadPlugin(filename);
+ }
+ } while (FindNextFile(find_handle, &find_file_data) != 0);
+
+ DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
+ 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;
+}
+
+bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) {
+
+ // Version check
+
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (plugins_[i].path.BaseName() == info.path.BaseName() &&
+ !IsNewerVersion(plugins_[i].version, info.version)) {
+ return false; // We already have a loaded plugin whose version is newer.
+ }
+ }
+
+ // Troublemakers
+
+ std::wstring filename = StringToLowerASCII(info.path.BaseName().value());
+ // Depends on XPCOM.
+ 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 == kYahooApplicationStatePlugin)
+ return false;
+
+ // Special WMP handling
+
+ // We will use the ActiveX shim to handle embedded WMP media.
+ if (use_internal_activex_shim_) {
+ if (filename == kNewWMPPlugin || filename == kOldWMPPlugin)
+ return false;
+ } else {
+ // If both the new and old WMP plugins exist, only load the new one.
+ if (filename == kNewWMPPlugin) {
+ if (dont_load_new_wmp_)
+ return false;
+
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (plugins_[i].path.BaseName().value() == kOldWMPPlugin) {
+ plugins_.erase(plugins_.begin() + i);
+ break;
+ }
+ }
+ } else if (filename == kOldWMPPlugin) {
+ for (size_t i = 0; i < plugins_.size(); ++i) {
+ if (plugins_[i].path.BaseName().value() == kNewWMPPlugin)
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void PluginList::LoadInternalPlugins() {
+ if (!use_internal_activex_shim_)
+ return;
+
+ WebPluginInfo info;
+ if (PluginLib::ReadWebPluginInfo(FilePath(kActiveXShimFileName),
+ &info)) {
+ plugins_.push_back(info);
+ }
+
+ if (PluginLib::ReadWebPluginInfo(FilePath(kActiveXShimFileNameForMediaPlayer),
+ &info)) {
+ plugins_.push_back(info);
+ }
+}
+
+} // namespace NPAPI
+
diff --git a/webkit/glue/plugins/plugin_stream.cc b/webkit/glue/plugins/plugin_stream.cc
index a2b3980..c5893f2 100644
--- a/webkit/glue/plugins/plugin_stream.cc
+++ b/webkit/glue/plugins/plugin_stream.cc
@@ -6,6 +6,8 @@
// TODO : Support NP_SEEK mode
// TODO : Support SEEKABLE=true in NewStream
+#include "config.h"
+
#include "webkit/glue/plugins/plugin_stream.h"
#include "base/string_util.h"
diff --git a/webkit/glue/plugins/plugin_stream_posix.cc b/webkit/glue/plugins/plugin_stream_posix.cc
index 10bcdfd7..40306a8 100644
--- a/webkit/glue/plugins/plugin_stream_posix.cc
+++ b/webkit/glue/plugins/plugin_stream_posix.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "config.h"
+
#include "webkit/glue/plugins/plugin_stream.h"
#include <string.h>
diff --git a/webkit/glue/plugins/plugin_stream_url.cc b/webkit/glue/plugins/plugin_stream_url.cc
index f7e8ec7..54dfbdd 100644
--- a/webkit/glue/plugins/plugin_stream_url.cc
+++ b/webkit/glue/plugins/plugin_stream_url.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
+#include "config.h"
+
#include "webkit/glue/plugins/plugin_stream_url.h"
#include "webkit/glue/glue_util.h"
diff --git a/webkit/glue/plugins/plugin_string_stream.cc b/webkit/glue/plugins/plugin_string_stream.cc
index db46d1c..bb56d7c 100644
--- a/webkit/glue/plugins/plugin_string_stream.cc
+++ b/webkit/glue/plugins/plugin_string_stream.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "config.h"
+
#include "webkit/glue/plugins/plugin_string_stream.h"
namespace NPAPI {