2001-09-28 20:14:13 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-04-18 22:01:16 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
1998-07-28 02:07:25 +00:00
|
|
|
*
|
2004-04-18 22:01:16 +00:00
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
1998-07-28 02:07:25 +00:00
|
|
|
*
|
2001-09-28 20:14:13 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
1998-07-28 02:07:25 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2004-04-18 22:01:16 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
2001-09-28 20:14:13 +00:00
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
1999-11-06 03:43:54 +00:00
|
|
|
*
|
2001-09-28 20:14:13 +00:00
|
|
|
* Contributor(s):
|
2001-03-31 02:26:51 +00:00
|
|
|
* Sean Echevarria <sean@beatnik.com>
|
2008-03-10 07:07:15 +00:00
|
|
|
* Håkan Waara <hwaara@chello.se>
|
2006-01-05 17:07:01 +00:00
|
|
|
* Josh Aas <josh@mozilla.com>
|
2001-09-28 20:14:13 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-04-18 22:01:16 +00:00
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
2001-09-28 20:14:13 +00:00
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
2004-04-18 22:01:16 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-09-28 20:14:13 +00:00
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
2004-04-18 22:01:16 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-09-28 20:14:13 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1998-07-28 02:07:25 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
/* nsPluginHost.cpp - top-level plugin management code */
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-08-14 07:59:59 +00:00
|
|
|
#include "nscore.h"
|
2009-07-02 05:48:08 +00:00
|
|
|
#include "nsPluginHost.h"
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1998-07-28 02:07:25 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include "prio.h"
|
|
|
|
#include "prmem.h"
|
2010-06-10 18:11:40 +00:00
|
|
|
#include "nsIComponentManager.h"
|
2008-09-15 12:45:01 +00:00
|
|
|
#include "nsNPAPIPlugin.h"
|
|
|
|
#include "nsNPAPIPluginStreamListener.h"
|
2001-03-12 02:07:15 +00:00
|
|
|
#include "nsIPlugin.h"
|
2009-06-29 18:53:52 +00:00
|
|
|
#include "nsNPAPIPluginInstance.h"
|
1999-01-25 08:05:00 +00:00
|
|
|
#include "nsIPluginStreamListener.h"
|
2004-10-11 04:01:49 +00:00
|
|
|
#include "nsIHTTPHeaderListener.h"
|
|
|
|
#include "nsIHttpHeaderVisitor.h"
|
2001-03-12 02:07:15 +00:00
|
|
|
#include "nsIObserverService.h"
|
2001-05-11 21:05:08 +00:00
|
|
|
#include "nsIHttpProtocolHandler.h"
|
|
|
|
#include "nsIHttpChannel.h"
|
2007-03-16 23:53:16 +00:00
|
|
|
#include "nsIHttpChannelInternal.h"
|
2001-09-05 03:52:26 +00:00
|
|
|
#include "nsIUploadChannel.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsIByteRangeRequest.h"
|
1998-08-05 04:21:36 +00:00
|
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "nsIInputStream.h"
|
1999-03-11 22:48:58 +00:00
|
|
|
#include "nsIOutputStream.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#include "nsIURL.h"
|
1999-10-09 01:18:02 +00:00
|
|
|
#include "nsXPIDLString.h"
|
2001-09-29 08:28:41 +00:00
|
|
|
#include "nsReadableUtils.h"
|
2001-05-02 23:38:41 +00:00
|
|
|
#include "nsIProtocolProxyService.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsIStreamConverterService.h"
|
2000-08-19 05:44:34 +00:00
|
|
|
#include "nsIFile.h"
|
2000-08-22 07:03:33 +00:00
|
|
|
#include "nsIInputStream.h"
|
1999-06-18 17:34:08 +00:00
|
|
|
#include "nsIIOService.h"
|
1999-06-23 03:29:44 +00:00
|
|
|
#include "nsIURL.h"
|
1999-06-25 01:41:26 +00:00
|
|
|
#include "nsIChannel.h"
|
2003-03-15 01:04:32 +00:00
|
|
|
#include "nsISeekableStream.h"
|
1999-11-30 04:50:42 +00:00
|
|
|
#include "nsNetUtil.h"
|
1999-07-07 08:08:40 +00:00
|
|
|
#include "nsIProgressEventSink.h"
|
1999-07-09 21:18:47 +00:00
|
|
|
#include "nsIDocument.h"
|
2001-03-14 02:05:21 +00:00
|
|
|
#include "nsICachingChannel.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsHashtable.h"
|
2001-09-13 02:21:05 +00:00
|
|
|
#include "nsIProxyInfo.h"
|
2001-08-16 02:59:03 +00:00
|
|
|
#include "nsPluginLogging.h"
|
2005-11-06 18:34:03 +00:00
|
|
|
#include "nsIPrefBranch2.h"
|
2007-03-02 08:38:31 +00:00
|
|
|
#include "nsIScriptChannel.h"
|
2007-03-16 23:53:16 +00:00
|
|
|
#include "nsPrintfCString.h"
|
2008-11-02 12:13:48 +00:00
|
|
|
#include "nsIBlocklistService.h"
|
2008-11-02 15:49:03 +00:00
|
|
|
#include "nsVersionComparator.h"
|
2009-01-30 21:40:14 +00:00
|
|
|
#include "nsIPrivateBrowsingService.h"
|
2010-01-13 16:42:41 +00:00
|
|
|
#include "nsIObjectLoadingContent.h"
|
2010-02-10 01:05:31 +00:00
|
|
|
#include "nsIWritablePropertyBag2.h"
|
2010-07-13 20:48:00 +00:00
|
|
|
#include "nsPluginStreamListenerPeer.h"
|
2001-04-17 10:47:22 +00:00
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
#include "nsEnumeratorUtils.h"
|
2002-09-03 23:36:13 +00:00
|
|
|
#include "nsXPCOM.h"
|
2003-02-27 13:51:55 +00:00
|
|
|
#include "nsXPCOMCID.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsISupportsPrimitives.h"
|
2009-02-09 18:48:06 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
#include "nsIXULRuntime.h"
|
|
|
|
|
2000-06-20 21:04:52 +00:00
|
|
|
// for the dialog
|
|
|
|
#include "nsIStringBundle.h"
|
2001-04-07 03:33:56 +00:00
|
|
|
#include "nsIWindowWatcher.h"
|
2005-09-17 03:40:08 +00:00
|
|
|
#include "nsPIDOMWindow.h"
|
2000-07-20 22:53:32 +00:00
|
|
|
|
2000-07-13 02:44:14 +00:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "nsIScriptGlobalObjectOwner.h"
|
|
|
|
#include "nsIPrincipal.h"
|
2000-06-20 21:04:52 +00:00
|
|
|
|
2003-10-30 02:59:31 +00:00
|
|
|
#include "nsNetCID.h"
|
1999-04-20 19:29:28 +00:00
|
|
|
#include "nsIDOMPlugin.h"
|
|
|
|
#include "nsIDOMMimeType.h"
|
2001-06-04 22:59:22 +00:00
|
|
|
#include "nsMimeTypes.h"
|
1998-09-15 03:48:58 +00:00
|
|
|
#include "prprf.h"
|
2006-05-10 17:30:15 +00:00
|
|
|
#include "nsThreadUtils.h"
|
2001-06-19 01:38:20 +00:00
|
|
|
#include "nsIInputStreamTee.h"
|
2002-07-01 20:36:57 +00:00
|
|
|
#include "nsIInterfaceInfoManager.h"
|
|
|
|
#include "xptinfo.h"
|
2001-06-19 01:38:20 +00:00
|
|
|
|
2000-09-22 06:31:29 +00:00
|
|
|
#include "nsIMIMEService.h"
|
|
|
|
#include "nsCExternalHandlerService.h"
|
2001-04-17 23:30:25 +00:00
|
|
|
#include "nsILocalFile.h"
|
2001-04-28 02:21:25 +00:00
|
|
|
#include "nsIFileChannel.h"
|
2000-09-22 06:31:29 +00:00
|
|
|
|
2001-10-11 04:51:06 +00:00
|
|
|
#include "nsPluginSafety.h"
|
|
|
|
|
2001-10-11 20:55:12 +00:00
|
|
|
#include "nsICharsetConverterManager.h"
|
|
|
|
#include "nsIPlatformCharset.h"
|
|
|
|
|
2001-06-09 01:03:53 +00:00
|
|
|
#include "nsIDirectoryService.h"
|
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2009-09-22 07:46:32 +00:00
|
|
|
#include "nsXULAppAPI.h"
|
2002-06-13 18:19:10 +00:00
|
|
|
#include "nsAppDirectoryServiceDefs.h"
|
2001-06-09 01:03:53 +00:00
|
|
|
#include "nsIFile.h"
|
2001-11-17 15:26:02 +00:00
|
|
|
#include "nsPluginDirServiceProvider.h"
|
2011-04-01 16:23:48 +00:00
|
|
|
#include "nsInt64.h"
|
2002-02-11 23:09:38 +00:00
|
|
|
#include "nsPluginError.h"
|
2001-06-09 01:03:53 +00:00
|
|
|
|
2002-02-19 22:49:12 +00:00
|
|
|
#include "nsUnicharUtils.h"
|
2002-08-14 22:31:59 +00:00
|
|
|
#include "nsPluginManifestLineReader.h"
|
2002-02-19 22:49:12 +00:00
|
|
|
|
2010-02-24 02:58:27 +00:00
|
|
|
#include "nsIWeakReferenceUtils.h"
|
2002-05-30 22:31:27 +00:00
|
|
|
#include "nsIDOMElement.h"
|
2005-01-05 00:21:06 +00:00
|
|
|
#include "nsIDOMHTMLObjectElement.h"
|
|
|
|
#include "nsIDOMHTMLEmbedElement.h"
|
2002-07-03 21:03:51 +00:00
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIWebNavigation.h"
|
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsIDocShell.h"
|
2002-09-26 02:53:27 +00:00
|
|
|
#include "nsPluginNativeWindow.h"
|
2003-04-03 19:11:41 +00:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2005-09-07 02:39:51 +00:00
|
|
|
#include "nsIContentPolicy.h"
|
|
|
|
#include "nsContentPolicyUtils.h"
|
2005-09-07 16:32:52 +00:00
|
|
|
#include "nsContentErrors.h"
|
2010-01-27 01:30:58 +00:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2002-03-26 06:30:33 +00:00
|
|
|
|
2009-02-09 18:48:06 +00:00
|
|
|
#if defined(XP_WIN)
|
2010-11-05 15:18:07 +00:00
|
|
|
#include "nsIWindowMediator.h"
|
|
|
|
#include "nsIBaseWindow.h"
|
2009-02-09 18:48:06 +00:00
|
|
|
#include "windows.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#endif
|
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
using namespace mozilla;
|
2010-01-27 01:30:58 +00:00
|
|
|
using mozilla::TimeStamp;
|
|
|
|
|
2009-08-19 00:25:36 +00:00
|
|
|
// Null out a strong ref to a linked list iteratively to avoid
|
|
|
|
// exhausting the stack (bug 486349).
|
|
|
|
#define NS_ITERATIVE_UNREF_LIST(type_, list_, mNext_) \
|
|
|
|
{ \
|
|
|
|
while (list_) { \
|
|
|
|
type_ temp = list_->mNext_; \
|
|
|
|
list_->mNext_ = nsnull; \
|
|
|
|
list_ = temp; \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
// this is the name of the directory which will be created
|
|
|
|
// to cache temporary files.
|
2002-04-27 05:33:09 +00:00
|
|
|
#define kPluginTmpDirName NS_LITERAL_CSTRING("plugtmp")
|
2001-10-18 12:26:23 +00:00
|
|
|
|
|
|
|
// Version of cached plugin info
|
2001-10-30 06:46:40 +00:00
|
|
|
// 0.01 first implementation
|
|
|
|
// 0.02 added caching of CanUnload to fix bug 105935
|
2001-12-06 02:30:23 +00:00
|
|
|
// 0.03 changed name, description and mime desc from string to bytes, bug 108246
|
2002-04-13 05:10:30 +00:00
|
|
|
// 0.04 added new mime entry point on Mac, bug 113464
|
2002-04-30 05:08:44 +00:00
|
|
|
// 0.05 added new entry point check for the default plugin, bug 132430
|
2002-08-15 00:16:56 +00:00
|
|
|
// 0.06 strip off suffixes in mime description strings, bug 53895
|
2002-11-26 22:28:39 +00:00
|
|
|
// 0.07 changed nsIRegistry to flat file support for caching plugins info
|
2004-10-11 04:01:49 +00:00
|
|
|
// 0.08 mime entry point on MachO, bug 137535
|
2008-03-10 07:07:15 +00:00
|
|
|
// 0.09 the file encoding is changed to UTF-8, bug 420285
|
2008-07-15 10:50:42 +00:00
|
|
|
// 0.10 added plugin versions on appropriate platforms, bug 427743
|
2009-06-10 20:47:49 +00:00
|
|
|
// 0.11 file name and full path fields now store expected values on all platforms, bug 488181
|
2010-11-15 22:21:50 +00:00
|
|
|
// 0.12 force refresh due to quicktime pdf claim fix, bug 611197
|
2010-12-09 22:28:15 +00:00
|
|
|
// 0.13 add architecture and list of invalid plugins, bug 616271
|
2011-01-07 12:47:41 +00:00
|
|
|
// 0.14 force refresh due to locale comparison fix, bug 611296
|
2011-03-24 18:43:37 +00:00
|
|
|
// 0.15 force refresh due to bug in reading Java plist MIME data, bug 638171
|
2008-11-02 15:49:03 +00:00
|
|
|
// The current plugin registry version (and the maximum version we know how to read)
|
2011-03-24 18:43:37 +00:00
|
|
|
static const char *kPluginRegistryVersion = "0.15";
|
2008-11-02 15:49:03 +00:00
|
|
|
// The minimum registry version we know how to read
|
|
|
|
static const char *kMinimumRegistryVersion = "0.9";
|
2008-11-03 19:23:07 +00:00
|
|
|
|
2009-07-02 00:54:18 +00:00
|
|
|
static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID);
|
2001-11-17 15:26:02 +00:00
|
|
|
static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
2000-07-07 00:10:54 +00:00
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
// Registry keys for caching plugin info
|
|
|
|
static const char kPluginsRootKey[] = "software/plugins";
|
|
|
|
static const char kPluginsNameKey[] = "name";
|
|
|
|
static const char kPluginsDescKey[] = "description";
|
|
|
|
static const char kPluginsFilenameKey[] = "filename";
|
|
|
|
static const char kPluginsFullpathKey[] = "fullpath";
|
|
|
|
static const char kPluginsModTimeKey[] = "lastModTimeStamp";
|
2001-10-30 06:46:40 +00:00
|
|
|
static const char kPluginsCanUnload[] = "canUnload";
|
2001-10-18 12:26:23 +00:00
|
|
|
static const char kPluginsVersionKey[] = "version";
|
|
|
|
static const char kPluginsMimeTypeKey[] = "mimetype";
|
|
|
|
static const char kPluginsMimeDescKey[] = "description";
|
|
|
|
static const char kPluginsMimeExtKey[] = "extension";
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
#define kPluginRegistryFilename NS_LITERAL_CSTRING("pluginreg.dat")
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
PRLogModuleInfo* nsPluginLogging::gNPNLog = nsnull;
|
|
|
|
PRLogModuleInfo* nsPluginLogging::gNPPLog = nsnull;
|
|
|
|
PRLogModuleInfo* nsPluginLogging::gPluginLog = nsnull;
|
|
|
|
#endif
|
|
|
|
|
2005-03-10 04:38:35 +00:00
|
|
|
#define BRAND_PROPERTIES_URL "chrome://branding/locale/brand.properties"
|
2000-06-20 21:04:52 +00:00
|
|
|
#define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.properties"
|
2001-02-07 01:13:01 +00:00
|
|
|
|
2001-02-14 23:03:47 +00:00
|
|
|
// #defines for plugin cache and prefs
|
|
|
|
#define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins"
|
|
|
|
#define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
|
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
#ifdef CALL_SAFETY_ON
|
2011-02-04 15:23:55 +00:00
|
|
|
// By default we run OOPP, so we don't want to cover up crashes.
|
|
|
|
PRBool gSkipPluginSafeCalls = PR_TRUE;
|
2010-07-13 20:48:00 +00:00
|
|
|
#endif
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
nsIFile *nsPluginHost::sPluginTempDir;
|
|
|
|
nsPluginHost *nsPluginHost::sInst;
|
1998-08-05 04:21:36 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
NS_IMPL_ISUPPORTS0(nsInvalidPluginTag)
|
|
|
|
|
|
|
|
nsInvalidPluginTag::nsInvalidPluginTag(const char* aFullPath, PRInt64 aLastModifiedTime)
|
|
|
|
: mFullPath(aFullPath),
|
|
|
|
mLastModifiedTime(aLastModifiedTime),
|
2010-12-20 23:38:04 +00:00
|
|
|
mSeen(false)
|
2010-12-09 22:28:15 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
nsInvalidPluginTag::~nsInvalidPluginTag()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// flat file reg funcs
|
|
|
|
static
|
|
|
|
PRBool ReadSectionHeader(nsPluginManifestLineReader& reader, const char *token)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
2010-07-13 20:48:00 +00:00
|
|
|
do {
|
|
|
|
if (*reader.LinePtr() == '[') {
|
|
|
|
char* p = reader.LinePtr() + (reader.LineLength() - 1);
|
|
|
|
if (*p != ']')
|
|
|
|
break;
|
|
|
|
*p = 0;
|
2002-03-27 03:41:43 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
char* values[1];
|
|
|
|
if (1 != reader.ParseLine(values, 1))
|
|
|
|
break;
|
|
|
|
// ignore the leading '['
|
|
|
|
if (PL_strcmp(values[0]+1, token)) {
|
|
|
|
break; // it's wrong token
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
2010-07-13 20:48:00 +00:00
|
|
|
return PR_TRUE;
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
2010-07-13 20:48:00 +00:00
|
|
|
} while (reader.NextLine());
|
|
|
|
return PR_FALSE;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// Little helper struct to asynchronously reframe any presentations (embedded)
|
|
|
|
// or reload any documents (full-page), that contained plugins
|
|
|
|
// which were shutdown as a result of a plugins.refresh(1)
|
|
|
|
class nsPluginDocReframeEvent: public nsRunnable {
|
|
|
|
public:
|
|
|
|
nsPluginDocReframeEvent(nsISupportsArray* aDocs) { mDocs = aDocs; }
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
NS_DECL_NSIRUNNABLE
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> mDocs;
|
|
|
|
};
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
NS_IMETHODIMP nsPluginDocReframeEvent::Run() {
|
|
|
|
NS_ENSURE_TRUE(mDocs, NS_ERROR_FAILURE);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
PRUint32 c;
|
|
|
|
mDocs->Count(&c);
|
2000-09-20 09:27:54 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// for each document (which previously had a running instance), tell
|
|
|
|
// the frame constructor to rebuild
|
|
|
|
for (PRUint32 i = 0; i < c; i++) {
|
|
|
|
nsCOMPtr<nsIDocument> doc (do_QueryElementAt(mDocs, i));
|
|
|
|
if (doc) {
|
|
|
|
nsIPresShell *shell = doc->GetShell();
|
2000-09-20 09:27:54 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// if this document has a presentation shell, then it has frames and can be reframed
|
|
|
|
if (shell) {
|
|
|
|
/* A reframe will cause a fresh object frame, instance owner, and instance
|
|
|
|
* to be created. Reframing of the entire document is necessary as we may have
|
|
|
|
* recently found new plugins and we want a shot at trying to use them instead
|
|
|
|
* of leaving alternate renderings.
|
|
|
|
* We do not want to completely reload all the documents that had running plugins
|
|
|
|
* because we could possibly trigger a script to run in the unload event handler
|
|
|
|
* which may want to access our defunct plugin and cause us to crash.
|
|
|
|
*/
|
2007-03-16 23:53:16 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
shell->ReconstructFrames(); // causes reframe of document
|
|
|
|
} else { // no pres shell --> full-page plugin
|
2007-03-16 23:53:16 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
NS_NOTREACHED("all plugins should have a pres shell!");
|
2007-03-16 23:53:16 +00:00
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
}
|
2005-07-22 18:29:34 +00:00
|
|
|
}
|
2002-09-12 19:12:56 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
return mDocs->Clear();
|
|
|
|
}
|
2002-09-12 19:12:56 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
static PRBool UnloadPluginsASAP()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
PRBool unloadPluginsASAP = PR_FALSE;
|
|
|
|
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
return unloadPluginsASAP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// helper struct for asynchronous handling of plugin unloading
|
|
|
|
class nsPluginUnloadEvent : public nsRunnable {
|
|
|
|
public:
|
|
|
|
nsPluginUnloadEvent(PRLibrary* aLibrary)
|
|
|
|
: mLibrary(aLibrary)
|
|
|
|
{}
|
|
|
|
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
|
|
|
|
PRLibrary* mLibrary;
|
|
|
|
};
|
2001-08-10 19:49:04 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
NS_IMETHODIMP nsPluginUnloadEvent::Run()
|
|
|
|
{
|
|
|
|
if (mLibrary) {
|
|
|
|
// put our unload call in a safety wrapper
|
2010-10-14 21:06:31 +00:00
|
|
|
NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(mLibrary), nsnull);
|
2010-07-13 20:48:00 +00:00
|
|
|
} else {
|
|
|
|
NS_WARNING("missing library from nsPluginUnloadEvent");
|
2002-09-12 19:12:56 +00:00
|
|
|
}
|
2002-08-29 22:00:20 +00:00
|
|
|
return NS_OK;
|
1999-03-11 22:48:58 +00:00
|
|
|
}
|
1998-12-11 04:50:57 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// unload plugin asynchronously if possible, otherwise just unload now
|
|
|
|
nsresult nsPluginHost::PostPluginUnloadEvent(PRLibrary* aLibrary)
|
1999-03-11 22:48:58 +00:00
|
|
|
{
|
2010-07-13 20:48:00 +00:00
|
|
|
nsCOMPtr<nsIRunnable> ev = new nsPluginUnloadEvent(aLibrary);
|
|
|
|
if (ev && NS_SUCCEEDED(NS_DispatchToCurrentThread(ev)))
|
2002-04-27 05:33:09 +00:00
|
|
|
return NS_OK;
|
1998-12-11 04:50:57 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
// failure case
|
2010-10-14 21:06:31 +00:00
|
|
|
NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(aLibrary), nsnull);
|
a=brendan,av
r=av
bug=50811
This bug fix was suggested by Stanley Ho <stanley.ho@eng.sun.com>.
Stanley proposed we overload the meaning of the nsIPluginStreamListener
argument to nsIPluginManager::{GetURL,PostURL}() so that it also may
implement an interface for reading headers. Thus, the browser could QI
the plugin's nsIPluginStreamListener instance to this headers reading
interface and send the plugin the headers from the response.
I have implemented Stanley's above proposal. I have defined a new
interface, nsIHTTPHeaderListener.idl with one method:
/**
* Called for each HTTP Response header.
* NOTE: You must copy the values of the params.
*/
void newResponseHeader(in string headerName, in string headerValue);
To affect this fix, I have added a new private method
nsPluginStreamListenerPeer::
ReadHeadersFromChannelAndPostToListener(nsIHTTPChannel *httpChannel,
nsIHTTPHeaderListener *listener)
Then, modified nsPluginStreamListenerPeer::OnDataAvailable() to call
this method BEFORE reading the content data. However, this fix makes
two important assumptions I would like to check out:
* Assumption
* By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
* called, all the headers have been read.
* Assumption:
* The return value from nsIHTTPHeader->{GetFieldName,GetValue}()
* must be freed.
The following files are included in this fix:
A modules/plugin/public/nsIHTTPHeaderListener.idl
A modules/plugin/public/makefile.win
A modules/plugin/public/Makefile.in
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
2000-09-13 07:09:38 +00:00
|
|
|
|
2010-07-13 20:48:00 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
a=brendan,av
r=av
bug=50811
This bug fix was suggested by Stanley Ho <stanley.ho@eng.sun.com>.
Stanley proposed we overload the meaning of the nsIPluginStreamListener
argument to nsIPluginManager::{GetURL,PostURL}() so that it also may
implement an interface for reading headers. Thus, the browser could QI
the plugin's nsIPluginStreamListener instance to this headers reading
interface and send the plugin the headers from the response.
I have implemented Stanley's above proposal. I have defined a new
interface, nsIHTTPHeaderListener.idl with one method:
/**
* Called for each HTTP Response header.
* NOTE: You must copy the values of the params.
*/
void newResponseHeader(in string headerName, in string headerValue);
To affect this fix, I have added a new private method
nsPluginStreamListenerPeer::
ReadHeadersFromChannelAndPostToListener(nsIHTTPChannel *httpChannel,
nsIHTTPHeaderListener *listener)
Then, modified nsPluginStreamListenerPeer::OnDataAvailable() to call
this method BEFORE reading the content data. However, this fix makes
two important assumptions I would like to check out:
* Assumption
* By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
* called, all the headers have been read.
* Assumption:
* The return value from nsIHTTPHeader->{GetFieldName,GetValue}()
* must be freed.
The following files are included in this fix:
A modules/plugin/public/nsIHTTPHeaderListener.idl
A modules/plugin/public/makefile.win
A modules/plugin/public/Makefile.in
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
2000-09-13 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::nsPluginHost()
|
2009-08-19 00:25:36 +00:00
|
|
|
// No need to initialize members to nsnull, PR_FALSE etc because this class
|
|
|
|
// has a zeroing operator new.
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2004-10-11 04:01:49 +00:00
|
|
|
// check to see if pref is set at startup to let plugins take over in
|
2002-03-26 06:30:33 +00:00
|
|
|
// full page mode for certain image mime types that we handle internally
|
2003-05-27 21:14:55 +00:00
|
|
|
mPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
|
|
if (mPrefService) {
|
2005-01-05 00:21:06 +00:00
|
|
|
PRBool tmp;
|
2005-11-06 18:34:03 +00:00
|
|
|
nsresult rv = mPrefService->GetBoolPref("plugin.override_internal_types",
|
|
|
|
&tmp);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mOverrideInternalTypes = tmp;
|
|
|
|
}
|
2005-01-05 00:21:06 +00:00
|
|
|
|
2009-10-05 09:00:57 +00:00
|
|
|
rv = mPrefService->GetBoolPref("plugin.disable", &tmp);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mPluginsDisabled = tmp;
|
|
|
|
}
|
2002-04-27 01:47:18 +00:00
|
|
|
}
|
2001-03-12 02:07:15 +00:00
|
|
|
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 16:59:13 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
|
|
|
mozilla::services::GetObserverService();
|
2009-01-30 21:40:14 +00:00
|
|
|
if (obsService) {
|
2002-05-31 08:05:14 +00:00
|
|
|
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
2009-01-30 21:40:14 +00:00
|
|
|
obsService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, PR_FALSE);
|
2001-03-31 02:26:51 +00:00
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
nsPluginLogging::gNPNLog = PR_NewLogModule(NPN_LOG_NAME);
|
|
|
|
nsPluginLogging::gNPPLog = PR_NewLogModule(NPP_LOG_NAME);
|
|
|
|
nsPluginLogging::gPluginLog = PR_NewLogModule(PLUGIN_LOG_NAME);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PR_LOG(nsPluginLogging::gNPNLog, PLUGIN_LOG_ALWAYS,("NPN Logging Active!\n"));
|
2009-07-02 05:48:08 +00:00
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHost::ctor)\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
PR_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::ctor\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
2009-12-15 20:44:52 +00:00
|
|
|
|
|
|
|
#ifdef MAC_CARBON_PLUGINS
|
|
|
|
mVisiblePluginTimer = do_CreateInstance("@mozilla.org/timer;1");
|
|
|
|
mHiddenPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
|
|
|
|
#endif
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::~nsPluginHost()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::dtor\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-03-31 02:26:51 +00:00
|
|
|
Destroy();
|
2005-11-06 18:34:03 +00:00
|
|
|
sInst = nsnull;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_IMPL_ISUPPORTS5(nsPluginHost,
|
2000-07-22 01:34:13 +00:00
|
|
|
nsIPluginHost,
|
2011-02-08 22:16:07 +00:00
|
|
|
nsIPluginHost_MOZILLA_2_0_BRANCH,
|
2001-04-03 22:49:38 +00:00
|
|
|
nsIObserver,
|
2009-12-16 20:54:16 +00:00
|
|
|
nsITimerCallback,
|
2005-11-06 18:34:03 +00:00
|
|
|
nsISupportsWeakReference)
|
2008-11-03 19:23:07 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost*
|
|
|
|
nsPluginHost::GetInst()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2005-11-06 18:34:03 +00:00
|
|
|
if (!sInst) {
|
2009-07-02 05:48:08 +00:00
|
|
|
sInst = new nsPluginHost();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!sInst)
|
2005-11-06 18:34:03 +00:00
|
|
|
return nsnull;
|
|
|
|
NS_ADDREF(sInst);
|
|
|
|
}
|
1998-07-28 02:07:25 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
NS_ADDREF(sInst);
|
|
|
|
return sInst;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PRBool nsPluginHost::IsRunningPlugin(nsPluginTag * plugin)
|
2001-02-02 23:48:17 +00:00
|
|
|
{
|
2011-03-29 20:43:18 +00:00
|
|
|
if (!plugin || !plugin->mEntryPoint) {
|
2001-02-02 23:48:17 +00:00
|
|
|
return PR_FALSE;
|
2011-03-29 20:43:18 +00:00
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2011-03-29 20:43:18 +00:00
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i].get();
|
|
|
|
if (instance &&
|
|
|
|
instance->GetPlugin() == plugin->mEntryPoint &&
|
|
|
|
instance->IsRunning()) {
|
2001-02-02 23:48:17 +00:00
|
|
|
return PR_TRUE;
|
2011-03-29 20:43:18 +00:00
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::ReloadPlugins(PRBool reloadPages)
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::ReloadPlugins Begin reloadPages=%d, active_instance_count=%d\n",
|
2010-07-20 02:11:26 +00:00
|
|
|
reloadPages, mInstances.Length()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2002-05-16 20:47:29 +00:00
|
|
|
// this will create the initial plugin list out of cache
|
|
|
|
// if it was not created yet
|
2002-07-01 20:36:57 +00:00
|
|
|
if (!mPluginsLoaded)
|
|
|
|
return LoadPlugins();
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
// we are re-scanning plugins. New plugins may have been added, also some
|
|
|
|
// plugins may have been removed, so we should probably shut everything down
|
|
|
|
// but don't touch running (active and not stopped) plugins
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-05-16 20:47:29 +00:00
|
|
|
// check if plugins changed, no need to do anything else
|
|
|
|
// if no changes to plugins have been made
|
|
|
|
// PR_FALSE instructs not to touch the plugin list, just to
|
|
|
|
// look for possible changes
|
|
|
|
PRBool pluginschanged = PR_TRUE;
|
|
|
|
FindPlugins(PR_FALSE, &pluginschanged);
|
|
|
|
|
|
|
|
// if no changed detected, return an appropriate error code
|
|
|
|
if (!pluginschanged)
|
|
|
|
return NS_ERROR_PLUGINS_PLUGINSNOTCHANGED;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> instsToReload;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (reloadPages) {
|
2002-07-03 21:03:51 +00:00
|
|
|
NS_NewISupportsArray(getter_AddRefs(instsToReload));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
// Then stop any running plugin instances but hold on to the documents in the array
|
|
|
|
// We are going to need to restart the instances in these documents later
|
2010-07-20 02:11:26 +00:00
|
|
|
DestroyRunningInstances(instsToReload, nsnull);
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// shutdown plugins and kill the list if there are no running plugins
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> prev;
|
|
|
|
nsRefPtr<nsPluginTag> next;
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsRefPtr<nsPluginTag> p = mPlugins; p != nsnull;) {
|
2001-02-02 23:48:17 +00:00
|
|
|
next = p->mNext;
|
|
|
|
|
2009-06-11 17:40:38 +00:00
|
|
|
// only remove our plugin from the list if it's not running.
|
|
|
|
if (!IsRunningPlugin(p)) {
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p == mPlugins)
|
2001-02-02 23:48:17 +00:00
|
|
|
mPlugins = next;
|
|
|
|
else
|
|
|
|
prev->mNext = next;
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
p->mNext = nsnull;
|
2009-12-03 05:14:13 +00:00
|
|
|
|
|
|
|
// attempt to unload plugins whenever they are removed from the list
|
|
|
|
p->TryUnloadPlugin();
|
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
p = next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
prev = p;
|
|
|
|
p = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set flags
|
1998-09-30 18:57:27 +00:00
|
|
|
mPluginsLoaded = PR_FALSE;
|
2000-11-30 22:01:45 +00:00
|
|
|
|
|
|
|
// load them again
|
2002-01-29 21:22:13 +00:00
|
|
|
rv = LoadPlugins();
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
// If we have shut down any plugin instances, we've now got to restart them.
|
|
|
|
// Post an event to do the rest as we are going to be destroying the frame tree and we also want
|
|
|
|
// any posted unload events to finish
|
|
|
|
PRUint32 c;
|
2004-10-11 04:01:49 +00:00
|
|
|
if (reloadPages &&
|
|
|
|
instsToReload &&
|
|
|
|
NS_SUCCEEDED(instsToReload->Count(&c)) &&
|
2002-07-03 21:03:51 +00:00
|
|
|
c > 0) {
|
2006-05-10 17:30:15 +00:00
|
|
|
nsCOMPtr<nsIRunnable> ev = new nsPluginDocReframeEvent(instsToReload);
|
|
|
|
if (ev)
|
|
|
|
NS_DispatchToCurrentThread(ev);
|
2002-07-03 21:03:51 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::ReloadPlugins End active_instance_count=%d\n",
|
2010-07-20 02:11:26 +00:00
|
|
|
mInstances.Length()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
return rv;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2000-10-31 20:25:19 +00:00
|
|
|
#define NS_RETURN_UASTRING_SIZE 128
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::UserAgent(const char **retstring)
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2000-10-31 20:25:19 +00:00
|
|
|
static char resultString[NS_RETURN_UASTRING_SIZE];
|
1998-11-22 00:22:35 +00:00
|
|
|
nsresult res;
|
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &res);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(res))
|
2000-10-31 20:25:19 +00:00
|
|
|
return res;
|
1998-10-28 21:16:00 +00:00
|
|
|
|
2002-03-20 22:50:33 +00:00
|
|
|
nsCAutoString uaString;
|
|
|
|
res = http->GetUserAgent(uaString);
|
1999-06-18 17:34:08 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
|
|
|
if (NS_RETURN_UASTRING_SIZE > uaString.Length()) {
|
2002-03-20 22:50:33 +00:00
|
|
|
PL_strcpy(resultString, uaString.get());
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
2008-08-04 21:24:50 +00:00
|
|
|
// Copy as much of UA string as we can (terminate at right-most space).
|
|
|
|
PL_strncpy(resultString, uaString.get(), NS_RETURN_UASTRING_SIZE);
|
2008-11-03 19:23:07 +00:00
|
|
|
for (int i = NS_RETURN_UASTRING_SIZE - 1; i >= 0; i--) {
|
|
|
|
if (i == 0) {
|
2008-08-04 21:24:50 +00:00
|
|
|
resultString[NS_RETURN_UASTRING_SIZE - 1] = '\0';
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
|
|
|
else if (resultString[i] == ' ') {
|
2008-08-04 21:24:50 +00:00
|
|
|
resultString[i] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2000-10-31 20:25:19 +00:00
|
|
|
}
|
2008-08-04 21:24:50 +00:00
|
|
|
*retstring = resultString;
|
2004-10-11 04:01:49 +00:00
|
|
|
}
|
2008-11-03 19:23:07 +00:00
|
|
|
else {
|
2000-10-31 20:25:19 +00:00
|
|
|
*retstring = nsnull;
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1998-11-22 00:22:35 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHost::UserAgent return=%s\n", *retstring));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
1998-10-28 21:16:00 +00:00
|
|
|
return res;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::GetPrompt(nsIPluginInstanceOwner *aOwner, nsIPrompt **aPrompt)
|
2002-06-01 00:56:38 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIPrompt> prompt;
|
2002-08-06 05:37:58 +00:00
|
|
|
nsCOMPtr<nsIWindowWatcher> wwatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
if (wwatch) {
|
|
|
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
|
|
|
if (aOwner) {
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aOwner->GetDocument(getter_AddRefs(document));
|
|
|
|
if (document) {
|
2005-09-17 03:40:08 +00:00
|
|
|
domWindow = document->GetWindow();
|
2002-06-01 00:56:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!domWindow) {
|
|
|
|
wwatch->GetWindowByName(NS_LITERAL_STRING("_content").get(), nsnull, getter_AddRefs(domWindow));
|
|
|
|
}
|
|
|
|
rv = wwatch->GetNewPrompter(domWindow, getter_AddRefs(prompt));
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_ADDREF(*aPrompt = prompt);
|
|
|
|
return rv;
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::GetURL(nsISupports* pluginInst,
|
|
|
|
const char* url,
|
|
|
|
const char* target,
|
|
|
|
nsIPluginStreamListener* streamListener,
|
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
|
|
|
PRBool forceJSEnabled)
|
r=vidur, av
a=brendan
bug=49525
This simple fix just adds parameters to an existing method in an XPCOM
safe way, by defining a new method at the end of the interface
definition with the additional parameters.
Original method:
NS_IMETHOD
GetURL(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE) = 0;
New method:
NS_IMETHOD
GetURLWithHeaders(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE,
PRUint32 getHeadersLength = 0,
const char* getHeaders = NULL) = 0;
I have modified nsPluginHostImpl.h to include this new method, and
modified nsPluginHostImpl.cpp so that its GetURL calls GetURLWithHeaders
with null values for the last two params.
M modules/plugin/public/nsIPluginManager.h
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-14 22:57:56 +00:00
|
|
|
{
|
2010-07-16 19:55:54 +00:00
|
|
|
return GetURLWithHeaders(static_cast<nsNPAPIPluginInstance*>(pluginInst),
|
|
|
|
url, target, streamListener, altHost, referrer,
|
|
|
|
forceJSEnabled, nsnull, nsnull);
|
r=vidur, av
a=brendan
bug=49525
This simple fix just adds parameters to an existing method in an XPCOM
safe way, by defining a new method at the end of the interface
definition with the additional parameters.
Original method:
NS_IMETHOD
GetURL(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE) = 0;
New method:
NS_IMETHOD
GetURLWithHeaders(nsISupports* pluginInst,
const char* url,
const char* target = NULL,
nsIPluginStreamListener* streamListener = NULL,
const char* altHost = NULL,
const char* referrer = NULL,
PRBool forceJSEnabled = PR_FALSE,
PRUint32 getHeadersLength = 0,
const char* getHeaders = NULL) = 0;
I have modified nsPluginHostImpl.h to include this new method, and
modified nsPluginHostImpl.cpp so that its GetURL calls GetURLWithHeaders
with null values for the last two params.
M modules/plugin/public/nsIPluginManager.h
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-14 22:57:56 +00:00
|
|
|
}
|
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsresult nsPluginHost::GetURLWithHeaders(nsNPAPIPluginInstance* pluginInst,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char* url,
|
|
|
|
const char* target,
|
|
|
|
nsIPluginStreamListener* streamListener,
|
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
|
|
|
PRBool forceJSEnabled,
|
|
|
|
PRUint32 getHeadersLength,
|
|
|
|
const char* getHeaders)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
nsAutoString string;
|
|
|
|
string.AssignWithConversion(url);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// we can only send a stream back to the plugin (as specified by a
|
2003-04-03 19:11:41 +00:00
|
|
|
// null target) if we also have a nsIPluginStreamListener to talk to
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!target && !streamListener)
|
2009-10-29 00:29:44 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsresult rv = DoURLLoadSecurityCheck(pluginInst, url);
|
2009-10-29 00:29:44 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (target) {
|
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2010-07-16 19:55:54 +00:00
|
|
|
rv = pluginInst->GetOwner(getter_AddRefs(owner));
|
2009-10-29 00:29:44 +00:00
|
|
|
if (owner) {
|
|
|
|
if ((0 == PL_strcmp(target, "newwindow")) ||
|
|
|
|
(0 == PL_strcmp(target, "_new")))
|
|
|
|
target = "_blank";
|
|
|
|
else if (0 == PL_strcmp(target, "_current"))
|
|
|
|
target = "_self";
|
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
rv = owner->GetURL(url, target, nsnull, nsnull, 0);
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (streamListener)
|
2010-07-16 19:55:54 +00:00
|
|
|
rv = NewPluginURLStream(string, pluginInst, streamListener, nsnull,
|
2009-12-27 20:26:00 +00:00
|
|
|
getHeaders, getHeadersLength);
|
2009-10-29 00:29:44 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::PostURL(nsISupports* pluginInst,
|
|
|
|
const char* url,
|
|
|
|
PRUint32 postDataLen,
|
|
|
|
const char* postData,
|
|
|
|
PRBool isFile,
|
|
|
|
const char* target,
|
|
|
|
nsIPluginStreamListener* streamListener,
|
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
|
|
|
PRBool forceJSEnabled,
|
|
|
|
PRUint32 postHeadersLength,
|
|
|
|
const char* postHeaders)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2009-10-29 00:29:44 +00:00
|
|
|
nsAutoString string;
|
2008-11-03 19:23:07 +00:00
|
|
|
nsresult rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
string.AssignWithConversion(url);
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// we can only send a stream back to the plugin (as specified
|
|
|
|
// by a null target) if we also have a nsIPluginStreamListener
|
2000-04-22 20:50:22 +00:00
|
|
|
// to talk to also
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!target && !streamListener)
|
2009-10-29 00:29:44 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance* instance = static_cast<nsNPAPIPluginInstance*>(pluginInst);
|
2003-04-03 19:11:41 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
rv = DoURLLoadSecurityCheck(instance, url);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2002-08-22 18:12:59 +00:00
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
nsCOMPtr<nsIInputStream> postStream;
|
2009-10-29 00:29:44 +00:00
|
|
|
if (isFile) {
|
2009-12-27 20:26:00 +00:00
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
rv = CreateTempFileToPost(postData, getter_AddRefs(file));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInputStream> fileStream;
|
|
|
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
|
|
|
|
file,
|
|
|
|
PR_RDONLY,
|
|
|
|
0600,
|
|
|
|
nsIFileInputStream::DELETE_ON_CLOSE |
|
|
|
|
nsIFileInputStream::CLOSE_ON_EOF);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
rv = NS_NewBufferedInputStream(getter_AddRefs(postStream), fileStream, 8192);
|
|
|
|
if (NS_FAILED(rv))
|
2009-10-29 00:29:44 +00:00
|
|
|
return rv;
|
|
|
|
} else {
|
2009-12-27 20:26:00 +00:00
|
|
|
char *dataToPost;
|
2009-10-29 00:29:44 +00:00
|
|
|
PRUint32 newDataToPostLen;
|
|
|
|
ParsePostBufferToFixHeaders(postData, postDataLen, &dataToPost, &newDataToPostLen);
|
|
|
|
if (!dataToPost)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
nsCOMPtr<nsIStringInputStream> sis = do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
|
|
|
|
if (!sis) {
|
|
|
|
NS_Free(dataToPost);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// data allocated by ParsePostBufferToFixHeaders() is managed and
|
|
|
|
// freed by the string stream.
|
2009-10-29 00:29:44 +00:00
|
|
|
postDataLen = newDataToPostLen;
|
2009-12-27 20:26:00 +00:00
|
|
|
sis->AdoptData(dataToPost, postDataLen);
|
|
|
|
postStream = sis;
|
2009-10-29 00:29:44 +00:00
|
|
|
}
|
2002-01-30 02:40:46 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (target) {
|
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
|
|
|
rv = instance->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (owner) {
|
2010-03-11 06:49:29 +00:00
|
|
|
if ((0 == PL_strcmp(target, "newwindow")) ||
|
|
|
|
(0 == PL_strcmp(target, "_new"))) {
|
|
|
|
target = "_blank";
|
|
|
|
} else if (0 == PL_strcmp(target, "_current")) {
|
2009-10-29 00:29:44 +00:00
|
|
|
target = "_self";
|
2002-08-22 18:12:59 +00:00
|
|
|
}
|
2009-12-27 20:26:00 +00:00
|
|
|
rv = owner->GetURL(url, target, postStream,
|
|
|
|
(void*)postHeaders, postHeadersLength);
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
// if we don't have a target, just create a stream. This does
|
|
|
|
// NS_OpenURI()!
|
|
|
|
if (streamListener)
|
|
|
|
rv = NewPluginURLStream(string, instance, streamListener,
|
2009-12-27 20:26:00 +00:00
|
|
|
postStream, postHeaders, postHeadersLength);
|
2009-10-29 00:29:44 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
/* This method queries the prefs for proxy information.
|
1999-10-09 01:18:02 +00:00
|
|
|
* It has been tested and is known to work in the following three cases
|
|
|
|
* when no proxy host or port is specified
|
|
|
|
* when only the proxy host is specified
|
|
|
|
* when only the proxy port is specified
|
2004-10-11 04:01:49 +00:00
|
|
|
* This method conforms to the return code specified in
|
1999-10-09 01:18:02 +00:00
|
|
|
* http://developer.netscape.com/docs/manuals/proxy/adminnt/autoconf.htm#1020923
|
|
|
|
* with the exception that multiple values are not implemented.
|
|
|
|
*/
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::FindProxyForURL(const char* url, char* *result)
|
1998-09-01 00:17:25 +00:00
|
|
|
{
|
2000-10-05 07:58:51 +00:00
|
|
|
if (!url || !result) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
nsresult res;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uriIn;
|
2001-05-02 23:38:41 +00:00
|
|
|
nsCOMPtr<nsIProtocolProxyService> proxyService;
|
|
|
|
nsCOMPtr<nsIIOService> ioService;
|
1999-10-09 01:18:02 +00:00
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
proxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res) || !proxyService)
|
1999-10-09 01:18:02 +00:00
|
|
|
return res;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res) || !ioService)
|
2001-05-02 23:38:41 +00:00
|
|
|
return res;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-10-09 01:18:02 +00:00
|
|
|
// make an nsURI from the argument url
|
2002-03-06 07:48:55 +00:00
|
|
|
res = ioService->NewURI(nsDependentCString(url), nsnull, nsnull, getter_AddRefs(uriIn));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res))
|
2000-10-05 07:58:51 +00:00
|
|
|
return res;
|
1999-10-09 01:18:02 +00:00
|
|
|
|
2001-09-13 02:21:05 +00:00
|
|
|
nsCOMPtr<nsIProxyInfo> pi;
|
|
|
|
|
2005-03-25 03:41:33 +00:00
|
|
|
res = proxyService->Resolve(uriIn, 0, getter_AddRefs(pi));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res))
|
2001-05-02 23:38:41 +00:00
|
|
|
return res;
|
2000-10-05 07:58:51 +00:00
|
|
|
|
2005-03-25 03:41:33 +00:00
|
|
|
nsCAutoString host, type;
|
|
|
|
PRInt32 port = -1;
|
|
|
|
|
|
|
|
// These won't fail, and even if they do... we'll be ok.
|
2005-03-25 21:33:12 +00:00
|
|
|
if (pi) {
|
|
|
|
pi->GetType(type);
|
|
|
|
pi->GetHost(host);
|
|
|
|
pi->GetPort(&port);
|
|
|
|
}
|
2005-03-25 03:41:33 +00:00
|
|
|
|
|
|
|
if (!pi || host.IsEmpty() || port <= 0 || host.EqualsLiteral("direct")) {
|
2001-09-13 02:21:05 +00:00
|
|
|
*result = PL_strdup("DIRECT");
|
2005-03-25 03:41:33 +00:00
|
|
|
} else if (type.EqualsLiteral("http")) {
|
|
|
|
*result = PR_smprintf("PROXY %s:%d", host.get(), port);
|
|
|
|
} else if (type.EqualsLiteral("socks4")) {
|
|
|
|
*result = PR_smprintf("SOCKS %s:%d", host.get(), port);
|
|
|
|
} else if (type.EqualsLiteral("socks")) {
|
2001-09-13 02:21:05 +00:00
|
|
|
// XXX - this is socks5, but there is no API for us to tell the
|
|
|
|
// plugin that fact. SOCKS for now, in case the proxy server
|
|
|
|
// speaks SOCKS4 as well. See bug 78176
|
|
|
|
// For a long time this was returning an http proxy type, so
|
|
|
|
// very little is probably broken by this
|
2005-03-25 03:41:33 +00:00
|
|
|
*result = PR_smprintf("SOCKS %s:%d", host.get(), port);
|
2001-09-13 02:21:05 +00:00
|
|
|
} else {
|
|
|
|
NS_ASSERTION(PR_FALSE, "Unknown proxy type!");
|
2001-05-02 23:38:41 +00:00
|
|
|
*result = PL_strdup("DIRECT");
|
2001-05-11 21:05:08 +00:00
|
|
|
}
|
2001-05-02 23:38:41 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (nsnull == *result)
|
2001-05-02 23:38:41 +00:00
|
|
|
res = NS_ERROR_OUT_OF_MEMORY;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-10-09 01:18:02 +00:00
|
|
|
return res;
|
1998-09-27 22:21:39 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::Init()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
1999-03-02 22:33:32 +00:00
|
|
|
return NS_OK;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::Destroy()
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2009-07-02 05:48:08 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHost::Destroy Called\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
if (mIsDestroyed)
|
|
|
|
return NS_OK;
|
1999-05-17 21:26:48 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
mIsDestroyed = PR_TRUE;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// we should call nsIPluginInstance::Stop and nsIPluginInstance::SetWindow
|
2001-04-16 21:26:28 +00:00
|
|
|
// for those plugins who want it
|
2010-07-20 02:11:26 +00:00
|
|
|
DestroyRunningInstances(nsnull, nsnull);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2009-12-03 05:14:13 +00:00
|
|
|
nsPluginTag *pluginTag;
|
|
|
|
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
|
|
|
pluginTag->TryUnloadPlugin();
|
2001-03-31 02:26:51 +00:00
|
|
|
}
|
|
|
|
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mPlugins, mNext);
|
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-09 22:28:15 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// Lets remove any of the temporary files that we created.
|
2005-02-11 23:37:51 +00:00
|
|
|
if (sPluginTempDir) {
|
|
|
|
sPluginTempDir->Remove(PR_TRUE);
|
|
|
|
NS_RELEASE(sPluginTempDir);
|
|
|
|
}
|
2001-06-19 01:38:20 +00:00
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPrivateDirServiceProvider) {
|
2005-02-11 23:37:51 +00:00
|
|
|
nsCOMPtr<nsIDirectoryService> dirService =
|
|
|
|
do_GetService(kDirectoryServiceContractID);
|
|
|
|
if (dirService)
|
2001-11-17 15:26:02 +00:00
|
|
|
dirService->UnregisterProvider(mPrivateDirServiceProvider);
|
|
|
|
mPrivateDirServiceProvider = nsnull;
|
|
|
|
}
|
2007-07-20 20:34:51 +00:00
|
|
|
#endif /* XP_WIN */
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
mPrefService = nsnull; // release prefs service to avoid leaks!
|
|
|
|
|
2002-12-26 22:54:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-11-17 15:26:02 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
void nsPluginHost::OnPluginInstanceDestroyed(nsPluginTag* aPluginTag)
|
|
|
|
{
|
|
|
|
PRBool hasInstance = PR_FALSE;
|
2010-07-20 02:11:26 +00:00
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
if (TagForPlugin(mInstances[i]->GetPlugin()) == aPluginTag) {
|
2010-01-27 01:30:58 +00:00
|
|
|
hasInstance = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
if (!hasInstance && UnloadPluginsASAP()) {
|
|
|
|
aPluginTag->TryUnloadPlugin();
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetPluginTempDir(nsIFile **aDir)
|
2005-02-11 23:37:51 +00:00
|
|
|
{
|
|
|
|
if (!sPluginTempDir) {
|
|
|
|
nsCOMPtr<nsIFile> tmpDir;
|
|
|
|
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR,
|
|
|
|
getter_AddRefs(tmpDir));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = tmpDir->AppendNative(kPluginTmpDirName);
|
|
|
|
|
|
|
|
// make it unique, and mode == 0700, not world-readable
|
|
|
|
rv = tmpDir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0700);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
tmpDir.swap(sPluginTempDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
return sPluginTempDir->Clone(aDir);
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::InstantiatePluginForChannel(nsIChannel* aChannel,
|
2010-10-23 01:16:29 +00:00
|
|
|
nsIPluginInstanceOwner* aOwner,
|
|
|
|
nsIStreamListener** aListener)
|
2005-09-21 19:14:30 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aChannel && aOwner,
|
|
|
|
"Invalid arguments to InstantiatePluginForChannel");
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
if (PR_LOG_TEST(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL)) {
|
|
|
|
nsCAutoString urlSpec;
|
|
|
|
uri->GetAsciiSpec(urlSpec);
|
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiatePluginForChannel Begin owner=%p, url=%s\n",
|
2005-09-21 19:14:30 +00:00
|
|
|
aOwner, urlSpec.get()));
|
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-10-23 01:16:29 +00:00
|
|
|
// Note that we're not setting up a plugin instance here; the stream
|
|
|
|
// listener's OnStartRequest will handle doing that, looking for
|
|
|
|
// stopped plugins, etc, etc.
|
2005-09-21 19:14:30 +00:00
|
|
|
|
|
|
|
return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener);
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2009-12-15 20:44:52 +00:00
|
|
|
// Called by nsPluginInstanceOwner
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType,
|
2010-07-16 19:55:54 +00:00
|
|
|
nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner)
|
2010-10-23 01:16:29 +00:00
|
|
|
{
|
|
|
|
return DoInstantiateEmbeddedPlugin(aMimeType, aURL, aOwner, PR_TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsPluginHost::DoInstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner* aOwner,
|
|
|
|
PRBool aAllowOpeningStreams)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2006-06-03 23:23:45 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aOwner);
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString urlSpec;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aURL)
|
|
|
|
aURL->GetAsciiSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiateEmbeddedPlugin Begin mime=%s, owner=%p, url=%s\n",
|
2002-03-06 07:48:55 +00:00
|
|
|
aMimeType, aOwner, urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsresult rv;
|
2009-07-02 00:54:18 +00:00
|
|
|
nsCOMPtr<nsIPluginTagInfo> pti;
|
2000-06-20 21:04:52 +00:00
|
|
|
nsPluginTagType tagType;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-07-02 00:54:18 +00:00
|
|
|
rv = aOwner->QueryInterface(kIPluginTagInfoIID, getter_AddRefs(pti));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (rv != NS_OK)
|
2000-06-20 21:04:52 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-07-02 00:54:18 +00:00
|
|
|
rv = pti->GetTagType(&tagType);
|
2000-06-20 21:04:52 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if ((rv != NS_OK) || !((tagType == nsPluginTagType_Embed)
|
2000-06-22 23:17:50 +00:00
|
|
|
|| (tagType == nsPluginTagType_Applet)
|
2008-11-03 19:23:07 +00:00
|
|
|
|| (tagType == nsPluginTagType_Object))) {
|
2000-06-20 21:04:52 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2005-09-07 02:39:51 +00:00
|
|
|
// Security checks
|
|
|
|
// Can't do security checks without a URI - hopefully the plugin will take
|
|
|
|
// care of that
|
2010-10-23 01:16:29 +00:00
|
|
|
// No need to do the security check if aAllowOpeningStreams is
|
|
|
|
// false; we don't plan to do any network access in that case.
|
|
|
|
// Furthermore, doing it could reenter plugin instantiation, which
|
|
|
|
// would be Bad.
|
|
|
|
if (aURL && aAllowOpeningStreams) {
|
2005-09-07 02:39:51 +00:00
|
|
|
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
|
|
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv; // Better fail if we can't do security checks
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
2006-06-03 23:23:45 +00:00
|
|
|
aOwner->GetDocument(getter_AddRefs(doc));
|
2005-09-07 02:39:51 +00:00
|
|
|
if (!doc)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2006-04-27 18:21:11 +00:00
|
|
|
rv = secMan->CheckLoadURIWithPrincipal(doc->NodePrincipal(), aURL, 0);
|
2005-09-07 02:39:51 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> elem;
|
2009-07-02 00:54:18 +00:00
|
|
|
pti->GetDOMElement(getter_AddRefs(elem));
|
2005-09-07 02:39:51 +00:00
|
|
|
|
|
|
|
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT; // default permit
|
|
|
|
nsresult rv =
|
|
|
|
NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OBJECT,
|
|
|
|
aURL,
|
2007-08-08 01:16:09 +00:00
|
|
|
doc->NodePrincipal(),
|
2005-09-07 02:39:51 +00:00
|
|
|
elem,
|
|
|
|
nsDependentCString(aMimeType ? aMimeType : ""),
|
|
|
|
nsnull, //extra
|
|
|
|
&shouldLoad);
|
|
|
|
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad))
|
2005-09-07 16:32:52 +00:00
|
|
|
return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
|
2005-09-07 02:39:51 +00:00
|
|
|
}
|
|
|
|
|
2010-08-04 19:16:12 +00:00
|
|
|
PRBool isJava = PR_FALSE;
|
|
|
|
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_TRUE);
|
2005-11-06 18:34:03 +00:00
|
|
|
if (pluginTag) {
|
2010-08-04 19:16:12 +00:00
|
|
|
isJava = pluginTag->mIsJavaPlugin;
|
2000-06-30 17:31:02 +00:00
|
|
|
}
|
2009-08-24 22:56:43 +00:00
|
|
|
|
2002-02-28 04:47:08 +00:00
|
|
|
// Determine if the scheme of this URL is one we can handle internaly because we should
|
|
|
|
// only open the initial stream if it's one that we can handle internally. Otherwise
|
2005-06-08 23:42:15 +00:00
|
|
|
// |NS_OpenURI| in |InstantiateEmbeddedPlugin| may open up a OS protocal registered helper app
|
2010-10-23 01:16:29 +00:00
|
|
|
// Also set bCanHandleInternally to true if aAllowOpeningStreams is
|
|
|
|
// false; we don't want to do any network traffic in that case.
|
2002-02-28 04:47:08 +00:00
|
|
|
PRBool bCanHandleInternally = PR_FALSE;
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString scheme;
|
2010-10-23 01:16:29 +00:00
|
|
|
if (aURL && aAllowOpeningStreams && NS_SUCCEEDED(aURL->GetScheme(scheme))) {
|
2002-02-28 04:47:08 +00:00
|
|
|
nsCAutoString contractID(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX);
|
|
|
|
contractID += scheme;
|
|
|
|
ToLowerCase(contractID);
|
|
|
|
nsCOMPtr<nsIProtocolHandler> handler = do_GetService(contractID.get());
|
|
|
|
if (handler)
|
|
|
|
bCanHandleInternally = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (FindStoppedPluginForURL(aURL, aOwner) == NS_OK) {
|
2004-10-11 04:01:49 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiateEmbeddedPlugin FoundStopped mime=%s\n", aMimeType));
|
1999-07-07 00:28:34 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instanceCOMPtr;
|
|
|
|
aOwner->GetInstance(getter_AddRefs(instanceCOMPtr));
|
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(instanceCOMPtr.get());
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!isJava && bCanHandleInternally)
|
2005-06-08 23:42:15 +00:00
|
|
|
rv = NewEmbeddedPluginStream(aURL, aOwner, instance);
|
2000-05-16 00:22:30 +00:00
|
|
|
|
1999-05-07 22:06:47 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we don't have a MIME type at this point, we still have one more chance by
|
|
|
|
// opening the stream and seeing if the server hands one back
|
2001-01-10 23:49:19 +00:00
|
|
|
if (!aMimeType)
|
2005-06-08 23:42:15 +00:00
|
|
|
return bCanHandleInternally ? NewEmbeddedPluginStream(aURL, aOwner, nsnull) : NS_ERROR_FAILURE;
|
2001-01-10 23:49:19 +00:00
|
|
|
|
1999-03-11 22:48:58 +00:00
|
|
|
rv = SetUpPluginInstance(aMimeType, aURL, aOwner);
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2010-05-14 17:08:12 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_ERROR_FAILURE;
|
2010-05-13 19:56:19 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instanceCOMPtr;
|
|
|
|
rv = aOwner->GetInstance(getter_AddRefs(instanceCOMPtr));
|
1999-03-23 03:18:12 +00:00
|
|
|
// if we have a failure error, it means we found a plugin for the mimetype,
|
|
|
|
// but we had a problem with the entry point
|
2008-11-03 19:23:07 +00:00
|
|
|
if (rv == NS_ERROR_FAILURE)
|
2001-08-16 02:59:03 +00:00
|
|
|
return rv;
|
1999-03-23 03:18:12 +00:00
|
|
|
|
2001-08-10 01:53:38 +00:00
|
|
|
// if we are here then we have loaded a plugin for this mimetype
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(instanceCOMPtr.get());
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (instance) {
|
2001-08-10 01:53:38 +00:00
|
|
|
instance->Start();
|
|
|
|
aOwner->CreateWidget();
|
2000-05-16 00:22:30 +00:00
|
|
|
|
2001-08-10 01:53:38 +00:00
|
|
|
// If we've got a native window, the let the plugin know about it.
|
2010-12-07 21:18:50 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(aOwner);
|
|
|
|
if (owner)
|
|
|
|
owner->SetWindow();
|
2001-08-10 01:53:38 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// create an initial stream with data
|
2001-08-10 01:53:38 +00:00
|
|
|
// don't make the stream if it's a java applet or we don't have SRC or DATA attribute
|
|
|
|
PRBool havedata = PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPluginTagInfo> pti(do_QueryInterface(aOwner, &rv));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (pti) {
|
2001-08-10 01:53:38 +00:00
|
|
|
const char *value;
|
2002-06-27 01:51:34 +00:00
|
|
|
havedata = NS_SUCCEEDED(pti->GetAttribute("SRC", &value));
|
|
|
|
// no need to check for "data" as it would have been converted to "src"
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (havedata && !isJava && bCanHandleInternally)
|
2005-06-08 23:42:15 +00:00
|
|
|
rv = NewEmbeddedPluginStream(aURL, aOwner, instance);
|
2001-08-10 01:53:38 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString urlSpec2;
|
2009-07-02 05:48:08 +00:00
|
|
|
if (aURL != nsnull) aURL->GetAsciiSpec(urlSpec2);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiateEmbeddedPlugin Finished mime=%s, rv=%d, owner=%p, url=%s\n",
|
2002-03-06 07:48:55 +00:00
|
|
|
aMimeType, rv, aOwner, urlSpec2.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
1999-07-07 00:28:34 +00:00
|
|
|
#endif
|
2001-08-16 02:59:03 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by full-page case
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::InstantiateFullPagePlugin(const char *aMimeType,
|
2010-07-16 19:55:54 +00:00
|
|
|
nsIURI* aURI,
|
2010-07-17 23:47:29 +00:00
|
|
|
nsIPluginInstanceOwner *aOwner,
|
|
|
|
nsIStreamListener **aStreamListener)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2005-04-29 12:11:45 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
nsCAutoString urlSpec;
|
|
|
|
aURI->GetSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiateFullPagePlugin Begin mime=%s, owner=%p, url=%s\n",
|
2005-04-29 12:11:45 +00:00
|
|
|
aMimeType, aOwner, urlSpec.get()));
|
|
|
|
#endif
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (FindStoppedPluginForURL(aURI, aOwner) == NS_OK) {
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiateFullPagePlugin FoundStopped mime=%s\n",aMimeType));
|
1999-07-07 00:28:34 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_TRUE);
|
2010-07-16 19:55:54 +00:00
|
|
|
if (!pluginTag || !pluginTag->mIsJavaPlugin) {
|
|
|
|
nsCOMPtr<nsIPluginInstance> instanceCOMPtr;
|
|
|
|
aOwner->GetInstance(getter_AddRefs(instanceCOMPtr));
|
2010-07-17 23:47:29 +00:00
|
|
|
NewFullPagePluginStream(aURI, static_cast<nsNPAPIPluginInstance*>(instanceCOMPtr.get()), aStreamListener);
|
2010-07-16 19:55:54 +00:00
|
|
|
}
|
1999-05-07 22:06:47 +00:00
|
|
|
return NS_OK;
|
2004-10-11 04:01:49 +00:00
|
|
|
}
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2005-04-29 12:11:45 +00:00
|
|
|
nsresult rv = SetUpPluginInstance(aMimeType, aURI, aOwner);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_OK == rv) {
|
2010-07-16 19:55:54 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instanceCOMPtr;
|
|
|
|
aOwner->GetInstance(getter_AddRefs(instanceCOMPtr));
|
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(instanceCOMPtr.get());
|
2010-07-16 17:25:01 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
NPWindow* win = nsnull;
|
2002-09-26 02:53:27 +00:00
|
|
|
aOwner->GetWindow(win);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (win && instance) {
|
1999-01-25 08:05:00 +00:00
|
|
|
instance->Start();
|
|
|
|
aOwner->CreateWidget();
|
2000-07-20 01:40:54 +00:00
|
|
|
|
|
|
|
// If we've got a native window, the let the plugin know about it.
|
2010-12-07 21:18:50 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(aOwner);
|
|
|
|
if (owner)
|
|
|
|
owner->SetWindow();
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2010-07-17 23:47:29 +00:00
|
|
|
rv = NewFullPagePluginStream(aURI, instance, aStreamListener);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-03-28 01:00:47 +00:00
|
|
|
// If we've got a native window, the let the plugin know about it.
|
2010-12-07 21:18:50 +00:00
|
|
|
if (owner)
|
|
|
|
owner->SetWindow();
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::InstantiateFullPagePlugin End mime=%s, rv=%d, owner=%p, url=%s\n",
|
2005-04-29 12:11:45 +00:00
|
|
|
aMimeType, rv, aOwner, urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-04-05 15:25:59 +00:00
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHost::FindTagForLibrary(PRLibrary* aLibrary)
|
|
|
|
{
|
|
|
|
nsPluginTag* pluginTag;
|
|
|
|
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
|
|
|
if (pluginTag->mLibrary == aLibrary) {
|
|
|
|
return pluginTag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2010-01-12 06:45:23 +00:00
|
|
|
nsPluginTag*
|
2010-07-20 02:11:26 +00:00
|
|
|
nsPluginHost::TagForPlugin(nsNPAPIPlugin* aPlugin)
|
2010-01-12 06:45:23 +00:00
|
|
|
{
|
|
|
|
nsPluginTag* pluginTag;
|
|
|
|
for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
|
|
|
|
if (pluginTag->mEntryPoint == aPlugin) {
|
|
|
|
return pluginTag;
|
|
|
|
}
|
|
|
|
}
|
2010-07-20 02:11:26 +00:00
|
|
|
// a plugin should never exist without a corresponding tag
|
2010-12-20 01:37:43 +00:00
|
|
|
NS_ERROR("TagForPlugin has failed");
|
2010-01-12 06:45:23 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
|
2009-12-18 02:09:22 +00:00
|
|
|
nsIPluginInstanceOwner *aOwner)
|
1999-05-07 22:06:47 +00:00
|
|
|
{
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString url;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!aURL)
|
2001-08-16 02:59:03 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-04-22 20:50:22 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
aURL->GetAsciiSpec(url);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance *instance = FindStoppedInstance(url.get());
|
|
|
|
if (instance && !instance->IsRunning()) {
|
2000-06-13 23:23:13 +00:00
|
|
|
aOwner->SetInstance(instance);
|
2009-06-29 18:53:52 +00:00
|
|
|
instance->SetOwner(aOwner);
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
instance->Start();
|
|
|
|
aOwner->CreateWidget();
|
2000-07-20 01:40:54 +00:00
|
|
|
|
|
|
|
// If we've got a native window, the let the plugin know about it.
|
2010-12-07 21:18:50 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(aOwner);
|
|
|
|
if (owner)
|
|
|
|
owner->SetWindow();
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
return NS_OK;
|
1999-05-07 22:06:47 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::SetUpPluginInstance(const char *aMimeType,
|
|
|
|
nsIURI *aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner)
|
2002-05-16 20:47:29 +00:00
|
|
|
{
|
2010-12-20 09:13:00 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aOwner);
|
|
|
|
|
2002-05-16 20:47:29 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
rv = TrySetUpPluginInstance(aMimeType, aURL, aOwner);
|
|
|
|
|
|
|
|
// if we fail, refresh plugin list just in case the plugin has been
|
|
|
|
// just added and try to instantiate plugin instance again, see bug 143178
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
// we should also make sure not to do this more than once per page
|
|
|
|
// so if there are a few embed tags with unknown plugins,
|
|
|
|
// we don't get unnecessary overhead
|
|
|
|
// let's cache document to decide whether this is the same page or not
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
2010-12-20 09:13:00 +00:00
|
|
|
aOwner->GetDocument(getter_AddRefs(document));
|
2002-05-16 20:47:29 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> currentdocument = do_QueryReferent(mCurrentDocument);
|
|
|
|
if (document == currentdocument)
|
|
|
|
return rv;
|
|
|
|
|
2003-07-25 19:06:59 +00:00
|
|
|
mCurrentDocument = do_GetWeakReference(document);
|
2002-05-16 20:47:29 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// ReloadPlugins will do the job smartly: nothing will be done
|
2002-05-16 20:47:29 +00:00
|
|
|
// if no changes detected, in such a case just return
|
|
|
|
if (NS_ERROR_PLUGINS_PLUGINSNOTCHANGED == ReloadPlugins(PR_FALSE))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// other failure return codes may be not fatal, so we can still try
|
2009-08-19 00:25:36 +00:00
|
|
|
aOwner->SetInstance(nsnull); // avoid assert about setting it twice
|
2002-05-16 20:47:29 +00:00
|
|
|
rv = TrySetUpPluginInstance(aMimeType, aURL, aOwner);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2009-06-25 21:06:54 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
|
|
|
nsIURI *aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner)
|
1999-03-03 04:10:54 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString urlSpec;
|
2009-07-02 05:48:08 +00:00
|
|
|
if (aURL != nsnull) aURL->GetSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::TrySetupPluginInstance Begin mime=%s, owner=%p, url=%s\n",
|
2002-03-06 07:48:55 +00:00
|
|
|
aMimeType, aOwner, urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
const char* mimetype = nsnull;
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2002-09-17 22:56:06 +00:00
|
|
|
// if don't have a mimetype or no plugin can handle this mimetype
|
|
|
|
// check by file extension
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_TRUE);
|
2008-03-25 06:00:31 +00:00
|
|
|
if (!pluginTag) {
|
2002-09-17 22:56:06 +00:00
|
|
|
nsCOMPtr<nsIURL> url = do_QueryInterface(aURL);
|
|
|
|
if (!url) return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-17 22:56:06 +00:00
|
|
|
nsCAutoString fileExtension;
|
|
|
|
url->GetFileExtension(fileExtension);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-17 22:56:06 +00:00
|
|
|
// if we don't have an extension or no plugin for this extension,
|
|
|
|
// return failure as there is nothing more we can do
|
2004-10-11 04:01:49 +00:00
|
|
|
if (fileExtension.IsEmpty() ||
|
2005-11-06 18:34:03 +00:00
|
|
|
!(pluginTag = FindPluginEnabledForExtension(fileExtension.get(),
|
|
|
|
mimetype))) {
|
2001-03-12 02:07:15 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-01-05 00:21:06 +00:00
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2009-06-10 20:47:49 +00:00
|
|
|
else {
|
2001-03-12 02:07:15 +00:00
|
|
|
mimetype = aMimeType;
|
2009-06-10 20:47:49 +00:00
|
|
|
}
|
1999-03-29 22:18:05 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
NS_ASSERTION(pluginTag, "Must have plugin tag here!");
|
2009-05-07 13:27:08 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
nsCOMPtr<nsIPlugin> plugin;
|
2009-07-08 01:00:11 +00:00
|
|
|
GetPlugin(mimetype, getter_AddRefs(plugin));
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instance;
|
2009-06-11 17:40:38 +00:00
|
|
|
if (plugin) {
|
2009-05-07 13:27:08 +00:00
|
|
|
#if defined(XP_WIN) && !defined(WINCE)
|
2009-06-11 17:40:38 +00:00
|
|
|
static BOOL firstJavaPlugin = FALSE;
|
|
|
|
BOOL restoreOrigDir = FALSE;
|
2010-02-13 21:59:39 +00:00
|
|
|
WCHAR origDir[_MAX_PATH];
|
2009-06-11 17:40:38 +00:00
|
|
|
if (pluginTag->mIsJavaPlugin && !firstJavaPlugin) {
|
2010-02-13 21:59:39 +00:00
|
|
|
DWORD dw = GetCurrentDirectoryW(_MAX_PATH, origDir);
|
2009-11-10 05:16:05 +00:00
|
|
|
NS_ASSERTION(dw <= _MAX_PATH, "Failed to obtain the current directory, which may lead to incorrect class loading");
|
2009-06-11 17:40:38 +00:00
|
|
|
nsCOMPtr<nsIFile> binDirectory;
|
2010-08-18 00:05:48 +00:00
|
|
|
rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
|
|
|
getter_AddRefs(binDirectory));
|
1999-03-29 22:18:05 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2010-02-13 21:59:39 +00:00
|
|
|
nsAutoString path;
|
|
|
|
binDirectory->GetPath(path);
|
|
|
|
restoreOrigDir = SetCurrentDirectoryW(path.get());
|
2009-05-07 13:27:08 +00:00
|
|
|
}
|
|
|
|
}
|
2009-06-11 17:40:38 +00:00
|
|
|
#endif
|
2010-08-18 00:05:48 +00:00
|
|
|
|
|
|
|
rv = plugin->CreatePluginInstance(getter_AddRefs(instance));
|
2009-05-07 13:27:08 +00:00
|
|
|
|
2009-06-11 17:40:38 +00:00
|
|
|
#if defined(XP_WIN) && !defined(WINCE)
|
|
|
|
if (!firstJavaPlugin && restoreOrigDir) {
|
2010-02-13 21:59:39 +00:00
|
|
|
BOOL bCheck = SetCurrentDirectoryW(origDir);
|
2009-11-10 05:16:05 +00:00
|
|
|
NS_ASSERTION(bCheck, "Error restoring directory");
|
2009-06-11 17:40:38 +00:00
|
|
|
firstJavaPlugin = TRUE;
|
2009-05-07 13:27:08 +00:00
|
|
|
}
|
2009-06-11 17:40:38 +00:00
|
|
|
#endif
|
2005-01-05 00:21:06 +00:00
|
|
|
}
|
1999-03-03 04:10:54 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
1999-03-03 04:10:54 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// it is adreffed here
|
|
|
|
aOwner->SetInstance(instance);
|
2000-04-22 00:04:24 +00:00
|
|
|
|
2009-12-15 20:28:12 +00:00
|
|
|
// this should not addref the instance or owner
|
|
|
|
// except in some cases not Java, see bug 140931
|
|
|
|
// our COM pointer will free the peer
|
2010-08-18 00:05:48 +00:00
|
|
|
rv = instance->Initialize(aOwner, mimetype);
|
|
|
|
if (NS_FAILED(rv)) {
|
2009-12-15 20:28:12 +00:00
|
|
|
aOwner->SetInstance(nsnull);
|
2010-08-18 00:05:48 +00:00
|
|
|
return rv;
|
2009-12-15 20:28:12 +00:00
|
|
|
}
|
1999-07-25 23:20:03 +00:00
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
mInstances.AppendElement(static_cast<nsNPAPIPluginInstance*>(instance.get()));
|
1999-07-25 23:20:03 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString urlSpec2;
|
2005-01-05 00:21:06 +00:00
|
|
|
if (aURL)
|
|
|
|
aURL->GetSpec(urlSpec2);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::TrySetupPluginInstance Finished mime=%s, rv=%d, owner=%p, url=%s\n",
|
2010-08-18 00:05:48 +00:00
|
|
|
aMimeType, rv, aOwner, urlSpec2.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
return rv;
|
1999-03-03 04:10:54 +00:00
|
|
|
}
|
|
|
|
|
1999-03-29 22:18:05 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2010-02-03 21:52:07 +00:00
|
|
|
nsPluginTag *plugin = FindPluginForType(aMimeType, PR_TRUE);
|
|
|
|
if (plugin)
|
|
|
|
return NS_OK;
|
|
|
|
|
2006-08-12 02:13:24 +00:00
|
|
|
// Pass PR_FALSE as the second arg so we can return NS_ERROR_PLUGIN_DISABLED
|
|
|
|
// for disabled plug-ins.
|
2010-02-03 21:52:07 +00:00
|
|
|
plugin = FindPluginForType(aMimeType, PR_FALSE);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin)
|
2006-08-12 02:13:24 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2008-03-18 10:38:15 +00:00
|
|
|
if (!plugin->IsEnabled()) {
|
2007-07-14 00:28:05 +00:00
|
|
|
if (plugin->HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED))
|
|
|
|
return NS_ERROR_PLUGIN_BLOCKLISTED;
|
|
|
|
else
|
|
|
|
return NS_ERROR_PLUGIN_DISABLED;
|
|
|
|
}
|
|
|
|
|
2006-08-12 02:13:24 +00:00
|
|
|
return NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
2001-12-23 23:23:41 +00:00
|
|
|
// check comma delimitered extensions
|
1999-09-01 19:58:22 +00:00
|
|
|
static int CompareExtensions(const char *aExtensionList, const char *aExtension)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!aExtensionList || !aExtension)
|
1999-09-01 19:58:22 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
const char *pExt = aExtensionList;
|
1999-11-12 23:55:01 +00:00
|
|
|
const char *pComma = strchr(pExt, ',');
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!pComma)
|
2001-07-02 20:08:17 +00:00
|
|
|
return PL_strcasecmp(pExt, aExtension);
|
1999-09-01 19:58:22 +00:00
|
|
|
|
2006-01-05 13:12:46 +00:00
|
|
|
int extlen = strlen(aExtension);
|
2008-11-03 19:23:07 +00:00
|
|
|
while (pComma) {
|
1999-09-01 19:58:22 +00:00
|
|
|
int length = pComma - pExt;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (length == extlen && 0 == PL_strncasecmp(aExtension, pExt, length))
|
1999-09-01 19:58:22 +00:00
|
|
|
return 0;
|
|
|
|
pComma++;
|
|
|
|
pExt = pComma;
|
|
|
|
pComma = strchr(pExt, ',');
|
|
|
|
}
|
|
|
|
|
|
|
|
// the last one
|
2001-07-02 20:08:17 +00:00
|
|
|
return PL_strcasecmp(pExt, aExtension);
|
1999-09-01 19:58:22 +00:00
|
|
|
}
|
|
|
|
|
1999-03-23 03:18:12 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::IsPluginEnabledForExtension(const char* aExtension,
|
|
|
|
const char* &aMimeType)
|
1999-03-23 03:18:12 +00:00
|
|
|
{
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag *plugin = FindPluginEnabledForExtension(aExtension, aMimeType);
|
|
|
|
return plugin ? NS_OK : NS_ERROR_FAILURE;
|
1999-03-23 03:18:12 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
class DOMMimeTypeImpl : public nsIDOMMimeType {
|
|
|
|
public:
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
DOMMimeTypeImpl(nsPluginTag* aTag, PRUint32 aMimeTypeIndex)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
if (!aTag)
|
|
|
|
return;
|
|
|
|
CopyUTF8toUTF16(aTag->mMimeDescriptionArray[aMimeTypeIndex], mDescription);
|
|
|
|
if (aTag->mExtensionsArray)
|
|
|
|
CopyUTF8toUTF16(aTag->mExtensionsArray[aMimeTypeIndex], mSuffixes);
|
|
|
|
if (aTag->mMimeTypeArray)
|
|
|
|
CopyUTF8toUTF16(aTag->mMimeTypeArray[aMimeTypeIndex], mType);
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
virtual ~DOMMimeTypeImpl() {
|
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD GetDescription(nsAString& aDescription)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
|
|
|
aDescription.Assign(mDescription);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD GetEnabledPlugin(nsIDOMPlugin** aEnabledPlugin)
|
|
|
|
{
|
|
|
|
// this has to be implemented by the DOM version.
|
|
|
|
*aEnabledPlugin = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD GetSuffixes(nsAString& aSuffixes)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
|
|
|
aSuffixes.Assign(mSuffixes);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD GetType(nsAString& aType)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
|
|
|
aType.Assign(mType);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-20 19:29:28 +00:00
|
|
|
|
|
|
|
private:
|
2001-08-16 02:59:03 +00:00
|
|
|
nsString mDescription;
|
|
|
|
nsString mSuffixes;
|
|
|
|
nsString mType;
|
1999-04-20 19:29:28 +00:00
|
|
|
};
|
|
|
|
|
2001-08-21 01:48:11 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(DOMMimeTypeImpl, nsIDOMMimeType)
|
2008-11-03 19:23:07 +00:00
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
class DOMPluginImpl : public nsIDOMPlugin {
|
|
|
|
public:
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_DECL_ISUPPORTS
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
DOMPluginImpl(nsPluginTag* aPluginTag) : mPluginTag(aPluginTag)
|
|
|
|
{
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
virtual ~DOMPluginImpl() {
|
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD GetDescription(nsAString& aDescription)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mDescription, aDescription);
|
2002-08-02 21:03:16 +00:00
|
|
|
return NS_OK;
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD GetFilename(nsAString& aFilename)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
2002-06-24 07:17:42 +00:00
|
|
|
PRBool bShowPath;
|
2003-05-27 21:14:55 +00:00
|
|
|
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
2002-06-24 07:17:42 +00:00
|
|
|
if (prefService &&
|
2009-06-10 20:47:49 +00:00
|
|
|
NS_SUCCEEDED(prefService->GetBoolPref("plugin.expose_full_path", &bShowPath)) &&
|
2008-11-03 19:23:07 +00:00
|
|
|
bShowPath) {
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mFullPath, aFilename);
|
2009-05-17 01:09:48 +00:00
|
|
|
} else {
|
2009-06-10 20:47:49 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mFileName, aFilename);
|
2009-05-17 01:09:48 +00:00
|
|
|
}
|
|
|
|
|
2009-06-10 20:47:49 +00:00
|
|
|
return NS_OK;
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
|
|
|
|
2009-04-22 19:13:10 +00:00
|
|
|
NS_METHOD GetVersion(nsAString& aVersion)
|
|
|
|
{
|
|
|
|
CopyUTF8toUTF16(mPluginTag.mVersion, aVersion);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD GetName(nsAString& aName)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mName, aName);
|
2002-08-02 21:03:16 +00:00
|
|
|
return NS_OK;
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD GetLength(PRUint32* aLength)
|
|
|
|
{
|
|
|
|
*aLength = mPluginTag.mVariants;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_METHOD Item(PRUint32 aIndex, nsIDOMMimeType** aReturn)
|
|
|
|
{
|
|
|
|
nsIDOMMimeType* mimeType = new DOMMimeTypeImpl(&mPluginTag, aIndex);
|
|
|
|
NS_IF_ADDREF(mimeType);
|
|
|
|
*aReturn = mimeType;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-03-23 21:23:50 +00:00
|
|
|
NS_METHOD NamedItem(const nsAString& aName, nsIDOMMimeType** aReturn)
|
2001-08-16 02:59:03 +00:00
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
for (int i = mPluginTag.mVariants - 1; i >= 0; --i) {
|
|
|
|
if (aName.Equals(NS_ConvertUTF8toUTF16(mPluginTag.mMimeTypeArray[i])))
|
|
|
|
return Item(i, aReturn);
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-20 19:29:28 +00:00
|
|
|
|
|
|
|
private:
|
2001-08-16 02:59:03 +00:00
|
|
|
nsPluginTag mPluginTag;
|
1999-04-20 19:29:28 +00:00
|
|
|
};
|
|
|
|
|
2001-08-21 01:48:11 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(DOMPluginImpl, nsIDOMPlugin)
|
1999-04-20 19:29:28 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetPluginCount(PRUint32* aPluginCount)
|
1999-04-20 19:29:28 +00:00
|
|
|
{
|
2000-08-17 19:26:15 +00:00
|
|
|
LoadPlugins();
|
|
|
|
|
|
|
|
PRUint32 count = 0;
|
|
|
|
|
|
|
|
nsPluginTag* plugin = mPlugins;
|
|
|
|
while (plugin != nsnull) {
|
2008-03-18 10:38:15 +00:00
|
|
|
if (plugin->IsEnabled()) {
|
2006-08-12 02:13:24 +00:00
|
|
|
++count;
|
|
|
|
}
|
2000-08-17 19:26:15 +00:00
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aPluginCount = count;
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-04-20 19:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray)
|
1999-04-20 19:29:28 +00:00
|
|
|
{
|
2000-08-17 19:26:15 +00:00
|
|
|
LoadPlugins();
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2000-04-22 20:50:22 +00:00
|
|
|
nsPluginTag* plugin = mPlugins;
|
2007-07-03 21:42:35 +00:00
|
|
|
for (PRUint32 i = 0; i < aPluginCount && plugin; plugin = plugin->mNext) {
|
2008-03-18 10:38:15 +00:00
|
|
|
if (plugin->IsEnabled()) {
|
2006-08-12 02:13:24 +00:00
|
|
|
nsIDOMPlugin* domPlugin = new DOMPluginImpl(plugin);
|
|
|
|
NS_IF_ADDREF(domPlugin);
|
2007-07-03 21:42:35 +00:00
|
|
|
aPluginArray[i++] = domPlugin;
|
2006-08-12 02:13:24 +00:00
|
|
|
}
|
2000-04-22 20:50:22 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2000-04-22 20:50:22 +00:00
|
|
|
return NS_OK;
|
1999-04-20 19:29:28 +00:00
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetPluginTags(PRUint32* aPluginCount, nsIPluginTag*** aResults)
|
2007-07-03 21:42:35 +00:00
|
|
|
{
|
|
|
|
LoadPlugins();
|
|
|
|
|
|
|
|
PRUint32 count = 0;
|
|
|
|
nsRefPtr<nsPluginTag> plugin = mPlugins;
|
|
|
|
while (plugin != nsnull) {
|
|
|
|
count++;
|
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
|
|
|
|
2007-07-08 07:08:04 +00:00
|
|
|
*aResults = static_cast<nsIPluginTag**>
|
|
|
|
(nsMemory::Alloc(count * sizeof(**aResults)));
|
2007-07-03 21:42:35 +00:00
|
|
|
if (!*aResults)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
*aPluginCount = count;
|
|
|
|
|
|
|
|
plugin = mPlugins;
|
|
|
|
PRUint32 i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
(*aResults)[i] = plugin;
|
|
|
|
NS_ADDREF((*aResults)[i]);
|
|
|
|
plugin = plugin->mNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag*
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::FindPluginForType(const char* aMimeType,
|
|
|
|
PRBool aCheckEnabled)
|
1999-03-23 03:18:12 +00:00
|
|
|
{
|
|
|
|
nsPluginTag *plugins = nsnull;
|
|
|
|
PRInt32 variants, cnt;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2000-08-17 19:26:15 +00:00
|
|
|
LoadPlugins();
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
// if we have a mimetype passed in, search the mPlugins
|
2000-04-22 20:50:22 +00:00
|
|
|
// linked list for a match
|
2010-08-02 20:31:31 +00:00
|
|
|
if (aMimeType) {
|
1999-03-23 03:18:12 +00:00
|
|
|
plugins = mPlugins;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-08-02 20:31:31 +00:00
|
|
|
while (plugins) {
|
1999-03-23 03:18:12 +00:00
|
|
|
variants = plugins->mVariants;
|
2000-04-22 20:50:22 +00:00
|
|
|
for (cnt = 0; cnt < variants; cnt++) {
|
2008-03-18 10:38:15 +00:00
|
|
|
if ((!aCheckEnabled || plugins->IsEnabled()) &&
|
2005-11-06 18:34:03 +00:00
|
|
|
plugins->mMimeTypeArray[cnt] &&
|
|
|
|
(0 == PL_strcasecmp(plugins->mMimeTypeArray[cnt], aMimeType))) {
|
|
|
|
return plugins;
|
2000-04-22 20:50:22 +00:00
|
|
|
}
|
|
|
|
}
|
2005-11-06 18:34:03 +00:00
|
|
|
plugins = plugins->mNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag*
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::FindPluginEnabledForExtension(const char* aExtension,
|
|
|
|
const char*& aMimeType)
|
2005-11-06 18:34:03 +00:00
|
|
|
{
|
|
|
|
nsPluginTag *plugins = nsnull;
|
|
|
|
PRInt32 variants, cnt;
|
|
|
|
|
|
|
|
LoadPlugins();
|
|
|
|
|
|
|
|
// if we have a mimetype passed in, search the mPlugins linked
|
|
|
|
// list for a match
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aExtension) {
|
2005-11-06 18:34:03 +00:00
|
|
|
plugins = mPlugins;
|
2008-11-03 19:23:07 +00:00
|
|
|
while (plugins) {
|
2005-11-06 18:34:03 +00:00
|
|
|
variants = plugins->mVariants;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugins->mExtensionsArray) {
|
|
|
|
for (cnt = 0; cnt < variants; cnt++) {
|
2005-11-06 18:34:03 +00:00
|
|
|
// mExtensionsArray[cnt] is a list of extensions separated
|
|
|
|
// by commas
|
2008-03-18 10:38:15 +00:00
|
|
|
if (plugins->IsEnabled() &&
|
2008-11-03 19:23:07 +00:00
|
|
|
0 == CompareExtensions(plugins->mExtensionsArray[cnt], aExtension)) {
|
2005-11-06 18:34:03 +00:00
|
|
|
aMimeType = plugins->mMimeTypeArray[cnt];
|
|
|
|
return plugins;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-03-23 03:18:12 +00:00
|
|
|
plugins = plugins->mNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
return nsnull;
|
1999-03-23 03:18:12 +00:00
|
|
|
}
|
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
static nsresult ConvertToNative(nsIUnicodeEncoder *aEncoder,
|
|
|
|
const nsACString& aUTF8String,
|
|
|
|
nsACString& aNativeString)
|
|
|
|
{
|
|
|
|
NS_ConvertUTF8toUTF16 utf16(aUTF8String);
|
|
|
|
PRInt32 len = utf16.Length();
|
|
|
|
PRInt32 outLen;
|
|
|
|
nsresult rv = aEncoder->GetMaxLength(utf16.get(), len, &outLen);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!EnsureStringLength(aNativeString, outLen))
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
rv = aEncoder->Convert(utf16.get(), &len,
|
|
|
|
aNativeString.BeginWriting(), &outLen);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aNativeString.SetLength(outLen);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag,
|
2011-02-08 22:16:07 +00:00
|
|
|
nsNPAPIPlugin **aOutNPAPIPlugin)
|
2008-03-10 07:07:15 +00:00
|
|
|
{
|
2010-08-18 00:05:48 +00:00
|
|
|
// If this is an in-process plugin we'll need to load it here if we haven't already.
|
|
|
|
#ifdef MOZ_IPC
|
2010-09-16 04:57:13 +00:00
|
|
|
if (!nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
|
2010-08-18 00:05:48 +00:00
|
|
|
#else
|
|
|
|
if (!aPluginTag->mLibrary) {
|
|
|
|
#endif
|
|
|
|
if (aPluginTag->mFullPath.IsEmpty())
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
|
|
|
file->InitWithPath(NS_ConvertUTF8toUTF16(aPluginTag->mFullPath));
|
|
|
|
nsPluginFile pluginFile(file);
|
|
|
|
PRLibrary* pluginLibrary = NULL;
|
|
|
|
|
|
|
|
if (NS_FAILED(pluginFile.LoadPlugin(&pluginLibrary)) || !pluginLibrary)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
aPluginTag->mLibrary = pluginLibrary;
|
|
|
|
}
|
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr <nsIPlatformCharset> pcs =
|
|
|
|
do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCAutoString charset;
|
|
|
|
rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2009-06-10 20:47:49 +00:00
|
|
|
nsCAutoString fullPath;
|
2008-03-10 07:07:15 +00:00
|
|
|
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
|
|
|
nsCOMPtr<nsIUnicodeEncoder> encoder;
|
|
|
|
nsCOMPtr<nsICharsetConverterManager> ccm =
|
|
|
|
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = ccm->GetUnicodeEncoderRaw(charset.get(), getter_AddRefs(encoder));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = ConvertToNative(encoder, aPluginTag->mFullPath, fullPath);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else {
|
|
|
|
fullPath = aPluginTag->mFullPath;
|
|
|
|
}
|
|
|
|
|
2010-04-07 22:14:54 +00:00
|
|
|
#if defined(XP_MACOSX) && !defined(__LP64__)
|
|
|
|
short appRefNum = ::CurResFile();
|
|
|
|
nsCOMPtr<nsILocalFile> pluginPath;
|
|
|
|
NS_NewNativeLocalFile(nsDependentCString(fullPath.get()), PR_TRUE,
|
|
|
|
getter_AddRefs(pluginPath));
|
|
|
|
nsPluginFile pluginFile(pluginPath);
|
|
|
|
short pluginRefNum = pluginFile.OpenPluginResource();
|
|
|
|
#endif
|
|
|
|
|
2010-09-16 04:57:13 +00:00
|
|
|
rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin);
|
2010-04-07 22:14:54 +00:00
|
|
|
|
|
|
|
#if defined(XP_MACOSX) && !defined(__LP64__)
|
|
|
|
if (NS_SUCCEEDED(rv))
|
2011-02-08 22:16:07 +00:00
|
|
|
(*aOutNPAPIPlugin)->SetPluginRefNum(pluginRefNum);
|
2010-04-07 22:14:54 +00:00
|
|
|
else if (pluginRefNum > 0)
|
|
|
|
::CloseResFile(pluginRefNum);
|
|
|
|
::UseResFile(appRefNum);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return rv;
|
2008-03-10 07:07:15 +00:00
|
|
|
}
|
2002-11-06 01:24:57 +00:00
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
nsresult nsPluginHost::EnsurePluginLoaded(nsPluginTag* plugin)
|
|
|
|
{
|
|
|
|
nsRefPtr<nsNPAPIPlugin> entrypoint = plugin->mEntryPoint;
|
|
|
|
if (!entrypoint) {
|
|
|
|
nsresult rv = CreateNPAPIPlugin(plugin, getter_AddRefs(entrypoint));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
plugin->mEntryPoint = entrypoint;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-07-08 01:00:11 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::GetPlugin(const char *aMimeType, nsIPlugin** aPlugin)
|
1999-02-20 02:24:15 +00:00
|
|
|
{
|
2001-04-17 23:30:25 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
*aPlugin = NULL;
|
1999-02-25 04:15:39 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!aMimeType)
|
2001-04-17 23:30:25 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
1999-03-29 22:18:05 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
// If plugins haven't been scanned yet, do so now
|
2000-08-17 19:26:15 +00:00
|
|
|
LoadPlugins();
|
1999-02-25 04:15:39 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_TRUE);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (pluginTag) {
|
2005-11-06 18:34:03 +00:00
|
|
|
rv = NS_OK;
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_BASIC,
|
2009-07-08 01:00:11 +00:00
|
|
|
("nsPluginHost::GetPlugin Begin mime=%s, plugin=%s\n",
|
2008-03-10 07:07:15 +00:00
|
|
|
aMimeType, pluginTag->mFileName.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
#ifdef NS_DEBUG
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aMimeType && !pluginTag->mFileName.IsEmpty())
|
2008-03-10 07:07:15 +00:00
|
|
|
printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName.get());
|
2001-02-02 23:48:17 +00:00
|
|
|
#endif
|
1999-07-06 04:14:54 +00:00
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
rv = EnsurePluginLoaded(pluginTag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
2009-11-20 15:34:20 +00:00
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
NS_ADDREF(*aPlugin = pluginTag->mEntryPoint);
|
2009-11-20 15:34:20 +00:00
|
|
|
return NS_OK;
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
1999-02-20 02:24:15 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-08 01:00:11 +00:00
|
|
|
("nsPluginHost::GetPlugin End mime=%s, rv=%d, plugin=%p name=%s\n",
|
2008-03-10 07:07:15 +00:00
|
|
|
aMimeType, rv, *aPlugin,
|
|
|
|
(pluginTag ? pluginTag->mFileName.get() : "(not found)")));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
return rv;
|
1999-03-29 22:18:05 +00:00
|
|
|
}
|
1999-02-20 02:24:15 +00:00
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
// Normalize 'host' to ACE.
|
|
|
|
nsresult
|
|
|
|
nsPluginHost::NormalizeHostname(nsCString& host)
|
|
|
|
{
|
|
|
|
if (IsASCII(host)) {
|
|
|
|
ToLowerCase(host);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mIDNService) {
|
|
|
|
nsresult rv;
|
|
|
|
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mIDNService->ConvertUTF8toACE(host, host);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enumerate a 'sites' array returned by GetSitesWithData and determine if
|
|
|
|
// any of them have a base domain in common with 'domain'; if so, append them
|
|
|
|
// to the 'result' array. If 'firstMatchOnly' is true, return after finding the
|
|
|
|
// first match.
|
|
|
|
nsresult
|
|
|
|
nsPluginHost::EnumerateSiteData(const nsACString& domain,
|
|
|
|
const nsTArray<nsCString>& sites,
|
|
|
|
InfallibleTArray<nsCString>& result,
|
|
|
|
bool firstMatchOnly)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!domain.IsVoid(), "null domain string");
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (!mTLDService) {
|
|
|
|
mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the base domain from the domain.
|
|
|
|
nsCString baseDomain;
|
|
|
|
rv = mTLDService->GetBaseDomainFromHost(domain, 0, baseDomain);
|
|
|
|
bool isIP = rv == NS_ERROR_HOST_IS_IP_ADDRESS;
|
|
|
|
if (isIP || rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
|
|
|
// The base domain is the site itself. However, we must be careful to
|
|
|
|
// normalize.
|
|
|
|
baseDomain = domain;
|
|
|
|
rv = NormalizeHostname(baseDomain);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enumerate the array of sites with data.
|
|
|
|
for (PRUint32 i = 0; i < sites.Length(); ++i) {
|
|
|
|
const nsCString& site = sites[i];
|
|
|
|
|
|
|
|
// Check if the site is an IP address.
|
|
|
|
bool siteIsIP =
|
|
|
|
site.Length() >= 2 && site.First() == '[' && site.Last() == ']';
|
|
|
|
if (siteIsIP != isIP)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nsCString siteBaseDomain;
|
|
|
|
if (siteIsIP) {
|
|
|
|
// Strip the '[]'.
|
|
|
|
siteBaseDomain = Substring(site, 1, site.Length() - 2);
|
|
|
|
} else {
|
|
|
|
// Determine the base domain of the site.
|
|
|
|
rv = mTLDService->GetBaseDomainFromHost(site, 0, siteBaseDomain);
|
|
|
|
if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
|
|
|
// The base domain is the site itself. However, we must be careful to
|
|
|
|
// normalize.
|
|
|
|
siteBaseDomain = site;
|
|
|
|
rv = NormalizeHostname(siteBaseDomain);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point, we can do an exact comparison of the two domains.
|
|
|
|
if (baseDomain != siteBaseDomain) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Append the site to the result array.
|
|
|
|
result.AppendElement(site);
|
|
|
|
|
|
|
|
// If we're supposed to return early, do so.
|
|
|
|
if (firstMatchOnly) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::ClearSiteData(nsIPluginTag* plugin, const nsACString& domain,
|
|
|
|
PRUint64 flags, PRInt64 maxAge)
|
|
|
|
{
|
|
|
|
// maxAge must be either a nonnegative integer or -1.
|
|
|
|
NS_ENSURE_ARG(maxAge >= 0 || maxAge == -1);
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
// Caller may give us a tag object that is no longer live.
|
|
|
|
if (!IsLiveTag(plugin)) {
|
2011-02-08 22:16:07 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
|
|
|
|
|
|
|
|
// We only ensure support for clearing Flash site data for now.
|
|
|
|
// We will also attempt to clear data for any plugin that happens
|
|
|
|
// to be loaded already.
|
|
|
|
if (!tag->mIsFlashPlugin && !tag->mEntryPoint) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the plugin is loaded.
|
|
|
|
nsresult rv = EnsurePluginLoaded(tag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
PluginLibrary* library = tag->mEntryPoint->GetLibrary();
|
|
|
|
|
|
|
|
// If 'domain' is the null string, clear everything.
|
|
|
|
if (domain.IsVoid()) {
|
|
|
|
return library->NPP_ClearSiteData(NULL, flags, maxAge);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the list of sites from the plugin.
|
|
|
|
InfallibleTArray<nsCString> sites;
|
2011-02-19 01:05:23 +00:00
|
|
|
rv = library->NPP_GetSitesWithData(sites);
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Enumerate the sites and build a list of matches.
|
|
|
|
InfallibleTArray<nsCString> matches;
|
|
|
|
rv = EnumerateSiteData(domain, sites, matches, false);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// Clear the matches.
|
|
|
|
for (PRUint32 i = 0; i < matches.Length(); ++i) {
|
|
|
|
const nsCString& match = matches[i];
|
|
|
|
rv = library->NPP_ClearSiteData(match.get(), flags, maxAge);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::SiteHasData(nsIPluginTag* plugin, const nsACString& domain,
|
|
|
|
PRBool* result)
|
|
|
|
{
|
2011-02-19 01:05:23 +00:00
|
|
|
// Caller may give us a tag object that is no longer live.
|
|
|
|
if (!IsLiveTag(plugin)) {
|
2011-02-08 22:16:07 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
nsPluginTag* tag = static_cast<nsPluginTag*>(plugin);
|
|
|
|
|
|
|
|
// We only ensure support for clearing Flash site data for now.
|
|
|
|
// We will also attempt to clear data for any plugin that happens
|
|
|
|
// to be loaded already.
|
|
|
|
if (!tag->mIsFlashPlugin && !tag->mEntryPoint) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the plugin is loaded.
|
|
|
|
nsresult rv = EnsurePluginLoaded(tag);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-02-08 22:16:07 +00:00
|
|
|
PluginLibrary* library = tag->mEntryPoint->GetLibrary();
|
|
|
|
|
|
|
|
// Get the list of sites from the plugin.
|
|
|
|
InfallibleTArray<nsCString> sites;
|
2011-02-19 01:05:23 +00:00
|
|
|
rv = library->NPP_GetSitesWithData(sites);
|
2011-02-08 22:16:07 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
// If there's no data, we're done.
|
|
|
|
if (sites.IsEmpty()) {
|
|
|
|
*result = false;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If 'domain' is the null string, and there's data for at least one site,
|
|
|
|
// we're done.
|
|
|
|
if (domain.IsVoid()) {
|
|
|
|
*result = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enumerate the sites and determine if there's a match.
|
|
|
|
InfallibleTArray<nsCString> matches;
|
|
|
|
rv = EnumerateSiteData(domain, sites, matches, true);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
*result = !matches.IsEmpty();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PRBool nsPluginHost::IsJavaMIMEType(const char* aType)
|
2005-11-06 18:34:03 +00:00
|
|
|
{
|
|
|
|
return aType &&
|
|
|
|
((0 == PL_strncasecmp(aType, "application/x-java-vm",
|
|
|
|
sizeof("application/x-java-vm") - 1)) ||
|
|
|
|
(0 == PL_strncasecmp(aType, "application/x-java-applet",
|
|
|
|
sizeof("application/x-java-applet") - 1)) ||
|
|
|
|
(0 == PL_strncasecmp(aType, "application/x-java-bean",
|
|
|
|
sizeof("application/x-java-bean") - 1)));
|
|
|
|
}
|
|
|
|
|
2011-02-19 01:05:23 +00:00
|
|
|
// Check whether or not a tag is a live, valid tag, and that it's loaded.
|
|
|
|
PRBool
|
|
|
|
nsPluginHost::IsLiveTag(nsIPluginTag* aPluginTag)
|
|
|
|
{
|
|
|
|
nsPluginTag* tag;
|
|
|
|
for (tag = mPlugins; tag; tag = tag->mNext) {
|
|
|
|
if (tag == aPluginTag) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginTag * nsPluginHost::HaveSamePlugin(nsPluginTag * aPluginTag)
|
2002-02-13 02:18:57 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
|
|
|
|
if (tag->Equals(aPluginTag))
|
2002-02-13 02:18:57 +00:00
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
PRBool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
|
2002-02-13 02:18:57 +00:00
|
|
|
{
|
|
|
|
nsPluginTag * tag = HaveSamePlugin(aPluginTag);
|
|
|
|
if (tag) {
|
|
|
|
// if we got the same plugin, check the full path to see if this is a dup;
|
|
|
|
|
|
|
|
// mFileName contains full path on Windows and Unix and leaf name on Mac
|
|
|
|
// if those are not equal, we have the same plugin with different path,
|
|
|
|
// i.e. duplicate, return true
|
2008-03-10 07:07:15 +00:00
|
|
|
if (!tag->mFileName.Equals(aPluginTag->mFileName))
|
2002-02-13 02:18:57 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if they are equal, compare mFullPath fields just in case
|
2002-02-13 02:18:57 +00:00
|
|
|
// mFileName contained leaf name only, and if not equal, return true
|
2008-03-10 07:07:15 +00:00
|
|
|
if (!tag->mFullPath.Equals(aPluginTag->mFullPath))
|
2002-02-13 02:18:57 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we do not have it at all, return false
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-01-26 00:44:47 +00:00
|
|
|
// Structure for collecting plugin files found during directory scanning
|
|
|
|
struct pluginFileinDirectory
|
|
|
|
{
|
2009-06-10 20:47:49 +00:00
|
|
|
nsString mFilePath;
|
2002-01-26 00:44:47 +00:00
|
|
|
PRInt64 mModTime;
|
|
|
|
|
|
|
|
pluginFileinDirectory()
|
|
|
|
{
|
|
|
|
mModTime = LL_ZERO;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// QuickSort callback for comparing the modification time of two files
|
|
|
|
// if the times are the same, compare the filenames
|
|
|
|
|
2009-03-28 13:57:13 +00:00
|
|
|
NS_SPECIALIZE_TEMPLATE
|
|
|
|
class nsDefaultComparator<pluginFileinDirectory, pluginFileinDirectory>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PRBool Equals(const pluginFileinDirectory& aA,
|
|
|
|
const pluginFileinDirectory& aB) const {
|
|
|
|
if (aA.mModTime == aB.mModTime &&
|
2009-06-10 20:47:49 +00:00
|
|
|
Compare(aA.mFilePath, aB.mFilePath,
|
2009-03-28 13:57:13 +00:00
|
|
|
nsCaseInsensitiveStringComparator()) == 0)
|
|
|
|
return PR_TRUE;
|
|
|
|
else
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
PRBool LessThan(const pluginFileinDirectory& aA,
|
|
|
|
const pluginFileinDirectory& aB) const {
|
|
|
|
if (aA.mModTime < aB.mModTime)
|
|
|
|
return PR_TRUE;
|
|
|
|
else if(aA.mModTime == aB.mModTime)
|
2009-06-10 20:47:49 +00:00
|
|
|
return Compare(aA.mFilePath, aB.mFilePath,
|
2009-03-28 13:57:13 +00:00
|
|
|
nsCaseInsensitiveStringComparator()) < 0;
|
|
|
|
else
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
};
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2008-09-15 12:45:01 +00:00
|
|
|
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
|
2002-04-27 01:47:18 +00:00
|
|
|
|
2011-03-31 18:26:57 +00:00
|
|
|
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
2009-07-02 05:48:08 +00:00
|
|
|
PRBool aCreatePluginList,
|
2011-03-31 18:26:57 +00:00
|
|
|
PRBool *aPluginsChanged)
|
2000-02-01 00:42:52 +00:00
|
|
|
{
|
2002-02-11 23:09:38 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aPluginsChanged);
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
*aPluginsChanged = PR_FALSE;
|
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString dirPath;
|
|
|
|
pluginsDir->GetNativePath(dirPath);
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_BASIC,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::ScanPluginsDirectory dir=%s\n", dirPath.get()));
|
2001-11-17 15:26:02 +00:00
|
|
|
#endif
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> iter;
|
|
|
|
rv = pluginsDir->GetDirectoryEntries(getter_AddRefs(iter));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2002-01-26 00:44:47 +00:00
|
|
|
|
2009-03-28 13:57:13 +00:00
|
|
|
// Collect all the files in this directory in an array we can sort later
|
|
|
|
nsAutoTArray<pluginFileinDirectory, 8> pluginFilesArray;
|
2006-01-19 03:40:06 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
PRBool hasMore;
|
2002-02-11 23:09:38 +00:00
|
|
|
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
rv = iter->GetNext(getter_AddRefs(supports));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCOMPtr<nsILocalFile> dirEntry(do_QueryInterface(supports, &rv));
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2003-03-22 04:04:55 +00:00
|
|
|
|
|
|
|
// Sun's JRE 1.3.1 plugin must have symbolic links resolved or else it'll crash.
|
2004-10-11 04:01:49 +00:00
|
|
|
// See bug 197855.
|
2003-03-22 04:04:55 +00:00
|
|
|
dirEntry->Normalize();
|
|
|
|
|
2003-05-31 19:07:04 +00:00
|
|
|
nsAutoString filePath;
|
|
|
|
rv = dirEntry->GetPath(filePath);
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2006-11-08 16:43:17 +00:00
|
|
|
if (nsPluginsDir::IsPluginFile(dirEntry)) {
|
2009-03-28 13:57:13 +00:00
|
|
|
pluginFileinDirectory * item = pluginFilesArray.AppendElement();
|
2006-11-08 16:43:17 +00:00
|
|
|
if (!item)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// Get file mod time
|
|
|
|
PRInt64 fileModTime = LL_ZERO;
|
|
|
|
dirEntry->GetLastModifiedTime(&fileModTime);
|
|
|
|
|
|
|
|
item->mModTime = fileModTime;
|
2009-06-10 20:47:49 +00:00
|
|
|
item->mFilePath = filePath;
|
2006-11-08 16:43:17 +00:00
|
|
|
}
|
2002-01-26 00:44:47 +00:00
|
|
|
} // end round of up of plugin files
|
|
|
|
|
|
|
|
// now sort the array by file modification time or by filename, if equal
|
|
|
|
// put newer plugins first to weed out dups and catch upgrades, see bug 119966
|
2009-03-28 13:57:13 +00:00
|
|
|
pluginFilesArray.Sort();
|
2002-01-26 00:44:47 +00:00
|
|
|
|
2009-10-02 11:26:04 +00:00
|
|
|
PRBool warnOutdated = PR_FALSE;
|
|
|
|
|
2002-01-26 00:44:47 +00:00
|
|
|
// finally, go through the array, looking at each entry and continue processing it
|
2009-03-28 13:57:13 +00:00
|
|
|
for (PRUint32 i = 0; i < pluginFilesArray.Length(); i++) {
|
|
|
|
pluginFileinDirectory &pfd = pluginFilesArray[i];
|
2003-03-15 01:04:32 +00:00
|
|
|
nsCOMPtr <nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
|
|
|
nsCOMPtr <nsILocalFile> localfile = do_QueryInterface(file);
|
2009-06-10 20:47:49 +00:00
|
|
|
localfile->InitWithPath(pfd.mFilePath);
|
2009-03-28 13:57:13 +00:00
|
|
|
PRInt64 fileModTime = pfd.mModTime;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
// Look for it in our cache
|
2010-12-09 22:28:15 +00:00
|
|
|
NS_ConvertUTF16toUTF8 filePath(pfd.mFilePath);
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> pluginTag;
|
2010-12-09 22:28:15 +00:00
|
|
|
RemoveCachedPluginsInfo(filePath.get(),
|
2007-07-03 21:42:35 +00:00
|
|
|
getter_AddRefs(pluginTag));
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2008-11-02 12:13:48 +00:00
|
|
|
PRBool enabled = PR_TRUE;
|
|
|
|
PRBool seenBefore = PR_FALSE;
|
2002-02-11 23:09:38 +00:00
|
|
|
if (pluginTag) {
|
2008-11-02 12:13:48 +00:00
|
|
|
seenBefore = PR_TRUE;
|
2005-11-25 08:16:51 +00:00
|
|
|
// If plugin changed, delete cachedPluginTag and don't use cache
|
2002-02-11 23:09:38 +00:00
|
|
|
if (LL_NE(fileModTime, pluginTag->mLastModifiedTime)) {
|
2005-11-25 08:16:51 +00:00
|
|
|
// Plugins has changed. Don't use cached plugin info.
|
2008-11-02 12:13:48 +00:00
|
|
|
enabled = (pluginTag->Flags() & NS_PLUGIN_FLAG_ENABLED) != 0;
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag = nsnull;
|
|
|
|
|
|
|
|
// plugin file changed, flag this fact
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
else {
|
2002-02-11 23:09:38 +00:00
|
|
|
// if it is unwanted plugin we are checking for, get it back to the cache info list
|
2002-02-13 02:18:57 +00:00
|
|
|
// if this is a duplicate plugin, too place it back in the cache info list marking unwantedness
|
2011-03-31 18:26:57 +00:00
|
|
|
if (IsDuplicatePlugin(pluginTag)) {
|
2005-11-06 18:34:03 +00:00
|
|
|
if (!pluginTag->HasFlag(NS_PLUGIN_FLAG_UNWANTED)) {
|
|
|
|
// Plugin switched from wanted to unwanted
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag->Mark(NS_PLUGIN_FLAG_UNWANTED);
|
|
|
|
pluginTag->mNext = mCachedPlugins;
|
|
|
|
mCachedPlugins = pluginTag;
|
2005-11-06 18:34:03 +00:00
|
|
|
} else if (pluginTag->HasFlag(NS_PLUGIN_FLAG_UNWANTED)) {
|
|
|
|
pluginTag->UnMark(NS_PLUGIN_FLAG_UNWANTED);
|
|
|
|
// Plugin switched from unwanted to wanted
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
|
2010-10-13 15:50:35 +00:00
|
|
|
// If we're not creating a list and we already know something changed then
|
|
|
|
// we're done.
|
|
|
|
if (!aCreatePluginList) {
|
|
|
|
if (*aPluginsChanged) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
continue;
|
2010-10-13 15:50:35 +00:00
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2010-12-09 22:28:15 +00:00
|
|
|
|
2010-12-20 23:38:04 +00:00
|
|
|
bool isKnownInvalidPlugin = false;
|
2010-12-09 22:28:15 +00:00
|
|
|
for (nsRefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
|
|
|
|
invalidPlugins; invalidPlugins = invalidPlugins->mNext) {
|
|
|
|
// If already marked as invalid, ignore it
|
|
|
|
if (invalidPlugins->mFullPath.Equals(filePath.get()) &&
|
|
|
|
invalidPlugins->mLastModifiedTime == fileModTime) {
|
|
|
|
if (aCreatePluginList) {
|
|
|
|
invalidPlugins->mSeen = true;
|
|
|
|
}
|
|
|
|
isKnownInvalidPlugin = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isKnownInvalidPlugin) {
|
|
|
|
continue;
|
|
|
|
}
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if it is not found in cache info list or has been changed, create a new one
|
|
|
|
if (!pluginTag) {
|
|
|
|
nsPluginFile pluginFile(file);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// create a tag describing this plugin.
|
2010-08-18 00:05:48 +00:00
|
|
|
PRLibrary *library = nsnull;
|
2008-12-09 17:15:49 +00:00
|
|
|
nsPluginInfo info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
2010-08-18 00:05:48 +00:00
|
|
|
nsresult res = pluginFile.GetPluginInfo(info, &library);
|
2008-12-09 17:15:49 +00:00
|
|
|
// if we don't have mime type don't proceed, this is not a plugin
|
|
|
|
if (NS_FAILED(res) || !info.fMimeTypeArray) {
|
2010-12-09 22:28:15 +00:00
|
|
|
nsRefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
|
|
|
|
fileModTime);
|
2001-10-17 00:39:21 +00:00
|
|
|
pluginFile.FreePluginInfo(info);
|
2010-12-09 22:28:15 +00:00
|
|
|
|
|
|
|
if (aCreatePluginList) {
|
2010-12-20 23:38:04 +00:00
|
|
|
invalidTag->mSeen = true;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
|
|
|
invalidTag->mNext = mInvalidPlugins;
|
|
|
|
if (mInvalidPlugins) {
|
|
|
|
mInvalidPlugins->mPrev = invalidTag;
|
|
|
|
}
|
|
|
|
mInvalidPlugins = invalidTag;
|
|
|
|
|
|
|
|
// Mark aPluginsChanged so pluginreg is rewritten
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
2002-02-11 23:09:38 +00:00
|
|
|
continue;
|
2001-10-17 00:39:21 +00:00
|
|
|
}
|
2002-04-27 01:47:18 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag = new nsPluginTag(&info);
|
|
|
|
pluginFile.FreePluginInfo(info);
|
2010-08-18 00:05:48 +00:00
|
|
|
if (!pluginTag)
|
2002-02-11 23:09:38 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-08-18 00:05:48 +00:00
|
|
|
pluginTag->mLibrary = library;
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag->mLastModifiedTime = fileModTime;
|
2007-07-14 00:28:05 +00:00
|
|
|
|
2008-11-02 12:13:48 +00:00
|
|
|
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
|
|
|
|
if (blocklist) {
|
|
|
|
PRUint32 state;
|
|
|
|
rv = blocklist->GetPluginBlocklistState(pluginTag, EmptyString(),
|
|
|
|
EmptyString(), &state);
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// If the blocklist says so then block the plugin. If the blocklist says
|
|
|
|
// it is risky and we have never seen this plugin before then disable it
|
|
|
|
if (state == nsIBlocklistService::STATE_BLOCKED)
|
|
|
|
pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
|
|
|
else if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore)
|
|
|
|
enabled = PR_FALSE;
|
2009-10-02 11:26:04 +00:00
|
|
|
else if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore)
|
|
|
|
warnOutdated = PR_TRUE;
|
2008-11-02 12:13:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-24 22:56:43 +00:00
|
|
|
if (!enabled)
|
2008-11-02 12:13:48 +00:00
|
|
|
pluginTag->UnMark(NS_PLUGIN_FLAG_ENABLED);
|
2008-11-02 03:27:18 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if this is unwanted plugin we are checkin for, or this is a duplicate plugin,
|
|
|
|
// add it to our cache info list so we can cache the unwantedness of this plugin
|
2002-02-13 02:18:57 +00:00
|
|
|
// when we sync cached plugins to registry
|
2005-11-06 18:34:03 +00:00
|
|
|
NS_ASSERTION(!pluginTag->HasFlag(NS_PLUGIN_FLAG_UNWANTED),
|
|
|
|
"Brand-new tags should not be unwanted");
|
2011-03-31 18:26:57 +00:00
|
|
|
if (IsDuplicatePlugin(pluginTag)) {
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag->Mark(NS_PLUGIN_FLAG_UNWANTED);
|
|
|
|
pluginTag->mNext = mCachedPlugins;
|
|
|
|
mCachedPlugins = pluginTag;
|
2000-09-22 00:58:46 +00:00
|
|
|
}
|
2010-08-18 00:05:48 +00:00
|
|
|
|
|
|
|
// Plugin unloading is tag-based. If we created a new tag and loaded
|
|
|
|
// the library in the process then we want to attempt to unload it here.
|
|
|
|
// Only do this if the pref is set for aggressive unloading.
|
|
|
|
if (UnloadPluginsASAP()) {
|
|
|
|
pluginTag->TryUnloadPlugin();
|
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2000-09-22 00:58:46 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// set the flag that we want to add this plugin to the list for now
|
|
|
|
// and see if it remains after we check several reasons not to do so
|
|
|
|
PRBool bAddIt = PR_TRUE;
|
2011-03-31 18:26:57 +00:00
|
|
|
|
|
|
|
if (HaveSamePlugin(pluginTag)) {
|
|
|
|
// we cannot get here if the plugin has just been added
|
|
|
|
// and thus |pluginTag| is not from cache, because otherwise
|
|
|
|
// it would not be present in the list;
|
2002-02-11 23:09:38 +00:00
|
|
|
bAddIt = PR_FALSE;
|
|
|
|
}
|
2000-09-22 00:58:46 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// do it if we still want it
|
|
|
|
if (bAddIt) {
|
2010-11-20 02:00:52 +00:00
|
|
|
if (!seenBefore) {
|
|
|
|
// We have a valid new plugin so report that plugins have changed.
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
}
|
2010-10-13 15:50:35 +00:00
|
|
|
|
|
|
|
// If we're not creating a plugin list, simply looking for changes,
|
|
|
|
// then we're done.
|
|
|
|
if (!aCreatePluginList) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-06-26 04:32:49 +00:00
|
|
|
pluginTag->SetHost(this);
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag->mNext = mPlugins;
|
|
|
|
mPlugins = pluginTag;
|
2010-06-29 20:56:13 +00:00
|
|
|
|
|
|
|
if (pluginTag->IsEnabled())
|
|
|
|
pluginTag->RegisterWithCategoryManager(mOverrideInternalTypes);
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2009-10-02 11:26:04 +00:00
|
|
|
|
|
|
|
if (warnOutdated)
|
|
|
|
mPrefService->SetBoolPref("plugins.update.notifyUser", PR_TRUE);
|
|
|
|
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2011-03-31 18:26:57 +00:00
|
|
|
nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
|
2009-07-02 05:48:08 +00:00
|
|
|
PRBool aCreatePluginList,
|
2011-03-31 18:26:57 +00:00
|
|
|
PRBool *aPluginsChanged)
|
2001-11-17 15:26:02 +00:00
|
|
|
{
|
|
|
|
PRBool hasMore;
|
|
|
|
while (NS_SUCCEEDED(dirEnum->HasMoreElements(&hasMore)) && hasMore) {
|
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
nsresult rv = dirEnum->GetNext(getter_AddRefs(supports));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
|
|
|
nsCOMPtr<nsIFile> nextDir(do_QueryInterface(supports, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// don't pass aPluginsChanged directly to prevent it from been reset
|
|
|
|
PRBool pluginschanged = PR_FALSE;
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectory(nextDir, aCreatePluginList, &pluginschanged);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
if (pluginschanged)
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
|
|
|
|
// if changes are detected and we are not creating the list, do not proceed
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged)
|
|
|
|
break;
|
2001-11-17 15:26:02 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::LoadPlugins()
|
2000-09-22 00:58:46 +00:00
|
|
|
{
|
|
|
|
// do not do anything if it is already done
|
2002-02-11 23:09:38 +00:00
|
|
|
// use ReloadPlugins() to enforce loading
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPluginsLoaded)
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2009-10-05 09:00:57 +00:00
|
|
|
if (mPluginsDisabled)
|
|
|
|
return NS_OK;
|
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
PRBool pluginschanged;
|
2002-07-01 20:36:57 +00:00
|
|
|
nsresult rv = FindPlugins(PR_TRUE, &pluginschanged);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2009-07-01 13:34:31 +00:00
|
|
|
// only if plugins have changed will we notify plugin-change observers
|
2002-07-01 20:36:57 +00:00
|
|
|
if (pluginschanged) {
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 16:59:13 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
|
|
|
mozilla::services::GetObserverService();
|
2007-07-14 00:28:05 +00:00
|
|
|
if (obsService)
|
|
|
|
obsService->NotifyObservers(nsnull, "plugins-list-updated", nsnull);
|
2002-07-01 20:36:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#include "nsITimelineService.h"
|
|
|
|
|
|
|
|
// if aCreatePluginList is false we will just scan for plugins
|
|
|
|
// and see if any changes have been made to the plugins.
|
|
|
|
// This is needed in ReloadPlugins to prevent possible recursive reloads
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::FindPlugins(PRBool aCreatePluginList, PRBool * aPluginsChanged)
|
2002-02-11 23:09:38 +00:00
|
|
|
{
|
|
|
|
// let's start timing if we are only really creating the plugin list
|
2002-08-23 11:23:49 +00:00
|
|
|
if (aCreatePluginList) {
|
|
|
|
NS_TIMELINE_START_TIMER("LoadPlugins");
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2001-10-11 05:40:00 +00:00
|
|
|
#ifdef CALL_SAFETY_ON
|
2001-10-11 04:51:06 +00:00
|
|
|
// check preferences on whether or not we want to try safe calls to plugins
|
|
|
|
NS_INIT_PLUGIN_SAFE_CALLS;
|
2001-10-11 05:40:00 +00:00
|
|
|
#endif
|
2001-10-11 04:51:06 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aPluginsChanged);
|
|
|
|
|
|
|
|
*aPluginsChanged = PR_FALSE;
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2009-09-22 07:46:32 +00:00
|
|
|
// Read cached plugins info. If the profile isn't yet available then don't
|
|
|
|
// scan for plugins
|
|
|
|
if (ReadPluginInfo() == NS_ERROR_NOT_AVAILABLE)
|
|
|
|
return NS_OK;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2002-07-14 00:39:35 +00:00
|
|
|
// Failure here is not a show-stopper so just warn.
|
2001-11-17 15:26:02 +00:00
|
|
|
rv = EnsurePrivateDirServiceProvider();
|
2006-03-30 18:40:56 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to register dir service provider.");
|
2007-07-20 20:34:51 +00:00
|
|
|
#endif /* XP_WIN */
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsIProperties> dirService(do_GetService(kDirectoryServiceContractID, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> dirList;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// Scan plugins directories;
|
2004-10-11 04:01:49 +00:00
|
|
|
// don't pass aPluginsChanged directly, to prevent its
|
2002-02-11 23:09:38 +00:00
|
|
|
// possible reset in subsequent ScanPluginsDirectory calls
|
|
|
|
PRBool pluginschanged = PR_FALSE;
|
|
|
|
|
2002-09-20 18:47:49 +00:00
|
|
|
// Scan the app-defined list of plugin dirs.
|
2001-11-17 15:26:02 +00:00
|
|
|
rv = dirService->Get(NS_APP_PLUGINS_DIR_LIST, NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dirList));
|
2002-02-11 23:09:38 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectoryList(dirList, aCreatePluginList, &pluginschanged);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
if (pluginschanged)
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we are just looking for possible changes,
|
2002-02-11 23:09:38 +00:00
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-20 23:38:10 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-02-11 23:09:38 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
mPluginsLoaded = PR_TRUE; // at this point 'some' plugins have been loaded,
|
|
|
|
// the rest is optional
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2003-05-27 21:14:55 +00:00
|
|
|
PRBool bScanPLIDs = PR_FALSE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
if (mPrefService)
|
|
|
|
mPrefService->GetBoolPref("plugin.scan.plid.all", &bScanPLIDs);
|
|
|
|
|
|
|
|
// Now lets scan any PLID directories
|
|
|
|
if (bScanPLIDs && mPrivateDirServiceProvider) {
|
|
|
|
rv = mPrivateDirServiceProvider->GetPLIDDirectories(getter_AddRefs(dirList));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-03-31 18:26:57 +00:00
|
|
|
ScanPluginsDirectoryList(dirList, aCreatePluginList, &pluginschanged);
|
2003-05-27 21:14:55 +00:00
|
|
|
|
|
|
|
if (pluginschanged)
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
|
|
|
|
// if we are just looking for possible changes,
|
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-20 23:38:10 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2003-05-27 21:14:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-20 18:47:49 +00:00
|
|
|
// Scan the installation paths of our popular plugins if the prefs are enabled
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// This table controls the order of scanning
|
2011-03-31 18:26:57 +00:00
|
|
|
const char* const prefs[] = {NS_WIN_JRE_SCAN_KEY,
|
|
|
|
NS_WIN_ACROBAT_SCAN_KEY,
|
|
|
|
NS_WIN_QUICKTIME_SCAN_KEY,
|
|
|
|
NS_WIN_WMP_SCAN_KEY};
|
2002-05-01 02:01:50 +00:00
|
|
|
|
|
|
|
PRUint32 size = sizeof(prefs) / sizeof(prefs[0]);
|
|
|
|
|
2011-03-31 18:26:57 +00:00
|
|
|
for (PRUint32 i = 0; i < size; i+=1) {
|
2002-05-01 02:01:50 +00:00
|
|
|
nsCOMPtr<nsIFile> dirToScan;
|
|
|
|
PRBool bExists;
|
|
|
|
if (NS_SUCCEEDED(dirService->Get(prefs[i], NS_GET_IID(nsIFile), getter_AddRefs(dirToScan))) &&
|
|
|
|
dirToScan &&
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_SUCCEEDED(dirToScan->Exists(&bExists)) &&
|
2002-05-01 02:01:50 +00:00
|
|
|
bExists) {
|
2011-03-31 18:26:57 +00:00
|
|
|
|
|
|
|
ScanPluginsDirectory(dirToScan, aCreatePluginList, &pluginschanged);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
if (pluginschanged)
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we are just looking for possible changes,
|
2002-05-01 02:01:50 +00:00
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-20 23:38:10 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-05-01 02:01:50 +00:00
|
|
|
return NS_OK;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2001-02-07 01:13:01 +00:00
|
|
|
}
|
2001-11-17 15:26:02 +00:00
|
|
|
#endif
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if get to this point and did not detect changes in plugins
|
|
|
|
// that means no plugins got updated or added
|
|
|
|
// let's see if plugins have been removed
|
|
|
|
if (!*aPluginsChanged) {
|
|
|
|
// count plugins remained in cache, if there are some, that means some plugins were removed;
|
|
|
|
// while counting, we should ignore unwanted plugins which are also present in cache
|
|
|
|
PRUint32 cachecount = 0;
|
|
|
|
for (nsPluginTag * cachetag = mCachedPlugins; cachetag; cachetag = cachetag->mNext) {
|
2005-11-06 18:34:03 +00:00
|
|
|
if (!cachetag->HasFlag(NS_PLUGIN_FLAG_UNWANTED))
|
2002-02-11 23:09:38 +00:00
|
|
|
cachecount++;
|
|
|
|
}
|
|
|
|
// if there is something left in cache, some plugins got removed from the directory
|
|
|
|
// and therefor their info did not get removed from the cache info list during directory scan;
|
|
|
|
// flag this fact
|
2004-10-11 04:01:49 +00:00
|
|
|
if (cachecount > 0)
|
2002-02-11 23:09:38 +00:00
|
|
|
*aPluginsChanged = PR_TRUE;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2010-12-09 22:28:15 +00:00
|
|
|
|
|
|
|
// Remove unseen invalid plugins
|
|
|
|
nsRefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
|
|
|
|
while (invalidPlugins) {
|
|
|
|
if (!invalidPlugins->mSeen) {
|
|
|
|
nsRefPtr<nsInvalidPluginTag> invalidPlugin = invalidPlugins;
|
|
|
|
|
|
|
|
if (invalidPlugin->mPrev) {
|
|
|
|
invalidPlugin->mPrev->mNext = invalidPlugin->mNext;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mInvalidPlugins = invalidPlugin->mNext;
|
|
|
|
}
|
|
|
|
if (invalidPlugin->mNext) {
|
|
|
|
invalidPlugin->mNext->mPrev = invalidPlugin->mPrev;
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidPlugins = invalidPlugin->mNext;
|
|
|
|
|
|
|
|
invalidPlugin->mPrev = NULL;
|
|
|
|
invalidPlugin->mNext = NULL;
|
|
|
|
}
|
|
|
|
else {
|
2010-12-20 23:38:04 +00:00
|
|
|
invalidPlugins->mSeen = false;
|
2010-12-09 22:28:15 +00:00
|
|
|
invalidPlugins = invalidPlugins->mNext;
|
|
|
|
}
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if we are not creating the list, there is no need to proceed
|
|
|
|
if (!aCreatePluginList) {
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-20 23:38:10 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-02-11 23:09:38 +00:00
|
|
|
return NS_OK;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if we are creating the list, it is already done;
|
|
|
|
// update the plugins info cache if changes are detected
|
|
|
|
if (*aPluginsChanged)
|
2002-08-14 22:31:59 +00:00
|
|
|
WritePluginInfo();
|
2002-02-11 23:09:38 +00:00
|
|
|
|
|
|
|
// No more need for cached plugins. Clear it up.
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-20 23:38:10 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// reverse our list of plugins
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> next;
|
|
|
|
nsRefPtr<nsPluginTag> prev;
|
|
|
|
for (nsRefPtr<nsPluginTag> cur = mPlugins; cur; cur = next) {
|
2001-12-20 06:54:07 +00:00
|
|
|
next = cur->mNext;
|
|
|
|
cur->mNext = prev;
|
|
|
|
prev = cur;
|
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2001-12-20 06:54:07 +00:00
|
|
|
mPlugins = prev;
|
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
NS_TIMELINE_STOP_TIMER("LoadPlugins");
|
|
|
|
NS_TIMELINE_MARK_TIMER("LoadPlugins");
|
|
|
|
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
2000-02-01 00:42:52 +00:00
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::UpdatePluginInfo(nsPluginTag* aPluginTag)
|
2007-07-03 21:42:35 +00:00
|
|
|
{
|
|
|
|
ReadPluginInfo();
|
|
|
|
WritePluginInfo();
|
2009-08-19 00:25:36 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
|
2010-12-20 23:38:10 +00:00
|
|
|
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
2007-07-14 00:28:05 +00:00
|
|
|
|
2008-03-18 10:38:15 +00:00
|
|
|
if (!aPluginTag || aPluginTag->IsEnabled())
|
2007-07-14 00:28:05 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupportsArray> instsToReload;
|
|
|
|
NS_NewISupportsArray(getter_AddRefs(instsToReload));
|
2010-07-20 02:11:26 +00:00
|
|
|
DestroyRunningInstances(instsToReload, aPluginTag);
|
2007-07-14 00:28:05 +00:00
|
|
|
|
|
|
|
PRUint32 c;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (instsToReload && NS_SUCCEEDED(instsToReload->Count(&c)) && c > 0) {
|
2007-07-14 00:28:05 +00:00
|
|
|
nsCOMPtr<nsIRunnable> ev = new nsPluginDocReframeEvent(instsToReload);
|
|
|
|
if (ev)
|
|
|
|
NS_DispatchToCurrentThread(ev);
|
|
|
|
}
|
2007-07-03 21:42:35 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::WritePluginInfo()
|
2002-08-14 22:31:59 +00:00
|
|
|
{
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2007-07-26 07:01:22 +00:00
|
|
|
directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
|
2003-05-27 21:14:55 +00:00
|
|
|
getter_AddRefs(mPluginRegFile));
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
if (!mPluginRegFile)
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PRFileDesc* fd = nsnull;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsIFile> pluginReg;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = mPluginRegFile->Clone(getter_AddRefs(pluginReg));
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2011-03-27 21:40:59 +00:00
|
|
|
nsCAutoString filename(kPluginRegistryFilename);
|
|
|
|
filename.Append(".tmp");
|
|
|
|
rv = pluginReg->AppendNative(filename);
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(pluginReg, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = localFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0600, &fd);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
|
|
|
|
if (!runtime) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCAutoString arch;
|
|
|
|
rv = runtime->GetXPCOMABI(arch);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PR_fprintf(fd, "Generated File. Do not edit.\n");
|
2001-02-02 23:48:17 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
PR_fprintf(fd, "\n[HEADER]\nVersion%c%s%c%c\nArch%c%s%c%c\n",
|
2002-08-14 22:31:59 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-30 00:38:56 +00:00
|
|
|
kPluginRegistryVersion,
|
2002-08-14 22:31:59 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2010-12-09 22:28:15 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
arch.get(),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2002-07-23 02:18:44 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// Store all plugins in the mPlugins list - all plugins currently in use.
|
2002-08-30 00:38:56 +00:00
|
|
|
PR_fprintf(fd, "\n[PLUGINS]\n");
|
2002-02-13 02:18:57 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsPluginTag *taglist[] = {mPlugins, mCachedPlugins};
|
2002-08-22 22:59:43 +00:00
|
|
|
for (int i=0; i<(int)(sizeof(taglist)/sizeof(nsPluginTag *)); i++) {
|
2002-08-14 22:31:59 +00:00
|
|
|
for (nsPluginTag *tag = taglist[i]; tag; tag=tag->mNext) {
|
|
|
|
// from mCachedPlugins list write down only unwanted plugins
|
2005-11-06 18:34:03 +00:00
|
|
|
if ((taglist[i] == mCachedPlugins) && !tag->HasFlag(NS_PLUGIN_FLAG_UNWANTED))
|
2002-08-14 22:31:59 +00:00
|
|
|
continue;
|
|
|
|
// store each plugin info into the registry
|
2002-08-30 00:38:56 +00:00
|
|
|
// filename & fullpath are on separate line
|
|
|
|
// because they can contain field delimiter char
|
2008-07-15 10:50:42 +00:00
|
|
|
PR_fprintf(fd, "%s%c%c\n%s%c%c\n%s%c%c\n",
|
2008-03-10 07:07:15 +00:00
|
|
|
(!tag->mFileName.IsEmpty() ? tag->mFileName.get() : ""),
|
2002-08-14 22:31:59 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
2008-03-10 07:07:15 +00:00
|
|
|
(!tag->mFullPath.IsEmpty() ? tag->mFullPath.get() : ""),
|
2002-08-14 22:31:59 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2008-07-15 10:50:42 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
|
|
|
(!tag->mVersion.IsEmpty() ? tag->mVersion.get() : ""),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
|
|
|
|
|
|
|
// lastModifiedTimeStamp|canUnload|tag->mFlags
|
|
|
|
PR_fprintf(fd, "%lld%c%d%c%lu%c%c\n",
|
|
|
|
tag->mLastModifiedTime,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
tag->mCanUnloadLibrary,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2005-11-06 18:34:03 +00:00
|
|
|
tag->Flags(),
|
2002-08-30 00:38:56 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-22 22:59:43 +00:00
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
//description, name & mtypecount are on separate line
|
2004-10-11 04:01:49 +00:00
|
|
|
PR_fprintf(fd, "%s%c%c\n%s%c%c\n%d\n",
|
2008-03-10 07:07:15 +00:00
|
|
|
(!tag->mDescription.IsEmpty() ? tag->mDescription.get() : ""),
|
2002-08-22 22:59:43 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
2008-03-10 07:07:15 +00:00
|
|
|
(!tag->mName.IsEmpty() ? tag->mName.get() : ""),
|
2002-08-22 22:59:43 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
|
2007-10-10 01:24:28 +00:00
|
|
|
tag->mVariants + (tag->mIsNPRuntimeEnabledJavaPlugin ? 1 : 0));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// Add in each mimetype this plugin supports
|
|
|
|
for (int i=0; i<tag->mVariants; i++) {
|
2002-08-22 22:59:43 +00:00
|
|
|
PR_fprintf(fd, "%d%c%s%c%s%c%s%c%c\n",
|
2002-08-14 22:31:59 +00:00
|
|
|
i,PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2002-08-22 22:59:43 +00:00
|
|
|
(tag->mMimeTypeArray && tag->mMimeTypeArray[i] ? tag->mMimeTypeArray[i] : ""),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
2008-03-10 07:07:15 +00:00
|
|
|
(!tag->mMimeDescriptionArray[i].IsEmpty() ? tag->mMimeDescriptionArray[i].get() : ""),
|
2002-08-22 22:59:43 +00:00
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
(tag->mExtensionsArray && tag->mExtensionsArray[i] ? tag->mExtensionsArray[i] : ""),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
2002-08-14 22:31:59 +00:00
|
|
|
}
|
2007-10-10 01:24:28 +00:00
|
|
|
|
|
|
|
if (tag->mIsNPRuntimeEnabledJavaPlugin) {
|
|
|
|
PR_fprintf(fd, "%d%c%s%c%s%c%s%c%c\n",
|
|
|
|
tag->mVariants, PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
"application/x-java-vm-npruntime",
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
"",
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
"",
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
2010-12-09 22:28:15 +00:00
|
|
|
|
|
|
|
PR_fprintf(fd, "\n[INVALID]\n");
|
|
|
|
|
|
|
|
nsRefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
|
|
|
|
while (invalidPlugins) {
|
|
|
|
// fullPath
|
|
|
|
PR_fprintf(fd, "%s%c%c\n",
|
|
|
|
(!invalidPlugins->mFullPath.IsEmpty() ? invalidPlugins->mFullPath.get() : ""),
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
|
|
|
|
|
|
|
// lastModifiedTimeStamp
|
|
|
|
PR_fprintf(fd, "%lld%c%c\n",
|
|
|
|
invalidPlugins->mLastModifiedTime,
|
|
|
|
PLUGIN_REGISTRY_FIELD_DELIMITER,
|
|
|
|
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
|
|
|
|
|
|
|
|
invalidPlugins = invalidPlugins->mNext;
|
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2011-03-27 21:40:59 +00:00
|
|
|
PR_Close(fd);
|
|
|
|
nsCOMPtr<nsIFile> parent;
|
|
|
|
rv = localFile->GetParent(getter_AddRefs(parent));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = localFile->MoveToNative(parent, kPluginRegistryFilename);
|
|
|
|
return rv;
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
#define PLUGIN_REG_MIMETYPES_ARRAY_SIZE 12
|
2001-10-18 12:26:23 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::ReadPluginInfo()
|
2001-10-18 12:26:23 +00:00
|
|
|
{
|
2002-08-14 22:31:59 +00:00
|
|
|
nsresult rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID,&rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2007-07-26 07:01:22 +00:00
|
|
|
directoryService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
|
2003-05-27 21:14:55 +00:00
|
|
|
getter_AddRefs(mPluginRegFile));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-09-22 07:46:32 +00:00
|
|
|
if (!mPluginRegFile) {
|
|
|
|
// There is no profile yet, this will tell us if there is going to be one
|
|
|
|
// in the future.
|
|
|
|
directoryService->Get(NS_APP_PROFILE_DIR_STARTUP, NS_GET_IID(nsIFile),
|
|
|
|
getter_AddRefs(mPluginRegFile));
|
|
|
|
if (!mPluginRegFile)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
else
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PRFileDesc* fd = nsnull;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsIFile> pluginReg;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = mPluginRegFile->Clone(getter_AddRefs(pluginReg));
|
2002-08-14 22:31:59 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = pluginReg->AppendNative(kPluginRegistryFilename);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(pluginReg, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PRInt64 fileSize;
|
|
|
|
rv = localFile->GetFileSize(&fileSize);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2011-04-01 16:23:48 +00:00
|
|
|
PRInt32 flen = nsInt64(fileSize);
|
2002-08-14 22:31:59 +00:00
|
|
|
if (flen == 0) {
|
|
|
|
NS_WARNING("Plugins Registry Empty!");
|
|
|
|
return NS_OK; // ERROR CONDITION
|
|
|
|
}
|
2002-06-26 04:32:49 +00:00
|
|
|
|
2002-08-26 21:20:31 +00:00
|
|
|
nsPluginManifestLineReader reader;
|
2002-08-14 22:31:59 +00:00
|
|
|
char* registry = reader.Init(flen);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!registry)
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = localFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
// set rv to return an error on goto out
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = NS_ERROR_FAILURE;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PRInt32 bread = PR_Read(fd, registry, flen);
|
|
|
|
PR_Close(fd);
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
if (flen > bread)
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!ReadSectionHeader(reader, "HEADER"))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!reader.NextLine())
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
char* values[6];
|
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
// VersionLiteral, kPluginRegistryVersion
|
2008-11-03 19:23:07 +00:00
|
|
|
if (2 != reader.ParseLine(values, 2))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// VersionLiteral
|
2008-11-03 19:23:07 +00:00
|
|
|
if (PL_strcmp(values[0], "Version"))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
// kPluginRegistryVersion
|
2008-11-02 15:49:03 +00:00
|
|
|
PRInt32 vdiff = NS_CompareVersions(values[1], kPluginRegistryVersion);
|
|
|
|
// If this is a registry from some future version then don't attempt to read it
|
2008-11-03 19:23:07 +00:00
|
|
|
if (vdiff > 0)
|
2008-11-02 15:49:03 +00:00
|
|
|
return rv;
|
|
|
|
// If this is a registry from before the minimum then don't attempt to read it
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_CompareVersions(values[1], kMinimumRegistryVersion) < 0)
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2008-11-02 15:49:03 +00:00
|
|
|
// Registry v0.10 and upwards includes the plugin version field
|
|
|
|
PRBool regHasVersion = NS_CompareVersions(values[1], "0.10") >= 0;
|
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
// Registry v0.13 and upwards includes the architecture
|
|
|
|
if (NS_CompareVersions(values[1], "0.13") >= 0) {
|
|
|
|
char* archValues[6];
|
|
|
|
|
|
|
|
if (!reader.NextLine()) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ArchLiteral, Architecture
|
|
|
|
if (2 != reader.ParseLine(archValues, 2)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ArchLiteral
|
|
|
|
if (PL_strcmp(archValues[0], "Arch")) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
|
|
|
|
if (!runtime) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCAutoString arch;
|
|
|
|
if (NS_FAILED(runtime->GetXPCOMABI(arch))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is a registry from a different architecture then don't attempt to read it
|
|
|
|
if (PL_strcmp(archValues[1], arch.get())) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Registry v0.13 and upwards includes the list of invalid plugins
|
|
|
|
bool hasInvalidPlugins = (NS_CompareVersions(values[1], "0.13") >= 0);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!ReadSectionHeader(reader, "PLUGINS"))
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2009-06-10 20:47:49 +00:00
|
|
|
#if defined(XP_MACOSX)
|
|
|
|
PRBool hasFullPathInFileNameField = PR_FALSE;
|
|
|
|
#else
|
|
|
|
PRBool hasFullPathInFileNameField = (NS_CompareVersions(values[1], "0.11") < 0);
|
|
|
|
#endif
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
while (reader.NextLine()) {
|
2009-06-10 20:47:49 +00:00
|
|
|
const char *filename;
|
|
|
|
const char *fullpath;
|
|
|
|
nsCAutoString derivedFileName;
|
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
if (hasInvalidPlugins && *reader.LinePtr() == '[') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-06-10 20:47:49 +00:00
|
|
|
if (hasFullPathInFileNameField) {
|
|
|
|
fullpath = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
|
|
|
// try to derive a file name from the full path
|
|
|
|
if (fullpath) {
|
|
|
|
nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
|
|
|
file->InitWithNativePath(nsDependentCString(fullpath));
|
|
|
|
file->GetNativeLeafName(derivedFileName);
|
|
|
|
filename = derivedFileName.get();
|
|
|
|
} else {
|
|
|
|
filename = NULL;
|
|
|
|
}
|
2002-08-30 00:38:56 +00:00
|
|
|
|
2009-06-10 20:47:49 +00:00
|
|
|
// skip the next line, useless in this version
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
|
|
|
} else {
|
|
|
|
filename = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
fullpath = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
|
|
|
}
|
2002-08-22 22:59:43 +00:00
|
|
|
|
2009-03-10 23:21:40 +00:00
|
|
|
const char *version;
|
2008-11-02 15:49:03 +00:00
|
|
|
if (regHasVersion) {
|
|
|
|
version = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
2008-11-02 15:49:03 +00:00
|
|
|
version = "0";
|
|
|
|
}
|
2008-07-15 10:50:42 +00:00
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
// lastModifiedTimeStamp|canUnload|tag.mFlag
|
2008-11-03 19:23:07 +00:00
|
|
|
if (reader.ParseLine(values, 3) != 3)
|
2002-08-30 00:38:56 +00:00
|
|
|
return rv;
|
|
|
|
|
2008-11-02 15:49:03 +00:00
|
|
|
// If this is an old plugin registry mark this plugin tag to be refreshed
|
2009-06-10 20:47:49 +00:00
|
|
|
PRInt64 lastmod = (vdiff == 0) ? nsCRT::atoll(values[0]) : -1;
|
2002-08-30 00:38:56 +00:00
|
|
|
PRBool canunload = atoi(values[1]);
|
|
|
|
PRUint32 tagflag = atoi(values[2]);
|
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
|
|
|
|
2009-03-10 23:21:40 +00:00
|
|
|
const char *description = reader.LinePtr();
|
2002-08-14 22:31:59 +00:00
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2002-08-22 22:59:43 +00:00
|
|
|
|
2009-03-10 23:21:40 +00:00
|
|
|
const char *name = reader.LinePtr();
|
2002-08-14 22:31:59 +00:00
|
|
|
if (!reader.NextLine())
|
2002-08-30 00:38:56 +00:00
|
|
|
return rv;
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
int mimetypecount = atoi(reader.LinePtr());
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
char *stackalloced[PLUGIN_REG_MIMETYPES_ARRAY_SIZE * 3];
|
2002-08-14 22:31:59 +00:00
|
|
|
char **mimetypes;
|
|
|
|
char **mimedescriptions;
|
|
|
|
char **extensions;
|
|
|
|
char **heapalloced = 0;
|
2002-08-30 00:38:56 +00:00
|
|
|
if (mimetypecount > PLUGIN_REG_MIMETYPES_ARRAY_SIZE - 1) {
|
2002-08-14 22:31:59 +00:00
|
|
|
heapalloced = new char *[mimetypecount * 3];
|
|
|
|
mimetypes = heapalloced;
|
|
|
|
} else {
|
|
|
|
mimetypes = stackalloced;
|
|
|
|
}
|
|
|
|
mimedescriptions = mimetypes + mimetypecount;
|
|
|
|
extensions = mimedescriptions + mimetypecount;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
int mtr = 0; //mimetype read
|
|
|
|
for (; mtr < mimetypecount; mtr++) {
|
|
|
|
if (!reader.NextLine())
|
|
|
|
break;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
//line number|mimetype|description|extension
|
|
|
|
if (4 != reader.ParseLine(values, 4))
|
|
|
|
break;
|
|
|
|
int line = atoi(values[0]);
|
|
|
|
if (line != mtr)
|
2004-10-11 04:01:49 +00:00
|
|
|
break;
|
2002-08-14 22:31:59 +00:00
|
|
|
mimetypes[mtr] = values[1];
|
|
|
|
mimedescriptions[mtr] = values[2];
|
|
|
|
extensions[mtr] = values[3];
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
if (mtr != mimetypecount) {
|
|
|
|
if (heapalloced) {
|
|
|
|
delete [] heapalloced;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> tag = new nsPluginTag(name,
|
2002-08-14 22:31:59 +00:00
|
|
|
description,
|
|
|
|
filename,
|
2009-06-10 20:47:49 +00:00
|
|
|
fullpath,
|
2008-07-15 10:50:42 +00:00
|
|
|
version,
|
2002-08-14 22:31:59 +00:00
|
|
|
(const char* const*)mimetypes,
|
|
|
|
(const char* const*)mimedescriptions,
|
|
|
|
(const char* const*)extensions,
|
2008-03-10 07:07:15 +00:00
|
|
|
mimetypecount, lastmod, canunload, PR_TRUE);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (heapalloced)
|
2002-08-14 22:31:59 +00:00
|
|
|
delete [] heapalloced;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!tag)
|
2001-10-18 12:26:23 +00:00
|
|
|
continue;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// Mark plugin as loaded from cache
|
|
|
|
tag->Mark(tagflag | NS_PLUGIN_FLAG_FROMCACHE);
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
|
2008-03-13 00:26:18 +00:00
|
|
|
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName.get()));
|
2002-08-14 22:31:59 +00:00
|
|
|
tag->mNext = mCachedPlugins;
|
|
|
|
mCachedPlugins = tag;
|
2010-12-09 22:28:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hasInvalidPlugins) {
|
|
|
|
if (!ReadSectionHeader(reader, "INVALID")) {
|
|
|
|
return rv;
|
|
|
|
}
|
2010-12-20 23:38:10 +00:00
|
|
|
|
2010-12-09 22:28:15 +00:00
|
|
|
while (reader.NextLine()) {
|
|
|
|
const char *fullpath = reader.LinePtr();
|
|
|
|
if (!reader.NextLine()) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *lastModifiedTimeStamp = reader.LinePtr();
|
|
|
|
PRInt64 lastmod = (vdiff == 0) ? nsCRT::atoll(lastModifiedTimeStamp) : -1;
|
|
|
|
|
|
|
|
nsRefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(fullpath, lastmod);
|
|
|
|
|
|
|
|
invalidTag->mNext = mInvalidPlugins;
|
|
|
|
if (mInvalidPlugins) {
|
|
|
|
mInvalidPlugins->mPrev = invalidTag;
|
|
|
|
}
|
|
|
|
mInvalidPlugins = invalidTag;
|
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
void
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::RemoveCachedPluginsInfo(const char *filePath, nsPluginTag **result)
|
2001-10-18 12:26:23 +00:00
|
|
|
{
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> prev;
|
|
|
|
nsRefPtr<nsPluginTag> tag = mCachedPlugins;
|
|
|
|
while (tag)
|
2001-10-18 12:26:23 +00:00
|
|
|
{
|
2009-06-10 20:47:49 +00:00
|
|
|
if (tag->mFullPath.Equals(filePath)) {
|
2001-10-18 12:26:23 +00:00
|
|
|
// Found it. Remove it from our list
|
2007-07-03 21:42:35 +00:00
|
|
|
if (prev)
|
|
|
|
prev->mNext = tag->mNext;
|
|
|
|
else
|
|
|
|
mCachedPlugins = tag->mNext;
|
|
|
|
tag->mNext = nsnull;
|
|
|
|
*result = tag;
|
|
|
|
NS_ADDREF(*result);
|
|
|
|
break;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
2007-07-03 21:42:35 +00:00
|
|
|
prev = tag;
|
|
|
|
tag = tag->mNext;
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-20 20:34:51 +00:00
|
|
|
#ifdef XP_WIN
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::EnsurePrivateDirServiceProvider()
|
2001-11-17 15:26:02 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mPrivateDirServiceProvider) {
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
2003-05-27 21:14:55 +00:00
|
|
|
mPrivateDirServiceProvider = new nsPluginDirServiceProvider();
|
|
|
|
if (!mPrivateDirServiceProvider)
|
2001-11-17 15:26:02 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
nsCOMPtr<nsIDirectoryService> dirService(do_GetService(kDirectoryServiceContractID, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = dirService->RegisterProvider(mPrivateDirServiceProvider);
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-07-20 20:34:51 +00:00
|
|
|
#endif /* XP_WIN */
|
2001-11-17 15:26:02 +00:00
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::NewPluginURLStream(const nsString& aURL,
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance *aInstance,
|
2009-07-02 05:48:08 +00:00
|
|
|
nsIPluginStreamListener* aListener,
|
2009-12-27 20:26:00 +00:00
|
|
|
nsIInputStream *aPostStream,
|
2009-07-02 05:48:08 +00:00
|
|
|
const char *aHeadersData,
|
|
|
|
PRUint32 aHeadersDataLen)
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2000-06-16 22:27:16 +00:00
|
|
|
nsCOMPtr<nsIURI> url;
|
2001-04-17 23:30:25 +00:00
|
|
|
nsAutoString absUrl;
|
2000-04-22 20:50:22 +00:00
|
|
|
nsresult rv;
|
2001-01-16 22:53:39 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
if (aURL.Length() <= 0)
|
|
|
|
return NS_OK;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2000-06-16 22:27:16 +00:00
|
|
|
// get the full URL of the document that the plugin is embedded
|
|
|
|
// in to create an absolute url in case aURL is relative
|
2000-07-13 02:44:14 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
2007-04-05 01:56:32 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2009-06-29 18:53:52 +00:00
|
|
|
aInstance->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (owner) {
|
|
|
|
rv = owner->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (NS_SUCCEEDED(rv) && doc) {
|
|
|
|
// Create an absolute URL
|
2010-04-19 15:40:15 +00:00
|
|
|
rv = NS_MakeAbsoluteURI(absUrl, aURL, doc->GetDocBaseURI());
|
2000-06-16 22:27:16 +00:00
|
|
|
}
|
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2000-06-16 22:27:16 +00:00
|
|
|
if (absUrl.IsEmpty())
|
|
|
|
absUrl.Assign(aURL);
|
|
|
|
|
|
|
|
rv = NS_NewURI(getter_AddRefs(url), absUrl);
|
2009-10-29 00:29:44 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-06-16 22:27:16 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
nsCOMPtr<nsIPluginTagInfo> pti = do_QueryInterface(owner);
|
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
|
|
|
if (pti)
|
|
|
|
pti->GetDOMElement(getter_AddRefs(element));
|
|
|
|
|
|
|
|
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
|
|
|
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OBJECT_SUBREQUEST,
|
|
|
|
url,
|
|
|
|
(doc ? doc->NodePrincipal() : nsnull),
|
|
|
|
element,
|
|
|
|
EmptyCString(), //mime guess
|
|
|
|
nsnull, //extra
|
|
|
|
&shouldLoad);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
if (NS_CP_REJECTED(shouldLoad)) {
|
|
|
|
// Disallowed by content policy
|
|
|
|
return NS_ERROR_CONTENT_BLOCKED;
|
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
nsRefPtr<nsPluginStreamListenerPeer> listenerPeer = new nsPluginStreamListenerPeer();
|
2010-07-16 19:55:54 +00:00
|
|
|
if (!listenerPeer)
|
2009-10-29 00:29:44 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2000-07-13 02:44:14 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
rv = listenerPeer->Initialize(url, aInstance, aListener);
|
2009-12-27 20:26:00 +00:00
|
|
|
if (NS_FAILED(rv))
|
2009-10-29 00:29:44 +00:00
|
|
|
return rv;
|
2000-07-13 02:44:14 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
|
|
rv = NS_NewChannel(getter_AddRefs(channel), url, nsnull,
|
|
|
|
nsnull, /* do not add this internal plugin's channel
|
|
|
|
on the load group otherwise this channel could be canceled
|
|
|
|
form |nsDocShell::OnLinkClickSync| bug 166613 */
|
2010-11-17 19:25:48 +00:00
|
|
|
listenerPeer);
|
2009-10-29 00:29:44 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
if (doc) {
|
|
|
|
// Set the owner of channel to the document principal...
|
|
|
|
channel->SetOwner(doc->NodePrincipal());
|
|
|
|
|
|
|
|
// And if it's a script allow it to execute against the
|
|
|
|
// document's script context.
|
|
|
|
nsCOMPtr<nsIScriptChannel> scriptChannel(do_QueryInterface(channel));
|
|
|
|
if (scriptChannel) {
|
|
|
|
scriptChannel->SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
|
|
|
|
// Plug-ins seem to depend on javascript: URIs running synchronously
|
|
|
|
scriptChannel->SetExecuteAsync(PR_FALSE);
|
|
|
|
}
|
|
|
|
}
|
2001-12-12 01:38:02 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
// deal with headers and post data
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
|
|
|
if (httpChannel) {
|
2009-12-27 20:26:00 +00:00
|
|
|
if (aPostStream) {
|
2009-10-29 00:29:44 +00:00
|
|
|
// XXX it's a bit of a hack to rewind the postdata stream
|
|
|
|
// here but it has to be done in case the post data is
|
|
|
|
// being reused multiple times.
|
|
|
|
nsCOMPtr<nsISeekableStream>
|
2009-12-27 20:26:00 +00:00
|
|
|
postDataSeekable(do_QueryInterface(aPostStream));
|
2009-10-29 00:29:44 +00:00
|
|
|
if (postDataSeekable)
|
|
|
|
postDataSeekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
2001-09-05 03:52:26 +00:00
|
|
|
|
2009-10-29 00:29:44 +00:00
|
|
|
nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
|
|
|
|
NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel");
|
2001-04-17 23:30:25 +00:00
|
|
|
|
2009-12-27 20:26:00 +00:00
|
|
|
uploadChannel->SetUploadStream(aPostStream, EmptyCString(), -1);
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
2009-10-29 00:29:44 +00:00
|
|
|
|
|
|
|
if (aHeadersData)
|
|
|
|
rv = AddHeadersToChannel(aHeadersData, aHeadersDataLen, httpChannel);
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
2009-10-29 00:29:44 +00:00
|
|
|
rv = channel->AsyncOpen(listenerPeer, nsnull);
|
2011-02-23 15:47:25 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
listenerPeer->TrackRequest(channel);
|
1998-08-05 04:21:36 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by GetURL and PostURL
|
2003-04-03 19:11:41 +00:00
|
|
|
nsresult
|
2010-07-16 19:55:54 +00:00
|
|
|
nsPluginHost::DoURLLoadSecurityCheck(nsNPAPIPluginInstance *aInstance,
|
|
|
|
const char* aURL)
|
2003-04-03 19:11:41 +00:00
|
|
|
{
|
|
|
|
if (!aURL || *aURL == '\0')
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// get the URL of the document that loaded the plugin
|
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2009-06-29 18:53:52 +00:00
|
|
|
aInstance->GetOwner(getter_AddRefs(owner));
|
2003-04-03 19:11:41 +00:00
|
|
|
if (!owner)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2009-06-29 18:53:52 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
owner->GetDocument(getter_AddRefs(doc));
|
2003-04-03 19:11:41 +00:00
|
|
|
if (!doc)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// Create an absolute URL for the target in case the target is relative
|
|
|
|
nsCOMPtr<nsIURI> targetURL;
|
2010-04-19 15:40:15 +00:00
|
|
|
NS_NewURI(getter_AddRefs(targetURL), aURL, doc->GetDocBaseURI());
|
2003-04-03 19:11:41 +00:00
|
|
|
if (!targetURL)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2009-06-29 18:53:52 +00:00
|
|
|
nsresult rv;
|
2003-04-03 19:11:41 +00:00
|
|
|
nsCOMPtr<nsIScriptSecurityManager> secMan(
|
|
|
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2006-04-27 18:21:11 +00:00
|
|
|
return secMan->CheckLoadURIWithPrincipal(doc->NodePrincipal(), targetURL,
|
2004-04-25 16:55:27 +00:00
|
|
|
nsIScriptSecurityManager::STANDARD);
|
2003-04-03 19:11:41 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-06-25 21:06:54 +00:00
|
|
|
nsresult
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::AddHeadersToChannel(const char *aHeadersData,
|
|
|
|
PRUint32 aHeadersDataLen,
|
|
|
|
nsIChannel *aGenericChannel)
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2001-05-11 21:05:08 +00:00
|
|
|
nsCOMPtr<nsIHttpChannel> aChannel = do_QueryInterface(aGenericChannel);
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
if (!aChannel) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
// used during the manipulation of the String from the aHeadersData
|
|
|
|
nsCAutoString headersString;
|
|
|
|
nsCAutoString oneHeader;
|
|
|
|
nsCAutoString headerName;
|
|
|
|
nsCAutoString headerValue;
|
2001-01-30 20:39:55 +00:00
|
|
|
PRInt32 crlf = 0;
|
|
|
|
PRInt32 colon = 0;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
// Turn the char * buffer into an nsString.
|
|
|
|
headersString = aHeadersData;
|
|
|
|
|
2005-02-05 00:49:25 +00:00
|
|
|
// Iterate over the nsString: for each "\r\n" delimited chunk,
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
// add the value as a header to the nsIHTTPChannel
|
|
|
|
while (PR_TRUE) {
|
|
|
|
crlf = headersString.Find("\r\n", PR_TRUE);
|
|
|
|
if (-1 == crlf) {
|
|
|
|
rv = NS_OK;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
headersString.Mid(oneHeader, 0, crlf);
|
|
|
|
headersString.Cut(0, crlf + 2);
|
|
|
|
oneHeader.StripWhitespace();
|
|
|
|
colon = oneHeader.Find(":");
|
|
|
|
if (-1 == colon) {
|
|
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
oneHeader.Left(headerName, colon);
|
|
|
|
colon++;
|
|
|
|
oneHeader.Mid(headerValue, colon, oneHeader.Length() - colon);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
// FINALLY: we can set the header!
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-11-22 07:40:16 +00:00
|
|
|
rv = aChannel->SetRequestHeader(headerName, headerValue, PR_TRUE);
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
|
|
return rv;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
}
|
r=av
a=waterson
bug=51919
This fix makes it so nsIPluginManager::PostURL() works correctly in the
case of a null target and non-null streamListener.
The fix was to add parameters to NewPluginURLStream() for headers and
post data:
NS_IMETHOD
- NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance, nsIPluginStreamListener *aListener);
+ NewPluginURLStream(const nsString& aURL, nsIPluginInstance *aInstance,
+ nsIPluginStreamListener *aListener,
+ void *aPostData = nsnull, PRUint32 aPostDataLen = 0,
+ const char *aHeadersData = nsnull,
+ PRUint32 aHeadersDataLen = 0);
And to add a new method to correctly send the headers to the channel:
+ NS_IMETHOD
+ AddHeadersToChannel(const char *aHeadersData, PRUint32 aHeadersDataLen,
+ nsIChannel *aGenericChannel);
Files in this fix:
M modules/plugin/nglsrc/nsPluginHostImpl.cpp
M modules/plugin/nglsrc/nsPluginHostImpl.h
2000-09-08 23:58:36 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1999-06-04 22:32:27 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::StopPluginInstance(nsIPluginInstance* aInstance)
|
1999-06-04 22:32:27 +00:00
|
|
|
{
|
2008-02-29 02:06:00 +00:00
|
|
|
if (PluginDestructionGuard::DelayDestroy(aInstance)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2009-07-02 05:48:08 +00:00
|
|
|
("nsPluginHost::StopPluginInstance called instance=%p\n",aInstance));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2010-12-24 02:14:04 +00:00
|
|
|
nsNPAPIPluginInstance* instance = static_cast<nsNPAPIPluginInstance*>(aInstance);
|
2010-12-20 01:37:43 +00:00
|
|
|
if (instance->HasStartedDestroying())
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
aInstance->Stop();
|
2010-12-24 02:14:04 +00:00
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
// if the plugin does not want to be 'cached' just remove it
|
|
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
aInstance->ShouldCache(&doCache);
|
|
|
|
if (doCache) {
|
|
|
|
// try to get the max cached plugins from a pref or use default
|
|
|
|
PRUint32 cachedPluginLimit;
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
if (mPrefService)
|
|
|
|
rv = mPrefService->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS, (int*)&cachedPluginLimit);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
cachedPluginLimit = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
|
|
|
|
|
|
|
|
if (StoppedInstanceCount() >= cachedPluginLimit) {
|
|
|
|
nsNPAPIPluginInstance *oldestInstance = FindOldestStoppedInstance();
|
|
|
|
if (oldestInstance) {
|
|
|
|
nsPluginTag* pluginTag = TagForPlugin(oldestInstance->GetPlugin());
|
|
|
|
oldestInstance->Destroy();
|
|
|
|
mInstances.RemoveElement(oldestInstance);
|
|
|
|
OnPluginInstanceDestroyed(pluginTag);
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
2000-06-15 01:07:27 +00:00
|
|
|
}
|
2010-07-20 02:11:26 +00:00
|
|
|
} else {
|
|
|
|
nsPluginTag* pluginTag = TagForPlugin(instance->GetPlugin());
|
|
|
|
instance->Destroy();
|
|
|
|
mInstances.RemoveElement(instance);
|
|
|
|
OnPluginInstanceDestroyed(pluginTag);
|
2000-06-15 01:07:27 +00:00
|
|
|
}
|
2010-01-27 01:30:58 +00:00
|
|
|
|
1999-06-04 22:32:27 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::NewEmbeddedPluginStreamListener(nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner,
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance* aInstance,
|
2009-07-02 05:48:08 +00:00
|
|
|
nsIStreamListener** aListener)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
2002-04-25 21:28:06 +00:00
|
|
|
if (!aURL)
|
|
|
|
return NS_OK;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-07-16 19:55:54 +00:00
|
|
|
nsRefPtr<nsPluginStreamListenerPeer> listener = new nsPluginStreamListenerPeer();
|
|
|
|
if (!listener)
|
1999-07-30 23:51:53 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
nsresult rv;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
// if we have an instance, everything has been set up
|
|
|
|
// if we only have an owner, then we need to pass it in
|
|
|
|
// so the listener can set up the instance later after
|
|
|
|
// we've determined the mimetype of the stream
|
2010-07-16 19:55:54 +00:00
|
|
|
if (aInstance)
|
2005-06-08 23:42:15 +00:00
|
|
|
rv = listener->InitializeEmbedded(aURL, aInstance);
|
2008-11-03 19:23:07 +00:00
|
|
|
else if (aOwner != nsnull)
|
2010-01-27 01:30:58 +00:00
|
|
|
rv = listener->InitializeEmbedded(aURL, nsnull, aOwner);
|
2001-02-02 23:48:17 +00:00
|
|
|
else
|
|
|
|
rv = NS_ERROR_ILLEGAL_VALUE;
|
2005-09-21 19:14:30 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
NS_ADDREF(*aListener = listener);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by InstantiateEmbeddedPlugin()
|
2009-07-02 05:48:08 +00:00
|
|
|
nsresult nsPluginHost::NewEmbeddedPluginStream(nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner,
|
2010-07-16 19:55:54 +00:00
|
|
|
nsNPAPIPluginInstance* aInstance)
|
2005-09-21 19:14:30 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIStreamListener> listener;
|
|
|
|
nsresult rv = NewEmbeddedPluginStreamListener(aURL, aOwner, aInstance,
|
|
|
|
getter_AddRefs(listener));
|
2002-04-12 05:59:26 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
|
|
|
if (aOwner) {
|
|
|
|
rv = aOwner->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (NS_SUCCEEDED(rv) && doc) {
|
2003-10-22 06:09:48 +00:00
|
|
|
loadGroup = doc->GetDocumentLoadGroup();
|
2002-04-12 05:59:26 +00:00
|
|
|
}
|
|
|
|
}
|
2002-08-12 06:18:52 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel;
|
2002-11-16 03:38:01 +00:00
|
|
|
rv = NS_NewChannel(getter_AddRefs(channel), aURL, nsnull, loadGroup, nsnull);
|
2002-08-12 06:18:52 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// if this is http channel, set referrer, some servers are configured
|
|
|
|
// to reject requests without referrer set, see bug 157796
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
2003-10-22 06:09:48 +00:00
|
|
|
if (httpChannel && doc)
|
2005-05-01 13:08:14 +00:00
|
|
|
httpChannel->SetReferrer(doc->GetDocumentURI());
|
2002-08-12 06:18:52 +00:00
|
|
|
|
|
|
|
rv = channel->AsyncOpen(listener, nsnull);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
1998-08-05 04:21:36 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
return rv;
|
1998-09-15 03:48:58 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by InstantiateFullPagePlugin()
|
2010-07-17 23:47:29 +00:00
|
|
|
nsresult nsPluginHost::NewFullPagePluginStream(nsIURI* aURI,
|
|
|
|
nsNPAPIPluginInstance *aInstance,
|
|
|
|
nsIStreamListener **aStreamListener)
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2010-07-17 23:47:29 +00:00
|
|
|
NS_ASSERTION(aStreamListener, "Stream listener out param cannot be null");
|
|
|
|
|
|
|
|
nsRefPtr<nsPluginStreamListenerPeer> listener = new nsPluginStreamListenerPeer();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!listener)
|
1999-07-30 23:51:53 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2010-07-17 23:47:29 +00:00
|
|
|
nsresult rv = listener->InitializeFullPage(aURI, aInstance);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2010-07-17 23:47:29 +00:00
|
|
|
listener.forget(aStreamListener);
|
2001-06-19 01:38:20 +00:00
|
|
|
|
2010-07-17 23:47:29 +00:00
|
|
|
return NS_OK;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
|
|
|
|
const char *aTopic,
|
|
|
|
const PRUnichar *someData)
|
2001-03-12 02:07:15 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!nsCRT::strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
|
2007-07-11 23:25:45 +00:00
|
|
|
OnShutdown();
|
2001-03-31 02:26:51 +00:00
|
|
|
Destroy();
|
2005-11-06 18:34:03 +00:00
|
|
|
sInst->Release();
|
|
|
|
}
|
2009-01-30 21:40:14 +00:00
|
|
|
if (!nsCRT::strcmp(NS_PRIVATE_BROWSING_SWITCH_TOPIC, aTopic)) {
|
2009-07-06 06:10:10 +00:00
|
|
|
// inform all active plugins of changed private mode state
|
2010-07-20 02:11:26 +00:00
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
mInstances[i]->PrivateModeStateChanged();
|
2009-01-30 21:40:14 +00:00
|
|
|
}
|
|
|
|
}
|
2001-03-12 02:07:15 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::HandleBadPlugin(PRLibrary* aLibrary, nsIPluginInstance *aInstance)
|
2000-09-14 06:03:37 +00:00
|
|
|
{
|
2002-09-26 02:53:27 +00:00
|
|
|
// the |aLibrary| parameter is not needed anymore, after we added |aInstance| which
|
|
|
|
// can also be used to look up the plugin name, but we cannot get rid of it because
|
|
|
|
// the |nsIPluginHost| interface is deprecated which in fact means 'frozen'
|
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
NS_ERROR("Plugin performed illegal operation");
|
|
|
|
NS_ENSURE_ARG_POINTER(aInstance);
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mDontShowBadPluginMessage)
|
2010-12-08 12:22:10 +00:00
|
|
|
return NS_OK;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2010-12-08 12:22:10 +00:00
|
|
|
aInstance->GetOwner(getter_AddRefs(owner));
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsCOMPtr<nsIPrompt> prompt;
|
|
|
|
GetPrompt(owner, getter_AddRefs(prompt));
|
2010-12-08 12:22:10 +00:00
|
|
|
if (!prompt)
|
|
|
|
return NS_OK;
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsCOMPtr<nsIStringBundleService> strings =
|
|
|
|
mozilla::services::GetStringBundleService();
|
|
|
|
if (!strings)
|
|
|
|
return NS_ERROR_FAILURE;
|
2005-01-13 12:46:52 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsCOMPtr<nsIStringBundle> bundle;
|
|
|
|
nsresult rv = strings->CreateBundle(BRAND_PROPERTIES_URL, getter_AddRefs(bundle));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2005-01-13 12:46:52 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsXPIDLString brandName;
|
|
|
|
rv = bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
|
|
|
|
getter_Copies(brandName));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
rv = strings->CreateBundle(PLUGIN_PROPERTIES_URL, getter_AddRefs(bundle));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsXPIDLString title, message, checkboxMessage;
|
|
|
|
rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginTitle").get(),
|
|
|
|
getter_Copies(title));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
const PRUnichar *formatStrings[] = { brandName.get() };
|
|
|
|
if (NS_FAILED(rv = bundle->FormatStringFromName(NS_LITERAL_STRING("BadPluginMessage").get(),
|
|
|
|
formatStrings, 1, getter_Copies(message))))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginCheckboxMessage").get(),
|
|
|
|
getter_Copies(checkboxMessage));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(aInstance);
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsNPAPIPlugin *plugin = instance->GetPlugin();
|
|
|
|
if (!plugin)
|
|
|
|
return NS_ERROR_FAILURE;
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
nsPluginTag *pluginTag = TagForPlugin(plugin);
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
// add plugin name to the message
|
|
|
|
nsCString pluginname;
|
2010-12-26 22:36:33 +00:00
|
|
|
if (pluginTag) {
|
|
|
|
if (!pluginTag->mName.IsEmpty()) {
|
|
|
|
pluginname = pluginTag->mName;
|
|
|
|
} else {
|
|
|
|
pluginname = pluginTag->mFileName;
|
|
|
|
}
|
2010-12-08 12:22:10 +00:00
|
|
|
} else {
|
2010-12-26 22:51:06 +00:00
|
|
|
pluginname.AppendLiteral("???");
|
2010-12-08 12:22:10 +00:00
|
|
|
}
|
2002-02-12 22:25:40 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
NS_ConvertUTF8toUTF16 msg(pluginname);
|
|
|
|
msg.AppendLiteral("\n\n");
|
|
|
|
msg.Append(message);
|
2002-02-12 22:25:40 +00:00
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
PRInt32 buttonPressed;
|
|
|
|
PRBool checkboxState = PR_FALSE;
|
|
|
|
rv = prompt->ConfirmEx(title, msg.get(),
|
|
|
|
nsIPrompt::BUTTON_TITLE_OK * nsIPrompt::BUTTON_POS_0,
|
|
|
|
nsnull, nsnull, nsnull,
|
|
|
|
checkboxMessage, &checkboxState, &buttonPressed);
|
2000-09-14 06:03:37 +00:00
|
|
|
|
|
|
|
|
2010-12-08 12:22:10 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && checkboxState)
|
|
|
|
mDontShowBadPluginMessage = PR_TRUE;
|
2000-09-14 23:58:17 +00:00
|
|
|
|
2000-09-14 06:03:37 +00:00
|
|
|
return rv;
|
|
|
|
}
|
2002-01-30 02:40:46 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::ParsePostBufferToFixHeaders(const char *inPostData, PRUint32 inPostDataLen,
|
|
|
|
char **outPostData, PRUint32 *outPostDataLen)
|
2002-01-30 02:40:46 +00:00
|
|
|
{
|
|
|
|
if (!inPostData || !outPostData || !outPostDataLen)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
*outPostData = 0;
|
|
|
|
*outPostDataLen = 0;
|
|
|
|
|
|
|
|
const char CR = '\r';
|
|
|
|
const char LF = '\n';
|
2004-10-11 04:01:49 +00:00
|
|
|
const char CRLFCRLF[] = {CR,LF,CR,LF,'\0'}; // C string"\r\n\r\n"
|
2002-01-30 02:40:46 +00:00
|
|
|
const char ContentLenHeader[] = "Content-length";
|
|
|
|
|
2009-03-28 13:57:13 +00:00
|
|
|
nsAutoTArray<const char*, 8> singleLF;
|
2002-01-30 02:40:46 +00:00
|
|
|
const char *pSCntlh = 0;// pointer to start of ContentLenHeader in inPostData
|
|
|
|
const char *pSod = 0; // pointer to start of data in inPostData
|
|
|
|
const char *pEoh = 0; // pointer to end of headers in inPostData
|
|
|
|
const char *pEod = inPostData + inPostDataLen; // pointer to end of inPostData
|
|
|
|
if (*inPostData == LF) {
|
|
|
|
// If no custom headers are required, simply add a blank
|
|
|
|
// line ('\n') to the beginning of the file or buffer.
|
|
|
|
// so *inPostData == '\n' is valid
|
|
|
|
pSod = inPostData + 1;
|
2004-10-11 04:01:49 +00:00
|
|
|
} else {
|
2002-01-30 02:40:46 +00:00
|
|
|
const char *s = inPostData; //tmp pointer to sourse inPostData
|
|
|
|
while (s < pEod) {
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!pSCntlh &&
|
|
|
|
(*s == 'C' || *s == 'c') &&
|
2002-01-30 02:40:46 +00:00
|
|
|
(s + sizeof(ContentLenHeader) - 1 < pEod) &&
|
|
|
|
(!PL_strncasecmp(s, ContentLenHeader, sizeof(ContentLenHeader) - 1)))
|
|
|
|
{
|
|
|
|
// lets assume this is ContentLenHeader for now
|
|
|
|
const char *p = pSCntlh = s;
|
|
|
|
p += sizeof(ContentLenHeader) - 1;
|
|
|
|
// search for first CR or LF == end of ContentLenHeader
|
|
|
|
for (; p < pEod; p++) {
|
|
|
|
if (*p == CR || *p == LF) {
|
2004-10-11 04:01:49 +00:00
|
|
|
// got delimiter,
|
|
|
|
// one more check; if previous char is a digit
|
2002-01-30 02:40:46 +00:00
|
|
|
// most likely pSCntlh points to the start of ContentLenHeader
|
|
|
|
if (*(p-1) >= '0' && *(p-1) <= '9') {
|
|
|
|
s = p;
|
|
|
|
}
|
|
|
|
break; //for loop
|
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
if (pSCntlh == s) { // curret ptr is the same
|
2002-01-30 02:40:46 +00:00
|
|
|
pSCntlh = 0; // that was not ContentLenHeader
|
|
|
|
break; // there is nothing to parse, break *WHILE LOOP* here
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*s == CR) {
|
|
|
|
if (pSCntlh && // only if ContentLenHeader is found we are looking for end of headers
|
|
|
|
((s + sizeof(CRLFCRLF)-1) <= pEod) &&
|
|
|
|
!memcmp(s, CRLFCRLF, sizeof(CRLFCRLF)-1))
|
|
|
|
{
|
|
|
|
s += sizeof(CRLFCRLF)-1;
|
|
|
|
pEoh = pSod = s; // data stars here
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (*s == LF) {
|
|
|
|
if (*(s-1) != CR) {
|
2009-03-28 13:57:13 +00:00
|
|
|
singleLF.AppendElement(s);
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
|
|
|
if (pSCntlh && (s+1 < pEod) && (*(s+1) == LF)) {
|
|
|
|
s++;
|
2009-03-28 13:57:13 +00:00
|
|
|
singleLF.AppendElement(s);
|
2002-01-30 02:40:46 +00:00
|
|
|
s++;
|
|
|
|
pEoh = pSod = s; // data stars here
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// deal with output buffer
|
|
|
|
if (!pSod) { // lets assume whole buffer is a data
|
|
|
|
pSod = inPostData;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRUint32 newBufferLen = 0;
|
|
|
|
PRUint32 dataLen = pEod - pSod;
|
|
|
|
PRUint32 headersLen = pEoh ? pSod - inPostData : 0;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
char *p; // tmp ptr into new output buf
|
|
|
|
if (headersLen) { // we got a headers
|
2004-10-11 04:01:49 +00:00
|
|
|
// this function does not make any assumption on correctness
|
2002-01-30 02:40:46 +00:00
|
|
|
// of ContentLenHeader value in this case.
|
|
|
|
|
2002-02-07 23:22:39 +00:00
|
|
|
newBufferLen = dataLen + headersLen;
|
2002-01-30 02:40:46 +00:00
|
|
|
// in case there were single LFs in headers
|
|
|
|
// reserve an extra space for CR will be added before each single LF
|
2009-03-28 13:57:13 +00:00
|
|
|
int cntSingleLF = singleLF.Length();
|
2002-01-30 02:40:46 +00:00
|
|
|
newBufferLen += cntSingleLF;
|
|
|
|
|
|
|
|
if (!(*outPostData = p = (char*)nsMemory::Alloc(newBufferLen)))
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// deal with single LF
|
|
|
|
const char *s = inPostData;
|
|
|
|
if (cntSingleLF) {
|
|
|
|
for (int i=0; i<cntSingleLF; i++) {
|
2009-03-28 13:57:13 +00:00
|
|
|
const char *plf = singleLF.ElementAt(i); // ptr to single LF in headers
|
2002-01-30 02:40:46 +00:00
|
|
|
int n = plf - s; // bytes to copy
|
|
|
|
if (n) { // for '\n\n' there is nothing to memcpy
|
|
|
|
memcpy(p, s, n);
|
|
|
|
p += n;
|
|
|
|
}
|
|
|
|
*p++ = CR;
|
|
|
|
s = plf;
|
|
|
|
*p++ = *s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// are we done with headers?
|
|
|
|
headersLen = pEoh - s;
|
|
|
|
if (headersLen) { // not yet
|
|
|
|
memcpy(p, s, headersLen); // copy the rest
|
|
|
|
p += headersLen;
|
|
|
|
}
|
|
|
|
} else if (dataLen) { // no ContentLenHeader is found but there is a data
|
|
|
|
// make new output buffer big enough
|
|
|
|
// to keep ContentLenHeader+value followed by data
|
|
|
|
PRUint32 l = sizeof(ContentLenHeader) + sizeof(CRLFCRLF) + 32;
|
|
|
|
newBufferLen = dataLen + l;
|
|
|
|
if (!(*outPostData = p = (char*)nsMemory::Alloc(newBufferLen)))
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
headersLen = PR_snprintf(p, l,"%s: %ld%s", ContentLenHeader, dataLen, CRLFCRLF);
|
|
|
|
if (headersLen == l) { // if PR_snprintf has ate all extra space consider this as an error
|
|
|
|
nsMemory::Free(p);
|
|
|
|
*outPostData = 0;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
p += headersLen;
|
2002-04-25 21:28:06 +00:00
|
|
|
newBufferLen = headersLen + dataLen;
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
|
|
|
// at this point we've done with headers.
|
|
|
|
// there is a possibility that input buffer has only headers info in it
|
|
|
|
// which already parsed and copied into output buffer.
|
|
|
|
// copy the data
|
|
|
|
if (dataLen) {
|
|
|
|
memcpy(p, pSod, dataLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
*outPostDataLen = newBufferLen;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-12-27 20:26:00 +00:00
|
|
|
nsPluginHost::CreateTempFileToPost(const char *aPostDataURL, nsIFile **aTmpFile)
|
2002-01-30 02:40:46 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
PRInt64 fileSize;
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString filename;
|
2002-08-15 18:38:46 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
// stat file == get size & convert file:///c:/ to c: if needed
|
2002-08-15 18:38:46 +00:00
|
|
|
nsCOMPtr<nsIFile> inFile;
|
2009-12-27 20:26:00 +00:00
|
|
|
rv = NS_GetFileFromURLSpec(nsDependentCString(aPostDataURL),
|
2002-08-15 18:38:46 +00:00
|
|
|
getter_AddRefs(inFile));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
nsCOMPtr<nsILocalFile> localFile;
|
2009-12-27 20:26:00 +00:00
|
|
|
rv = NS_NewNativeLocalFile(nsDependentCString(aPostDataURL), PR_FALSE,
|
2002-08-15 18:38:46 +00:00
|
|
|
getter_AddRefs(localFile));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
inFile = localFile;
|
|
|
|
}
|
|
|
|
rv = inFile->GetFileSize(&fileSize);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = inFile->GetNativePath(filename);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
if (!LL_IS_ZERO(fileSize)) {
|
|
|
|
nsCOMPtr<nsIInputStream> inStream;
|
2002-04-25 21:28:06 +00:00
|
|
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), inFile);
|
2002-01-30 02:40:46 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
// Create a temporary file to write the http Content-length:
|
|
|
|
// %ld\r\n\" header and "\r\n" == end of headers for post data to
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
nsCOMPtr<nsIFile> tempFile;
|
|
|
|
rv = GetPluginTempDir(getter_AddRefs(tempFile));
|
2002-04-25 21:28:06 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString inFileName;
|
2002-05-07 23:07:19 +00:00
|
|
|
inFile->GetNativeLeafName(inFileName);
|
|
|
|
// XXX hack around bug 70083
|
|
|
|
inFileName.Insert(NS_LITERAL_CSTRING("post-"), 0);
|
|
|
|
rv = tempFile->AppendNative(inFileName);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rv))
|
2002-04-25 21:28:06 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-04-25 21:28:06 +00:00
|
|
|
// make it unique, and mode == 0600, not world-readable
|
2004-10-11 04:01:49 +00:00
|
|
|
rv = tempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
|
2002-04-25 21:28:06 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
nsCOMPtr<nsIOutputStream> outStream;
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream),
|
|
|
|
tempFile,
|
|
|
|
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
|
|
|
0600); // 600 so others can't read our form data
|
|
|
|
}
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Post data file couldn't be created!");
|
2002-04-25 21:28:06 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
char buf[1024];
|
2002-04-25 21:28:06 +00:00
|
|
|
PRUint32 br, bw;
|
|
|
|
PRBool firstRead = PR_TRUE;
|
2002-01-30 02:40:46 +00:00
|
|
|
while (1) {
|
|
|
|
// Read() mallocs if buffer is null
|
|
|
|
rv = inStream->Read(buf, 1024, &br);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv) || (PRInt32)br <= 0)
|
2002-04-25 21:28:06 +00:00
|
|
|
break;
|
|
|
|
if (firstRead) {
|
2004-10-11 04:01:49 +00:00
|
|
|
//"For protocols in which the headers must be distinguished from the body,
|
2002-04-25 21:28:06 +00:00
|
|
|
// such as HTTP, the buffer or file should contain the headers, followed by
|
2004-10-11 04:01:49 +00:00
|
|
|
// a blank line, then the body. If no custom headers are required, simply
|
2002-04-25 21:28:06 +00:00
|
|
|
// add a blank line ('\n') to the beginning of the file or buffer.
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-04-25 21:28:06 +00:00
|
|
|
char *parsedBuf;
|
|
|
|
// assuming first 1K (or what we got) has all headers in,
|
2009-07-02 05:48:08 +00:00
|
|
|
// lets parse it through nsPluginHost::ParsePostBufferToFixHeaders()
|
2002-04-25 21:28:06 +00:00
|
|
|
ParsePostBufferToFixHeaders((const char *)buf, br, &parsedBuf, &bw);
|
|
|
|
rv = outStream->Write(parsedBuf, bw, &br);
|
|
|
|
nsMemory::Free(parsedBuf);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv) || (bw != br))
|
2002-04-25 21:28:06 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
firstRead = PR_FALSE;
|
|
|
|
continue;
|
|
|
|
}
|
2002-01-30 02:40:46 +00:00
|
|
|
bw = br;
|
|
|
|
rv = outStream->Write(buf, bw, &br);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv) || (bw != br))
|
2002-04-25 21:28:06 +00:00
|
|
|
break;
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
2002-04-25 21:28:06 +00:00
|
|
|
|
2002-01-30 02:40:46 +00:00
|
|
|
inStream->Close();
|
|
|
|
outStream->Close();
|
2009-12-27 20:26:00 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
*aTmpFile = tempFile.forget().get();
|
2002-01-30 02:40:46 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
2002-05-01 02:01:50 +00:00
|
|
|
|
2002-09-26 02:53:27 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
|
2002-09-26 02:53:27 +00:00
|
|
|
{
|
|
|
|
return PLUG_NewPluginNativeWindow(aPluginNativeWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
|
2002-09-26 02:53:27 +00:00
|
|
|
{
|
|
|
|
return PLUG_DeletePluginNativeWindow(aPluginNativeWindow);
|
|
|
|
}
|
|
|
|
|
2007-10-10 01:24:28 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::InstantiateDummyJavaPlugin(nsIPluginInstanceOwner *aOwner)
|
2007-10-10 01:24:28 +00:00
|
|
|
{
|
|
|
|
// Pass PR_FALSE as the second arg, we want the answer to be the
|
|
|
|
// same here whether the Java plugin is enabled or not.
|
|
|
|
nsPluginTag *plugin = FindPluginForType("application/x-java-vm", PR_FALSE);
|
|
|
|
|
|
|
|
if (!plugin || !plugin->mIsNPRuntimeEnabledJavaPlugin) {
|
|
|
|
// No NPRuntime enabled Java plugin found, no point in
|
|
|
|
// instantiating a dummy plugin then.
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv = SetUpPluginInstance("application/x-java-vm", nsnull, aOwner);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPluginInstance> instance;
|
|
|
|
aOwner->GetInstance(*getter_AddRefs(instance));
|
2009-07-02 04:52:07 +00:00
|
|
|
if (!instance)
|
2007-10-10 01:24:28 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
2009-07-02 04:52:07 +00:00
|
|
|
instance->DefineJavaProperties();
|
2007-10-10 01:24:28 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-04-16 20:06:48 +00:00
|
|
|
NS_IMETHODIMP
|
2009-07-02 05:48:08 +00:00
|
|
|
nsPluginHost::GetPluginName(nsIPluginInstance *aPluginInstance,
|
|
|
|
const char** aPluginName)
|
2008-04-16 20:06:48 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(aPluginInstance);
|
|
|
|
if (!instance)
|
2010-01-27 01:30:58 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPlugin* plugin = instance->GetPlugin();
|
|
|
|
if (!plugin)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aPluginName = TagForPlugin(plugin)->mName.get();
|
2010-01-27 01:30:58 +00:00
|
|
|
|
2008-04-16 20:06:48 +00:00
|
|
|
return NS_OK;
|
2009-10-02 11:26:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHost::GetPluginTagForInstance(nsIPluginInstance *aPluginInstance,
|
|
|
|
nsIPluginTag **aPluginTag)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aPluginInstance);
|
|
|
|
NS_ENSURE_ARG_POINTER(aPluginTag);
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(aPluginInstance);
|
|
|
|
nsNPAPIPlugin *plugin = instance->GetPlugin();
|
|
|
|
if (!plugin)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aPluginTag = TagForPlugin(plugin);
|
2010-01-29 19:42:54 +00:00
|
|
|
|
2010-02-03 01:18:37 +00:00
|
|
|
NS_ADDREF(*aPluginTag);
|
2009-10-02 11:26:04 +00:00
|
|
|
return NS_OK;
|
2008-04-16 20:06:48 +00:00
|
|
|
}
|
|
|
|
|
2009-12-15 20:44:52 +00:00
|
|
|
#ifdef MAC_CARBON_PLUGINS
|
|
|
|
// Flash requires a minimum of 8 events per second to avoid audio skipping.
|
|
|
|
// Since WebKit uses a hidden plugin event rate of 4 events per second Flash
|
|
|
|
// uses a Carbon timer for WebKit which fires at 8 events per second.
|
|
|
|
#define HIDDEN_PLUGIN_DELAY 125
|
|
|
|
#define VISIBLE_PLUGIN_DELAY 20
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void nsPluginHost::AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible)
|
|
|
|
{
|
|
|
|
#ifdef MAC_CARBON_PLUGINS
|
|
|
|
nsTObserverArray<nsIPluginInstanceOwner*> *targetArray;
|
|
|
|
if (isVisible) {
|
|
|
|
targetArray = &mVisibleTimerTargets;
|
|
|
|
} else {
|
|
|
|
targetArray = &mHiddenTimerTargets;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (targetArray->Contains(objectFrame)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
targetArray->AppendElement(objectFrame);
|
|
|
|
if (targetArray->Length() == 1) {
|
|
|
|
if (isVisible) {
|
|
|
|
mVisiblePluginTimer->InitWithCallback(this, VISIBLE_PLUGIN_DELAY, nsITimer::TYPE_REPEATING_SLACK);
|
|
|
|
} else {
|
|
|
|
mHiddenPluginTimer->InitWithCallback(this, HIDDEN_PLUGIN_DELAY, nsITimer::TYPE_REPEATING_SLACK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsPluginHost::RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame)
|
|
|
|
{
|
|
|
|
#ifdef MAC_CARBON_PLUGINS
|
|
|
|
PRBool visibleRemoved = mVisibleTimerTargets.RemoveElement(objectFrame);
|
|
|
|
if (visibleRemoved && mVisibleTimerTargets.IsEmpty()) {
|
|
|
|
mVisiblePluginTimer->Cancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool hiddenRemoved = mHiddenTimerTargets.RemoveElement(objectFrame);
|
|
|
|
if (hiddenRemoved && mHiddenTimerTargets.IsEmpty()) {
|
|
|
|
mHiddenPluginTimer->Cancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(!(hiddenRemoved && visibleRemoved), "Plugin instance received visible and hidden idle event notifications");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
|
|
|
|
{
|
|
|
|
#ifdef MAC_CARBON_PLUGINS
|
|
|
|
if (timer == mVisiblePluginTimer) {
|
|
|
|
nsTObserverArray<nsIPluginInstanceOwner*>::ForwardIterator iter(mVisibleTimerTargets);
|
|
|
|
while (iter.HasMore()) {
|
|
|
|
iter.GetNext()->SendIdleEvent();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
} else if (timer == mHiddenPluginTimer) {
|
|
|
|
nsTObserverArray<nsIPluginInstanceOwner*>::ForwardIterator iter(mHiddenTimerTargets);
|
|
|
|
while (iter.HasMore()) {
|
|
|
|
iter.GetNext()->SendIdleEvent();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2009-12-16 20:08:45 +00:00
|
|
|
#ifdef MOZ_IPC
|
2010-11-05 15:18:07 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
// Re-enable any top level browser windows that were disabled by modal dialogs
|
|
|
|
// displayed by the crashed plugin.
|
|
|
|
static void
|
|
|
|
CheckForDisabledWindows()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIWindowMediator> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
|
|
|
|
if (!wm)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> windowList;
|
|
|
|
wm->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowList));
|
|
|
|
if (!windowList)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PRBool haveWindows;
|
|
|
|
do {
|
|
|
|
windowList->HasMoreElements(&haveWindows);
|
|
|
|
if (!haveWindows)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> supportsWindow;
|
|
|
|
windowList->GetNext(getter_AddRefs(supportsWindow));
|
|
|
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(supportsWindow));
|
|
|
|
if (baseWin) {
|
|
|
|
PRBool aFlag;
|
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
baseWin->GetMainWidget(getter_AddRefs(widget));
|
|
|
|
if (widget && !widget->GetParent() &&
|
|
|
|
NS_SUCCEEDED(widget->IsVisible(aFlag)) && aFlag == PR_TRUE &&
|
|
|
|
NS_SUCCEEDED(widget->IsEnabled(&aFlag)) && aFlag == PR_FALSE) {
|
2010-11-06 20:27:39 +00:00
|
|
|
nsIWidget * child = widget->GetFirstChild();
|
|
|
|
PRBool enable = PR_TRUE;
|
|
|
|
while (child) {
|
|
|
|
nsWindowType aType;
|
|
|
|
if (NS_SUCCEEDED(child->GetWindowType(aType)) &&
|
|
|
|
aType == eWindowType_dialog) {
|
|
|
|
enable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
child = child->GetNextSibling();
|
2010-11-05 15:18:07 +00:00
|
|
|
}
|
|
|
|
if (enable) {
|
|
|
|
widget->Enable(PR_TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (haveWindows);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-12-16 20:08:45 +00:00
|
|
|
void
|
2010-03-24 21:22:04 +00:00
|
|
|
nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin,
|
|
|
|
const nsAString& pluginDumpID,
|
|
|
|
const nsAString& browserDumpID)
|
2009-12-16 20:08:45 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
nsPluginTag* crashedPluginTag = TagForPlugin(aPlugin);
|
2009-12-16 20:08:45 +00:00
|
|
|
|
2010-03-24 21:22:04 +00:00
|
|
|
// Notify the app's observer that a plugin crashed so it can submit
|
|
|
|
// a crashreport.
|
2010-02-10 01:05:31 +00:00
|
|
|
PRBool submittedCrashReport = PR_FALSE;
|
2010-03-24 21:22:04 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService =
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 16:59:13 +00:00
|
|
|
mozilla::services::GetObserverService();
|
2010-03-24 21:22:04 +00:00
|
|
|
nsCOMPtr<nsIWritablePropertyBag2> propbag =
|
|
|
|
do_CreateInstance("@mozilla.org/hash-property-bag;1");
|
2010-02-10 01:05:31 +00:00
|
|
|
if (obsService && propbag) {
|
2010-03-24 21:22:04 +00:00
|
|
|
propbag->SetPropertyAsAString(NS_LITERAL_STRING("pluginDumpID"),
|
|
|
|
pluginDumpID);
|
|
|
|
propbag->SetPropertyAsAString(NS_LITERAL_STRING("browserDumpID"),
|
|
|
|
browserDumpID);
|
|
|
|
propbag->SetPropertyAsBool(NS_LITERAL_STRING("submittedCrashReport"),
|
|
|
|
submittedCrashReport);
|
2010-02-10 01:05:31 +00:00
|
|
|
obsService->NotifyObservers(propbag, "plugin-crashed", nsnull);
|
|
|
|
// see if an observer submitted a crash report.
|
2010-03-24 21:22:04 +00:00
|
|
|
propbag->GetPropertyAsBool(NS_LITERAL_STRING("submittedCrashReport"),
|
|
|
|
&submittedCrashReport);
|
2010-02-10 01:05:31 +00:00
|
|
|
}
|
|
|
|
|
2009-12-16 20:08:45 +00:00
|
|
|
// Invalidate each nsPluginInstanceTag for the crashed plugin
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
for (PRUint32 i = mInstances.Length(); i > 0; i--) {
|
|
|
|
nsNPAPIPluginInstance* instance = mInstances[i - 1];
|
|
|
|
if (instance->GetPlugin() == aPlugin) {
|
2010-03-24 21:22:04 +00:00
|
|
|
// notify the content node (nsIObjectLoadingContent) that the
|
|
|
|
// plugin has crashed
|
2010-01-13 16:42:41 +00:00
|
|
|
nsCOMPtr<nsIDOMElement> domElement;
|
2010-07-20 02:11:26 +00:00
|
|
|
instance->GetDOMElement(getter_AddRefs(domElement));
|
2010-01-13 16:42:41 +00:00
|
|
|
nsCOMPtr<nsIObjectLoadingContent> objectContent(do_QueryInterface(domElement));
|
|
|
|
if (objectContent) {
|
2010-07-20 02:11:26 +00:00
|
|
|
objectContent->PluginCrashed(crashedPluginTag, pluginDumpID, browserDumpID,
|
2010-03-24 21:22:04 +00:00
|
|
|
submittedCrashReport);
|
2010-01-13 16:42:41 +00:00
|
|
|
}
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
instance->Destroy();
|
|
|
|
mInstances.RemoveElement(instance);
|
|
|
|
OnPluginInstanceDestroyed(crashedPluginTag);
|
2009-12-16 20:08:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only after all instances have been invalidated is it safe to null
|
|
|
|
// out nsPluginTag.mEntryPoint. The next time we try to create an
|
|
|
|
// instance of this plugin we reload it (launch a new plugin process).
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
crashedPluginTag->mEntryPoint = nsnull;
|
2010-11-05 15:18:07 +00:00
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
CheckForDisabledWindows();
|
|
|
|
#endif
|
2009-12-16 20:08:45 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance*
|
|
|
|
nsPluginHost::FindInstance(const char *mimetype)
|
2010-02-03 01:18:37 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
nsNPAPIPluginInstance* instance = mInstances[i];
|
2010-02-03 01:18:37 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
const char* mt;
|
2010-07-20 02:11:26 +00:00
|
|
|
nsresult rv = instance->GetMIMEType(&mt);
|
2010-01-27 01:30:58 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
continue;
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
if (PL_strcasecmp(mt, mimetype) == 0)
|
2010-07-20 02:11:26 +00:00
|
|
|
return instance;
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance*
|
|
|
|
nsPluginHost::FindStoppedInstance(const char *url)
|
2010-01-27 01:30:58 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i];
|
|
|
|
|
|
|
|
nsIURI *uri = instance->GetURI();
|
|
|
|
if (!uri)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
nsCAutoString spec;
|
|
|
|
uri->GetSpec(spec);
|
|
|
|
if (!PL_strcmp(url, spec.get()) && !instance->IsRunning())
|
|
|
|
return instance;
|
2010-01-27 01:30:58 +00:00
|
|
|
}
|
2010-07-20 02:11:26 +00:00
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
nsNPAPIPluginInstance*
|
|
|
|
nsPluginHost::FindOldestStoppedInstance()
|
|
|
|
{
|
|
|
|
nsNPAPIPluginInstance *oldestInstance = nsnull;
|
|
|
|
TimeStamp oldestTime = TimeStamp::Now();
|
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i];
|
|
|
|
if (instance->IsRunning())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
TimeStamp time = instance->LastStopTime();
|
|
|
|
if (time < oldestTime) {
|
|
|
|
oldestTime = time;
|
|
|
|
oldestInstance = instance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return oldestInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRUint32
|
|
|
|
nsPluginHost::StoppedInstanceCount()
|
|
|
|
{
|
|
|
|
PRUint32 stoppedCount = 0;
|
|
|
|
for (PRUint32 i = 0; i < mInstances.Length(); i++) {
|
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i];
|
|
|
|
if (!instance->IsRunning())
|
|
|
|
stoppedCount++;
|
|
|
|
}
|
|
|
|
return stoppedCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray< nsRefPtr<nsNPAPIPluginInstance> >*
|
|
|
|
nsPluginHost::InstanceArray()
|
|
|
|
{
|
|
|
|
return &mInstances;
|
|
|
|
}
|
|
|
|
|
2010-01-27 01:30:58 +00:00
|
|
|
void
|
2010-07-20 02:11:26 +00:00
|
|
|
nsPluginHost::DestroyRunningInstances(nsISupportsArray* aReloadDocs, nsPluginTag* aPluginTag)
|
2010-01-27 01:30:58 +00:00
|
|
|
{
|
2010-07-20 02:11:26 +00:00
|
|
|
for (PRInt32 i = mInstances.Length(); i > 0; i--) {
|
|
|
|
nsNPAPIPluginInstance *instance = mInstances[i - 1];
|
|
|
|
if (instance->IsRunning() && (!aPluginTag || aPluginTag == TagForPlugin(instance->GetPlugin()))) {
|
2010-01-27 01:30:58 +00:00
|
|
|
instance->SetWindow(nsnull);
|
|
|
|
instance->Stop();
|
|
|
|
|
|
|
|
// If we've been passed an array to return, lets collect all our documents,
|
|
|
|
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
|
|
|
// to kickstart our instances.
|
|
|
|
if (aReloadDocs) {
|
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
|
|
|
instance->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (owner) {
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
owner->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (doc && aReloadDocs->IndexOf(doc) == -1) // don't allow for duplicates
|
|
|
|
aReloadDocs->AppendElement(doc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-20 02:11:26 +00:00
|
|
|
// Get rid of all the instances without the possibility of caching.
|
|
|
|
nsPluginTag* pluginTag = TagForPlugin(instance->GetPlugin());
|
|
|
|
instance->SetWindow(nsnull);
|
|
|
|
instance->Destroy();
|
|
|
|
mInstances.RemoveElement(instance);
|
2010-01-27 01:30:58 +00:00
|
|
|
OnPluginInstanceDestroyed(pluginTag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-29 02:06:00 +00:00
|
|
|
// Runnable that does an async destroy of a plugin.
|
|
|
|
|
|
|
|
class nsPluginDestroyRunnable : public nsRunnable,
|
|
|
|
public PRCList
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsPluginDestroyRunnable(nsIPluginInstance *aInstance)
|
|
|
|
: mInstance(aInstance)
|
|
|
|
{
|
|
|
|
PR_INIT_CLIST(this);
|
|
|
|
PR_APPEND_LINK(this, &sRunnableListHead);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~nsPluginDestroyRunnable()
|
|
|
|
{
|
|
|
|
PR_REMOVE_LINK(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD Run()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPluginInstance> instance;
|
|
|
|
|
|
|
|
// Null out mInstance to make sure this code in another runnable
|
|
|
|
// will do the right thing even if someone was holding on to this
|
|
|
|
// runnable longer than we expect.
|
|
|
|
instance.swap(mInstance);
|
|
|
|
|
|
|
|
if (PluginDestructionGuard::DelayDestroy(instance)) {
|
|
|
|
// It's still not safe to destroy the plugin, it's now up to the
|
|
|
|
// outermost guard on the stack to take care of the destruction.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginDestroyRunnable *r =
|
|
|
|
static_cast<nsPluginDestroyRunnable*>(PR_NEXT_LINK(&sRunnableListHead));
|
|
|
|
|
|
|
|
while (r != &sRunnableListHead) {
|
|
|
|
if (r != this && r->mInstance == instance) {
|
|
|
|
// There's another runnable scheduled to tear down
|
|
|
|
// instance. Let it do the job.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2008-03-05 07:14:58 +00:00
|
|
|
r = static_cast<nsPluginDestroyRunnable*>(PR_NEXT_LINK(r));
|
2008-02-29 02:06:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("Doing delayed destroy of instance %p\n", instance.get()));
|
|
|
|
|
2009-07-02 05:48:08 +00:00
|
|
|
nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (host)
|
2008-02-29 02:06:00 +00:00
|
|
|
host->StopPluginInstance(instance);
|
|
|
|
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("Done with delayed destroy of instance %p\n", instance.get()));
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
nsCOMPtr<nsIPluginInstance> mInstance;
|
|
|
|
|
|
|
|
static PRCList sRunnableListHead;
|
|
|
|
};
|
|
|
|
|
|
|
|
PRCList nsPluginDestroyRunnable::sRunnableListHead =
|
|
|
|
PR_INIT_STATIC_CLIST(&nsPluginDestroyRunnable::sRunnableListHead);
|
|
|
|
|
|
|
|
PRCList PluginDestructionGuard::sListHead =
|
|
|
|
PR_INIT_STATIC_CLIST(&PluginDestructionGuard::sListHead);
|
|
|
|
|
|
|
|
PluginDestructionGuard::~PluginDestructionGuard()
|
|
|
|
{
|
|
|
|
NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
|
|
|
|
|
|
|
|
PR_REMOVE_LINK(this);
|
|
|
|
|
|
|
|
if (mDelayedDestroy) {
|
|
|
|
// We've attempted to destroy the plugin instance we're holding on
|
|
|
|
// to while we were guarding it. Do the actual destroy now, off of
|
|
|
|
// a runnable.
|
|
|
|
nsRefPtr<nsPluginDestroyRunnable> evt =
|
|
|
|
new nsPluginDestroyRunnable(mInstance);
|
|
|
|
|
|
|
|
NS_DispatchToMainThread(evt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
PRBool
|
|
|
|
PluginDestructionGuard::DelayDestroy(nsIPluginInstance *aInstance)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread");
|
|
|
|
NS_ASSERTION(aInstance, "Uh, I need an instance!");
|
|
|
|
|
|
|
|
// Find the first guard on the stack and make it do a delayed
|
|
|
|
// destroy upon destruction.
|
|
|
|
|
|
|
|
PluginDestructionGuard *g =
|
|
|
|
static_cast<PluginDestructionGuard*>(PR_LIST_HEAD(&sListHead));
|
|
|
|
|
|
|
|
while (g != &sListHead) {
|
|
|
|
if (g->mInstance == aInstance) {
|
|
|
|
g->mDelayedDestroy = PR_TRUE;
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
g = static_cast<PluginDestructionGuard*>(PR_NEXT_LINK(g));
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|