~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/plugins/win/PluginDatabaseWin.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
 
3
 * Copyright (C) 2008 Collabora, Ltd.  All rights reserved.
 
4
 * Copyright (C) 2008-2009 Torch Mobile, Inc.  All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 * 1. Redistributions of source code must retain the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer.
 
11
 * 2. Redistributions in binary form must reproduce the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer in the
 
13
 *    documentation and/or other materials provided with the distribution.
 
14
 *
 
15
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 
16
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
18
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 
19
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
22
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 
23
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
25
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
26
 */
 
27
 
 
28
#include "config.h"
 
29
#include "PluginDatabase.h"
 
30
 
 
31
#include "Frame.h"
 
32
#include "KURL.h"
 
33
#include "PluginPackage.h"
 
34
#include "WindowsExtras.h"
 
35
 
 
36
#if OS(WINCE)
 
37
// WINCE doesn't support Registry Key Access Rights. The parameter should always be 0
 
38
#ifndef KEY_ENUMERATE_SUB_KEYS
 
39
#define KEY_ENUMERATE_SUB_KEYS 0
 
40
#endif
 
41
 
 
42
BOOL PathRemoveFileSpec(LPWSTR moduleFileNameStr)
 
43
{
 
44
    if (!*moduleFileNameStr)
 
45
        return FALSE;
 
46
 
 
47
    LPWSTR lastPos = 0;
 
48
    LPWSTR curPos = moduleFileNameStr;
 
49
    do {
 
50
        if (*curPos == L'/' || *curPos == L'\\')
 
51
            lastPos = curPos;
 
52
    } while (*++curPos);
 
53
 
 
54
    if (lastPos == curPos - 1)
 
55
        return FALSE;
 
56
 
 
57
    if (lastPos)
 
58
        *lastPos = 0;
 
59
    else {
 
60
        moduleFileNameStr[0] = L'\\';
 
61
        moduleFileNameStr[1] = 0;
 
62
    }
 
63
 
 
64
    return TRUE;
 
65
}
 
66
#endif
 
67
 
 
68
namespace WebCore {
 
69
 
 
70
static inline void addPluginPathsFromRegistry(HKEY rootKey, HashSet<String>& paths)
 
71
{
 
72
    HKEY key;
 
73
    HRESULT result = RegOpenKeyExW(rootKey, L"Software\\MozillaPlugins", 0, KEY_ENUMERATE_SUB_KEYS, &key);
 
74
 
 
75
    if (result != ERROR_SUCCESS)
 
76
        return;
 
77
 
 
78
    wchar_t name[128];
 
79
    FILETIME lastModified;
 
80
 
 
81
    // Enumerate subkeys
 
82
    for (int i = 0;; i++) {
 
83
        DWORD nameLen = WTF_ARRAY_LENGTH(name);
 
84
        result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified);
 
85
 
 
86
        if (result != ERROR_SUCCESS)
 
87
            break;
 
88
 
 
89
        WCHAR pathStr[_MAX_PATH];
 
90
        DWORD pathStrSize = sizeof(pathStr);
 
91
        DWORD type;
 
92
 
 
93
        result = getRegistryValue(key, name, L"Path", &type, pathStr, &pathStrSize);
 
94
        if (result != ERROR_SUCCESS || type != REG_SZ)
 
95
            continue;
 
96
 
 
97
        paths.add(String(pathStr, pathStrSize / sizeof(WCHAR) - 1));
 
98
    }
 
99
 
 
100
    RegCloseKey(key);
 
101
}
 
102
 
 
103
void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
 
