diff options
author | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-15 21:49:54 +0000 |
---|---|---|
committer | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-15 21:49:54 +0000 |
commit | ae4e20ac9d99988fb5b522acfaae08cb469a2ab7 (patch) | |
tree | ede89baf7be0f91f2fc9c1734a6060ce75fe648f /webkit/glue | |
parent | 022f42453b737577e9175eb279d507981ef40b30 (diff) | |
download | chromium_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/SConscript | 10 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_constants_win.h | 23 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.cc | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib.cc | 210 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib.h | 53 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib_mac.mm | 367 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_lib_win.cc | 185 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_list.cc | 351 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_list.h | 71 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_list_mac.mm | 92 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_list_win.cc | 343 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_stream.cc | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_stream_posix.cc | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_stream_url.cc | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_string_stream.cc | 2 |
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, ¤t_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, ¤t_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 { |