1/*
2 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3 * Copyright (C) 2008 Collabora Ltd. All rights reserved.
4 * Copyright (C) 2008 Nuanti Ltd.
5 * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
6 * Copyright (C) 2009-2010 ProFUSION embedded systems
7 * Copyright (C) 2009-2011 Samsung Electronics
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "PluginPackage.h"
33
34#include "MIMETypeRegistry.h"
35#include "NotImplemented.h"
36#include "PluginDatabase.h"
37#include "PluginDebug.h"
38#include "npruntime_impl.h"
39
40#include <Eina.h>
41#include <dlfcn.h>
42#include <wtf/text/CString.h>
43
44namespace WebCore {
45
46bool PluginPackage::fetchInfo()
47{
48    const char *errmsg;
49
50    if (!load())
51        return false;
52
53    NPP_GetValueProcPtr getValue = 0;
54    NP_GetMIMEDescriptionFuncPtr getMIMEDescription = 0;
55
56    getValue = reinterpret_cast<NPP_GetValueProcPtr>(eina_module_symbol_get(m_module, "NP_GetValue"));
57    if ((errmsg = dlerror())) {
58        EINA_LOG_ERR("Could not get symbol NP_GetValue: %s", errmsg);
59        return false;
60    }
61
62    getMIMEDescription = reinterpret_cast<NP_GetMIMEDescriptionFuncPtr>(eina_module_symbol_get(m_module, "NP_GetMIMEDescription"));
63    if ((errmsg = dlerror())) {
64        EINA_LOG_ERR("Could not get symbol NP_GetMIMEDescription: %s", errmsg);
65        return false;
66    }
67
68    char* buffer = 0;
69    NPError err = getValue(0, NPPVpluginNameString, static_cast<void*>(&buffer));
70    if (err != NPERR_NO_ERROR)
71        return false;
72    m_name = String::fromUTF8(buffer);
73
74    buffer = 0;
75    err = getValue(0, NPPVpluginDescriptionString, static_cast<void*>(&buffer));
76    if (err != NPERR_NO_ERROR)
77        return false;
78    m_description = String::fromUTF8(buffer);
79    determineModuleVersionFromDescription();
80
81    String description = String::fromUTF8(getMIMEDescription());
82
83    Vector<String> types;
84    description.split(UChar(';'), false, types);
85
86    for (size_t i = 0; i < types.size(); ++i) {
87        Vector<String> mime;
88        types[i].split(UChar(':'), true, mime);
89
90        if (!mime.isEmpty() > 0) {
91            Vector<String> exts;
92
93            if (mime.size() > 1)
94                mime[1].split(UChar(','), false, exts);
95
96            determineQuirks(mime[0]);
97            m_mimeToExtensions.add(mime[0], exts);
98
99            if (mime.size() > 2)
100                m_mimeToDescriptions.add(mime[0], mime[2]);
101        }
102    }
103
104    return true;
105}
106
107uint16_t PluginPackage::NPVersion() const
108{
109    return NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL;
110}
111
112bool PluginPackage::load()
113{
114    if (m_isLoaded) {
115        ++m_loadCount;
116        return true;
117    }
118
119    m_module = eina_module_new(m_path.utf8().data());
120    if (!m_module) {
121        EINA_LOG_WARN("%s not loaded: eina_module_new() failed", m_path.utf8().data());
122        return false;
123    }
124    if (!eina_module_load(m_module)) {
125        const char* errorMessage = eina_error_msg_get(eina_error_get());
126        EINA_LOG_WARN("%s not loaded: %s", m_path.utf8().data(), errorMessage ? errorMessage : "None");
127        return false;
128    }
129
130    m_isLoaded = true;
131
132    NPError err;
133
134    NP_InitializeFuncPtr initialize = reinterpret_cast<NP_InitializeFuncPtr>(eina_module_symbol_get(m_module, "NP_Initialize"));
135    if (!initialize) {
136        EINA_LOG_ERR("Could not get symbol NP_Initialize");
137        goto abort;
138    }
139
140    m_NPP_Shutdown = reinterpret_cast<NPP_ShutdownProcPtr>(eina_module_symbol_get(m_module, "NP_Shutdown"));
141    if (!m_NPP_Shutdown) {
142        EINA_LOG_ERR("Could not get symbol NP_Shutdown");
143        goto abort;
144    }
145
146    memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
147    m_pluginFuncs.size = sizeof(m_pluginFuncs);
148
149    initializeBrowserFuncs();
150
151#if defined(XP_UNIX)
152    err = initialize(&m_browserFuncs, &m_pluginFuncs);
153#else
154    err = initialize(&m_browserFuncs);
155#endif
156    if (err != NPERR_NO_ERROR)
157        goto abort;
158
159    ++m_loadCount;
160    return true;
161
162abort:
163    EINA_LOG_DBG("failed to load plugin, unload it without shutting it down.");
164    unloadWithoutShutdown();
165    return false;
166}
167
168}
169