104
{
 
105
    // FIXME: This should be a case insensitive set.
 
106
    HashSet<String> uniqueFilenames;
 
107
 
 
108
    HANDLE hFind = INVALID_HANDLE_VALUE;
 
109
    WIN32_FIND_DATAW findFileData;
 
110
 
 
111
    String oldWMPPluginPath;
 
112
    String newWMPPluginPath;
 
113
 
 
114
    Vector<String>::const_iterator end = m_pluginDirectories.end();
 
115
    for (Vector<String>::const_iterator it = m_pluginDirectories.begin(); it != end; ++it) {
 
116
        String pattern = *it + "\\*";
 
117
 
 
118
        hFind = FindFirstFileW(pattern.charactersWithNullTermination(), &findFileData);
 
119
 
 
120
        if (hFind == INVALID_HANDLE_VALUE)
 
121
            continue;
 
122
 
 
123
        do {
 
124
            if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 
125
                continue;
 
126
 
 
127
            String filename = String(findFileData.cFileName, wcslen(findFileData.cFileName));
 
128
            if ((!filename.startsWith("np", false) || !filename.endsWith("dll", false)) &&
 
129
                (!equalIgnoringCase(filename, "Plugin.dll") || !it->endsWith("Shockwave 10", false)))
 
130
                continue;
 
131
 
 
132
            String fullPath = *it + "\\" + filename;
 
133
            if (!uniqueFilenames.add(fullPath).isNewEntry)
 
134
                continue;
 
135
 
 
136
            paths.add(fullPath);
 
137
 
 
138
            if (equalIgnoringCase(filename, "npdsplay.dll"))
 
139
                oldWMPPluginPath = fullPath;
 
140
            else if (equalIgnoringCase(filename, "np-mswmp.dll"))
 
141
                newWMPPluginPath = fullPath;
 
142
 
 
143
        } while (FindNextFileW(hFind, &findFileData) != 0);
 
144
 
 
145
        FindClose(hFind);
 
146
    }
 
147
 
 
148
    addPluginPathsFromRegistry(HKEY_LOCAL_MACHINE, paths);
 
149
    addPluginPathsFromRegistry(HKEY_CURRENT_USER, paths);
 
150
 
 
151
    // If both the old and new WMP plugin are present in the plugins set, 
 
152
    // we remove the old one so we don't end up choosing the old one.
 
153
    if (!oldWMPPluginPath.isEmpty() && !newWMPPluginPath.isEmpty())
 
154
        paths.remove(oldWMPPluginPath);
 
155
}
 
156
 
 
157
static inline Vector<int> parseVersionString(const String& versionString)
 
158
{
 
159
    Vector<int> version;
 
160
 
 
161
    unsigned startPos = 0;
 
162
    unsigned endPos;
 
163
    
 
164
    while (startPos < versionString.length()) {
 
165
        for (endPos = startPos; endPos < versionString.length(); ++endPos)
 
166
            if (versionString[endPos] == '.' || versionString[endPos] == '_')
 
167
                break;
 
168
 
 
169
        int versionComponent = versionString.substring(startPos, endPos - startPos).toInt();
 
170
        version.append(versionComponent);
 
171
 
 
172
        startPos = endPos + 1;
 
173
    }
 
174
 
 
175
    return version;
 
176
}
 
177
 
 
178
// This returns whether versionA is higher than versionB
 
179
static inline bool compareVersions(const Vector<int>& versionA, const Vector<int>& versionB)
 
180
{
 
181
    for (unsigned i = 0; i < versionA.size(); i++) {
 
182
        if (i >= versionB.size())
 
183
            return true;
 
184
 
 
185
        if (versionA[i] > versionB[i])
 
186
            return true;
 
187
        else if (versionA[i] < versionB[i])
 
188
            return false;
 
189
    }
 
190
 
 
191
    // If we come here, the versions are either the same or versionB has an extra component, just return false
 
192
    return false;
 
193
}
 
194
 
 
195
static inline void addMozillaPluginDirectories(Vector<String>& directories)
 
