1cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block/*
2cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
4cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    This library is free software; you can redistribute it and/or
5cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    modify it under the terms of the GNU Library General Public
6cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    License as published by the Free Software Foundation; either
7cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    version 2 of the License, or (at your option) any later version.
8cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
9cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    This library is distributed in the hope that it will be useful,
10cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    but WITHOUT ANY WARRANTY; without even the implied warranty of
11cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    Library General Public License for more details.
13cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
14cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    You should have received a copy of the GNU Library General Public License
15cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    along with this library; see the file COPYING.LIB.  If not, write to
16cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    Boston, MA 02110-1301, USA.
18cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block*/
19cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "config.h"
20cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "PluginPackage.h"
21cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
22cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "MIMETypeRegistry.h"
23cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "npinterface.h"
24cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "npruntime_impl.h"
25cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "PluginDatabase.h"
26cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "PluginDebug.h"
27cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include <QPluginLoader>
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h>
29cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
30cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blocknamespace WebCore {
31cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(NETSCAPE_PLUGIN_API)
33cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockbool PluginPackage::fetchInfo()
34cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
35cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!load())
36cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return false;
37cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
38cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    char* buf = 0;
39cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    NPError err = m_pluginFuncs.getvalue(0, NPPVpluginNameString, (void *)&buf);
40cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_name = buf;
41cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    err = m_pluginFuncs.getvalue(0, NPPVpluginDescriptionString, (void *)&buf);
42cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_description = buf;
43cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
44cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    determineModuleVersionFromDescription();
45cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
46cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    String s = m_npInterface->NP_GetMIMEDescription();
47cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    Vector<String> types;
48cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    s.split(UChar('|'), false, types);  // <MIME1>;<ext1,ext2,ext3,...>;<Description>|<MIME2>|<MIME3>|...
49cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
50cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    for (int i = 0; i < types.size(); ++i) {
51cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        Vector<String> mime;
52cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        types[i].split(UChar(';'), true, mime);  // <MIME1>;<ext1,ext2,ext3,...>;<Description>
53cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (mime.size() > 0) {
54cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            Vector<String> exts;
55cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            if (mime.size() > 1)
56cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                mime[1].split(UChar(','), false, exts); // <ext1,ext2,ext3,...>
57cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
58cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            m_mimeToExtensions.add(mime[0], exts); // <MIME>,<ext1,ext2,ext3>
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            determineQuirks(mime[0]);
60cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            if (mime.size() > 2)
61cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                m_mimeToDescriptions.add(mime[0], mime[2]); // <MIME>,<Description>
62cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        }
63cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
64cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    unload();
65cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return true;
66cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
67cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid PluginPackage::determineQuirks(const String& mimeType)
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (mimeType == "application/x-shockwave-flash") {
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        PlatformModuleVersion flashTenVersion(0x000a0000);
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (compareFileVersion(flashTenVersion) >= 0) {
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // Flash 10 doesn't like having a 0 window handle.
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            m_quirks.add(PluginQuirkDontSetNullWindowHandleOnDestroy);
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
79cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockbool PluginPackage::load()
80cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
81cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (m_isLoaded) {
82cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_loadCount++;
83cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return true;
84cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
85cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
86cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_pluginLoader = new QPluginLoader(m_path);
87cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!m_pluginLoader->load()) {
88cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        delete m_pluginLoader;
89cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader = 0;
90cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return false;
91cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
92cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
93cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    QObject* plugin = m_pluginLoader->instance();
94cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!plugin) {
95cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader->unload();
96cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        delete m_pluginLoader;
97cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader = 0;
98cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return false;
99cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
100cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
101cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // Plugin instance created
102cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    // Cast plugin to NPInterface,
103cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_npInterface = qobject_cast<NPInterface*>(plugin);
104cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!m_npInterface) {
105cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader->unload();
106cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        delete m_pluginLoader;
107cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader = 0;
108cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return false;
109cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
110cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
111cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_isLoaded = true;
112cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
113cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    NPError npErr;
114cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
115cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_pluginFuncs.size = sizeof(m_pluginFuncs);
116cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.size = sizeof(m_browserFuncs);
117cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.version = NP_VERSION_MINOR;
118cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.geturl = NPN_GetURL;
119cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.posturl = NPN_PostURL;
120cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.requestread = NPN_RequestRead;
121cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.newstream = NPN_NewStream;
122cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.write = NPN_Write;
123cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.destroystream = NPN_DestroyStream;
124cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.status = NPN_Status;
125cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.uagent = NPN_UserAgent;
126cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.memalloc = NPN_MemAlloc;
127cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.memfree = NPN_MemFree;
128cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.memflush = NPN_MemFlush;
129cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.reloadplugins = NPN_ReloadPlugins;
130cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.geturlnotify = NPN_GetURLNotify;
131cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.posturlnotify = NPN_PostURLNotify;
132cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getvalue = NPN_GetValue;
133cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.setvalue = NPN_SetValue;
134cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.invalidaterect = NPN_InvalidateRect;
135cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.invalidateregion = NPN_InvalidateRegion;
136cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.forceredraw = NPN_ForceRedraw;
137cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getJavaEnv = NPN_GetJavaEnv;
138cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getJavaPeer = NPN_GetJavaPeer;
139cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
140cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
141cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
142cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
143cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
144cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
145cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.identifierisstring = _NPN_IdentifierIsString;
146cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
147cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.createobject = _NPN_CreateObject;
148cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.retainobject = _NPN_RetainObject;
149cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.releaseobject = _NPN_ReleaseObject;
150cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.invoke = _NPN_Invoke;
151cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.invokeDefault = _NPN_InvokeDefault;
152cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.evaluate = _NPN_Evaluate;
153cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.getproperty = _NPN_GetProperty;
154cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.setproperty = _NPN_SetProperty;
155cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.removeproperty = _NPN_RemoveProperty;
156cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.hasproperty = _NPN_HasMethod;
157cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.hasmethod = _NPN_HasProperty;
158cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.setexception = _NPN_SetException;
159cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.enumerate = _NPN_Enumerate;
160cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_browserFuncs.construct = _NPN_Construct;
161cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
162cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    npErr = m_npInterface->NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (npErr != NPERR_NO_ERROR) {
164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader->unload();
165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        delete m_pluginLoader;
166cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_pluginLoader = 0;
167cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return false;
168cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
169cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
170cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_loadCount++;
171cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return true;
172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
174cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
175cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid PluginPackage::unload()
176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
177cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (!m_isLoaded)
178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return;
179cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    if (--m_loadCount > 0)
181cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        return;
182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
183cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_isLoaded = false;
184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_npInterface->NP_Shutdown();
185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_pluginLoader->unload();
187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    delete m_pluginLoader;
188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    m_pluginLoader = 0;
189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
190692e5dbf12901edacf14812a6fae25462920af42Steve Block
1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if ENABLE(NETSCAPE_PLUGIN_API)
19221939df44de1705786c545cd1bf519d47250322dBen Murdochuint16_t PluginPackage::NPVersion() const
193692e5dbf12901edacf14812a6fae25462920af42Steve Block{
194692e5dbf12901edacf14812a6fae25462920af42Steve Block    return NP_VERSION_MINOR;
195692e5dbf12901edacf14812a6fae25462920af42Steve Block}
1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
197cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
198cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
199