summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/Shared/Plugins/Netscape
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-13 16:23:25 +0100
committerBen Murdoch <benm@google.com>2011-05-16 11:35:02 +0100
commit65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch)
treef478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit2/Shared/Plugins/Netscape
parent47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff)
downloadexternal_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit2/Shared/Plugins/Netscape')
-rw-r--r--Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.cpp173
-rw-r--r--Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h81
-rw-r--r--Source/WebKit2/Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm338
-rw-r--r--Source/WebKit2/Shared/Plugins/Netscape/win/NetscapePluginModuleWin.cpp121
-rw-r--r--Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp71
5 files changed, 784 insertions, 0 deletions
diff --git a/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.cpp b/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.cpp
new file mode 100644
index 0000000..fec00b3
--- /dev/null
+++ b/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "NetscapePluginModule.h"
+
+#include "Module.h"
+#include "NetscapeBrowserFuncs.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebKit {
+
+static Vector<NetscapePluginModule*>& initializedNetscapePluginModules()
+{
+ DEFINE_STATIC_LOCAL(Vector<NetscapePluginModule*>, initializedNetscapePluginModules, ());
+ return initializedNetscapePluginModules;
+}
+
+NetscapePluginModule::NetscapePluginModule(const String& pluginPath)
+ : m_pluginPath(pluginPath)
+ , m_isInitialized(false)
+ , m_pluginCount(0)
+ , m_shutdownProcPtr(0)
+ , m_pluginFuncs()
+{
+}
+
+NetscapePluginModule::~NetscapePluginModule()
+{
+ ASSERT(initializedNetscapePluginModules().find(this) == notFound);
+}
+
+void NetscapePluginModule::pluginCreated()
+{
+ if (!m_pluginCount) {
+ // Load the plug-in module if necessary.
+ load();
+ }
+
+ m_pluginCount++;
+}
+
+void NetscapePluginModule::pluginDestroyed()
+{
+ ASSERT(m_pluginCount > 0);
+ m_pluginCount--;
+
+ if (!m_pluginCount) {
+ shutdown();
+ unload();
+ }
+}
+
+void NetscapePluginModule::shutdown()
+{
+ ASSERT(m_isInitialized);
+
+ m_shutdownProcPtr();
+
+ m_isInitialized = false;
+
+ size_t pluginModuleIndex = initializedNetscapePluginModules().find(this);
+ ASSERT(pluginModuleIndex != notFound);
+
+ initializedNetscapePluginModules().remove(pluginModuleIndex);
+}
+
+PassRefPtr<NetscapePluginModule> NetscapePluginModule::getOrCreate(const String& pluginPath)
+{
+ // First, see if we already have a module with this plug-in path.
+ for (size_t i = 0; i < initializedNetscapePluginModules().size(); ++i) {
+ NetscapePluginModule* pluginModule = initializedNetscapePluginModules()[i];
+
+ if (pluginModule->m_pluginPath == pluginPath)
+ return pluginModule;
+ }
+
+ RefPtr<NetscapePluginModule> pluginModule(adoptRef(new NetscapePluginModule(pluginPath)));
+
+ // Try to load and initialize the plug-in module.
+ if (!pluginModule->load())
+ return 0;
+
+ return pluginModule.release();
+}
+
+bool NetscapePluginModule::load()
+{
+ if (m_isInitialized) {
+ ASSERT(initializedNetscapePluginModules().find(this) != notFound);
+ return true;
+ }
+
+ if (!tryLoad()) {
+ unload();
+ return false;
+ }
+
+ m_isInitialized = true;
+
+ ASSERT(initializedNetscapePluginModules().find(this) == notFound);
+ initializedNetscapePluginModules().append(this);
+
+ determineQuirks();
+
+ return true;
+}
+
+bool NetscapePluginModule::tryLoad()
+{
+ m_module = adoptPtr(new Module(m_pluginPath));
+ if (!m_module->load())
+ return false;
+
+ NP_InitializeFuncPtr initializeFuncPtr = m_module->functionPointer<NP_InitializeFuncPtr>("NP_Initialize");
+ if (!initializeFuncPtr)
+ return false;
+
+ NP_GetEntryPointsFuncPtr getEntryPointsFuncPtr = m_module->functionPointer<NP_GetEntryPointsFuncPtr>("NP_GetEntryPoints");
+ if (!getEntryPointsFuncPtr)
+ return false;
+
+ m_shutdownProcPtr = m_module->functionPointer<NPP_ShutdownProcPtr>("NP_Shutdown");
+ if (!m_shutdownProcPtr)
+ return false;
+
+ m_pluginFuncs.size = sizeof(NPPluginFuncs);
+ m_pluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
+
+ // On Mac, NP_Initialize must be called first, then NP_GetEntryPoints. On Windows, the order is
+ // reversed. Failing to follow this order results in crashes (e.g., in Silverlight on Mac and
+ // in Flash and QuickTime on Windows).
+#if PLATFORM(MAC)
+ if (initializeFuncPtr(netscapeBrowserFuncs()) != NPERR_NO_ERROR || getEntryPointsFuncPtr(&m_pluginFuncs) != NPERR_NO_ERROR)
+ return false;
+#elif PLATFORM(WIN)
+ if (getEntryPointsFuncPtr(&m_pluginFuncs) != NPERR_NO_ERROR || initializeFuncPtr(netscapeBrowserFuncs()) != NPERR_NO_ERROR)
+ return false;
+#endif
+
+ return true;
+}
+
+void NetscapePluginModule::unload()
+{
+ ASSERT(!m_isInitialized);
+
+ m_module = 0;
+}
+
+} // namespace WebKit
+
diff --git a/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h b/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h
new file mode 100644
index 0000000..a245b11
--- /dev/null
+++ b/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetscapePluginModule_h
+#define NetscapePluginModule_h
+
+#include "Module.h"
+#include "PluginQuirks.h"
+#include <WebCore/npfunctions.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+// FIXME: We should not include PluginInfoStore.h here. Instead,
+// PluginInfoStore::Plugin should be moved out into its own header which we can
+// put in Shared/Plugins.
+#include "PluginInfoStore.h"
+
+namespace WebKit {
+
+class NetscapePluginModule : public RefCounted<NetscapePluginModule> {
+public:
+ static PassRefPtr<NetscapePluginModule> getOrCreate(const String& pluginPath);
+ ~NetscapePluginModule();
+
+ const NPPluginFuncs& pluginFuncs() const { return m_pluginFuncs; }
+
+ void pluginCreated();
+ void pluginDestroyed();
+
+ static bool getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin&);
+
+ const PluginQuirks& pluginQuirks() const { return m_pluginQuirks; }
+
+private:
+ explicit NetscapePluginModule(const String& pluginPath);
+
+ void determineQuirks();
+
+ bool tryLoad();
+ bool load();
+ void unload();
+
+ void shutdown();
+
+ String m_pluginPath;
+ bool m_isInitialized;
+ unsigned m_pluginCount;
+
+ PluginQuirks m_pluginQuirks;
+
+ NPP_ShutdownProcPtr m_shutdownProcPtr;
+ NPPluginFuncs m_pluginFuncs;
+
+ OwnPtr<Module> m_module;
+};
+
+} // namespace WebKit
+
+#endif // NetscapePluginModule_h
diff --git a/Source/WebKit2/Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm b/Source/WebKit2/Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm
new file mode 100644
index 0000000..6ecacf0
--- /dev/null
+++ b/Source/WebKit2/Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "NetscapePluginModule.h"
+
+#include <WebCore/WebCoreNSStringExtras.h>
+#include <wtf/HashSet.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static bool getPluginArchitecture(CFBundleRef bundle, cpu_type_t& pluginArchitecture)
+{
+ RetainPtr<CFArrayRef> pluginArchitecturesArray(AdoptCF, CFBundleCopyExecutableArchitectures(bundle));
+ if (!pluginArchitecturesArray)
+ return false;
+
+ // Turn the array into a set.
+ HashSet<unsigned> architectures;
+ for (CFIndex i = 0, numPluginArchitectures = CFArrayGetCount(pluginArchitecturesArray.get()); i < numPluginArchitectures; ++i) {
+ CFNumberRef number = static_cast<CFNumberRef>(CFArrayGetValueAtIndex(pluginArchitecturesArray.get(), i));
+
+ SInt32 architecture;
+ if (!CFNumberGetValue(number, kCFNumberSInt32Type, &architecture))
+ continue;
+ architectures.add(architecture);
+ }
+
+#ifdef __x86_64__
+ // We only support 64-bit Intel plug-ins on 64-bit Intel.
+ if (architectures.contains(kCFBundleExecutableArchitectureX86_64)) {
+ pluginArchitecture = CPU_TYPE_X86_64;
+ return true;
+ }
+
+ // We also support 32-bit Intel plug-ins on 64-bit Intel.
+ if (architectures.contains(kCFBundleExecutableArchitectureI386)) {
+ pluginArchitecture = CPU_TYPE_X86;
+ return true;
+ }
+#elif defined(__i386__)
+ // We only support 32-bit Intel plug-ins on 32-bit Intel.
+ if (architectures.contains(kCFBundleExecutableArchitectureI386)) {
+ pluginArchitecture = CPU_TYPE_X86;
+ return true;
+ }
+#elif defined(__ppc64__)
+ // We only support 64-bit PPC plug-ins on 64-bit PPC.
+ if (architectures.contains(kCFBundleExecutableArchitecturePPC64)) {
+ pluginArchitecture = CPU_TYPE_POWERPC64;
+ return true;
+ }
+#elif defined(__ppc__)
+ // We only support 32-bit PPC plug-ins on 32-bit PPC.
+ if (architectures.contains(kCFBundleExecutableArchitecturePPC)) {
+ pluginArchitecture = CPU_TYPE_POWERPC;
+ return true;
+ }
+#else
+#error "Unhandled architecture"
+#endif
+
+ return false;
+}
+
+static bool getPluginInfoFromPropertyLists(CFBundleRef bundle, PluginInfo& pluginInfo)
+{
+ // FIXME: Handle WebPluginMIMETypesFilenameKey.
+
+ CFDictionaryRef mimeTypes = static_cast<CFDictionaryRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes")));
+ if (!mimeTypes || CFGetTypeID(mimeTypes) != CFDictionaryGetTypeID())
+ return false;
+
+ // Get the plug-in name.
+ CFStringRef pluginName = static_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName")));
+ if (pluginName && CFGetTypeID(pluginName) == CFStringGetTypeID())
+ pluginInfo.name = pluginName;
+
+ // Get the plug-in description.
+ CFStringRef pluginDescription = static_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription")));
+ if (pluginDescription && CFGetTypeID(pluginDescription) == CFStringGetTypeID())
+ pluginInfo.desc = pluginDescription;
+
+ // Get the MIME type mapping dictionary.
+ CFIndex numMimeTypes = CFDictionaryGetCount(mimeTypes);
+ Vector<CFStringRef> mimeTypesVector(numMimeTypes);
+ Vector<CFDictionaryRef> mimeTypeInfoVector(numMimeTypes);
+ CFDictionaryGetKeysAndValues(mimeTypes, reinterpret_cast<const void**>(mimeTypesVector.data()), reinterpret_cast<const void**>(mimeTypeInfoVector.data()));
+
+ for (CFIndex i = 0; i < numMimeTypes; ++i) {
+ MimeClassInfo mimeClassInfo;
+
+ // If this MIME type is invalid, ignore it.
+ CFStringRef mimeType = mimeTypesVector[i];
+ if (!mimeType || CFGetTypeID(mimeType) != CFStringGetTypeID() || CFStringGetLength(mimeType) == 0)
+ continue;
+
+ // If this MIME type doesn't have a valid info dictionary, ignore it.
+ CFDictionaryRef mimeTypeInfo = mimeTypeInfoVector[i];
+ if (!mimeTypeInfo || CFGetTypeID(mimeTypeInfo) != CFDictionaryGetTypeID())
+ continue;
+
+ // Get the MIME type description.
+ CFStringRef mimeTypeDescription = static_cast<CFStringRef>(CFDictionaryGetValue(mimeTypeInfo, CFSTR("WebPluginTypeDescription")));
+ if (mimeTypeDescription && CFGetTypeID(mimeTypeDescription) != CFStringGetTypeID())
+ mimeTypeDescription = 0;
+
+ mimeClassInfo.type = String(mimeType).lower();
+ mimeClassInfo.desc = mimeTypeDescription;
+
+ // Now get the extensions for this MIME type.
+ CFIndex numExtensions = 0;
+ CFArrayRef extensionsArray = static_cast<CFArrayRef>(CFDictionaryGetValue(mimeTypeInfo, CFSTR("WebPluginExtensions")));
+ if (extensionsArray && CFGetTypeID(extensionsArray) == CFArrayGetTypeID())
+ numExtensions = CFArrayGetCount(extensionsArray);
+
+ for (CFIndex i = 0; i < numExtensions; ++i) {
+ CFStringRef extension = static_cast<CFStringRef>(CFArrayGetValueAtIndex(extensionsArray, i));
+ if (!extension || CFGetTypeID(extension) != CFStringGetTypeID())
+ continue;
+
+ mimeClassInfo.extensions.append(String(extension).lower());
+ }
+
+ // Add this MIME type.
+ pluginInfo.mimes.append(mimeClassInfo);
+ }
+
+ return true;
+}
+
+class ResourceMap {
+public:
+ explicit ResourceMap(CFBundleRef bundle)
+ : m_bundle(bundle)
+ , m_currentResourceFile(CurResFile())
+ , m_bundleResourceMap(CFBundleOpenBundleResourceMap(m_bundle))
+ {
+ UseResFile(m_bundleResourceMap);
+ }
+
+ ~ResourceMap()
+ {
+ // Close the resource map.
+ CFBundleCloseBundleResourceMap(m_bundle, m_bundleResourceMap);
+
+ // And restore the old resource.
+ UseResFile(m_currentResourceFile);
+ }
+
+ bool isValid() const { return m_bundleResourceMap != -1; }
+
+private:
+ CFBundleRef m_bundle;
+ ResFileRefNum m_currentResourceFile;
+ ResFileRefNum m_bundleResourceMap;
+};
+
+static bool getStringListResource(ResID resourceID, Vector<String>& stringList) {
+ Handle stringListHandle = Get1Resource('STR#', resourceID);
+ if (!stringListHandle || !*stringListHandle)
+ return false;
+
+ // Get the string list size.
+ Size stringListSize = GetHandleSize(stringListHandle);
+ if (stringListSize < static_cast<Size>(sizeof(UInt16)))
+ return false;
+
+ CFStringEncoding stringEncoding = stringEncodingForResource(stringListHandle);
+
+ unsigned char* ptr = reinterpret_cast<unsigned char*>(*stringListHandle);
+ unsigned char* end = ptr + stringListSize;
+
+ // Get the number of strings in the string list.
+ UInt16 numStrings = *reinterpret_cast<UInt16*>(ptr);
+ ptr += sizeof(UInt16);
+
+ for (UInt16 i = 0; i < numStrings; ++i) {
+ // We're past the end of the string, bail.
+ if (ptr >= end)
+ return false;
+
+ // Get the string length.
+ unsigned char stringLength = *ptr++;
+
+ RetainPtr<CFStringRef> cfString(AdoptCF, CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, ptr, stringLength, stringEncoding, false, kCFAllocatorNull));
+ if (!cfString.get())
+ return false;
+
+ stringList.append(cfString.get());
+ ptr += stringLength;
+ }
+
+ if (ptr != end)
+ return false;
+
+ return true;
+}
+
+static const ResID PluginNameOrDescriptionStringNumber = 126;
+static const ResID MIMEDescriptionStringNumber = 127;
+static const ResID MIMEListStringStringNumber = 128;
+
+static bool getPluginInfoFromCarbonResources(CFBundleRef bundle, PluginInfo& pluginInfo)
+{
+ ResourceMap resourceMap(bundle);
+ if (!resourceMap.isValid())
+ return false;
+
+ // Get the description and name string list.
+ Vector<String> descriptionAndName;
+ if (!getStringListResource(PluginNameOrDescriptionStringNumber, descriptionAndName))
+ return false;
+
+ // Get the MIME types and extensions string list. This list needs to be a multiple of two.
+ Vector<String> mimeTypesAndExtensions;
+ if (!getStringListResource(MIMEListStringStringNumber, mimeTypesAndExtensions))
+ return false;
+
+ if (mimeTypesAndExtensions.size() % 2)
+ return false;
+
+ size_t numMimeTypes = mimeTypesAndExtensions.size() / 2;
+
+ // Now get the MIME type descriptions string list. This string list needs to be the same length as the number of MIME types.
+ Vector<String> mimeTypeDescriptions;
+ if (!getStringListResource(MIMEDescriptionStringNumber, mimeTypeDescriptions))
+ return false;
+
+ if (mimeTypeDescriptions.size() != numMimeTypes)
+ return false;
+
+ // Add all MIME types.
+ for (size_t i = 0; i < mimeTypesAndExtensions.size() / 2; ++i) {
+ MimeClassInfo mimeClassInfo;
+
+ const String& mimeType = mimeTypesAndExtensions[i * 2];
+ const String& description = mimeTypeDescriptions[i];
+
+ mimeClassInfo.type = mimeType.lower();
+ mimeClassInfo.desc = description;
+
+ Vector<String> extensions;
+ mimeTypesAndExtensions[i * 2 + 1].split(',', extensions);
+
+ for (size_t i = 0; i < extensions.size(); ++i)
+ mimeClassInfo.extensions.append(extensions[i].lower());
+
+ pluginInfo.mimes.append(mimeClassInfo);
+ }
+
+ // Set the description and name if they exist.
+ if (descriptionAndName.size() > 0)
+ pluginInfo.desc = descriptionAndName[0];
+ if (descriptionAndName.size() > 1)
+ pluginInfo.name = descriptionAndName[1];
+
+ return true;
+}
+
+bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin& plugin)
+{
+ RetainPtr<CFStringRef> bundlePath(AdoptCF, pluginPath.createCFString());
+ RetainPtr<CFURLRef> bundleURL(AdoptCF, CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundlePath.get(), kCFURLPOSIXPathStyle, false));
+
+ // Try to initialize the bundle.
+ RetainPtr<CFBundleRef> bundle(AdoptCF, CFBundleCreate(kCFAllocatorDefault, bundleURL.get()));
+ if (!bundle)
+ return false;
+
+ // Check if this bundle is an NPAPI plug-in.
+ UInt32 packageType = 0;
+ CFBundleGetPackageInfo(bundle.get(), &packageType, 0);
+ if (packageType != FOUR_CHAR_CODE('BRPL'))
+ return false;
+
+ // Check that the architecture is valid.
+ cpu_type_t pluginArchitecture = 0;
+ if (!getPluginArchitecture(bundle.get(), pluginArchitecture))
+ return false;
+
+ // Check that there's valid info for this plug-in.
+ if (!getPluginInfoFromPropertyLists(bundle.get(), plugin.info) &&
+ !getPluginInfoFromCarbonResources(bundle.get(), plugin.info))
+ return false;
+
+ plugin.path = pluginPath;
+ plugin.pluginArchitecture = pluginArchitecture;
+ plugin.bundleIdentifier = CFBundleGetIdentifier(bundle.get());
+ plugin.versionNumber = CFBundleGetVersionNumber(bundle.get());
+
+ RetainPtr<CFStringRef> filename(AdoptCF, CFURLCopyLastPathComponent(bundleURL.get()));
+ plugin.info.file = filename.get();
+
+ if (plugin.info.name.isNull())
+ plugin.info.name = plugin.info.file;
+ if (plugin.info.desc.isNull())
+ plugin.info.desc = plugin.info.file;
+
+ return true;
+}
+
+void NetscapePluginModule::determineQuirks()
+{
+ PluginInfoStore::Plugin plugin;
+ if (!getPluginInfo(m_pluginPath, plugin))
+ return;
+
+ if (plugin.bundleIdentifier == "com.macromedia.Flash Player.plugin") {
+ // Flash requires that the return value of getprogname() be "WebKitPluginHost".
+ m_pluginQuirks.add(PluginQuirks::PrognameShouldBeWebKitPluginHost);
+ }
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/Shared/Plugins/Netscape/win/NetscapePluginModuleWin.cpp b/Source/WebKit2/Shared/Plugins/Netscape/win/NetscapePluginModuleWin.cpp
new file mode 100644
index 0000000..f969ba4
--- /dev/null
+++ b/Source/WebKit2/Shared/Plugins/Netscape/win/NetscapePluginModuleWin.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "NetscapePluginModule.h"
+
+#include <WebCore/FileSystem.h>
+#include <wtf/OwnArrayPtr.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static String getVersionInfo(const LPVOID versionInfoData, const String& info)
+{
+ LPVOID buffer;
+ UINT bufferLength;
+ String subInfo = "\\StringfileInfo\\040904E4\\" + info;
+ if (!::VerQueryValueW(versionInfoData, const_cast<UChar*>(subInfo.charactersWithNullTermination()), &buffer, &bufferLength) || !bufferLength)
+ return String();
+
+ // Subtract 1 from the length; we don't want the trailing null character.
+ return String(reinterpret_cast<UChar*>(buffer), bufferLength - 1);
+}
+
+static uint64_t fileVersion(DWORD leastSignificant, DWORD mostSignificant)
+{
+ ULARGE_INTEGER version;
+ version.LowPart = leastSignificant;
+ version.HighPart = mostSignificant;
+ return version.QuadPart;
+}
+
+bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin& plugin)
+{
+ String pathCopy = pluginPath;
+ DWORD versionInfoSize = ::GetFileVersionInfoSizeW(pathCopy.charactersWithNullTermination(), 0);
+ if (!versionInfoSize)
+ return false;
+
+ OwnArrayPtr<char> versionInfoData(new char[versionInfoSize]);
+ if (!::GetFileVersionInfoW(pathCopy.charactersWithNullTermination(), 0, versionInfoSize, versionInfoData.get()))
+ return false;
+
+ String name = getVersionInfo(versionInfoData.get(), "ProductName");
+ String description = getVersionInfo(versionInfoData.get(), "FileDescription");
+ if (name.isNull() || description.isNull())
+ return false;
+
+ VS_FIXEDFILEINFO* info;
+ UINT infoSize;
+ if (!::VerQueryValueW(versionInfoData.get(), L"\\", reinterpret_cast<void**>(&info), &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO))
+ return false;
+
+ Vector<String> types;
+ getVersionInfo(versionInfoData.get(), "MIMEType").split('|', types);
+ Vector<String> extensionLists;
+ getVersionInfo(versionInfoData.get(), "FileExtents").split('|', extensionLists);
+ Vector<String> descriptions;
+ getVersionInfo(versionInfoData.get(), "FileOpenName").split('|', descriptions);
+
+ Vector<MimeClassInfo> mimes(types.size());
+ for (size_t i = 0; i < types.size(); i++) {
+ String type = types[i].lower();
+ String description = i < descriptions.size() ? descriptions[i] : "";
+ String extensionList = i < extensionLists.size() ? extensionLists[i] : "";
+
+ Vector<String> extensionsVector;
+ extensionList.split(',', extensionsVector);
+
+ // Get rid of the extension list that may be at the end of the description string.
+ int pos = description.find("(*");
+ if (pos != -1) {
+ // There might be a space that we need to get rid of.
+ if (pos > 1 && description[pos - 1] == ' ')
+ pos--;
+ description = description.left(pos);
+ }
+
+ mimes[i].type = type;
+ mimes[i].desc = description;
+ mimes[i].extensions.swap(extensionsVector);
+ }
+
+ plugin.path = pluginPath;
+ plugin.info.desc = description;
+ plugin.info.name = name;
+ plugin.info.file = pathGetFileName(pluginPath);
+ plugin.info.mimes.swap(mimes);
+ plugin.fileVersion = fileVersion(info->dwFileVersionLS, info->dwFileVersionMS);
+
+ return true;
+}
+
+void NetscapePluginModule::determineQuirks()
+{
+}
+
+} // namespace WebKit
+
diff --git a/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp b/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp
new file mode 100644
index 0000000..a02cdad
--- /dev/null
+++ b/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "NetscapePluginModule.h"
+
+#include "PluginDatabase.h"
+#include "PluginPackage.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+bool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin& plugin)
+{
+ // We are loading the plugin here since it does not seem to be a standardized way to
+ // get the needed informations from a UNIX plugin without loading it.
+
+ RefPtr<PluginPackage> package = PluginPackage::createPackage(pluginPath, 0 /*lastModified*/);
+ if (!package)
+ return false;
+
+ plugin.path = pluginPath;
+ plugin.info.desc = package->description();
+ plugin.info.file = package->fileName();
+
+ const MIMEToDescriptionsMap& descriptions = package->mimeToDescriptions();
+ const MIMEToExtensionsMap& extensions = package->mimeToExtensions();
+ MIMEToDescriptionsMap::const_iterator descEnd = descriptions.end();
+ plugin.info.mimes.reserveCapacity(descriptions.size());
+ unsigned i = 0;
+ for (MIMEToDescriptionsMap::const_iterator it = descriptions.begin(); it != descEnd; ++it) {
+ plugin.info.mimes.uncheckedAppend(MimeClassInfo());
+ MimeClassInfo& mime = plugin.info.mimes[i++];
+ mime.type = it->first;
+ mime.desc = it->second;
+ MIMEToExtensionsMap::const_iterator extensionIt = extensions.find(it->first);
+ ASSERT(extensionIt != extensions.end());
+ mime.extensions = extensionIt->second;
+ }
+
+ package->unload();
+ return true;
+}
+
+void NetscapePluginModule::determineQuirks()
+{
+}
+
+} // namespace WebKit