196
{
 
197
    // Enumerate all Mozilla plugin directories in the registry
 
198
    HKEY key;
 
199
    LONG result;
 
200
    
 
201
    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Mozilla"), 0, KEY_READ, &key);
 
202
    if (result == ERROR_SUCCESS) {
 
203
        WCHAR name[128];
 
204
        FILETIME lastModified;
 
205
 
 
206
        // Enumerate subkeys
 
207
        for (int i = 0;; i++) {
 
208
            DWORD nameLen = sizeof(name) / sizeof(WCHAR);
 
209
            result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified);
 
210
 
 
211
            if (result != ERROR_SUCCESS)
 
212
                break;
 
213
 
 
214
            String extensionsPath = String(name, nameLen) + "\\Extensions";
 
215
            HKEY extensionsKey;
 
216
 
 
217
            // Try opening the key
 
218
            result = RegOpenKeyEx(key, extensionsPath.charactersWithNullTermination(), 0, KEY_READ, &extensionsKey);
 
219
 
 
220
            if (result == ERROR_SUCCESS) {
 
221
                // Now get the plugins directory
 
222
                WCHAR pluginsDirectoryStr[_MAX_PATH];
 
223
                DWORD pluginsDirectorySize = sizeof(pluginsDirectoryStr);
 
224
                DWORD type;
 
225
 
 
226
                result = RegQueryValueEx(extensionsKey, TEXT("Plugins"), 0, &type, (LPBYTE)&pluginsDirectoryStr, &pluginsDirectorySize);
 
227
 
 
228
                if (result == ERROR_SUCCESS && type == REG_SZ)
 
229
                    directories.append(String(pluginsDirectoryStr, pluginsDirectorySize / sizeof(WCHAR) - 1));
 
230
 
 
231
                RegCloseKey(extensionsKey);
 
232
            }
 
233
        }
 
234
        
 
235
        RegCloseKey(key);
 
236
    }
 
237
}
 
238
 
 
239
static inline void addWindowsMediaPlayerPluginDirectory(Vector<String>& directories)
 
240
{
 
241
#if !OS(WINCE)
 
242
    // The new WMP Firefox plugin is installed in \PFiles\Plugins if it can't find any Firefox installs
 
243
    WCHAR pluginDirectoryStr[_MAX_PATH + 1];
 
244
    DWORD pluginDirectorySize = ::ExpandEnvironmentStringsW(TEXT("%SYSTEMDRIVE%\\PFiles\\Plugins"), pluginDirectoryStr, WTF_ARRAY_LENGTH(pluginDirectoryStr));
 
245
 
 
246
    if (pluginDirectorySize > 0 && pluginDirectorySize <= WTF_ARRAY_LENGTH(pluginDirectoryStr))
 
247
        directories.append(String(pluginDirectoryStr, pluginDirectorySize - 1));
 
248
#endif
 
249
 
 
250
    DWORD type;
 
251
    WCHAR installationDirectoryStr[_MAX_PATH];
 
252
    DWORD installationDirectorySize = sizeof(installationDirectoryStr);
 
253
 
 
254
    HRESULT result = getRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MediaPlayer", L"Installation Directory", &type, &installationDirectoryStr, &installationDirectorySize);
 
255
 
 
256
    if (result == ERROR_SUCCESS && type == REG_SZ)
 
257
        directories.append(String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1));
 
258
}
 
259
 
 
260
static inline void addQuickTimePluginDirectory(Vector<String>& directories)
 
261
{
 
262
    DWORD type;
 
263
    WCHAR installationDirectoryStr[_MAX_PATH];
 
264
    DWORD installationDirectorySize = sizeof(installationDirectoryStr);
 
265
 
 
266
    HRESULT result = getRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Apple Computer, Inc.\\QuickTime", L"InstallDir", &type, &installationDirectoryStr, &installationDirectorySize);
 
267
 
 
268
    if (result == ERROR_SUCCESS && type == REG_SZ) {
 
269
        String pluginDir = String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1) + "\\plugins";
 
270
        directories.append(pluginDir);
 
271
    }
 
272
}
 
273
 
 
274
static inline void addAdobeAcrobatPluginDirectory(Vector<String>& directories)
 
