summaryrefslogtreecommitdiffstats
path: root/WebCore/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/plugins')
-rw-r--r--WebCore/plugins/PluginDatabase.cpp236
-rw-r--r--WebCore/plugins/PluginDatabase.h13
-rw-r--r--WebCore/plugins/PluginPackage.cpp32
-rw-r--r--WebCore/plugins/PluginPackage.h12
-rw-r--r--WebCore/plugins/PluginViewNone.cpp2
-rw-r--r--WebCore/plugins/gtk/PluginPackageGtk.cpp4
-rw-r--r--WebCore/plugins/qt/PluginPackageQt.cpp17
-rw-r--r--WebCore/plugins/qt/PluginViewQt.cpp37
-rw-r--r--WebCore/plugins/win/PluginDatabaseWin.cpp53
9 files changed, 391 insertions, 15 deletions
diff --git a/WebCore/plugins/PluginDatabase.cpp b/WebCore/plugins/PluginDatabase.cpp
index 88297ac..77c84eb 100644
--- a/WebCore/plugins/PluginDatabase.cpp
+++ b/WebCore/plugins/PluginDatabase.cpp
@@ -30,6 +30,9 @@
#include "Frame.h"
#include "KURL.h"
#include "PluginPackage.h"
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+#include "FileSystem.h"
+#endif
#include <stdlib.h>
#if PLATFORM(ANDROID)
@@ -41,7 +44,22 @@ namespace WebCore {
typedef HashMap<String, RefPtr<PluginPackage> > PluginPackageByNameMap;
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+static const size_t maximumPersistentPluginMetadataCacheSize = 32768;
+
+static bool gPersistentPluginMetadataCacheIsEnabled;
+
+String& persistentPluginMetadataCachePath()
+{
+ DEFINE_STATIC_LOCAL(String, cachePath, ());
+ return cachePath;
+}
+#endif
+
PluginDatabase::PluginDatabase()
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ : m_persistentMetadataCacheIsLoaded(false)
+#endif
{
}
@@ -79,6 +97,10 @@ void PluginDatabase::addExtraPluginDirectory(const String& directory)
bool PluginDatabase::refresh()
{
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ if (!m_persistentMetadataCacheIsLoaded)
+ loadPersistentMetadataCache();
+#endif
bool pluginSetChanged = false;
if (!m_plugins.isEmpty()) {
@@ -131,6 +153,10 @@ bool PluginDatabase::refresh()
if (!pluginSetChanged)
return false;
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ updatePersistentMetadataCache();
+#endif
+
m_registeredMIMETypes.clear();
// Register plug-in MIME types
@@ -187,8 +213,13 @@ PluginPackage* PluginDatabase::pluginForMIMEType(const String& mimeType)
if (!plugin->isEnabled())
continue;
- if (plugin->mimeToDescriptions().contains(key))
+ if (plugin->mimeToDescriptions().contains(key)) {
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ if (!plugin->ensurePluginLoaded())
+ continue;
+#endif
pluginChoices.append(plugin);
+ }
}
if (pluginChoices.isEmpty())
@@ -227,6 +258,10 @@ String PluginDatabase::MIMETypeForExtension(const String& extension) const
if (preferredPlugin && PluginPackage::equal(*plugin, *preferredPlugin))
return mimeType;
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ if (!plugin->ensurePluginLoaded())
+ continue;
+#endif
pluginChoices.append(plugin);
mimeTypeForPlugin.add(plugin, mimeType);
foundMapping = true;
@@ -320,6 +355,9 @@ void PluginDatabase::clear()
m_pluginPathsWithTimes.clear();
m_registeredMIMETypes.clear();
m_preferredPlugins.clear();
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ m_persistentMetadataCacheIsLoaded = false;
+#endif
}
#if (!OS(WINCE)) && (!OS(SYMBIAN)) && (!OS(WINDOWS) || !ENABLE(NETSCAPE_PLUGIN_API))
@@ -437,4 +475,200 @@ void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
#endif // !OS(SYMBIAN) && !OS(WINDOWS)
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+
+static void fillBufferWithContentsOfFile(PlatformFileHandle file, Vector<char>& buffer)
+{
+ size_t bufferSize = 0;
+ size_t bufferCapacity = 1024;
+ buffer.resize(bufferCapacity);
+
+ do {
+ bufferSize += readFromFile(file, buffer.data() + bufferSize, bufferCapacity - bufferSize);
+ if (bufferSize == bufferCapacity) {
+ if (bufferCapacity < maximumPersistentPluginMetadataCacheSize) {
+ bufferCapacity *= 2;
+ buffer.resize(bufferCapacity);
+ } else {
+ buffer.clear();
+ return;
+ }
+ } else
+ break;
+ } while (true);
+
+ buffer.shrink(bufferSize);
+}
+
+static bool readUTF8String(String& resultString, char*& start, const char* end)
+{
+ if (start >= end)
+ return false;
+
+ int len = strlen(start);
+ resultString = String::fromUTF8(start, len);
+ start += len + 1;
+
+ return true;
+}
+
+static bool readTime(time_t& resultTime, char*& start, const char* end)
+{
+ if (start + sizeof(time_t) >= end)
+ return false;
+
+ resultTime = *reinterpret_cast<time_t*>(start);
+ start += sizeof(time_t);
+
+ return true;
+}
+
+static const char schemaVersion = '1';
+static const char persistentPluginMetadataCacheFilename[] = "PluginMetadataCache.bin";
+
+void PluginDatabase::loadPersistentMetadataCache()
+{
+ if (!isPersistentMetadataCacheEnabled() || persistentMetadataCachePath().isEmpty())
+ return;
+
+ PlatformFileHandle file;
+ String absoluteCachePath = pathByAppendingComponent(persistentMetadataCachePath(), persistentPluginMetadataCacheFilename);
+ file = openFile(absoluteCachePath, OpenForRead);
+
+ if (!isHandleValid(file))
+ return;
+
+ // Mark cache as loaded regardless of success or failure. If
+ // there's error in the cache, we won't try to load it anymore.
+ m_persistentMetadataCacheIsLoaded = true;
+
+ Vector<char> fileContents;
+ fillBufferWithContentsOfFile(file, fileContents);
+ closeFile(file);
+
+ if (fileContents.size() < 2 || fileContents.first() != schemaVersion || fileContents.last() != '\0') {
+ LOG_ERROR("Unable to read plugin metadata cache: corrupt schema");
+ deleteFile(absoluteCachePath);
+ return;
+ }
+
+ char* bufferPos = fileContents.data() + 1;
+ char* end = fileContents.data() + fileContents.size();
+
+ PluginSet cachedPlugins;
+ HashMap<String, time_t> cachedPluginPathsWithTimes;
+ HashMap<String, RefPtr<PluginPackage> > cachedPluginsByPath;
+
+ while (bufferPos < end) {
+ String path;
+ time_t lastModified;
+ String name;
+ String desc;
+ String mimeDesc;
+ if (!(readUTF8String(path, bufferPos, end)
+ && readTime(lastModified, bufferPos, end)
+ && readUTF8String(name, bufferPos, end)
+ && readUTF8String(desc, bufferPos, end)
+ && readUTF8String(mimeDesc, bufferPos, end))) {
+ LOG_ERROR("Unable to read plugin metadata cache: corrupt data");
+ deleteFile(absoluteCachePath);
+ return;
+ }
+
+ // Skip metadata that points to plugins from directories that
+ // are not part of plugin directory list anymore.
+ String pluginDirectoryName = directoryName(path);
+ if (m_pluginDirectories.find(pluginDirectoryName) == WTF::notFound)
+ continue;
+
+ RefPtr<PluginPackage> package = PluginPackage::createPackageFromCache(path, lastModified, name, desc, mimeDesc);
+
+ if (package && cachedPlugins.add(package).second) {
+ cachedPluginPathsWithTimes.add(package->path(), package->lastModified());
+ cachedPluginsByPath.add(package->path(), package);
+ }
+ }
+
+ m_plugins.swap(cachedPlugins);
+ m_pluginsByPath.swap(cachedPluginsByPath);
+ m_pluginPathsWithTimes.swap(cachedPluginPathsWithTimes);
+}
+
+static bool writeUTF8String(PlatformFileHandle file, const String& string)
+{
+ CString utf8String = string.utf8();
+ int length = utf8String.length() + 1;
+ return writeToFile(file, utf8String.data(), length) == length;
+}
+
+static bool writeTime(PlatformFileHandle file, const time_t& time)
+{
+ return writeToFile(file, reinterpret_cast<const char*>(&time), sizeof(time_t)) == sizeof(time_t);
+}
+
+void PluginDatabase::updatePersistentMetadataCache()
+{
+ if (!isPersistentMetadataCacheEnabled() || persistentMetadataCachePath().isEmpty())
+ return;
+
+ makeAllDirectories(persistentMetadataCachePath());
+ String absoluteCachePath = pathByAppendingComponent(persistentMetadataCachePath(), persistentPluginMetadataCacheFilename);
+ deleteFile(absoluteCachePath);
+
+ if (m_plugins.isEmpty())
+ return;
+
+ PlatformFileHandle file;
+ file = openFile(absoluteCachePath, OpenForWrite);
+
+ if (!isHandleValid(file)) {
+ LOG_ERROR("Unable to open plugin metadata cache for saving");
+ return;
+ }
+
+ char localSchemaVersion = schemaVersion;
+ if (writeToFile(file, &localSchemaVersion, 1) != 1) {
+ LOG_ERROR("Unable to write plugin metadata cache schema");
+ closeFile(file);
+ deleteFile(absoluteCachePath);
+ return;
+ }
+
+ PluginSet::const_iterator end = m_plugins.end();
+ for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+ if (!(writeUTF8String(file, (*it)->path())
+ && writeTime(file, (*it)->lastModified())
+ && writeUTF8String(file, (*it)->name())
+ && writeUTF8String(file, (*it)->description())
+ && writeUTF8String(file, (*it)->fullMIMEDescription()))) {
+ LOG_ERROR("Unable to write plugin metadata to cache");
+ closeFile(file);
+ deleteFile(absoluteCachePath);
+ return;
+ }
+ }
+
+ closeFile(file);
+}
+
+bool PluginDatabase::isPersistentMetadataCacheEnabled()
+{
+ return gPersistentPluginMetadataCacheIsEnabled;
+}
+
+void PluginDatabase::setPersistentMetadataCacheEnabled(bool isEnabled)
+{
+ gPersistentPluginMetadataCacheIsEnabled = isEnabled;
+}
+
+String PluginDatabase::persistentMetadataCachePath()
+{
+ return WebCore::persistentPluginMetadataCachePath();
+}
+
+void PluginDatabase::setPersistentMetadataCachePath(const String& persistentMetadataCachePath)
+{
+ WebCore::persistentPluginMetadataCachePath() = persistentMetadataCachePath;
+}
+#endif
}
diff --git a/WebCore/plugins/PluginDatabase.h b/WebCore/plugins/PluginDatabase.h
index 287857e..b1e1525 100644
--- a/WebCore/plugins/PluginDatabase.h
+++ b/WebCore/plugins/PluginDatabase.h
@@ -84,6 +84,12 @@ namespace WebCore {
Vector<String> pluginDirectories() const { return m_pluginDirectories; }
String MIMETypeForExtension(const String& extension) const;
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ static bool isPersistentMetadataCacheEnabled();
+ static void setPersistentMetadataCacheEnabled(bool isEnabled);
+ static String persistentMetadataCachePath();
+ static void setPersistentMetadataCachePath(const String& persistentMetadataCachePath);
+#endif
private:
void getPluginPathsInDirectories(HashSet<String>&) const;
@@ -92,6 +98,10 @@ namespace WebCore {
// Returns whether the plugin was actually added or not (it won't be added if it's a duplicate of an existing plugin).
bool add(PassRefPtr<PluginPackage>);
void remove(PluginPackage*);
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ void loadPersistentMetadataCache();
+ void updatePersistentMetadataCache();
+#endif
Vector<String> m_pluginDirectories;
HashSet<String> m_registeredMIMETypes;
@@ -105,6 +115,9 @@ namespace WebCore {
friend class ::android::WebSettings;
#endif
HashMap<String, RefPtr<PluginPackage> > m_preferredPlugins;
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ bool m_persistentMetadataCacheIsLoaded;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/plugins/PluginPackage.cpp b/WebCore/plugins/PluginPackage.cpp
index 48c44f0..168d45a 100644
--- a/WebCore/plugins/PluginPackage.cpp
+++ b/WebCore/plugins/PluginPackage.cpp
@@ -114,6 +114,9 @@ PluginPackage::PluginPackage(const String& path, const time_t& lastModified)
, m_module(0)
, m_lastModified(lastModified)
, m_freeLibraryTimer(this, &PluginPackage::freeLibraryTimerFired)
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ , m_infoIsFromCache(true)
+#endif
{
m_fileName = pathGetFileName(m_path);
m_parentDirectory = m_path.left(m_path.length() - m_fileName.length() - 1);
@@ -168,6 +171,19 @@ PassRefPtr<PluginPackage> PluginPackage::createPackage(const String& path, const
return package.release();
}
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+PassRefPtr<PluginPackage> PluginPackage::createPackageFromCache(const String& path, const time_t& lastModified, const String& name, const String& description, const String& mimeDescription)
+{
+ RefPtr<PluginPackage> package = adoptRef(new PluginPackage(path, lastModified));
+ package->m_name = name;
+ package->m_description = description;
+ package->determineModuleVersionFromDescription();
+ package->setMIMEDescription(mimeDescription);
+ package->m_infoIsFromCache = true;
+ return package.release();
+}
+#endif
+
#if defined(XP_UNIX)
void PluginPackage::determineQuirks(const String& mimeType)
{
@@ -349,4 +365,20 @@ int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersio
return 0;
}
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+bool PluginPackage::ensurePluginLoaded()
+{
+ if (!m_infoIsFromCache)
+ return m_isLoaded;
+
+ m_quirks = PluginQuirkSet();
+ m_name = String();
+ m_description = String();
+ m_fullMIMEDescription = String();
+ m_moduleVersion = 0;
+
+ return fetchInfo();
+}
+#endif
+
}
diff --git a/WebCore/plugins/PluginPackage.h b/WebCore/plugins/PluginPackage.h
index 92a9c52..f4d1dac 100644
--- a/WebCore/plugins/PluginPackage.h
+++ b/WebCore/plugins/PluginPackage.h
@@ -49,6 +49,9 @@ namespace WebCore {
public:
~PluginPackage();
static PassRefPtr<PluginPackage> createPackage(const String& path, const time_t& lastModified);
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ static PassRefPtr<PluginPackage> createPackageFromCache(const String& path, const time_t& lastModified, const String& name, const String& description, const String& mimeDescription);
+#endif
const String& name() const { return m_name; }
const String& description() const { return m_description; }
@@ -80,6 +83,11 @@ namespace WebCore {
NPInterface* npInterface() const { return m_npInterface; }
#endif // OS(SYMBIAN)
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ bool ensurePluginLoaded();
+ void setMIMEDescription(const String& mimeDescription);
+ String fullMIMEDescription() const { return m_fullMIMEDescription;}
+#endif
private:
PluginPackage(const String& path, const time_t& lastModified);
@@ -121,6 +129,10 @@ namespace WebCore {
Timer<PluginPackage> m_freeLibraryTimer;
PluginQuirkSet m_quirks;
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+ String m_fullMIMEDescription;
+ bool m_infoIsFromCache;
+#endif
};
struct PluginPackageHash {
diff --git a/WebCore/plugins/PluginViewNone.cpp b/WebCore/plugins/PluginViewNone.cpp
index ab8f620..9aeaf3b 100644
--- a/WebCore/plugins/PluginViewNone.cpp
+++ b/WebCore/plugins/PluginViewNone.cpp
@@ -141,7 +141,7 @@ void PluginView::handleFocusOutEvent()
// ports using PluginView, but until then, if new functions like this are
// added, please make sure they have the proper platform #ifs so that changes
// do not break ports who compile both this file and PluginView.cpp.
-#if PLATFORM(MAC) || PLATFORM(CHROMIUM) || PLATFORM(EFL) || (OS(WINCE) && !PLATFORM(QT)) || (PLATFORM(QT) && !OS(WINCE))
+#if PLATFORM(MAC) || PLATFORM(CHROMIUM) || PLATFORM(EFL) || (OS(WINCE) && !PLATFORM(QT)) || (PLATFORM(QT) && !OS(WINCE)) || PLATFORM(BREWMP)
#if ENABLE(NETSCAPE_PLUGIN_API)
void PluginView::keepAlive(NPP)
{
diff --git a/WebCore/plugins/gtk/PluginPackageGtk.cpp b/WebCore/plugins/gtk/PluginPackageGtk.cpp
index 97553a1..d0218fb 100644
--- a/WebCore/plugins/gtk/PluginPackageGtk.cpp
+++ b/WebCore/plugins/gtk/PluginPackageGtk.cpp
@@ -113,9 +113,9 @@ bool PluginPackage::load()
GOwnPtr<gchar> finalPath(g_strdup(m_path.utf8().data()));
while (g_file_test(finalPath.get(), G_FILE_TEST_IS_SYMLINK)) {
GOwnPtr<GFile> file(g_file_new_for_path(finalPath.get()));
+ GOwnPtr<GFile> dir(g_file_get_parent(file.get()));
GOwnPtr<gchar> linkPath(g_file_read_link(finalPath.get(), 0));
-
- GOwnPtr<GFile> resolvedFile(g_file_resolve_relative_path(file.get(), linkPath.get()));
+ GOwnPtr<GFile> resolvedFile(g_file_resolve_relative_path(dir.get(), linkPath.get()));
finalPath.set(g_file_get_path(resolvedFile.get()));
}
diff --git a/WebCore/plugins/qt/PluginPackageQt.cpp b/WebCore/plugins/qt/PluginPackageQt.cpp
index d92fffe..e7058c7 100644
--- a/WebCore/plugins/qt/PluginPackageQt.cpp
+++ b/WebCore/plugins/qt/PluginPackageQt.cpp
@@ -60,9 +60,19 @@ bool PluginPackage::fetchInfo()
m_description = buf;
determineModuleVersionFromDescription();
- String s = gm();
+ String mimeDescription = gm();
+ setMIMEDescription(mimeDescription);
+ m_infoIsFromCache = false;
+
+ return true;
+}
+
+void PluginPackage::setMIMEDescription(const String& mimeDescription)
+{
+ m_fullMIMEDescription = mimeDescription;
+
Vector<String> types;
- s.split(UChar(';'), false, types);
+ mimeDescription.split(UChar(';'), false, types);
for (unsigned i = 0; i < types.size(); ++i) {
Vector<String> mime;
types[i].split(UChar(':'), true, mime);
@@ -76,8 +86,6 @@ bool PluginPackage::fetchInfo()
m_mimeToDescriptions.add(mime[0], mime[2]);
}
}
-
- return true;
}
static NPError staticPluginQuirkRequiresGtkToolKit_NPN_GetValue(NPP instance, NPNVariable variable, void* value)
@@ -187,4 +195,5 @@ uint16_t PluginPackage::NPVersion() const
{
return NP_VERSION_MINOR;
}
+
}
diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp
index 5c681b8..f60885d 100644
--- a/WebCore/plugins/qt/PluginViewQt.cpp
+++ b/WebCore/plugins/qt/PluginViewQt.cpp
@@ -154,6 +154,13 @@ void PluginView::setFocus(bool focused)
} else {
Widget::setFocus(focused);
}
+ if (!m_isWindowed) {
+ XEvent npEvent;
+ initXEvent(&npEvent);
+ npEvent.type = (focused) ? 9 : 10; // ints as Qt unsets FocusIn and FocusOut
+ if (!dispatchNPEvent(npEvent))
+ LOG(Events, "PluginView::setFocus(%d): Focus event not accepted", focused);
+ }
}
void PluginView::show()
@@ -374,6 +381,17 @@ void setXKeyEventSpecificFields(XEvent* xEvent, KeyboardEvent* event)
xEvent->xkey.time = event->timeStamp();
xEvent->xkey.state = qKeyEvent->nativeModifiers();
xEvent->xkey.keycode = qKeyEvent->nativeScanCode();
+
+ // We may not have a nativeScanCode() if the key event is from DRT's eventsender. In that
+ // case just populate the XEvent's keycode with the Qt platform-independent keycode. The only
+ // place this keycode will be used is in webkit_test_plugin_handle_event().
+ if (QWebPagePrivate::drtRun && !xEvent->xkey.keycode) {
+ if (!qKeyEvent->text().isEmpty())
+ xEvent->xkey.keycode = int(qKeyEvent->text().at(0).unicode() + qKeyEvent->modifiers());
+ else if (qKeyEvent->key() && (qKeyEvent->key() != Qt::Key_unknown))
+ xEvent->xkey.keycode = int(qKeyEvent->key() + qKeyEvent->modifiers());
+ }
+
xEvent->xkey.same_screen = true;
// NOTE: As the XEvents sent to the plug-in are synthesized and there is not a native window
@@ -578,19 +596,24 @@ void PluginView::setNPWindowIfNeeded()
m_npWindow.x = m_windowRect.x();
m_npWindow.y = m_windowRect.y();
-
- m_npWindow.clipRect.left = max(0, m_clipRect.x());
- m_npWindow.clipRect.top = max(0, m_clipRect.y());
- m_npWindow.clipRect.right = m_clipRect.x() + m_clipRect.width();
- m_npWindow.clipRect.bottom = m_clipRect.y() + m_clipRect.height();
} else {
m_npWindow.x = 0;
m_npWindow.y = 0;
+ }
+ // If the width or height are null, set the clipRect to null, indicating that
+ // the plugin is not visible/scrolled out.
+ if (!m_clipRect.width() || !m_clipRect.height()) {
m_npWindow.clipRect.left = 0;
- m_npWindow.clipRect.top = 0;
m_npWindow.clipRect.right = 0;
+ m_npWindow.clipRect.top = 0;
m_npWindow.clipRect.bottom = 0;
+ } else {
+ // Clipping rectangle of the plug-in; the origin is the top left corner of the drawable or window.
+ m_npWindow.clipRect.left = m_npWindow.x + m_clipRect.x();
+ m_npWindow.clipRect.top = m_npWindow.y + m_clipRect.y();
+ m_npWindow.clipRect.right = m_npWindow.x + m_clipRect.x() + m_clipRect.width();
+ m_npWindow.clipRect.bottom = m_npWindow.y + m_clipRect.y() + m_clipRect.height();
}
if (m_plugin->quirks().contains(PluginQuirkDontCallSetWindowMoreThanOnce)) {
@@ -755,7 +778,7 @@ static Display *getPluginDisplay()
// support gdk based plugins (like flash) that use a different X connection.
// The code below has the same effect as this one:
// Display *gdkDisplay = gdk_x11_display_get_xdisplay(gdk_display_get_default());
- QLibrary library("libgdk-x11-2.0.so.0");
+ QLibrary library("libgdk-x11-2.0", 0);
if (!library.load())
return 0;
diff --git a/WebCore/plugins/win/PluginDatabaseWin.cpp b/WebCore/plugins/win/PluginDatabaseWin.cpp
index 5d86117..6cbcdc8 100644
--- a/WebCore/plugins/win/PluginDatabaseWin.cpp
+++ b/WebCore/plugins/win/PluginDatabaseWin.cpp
@@ -332,6 +332,56 @@ static inline void addAdobeAcrobatPluginDirectory(Vector<String>& directories)
RegCloseKey(key);
}
+static inline void addJavaPluginDirectory(Vector<String>& directories)
+{
+ HKEY key;
+ HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\JavaSoft\\Java Plug-in"), 0, KEY_READ, &key);
+ if (result != ERROR_SUCCESS)
+ return;
+
+ WCHAR name[128];
+ FILETIME lastModified;
+
+ Vector<int> latestJavaVersion;
+ String latestJavaVersionString;
+
+ // Enumerate subkeys
+ for (int i = 0;; i++) {
+ DWORD nameLen = sizeof(name) / sizeof(WCHAR);
+ result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified);
+
+ if (result != ERROR_SUCCESS)
+ break;
+
+ Vector<int> javaVersion = parseVersionString(String(name, nameLen));
+ if (compareVersions(javaVersion, latestJavaVersion)) {
+ latestJavaVersion = javaVersion;
+ latestJavaVersionString = String(name, nameLen);
+ }
+ }
+
+ if (!latestJavaVersionString.isEmpty()) {
+ DWORD type;
+ WCHAR javaInstallPathStr[_MAX_PATH];
+ DWORD javaInstallPathSize = sizeof(javaInstallPathStr);
+ DWORD useNewPluginValue;
+ DWORD useNewPluginSize;
+
+ String javaPluginKeyPath = "Software\\JavaSoft\\Java Plug-in\\" + latestJavaVersionString;
+ result = SHGetValue(HKEY_LOCAL_MACHINE, javaPluginKeyPath.charactersWithNullTermination(), TEXT("UseNewJavaPlugin"), &type, (LPVOID)&useNewPluginValue, &useNewPluginSize);
+
+ if (result == ERROR_SUCCESS && useNewPluginValue == 1) {
+ result = SHGetValue(HKEY_LOCAL_MACHINE, javaPluginKeyPath.charactersWithNullTermination(), TEXT("JavaHome"), &type, (LPBYTE)javaInstallPathStr, &javaInstallPathSize);
+ if (result == ERROR_SUCCESS) {
+ String javaPluginDirectory = String(javaInstallPathStr, javaInstallPathSize / sizeof(WCHAR) - 1) + "\\bin\\new_plugin";
+ directories.append(javaPluginDirectory);
+ }
+ }
+ }
+
+ RegCloseKey(key);
+}
+
static inline String safariPluginsDirectory()
{
WCHAR moduleFileNameStr[_MAX_PATH];
@@ -385,6 +435,9 @@ Vector<String> PluginDatabase::defaultPluginDirectories()
addMozillaPluginDirectories(directories);
addWindowsMediaPlayerPluginDirectory(directories);
addMacromediaPluginDirectories(directories);
+#if PLATFORM(QT)
+ addJavaPluginDirectory(directories);
+#endif
return directories;
}