Skip to content
Permalink
Browse files
Get WebKitTestRunner loading TestNetscapePlugin on Windows
Fixes <http://webkit.org/b/43513> WebKitTestRunner on Windows fails to
load TestNetscapePlugin

Reviewed by Jon Honeycutt.

WebKit2:

Teach WebKit2 how to load the TestNetscapePlugin

* Platform/Module.cpp:
(WebKit::Module::Module): Initialize m_module on Windows.

* Platform/Module.h: Added m_module on Windows.

* Platform/win/ModuleWin.cpp:
(WebKit::Module::load): Implemented using ::LoadLibraryExW.
(WebKit::Module::unload): Implemented using ::FreeLibrary.
(WebKit::Module::platformFunctionPointer): Implemented using
::GetProcAddress.

* Platform/win/RunLoopWin.cpp:
(RunLoop::TimerBase::timerFired): Kill the native timer before calling
the fired callback. This makes all our timers non-repeating, but
that's all we need currently.
(RunLoop::TimerBase::start): Added an assertion to help us figure out
when we need to implement repeating timers. Also fixed a typo.

* UIProcess/Plugins/win/PluginInfoStoreWin.cpp:
(WebKit::PluginInfoStore::pluginsDirectories): Added a FIXME.

(WebKit::PathWalker::PathWalker):
(WebKit::PathWalker::~PathWalker):
(WebKit::PathWalker::isValid):
(WebKit::PathWalker::data):
(WebKit::PathWalker::step):
Added. This class wraps the ::FindFirstFile/::FindNextFile APIs.

(WebKit::PluginInfoStore::pluginPathsInDirectory): Implemented by
porting logic from
WebCore::PluginDatabase::getPluginPathsInDirectories.
(WebKit::getVersionInfo): Copied from PluginDatabaseWin.cpp.
(WebKit::PluginInfoStore::getPluginInfo): Implemented by porting logic
from WebCore::PluginPackage::fetchInfo.
(WebKit::PluginInfoStore::shouldUsePlugin): Changed to always return
true for now. Added a FIXME about implementing this for real.

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didReceiveSyncMessage):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::createPlugin):
Removed PLATFORM(MAC) guards around plugin code.

* win/WebKit2.vcproj: Let VS sort the file.

WebKitTools:

Fix the path to TestNetscapePlugin's directory on Windows

* WebKitTestRunner/win/TestControllerWin.cpp:
(WTR::TestController::initializeTestPluginDirectory):
TestNetscapePlugin is in a TestNetscapePlugin[_Debug] directory that's
next to WebKitTestRunner.exe. Previously we were passing the directory
that contains WebKitTestRunner.exe. Also fixed some leaks.

Canonical link: https://commits.webkit.org/55562@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@64744 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
aroben committed Aug 5, 2010
1 parent 32cb070 commit b59d9710820cb2b0211ca5c6da76f8d0440776e1
Showing 11 changed files with 220 additions and 30 deletions.
@@ -1,3 +1,57 @@
2010-08-04 Adam Roben <aroben@apple.com>

Teach WebKit2 how to load the TestNetscapePlugin

Fixes <http://webkit.org/b/43513> WebKitTestRunner on Windows fails to
load TestNetscapePlugin

Reviewed by Jon Honeycutt.

* Platform/Module.cpp:
(WebKit::Module::Module): Initialize m_module on Windows.

* Platform/Module.h: Added m_module on Windows.

* Platform/win/ModuleWin.cpp:
(WebKit::Module::load): Implemented using ::LoadLibraryExW.
(WebKit::Module::unload): Implemented using ::FreeLibrary.
(WebKit::Module::platformFunctionPointer): Implemented using
::GetProcAddress.

* Platform/win/RunLoopWin.cpp:
(RunLoop::TimerBase::timerFired): Kill the native timer before calling
the fired callback. This makes all our timers non-repeating, but
that's all we need currently.
(RunLoop::TimerBase::start): Added an assertion to help us figure out
when we need to implement repeating timers. Also fixed a typo.

* UIProcess/Plugins/win/PluginInfoStoreWin.cpp:
(WebKit::PluginInfoStore::pluginsDirectories): Added a FIXME.