275
{
 
276
    HKEY key;
 
277
    HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Adobe\\Acrobat Reader"), 0, KEY_READ, &key);
 
278
    if (result != ERROR_SUCCESS)
 
279
        return;
 
280
 
 
281
    WCHAR name[128];
 
282
    FILETIME lastModified;
 
283
 
 
284
    Vector<int> latestAcrobatVersion;
 
285
    String latestAcrobatVersionString;
 
286
 
 
287
    // Enumerate subkeys
 
288
    for (int i = 0;; i++) {
 
289
        DWORD nameLen = sizeof(name) / sizeof(WCHAR);
 
290
        result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified);
 
291
 
 
292
        if (result != ERROR_SUCCESS)
 
293
            break;
 
294
 
 
295
        Vector<int> acrobatVersion = parseVersionString(String(name, nameLen));
 
296
        if (compareVersions(acrobatVersion, latestAcrobatVersion)) {
 
297
            latestAcrobatVersion = acrobatVersion;
 
298
            latestAcrobatVersionString = String(name, nameLen);
 
299
        }
 
300
    }
 
301
 
 
302
    if (!latestAcrobatVersionString.isNull()) {
 
303
        DWORD type;
 
304
        WCHAR acrobatInstallPathStr[_MAX_PATH];
 
305
        DWORD acrobatInstallPathSize = sizeof(acrobatInstallPathStr);
 
306
 
 
307
        String acrobatPluginKeyPath = "Software\\Adobe\\Acrobat Reader\\" + latestAcrobatVersionString + "\\InstallPath";
 
308
        result = getRegistryValue(HKEY_LOCAL_MACHINE, acrobatPluginKeyPath.charactersWithNullTermination(), 0, &type, acrobatInstallPathStr, &acrobatInstallPathSize);
 
309
 
 
310
        if (result == ERROR_SUCCESS) {
 
311
            String acrobatPluginDirectory = String(acrobatInstallPathStr, acrobatInstallPathSize / sizeof(WCHAR) - 1) + "\\browser";
 
312
            directories.append(acrobatPluginDirectory);
 
313
        }
 
314
    }
 
315
 
 
316
    RegCloseKey(key);
 
317
}
 
318
 
 
319
static inline void addJavaPluginDirectory(Vector<String>& directories)
 
320
{
 
321
    HKEY key;
 
322
    HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\JavaSoft\\Java Plug-in"), 0, KEY_READ, &key);
 
323
    if (result != ERROR_SUCCESS)
 
324
        return;
 
325
 
 
326
    WCHAR name[128];
 
327
    FILETIME lastModified;
 
328
 
 
329
    Vector<int> latestJavaVersion;
 
330
    String latestJavaVersionString;
 
331
 
 
332
    // Enumerate subkeys
 
333
    for (int i = 0;; i++) {
 
334
        DWORD nameLen = sizeof(name) / sizeof(WCHAR);
 
335
        result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified);
 
336
 
 
337
        if (result != ERROR_SUCCESS)
 
338
            break;
 
339
 
 
340
        Vector<int> javaVersion = parseVersionString(String(name, nameLen));
 
341
        if (compareVersions(javaVersion, latestJavaVersion)) {
 
342
            latestJavaVersion = javaVersion;
 
343
            latestJavaVersionString = String(name, nameLen);
 
344
        }
 
345
    }
 
346
 
 
347
    if (!latestJavaVersionString.isEmpty()) {
 
348
        DWORD type;
 
349
        WCHAR javaInstallPathStr[_MAX_PATH];
 
350
        DWORD javaInstallPathSize = sizeof(javaInstallPathStr);
 
351
        DWORD useNewPluginValue;
 
352
        DWORD useNewPluginSize;
 
353
 
 
354
        String javaPluginKeyPath = "Software\\JavaSoft\\Java Plug-in\\" + latestJavaVersionString;
 
355
        result = getRegistryValue(HKEY_LOCAL_MACHINE, javaPluginKeyPath.charactersWithNullTermination(), L"UseNewJavaPlugin", &type, &useNewPluginValue, &useNewPluginSize);
 
356
 
 
357
        if (result == ERROR_SUCCESS && useNewPluginValue == 1) {
 
358
            result = getRegistryValue(HKEY_LOCAL_MACHINE, javaPluginKeyPath.charactersWithNullTermination(), L"JavaHome", &type, javaInstallPathStr, &javaInstallPathSize);
 
359
            if (result == ERROR_SUCCESS) {
 
360
                String javaPluginDirectory = String(javaInstallPathStr, javaInstallPathSize / sizeof(WCHAR) - 1) + "\\bin\\new_plugin";
 
361
                directories.append(javaPluginDirectory);
 
362
            }
 
363
        }
 
364
    }
 
