18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Collabora, Ltd.  All rights reserved.
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 Torch Mobile, Inc.  All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginPackage.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MIMETypeRegistry.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDatabase.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginDebug.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Timer.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "npruntime_impl.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <string.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/OwnArrayPtr.h>
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/CString.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <shlwapi.h>
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic String getVersionInfo(const LPVOID versionInfoData, const String& info)
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LPVOID buffer;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UINT bufferLength;
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String subInfo = "\\StringfileInfo\\040904E4\\" + info;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool retval = VerQueryValueW(versionInfoData,
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const_cast<UChar*>(subInfo.charactersWithNullTermination()),
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        &buffer, &bufferLength);
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!retval || bufferLength == 0)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return String();
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Subtract 1 from the length; we don't want the trailing null character.
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return String(reinterpret_cast<UChar*>(buffer), bufferLength - 1);
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginPackage::isPluginBlacklisted()
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (name() == "Citrix ICA Client") {
628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // The Citrix ICA Client plug-in requires a Mozilla-based browser; see <rdar://6418681>.
638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return true;
648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name() == "Silverlight Plug-In") {
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // workaround for <rdar://5557379> Crash in Silverlight when opening microsoft.com.
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the latest 1.0 version of Silverlight does not reproduce this crash, so allow it
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // and any newer versions
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const PlatformModuleVersion slPluginMinRequired(0x51BE0000, 0x00010000);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (compareFileVersion(slPluginMinRequired) < 0)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else if (fileName() == "npmozax.dll") {
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Bug 15217: Mozilla ActiveX control complains about missing xpcom_core.dll
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
772bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (fileName() == "npwpf.dll") {
782bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Bug 57119: Microsoft Windows Presentation Foundation (WPF) plug-in complains about missing xpcom.dll
792bde8e466a4451c7319e3a072d118917957d6554Steve Block        return true;
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else if (name() == "Yahoo Application State Plugin") {
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // https://bugs.webkit.org/show_bug.cgi?id=26860
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Bug in Yahoo Application State plug-in earlier than 1.0.0.6 leads to heap corruption.
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static const PlatformModuleVersion yahooAppStatePluginMinRequired(0x00000006, 0x00010000);
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (compareFileVersion(yahooAppStatePluginMinRequired) < 0)
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return true;
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid PluginPackage::determineQuirks(const String& mimeType)
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mimeType == "application/x-shockwave-flash") {
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const PlatformModuleVersion flashTenVersion(0x00000000, 0x000a0000);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Pre 10 Flash only requests windowless plugins if we return a mozilla user agent
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (compareFileVersion(flashTenVersion) < 0)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_quirks.add(PluginQuirkWantsMozillaUserAgent);
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkThrottleInvalidate);
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkFlashURLNotifyBug);
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name().contains("Microsoft") && name().contains("Windows Media")) {
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The WMP plugin sets its size on the first NPP_SetWindow call and never updates its size, so
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // call SetWindow when the plugin view has a correct size
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDeferFirstSetWindowCall);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Windowless mode does not work at all with the WMP plugin so just remove that parameter
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // and don't pass it to the plug-in.
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkRemoveWindowlessVideoParam);
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // WMP has a modal message loop that it enters whenever we call it or
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // ask it to paint. This modal loop can deliver messages to other
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // windows in WebKit at times when they are not expecting them (for
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // example, delivering a WM_PAINT message during a layout), and these
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // can cause crashes.
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkHasModalMessageLoop);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (name() == "VLC Multimedia Plugin" || name() == "VLC Multimedia Plug-in") {
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // VLC hangs on NPP_Destroy if we call NPP_SetWindow with a null window handle
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDontSetNullWindowHandleOnDestroy);
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // VLC 0.8.6d and 0.8.6e crash if multiple instances are created.
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // <rdar://problem/5773070> tracks allowing multiple instances when this
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // bug is fixed.
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDontAllowMultipleInstances);
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The DivX plugin sets its size on the first NPP_SetWindow call and never updates its size, so
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // call SetWindow when the plugin view has a correct size
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mimeType == "video/divx")
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDeferFirstSetWindowCall);
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: This is a workaround for a problem in our NPRuntime bindings; if a plug-in creates an
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // NPObject and passes it to a function it's not possible to see what root object that NPObject belongs to.
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Thus, we don't know that the object should be invalidated when the plug-in instance goes away.
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See <rdar://problem/5487742>.
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mimeType == "application/x-silverlight")
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDontUnloadPlugin);
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) {
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Because a single process cannot create multiple VMs, and we cannot reliably unload a
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Java VM, we cannot unload the Java plugin, or we'll lose reference to our only VM
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDontUnloadPlugin);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Setting the window region to an empty region causes bad scrolling repaint problems
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // with the Java plug-in.
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDontClipToZeroRectWhenScrolling);
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mimeType == "audio/x-pn-realaudio-plugin") {
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Prevent the Real plugin from calling the Window Proc recursively, causing the stack to overflow.
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_quirks.add(PluginQuirkDontCallWndProcForSameMessageRecursively);
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const PlatformModuleVersion lastKnownUnloadableRealPlayerVersion(0x000B0B24, 0x00060000);
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Unloading RealPlayer versions newer than 10.5 can cause a hang; see rdar://5669317.
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Resume unloading when this bug in the RealPlayer Plug-In is fixed (rdar://5713147)
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (compareFileVersion(lastKnownUnloadableRealPlayerVersion) > 0)
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_quirks.add(PluginQuirkDontUnloadPlugin);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginPackage::fetchInfo()
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD versionInfoSize, zeroHandle;
170635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    versionInfoSize = GetFileVersionInfoSizeW(const_cast<UChar*>(m_path.charactersWithNullTermination()), &zeroHandle);
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (versionInfoSize == 0)
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    OwnArrayPtr<char> versionInfoData = adoptArrayPtr(new char[versionInfoSize]);
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!GetFileVersionInfoW(const_cast<UChar*>(m_path.charactersWithNullTermination()),
177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            0, versionInfoSize, versionInfoData.get()))
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_name = getVersionInfo(versionInfoData.get(), "ProductName");
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_description = getVersionInfo(versionInfoData.get(), "FileDescription");
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_name.isNull() || m_description.isNull())
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    VS_FIXEDFILEINFO* info;
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UINT infoSize;
187f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (!VerQueryValueW(versionInfoData.get(), L"\\", (LPVOID*) &info, &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO))
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_moduleVersion.leastSig = info->dwFileVersionLS;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_moduleVersion.mostSig = info->dwFileVersionMS;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isPluginBlacklisted())
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> types;
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    getVersionInfo(versionInfoData.get(), "MIMEType").split('|', types);
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> extensionLists;
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    getVersionInfo(versionInfoData.get(), "FileExtents").split('|', extensionLists);
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> descriptions;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    getVersionInfo(versionInfoData.get(), "FileOpenName").split('|', descriptions);
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < types.size(); i++) {
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String type = types[i].lower();
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String description = i < descriptions.size() ? descriptions[i] : "";
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String extensionList = i < extensionLists.size() ? extensionLists[i] : "";
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<String> extensionsVector;
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        extensionList.split(',', extensionsVector);
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Get rid of the extension list that may be at the end of the description string.
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int pos = description.find("(*");
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (pos != -1) {
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // There might be a space that we need to get rid of.
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (pos > 1 && description[pos - 1] == ' ')
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                pos--;
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            description = description.left(pos);
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Determine the quirks for the MIME types this plug-in supports
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        determineQuirks(type);
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_mimeToExtensions.add(type, extensionsVector);
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_mimeToDescriptions.add(type, description);
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginPackage::load()
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_freeLibraryTimer.isActive()) {
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_module);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_freeLibraryTimer.stop();
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (m_isLoaded) {
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_quirks.contains(PluginQuirkDontAllowMultipleInstances))
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_loadCount++;
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
240d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_module = ::LoadLibraryW(m_path.charactersWithNullTermination());
2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        WCHAR currentPath[MAX_PATH];
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!::GetCurrentDirectoryW(MAX_PATH, currentPath))
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String path = m_path.substring(0, m_path.reverseFind('\\'));
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!::SetCurrentDirectoryW(path.charactersWithNullTermination()))
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Load the library
2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_module = ::LoadLibraryExW(m_path.charactersWithNullTermination(), 0, LOAD_WITH_ALTERED_SEARCH_PATH);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!::SetCurrentDirectoryW(currentPath)) {
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_module)
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ::FreeLibrary(m_module);
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_module)
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_isLoaded = true;
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NP_GetEntryPointsFuncPtr NP_GetEntryPoints = 0;
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NP_InitializeFuncPtr NP_Initialize = 0;
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NPError npErr;
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
273d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NP_Initialize = (NP_InitializeFuncPtr)GetProcAddress(m_module, L"NP_Initialize");
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)GetProcAddress(m_module, L"NP_GetEntryPoints");
2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_NPP_Shutdown = (NPP_ShutdownProcPtr)GetProcAddress(m_module, L"NP_Shutdown");
2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NP_Initialize = (NP_InitializeFuncPtr)GetProcAddress(m_module, "NP_Initialize");
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)GetProcAddress(m_module, "NP_GetEntryPoints");
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_NPP_Shutdown = (NPP_ShutdownProcPtr)GetProcAddress(m_module, "NP_Shutdown");
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!NP_Initialize || !NP_GetEntryPoints || !m_NPP_Shutdown)
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        goto abort;
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_pluginFuncs.size = sizeof(m_pluginFuncs);
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    npErr = NP_GetEntryPoints(&m_pluginFuncs);
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LOG_NPERROR(npErr);
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (npErr != NPERR_NO_ERROR)
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        goto abort;
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    initializeBrowserFuncs();
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    npErr = NP_Initialize(&m_browserFuncs);
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LOG_NPERROR(npErr);
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (npErr != NPERR_NO_ERROR)
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        goto abort;
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loadCount++;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectabort:
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unloadWithoutShutdown();
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned PluginPackage::hash() const
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const unsigned hashCodes[] = {
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_name.impl()->hash(),
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_description.impl()->hash(),
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_mimeToExtensions.size()
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3182bde8e466a4451c7319e3a072d118917957d6554Steve Block    return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (a.m_name != b.m_name)
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (a.m_description != b.m_description)
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (a.m_mimeToExtensions.size() != b.m_mimeToExtensions.size())
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MIMEToExtensionsMap::const_iterator::Keys end = a.m_mimeToExtensions.end().keys();
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (MIMEToExtensionsMap::const_iterator::Keys it = a.m_mimeToExtensions.begin().keys(); it != end; ++it) {
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!b.m_mimeToExtensions.contains(*it))
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34121939df44de1705786c545cd1bf519d47250322dBen Murdochuint16_t PluginPackage::NPVersion() const
342692e5dbf12901edacf14812a6fae25462920af42Steve Block{
343692e5dbf12901edacf14812a6fae25462920af42Steve Block    return NP_VERSION_MINOR;
344692e5dbf12901edacf14812a6fae25462920af42Steve Block}
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
346