(WebKit::PathWalker::PathWalker):
(WebKit::PathWalker::~PathWalker):
(WebKit::PathWalker::isValid):
(WebKit::PathWalker::data):
(WebKit::PathWalker::step):
Added. This class wraps the ::FindFirstFile/::FindNextFile APIs.

(WebKit::PluginInfoStore::pluginPathsInDirectory): Implemented by
porting logic from
WebCore::PluginDatabase::getPluginPathsInDirectories.
(WebKit::getVersionInfo): Copied from PluginDatabaseWin.cpp.
(WebKit::PluginInfoStore::getPluginInfo): Implemented by porting logic
from WebCore::PluginPackage::fetchInfo.
(WebKit::PluginInfoStore::shouldUsePlugin): Changed to always return
true for now. Added a FIXME about implementing this for real.

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didReceiveSyncMessage):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::createPlugin):
Removed PLATFORM(MAC) guards around plugin code.

* win/WebKit2.vcproj: Let VS sort the file.

2010-08-05 Antti Koivisto <koivisto@iki.fi>

Reviewed by Kenneth Rohde Christiansen.
@@ -31,6 +31,9 @@ namespace WebKit {

Module::Module(const String& path)
: m_path(path)
#if PLATFORM(WIN)
, m_module(0)
#endif
{
}

@@ -53,6 +53,8 @@ class Module : public Noncopyable {
WebCore::String m_path;
#if PLATFORM(MAC)
RetainPtr<CFBundleRef> m_bundle;
#elif PLATFORM(WIN)
HMODULE m_module;
#endif
};

@@ -25,25 +25,31 @@

#include "Module.h"

#include "NotImplemented.h"
#include <shlwapi.h>

namespace WebKit {

bool Module::load()
{
notImplemented();
return false;
ASSERT(!::PathIsRelativeW(m_path.charactersWithNullTermination()));
m_module = ::LoadLibraryExW(m_path.charactersWithNullTermination(), 0, LOAD_WITH_ALTERED_SEARCH_PATH);
return m_module;
}

void Module::unload()
{
notImplemented();
if (!m_module)
return;
::FreeLibrary(m_module);
m_module = 0;
}

void* Module::platformFunctionPointer(const char* functionName) const
{
notImplemented();
return 0;
}
if (!m_module)
return 0;

return ::GetProcAddress(m_module, functionName);
}

} // namespace WebKit
@@ -121,6 +121,9 @@ void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID)
ASSERT(it != runLoop->m_activeTimers.end());
TimerBase* timer = it->second;

// FIMXE: Support repeating timers.

::KillTimer(runLoop->m_runLoopMessageWindow, ID);
timer->fired();
}

@@ -141,9 +144,10 @@ RunLoop::TimerBase::~TimerBase()
stop();
}

void RunLoop::TimerBase::start(double nextFireInterval, double /*repeatInterval*/)
void RunLoop::TimerBase::start(double nextFireInterval, double repeatInterval)
{
// FIMXE: Support repeating timers.
// FIXME: Support repeating timers.
ASSERT_ARG(repeatInterval, !repeatInterval);

m_runLoop->m_activeTimers.set(m_ID, this);
::SetTimer(m_runLoop->m_runLoopMessageWindow, m_ID, nextFireInterval, 0);
@@ -26,33 +26,139 @@
#include "PluginInfoStore.h"

#include "NotImplemented.h"
#include <WebCore/FileSystem.h>
#include <wtf/OwnArrayPtr.h>

using namespace WebCore;

namespace WebKit {

Vector<String> PluginInfoStore::pluginsDirectories()
{
// FIXME: <http://webkit.org/b/43510> Migrate logic here from PluginDatabase::defaultPluginDirectories.
notImplemented();
return Vector<String>();
}

class PathWalker : public Noncopyable {
public:
PathWalker(const String& directory)
{
String pattern = directory + "\\*";
m_handle = ::FindFirstFileW(pattern.charactersWithNullTermination(), &m_data);
}

~PathWalker()
{
if (!isValid())
return;
::FindClose(m_handle);
}

bool isValid() const { return m_handle != INVALID_HANDLE_VALUE; }
const WIN32_FIND_DATAW& data() const { return m_data; }

bool step() { return ::FindNextFileW(m_handle, &m_data); }

private:
HANDLE m_handle;
WIN32_FIND_DATAW m_data;
};

Vector<String> PluginInfoStore::pluginPathsInDirectory(const String& directory)
{
notImplemented();
return Vector<String>();
Vector<String> paths;

PathWalker walker(directory);
if (!walker.isValid())
return paths;

do {
if (walker.data().dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;

String filename = walker.data().cFileName;
if ((!filename.startsWith("np", false) || !filename.endsWith("dll", false)) && (!equalIgnoringCase(filename, "Plugin.dll") || !directory.endsWith("Shockwave 10", false)))
continue;

paths.append(directory + "\\" + filename);
} while (walker.step());

return paths;
}

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);
}

bool PluginInfoStore::getPluginInfo(const String& pluginPath, Plugin& plugin)
{
notImplemented();
return false;
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;

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);
return true;
}