365
 
 
366
    RegCloseKey(key);
 
367
}
 
368
 
 
369
static inline String safariPluginsDirectory()
 
370
{
 
371
    WCHAR moduleFileNameStr[_MAX_PATH];
 
372
    static String pluginsDirectory;
 
373
    static bool cachedPluginDirectory = false;
 
374
 
 
375
    if (!cachedPluginDirectory) {
 
376
        cachedPluginDirectory = true;
 
377
 
 
378
        int moduleFileNameLen = GetModuleFileName(0, moduleFileNameStr, _MAX_PATH);
 
379
 
 
380
        if (!moduleFileNameLen || moduleFileNameLen == _MAX_PATH)
 
381
            goto exit;
 
382
 
 
383
        if (!PathRemoveFileSpec(moduleFileNameStr))
 
384
            goto exit;
 
385
 
 
386
        pluginsDirectory = String(moduleFileNameStr) + "\\Plugins";
 
387
    }
 
388
exit:
 
389
    return pluginsDirectory;
 
390
}
 
391
 
 
392
static inline void addMacromediaPluginDirectories(Vector<String>& directories)
 
393
{
 
394
#if !OS(WINCE)
 
395
    WCHAR systemDirectoryStr[MAX_PATH];
 
396
 
 
397
    if (!GetSystemDirectory(systemDirectoryStr, WTF_ARRAY_LENGTH(systemDirectoryStr)))
 
398
        return;
 
399
 
 
400
    WCHAR macromediaDirectoryStr[MAX_PATH];
 
401
 
 
402
    PathCombine(macromediaDirectoryStr, systemDirectoryStr, TEXT("macromed\\Flash"));
 
403
    directories.append(macromediaDirectoryStr);
 
404
 
 
405
    PathCombine(macromediaDirectoryStr, systemDirectoryStr, TEXT("macromed\\Shockwave 10"));
 
406
    directories.append(macromediaDirectoryStr);
 
407
#endif
 
408
}
 
409
 
 
410
#if PLATFORM(QT)
 
411
static inline void addQtWebKitPluginPath(Vector<String>& directories)
 
412
{
 
413
    Vector<String> qtPaths;
 
414
    String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").constData());
 
415
    qtPath.split(UChar(';'), false, qtPaths);
 
416
    directories.append(qtPaths);
 
417
}
 
418
#endif
 
419
 
 
420
Vector<String> PluginDatabase::defaultPluginDirectories()
 
421
{
 
422
    Vector<String> directories;
 
423
    String ourDirectory = safariPluginsDirectory();
 
424
 
 
425
    if (!ourDirectory.isNull())
 
426
        directories.append(ourDirectory);
 
427
    addQuickTimePluginDirectory(directories);
 
428
    addAdobeAcrobatPluginDirectory(directories);
 
429
    addMozillaPluginDirectories(directories);
 
430
    addWindowsMediaPlayerPluginDirectory(directories);
 
431
    addMacromediaPluginDirectories(directories);
 
432
#if PLATFORM(QT)
 
433
    addJavaPluginDirectory(directories);
 
434
    addQtWebKitPluginPath(directories);
 
435
#endif
 
436
 
 
437
    return directories;
 
438
}
 
439
 
 
440
bool PluginDatabase::isPreferredPluginDirectory(const String& directory)
 
441
{
 
442
    String ourDirectory = safariPluginsDirectory();
 
443
 
 
444
    if (!ourDirectory.isNull() && !directory.isNull())
 
445
        return ourDirectory == directory;
 
446
 
 
447
    return false;
 
448
}
 
449
 
 
450
}