bool PluginInfoStore::shouldUsePlugin(const Plugin& plugin, const Vector<Plugin>& loadedPlugins)
{
// FIXME: <http://webkit.org/b/43509> Migrate logic here from
// PluginDatabase::getPluginPathsInDirectories and PluginPackage::isPluginBlacklisted.
notImplemented();
return false;
return true;
}

} // namespace WebKit
@@ -337,7 +337,6 @@ void WebProcessProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, Cor
}

case WebProcessProxyMessage::GetPluginHostConnection: {
#if PLATFORM(MAC)
String mimeType;
String urlString;

@@ -347,7 +346,6 @@ void WebProcessProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, Cor
String pluginPath;
getPluginHostConnection(mimeType, KURL(ParsedURLString, urlString), pluginPath);
reply->encode(CoreIPC::In(pluginPath));
#endif
break;
}

@@ -28,10 +28,7 @@
#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1
#include "NotImplemented.h"

#if PLATFORM(MAC)
#include "NetscapePlugin.h"
#endif

#include "PluginView.h"
#include "WebCoreArgumentCoders.h"
#include "WebErrors.h"
@@ -836,8 +833,6 @@ PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugIn
if (pluginPath.isNull())
return 0;

// FIXME: This is Mac specific now because Windows doesn't have the necessary parts of NetscapePluginModule implemented.
#if PLATFORM(MAC)
RefPtr<NetscapePluginModule> pluginModule = NetscapePluginModule::getOrCreate(pluginPath);
if (!pluginModule)
return 0;
@@ -851,9 +846,6 @@ PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugIn

RefPtr<Plugin> plugin = NetscapePlugin::create(pluginModule.release());
return PluginView::create(pluginElement, plugin.release(), parameters);
#else
return 0;
#endif
}

void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
@@ -1341,15 +1341,15 @@
Name="Platform"
>
<File
RelativePath="..\Platform\PlatformProcessIdentifier.h"
RelativePath="..\Platform\Module.cpp"
>
</File>
<File
RelativePath="..\Platform\Module.cpp"
RelativePath="..\Platform\Module.h"
>
</File>
<File
RelativePath="..\Platform\Module.h"
RelativePath="..\Platform\PlatformProcessIdentifier.h"
>
</File>
<File
@@ -1,3 +1,18 @@
2010-08-04 Adam Roben <aroben@apple.com>

Fix the path to TestNetscapePlugin's directory on Windows

Fixes <http://webkit.org/b/43513> WebKitTestRunner on Windows fails to
load TestNetscapePlugin

Reviewed by Jon Honeycutt.

* WebKitTestRunner/win/TestControllerWin.cpp:
(WTR::TestController::initializeTestPluginDirectory):
TestNetscapePlugin is in a TestNetscapePlugin[_Debug] directory that's
next to WebKitTestRunner.exe. Previously we were passing the directory
that contains WebKitTestRunner.exe. Also fixed some leaks.

2010-08-05 Kenichi Ishibashi <bashi@google.com>

Reviewed by Shinichiro Hamaji.

0 comments on commit b59d971

Please sign in to comment.