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
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
/* nsPluginHostImpl.cpp - bulk of code for managing plugins */
|
|
|
|
|
2001-08-14 07:59:59 +00:00
|
|
|
#include "nscore.h"
|
1998-07-28 02:07:25 +00:00
|
|
|
#include "nsPluginHostImpl.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"
|
2008-09-15 12:45:01 +00:00
|
|
|
#include "nsNPAPIPlugin.h"
|
|
|
|
#include "nsNPAPIPluginStreamListener.h"
|
1998-08-01 05:46:47 +00:00
|
|
|
#include "nsPluginInstancePeer.h"
|
2001-03-12 02:07:15 +00:00
|
|
|
#include "nsIPlugin.h"
|
2007-10-10 01:24:28 +00:00
|
|
|
#include "nsIPluginInstanceInternal.h"
|
2003-03-25 06:54:52 +00:00
|
|
|
#ifdef OJI
|
2001-05-02 23:38:41 +00:00
|
|
|
#include "nsIJVMPlugin.h"
|
2003-04-03 19:11:41 +00:00
|
|
|
#include "nsIJVMPluginInstance.h"
|
2001-11-29 05:14:11 +00:00
|
|
|
#include "nsIJVMManager.h"
|
2003-03-25 06:54:52 +00:00
|
|
|
#endif
|
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-04-03 22:49:38 +00:00
|
|
|
#include "nsIScriptablePlugin.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-12-19 00:12:41 +00:00
|
|
|
#include "nsObsoleteModuleLoading.h"
|
2002-01-29 21:22:13 +00:00
|
|
|
#include "nsIComponentRegistrar.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"
|
2001-04-17 10:47:22 +00:00
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
// Friggin' X11 has to "#define None". Lame!
|
|
|
|
#ifdef None
|
|
|
|
#undef None
|
|
|
|
#endif
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
#ifdef CursorShape
|
|
|
|
#undef CursorShape /*X.h defines it as 0,
|
|
|
|
qnamespace.h makes an enum type by that name
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
//#include "nsIRegistry.h"
|
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"
|
|
|
|
#include "nsICategoryManager.h"
|
2001-05-22 22:32:45 +00:00
|
|
|
#include "nsISupportsPrimitives.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
|
|
|
|
1998-10-28 21:16:00 +00:00
|
|
|
#include "nsIServiceManager.h"
|
2003-10-30 02:59:31 +00:00
|
|
|
#include "nsNetCID.h"
|
1999-10-21 21:09:21 +00:00
|
|
|
#include "nsICookieService.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
|
|
|
|
2003-04-04 03:01:25 +00:00
|
|
|
#if defined(XP_WIN)
|
1998-07-28 02:07:25 +00:00
|
|
|
#include "windows.h"
|
1998-09-15 03:48:58 +00:00
|
|
|
#include "winbase.h"
|
1998-07-28 02:07:25 +00:00
|
|
|
#endif
|
|
|
|
|
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"
|
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"
|
2002-02-07 23:22:39 +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
|
|
|
|
2002-03-26 06:30:33 +00:00
|
|
|
#include "imgILoader.h"
|
2002-04-27 01:47:18 +00:00
|
|
|
#include "nsDefaultPlugin.h"
|
2002-05-26 22:52:19 +00:00
|
|
|
#include "nsWeakReference.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"
|
2004-07-31 23:15:21 +00:00
|
|
|
#include "nsPresContext.h"
|
2002-07-03 21:03:51 +00:00
|
|
|
#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"
|
2002-03-26 06:30:33 +00:00
|
|
|
|
2008-08-06 20:48:55 +00:00
|
|
|
#if defined(XP_UNIX) && defined(MOZ_WIDGET_GTK2) & defined(MOZ_X11)
|
2000-07-20 01:16:52 +00:00
|
|
|
#include <gdk/gdkx.h> // for GDK_DISPLAY()
|
|
|
|
#endif
|
|
|
|
|
2005-08-07 07:05:09 +00:00
|
|
|
#ifdef XP_MACOSX
|
|
|
|
#include <Carbon/Carbon.h> // for ::UseInputWindow()
|
2005-08-08 08:03:41 +00:00
|
|
|
#include <mach-o/loader.h>
|
|
|
|
#include <mach-o/fat.h>
|
2002-09-17 22:50:47 +00:00
|
|
|
#endif
|
2001-02-13 21:48:26 +00:00
|
|
|
|
2003-10-21 22:11:20 +00:00
|
|
|
#ifdef XP_OS2
|
|
|
|
#include "nsILegacyPluginWrapperOS2.h"
|
2004-10-11 04:01:49 +00:00
|
|
|
#endif
|
2003-10-21 22:11:20 +00:00
|
|
|
|
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
|
2008-11-02 15:49:03 +00:00
|
|
|
// The current plugin registry version (and the maximum version we know how to read)
|
2008-07-15 10:50:42 +00:00
|
|
|
static const char *kPluginRegistryVersion = "0.10";
|
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
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
// CID's && IID's
|
2000-09-22 00:58:46 +00:00
|
|
|
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
|
1999-03-03 04:10:54 +00:00
|
|
|
static NS_DEFINE_CID(kPluginCID, NS_PLUGIN_CID);
|
2004-10-11 04:01:49 +00:00
|
|
|
static NS_DEFINE_IID(kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
|
2001-11-17 15:26:02 +00:00
|
|
|
static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
2000-06-20 21:04:52 +00:00
|
|
|
// for the dialog
|
2003-07-20 12:13:22 +00:00
|
|
|
static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID); // needed for NS_TRY_SAFE_CALL
|
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-23 08:34:10 +00:00
|
|
|
#define PLUGIN_REGIONAL_URL "chrome://global-region/locale/region.properties"
|
2001-02-07 01:13:01 +00:00
|
|
|
|
|
|
|
// #defines for reading prefs and extra search plugin paths from windows registry
|
|
|
|
#define _MAXKEYVALUE_ 8196
|
|
|
|
#define _NS_PREF_COMMON_PLUGIN_REG_KEY_ "browser.plugins.registry_plugins_folder_key_location"
|
|
|
|
#define _NS_COMMON_PLUGIN_KEY_NAME_ "Plugins Folders"
|
|
|
|
|
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
|
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
#define MAGIC_REQUEST_CONTEXT 0x01020304
|
|
|
|
|
2002-02-19 01:26:17 +00:00
|
|
|
nsresult PostPluginUnloadEvent(PRLibrary * aLibrary);
|
2000-07-20 22:53:32 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
static nsActivePluginList *gActivePluginList;
|
2000-07-20 22:53:32 +00:00
|
|
|
|
2002-09-13 11:55:55 +00:00
|
|
|
#ifdef CALL_SAFETY_ON
|
|
|
|
PRBool gSkipPluginSafeCalls = PR_FALSE;
|
|
|
|
#endif
|
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
nsIFile *nsPluginHostImpl::sPluginTempDir;
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginHostImpl *nsPluginHostImpl::sInst;
|
2005-02-11 23:37:51 +00:00
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// flat file reg funcs
|
|
|
|
static
|
2002-08-26 21:20:31 +00:00
|
|
|
PRBool ReadSectionHeader(nsPluginManifestLineReader& reader, const char *token)
|
2002-08-14 22:31:59 +00:00
|
|
|
{
|
|
|
|
do {
|
|
|
|
if (*reader.LinePtr() == '[') {
|
|
|
|
char* p = reader.LinePtr() + (reader.LineLength() - 1);
|
|
|
|
if (*p != ']')
|
|
|
|
break;
|
|
|
|
*p = 0;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-14 22:31:59 +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
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
} while (reader.NextLine());
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
// Little helper struct to asynchronously reframe any presentations (embedded)
|
2004-10-11 04:01:49 +00:00
|
|
|
// or reload any documents (full-page), that contained plugins
|
2002-07-03 21:03:51 +00:00
|
|
|
// which were shutdown as a result of a plugins.refresh(1)
|
2006-05-10 17:30:15 +00:00
|
|
|
class nsPluginDocReframeEvent: public nsRunnable {
|
|
|
|
public:
|
|
|
|
nsPluginDocReframeEvent(nsISupportsArray* aDocs) { mDocs = aDocs; }
|
2007-02-17 18:44:42 +00:00
|
|
|
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> mDocs;
|
|
|
|
};
|
|
|
|
|
2006-05-10 17:30:15 +00:00
|
|
|
NS_IMETHODIMP nsPluginDocReframeEvent::Run() {
|
2002-07-03 21:03:51 +00:00
|
|
|
NS_ENSURE_TRUE(mDocs, NS_ERROR_FAILURE);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
PRUint32 c;
|
|
|
|
mDocs->Count(&c);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-07-03 21:03:51 +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) {
|
2007-05-01 22:24:20 +00:00
|
|
|
nsIPresShell *shell = doc->GetPrimaryShell();
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
// if this document has a presentation shell, then it has frames and can be reframed
|
|
|
|
if (shell) {
|
2008-11-03 19:23:07 +00:00
|
|
|
/* A reframe will cause a fresh object frame, instance owner, and instance
|
2004-01-21 23:05:10 +00:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
shell->ReconstructFrames(); // causes reframe of document
|
2002-07-03 21:03:51 +00:00
|
|
|
} else { // no pres shell --> full-page plugin
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2003-04-25 00:21:12 +00:00
|
|
|
NS_NOTREACHED("all plugins should have a pres shell!");
|
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return mDocs->Clear();
|
|
|
|
}
|
|
|
|
|
2001-04-11 23:08:36 +00:00
|
|
|
nsActivePlugin::nsActivePlugin(nsPluginTag* aPluginTag,
|
2004-10-11 04:01:49 +00:00
|
|
|
nsIPluginInstance* aInstance,
|
2002-03-06 07:48:55 +00:00
|
|
|
const char * url,
|
2002-06-14 20:45:29 +00:00
|
|
|
PRBool aDefaultPlugin,
|
|
|
|
nsIPluginInstancePeer* peer)
|
2000-06-13 23:23:13 +00:00
|
|
|
{
|
|
|
|
mNext = nsnull;
|
|
|
|
mPeer = nsnull;
|
2001-04-11 23:08:36 +00:00
|
|
|
mPluginTag = aPluginTag;
|
2000-06-13 23:23:13 +00:00
|
|
|
|
|
|
|
mURL = PL_strdup(url);
|
|
|
|
mInstance = aInstance;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aInstance && peer) {
|
2002-06-14 20:45:29 +00:00
|
|
|
mPeer = peer;
|
|
|
|
NS_ADDREF(mPeer);
|
2000-06-13 23:23:13 +00:00
|
|
|
NS_ADDREF(aInstance);
|
|
|
|
}
|
2001-04-03 22:49:38 +00:00
|
|
|
mXPConnected = PR_FALSE;
|
2001-02-02 23:48:17 +00:00
|
|
|
mDefaultPlugin = aDefaultPlugin;
|
2000-06-13 23:23:13 +00:00
|
|
|
mStopped = PR_FALSE;
|
2000-06-15 01:07:27 +00:00
|
|
|
mllStopTime = LL_ZERO;
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsActivePlugin::~nsActivePlugin()
|
|
|
|
{
|
2001-04-11 23:08:36 +00:00
|
|
|
mPluginTag = nsnull;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mInstance) {
|
|
|
|
if (mPeer) {
|
2001-06-19 22:42:07 +00:00
|
|
|
nsresult rv = NS_OK;
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> peer(do_QueryInterface(mPeer));
|
2001-06-19 22:42:07 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2002-08-23 11:23:49 +00:00
|
|
|
rv = peer->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (owner)
|
|
|
|
owner->SetInstance(nsnull);
|
2001-06-19 22:42:07 +00:00
|
|
|
}
|
2001-11-07 01:12:14 +00:00
|
|
|
|
|
|
|
// now check for cached plugins because they haven't had nsIPluginInstance::Destroy()
|
2004-10-11 04:01:49 +00:00
|
|
|
// called yet. For non-cached plugins, nsIPluginInstance::Destroy() is called
|
2001-11-07 01:12:14 +00:00
|
|
|
// in either nsObjectFrame::Destroy() or nsActivePluginList::stopRunning()
|
2004-10-11 04:01:49 +00:00
|
|
|
PRBool doCache = PR_TRUE;
|
2001-11-07 01:12:14 +00:00
|
|
|
mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (doCache)
|
2001-11-07 01:12:14 +00:00
|
|
|
mInstance->Destroy();
|
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
NS_RELEASE(mInstance);
|
2006-04-28 17:25:48 +00:00
|
|
|
NS_IF_RELEASE(mPeer);
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
PL_strfree(mURL);
|
|
|
|
}
|
|
|
|
|
2000-06-15 01:07:27 +00:00
|
|
|
void nsActivePlugin::setStopped(PRBool stopped)
|
|
|
|
{
|
|
|
|
mStopped = stopped;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mStopped) // plugin instance is told to stop
|
2000-06-15 01:07:27 +00:00
|
|
|
mllStopTime = PR_Now();
|
|
|
|
else
|
|
|
|
mllStopTime = LL_ZERO;
|
|
|
|
}
|
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
nsActivePluginList::nsActivePluginList()
|
|
|
|
{
|
2001-02-02 23:48:17 +00:00
|
|
|
mFirst = nsnull;
|
|
|
|
mLast = nsnull;
|
|
|
|
mCount = 0;
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsActivePluginList::~nsActivePluginList()
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mFirst == nsnull)
|
2000-06-13 23:23:13 +00:00
|
|
|
return;
|
|
|
|
shut();
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsActivePluginList::shut()
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mFirst)
|
2000-06-13 23:23:13 +00:00
|
|
|
return;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * plugin = mFirst; plugin != nsnull;) {
|
2000-06-13 23:23:13 +00:00
|
|
|
nsActivePlugin * next = plugin->mNext;
|
2002-06-26 04:32:49 +00:00
|
|
|
remove(plugin);
|
2000-06-13 23:23:13 +00:00
|
|
|
plugin = next;
|
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
mFirst = nsnull;
|
|
|
|
mLast = nsnull;
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 nsActivePluginList::add(nsActivePlugin * plugin)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mFirst) {
|
2001-02-02 23:48:17 +00:00
|
|
|
mFirst = plugin;
|
|
|
|
mLast = plugin;
|
|
|
|
mFirst->mNext = nsnull;
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
2008-11-03 19:23:07 +00:00
|
|
|
else {
|
2001-02-02 23:48:17 +00:00
|
|
|
mLast->mNext = plugin;
|
|
|
|
mLast = plugin;
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
mLast->mNext = nsnull;
|
|
|
|
mCount++;
|
|
|
|
return mCount;
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
PRBool nsActivePluginList::IsLastInstance(nsActivePlugin * plugin)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin)
|
2001-03-12 02:07:15 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin->mPluginTag)
|
2001-04-11 23:08:36 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if ((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
|
2001-03-12 02:07:15 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2002-06-26 04:32:49 +00:00
|
|
|
PRBool nsActivePluginList::remove(nsActivePlugin * plugin)
|
2000-06-13 23:23:13 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mFirst == nsnull)
|
2000-06-13 23:23:13 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
nsActivePlugin * prev = nsnull;
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if (p == plugin) {
|
2001-04-11 23:08:36 +00:00
|
|
|
PRBool lastInstance = IsLastInstance(p);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p == mFirst)
|
2001-02-02 23:48:17 +00:00
|
|
|
mFirst = p->mNext;
|
2000-06-13 23:23:13 +00:00
|
|
|
else
|
|
|
|
prev->mNext = p->mNext;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if ((prev != nsnull) && (prev->mNext == nsnull))
|
2001-02-02 23:48:17 +00:00
|
|
|
mLast = prev;
|
2000-06-13 23:23:13 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
// see if this is going to be the last instance of a plugin
|
2001-04-11 23:08:36 +00:00
|
|
|
// if so we should perform nsIPlugin::Shutdown and unload the library
|
|
|
|
// by calling nsPluginTag::TryUnloadPlugin()
|
2008-11-03 19:23:07 +00:00
|
|
|
if (lastInstance) {
|
2001-04-11 23:08:36 +00:00
|
|
|
// cache some things as we are going to destroy it right now
|
|
|
|
nsPluginTag *pluginTag = p->mPluginTag;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
delete p; // plugin instance is destroyed here
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (pluginTag)
|
2001-04-11 23:08:36 +00:00
|
|
|
pluginTag->TryUnloadPlugin();
|
|
|
|
else
|
|
|
|
NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown");
|
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
delete p;
|
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
mCount--;
|
2000-06-13 23:23:13 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
prev = p;
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-07-03 21:03:51 +00:00
|
|
|
// This method terminates all running instances of plugins and collects their
|
|
|
|
// documents to be returned through an array. This method is used
|
|
|
|
// when we are shutting down or when a plugins.refresh(1) happens.
|
2007-07-14 00:28:05 +00:00
|
|
|
// If aPluginTag is given, then only that plugin is terminated
|
|
|
|
void nsActivePluginList::stopRunning(nsISupportsArray* aReloadDocs,
|
|
|
|
nsPluginTag* aPluginTag)
|
2001-02-02 23:48:17 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mFirst == nsnull)
|
2001-02-02 23:48:17 +00:00
|
|
|
return;
|
|
|
|
|
2001-07-14 00:03:17 +00:00
|
|
|
PRBool doCallSetWindowAfterDestroy = PR_FALSE;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if (!p->mStopped && p->mInstance &&
|
|
|
|
(!aPluginTag || aPluginTag == p->mPluginTag)) {
|
2001-07-14 00:03:17 +00:00
|
|
|
// then determine if the plugin wants Destroy to be called after
|
|
|
|
// Set Window. This is for bug 50547.
|
2004-10-11 04:01:49 +00:00
|
|
|
p->mInstance->GetValue(nsPluginInstanceVariable_CallSetWindowAfterDestroyBool,
|
2001-07-14 00:03:17 +00:00
|
|
|
(void *) &doCallSetWindowAfterDestroy);
|
|
|
|
if (doCallSetWindowAfterDestroy) {
|
|
|
|
p->mInstance->Stop();
|
|
|
|
p->mInstance->Destroy();
|
|
|
|
p->mInstance->SetWindow(nsnull);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
p->mInstance->SetWindow(nsnull);
|
|
|
|
p->mInstance->Stop();
|
2001-11-07 01:12:14 +00:00
|
|
|
p->mInstance->Destroy();
|
2001-07-14 00:03:17 +00:00
|
|
|
}
|
|
|
|
doCallSetWindowAfterDestroy = PR_FALSE;
|
2001-02-02 23:48:17 +00:00
|
|
|
p->setStopped(PR_TRUE);
|
2002-07-03 21:03:51 +00:00
|
|
|
|
|
|
|
// If we've been passed an array to return, lets collect all our documents,
|
2004-10-11 04:01:49 +00:00
|
|
|
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
2002-07-03 21:03:51 +00:00
|
|
|
// to kickstart our instances.
|
|
|
|
if (aReloadDocs && p->mPeer) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> peer(do_QueryInterface(p->mPeer));
|
2002-07-03 21:03:51 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2002-08-23 11:23:49 +00:00
|
|
|
peer->GetOwner(getter_AddRefs(owner));
|
2002-07-03 21:03:51 +00:00
|
|
|
if (owner) {
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
owner->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (doc && aReloadDocs->IndexOf(doc) == -1) // don't allow for duplicates
|
|
|
|
aReloadDocs->AppendElement(doc);
|
|
|
|
}
|
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsActivePluginList::removeAllStopped()
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mFirst == nsnull)
|
2001-02-02 23:48:17 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
nsActivePlugin * next = nsnull;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull;) {
|
2001-02-02 23:48:17 +00:00
|
|
|
next = p->mNext;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p->mStopped)
|
2002-06-26 04:32:49 +00:00
|
|
|
remove(p);
|
2001-04-11 23:08:36 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
p = next;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
nsActivePlugin * nsActivePluginList::find(nsIPluginInstance* instance)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if (p->mInstance == instance) {
|
2001-03-12 02:07:15 +00:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
|
|
|
NS_ASSERTION(!p->mStopped || doCache, "This plugin is not supposed to be cached!");
|
|
|
|
#endif
|
2000-06-13 23:23:13 +00:00
|
|
|
return p;
|
2001-03-12 02:07:15 +00:00
|
|
|
}
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
nsActivePlugin * nsActivePluginList::find(const char * mimetype)
|
2001-02-02 23:48:17 +00:00
|
|
|
{
|
|
|
|
PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
2001-02-02 23:48:17 +00:00
|
|
|
// give it some special treatment for the default plugin first
|
|
|
|
// because we cannot tell the default plugin by asking peer for a mime type
|
2008-11-03 19:23:07 +00:00
|
|
|
if (defaultplugin && p->mDefaultPlugin)
|
2001-02-02 23:48:17 +00:00
|
|
|
return p;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!p->mPeer)
|
2001-02-02 23:48:17 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
nsMIMEType mt;
|
|
|
|
|
|
|
|
nsresult res = p->mPeer->GetMIMEType(&mt);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(res))
|
2001-02-02 23:48:17 +00:00
|
|
|
continue;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (PL_strcasecmp(mt, mimetype) == 0) {
|
2001-03-12 02:07:15 +00:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
|
|
|
NS_ASSERTION(!p->mStopped || doCache, "This plugin is not supposed to be cached!");
|
|
|
|
#endif
|
|
|
|
return p;
|
|
|
|
}
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
nsActivePlugin * nsActivePluginList::findStopped(const char * url)
|
2000-06-13 23:23:13 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if (!PL_strcmp(url, p->mURL) && p->mStopped) {
|
2001-03-12 02:07:15 +00:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
|
|
|
NS_ASSERTION(doCache, "This plugin is not supposed to be cached!");
|
|
|
|
#endif
|
|
|
|
return p;
|
|
|
|
}
|
2000-06-13 23:23:13 +00:00
|
|
|
}
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRUint32 nsActivePluginList::getStoppedCount()
|
|
|
|
{
|
|
|
|
PRUint32 stoppedCount = 0;
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if (p->mStopped)
|
2000-06-13 23:23:13 +00:00
|
|
|
stoppedCount++;
|
|
|
|
}
|
|
|
|
return stoppedCount;
|
|
|
|
}
|
|
|
|
|
2000-06-15 01:07:27 +00:00
|
|
|
nsActivePlugin * nsActivePluginList::findOldestStopped()
|
|
|
|
{
|
|
|
|
nsActivePlugin * res = nsnull;
|
|
|
|
PRInt64 llTime = LL_MAXINT;
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext) {
|
|
|
|
if (!p->mStopped)
|
2000-06-15 01:07:27 +00:00
|
|
|
continue;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (LL_CMP(p->mllStopTime, <, llTime)) {
|
2000-06-15 01:07:27 +00:00
|
|
|
llTime = p->mllStopTime;
|
|
|
|
res = p;
|
|
|
|
}
|
|
|
|
}
|
2001-03-12 02:07:15 +00:00
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
2008-11-03 19:23:07 +00:00
|
|
|
if (res) {
|
2001-03-12 02:07:15 +00:00
|
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
res->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
|
|
|
NS_ASSERTION(doCache, "This plugin is not supposed to be cached!");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2000-06-15 01:07:27 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
inline char* new_str(const char* str)
|
1999-04-20 19:29:28 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (str == nsnull)
|
1999-10-02 00:41:03 +00:00
|
|
|
return nsnull;
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
char* result = new char[strlen(str) + 1];
|
|
|
|
if (result != nsnull)
|
|
|
|
return strcpy(result, str);
|
|
|
|
return result;
|
1999-04-20 19:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
|
2007-10-10 01:24:28 +00:00
|
|
|
: mPluginHost(nsnull),
|
2008-03-10 07:07:15 +00:00
|
|
|
mName(aPluginTag->mName),
|
|
|
|
mDescription(aPluginTag->mDescription),
|
2007-10-10 01:24:28 +00:00
|
|
|
mVariants(aPluginTag->mVariants),
|
|
|
|
mMimeTypeArray(nsnull),
|
2008-03-10 07:07:15 +00:00
|
|
|
mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
|
2007-10-10 01:24:28 +00:00
|
|
|
mExtensionsArray(nsnull),
|
|
|
|
mLibrary(nsnull),
|
|
|
|
mEntryPoint(nsnull),
|
|
|
|
mCanUnloadLibrary(PR_TRUE),
|
|
|
|
mXPConnected(PR_FALSE),
|
|
|
|
mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
|
|
|
|
mIsNPRuntimeEnabledJavaPlugin(aPluginTag->mIsNPRuntimeEnabledJavaPlugin),
|
2008-03-10 07:07:15 +00:00
|
|
|
mFileName(aPluginTag->mFileName),
|
|
|
|
mFullPath(aPluginTag->mFullPath),
|
2008-07-15 10:50:42 +00:00
|
|
|
mVersion(aPluginTag->mVersion),
|
2007-10-10 01:24:28 +00:00
|
|
|
mLastModifiedTime(0),
|
|
|
|
mFlags(NS_PLUGIN_FLAG_ENABLED)
|
1999-04-20 19:29:28 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aPluginTag->mMimeTypeArray != nsnull) {
|
2000-04-13 22:34:49 +00:00
|
|
|
mMimeTypeArray = new char*[mVariants];
|
2001-02-02 23:48:17 +00:00
|
|
|
for (int i = 0; i < mVariants; i++)
|
|
|
|
mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
|
2000-04-13 22:34:49 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aPluginTag->mExtensionsArray != nsnull) {
|
2000-04-13 22:34:49 +00:00
|
|
|
mExtensionsArray = new char*[mVariants];
|
2001-02-02 23:48:17 +00:00
|
|
|
for (int i = 0; i < mVariants; i++)
|
|
|
|
mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2000-03-23 00:45:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
|
2007-10-10 01:24:28 +00:00
|
|
|
: mPluginHost(nsnull),
|
2008-03-10 07:07:15 +00:00
|
|
|
mName(aPluginInfo->fName),
|
|
|
|
mDescription(aPluginInfo->fDescription),
|
2007-10-10 01:24:28 +00:00
|
|
|
mVariants(aPluginInfo->fVariantCount),
|
|
|
|
mMimeTypeArray(nsnull),
|
|
|
|
mExtensionsArray(nsnull),
|
|
|
|
mLibrary(nsnull),
|
|
|
|
mEntryPoint(nsnull),
|
|
|
|
#ifdef XP_MACOSX
|
2008-12-11 21:52:42 +00:00
|
|
|
mCanUnloadLibrary(PR_FALSE),
|
2007-10-10 01:24:28 +00:00
|
|
|
#else
|
|
|
|
mCanUnloadLibrary(PR_TRUE),
|
|
|
|
#endif
|
|
|
|
mXPConnected(PR_FALSE),
|
|
|
|
mIsJavaPlugin(PR_FALSE),
|
|
|
|
mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
|
2008-03-10 07:07:15 +00:00
|
|
|
mFileName(aPluginInfo->fFileName),
|
|
|
|
mFullPath(aPluginInfo->fFullPath),
|
2008-07-15 10:50:42 +00:00
|
|
|
mVersion(aPluginInfo->fVersion),
|
2007-10-10 01:24:28 +00:00
|
|
|
mLastModifiedTime(0),
|
|
|
|
mFlags(NS_PLUGIN_FLAG_ENABLED)
|
2000-03-23 00:45:49 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aPluginInfo->fMimeTypeArray != nsnull) {
|
2000-04-13 22:34:49 +00:00
|
|
|
mMimeTypeArray = new char*[mVariants];
|
2007-09-04 18:19:31 +00:00
|
|
|
for (int i = 0; i < mVariants; i++) {
|
2007-10-10 01:24:28 +00:00
|
|
|
if (mIsJavaPlugin && aPluginInfo->fMimeTypeArray[i] &&
|
|
|
|
strcmp(aPluginInfo->fMimeTypeArray[i],
|
|
|
|
"application/x-java-vm-npruntime") == 0) {
|
|
|
|
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
|
|
|
|
|
|
|
|
// Stop processing here, any mimetypes after the magic "I'm a
|
|
|
|
// NPRuntime enabled Java plugin" mimetype will be ignored.
|
|
|
|
mVariants = i;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
|
2007-09-04 18:19:31 +00:00
|
|
|
if (nsPluginHostImpl::IsJavaMIMEType(mMimeTypeArray[i]))
|
|
|
|
mIsJavaPlugin = PR_TRUE;
|
|
|
|
}
|
2000-03-29 23:58:42 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aPluginInfo->fMimeDescriptionArray != nsnull) {
|
2002-08-07 03:10:33 +00:00
|
|
|
for (int i = 0; i < mVariants; i++) {
|
2004-10-11 04:01:49 +00:00
|
|
|
// we should cut off the list of suffixes which the mime
|
2002-08-07 03:10:33 +00:00
|
|
|
// description string may have, see bug 53895
|
2004-10-11 04:01:49 +00:00
|
|
|
// it is usually in form "some description (*.sf1, *.sf2)"
|
2002-08-07 03:10:33 +00:00
|
|
|
// so we can search for the opening round bracket
|
|
|
|
char cur = '\0';
|
|
|
|
char pre = '\0';
|
|
|
|
char * p = PL_strrchr(aPluginInfo->fMimeDescriptionArray[i], '(');
|
|
|
|
if (p && (p != aPluginInfo->fMimeDescriptionArray[i])) {
|
|
|
|
if ((p - 1) && *(p - 1) == ' ') {
|
|
|
|
pre = *(p - 1);
|
|
|
|
*(p - 1) = '\0';
|
|
|
|
} else {
|
|
|
|
cur = *p;
|
|
|
|
*p = '\0';
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-07 03:10:33 +00:00
|
|
|
}
|
2008-03-10 07:07:15 +00:00
|
|
|
mMimeDescriptionArray.AppendElement(
|
|
|
|
aPluginInfo->fMimeDescriptionArray[i]);
|
2002-08-07 03:10:33 +00:00
|
|
|
// restore the original string
|
|
|
|
if (cur != '\0')
|
|
|
|
*p = cur;
|
|
|
|
if (pre != '\0')
|
|
|
|
*(p - 1) = pre;
|
|
|
|
}
|
2008-03-10 07:07:15 +00:00
|
|
|
} else {
|
|
|
|
mMimeDescriptionArray.SetLength(mVariants);
|
2000-03-29 23:58:42 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aPluginInfo->fExtensionArray != nsnull) {
|
2000-04-13 22:34:49 +00:00
|
|
|
mExtensionsArray = new char*[mVariants];
|
2001-02-02 23:48:17 +00:00
|
|
|
for (int i = 0; i < mVariants; i++)
|
|
|
|
mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2008-03-10 07:07:15 +00:00
|
|
|
|
|
|
|
EnsureMembersAreUTF8();
|
1999-04-20 19:29:28 +00:00
|
|
|
}
|
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
nsPluginTag::nsPluginTag(const char* aName,
|
|
|
|
const char* aDescription,
|
|
|
|
const char* aFileName,
|
2001-10-18 12:26:23 +00:00
|
|
|
const char* aFullPath,
|
2008-07-15 10:50:42 +00:00
|
|
|
const char* aVersion,
|
2000-07-22 01:34:13 +00:00
|
|
|
const char* const* aMimeTypes,
|
|
|
|
const char* const* aMimeDescriptions,
|
|
|
|
const char* const* aExtensions,
|
2001-10-18 12:26:23 +00:00
|
|
|
PRInt32 aVariants,
|
2001-10-30 06:46:40 +00:00
|
|
|
PRInt64 aLastModifiedTime,
|
2008-03-10 07:07:15 +00:00
|
|
|
PRBool aCanUnload,
|
|
|
|
PRBool aArgsAreUTF8)
|
2007-10-10 01:24:28 +00:00
|
|
|
: mPluginHost(nsnull),
|
2008-03-10 07:07:15 +00:00
|
|
|
mName(aName),
|
|
|
|
mDescription(aDescription),
|
2000-07-22 01:34:13 +00:00
|
|
|
mVariants(aVariants),
|
|
|
|
mMimeTypeArray(nsnull),
|
|
|
|
mExtensionsArray(nsnull),
|
|
|
|
mLibrary(nsnull),
|
|
|
|
mEntryPoint(nsnull),
|
2005-02-04 16:54:11 +00:00
|
|
|
mCanUnloadLibrary(aCanUnload),
|
2001-10-18 12:26:23 +00:00
|
|
|
mXPConnected(PR_FALSE),
|
2007-10-10 01:24:28 +00:00
|
|
|
mIsJavaPlugin(PR_FALSE),
|
|
|
|
mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
|
2008-03-10 07:07:15 +00:00
|
|
|
mFileName(aFileName),
|
|
|
|
mFullPath(aFullPath),
|
2008-07-15 10:50:42 +00:00
|
|
|
mVersion(aVersion),
|
2005-11-06 18:34:03 +00:00
|
|
|
mLastModifiedTime(aLastModifiedTime),
|
|
|
|
mFlags(0) // Caller will read in our flags from cache
|
2000-07-22 01:34:13 +00:00
|
|
|
{
|
2007-10-10 01:24:28 +00:00
|
|
|
if (aVariants) {
|
2000-07-22 01:34:13 +00:00
|
|
|
mMimeTypeArray = new char*[mVariants];
|
|
|
|
mExtensionsArray = new char*[mVariants];
|
|
|
|
|
|
|
|
for (PRInt32 i = 0; i < aVariants; ++i) {
|
2007-10-10 01:24:28 +00:00
|
|
|
if (mIsJavaPlugin && aMimeTypes[i] &&
|
|
|
|
strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
|
|
|
|
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
|
|
|
|
|
|
|
|
// Stop processing here, any mimetypes after the magic "I'm a
|
|
|
|
// NPRuntime enabled Java plugin" mimetype will be ignored.
|
|
|
|
mVariants = i;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
mMimeTypeArray[i] = new_str(aMimeTypes[i]);
|
2008-03-10 07:07:15 +00:00
|
|
|
mMimeDescriptionArray.AppendElement(aMimeDescriptions[i]);
|
2000-07-22 01:34:13 +00:00
|
|
|
mExtensionsArray[i] = new_str(aExtensions[i]);
|
2007-09-04 18:19:31 +00:00
|
|
|
if (nsPluginHostImpl::IsJavaMIMEType(mMimeTypeArray[i]))
|
|
|
|
mIsJavaPlugin = PR_TRUE;
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-10 07:07:15 +00:00
|
|
|
|
|
|
|
if (!aArgsAreUTF8)
|
|
|
|
EnsureMembersAreUTF8();
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsPluginTag::~nsPluginTag()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2001-05-03 08:38:18 +00:00
|
|
|
TryUnloadPlugin(PR_TRUE);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
// Remove mime types added to the category manager
|
2003-02-27 13:51:55 +00:00
|
|
|
// only if we were made 'active' by setting the host
|
|
|
|
if (mPluginHost) {
|
|
|
|
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
|
|
|
}
|
|
|
|
|
2007-10-10 01:24:28 +00:00
|
|
|
if (mMimeTypeArray) {
|
2001-08-16 02:59:03 +00:00
|
|
|
for (int i = 0; i < mVariants; i++)
|
|
|
|
delete[] mMimeTypeArray[i];
|
2000-05-14 09:18:43 +00:00
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
delete[] (mMimeTypeArray);
|
1998-07-28 02:07:25 +00:00
|
|
|
mMimeTypeArray = nsnull;
|
|
|
|
}
|
|
|
|
|
2007-10-10 01:24:28 +00:00
|
|
|
if (mExtensionsArray) {
|
2001-08-16 02:59:03 +00:00
|
|
|
for (int i = 0; i < mVariants; i++)
|
|
|
|
delete[] mExtensionsArray[i];
|
2000-05-14 09:18:43 +00:00
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
delete[] (mExtensionsArray);
|
1998-07-28 02:07:25 +00:00
|
|
|
mExtensionsArray = nsnull;
|
|
|
|
}
|
2008-03-10 07:07:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
|
|
|
|
|
|
|
|
static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
|
|
|
|
nsAFlatCString& aString)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
1998-07-28 02:07:25 +00:00
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
PRInt32 numberOfBytes = aString.Length();
|
|
|
|
PRInt32 outUnicodeLen;
|
|
|
|
nsAutoString buffer;
|
|
|
|
rv = aUnicodeDecoder->GetMaxLength(aString.get(), numberOfBytes,
|
|
|
|
&outUnicodeLen);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!EnsureStringLength(buffer, outUnicodeLen))
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
rv = aUnicodeDecoder->Convert(aString.get(), &numberOfBytes,
|
|
|
|
buffer.BeginWriting(), &outUnicodeLen);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
buffer.SetLength(outUnicodeLen);
|
|
|
|
CopyUTF16toUTF8(buffer, aString);
|
2001-07-18 14:04:28 +00:00
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
return NS_OK;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
nsresult nsPluginTag::EnsureMembersAreUTF8()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPlatformCharset> pcs =
|
|
|
|
do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsIUnicodeDecoder> decoder;
|
|
|
|
nsCOMPtr<nsICharsetConverterManager> ccm =
|
|
|
|
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCAutoString charset;
|
|
|
|
rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
|
|
|
rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
ConvertToUTF8(decoder, mFileName);
|
|
|
|
ConvertToUTF8(decoder, mFullPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The description of the plug-in and the various MIME type descriptions
|
|
|
|
// should be encoded in the standard plain text file encoding for this system.
|
|
|
|
// XXX should we add kPlatformCharsetSel_PluginResource?
|
|
|
|
rv = pcs->GetCharset(kPlatformCharsetSel_PlainTextInFile, charset);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
|
|
|
rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2008-03-17 21:58:59 +00:00
|
|
|
ConvertToUTF8(decoder, mName);
|
2008-03-10 07:07:15 +00:00
|
|
|
ConvertToUTF8(decoder, mDescription);
|
2008-03-13 00:26:18 +00:00
|
|
|
for (PRUint32 i = 0; i < mMimeDescriptionArray.Length(); ++i) {
|
2008-03-10 07:07:15 +00:00
|
|
|
ConvertToUTF8(decoder, mMimeDescriptionArray[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-07-03 21:42:35 +00:00
|
|
|
|
2002-06-26 04:32:49 +00:00
|
|
|
void nsPluginTag::SetHost(nsPluginHostImpl * aHost)
|
|
|
|
{
|
|
|
|
mPluginHost = aHost;
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::GetDescription(nsACString& aDescription)
|
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
aDescription = mDescription;
|
2007-07-03 21:42:35 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::GetFilename(nsACString& aFileName)
|
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
aFileName = mFileName;
|
2007-07-03 21:42:35 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-07-15 10:50:42 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::GetVersion(nsACString& aVersion)
|
|
|
|
{
|
|
|
|
aVersion = mVersion;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::GetName(nsACString& aName)
|
|
|
|
{
|
2008-03-10 07:07:15 +00:00
|
|
|
aName = mName;
|
2007-07-03 21:42:35 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::GetDisabled(PRBool* aDisabled)
|
|
|
|
{
|
|
|
|
*aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::SetDisabled(PRBool aDisabled)
|
|
|
|
{
|
|
|
|
if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
|
|
|
|
return NS_OK;
|
|
|
|
|
2007-09-04 18:19:31 +00:00
|
|
|
if (mIsJavaPlugin) {
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
PRBool javaEnabled;
|
|
|
|
rv = pref->GetBoolPref("security.enable_java", &javaEnabled);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (javaEnabled == aDisabled)
|
|
|
|
return pref->SetBoolPref("security.enable_java", !aDisabled);
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
if (aDisabled)
|
|
|
|
UnMark(NS_PLUGIN_FLAG_ENABLED);
|
|
|
|
else
|
|
|
|
Mark(NS_PLUGIN_FLAG_ENABLED);
|
|
|
|
|
2007-07-14 00:28:05 +00:00
|
|
|
mPluginHost->UpdatePluginInfo(this);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::GetBlocklisted(PRBool* aBlocklisted)
|
|
|
|
{
|
|
|
|
*aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
|
|
|
|
{
|
|
|
|
if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
|
|
|
|
return NS_OK;
|
|
|
|
|
2008-03-18 10:38:15 +00:00
|
|
|
if (aBlocklisted)
|
2007-07-14 00:28:05 +00:00
|
|
|
Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
2008-03-18 10:38:15 +00:00
|
|
|
else
|
2007-07-14 00:28:05 +00:00
|
|
|
UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
|
|
|
|
|
|
|
mPluginHost->UpdatePluginInfo(nsnull);
|
2007-07-03 21:42:35 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-02-19 01:26:17 +00:00
|
|
|
// helper struct for asynchronous handeling of plugin unloading
|
2006-05-10 17:30:15 +00:00
|
|
|
class nsPluginUnloadEvent : public nsRunnable {
|
|
|
|
public:
|
|
|
|
nsPluginUnloadEvent(PRLibrary* aLibrary)
|
|
|
|
: mLibrary(aLibrary)
|
|
|
|
{}
|
2007-02-17 18:44:42 +00:00
|
|
|
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
|
2002-02-19 01:26:17 +00:00
|
|
|
PRLibrary* mLibrary;
|
|
|
|
};
|
|
|
|
|
2007-02-17 18:44:42 +00:00
|
|
|
NS_IMETHODIMP nsPluginUnloadEvent::Run()
|
|
|
|
{
|
|
|
|
if (mLibrary) {
|
|
|
|
// put our unload call in a saftey wrapper
|
|
|
|
NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(mLibrary), nsnull, nsnull);
|
|
|
|
} else {
|
|
|
|
NS_WARNING("missing library from nsPluginUnloadEvent");
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-02-19 01:26:17 +00:00
|
|
|
// unload plugin asynchronously if possible, otherwise just unload now
|
2006-05-10 17:30:15 +00:00
|
|
|
nsresult PostPluginUnloadEvent(PRLibrary* aLibrary)
|
2002-02-19 01:26:17 +00:00
|
|
|
{
|
2006-05-10 17:30:15 +00:00
|
|
|
nsCOMPtr<nsIRunnable> ev = new nsPluginUnloadEvent(aLibrary);
|
|
|
|
if (ev && NS_SUCCEEDED(NS_DispatchToCurrentThread(ev)))
|
|
|
|
return NS_OK;
|
2002-02-19 01:26:17 +00:00
|
|
|
|
|
|
|
// failure case
|
2002-06-01 00:56:38 +00:00
|
|
|
NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(aLibrary), nsnull, nsnull);
|
2002-02-19 01:26:17 +00:00
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2001-05-03 08:38:18 +00:00
|
|
|
void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown)
|
2001-04-11 23:08:36 +00:00
|
|
|
{
|
2001-05-18 23:38:06 +00:00
|
|
|
PRBool isXPCOM = PR_FALSE;
|
|
|
|
if (!(mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
|
|
|
|
isXPCOM = PR_TRUE;
|
|
|
|
|
2001-05-18 21:23:59 +00:00
|
|
|
if (isXPCOM && !aForceShutdown) return;
|
2001-05-03 08:38:18 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mEntryPoint) {
|
2001-04-11 23:08:36 +00:00
|
|
|
mEntryPoint->Shutdown();
|
|
|
|
mEntryPoint->Release();
|
|
|
|
mEntryPoint = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// before we unload check if we are allowed to, see bug #61388
|
2001-07-17 19:55:33 +00:00
|
|
|
// also, never unload an XPCOM plugin library
|
2002-06-26 04:32:49 +00:00
|
|
|
if (mLibrary && mCanUnloadLibrary && !isXPCOM) {
|
|
|
|
// NPAPI plugins can be unloaded now if they don't use XPConnect
|
|
|
|
if (!mXPConnected)
|
2004-10-11 04:01:49 +00:00
|
|
|
// unload the plugin asynchronously by posting a PLEvent
|
|
|
|
PostPluginUnloadEvent(mLibrary);
|
2002-06-26 04:32:49 +00:00
|
|
|
else {
|
|
|
|
// add library to the unused library list to handle it later
|
|
|
|
if (mPluginHost)
|
|
|
|
mPluginHost->AddUnusedLibrary(mLibrary);
|
|
|
|
}
|
|
|
|
}
|
2001-04-11 23:08:36 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// we should zero it anyway, it is going to be unloaded by
|
|
|
|
// CleanUnsedLibraries before we need to call the library
|
|
|
|
// again so the calling code should not be fooled and reload
|
2001-04-11 23:08:36 +00:00
|
|
|
// the library fresh
|
|
|
|
mLibrary = nsnull;
|
|
|
|
}
|
|
|
|
|
2001-11-20 01:19:33 +00:00
|
|
|
PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(aPluginTag, PR_FALSE);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if ((!mName.Equals(aPluginTag->mName)) ||
|
|
|
|
(!mDescription.Equals(aPluginTag->mDescription)) ||
|
|
|
|
(mVariants != aPluginTag->mVariants))
|
2001-11-20 01:19:33 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
|
|
|
|
for (PRInt32 i = 0; i < mVariants; i++) {
|
2001-11-20 01:19:33 +00:00
|
|
|
if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
|
|
|
|
return PR_FALSE;
|
2002-08-14 22:31:59 +00:00
|
|
|
}
|
|
|
|
}
|
2001-11-20 01:19:33 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
class nsPluginStreamListenerPeer;
|
|
|
|
|
2008-09-15 12:45:01 +00:00
|
|
|
class nsPluginStreamInfo : public nsINPAPIPluginStreamInfo
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
|
|
|
public:
|
2001-08-16 02:59:03 +00:00
|
|
|
nsPluginStreamInfo();
|
|
|
|
virtual ~nsPluginStreamInfo();
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_DECL_ISUPPORTS
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-09-15 12:45:01 +00:00
|
|
|
// nsINPAPIPluginStreamInfo interface
|
2007-02-17 18:44:42 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
GetContentType(nsMIMEType* result);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
IsSeekable(PRBool* result);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
GetLength(PRUint32* result);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
GetLastModified(PRUint32* result);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
GetURL(const char** result);
|
1999-03-11 22:48:58 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
RequestRead(nsByteRange* rangeList);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-03-27 03:41:43 +00:00
|
|
|
NS_IMETHOD
|
|
|
|
GetStreamOffset(PRInt32 *result);
|
|
|
|
|
|
|
|
NS_IMETHOD
|
|
|
|
SetStreamOffset(PRInt32 result);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
// local methods
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
|
|
|
SetContentType(const nsMIMEType contentType);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
|
|
|
SetSeekable(const PRBool seekable);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
|
|
|
SetLength(const PRUint32 length);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
|
|
|
SetLastModified(const PRUint32 modified);
|
1999-03-11 22:48:58 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
|
|
|
SetURL(const char* url);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
|
|
|
SetPluginInstance(nsIPluginInstance * aPluginInstance);
|
|
|
|
|
|
|
|
void
|
|
|
|
SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamListenerPeer);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
2002-03-20 22:50:33 +00:00
|
|
|
MakeByteRangeString(nsByteRange* aRangeList, nsACString &string, PRInt32 *numRequests);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
PRBool
|
2002-09-12 19:12:56 +00:00
|
|
|
UseExistingPluginCacheFile(nsPluginStreamInfo* psi);
|
|
|
|
|
|
|
|
void
|
|
|
|
SetStreamComplete(const PRBool complete);
|
2001-06-19 01:38:20 +00:00
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
void
|
|
|
|
SetRequest(nsIRequest *request)
|
|
|
|
{
|
|
|
|
mRequest = request;
|
|
|
|
}
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
private:
|
|
|
|
|
2001-06-26 21:57:48 +00:00
|
|
|
char* mContentType;
|
|
|
|
char* mURL;
|
|
|
|
PRBool mSeekable;
|
|
|
|
PRUint32 mLength;
|
|
|
|
PRUint32 mModified;
|
|
|
|
nsIPluginInstance * mPluginInstance;
|
|
|
|
nsPluginStreamListenerPeer * mPluginStreamListenerPeer;
|
2002-03-27 03:41:43 +00:00
|
|
|
PRInt32 mStreamOffset;
|
2002-09-12 19:12:56 +00:00
|
|
|
PRBool mStreamComplete;
|
2001-05-22 22:32:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class nsPluginStreamListenerPeer : public nsIStreamListener,
|
|
|
|
public nsIProgressEventSink,
|
2002-05-26 22:52:19 +00:00
|
|
|
public nsIHttpHeaderVisitor,
|
|
|
|
public nsSupportsWeakReference
|
2001-05-22 22:32:45 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsPluginStreamListenerPeer();
|
|
|
|
virtual ~nsPluginStreamListenerPeer();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIPROGRESSEVENTSINK
|
|
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
|
|
NS_DECL_NSISTREAMLISTENER
|
|
|
|
NS_DECL_NSIHTTPHEADERVISITOR
|
|
|
|
|
|
|
|
// Called by GetURL and PostURL (via NewStream)
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult Initialize(nsIURI *aURL,
|
|
|
|
nsIPluginInstance *aInstance,
|
2001-05-22 22:32:45 +00:00
|
|
|
nsIPluginStreamListener *aListener,
|
|
|
|
PRInt32 requestCount = 1);
|
|
|
|
|
2005-06-08 23:42:15 +00:00
|
|
|
nsresult InitializeEmbedded(nsIURI *aURL,
|
2004-10-11 04:01:49 +00:00
|
|
|
nsIPluginInstance* aInstance,
|
2001-05-22 22:32:45 +00:00
|
|
|
nsIPluginInstanceOwner *aOwner = nsnull,
|
|
|
|
nsIPluginHost *aHost = nsnull);
|
|
|
|
|
|
|
|
nsresult InitializeFullPage(nsIPluginInstance *aInstance);
|
|
|
|
|
2002-04-27 05:33:09 +00:00
|
|
|
nsresult OnFileAvailable(nsIFile* aFile);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
nsresult ServeStreamAsFile(nsIRequest *request, nsISupports *ctxt);
|
2008-08-04 21:17:55 +00:00
|
|
|
|
|
|
|
nsIPluginInstance *GetPluginInstance() { return mInstance; }
|
2002-05-10 18:32:42 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
private:
|
2001-06-19 01:38:20 +00:00
|
|
|
nsresult SetUpCache(nsIURI* aURL); // todo: see about removing this...
|
2001-05-22 22:32:45 +00:00
|
|
|
nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
|
2001-06-19 01:38:20 +00:00
|
|
|
nsresult SetupPluginCacheFile(nsIChannel* channel);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
|
|
|
nsIURI *mURL;
|
|
|
|
nsIPluginInstanceOwner *mOwner;
|
|
|
|
nsIPluginInstance *mInstance;
|
|
|
|
nsIPluginStreamListener *mPStreamListener;
|
2004-04-11 05:33:17 +00:00
|
|
|
nsRefPtr<nsPluginStreamInfo> mPluginStreamInfo;
|
2002-03-18 00:09:48 +00:00
|
|
|
|
|
|
|
// Set to PR_TRUE if we request failed (like with a HTTP response of 404)
|
|
|
|
PRPackedBool mRequestFailed;
|
2001-05-22 22:32:45 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set to PR_TRUE after nsIPluginInstancePeer::OnStartBinding() has
|
|
|
|
* been called. Checked in ::OnStopRequest so we can call the
|
|
|
|
* plugin's OnStartBinding if, for some reason, it has not already
|
|
|
|
* been called.
|
|
|
|
*/
|
2001-08-16 02:59:03 +00:00
|
|
|
PRPackedBool mStartBinding;
|
|
|
|
PRPackedBool mHaveFiredOnStartRequest;
|
2001-05-22 22:32:45 +00:00
|
|
|
// these get passed to the plugin stream listener
|
|
|
|
char *mMIMEType;
|
|
|
|
PRUint32 mLength;
|
|
|
|
nsPluginStreamType mStreamType;
|
|
|
|
nsIPluginHost *mHost;
|
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
// local cached file, we save the content into local cache if browser cache is not available,
|
|
|
|
// or plugin asks stream as file and it expects file extension until bug 90558 got fixed
|
|
|
|
nsIFile *mLocalCachedFile;
|
|
|
|
nsCOMPtr<nsIOutputStream> mFileCacheOutputStream;
|
2001-05-22 22:32:45 +00:00
|
|
|
nsHashtable *mDataForwardToRequest;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PRBool mAbort;
|
|
|
|
PRInt32 mPendingRequests;
|
2002-08-09 01:36:39 +00:00
|
|
|
nsWeakPtr mWeakPtrChannelCallbacks;
|
|
|
|
nsWeakPtr mWeakPtrChannelLoadGroup;
|
1999-01-25 08:05:00 +00:00
|
|
|
};
|
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
class nsPluginByteRangeStreamListener : public nsIStreamListener {
|
|
|
|
public:
|
2002-05-26 22:52:19 +00:00
|
|
|
nsPluginByteRangeStreamListener(nsIWeakReference* aWeakPtr);
|
2002-05-10 18:32:42 +00:00
|
|
|
virtual ~nsPluginByteRangeStreamListener();
|
|
|
|
|
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIRequestObserver methods:
|
|
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
|
|
|
|
|
|
// nsIStreamListener methods:
|
|
|
|
NS_DECL_NSISTREAMLISTENER
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIStreamListener> mStreamConverter;
|
2002-05-26 22:52:19 +00:00
|
|
|
nsWeakPtr mWeakPtrPluginStreamListenerPeer;
|
|
|
|
PRBool mRemoveMagicNumber;
|
2002-05-10 18:32:42 +00:00
|
|
|
};
|
2001-08-16 02:59:03 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
nsPluginStreamInfo::nsPluginStreamInfo()
|
|
|
|
{
|
2001-06-26 21:57:48 +00:00
|
|
|
mPluginInstance = nsnull;
|
|
|
|
mPluginStreamListenerPeer = nsnull;
|
|
|
|
|
|
|
|
mContentType = nsnull;
|
|
|
|
mURL = nsnull;
|
|
|
|
mSeekable = PR_FALSE;
|
|
|
|
mLength = 0;
|
|
|
|
mModified = 0;
|
2002-03-27 03:41:43 +00:00
|
|
|
mStreamOffset = 0;
|
2002-09-12 19:12:56 +00:00
|
|
|
mStreamComplete = PR_FALSE;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginStreamInfo::~nsPluginStreamInfo()
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mContentType)
|
|
|
|
PL_strfree(mContentType);
|
|
|
|
if (mURL)
|
2001-06-26 21:57:48 +00:00
|
|
|
PL_strfree(mURL);
|
|
|
|
|
|
|
|
NS_IF_RELEASE(mPluginInstance);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
NS_IMPL_ISUPPORTS2(nsPluginStreamInfo, nsIPluginStreamInfo,
|
2008-09-15 12:45:01 +00:00
|
|
|
nsINPAPIPluginStreamInfo)
|
1999-01-25 08:05:00 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::GetContentType(nsMIMEType* result)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
*result = mContentType;
|
|
|
|
return NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::IsSeekable(PRBool* result)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
*result = mSeekable;
|
|
|
|
return NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::GetLength(PRUint32* result)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
*result = mLength;
|
|
|
|
return NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::GetLastModified(PRUint32* result)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
*result = mModified;
|
|
|
|
return NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
1999-03-11 22:48:58 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::GetURL(const char** result)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
*result = mURL;
|
|
|
|
return NS_OK;
|
1999-03-11 22:48:58 +00:00
|
|
|
}
|
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
void
|
2002-03-20 22:50:33 +00:00
|
|
|
nsPluginStreamInfo::MakeByteRangeString(nsByteRange* aRangeList, nsACString &rangeRequest, PRInt32 *numRequests)
|
2001-05-22 22:32:45 +00:00
|
|
|
{
|
2002-03-20 22:50:33 +00:00
|
|
|
rangeRequest.Truncate();
|
2001-05-22 22:32:45 +00:00
|
|
|
*numRequests = 0;
|
|
|
|
//the string should look like this: bytes=500-700,601-999
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!aRangeList)
|
2001-05-22 22:32:45 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
PRInt32 requestCnt = 0;
|
2001-06-15 00:37:14 +00:00
|
|
|
nsCAutoString string("bytes=");
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (nsByteRange * range = aRangeList; range != nsnull; range = range->next) {
|
2001-05-22 22:32:45 +00:00
|
|
|
// XXX zero length?
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!range->length)
|
2001-05-22 22:32:45 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// XXX needs to be fixed for negative offsets
|
2001-06-15 00:37:14 +00:00
|
|
|
string.AppendInt(range->offset);
|
|
|
|
string.Append("-");
|
|
|
|
string.AppendInt(range->offset + range->length - 1);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (range->next)
|
2001-06-15 00:37:14 +00:00
|
|
|
string += ",";
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
requestCnt++;
|
|
|
|
}
|
|
|
|
|
2001-06-15 00:37:14 +00:00
|
|
|
// get rid of possible trailing comma
|
|
|
|
string.Trim(",", PR_FALSE);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2002-03-20 22:50:33 +00:00
|
|
|
rangeRequest = string;
|
2001-05-22 22:32:45 +00:00
|
|
|
*numRequests = requestCnt;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::RequestRead(nsByteRange* rangeList)
|
2004-10-11 04:01:49 +00:00
|
|
|
{
|
2002-03-27 03:41:43 +00:00
|
|
|
nsCAutoString rangeString;
|
|
|
|
PRInt32 numRequests;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
//first of all lets see if mPluginStreamListenerPeer is still alive
|
|
|
|
nsCOMPtr<nsISupportsWeakReference> suppWeakRef(
|
|
|
|
do_QueryInterface((nsISupportsWeakReference *)(mPluginStreamListenerPeer)));
|
|
|
|
if (!suppWeakRef)
|
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIWeakReference> pWeakRefPluginStreamListenerPeer =
|
2003-07-25 19:06:59 +00:00
|
|
|
do_GetWeakReference(suppWeakRef);
|
2002-05-26 22:52:19 +00:00
|
|
|
if (!pWeakRefPluginStreamListenerPeer)
|
|
|
|
return NS_ERROR_FAILURE;
|
2002-03-27 03:41:43 +00:00
|
|
|
|
|
|
|
MakeByteRangeString(rangeList, rangeString, &numRequests);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (numRequests == 0)
|
2002-03-27 03:41:43 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIURI> url;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
rv = NS_NewURI(getter_AddRefs(url), nsDependentCString(mURL));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-09 01:36:39 +00:00
|
|
|
nsCOMPtr<nsIInterfaceRequestor> callbacks = do_QueryReferent(mPluginStreamListenerPeer->mWeakPtrChannelCallbacks);
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mPluginStreamListenerPeer->mWeakPtrChannelLoadGroup);
|
2001-05-22 22:32:45 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel;
|
2002-08-09 01:36:39 +00:00
|
|
|
rv = NS_NewChannel(getter_AddRefs(channel), url, nsnull, loadGroup, callbacks);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv))
|
2001-05-22 22:32:45 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!httpChannel)
|
2001-05-22 22:32:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-11-22 07:40:16 +00:00
|
|
|
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, PR_FALSE);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-03-27 03:41:43 +00:00
|
|
|
mPluginStreamListenerPeer->mAbort = PR_TRUE; // instruct old stream listener to cancel
|
2002-05-26 22:52:19 +00:00
|
|
|
// the request on the next ODA.
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
nsCOMPtr<nsIStreamListener> converter;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
if (numRequests == 1) {
|
2002-05-26 22:52:19 +00:00
|
|
|
converter = mPluginStreamListenerPeer;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
// set current stream offset equal to the first offset in the range list
|
|
|
|
// it will work for single byte range request
|
2004-10-11 04:01:49 +00:00
|
|
|
// for multy range we'll reset it in ODA
|
2002-05-10 18:32:42 +00:00
|
|
|
SetStreamOffset(rangeList->offset);
|
|
|
|
} else {
|
2004-10-11 04:01:49 +00:00
|
|
|
nsPluginByteRangeStreamListener *brrListener =
|
2002-05-26 22:52:19 +00:00
|
|
|
new nsPluginByteRangeStreamListener(pWeakRefPluginStreamListenerPeer);
|
2002-05-10 18:32:42 +00:00
|
|
|
if (brrListener)
|
|
|
|
converter = brrListener;
|
|
|
|
else
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
mPluginStreamListenerPeer->mPendingRequests += numRequests;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
rv = container->SetData(MAGIC_REQUEST_CONTEXT);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
return channel->AsyncOpen(converter, container);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
2002-03-27 03:41:43 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::GetStreamOffset(PRInt32 *result)
|
|
|
|
{
|
|
|
|
*result = mStreamOffset;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginStreamInfo::SetStreamOffset(PRInt32 offset)
|
2004-10-11 04:01:49 +00:00
|
|
|
{
|
2002-03-27 03:41:43 +00:00
|
|
|
mStreamOffset = offset;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginStreamInfo::SetContentType(const nsMIMEType contentType)
|
2004-10-11 04:01:49 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mContentType != nsnull)
|
2001-08-16 02:59:03 +00:00
|
|
|
PL_strfree(mContentType);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
mContentType = PL_strdup(contentType);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginStreamInfo::SetSeekable(const PRBool seekable)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
mSeekable = seekable;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginStreamInfo::SetLength(const PRUint32 length)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
mLength = length;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPluginStreamInfo::SetLastModified(const PRUint32 modified)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
mModified = modified;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
1999-03-11 22:48:58 +00:00
|
|
|
void
|
|
|
|
nsPluginStreamInfo::SetURL(const char* url)
|
2004-10-11 04:01:49 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mURL)
|
2001-08-16 02:59:03 +00:00
|
|
|
PL_strfree(mURL);
|
1999-03-11 22:48:58 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
mURL = PL_strdup(url);
|
1999-03-11 22:48:58 +00:00
|
|
|
}
|
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
void
|
|
|
|
nsPluginStreamInfo::SetPluginInstance(nsIPluginInstance * aPluginInstance)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
NS_IF_ADDREF(mPluginInstance = aPluginInstance);
|
2001-05-22 22:32:45 +00:00
|
|
|
}
|
2001-04-17 23:30:25 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
void
|
2001-05-22 22:32:45 +00:00
|
|
|
nsPluginStreamInfo::SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamListenerPeer)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
// not addref'd - nsPluginStreamInfo is owned by mPluginStreamListenerPeer
|
|
|
|
mPluginStreamListenerPeer = aPluginStreamListenerPeer;
|
2001-05-22 22:32:45 +00:00
|
|
|
}
|
1999-03-11 22:48:58 +00:00
|
|
|
|
|
|
|
class nsPluginCacheListener : public nsIStreamListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsPluginCacheListener(nsPluginStreamListenerPeer* aListener);
|
1999-03-23 03:18:12 +00:00
|
|
|
virtual ~nsPluginCacheListener();
|
1999-03-11 22:48:58 +00:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
2001-04-10 06:01:08 +00:00
|
|
|
NS_DECL_NSIREQUESTOBSERVER
|
1999-09-16 01:16:22 +00:00
|
|
|
NS_DECL_NSISTREAMLISTENER
|
1999-06-25 00:03:22 +00:00
|
|
|
|
1999-03-11 22:48:58 +00:00
|
|
|
private:
|
2000-06-21 22:57:17 +00:00
|
|
|
nsPluginStreamListenerPeer* mListener;
|
1998-08-05 04:21:36 +00:00
|
|
|
};
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsPluginCacheListener::nsPluginCacheListener(nsPluginStreamListenerPeer* aListener)
|
1999-03-11 22:48:58 +00:00
|
|
|
{
|
|
|
|
mListener = aListener;
|
|
|
|
NS_ADDREF(mListener);
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsPluginCacheListener::~nsPluginCacheListener()
|
1999-03-11 22:48:58 +00:00
|
|
|
{
|
|
|
|
NS_IF_RELEASE(mListener);
|
|
|
|
}
|
|
|
|
|
2008-03-19 22:05:04 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(nsPluginCacheListener, nsIStreamListener)
|
2008-11-03 19:23:07 +00:00
|
|
|
|
1999-06-25 00:03:22 +00:00
|
|
|
NS_IMETHODIMP
|
2001-02-21 20:38:08 +00:00
|
|
|
nsPluginCacheListener::OnStartRequest(nsIRequest *request, nsISupports* ctxt)
|
1999-06-25 00:03:22 +00:00
|
|
|
{
|
2000-06-21 22:57:17 +00:00
|
|
|
return NS_OK;
|
1999-06-25 00:03:22 +00:00
|
|
|
}
|
1999-03-11 22:48:58 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginCacheListener::OnDataAvailable(nsIRequest *request, nsISupports* ctxt,
|
|
|
|
nsIInputStream* aIStream,
|
|
|
|
PRUint32 sourceOffset,
|
1999-07-07 08:08:40 +00:00
|
|
|
PRUint32 aLength)
|
1999-03-11 22:48:58 +00:00
|
|
|
{
|
1999-06-25 00:03:22 +00:00
|
|
|
|
2000-06-21 22:57:17 +00:00
|
|
|
PRUint32 readlen;
|
|
|
|
char* buffer = (char*) PR_Malloc(aLength);
|
1999-03-11 22:48:58 +00:00
|
|
|
|
2000-06-21 22:57:17 +00:00
|
|
|
// if we don't read from the stream, OnStopRequest will never be called
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!buffer)
|
2000-06-21 22:57:17 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
nsresult rv = aIStream->Read(buffer, aLength, &readlen);
|
|
|
|
|
|
|
|
NS_ASSERTION(aLength == readlen, "nsCacheListener->OnDataAvailable: "
|
|
|
|
"readlen != aLength");
|
|
|
|
|
|
|
|
PR_Free(buffer);
|
|
|
|
return rv;
|
1999-03-11 22:48:58 +00:00
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginCacheListener::OnStopRequest(nsIRequest *request,
|
|
|
|
nsISupports* aContext,
|
2001-04-10 06:01:08 +00:00
|
|
|
nsresult aStatus)
|
1999-03-11 22:48:58 +00:00
|
|
|
{
|
2000-06-21 22:57:17 +00:00
|
|
|
return NS_OK;
|
1999-03-11 22:48:58 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
|
|
|
mURL = nsnull;
|
1998-09-15 03:48:58 +00:00
|
|
|
mOwner = nsnull;
|
1998-08-05 04:21:36 +00:00
|
|
|
mInstance = nsnull;
|
1999-01-25 08:05:00 +00:00
|
|
|
mPStreamListener = nsnull;
|
1998-08-05 04:21:36 +00:00
|
|
|
mHost = nsnull;
|
1998-09-27 22:21:39 +00:00
|
|
|
mStreamType = nsPluginStreamType_Normal;
|
2000-09-20 09:27:54 +00:00
|
|
|
mStartBinding = PR_FALSE;
|
2001-05-22 22:32:45 +00:00
|
|
|
mAbort = PR_FALSE;
|
2002-03-18 00:09:48 +00:00
|
|
|
mRequestFailed = PR_FALSE;
|
2001-05-22 22:32:45 +00:00
|
|
|
|
|
|
|
mPendingRequests = 0;
|
|
|
|
mHaveFiredOnStartRequest = PR_FALSE;
|
|
|
|
mDataForwardToRequest = nsnull;
|
2002-08-29 22:00:20 +00:00
|
|
|
mLocalCachedFile = nsnull;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
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 (mURL != nsnull) (void)mURL->GetSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2002-08-29 22:00:20 +00:00
|
|
|
("nsPluginStreamListenerPeer::dtor this=%p, url=%s%c",this, urlSpec.get(), mLocalCachedFile?',':'\n'));
|
1998-09-15 03:48:58 +00:00
|
|
|
#endif
|
1999-01-25 08:05:00 +00:00
|
|
|
|
1998-08-05 04:21:36 +00:00
|
|
|
NS_IF_RELEASE(mURL);
|
1998-09-15 03:48:58 +00:00
|
|
|
NS_IF_RELEASE(mOwner);
|
1998-08-05 04:21:36 +00:00
|
|
|
NS_IF_RELEASE(mInstance);
|
1999-01-25 08:05:00 +00:00
|
|
|
NS_IF_RELEASE(mPStreamListener);
|
1998-08-05 04:21:36 +00:00
|
|
|
NS_IF_RELEASE(mHost);
|
2001-04-17 23:30:25 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
// close FD of mFileCacheOutputStream if it's still open
|
|
|
|
// or we won't be able to remove the cache file
|
|
|
|
if (mFileCacheOutputStream)
|
|
|
|
mFileCacheOutputStream = nsnull;
|
|
|
|
|
|
|
|
// if we have mLocalCachedFile lets release it
|
2004-10-11 04:01:49 +00:00
|
|
|
// and it'll be fiscally remove if refcnt == 1
|
2002-08-29 22:00:20 +00:00
|
|
|
if (mLocalCachedFile) {
|
|
|
|
nsrefcnt refcnt;
|
|
|
|
NS_RELEASE2(mLocalCachedFile, refcnt);
|
|
|
|
|
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
nsCAutoString filePath;
|
|
|
|
mLocalCachedFile->GetNativePath(filePath);
|
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
|
|
|
("LocalyCachedFile=%s has %d refcnt and will %s be deleted now\n",filePath.get(),refcnt,refcnt==1?"":"NOT"));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (refcnt == 1) {
|
|
|
|
mLocalCachedFile->Remove(PR_FALSE);
|
|
|
|
NS_RELEASE(mLocalCachedFile);
|
|
|
|
}
|
|
|
|
}
|
2002-04-27 05:33:09 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
delete mDataForwardToRequest;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
NS_IMPL_ISUPPORTS4(nsPluginStreamListenerPeer,
|
2001-05-22 22:32:45 +00:00
|
|
|
nsIStreamListener,
|
|
|
|
nsIRequestObserver,
|
2002-05-26 22:52:19 +00:00
|
|
|
nsIHttpHeaderVisitor,
|
|
|
|
nsISupportsWeakReference)
|
2001-09-13 02:21:05 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called as a result of GetURL and PostURL
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
|
2000-04-22 20:50:22 +00:00
|
|
|
nsIPluginInstance *aInstance,
|
2001-05-22 22:32:45 +00:00
|
|
|
nsIPluginStreamListener* aListener,
|
|
|
|
PRInt32 requestCount)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
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 != nsnull) (void)aURL->GetAsciiSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2002-03-06 07:48:55 +00:00
|
|
|
("nsPluginStreamListenerPeer::Initialize instance=%p, url=%s\n", aInstance, urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
1999-01-25 08:05:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
mURL = aURL;
|
|
|
|
NS_ADDREF(mURL);
|
|
|
|
|
|
|
|
mInstance = aInstance;
|
|
|
|
NS_ADDREF(mInstance);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
mPStreamListener = aListener;
|
|
|
|
NS_ADDREF(mPStreamListener);
|
|
|
|
|
|
|
|
mPluginStreamInfo = new nsPluginStreamInfo();
|
2001-05-25 01:38:42 +00:00
|
|
|
if (!mPluginStreamInfo)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1998-08-05 04:21:36 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
mPluginStreamInfo->SetPluginInstance(aInstance);
|
|
|
|
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
|
|
|
|
|
|
|
mPendingRequests = requestCount;
|
|
|
|
|
|
|
|
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!mDataForwardToRequest)
|
2001-05-22 22:32:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
1998-08-05 04:21:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
/* Called by NewEmbeddedPluginStream() - if this is called, we weren't
|
|
|
|
* able to load the plugin, so we need to load it later once we figure
|
|
|
|
* out the mimetype. In order to load it later, we need the plugin
|
|
|
|
* host and instance owner.
|
|
|
|
*/
|
2005-06-08 23:42:15 +00:00
|
|
|
nsresult nsPluginStreamListenerPeer::InitializeEmbedded(nsIURI *aURL,
|
|
|
|
nsIPluginInstance* aInstance,
|
|
|
|
nsIPluginInstanceOwner *aOwner,
|
|
|
|
nsIPluginHost *aHost)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString urlSpec;
|
2008-01-03 06:22:50 +00:00
|
|
|
(void)aURL->GetSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2005-06-08 23:42:15 +00:00
|
|
|
("nsPluginStreamListenerPeer::InitializeEmbedded url=%s\n", urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
1998-09-15 03:48:58 +00:00
|
|
|
#endif
|
1999-01-25 08:05:00 +00:00
|
|
|
|
1998-08-05 04:21:36 +00:00
|
|
|
mURL = aURL;
|
|
|
|
NS_ADDREF(mURL);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aInstance) {
|
2005-06-08 23:42:15 +00:00
|
|
|
NS_ASSERTION(mInstance == nsnull, "nsPluginStreamListenerPeer::InitializeEmbedded mInstance != nsnull");
|
2001-08-16 02:59:03 +00:00
|
|
|
mInstance = aInstance;
|
|
|
|
NS_ADDREF(mInstance);
|
|
|
|
} else {
|
|
|
|
mOwner = aOwner;
|
|
|
|
NS_IF_ADDREF(mOwner);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
mHost = aHost;
|
|
|
|
NS_IF_ADDREF(mHost);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
1998-08-05 04:21:36 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
mPluginStreamInfo = new nsPluginStreamInfo();
|
2001-05-25 01:38:42 +00:00
|
|
|
if (!mPluginStreamInfo)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1998-08-05 04:21:36 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
mPluginStreamInfo->SetPluginInstance(aInstance);
|
|
|
|
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
|
|
|
|
|
|
|
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!mDataForwardToRequest)
|
2001-05-22 22:32:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
1998-08-05 04:21:36 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by NewFullPagePluginStream()
|
1999-04-20 19:29:28 +00:00
|
|
|
nsresult nsPluginStreamListenerPeer::InitializeFullPage(nsIPluginInstance *aInstance)
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("nsPluginStreamListenerPeer::InitializeFullPage instance=%p\n",aInstance));
|
2000-04-22 20:50:22 +00:00
|
|
|
|
2000-06-21 22:57:17 +00:00
|
|
|
NS_ASSERTION(mInstance == nsnull, "nsPluginStreamListenerPeer::InitializeFullPage mInstance != nsnull");
|
1998-09-15 03:48:58 +00:00
|
|
|
mInstance = aInstance;
|
|
|
|
NS_ADDREF(mInstance);
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
mPluginStreamInfo = new nsPluginStreamInfo();
|
2001-05-25 01:38:42 +00:00
|
|
|
if (!mPluginStreamInfo)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
mPluginStreamInfo->SetPluginInstance(aInstance);
|
|
|
|
mPluginStreamInfo->SetPluginStreamListenerPeer(this);
|
|
|
|
|
|
|
|
mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!mDataForwardToRequest)
|
2001-05-22 22:32:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
1998-09-15 03:48:58 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// SetupPluginCacheFile is called if we have to save the stream to disk.
|
|
|
|
// the most likely cause for this is either there is no disk cache available
|
2004-10-11 04:01:49 +00:00
|
|
|
// or the stream is coming from a https server.
|
2001-06-19 01:38:20 +00:00
|
|
|
//
|
|
|
|
// These files will be deleted when the host is destroyed.
|
|
|
|
//
|
|
|
|
// TODO? What if we fill up the the dest dir?
|
|
|
|
nsresult
|
|
|
|
nsPluginStreamListenerPeer::SetupPluginCacheFile(nsIChannel* channel)
|
|
|
|
{
|
2002-08-29 22:00:20 +00:00
|
|
|
nsresult rv = NS_OK;
|
2004-10-11 04:01:49 +00:00
|
|
|
// lets try to reused a file if we already have in the local plugin cache
|
2002-08-29 22:00:20 +00:00
|
|
|
// we loop through all of active plugins
|
2004-10-11 04:01:49 +00:00
|
|
|
// and call |nsPluginStreamInfo::UseExistingPluginCacheFile()| on opened stream
|
|
|
|
// will return RP_TRUE if file exisrs
|
|
|
|
// and some conditions are matched, in this case that file will be use
|
2002-08-29 22:00:20 +00:00
|
|
|
// in |::OnFileAvailable()| calls w/o rewriting the file again.
|
|
|
|
// The file will be deleted in |nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer|
|
|
|
|
PRBool useExistingCacheFile = PR_FALSE;
|
|
|
|
nsActivePlugin *pActivePlugins = gActivePluginList->mFirst;
|
|
|
|
while (pActivePlugins && pActivePlugins->mStreams && !useExistingCacheFile) {
|
|
|
|
// most recent streams are at the end of list
|
|
|
|
PRInt32 cnt;
|
|
|
|
pActivePlugins->mStreams->Count((PRUint32*)&cnt);
|
|
|
|
while (--cnt >= 0 && !useExistingCacheFile) {
|
|
|
|
nsPluginStreamListenerPeer *lp =
|
2007-07-08 07:08:04 +00:00
|
|
|
reinterpret_cast<nsPluginStreamListenerPeer *>(pActivePlugins->mStreams->ElementAt(cnt));
|
2002-08-29 22:00:20 +00:00
|
|
|
if (lp) {
|
|
|
|
if (lp->mLocalCachedFile &&
|
|
|
|
lp->mPluginStreamInfo &&
|
2004-10-11 04:01:49 +00:00
|
|
|
(useExistingCacheFile =
|
2008-11-03 19:23:07 +00:00
|
|
|
lp->mPluginStreamInfo->UseExistingPluginCacheFile(mPluginStreamInfo))) {
|
2002-08-29 22:00:20 +00:00
|
|
|
NS_ADDREF(mLocalCachedFile = lp->mLocalCachedFile);
|
|
|
|
}
|
|
|
|
NS_RELEASE(lp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pActivePlugins = pActivePlugins->mNext;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
if (!useExistingCacheFile) {
|
2001-06-19 01:38:20 +00:00
|
|
|
nsCOMPtr<nsIFile> pluginTmp;
|
2005-02-11 23:37:51 +00:00
|
|
|
rv = nsPluginHostImpl::GetPluginTempDir(getter_AddRefs(pluginTmp));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// Get the filename from the channel
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
rv = channel->GetURI(getter_AddRefs(uri));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!url)
|
2001-06-20 22:43:37 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString filename;
|
|
|
|
url->GetFileName(filename);
|
2002-08-29 22:00:20 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// Create a file to save our stream into. Should we scramble the name?
|
2008-08-26 11:40:13 +00:00
|
|
|
filename.Insert(NS_LITERAL_CSTRING("plugin-"), 0);
|
2002-04-27 05:33:09 +00:00
|
|
|
rv = pluginTmp->AppendNative(filename);
|
2002-08-29 22:00:20 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// Yes, make it unique.
|
2004-10-11 04:01:49 +00:00
|
|
|
rv = pluginTmp->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
|
2002-08-29 22:00:20 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2001-06-19 01:38:20 +00:00
|
|
|
|
|
|
|
// create a file output stream to write to...
|
|
|
|
nsCOMPtr<nsIOutputStream> outstream;
|
2002-08-29 22:00:20 +00:00
|
|
|
rv = NS_NewLocalFileOutputStream(getter_AddRefs(mFileCacheOutputStream), pluginTmp, -1, 00600);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
// save the file.
|
|
|
|
CallQueryInterface(pluginTmp, &mLocalCachedFile); // no need to check return value, just addref
|
|
|
|
// add one extra refcnt, we can use NS_RELEASE2(mLocalCachedFile...) in dtor
|
2004-10-11 04:01:49 +00:00
|
|
|
// to remove this file when refcnt == 1
|
2002-08-29 22:00:20 +00:00
|
|
|
NS_ADDREF(mLocalCachedFile);
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
// add this listenerPeer to list of stream peers for this instance
|
|
|
|
// it'll delay release of listenerPeer until nsActivePlugin::~nsActivePlugin
|
|
|
|
// and the temp file is going to stay alive until then
|
|
|
|
pActivePlugins = gActivePluginList->find(mInstance);
|
|
|
|
if (pActivePlugins) {
|
|
|
|
if (!pActivePlugins->mStreams &&
|
|
|
|
(NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(pActivePlugins->mStreams))))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-07-08 07:08:04 +00:00
|
|
|
nsISupports* supports = static_cast<nsISupports*>((static_cast<nsIStreamListener*>(this)));
|
2002-08-29 22:00:20 +00:00
|
|
|
pActivePlugins->mStreams->AppendElement(supports);
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
return rv;
|
2001-06-19 01:38:20 +00:00
|
|
|
}
|
|
|
|
|
1999-07-07 08:08:40 +00:00
|
|
|
NS_IMETHODIMP
|
2005-01-05 00:21:06 +00:00
|
|
|
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
|
|
|
|
nsISupports* aContext)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
if (mHaveFiredOnStartRequest) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
mHaveFiredOnStartRequest = PR_TRUE;
|
|
|
|
|
2001-09-28 03:34:53 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
|
|
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-16 01:23:16 +00:00
|
|
|
// deal with 404 (Not Found) HTTP response,
|
|
|
|
// just return, this causes the request to be ignored.
|
2002-03-16 15:58:54 +00:00
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
|
|
|
if (httpChannel) {
|
2002-02-16 01:23:16 +00:00
|
|
|
PRUint32 responseCode = 0;
|
|
|
|
rv = httpChannel->GetResponseStatus(&responseCode);
|
2008-08-04 21:17:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2002-03-18 00:09:48 +00:00
|
|
|
// NPP_Notify() will be called from OnStopRequest
|
2008-09-15 12:45:01 +00:00
|
|
|
// in nsNPAPIPluginStreamListener::CleanUpStream
|
2002-02-16 01:23:16 +00:00
|
|
|
// return error will cancel this request
|
2002-03-18 00:09:48 +00:00
|
|
|
// ...and we also need to tell the plugin that
|
|
|
|
mRequestFailed = PR_TRUE;
|
2002-02-16 01:23:16 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2008-08-04 21:17:55 +00:00
|
|
|
|
|
|
|
if (responseCode > 206) { // not normal
|
|
|
|
PRBool bWantsAllNetworkStreams = PR_FALSE;
|
|
|
|
mInstance->GetValue(nsPluginInstanceVariable_WantsAllNetworkStreams,
|
|
|
|
(void *)&bWantsAllNetworkStreams);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!bWantsAllNetworkStreams) {
|
2008-08-04 21:17:55 +00:00
|
|
|
mRequestFailed = PR_TRUE;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
2005-01-05 00:21:06 +00:00
|
|
|
}
|
2002-03-16 15:58:54 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// do a little sanity check to make sure our frame isn't gone
|
|
|
|
// by getting the tag type and checking for an error, we can determine if
|
|
|
|
// the frame is gone
|
|
|
|
if (mOwner) {
|
|
|
|
nsCOMPtr<nsIPluginTagInfo2> pti2 = do_QueryInterface(mOwner);
|
|
|
|
NS_ENSURE_TRUE(pti2, NS_ERROR_FAILURE);
|
|
|
|
nsPluginTagType tagType;
|
|
|
|
if (NS_FAILED(pti2->GetTagType(&tagType)))
|
|
|
|
return NS_ERROR_FAILURE; // something happened to our object frame, so bail!
|
2002-02-16 01:23:16 +00:00
|
|
|
}
|
2001-03-14 02:05:21 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// Get the notification callbacks from the channel and save it as
|
|
|
|
// week ref we'll use it in nsPluginStreamInfo::RequestRead() when
|
|
|
|
// we'll create channel for byte range request.
|
|
|
|
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
|
|
|
channel->GetNotificationCallbacks(getter_AddRefs(callbacks));
|
|
|
|
if (callbacks)
|
|
|
|
mWeakPtrChannelCallbacks = do_GetWeakReference(callbacks);
|
|
|
|
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
|
|
|
channel->GetLoadGroup(getter_AddRefs(loadGroup));
|
|
|
|
if (loadGroup)
|
|
|
|
mWeakPtrChannelLoadGroup = do_GetWeakReference(loadGroup);
|
|
|
|
|
2002-10-02 20:38:46 +00:00
|
|
|
PRInt32 length;
|
|
|
|
rv = channel->GetContentLength(&length);
|
|
|
|
|
|
|
|
// it's possible for the server to not send a Content-Length.
|
|
|
|
// we should still work in this case.
|
|
|
|
if (NS_FAILED(rv) || length == -1) {
|
2004-10-11 04:01:49 +00:00
|
|
|
// check out if this is file channel
|
2002-10-02 20:38:46 +00:00
|
|
|
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel);
|
|
|
|
if (fileChannel) {
|
|
|
|
// file does not exist
|
|
|
|
mRequestFailed = PR_TRUE;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
mPluginStreamInfo->SetLength(PRUint32(0));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mPluginStreamInfo->SetLength(length);
|
|
|
|
}
|
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
mPluginStreamInfo->SetRequest(request);
|
|
|
|
|
2005-09-21 19:14:30 +00:00
|
|
|
nsCAutoString aContentType; // XXX but we already got the type above!
|
2002-03-20 22:50:33 +00:00
|
|
|
rv = channel->GetContentType(aContentType);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv))
|
2002-08-07 02:17:55 +00:00
|
|
|
return rv;
|
|
|
|
|
1999-06-28 10:35:57 +00:00
|
|
|
nsCOMPtr<nsIURI> aURL;
|
|
|
|
rv = channel->GetURI(getter_AddRefs(aURL));
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv))
|
2002-08-07 02:17:55 +00:00
|
|
|
return rv;
|
|
|
|
|
|
|
|
nsCAutoString urlSpec;
|
|
|
|
aURL->GetSpec(urlSpec);
|
|
|
|
mPluginStreamInfo->SetURL(urlSpec.get());
|
1999-06-25 00:03:22 +00:00
|
|
|
|
2002-03-20 22:50:33 +00:00
|
|
|
if (!aContentType.IsEmpty())
|
|
|
|
mPluginStreamInfo->SetContentType(aContentType.get());
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
#ifdef PLUGIN_LOGGING
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
|
2002-02-16 01:23:16 +00:00
|
|
|
("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n",
|
2002-03-20 22:50:33 +00:00
|
|
|
this, request, aContentType.get(), urlSpec.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
1998-08-05 04:21:36 +00:00
|
|
|
|
1998-09-15 03:48:58 +00:00
|
|
|
nsPluginWindow *window = nsnull;
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
// if we don't have an nsIPluginInstance (mInstance), it means
|
|
|
|
// we weren't able to load a plugin previously because we
|
|
|
|
// didn't have the mimetype. Now that we do (aContentType),
|
2004-10-11 04:01:49 +00:00
|
|
|
// we'll try again with SetUpPluginInstance()
|
2005-06-08 23:42:15 +00:00
|
|
|
// which is called by InstantiateEmbeddedPlugin()
|
2001-01-10 23:49:19 +00:00
|
|
|
// NOTE: we don't want to try again if we didn't get the MIME type this time
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mInstance && mOwner && !aContentType.IsEmpty()) {
|
1999-01-25 08:05:00 +00:00
|
|
|
mOwner->GetInstance(mInstance);
|
1998-09-15 03:48:58 +00:00
|
|
|
mOwner->GetWindow(window);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mInstance && mHost && window) {
|
2001-01-10 23:49:19 +00:00
|
|
|
// determine if we need to try embedded again. FullPage takes a different code path
|
2001-01-12 23:45:03 +00:00
|
|
|
nsPluginMode mode;
|
|
|
|
mOwner->GetMode(&mode);
|
|
|
|
if (mode == nsPluginMode_Embedded)
|
2005-06-08 23:42:15 +00:00
|
|
|
rv = mHost->InstantiateEmbeddedPlugin(aContentType.get(), aURL, mOwner);
|
2001-01-10 23:49:19 +00:00
|
|
|
else
|
2002-03-20 22:50:33 +00:00
|
|
|
rv = mHost->SetUpPluginInstance(aContentType.get(), aURL, mOwner);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_OK == rv) {
|
2001-08-16 02:59:03 +00:00
|
|
|
// GetInstance() adds a ref
|
1999-01-25 08:05:00 +00:00
|
|
|
mOwner->GetInstance(mInstance);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mInstance) {
|
1999-01-25 08:05:00 +00:00
|
|
|
mInstance->Start();
|
1998-09-15 03:48:58 +00:00
|
|
|
mOwner->CreateWidget();
|
2008-11-03 19:23:07 +00:00
|
|
|
// If we've got a native window, the let the plugin know about it.
|
|
|
|
if (window->window) {
|
2003-09-16 01:44:41 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> inst = mInstance;
|
|
|
|
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
|
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
}
|
|
|
|
}
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
}
|
1998-09-15 03:48:58 +00:00
|
|
|
|
1999-09-09 05:13:31 +00:00
|
|
|
// Set up the stream listener...
|
2001-02-21 20:38:08 +00:00
|
|
|
rv = SetUpStreamListener(request, aURL);
|
1999-09-09 05:13:31 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1998-08-05 04:21:36 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginStreamListenerPeer::OnProgress(nsIRequest *request,
|
|
|
|
nsISupports* aContext,
|
2005-01-09 20:43:35 +00:00
|
|
|
PRUint64 aProgress,
|
|
|
|
PRUint64 aProgressMax)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
1998-12-11 04:50:57 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
return rv;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStatus(nsIRequest *request,
|
2000-07-25 05:45:56 +00:00
|
|
|
nsISupports* aContext,
|
|
|
|
nsresult aStatus,
|
|
|
|
const PRUnichar* aStatusArg)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-06-25 00:03:22 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
class nsPRUintKey : public nsHashKey {
|
|
|
|
protected:
|
2008-11-03 19:23:07 +00:00
|
|
|
PRUint32 mKey;
|
2001-05-22 22:32:45 +00:00
|
|
|
public:
|
2008-11-03 19:23:07 +00:00
|
|
|
nsPRUintKey(PRUint32 key) : mKey(key) {}
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
PRUint32 HashCode(void) const {
|
|
|
|
return mKey;
|
|
|
|
}
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
PRBool Equals(const nsHashKey *aKey) const {
|
|
|
|
return mKey == ((const nsPRUintKey*)aKey)->mKey;
|
|
|
|
}
|
|
|
|
nsHashKey *Clone() const {
|
|
|
|
return new nsPRUintKey(mKey);
|
|
|
|
}
|
|
|
|
PRUint32 GetValue() { return mKey; }
|
2001-05-22 22:32:45 +00:00
|
|
|
};
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
|
|
|
|
nsISupports* aContext,
|
|
|
|
nsIInputStream *aIStream,
|
|
|
|
PRUint32 sourceOffset,
|
1999-07-07 08:08:40 +00:00
|
|
|
PRUint32 aLength)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
2002-08-29 22:00:20 +00:00
|
|
|
if (mRequestFailed)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mAbort) {
|
2001-05-22 22:32:45 +00:00
|
|
|
PRUint32 magicNumber = 0; // set it to something that is not the magic number.
|
|
|
|
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
|
|
|
if (container)
|
|
|
|
container->GetData(&magicNumber);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (magicNumber != MAGIC_REQUEST_CONTEXT) {
|
2001-05-22 22:32:45 +00:00
|
|
|
// this is not one of our range requests
|
|
|
|
mAbort = PR_FALSE;
|
|
|
|
return NS_BINDING_ABORTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-03-11 22:48:58 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-06-28 10:35:57 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mPStreamListener || !mPluginStreamInfo)
|
2001-08-16 02:59:03 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
mPluginStreamInfo->SetRequest(request);
|
|
|
|
|
2002-08-07 02:17:55 +00:00
|
|
|
const char * url = nsnull;
|
|
|
|
mPluginStreamInfo->GetURL(&url);
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
2002-02-16 01:23:16 +00:00
|
|
|
("nsPluginStreamListenerPeer::OnDataAvailable this=%p request=%p, offset=%d, length=%d, url=%s\n",
|
2002-08-07 02:17:55 +00:00
|
|
|
this, request, sourceOffset, aLength, url ? url : "no url set"));
|
1999-03-11 22:48:58 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if the plugin has requested an AsFileOnly stream, then don't
|
2000-04-22 20:50:22 +00:00
|
|
|
// call OnDataAvailable
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mStreamType != nsPluginStreamType_AsFileOnly) {
|
2001-05-22 22:32:45 +00:00
|
|
|
// get the absolute offset of the request, if one exists.
|
|
|
|
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
|
|
|
if (brr) {
|
2004-04-11 05:33:17 +00:00
|
|
|
if (!mDataForwardToRequest)
|
|
|
|
return NS_ERROR_FAILURE;
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2005-01-09 20:43:35 +00:00
|
|
|
PRInt64 absoluteOffset64 = LL_ZERO;
|
|
|
|
brr->GetStartRange(&absoluteOffset64);
|
|
|
|
|
|
|
|
// XXX handle 64-bit for real
|
|
|
|
PRInt32 absoluteOffset = (PRInt32)nsInt64(absoluteOffset64);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
// we need to track how much data we have forwarded to the
|
|
|
|
// plugin.
|
|
|
|
|
|
|
|
// FIXME: http://bugzilla.mozilla.org/show_bug.cgi?id=240130
|
|
|
|
//
|
|
|
|
// Why couldn't this be tracked on the plugin info, and not in a
|
|
|
|
// *hash table*?
|
|
|
|
nsPRUintKey key(absoluteOffset);
|
|
|
|
PRInt32 amtForwardToPlugin =
|
|
|
|
NS_PTR_TO_INT32(mDataForwardToRequest->Get(&key));
|
|
|
|
mDataForwardToRequest->Put(&key, NS_INT32_TO_PTR(amtForwardToPlugin + aLength));
|
|
|
|
|
|
|
|
mPluginStreamInfo->SetStreamOffset(absoluteOffset + amtForwardToPlugin);
|
2001-05-22 22:32:45 +00:00
|
|
|
}
|
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
nsCOMPtr<nsIInputStream> stream = aIStream;
|
|
|
|
|
|
|
|
// if we are caching the file ourselves to disk, we want to 'tee' off
|
|
|
|
// the data as the plugin read from the stream. We do this by the magic
|
|
|
|
// of an input stream tee.
|
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
if (mFileCacheOutputStream) {
|
|
|
|
rv = NS_NewInputStreamTee(getter_AddRefs(stream), aIStream, mFileCacheOutputStream);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv))
|
2001-06-19 01:38:20 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
rv = mPStreamListener->OnDataAvailable(mPluginStreamInfo,
|
|
|
|
stream,
|
2004-04-11 05:33:17 +00:00
|
|
|
aLength);
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2000-06-21 22:57:17 +00:00
|
|
|
// if a plugin returns an error, the peer must kill the stream
|
|
|
|
// else the stream and PluginStreamListener leak
|
|
|
|
if (NS_FAILED(rv))
|
2001-02-21 20:38:08 +00:00
|
|
|
request->Cancel(rv);
|
1999-04-06 01:53:37 +00:00
|
|
|
}
|
|
|
|
else
|
2000-06-21 22:57:17 +00:00
|
|
|
{
|
1999-07-01 19:30:20 +00:00
|
|
|
// if we don't read from the stream, OnStopRequest will never be called
|
1999-04-06 01:53:37 +00:00
|
|
|
char* buffer = new char[aLength];
|
2001-06-19 01:38:20 +00:00
|
|
|
PRUint32 amountRead, amountWrote = 0;
|
1999-04-06 01:53:37 +00:00
|
|
|
rv = aIStream->Read(buffer, aLength, &amountRead);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-06-19 01:38:20 +00:00
|
|
|
// if we are caching this to disk ourselves, lets write the bytes out.
|
2002-08-29 22:00:20 +00:00
|
|
|
if (mFileCacheOutputStream) {
|
|
|
|
while (amountWrote < amountRead && NS_SUCCEEDED(rv)) {
|
|
|
|
rv = mFileCacheOutputStream->Write(buffer, amountRead, &amountWrote);
|
|
|
|
}
|
|
|
|
}
|
1999-04-06 01:53:37 +00:00
|
|
|
delete [] buffer;
|
|
|
|
}
|
1999-03-11 22:48:58 +00:00
|
|
|
return rv;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request,
|
1999-07-07 08:08:40 +00:00
|
|
|
nsISupports* aContext,
|
2001-04-10 06:01:08 +00:00
|
|
|
nsresult aStatus)
|
1998-08-05 04:21:36 +00:00
|
|
|
{
|
1999-02-23 08:10:24 +00:00
|
|
|
nsresult rv = NS_OK;
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
2002-03-27 03:41:43 +00:00
|
|
|
("nsPluginStreamListenerPeer::OnStopRequest this=%p aStatus=%d request=%p\n",
|
|
|
|
this, aStatus, request));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-03-27 03:41:43 +00:00
|
|
|
// for ByteRangeRequest we're just updating the mDataForwardToRequest hash and return.
|
2001-05-22 22:32:45 +00:00
|
|
|
nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
|
|
|
|
if (brr) {
|
2005-01-09 20:43:35 +00:00
|
|
|
PRInt64 absoluteOffset64 = LL_ZERO;
|
|
|
|
brr->GetStartRange(&absoluteOffset64);
|
|
|
|
// XXX support 64-bit offsets
|
|
|
|
PRInt32 absoluteOffset = (PRInt32)nsInt64(absoluteOffset64);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
nsPRUintKey key(absoluteOffset);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
// remove the request from our data forwarding count hash.
|
2001-05-22 22:32:45 +00:00
|
|
|
(void) mDataForwardToRequest->Remove(&key);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
|
2002-03-27 03:41:43 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
|
|
|
(" ::OnStopRequest for ByteRangeRequest Started=%d\n",
|
|
|
|
absoluteOffset));
|
|
|
|
} else {
|
|
|
|
// if this is not byte range request and
|
2002-08-29 22:00:20 +00:00
|
|
|
// if we are writting the stream to disk ourselves,
|
|
|
|
// close & tear it down here
|
|
|
|
mFileCacheOutputStream = nsnull;
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
2001-05-22 22:32:45 +00:00
|
|
|
|
|
|
|
// if we still have pending stuff to do, lets not close the plugin socket.
|
|
|
|
if (--mPendingRequests > 0)
|
|
|
|
return NS_OK;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
// we keep our connections around...
|
|
|
|
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
|
2002-05-10 18:32:42 +00:00
|
|
|
if (container) {
|
|
|
|
PRUint32 magicNumber = 0; // set it to something that is not the magic number.
|
2001-05-22 22:32:45 +00:00
|
|
|
container->GetData(&magicNumber);
|
2002-05-10 18:32:42 +00:00
|
|
|
if (magicNumber == MAGIC_REQUEST_CONTEXT) {
|
|
|
|
// this is one of our range requests
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-05-22 22:32:45 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mPStreamListener)
|
2001-05-22 22:32:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-02-21 20:38:08 +00:00
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!channel)
|
2001-04-17 23:30:25 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2001-05-22 22:32:45 +00:00
|
|
|
// Set the content type to ensure we don't pass null to the plugin
|
2002-03-20 22:50:33 +00:00
|
|
|
nsCAutoString aContentType;
|
|
|
|
rv = channel->GetContentType(aContentType);
|
2008-06-27 20:19:37 +00:00
|
|
|
if (NS_FAILED(rv) && !mRequestFailed)
|
2001-05-22 22:32:45 +00:00
|
|
|
return rv;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2002-03-20 22:50:33 +00:00
|
|
|
if (!aContentType.IsEmpty())
|
|
|
|
mPluginStreamInfo->SetContentType(aContentType.get());
|
2000-10-17 20:57:36 +00:00
|
|
|
|
2002-03-18 00:09:48 +00:00
|
|
|
// set error status if stream failed so we notify the plugin
|
|
|
|
if (mRequestFailed)
|
|
|
|
aStatus = NS_ERROR_FAILURE;
|
|
|
|
|
2002-03-27 03:41:43 +00:00
|
|
|
if (NS_FAILED(aStatus)) {
|
2004-10-11 04:01:49 +00:00
|
|
|
// on error status cleanup the stream
|
2002-03-27 03:41:43 +00:00
|
|
|
// and return w/o OnFileAvailable()
|
2004-04-11 05:33:17 +00:00
|
|
|
mPStreamListener->OnStopBinding(mPluginStreamInfo, aStatus);
|
2002-03-27 03:41:43 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
// call OnFileAvailable if plugin requests stream type StreamType_AsFile or StreamType_AsFileOnly
|
|
|
|
if (mStreamType >= nsPluginStreamType_AsFile) {
|
|
|
|
nsCOMPtr<nsIFile> localFile = do_QueryInterface(mLocalCachedFile);
|
|
|
|
if (!localFile) {
|
|
|
|
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
|
|
|
|
if (cacheChannel) {
|
|
|
|
cacheChannel->GetCacheFile(getter_AddRefs(localFile));
|
|
|
|
} else {
|
|
|
|
// see if it is a file channel.
|
|
|
|
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
|
|
|
|
if (fileChannel) {
|
|
|
|
fileChannel->GetFile(getter_AddRefs(localFile));
|
|
|
|
}
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
if (localFile) {
|
|
|
|
OnFileAvailable(localFile);
|
|
|
|
}
|
2002-03-27 03:41:43 +00:00
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mStartBinding) {
|
2001-05-22 22:32:45 +00:00
|
|
|
// On start binding has been called
|
2004-04-11 05:33:17 +00:00
|
|
|
mPStreamListener->OnStopBinding(mPluginStreamInfo, aStatus);
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
2001-05-22 22:32:45 +00:00
|
|
|
// OnStartBinding hasn't been called, so complete the action.
|
2004-04-11 05:33:17 +00:00
|
|
|
mPStreamListener->OnStartBinding(mPluginStreamInfo);
|
|
|
|
mPStreamListener->OnStopBinding(mPluginStreamInfo, aStatus);
|
1998-09-27 22:21:39 +00:00
|
|
|
}
|
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
if (NS_SUCCEEDED(aStatus))
|
|
|
|
mPluginStreamInfo->SetStreamComplete(PR_TRUE);
|
|
|
|
|
2001-05-22 22:32:45 +00:00
|
|
|
return NS_OK;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
// private methods for nsPluginStreamListenerPeer
|
1999-06-23 03:29:44 +00:00
|
|
|
nsresult nsPluginStreamListenerPeer::SetUpCache(nsIURI* aURL)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2001-04-17 23:30:25 +00:00
|
|
|
nsPluginCacheListener* cacheListener = new nsPluginCacheListener(this);
|
|
|
|
// XXX: Null LoadGroup?
|
|
|
|
return NS_OpenURI(cacheListener, nsnull, aURL, nsnull);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
2001-02-21 20:38:08 +00:00
|
|
|
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
|
2000-09-20 09:27:54 +00:00
|
|
|
nsIURI* aURL)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
1999-02-04 23:37:20 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// If we don't yet have a stream listener, we need to get
|
2000-04-22 20:50:22 +00:00
|
|
|
// one from the plugin.
|
2004-10-11 04:01:49 +00:00
|
|
|
// NOTE: this should only happen when a stream was NOT created
|
|
|
|
// with GetURL or PostURL (i.e. it's the initial stream we
|
2000-04-22 20:50:22 +00:00
|
|
|
// send to the plugin as determined by the SRC or DATA attribute)
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPStreamListener == nsnull && mInstance != nsnull)
|
2001-08-16 02:59:03 +00:00
|
|
|
rv = mInstance->NewStream(&mPStreamListener);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (rv != NS_OK)
|
2001-08-16 02:59:03 +00:00
|
|
|
return rv;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPStreamListener == nsnull)
|
1999-01-25 08:05:00 +00:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
PRBool useLocalCache = PR_FALSE;
|
2000-09-20 09:27:54 +00:00
|
|
|
|
2001-04-17 23:47:01 +00:00
|
|
|
// get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
2001-05-11 21:05:08 +00:00
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
2000-09-20 09:27:54 +00:00
|
|
|
|
2001-04-17 23:47:01 +00:00
|
|
|
/*
|
2000-09-20 09:27:54 +00:00
|
|
|
* Assumption
|
|
|
|
* By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
|
|
|
|
* called, all the headers have been read.
|
|
|
|
*/
|
2002-09-12 19:12:56 +00:00
|
|
|
if (httpChannel) {
|
2007-03-16 23:53:16 +00:00
|
|
|
// Reassemble the HTTP response status line and provide it to our
|
|
|
|
// listener. Would be nice if we could get the raw status line,
|
|
|
|
// but nsIHttpChannel doesn't currently provide that.
|
|
|
|
nsCOMPtr<nsIHTTPHeaderListener> listener =
|
|
|
|
do_QueryInterface(mPStreamListener);
|
|
|
|
if (listener) {
|
|
|
|
// Status code: required; the status line isn't useful without it.
|
|
|
|
PRUint32 statusNum;
|
|
|
|
if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) &&
|
|
|
|
statusNum < 1000) {
|
|
|
|
// HTTP version: provide if available. Defaults to empty string.
|
|
|
|
nsCString ver;
|
|
|
|
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
|
|
|
|
do_QueryInterface(channel);
|
|
|
|
if (httpChannelInternal) {
|
|
|
|
PRUint32 major, minor;
|
|
|
|
if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major,
|
|
|
|
&minor))) {
|
|
|
|
ver = nsPrintfCString("/%lu.%lu", major, minor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Status text: provide if available. Defaults to "OK".
|
|
|
|
nsCString statusText;
|
2007-03-23 20:35:04 +00:00
|
|
|
if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) {
|
2007-03-16 23:53:16 +00:00
|
|
|
statusText = "OK";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assemble everything and pass to listener.
|
|
|
|
nsPrintfCString status(100, "HTTP%s %lu %s", ver.get(), statusNum,
|
|
|
|
statusText.get());
|
|
|
|
listener->StatusLine(status.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Also provide all HTTP response headers to our listener.
|
2001-05-11 21:05:08 +00:00
|
|
|
httpChannel->VisitResponseHeaders(this);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
PRBool bSeekable = PR_FALSE;
|
2005-07-22 18:29:34 +00:00
|
|
|
// first we look for a content-encoding header. If we find one, we tell the
|
|
|
|
// plugin that stream is not seekable, because the plugin always sees
|
|
|
|
// uncompressed data, so it can't make meaningful range requests on a
|
|
|
|
// compressed entity. Also, we force the plugin to use
|
|
|
|
// nsPluginStreamType_AsFile stream type and we have to save decompressed
|
|
|
|
// file into local plugin cache, because necko cache contains original
|
|
|
|
// compressed file.
|
|
|
|
nsCAutoString contentEncoding;
|
|
|
|
if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
|
|
|
|
contentEncoding))) {
|
|
|
|
useLocalCache = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
// set seekability (seekable if the stream has a known length and if the
|
|
|
|
// http server accepts byte ranges).
|
|
|
|
PRUint32 length;
|
|
|
|
mPluginStreamInfo->GetLength(&length);
|
|
|
|
if (length) {
|
2002-09-12 19:12:56 +00:00
|
|
|
nsCAutoString range;
|
|
|
|
if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("accept-ranges"), range)) &&
|
|
|
|
range.Equals(NS_LITERAL_CSTRING("bytes"), nsCaseInsensitiveCStringComparator())) {
|
|
|
|
bSeekable = PR_TRUE;
|
|
|
|
// nsPluginStreamInfo.mSeekable intitialized by PR_FALSE in ctor of nsPluginStreamInfo
|
|
|
|
// so we reset it only here.
|
|
|
|
mPluginStreamInfo->SetSeekable(bSeekable);
|
|
|
|
}
|
|
|
|
}
|
2005-07-22 18:29:34 +00:00
|
|
|
}
|
2001-07-17 01:19:19 +00:00
|
|
|
|
2005-07-22 18:29:34 +00:00
|
|
|
// we require a content len
|
|
|
|
// get Last-Modified header for plugin info
|
|
|
|
nsCAutoString lastModified;
|
|
|
|
if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) &&
|
2008-11-03 19:23:07 +00:00
|
|
|
!lastModified.IsEmpty()) {
|
2005-07-22 18:29:34 +00:00
|
|
|
PRTime time64;
|
2006-11-01 23:02:18 +00:00
|
|
|
PR_ParseTimeString(lastModified.get(), PR_TRUE, &time64); //convert string time to integer time
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-07-22 18:29:34 +00:00
|
|
|
// Convert PRTime to unix-style time_t, i.e. seconds since the epoch
|
|
|
|
double fpTime;
|
|
|
|
LL_L2D(fpTime, time64);
|
|
|
|
mPluginStreamInfo->SetLastModified((PRUint32)(fpTime * 1e-6 + 0.5));
|
2001-04-17 23:47:01 +00:00
|
|
|
}
|
2002-09-12 19:12:56 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
rv = mPStreamListener->OnStartBinding(mPluginStreamInfo);
|
1998-12-11 04:50:57 +00:00
|
|
|
|
2000-09-20 09:27:54 +00:00
|
|
|
mStartBinding = PR_TRUE;
|
2001-08-10 19:49:04 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
mPStreamListener->GetStreamType(&mStreamType);
|
2002-09-12 19:12:56 +00:00
|
|
|
|
|
|
|
if (!useLocalCache && mStreamType >= nsPluginStreamType_AsFile) {
|
|
|
|
// check it out if this is not a file channel.
|
|
|
|
nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
|
|
|
|
if (!fileChannel) {
|
|
|
|
// and browser cache is not available
|
|
|
|
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
|
|
|
|
if (!(cacheChannel && (NS_SUCCEEDED(cacheChannel->SetCacheAsFile(PR_TRUE))))) {
|
|
|
|
useLocalCache = PR_TRUE;
|
2002-04-22 01:08:27 +00:00
|
|
|
}
|
|
|
|
}
|
2001-08-10 19:49:04 +00:00
|
|
|
}
|
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
if (useLocalCache) {
|
|
|
|
SetupPluginCacheFile(channel);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
1999-03-11 22:48:58 +00:00
|
|
|
nsresult
|
2002-04-27 05:33:09 +00:00
|
|
|
nsPluginStreamListenerPeer::OnFileAvailable(nsIFile* aFile)
|
1999-03-11 22:48:58 +00:00
|
|
|
{
|
2000-06-21 22:57:17 +00:00
|
|
|
nsresult rv;
|
|
|
|
if (!mPStreamListener)
|
|
|
|
return NS_ERROR_FAILURE;
|
1998-12-11 04:50:57 +00:00
|
|
|
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString path;
|
|
|
|
rv = aFile->GetNativePath(path);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (path.IsEmpty()) {
|
|
|
|
NS_WARNING("empty path");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-04-11 05:33:17 +00:00
|
|
|
rv = mPStreamListener->OnFileAvailable(mPluginStreamInfo, path.get());
|
2000-06-21 22:57:17 +00:00
|
|
|
return rv;
|
1998-12-11 04:50:57 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
NS_IMETHODIMP
|
2002-03-20 22:50:33 +00:00
|
|
|
nsPluginStreamListenerPeer::VisitHeader(const nsACString &header, const nsACString &value)
|
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
|
|
|
{
|
2001-05-11 21:05:08 +00:00
|
|
|
nsCOMPtr<nsIHTTPHeaderListener> listener = do_QueryInterface(mPStreamListener);
|
|
|
|
if (!listener)
|
|
|
|
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
|
|
|
|
2002-03-20 22:50:33 +00:00
|
|
|
return listener->NewResponseHeader(PromiseFlatCString(header).get(),
|
|
|
|
PromiseFlatCString(value).get());
|
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
|
|
|
}
|
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
nsPluginHostImpl::nsPluginHostImpl()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
1999-01-25 08:05:00 +00:00
|
|
|
mPluginsLoaded = PR_FALSE;
|
2000-09-14 23:58:17 +00:00
|
|
|
mDontShowBadPluginMessage = PR_FALSE;
|
2001-03-12 02:07:15 +00:00
|
|
|
mIsDestroyed = PR_FALSE;
|
2002-03-26 06:30:33 +00:00
|
|
|
mOverrideInternalTypes = PR_FALSE;
|
2002-04-27 01:47:18 +00:00
|
|
|
mAllowAlienStarHandler = PR_FALSE;
|
2002-06-26 04:32:49 +00:00
|
|
|
mUnusedLibraries.Clear();
|
2005-01-05 00:21:06 +00:00
|
|
|
mDefaultPluginDisabled = PR_FALSE;
|
2005-11-06 18:34:03 +00:00
|
|
|
mJavaEnabled = PR_TRUE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
gActivePluginList = &mActivePluginList;
|
|
|
|
|
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
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
rv = mPrefService->GetBoolPref("plugin.allow_alien_star_handler", &tmp);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mAllowAlienStarHandler = tmp;
|
|
|
|
}
|
2005-01-05 00:21:06 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
rv = mPrefService->GetBoolPref("plugin.default_plugin_disabled", &tmp);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mDefaultPluginDisabled = tmp;
|
|
|
|
}
|
2005-07-13 19:08:20 +00:00
|
|
|
|
|
|
|
#ifdef WINCE
|
|
|
|
mDefaultPluginDisabled = PR_TRUE;
|
|
|
|
#endif
|
2005-11-06 18:34:03 +00:00
|
|
|
|
|
|
|
rv = mPrefService->GetBoolPref("security.enable_java", &tmp);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mJavaEnabled = tmp;
|
|
|
|
}
|
2002-04-27 01:47:18 +00:00
|
|
|
}
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2001-10-22 22:01:27 +00:00
|
|
|
nsCOMPtr<nsIObserverService> obsService = do_GetService("@mozilla.org/observer-service;1");
|
2001-03-12 02:07:15 +00:00
|
|
|
if (obsService)
|
2001-03-31 02:26:51 +00:00
|
|
|
{
|
2002-05-31 08:05:14 +00:00
|
|
|
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, 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"));
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHostImpl::ctor)\n"));
|
|
|
|
PR_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHostImpl::ctor\n"));
|
2001-08-16 02:59:03 +00:00
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
2001-10-18 12:26:23 +00:00
|
|
|
mCachedPlugins = nsnull;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsPluginHostImpl::~nsPluginHostImpl()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHostImpl::dtor\n"));
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2008-03-19 22:05:04 +00:00
|
|
|
NS_IMPL_ISUPPORTS8(nsPluginHostImpl,
|
2000-07-22 01:34:13 +00:00
|
|
|
nsIPluginManager,
|
|
|
|
nsIPluginManager2,
|
|
|
|
nsIPluginHost,
|
|
|
|
nsIFileUtilities,
|
2001-03-12 02:07:15 +00:00
|
|
|
nsICookieStorage,
|
2001-04-03 22:49:38 +00:00
|
|
|
nsIObserver,
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPIPluginHost,
|
|
|
|
nsISupportsWeakReference)
|
2008-11-03 19:23:07 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginHostImpl*
|
|
|
|
nsPluginHostImpl::GetInst()
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2005-11-06 18:34:03 +00:00
|
|
|
if (!sInst) {
|
|
|
|
sInst = new nsPluginHostImpl();
|
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
|
|
|
// Must call this after the refcount is already 1!
|
|
|
|
if (NS_FAILED(sInst->AddPrefObserver())) {
|
|
|
|
NS_RELEASE(sInst);
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2007-01-28 19:50:37 +00:00
|
|
|
// static
|
|
|
|
const char *
|
|
|
|
nsPluginHostImpl::GetPluginName(nsIPluginInstance *aPluginInstance)
|
|
|
|
{
|
|
|
|
nsActivePlugin *plugin =
|
|
|
|
gActivePluginList ? gActivePluginList->find(aPluginInstance) : nsnull;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin && plugin->mPluginTag)
|
2008-03-10 07:07:15 +00:00
|
|
|
return plugin->mPluginTag->mName.get();
|
2007-01-28 19:50:37 +00:00
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2000-07-20 01:16:52 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetValue(nsPluginManagerVariable aVariable, void *aValue)
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2000-07-20 01:16:52 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aValue);
|
|
|
|
|
2003-03-04 03:58:43 +00:00
|
|
|
#if defined(XP_UNIX) && !defined(XP_MACOSX) && defined(MOZ_X11)
|
2000-07-20 01:16:52 +00:00
|
|
|
if (nsPluginManagerVariable_XDisplay == aVariable) {
|
2007-07-08 07:08:04 +00:00
|
|
|
Display** value = reinterpret_cast<Display**>(aValue);
|
2007-04-30 23:52:44 +00:00
|
|
|
#if defined (MOZ_WIDGET_GTK2)
|
2000-11-30 22:01:45 +00:00
|
|
|
*value = GDK_DISPLAY();
|
|
|
|
#endif
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!(*value))
|
2000-11-30 22:01:45 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-07-20 01:16:52 +00:00
|
|
|
#endif
|
2003-09-16 01:44:41 +00:00
|
|
|
if (nsPluginManagerVariable_SupportsXEmbed == aVariable) {
|
|
|
|
#ifdef MOZ_WIDGET_GTK2
|
|
|
|
*(NPBool*)aValue = PR_TRUE;
|
|
|
|
#else
|
|
|
|
*(NPBool*)aValue = PR_FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
2000-07-20 01:16:52 +00:00
|
|
|
return rv;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
PRBool nsPluginHostImpl::IsRunningPlugin(nsPluginTag * plugin)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin)
|
2001-02-02 23:48:17 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
// we can check for mLibrary to be non-zero and then querry nsIPluginInstancePeer
|
|
|
|
// in nsActivePluginList to see if plugin with matching mime type is not stopped
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin->mLibrary)
|
2001-02-02 23:48:17 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
for (int i = 0; i < plugin->mVariants; i++) {
|
2001-02-02 23:48:17 +00:00
|
|
|
nsActivePlugin * p = mActivePluginList.find(plugin->mMimeTypeArray[i]);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p && !p->mStopped)
|
2001-02-02 23:48:17 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
|
1998-07-28 02:07:25 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("nsPluginHostImpl::ReloadPlugins Begin reloadPages=%d, active_instance_count=%d\n",
|
|
|
|
reloadPages, mActivePluginList.mCount));
|
|
|
|
|
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;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
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
|
2007-07-14 00:28:05 +00:00
|
|
|
mActivePluginList.stopRunning(instsToReload, nsnull);
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// clean active plugin list
|
|
|
|
mActivePluginList.removeAllStopped();
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
2001-10-08 23:00:58 +00:00
|
|
|
// XXX only remove our plugin from the list if it's not running and not
|
|
|
|
// an XPCOM plugin. XPCOM plugins do not get a call to nsIPlugin::Shutdown
|
|
|
|
// if plugins are reloaded. This also fixes a crash on UNIX where the call
|
|
|
|
// to shutdown would break the ProxyJNI connection to the JRE after a reload.
|
|
|
|
// see bug 86591
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!IsRunningPlugin(p) && (!p->mEntryPoint || p->HasFlag(NS_PLUGIN_FLAG_OLDSCHOOL))) {
|
|
|
|
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;
|
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,
|
|
|
|
("nsPluginHostImpl::ReloadPlugins End active_instance_count=%d\n",
|
|
|
|
mActivePluginList.mCount));
|
|
|
|
|
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
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
nsresult nsPluginHostImpl::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
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHostImpl::UserAgent return=%s\n", *retstring));
|
|
|
|
|
1998-10-28 21:16:00 +00:00
|
|
|
return res;
|
1998-07-28 02:07:25 +00:00
|
|
|
}
|
|
|
|
|
2007-10-10 01:24:28 +00:00
|
|
|
nsresult nsPluginHostImpl::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
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetURL(nsISupports* pluginInst,
|
|
|
|
const char* url,
|
2001-08-16 02:59:03 +00:00
|
|
|
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
|
|
|
{
|
2004-10-11 04:01:49 +00:00
|
|
|
return GetURLWithHeaders(pluginInst, url, target, streamListener,
|
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
|
|
|
altHost, referrer, forceJSEnabled, nsnull, nsnull);
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetURLWithHeaders(nsISupports* pluginInst,
|
|
|
|
const char* url,
|
2001-08-16 02:59:03 +00:00
|
|
|
const char* target,
|
|
|
|
nsIPluginStreamListener* streamListener,
|
|
|
|
const char* altHost,
|
|
|
|
const char* referrer,
|
|
|
|
PRBool forceJSEnabled,
|
2004-10-11 04:01:49 +00:00
|
|
|
PRUint32 getHeadersLength,
|
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
|
|
|
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)
|
2001-08-16 02:59:03 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
nsresult rv;
|
2002-09-18 20:16:16 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instance = do_QueryInterface(pluginInst, &rv);
|
2003-04-03 19:11:41 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
2005-02-04 16:54:11 +00:00
|
|
|
rv = DoURLLoadSecurityCheck(instance, url);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
if (target) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsIPluginInstancePeer> peer;
|
|
|
|
rv = instance->GetPeer(getter_AddRefs(peer));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && peer) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> privpeer(do_QueryInterface(peer));
|
2000-06-16 22:27:16 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2002-08-23 11:23:49 +00:00
|
|
|
rv = privpeer->GetOwner(getter_AddRefs(owner));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (owner) {
|
2004-10-11 04:01:49 +00:00
|
|
|
if ((0 == PL_strcmp(target, "newwindow")) ||
|
1999-01-25 08:05:00 +00:00
|
|
|
(0 == PL_strcmp(target, "_new")))
|
|
|
|
target = "_blank";
|
|
|
|
else if (0 == PL_strcmp(target, "_current"))
|
|
|
|
target = "_self";
|
|
|
|
|
2002-08-23 11:23:49 +00:00
|
|
|
rv = owner->GetURL(url, target, nsnull, 0, (void *) getHeaders, getHeadersLength);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (streamListener) {
|
2004-10-11 04:01:49 +00:00
|
|
|
rv = NewPluginURLStream(string, instance, streamListener, nsnull,
|
2001-04-17 23:30:25 +00:00
|
|
|
PR_FALSE, nsnull, getHeaders, getHeadersLength);
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::PostURL(nsISupports* pluginInst,
|
2001-08-16 02:59:03 +00:00
|
|
|
const char* url,
|
2004-10-11 04:01:49 +00:00
|
|
|
PRUint32 postDataLen,
|
2001-08-16 02:59:03 +00:00
|
|
|
const char* postData,
|
|
|
|
PRBool isFile,
|
|
|
|
const char* target,
|
|
|
|
nsIPluginStreamListener* streamListener,
|
2004-10-11 04:01:49 +00:00
|
|
|
const char* altHost,
|
2001-08-16 02:59:03 +00:00
|
|
|
const char* referrer,
|
|
|
|
PRBool forceJSEnabled,
|
2004-10-11 04:01:49 +00:00
|
|
|
PRUint32 postHeadersLength,
|
2001-08-16 02:59:03 +00:00
|
|
|
const char* postHeaders)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
nsAutoString string; string.AssignWithConversion(url);
|
|
|
|
nsresult rv;
|
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)
|
2001-08-16 02:59:03 +00:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-18 20:16:16 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instance = do_QueryInterface(pluginInst, &rv);
|
2003-04-03 19:11:41 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
2005-02-04 16:54:11 +00:00
|
|
|
rv = DoURLLoadSecurityCheck(instance, url);
|
2003-04-03 19:11:41 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
char *dataToPost;
|
|
|
|
if (isFile) {
|
|
|
|
rv = CreateTmpFileToPost(postData, &dataToPost);
|
|
|
|
if (NS_FAILED(rv) || !dataToPost)
|
|
|
|
return rv;
|
|
|
|
} else {
|
|
|
|
PRUint32 newDataToPostLen;
|
|
|
|
ParsePostBufferToFixHeaders(postData, postDataLen, &dataToPost, &newDataToPostLen);
|
|
|
|
if (!dataToPost)
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
2002-08-22 18:12:59 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// we use nsIStringInputStream::adoptDataa()
|
|
|
|
// in NS_NewPluginPostDataStream to set the stream
|
|
|
|
// all new data alloced in ParsePostBufferToFixHeaders()
|
|
|
|
// well be nsMemory::Free()d on destroy the stream
|
|
|
|
postDataLen = newDataToPostLen;
|
|
|
|
}
|
2002-01-30 02:40:46 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (target) {
|
|
|
|
nsCOMPtr<nsIPluginInstancePeer> peer;
|
|
|
|
rv = instance->GetPeer(getter_AddRefs(peer));
|
|
|
|
if (NS_SUCCEEDED(rv) && peer) {
|
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> privpeer(do_QueryInterface(peer));
|
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
|
|
|
rv = privpeer->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (owner) {
|
|
|
|
if (!target) {
|
|
|
|
target = "_self";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ((0 == PL_strcmp(target, "newwindow")) ||
|
|
|
|
(0 == PL_strcmp(target, "_new"))) {
|
|
|
|
target = "_blank";
|
2002-08-22 18:12:59 +00:00
|
|
|
}
|
2008-11-03 19:23:07 +00:00
|
|
|
else if (0 == PL_strcmp(target, "_current")) {
|
|
|
|
target = "_self";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rv = owner->GetURL(url, target, (void*)dataToPost, postDataLen,
|
|
|
|
(void*)postHeaders, postHeadersLength, isFile);
|
2002-08-22 01:31:44 +00:00
|
|
|
}
|
2002-08-22 18:12:59 +00:00
|
|
|
}
|
2008-11-03 19:23:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// if we don't have a target, just create a stream. This does
|
|
|
|
// NS_OpenURI()!
|
|
|
|
if (streamListener)
|
|
|
|
rv = NewPluginURLStream(string, instance, streamListener,
|
|
|
|
(const char*)dataToPost, isFile, postDataLen,
|
|
|
|
postHeaders, postHeadersLength);
|
|
|
|
if (isFile)
|
|
|
|
NS_Free(dataToPost);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
|
|
|
|
const char* aPluginName,
|
|
|
|
const char* aDescription,
|
|
|
|
const char** aMimeTypes,
|
|
|
|
const char** aMimeDescriptions,
|
|
|
|
const char** aFileExtensions,
|
|
|
|
PRInt32 aCount)
|
|
|
|
{
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::UnregisterPlugin(REFNSIID aCID)
|
|
|
|
{
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2000-07-22 01:34:13 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::BeginWaitCursor(void)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::EndWaitCursor(void)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::SupportsURLProtocol(const char* protocol, PRBool *result)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::NotifyStatusChange(nsIPlugin* plugin, nsresult errorStatus)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
1998-09-01 00:17:25 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::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
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::RegisterWindow(nsIEventHandler* handler, nsPluginPlatformWindowRef window)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::UnregisterWindow(nsIEventHandler* handler, nsPluginPlatformWindowRef window)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::AllocateMenuID(nsIEventHandler* handler, PRBool isSubmenu, PRInt16 *result)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::DeallocateMenuID(nsIEventHandler* handler, PRInt16 menuID)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::HasAllocatedMenuID(nsIEventHandler* handler, PRInt16 menuID, PRBool *result)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::ProcessNextEvent(PRBool *bEventHandled)
|
1998-09-27 22:21:39 +00:00
|
|
|
{
|
1998-09-01 00:17:25 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1998-08-01 05:46:47 +00:00
|
|
|
}
|
1998-07-28 02:07:25 +00:00
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::CreateInstance(nsISupports *aOuter,
|
|
|
|
REFNSIID aIID,
|
|
|
|
void **aResult)
|
|
|
|
{
|
|
|
|
NS_NOTREACHED("how'd I get here?");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::LockFactory(PRBool aLock)
|
|
|
|
{
|
|
|
|
NS_NOTREACHED("how'd I get here?");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::Init(void)
|
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
|
|
|
}
|
|
|
|
|
1999-03-03 04:10:54 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHostImpl::Destroy Called\n"));
|
|
|
|
|
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
|
2007-07-14 00:28:05 +00:00
|
|
|
mActivePluginList.stopRunning(nsnull, nsnull);
|
2001-04-16 21:26:28 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
// at this point nsIPlugin::Shutdown calls will be performed if needed
|
|
|
|
mActivePluginList.shut();
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPluginPath) {
|
2001-03-31 02:26:51 +00:00
|
|
|
PR_Free(mPluginPath);
|
|
|
|
mPluginPath = nsnull;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
while (mPlugins) {
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> temp = mPlugins->mNext;
|
2004-10-11 04:01:49 +00:00
|
|
|
// while walking through the list of the plugins see if we still have anything
|
|
|
|
// to shutdown some plugins may have never created an instance but still expect
|
2001-04-11 23:08:36 +00:00
|
|
|
// the shutdown call see bugzilla bug 73071
|
2004-10-11 04:01:49 +00:00
|
|
|
// with current logic, no need to do anything special as nsIPlugin::Shutdown
|
2001-04-11 23:08:36 +00:00
|
|
|
// will be performed in the destructor
|
2007-07-03 21:42:35 +00:00
|
|
|
mPlugins->mNext = nsnull;
|
2001-03-31 02:26:51 +00:00
|
|
|
mPlugins = temp;
|
|
|
|
}
|
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
// Delete any remaining cached plugins list
|
2007-07-03 21:42:35 +00:00
|
|
|
mCachedPlugins = nsnull;
|
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
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsCOMPtr<nsIPrefBranch2> prefBranch(do_QueryInterface(mPrefService));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (prefBranch)
|
2005-11-06 18:34:03 +00:00
|
|
|
prefBranch->RemoveObserver("security.enable_java", this);
|
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
|
|
|
|
2002-12-26 22:54:46 +00:00
|
|
|
void nsPluginHostImpl::UnloadUnusedLibraries()
|
|
|
|
{
|
2002-06-26 04:32:49 +00:00
|
|
|
// unload any remaining plugin libraries from memory
|
|
|
|
for (PRInt32 i = 0; i < mUnusedLibraries.Count(); i++) {
|
|
|
|
PRLibrary * library = (PRLibrary *)mUnusedLibraries[i];
|
|
|
|
if (library)
|
|
|
|
PostPluginUnloadEvent(library);
|
|
|
|
}
|
|
|
|
mUnusedLibraries.Clear();
|
1998-09-15 03:48:58 +00:00
|
|
|
}
|
|
|
|
|
2005-02-11 23:37:51 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHostImpl::GetPluginTempDir(nsIFile **aDir)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2005-09-21 19:14:30 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::InstantiatePluginForChannel(nsIChannel* aChannel,
|
|
|
|
nsIPluginInstanceOwner* aOwner,
|
|
|
|
nsIStreamListener** aListener)
|
|
|
|
{
|
|
|
|
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,
|
|
|
|
("nsPluginHostImpl::InstantiatePluginForChannel Begin owner=%p, url=%s\n",
|
|
|
|
aOwner, urlSpec.get()));
|
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// XXX do we need to look for stopped plugins, like InstantiateEmbeddedPlugin
|
|
|
|
// does?
|
|
|
|
|
|
|
|
return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener);
|
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by nsPluginInstanceOwner (nsObjectFrame.cpp - embedded case)
|
2005-06-08 23:42:15 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbeddedPlugin(const char *aMimeType,
|
1999-06-23 03:29:44 +00:00
|
|
|
nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner)
|
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,
|
2006-06-03 23:23:45 +00:00
|
|
|
("nsPluginHostImpl::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
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
nsresult rv;
|
1999-03-11 22:48:58 +00:00
|
|
|
nsIPluginInstance *instance = nsnull;
|
2001-08-10 01:53:38 +00:00
|
|
|
nsCOMPtr<nsIPluginTagInfo2> pti2;
|
2000-06-20 21:04:52 +00:00
|
|
|
nsPluginTagType tagType;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2000-06-20 21:04:52 +00:00
|
|
|
rv = aOwner->QueryInterface(kIPluginTagInfo2IID, getter_AddRefs(pti2));
|
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
|
|
|
|
2000-06-20 21:04:52 +00:00
|
|
|
rv = pti2->GetTagType(&tagType);
|
|
|
|
|
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
|
|
|
|
if (aURL) {
|
|
|
|
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;
|
|
|
|
pti2->GetDOMElement(getter_AddRefs(elem));
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
// Look for even disabled plugins, because if the plugin for this type is
|
|
|
|
// disabled, we don't want to go on and end up in SetUpDefaultPluginInstance.
|
|
|
|
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_FALSE);
|
|
|
|
if (pluginTag) {
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!pluginTag->IsEnabled())
|
2005-11-06 18:34:03 +00:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
} else if (!mJavaEnabled && IsJavaMIMEType(aMimeType)) {
|
|
|
|
// Even if we had no Java plugin, if mJavaEnabled is false we should throw
|
|
|
|
// here for Java types. Note that we only need to do this for the case
|
|
|
|
// when pluginTag is null; if we had a pluginTag, it would have its
|
|
|
|
// NS_PLUGIN_FLAG_ENABLED set the right way.
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
2000-06-30 17:31:02 +00:00
|
|
|
}
|
2005-11-06 18:34:03 +00:00
|
|
|
|
2007-09-04 18:19:31 +00:00
|
|
|
PRBool isJava = pluginTag && pluginTag->mIsJavaPlugin;
|
2000-06-30 17:31:02 +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
|
2002-02-28 04:47:08 +00:00
|
|
|
PRBool bCanHandleInternally = PR_FALSE;
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString scheme;
|
|
|
|
if (aURL && 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) {
|
1999-07-07 00:28:34 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
2006-06-03 23:23:45 +00:00
|
|
|
("nsPluginHostImpl::InstantiateEmbeddedPlugin FoundStopped mime=%s\n", aMimeType));
|
1999-07-07 00:28:34 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
aOwner->GetInstance(instance);
|
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
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// notify Java DOM component
|
2000-05-16 00:22:30 +00:00
|
|
|
nsresult res;
|
2004-10-11 04:01:49 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> javaDOM =
|
2001-07-25 07:54:28 +00:00
|
|
|
do_GetService("@mozilla.org/blackwood/java-dom;1", &res);
|
2000-05-16 00:22:30 +00:00
|
|
|
if (NS_SUCCEEDED(res) && javaDOM)
|
|
|
|
javaDOM->SetInstance(instance);
|
|
|
|
|
2000-05-02 22:27:58 +00:00
|
|
|
NS_IF_RELEASE(instance);
|
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
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (rv == NS_OK) {
|
2001-08-16 02:59:03 +00:00
|
|
|
rv = aOwner->GetInstance(instance);
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
|
|
|
/* If we are here, it's time to either show the default plugin
|
2002-05-30 22:31:27 +00:00
|
|
|
* or return failure so layout will replace us.
|
|
|
|
*
|
|
|
|
* Currently, the default plugin is shown for all EMBED and APPLET
|
2002-09-26 00:17:20 +00:00
|
|
|
* tags and also any OBJECT tag that has a PLUGINURL PARAM tag name.
|
2002-05-30 22:31:27 +00:00
|
|
|
*/
|
|
|
|
|
2002-09-26 00:17:20 +00:00
|
|
|
PRBool bHasPluginURL = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIPluginTagInfo2> pti2(do_QueryInterface(aOwner));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (pti2) {
|
2002-09-26 00:17:20 +00:00
|
|
|
const char *value;
|
|
|
|
bHasPluginURL = NS_SUCCEEDED(pti2->GetParameter("PLUGINURL", &value));
|
|
|
|
}
|
2002-05-30 22:31:27 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we didn't find a pluginURL param on the object tag,
|
2002-09-26 00:17:20 +00:00
|
|
|
// there's nothing more to do here
|
2008-11-03 19:23:07 +00:00
|
|
|
if (nsPluginTagType_Object == tagType && !bHasPluginURL)
|
2000-06-22 23:17:50 +00:00
|
|
|
return rv;
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(SetUpDefaultPluginInstance(aMimeType, aURL, aOwner)))
|
2002-12-17 22:53:23 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-05-26 22:14:39 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(aOwner->GetInstance(instance)))
|
2000-06-20 21:04:52 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-05-26 22:14:39 +00:00
|
|
|
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
1998-08-21 01:12:53 +00:00
|
|
|
|
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
|
|
|
|
// and it could be the Default plugin
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-08-10 01:53:38 +00:00
|
|
|
nsPluginWindow *window = nsnull;
|
1998-08-21 01:12:53 +00:00
|
|
|
|
2001-08-10 01:53:38 +00:00
|
|
|
//we got a plugin built, now stream
|
|
|
|
aOwner->GetWindow(window);
|
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.
|
2008-11-03 19:23:07 +00:00
|
|
|
if (window->window) {
|
2003-09-16 01:44:41 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> inst = instance;
|
|
|
|
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
|
|
|
|
}
|
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
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// notify Java DOM component
|
2001-08-10 01:53:38 +00:00
|
|
|
nsresult res;
|
2004-10-11 04:01:49 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> javaDOM =
|
2001-08-10 01:53:38 +00:00
|
|
|
do_GetService("@mozilla.org/blackwood/java-dom;1", &res);
|
|
|
|
if (NS_SUCCEEDED(res) && javaDOM)
|
|
|
|
javaDOM->SetInstance(instance);
|
|
|
|
|
|
|
|
NS_RELEASE(instance);
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
#ifdef PLUGIN_LOGGING
|
2002-03-06 07:48:55 +00:00
|
|
|
nsCAutoString urlSpec2;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aURL != nsnull) (void)aURL->GetAsciiSpec(urlSpec2);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2006-06-03 23:23:45 +00:00
|
|
|
("nsPluginHostImpl::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
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeType,
|
2005-04-29 12:11:45 +00:00
|
|
|
nsIURI* aURI,
|
2000-04-22 20:50:22 +00:00
|
|
|
nsIStreamListener *&aStreamListener,
|
|
|
|
nsIPluginInstanceOwner *aOwner)
|
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,
|
2006-06-03 23:23:45 +00:00
|
|
|
("nsPluginHostImpl::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,
|
2006-06-03 23:23:45 +00:00
|
|
|
("nsPluginHostImpl::InstantiateFullPagePlugin FoundStopped mime=%s\n",aMimeType));
|
1999-07-07 00:28:34 +00:00
|
|
|
|
1999-05-07 22:06:47 +00:00
|
|
|
nsIPluginInstance* instance;
|
2001-08-16 02:59:03 +00:00
|
|
|
aOwner->GetInstance(instance);
|
2005-11-06 18:34:03 +00:00
|
|
|
nsPluginTag* pluginTag = FindPluginForType(aMimeType, PR_TRUE);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!pluginTag || !pluginTag->mIsJavaPlugin)
|
2005-04-29 12:11:45 +00:00
|
|
|
NewFullPagePluginStream(aStreamListener, instance);
|
2000-05-02 22:27:58 +00:00
|
|
|
NS_IF_RELEASE(instance);
|
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) {
|
2002-09-26 02:53:27 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instance;
|
|
|
|
nsPluginWindow * win = nsnull;
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2002-09-26 02:53:27 +00:00
|
|
|
aOwner->GetInstance(*getter_AddRefs(instance));
|
|
|
|
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.
|
2002-09-26 02:53:27 +00:00
|
|
|
nsPluginNativeWindow * window = (nsPluginNativeWindow *)win;
|
2000-07-20 01:40:54 +00:00
|
|
|
if (window->window)
|
2002-09-26 02:53:27 +00:00
|
|
|
window->CallSetWindow(instance);
|
1999-01-25 08:05:00 +00:00
|
|
|
|
|
|
|
rv = NewFullPagePluginStream(aStreamListener, instance);
|
|
|
|
|
2001-03-28 01:00:47 +00:00
|
|
|
// If we've got a native window, the let the plugin know about it.
|
|
|
|
if (window->window)
|
2002-09-26 02:53:27 +00:00
|
|
|
window->CallSetWindow(instance);
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2006-06-03 23:23:45 +00:00
|
|
|
("nsPluginHostImpl::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;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult nsPluginHostImpl::FindStoppedPluginForURL(nsIURI* aURL,
|
2000-04-22 20:50: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
|
|
|
|
2002-03-06 07:48:55 +00:00
|
|
|
nsActivePlugin * plugin = mActivePluginList.findStopped(url.get());
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin && plugin->mStopped) {
|
2000-06-13 23:23:13 +00:00
|
|
|
nsIPluginInstance* instance = plugin->mInstance;
|
|
|
|
nsPluginWindow *window = nsnull;
|
|
|
|
aOwner->GetWindow(window);
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
aOwner->SetInstance(instance);
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
// we have to reset the owner and instance in the plugin instance peer
|
|
|
|
//instance->GetPeer(&peer);
|
|
|
|
((nsPluginInstancePeerImpl*)plugin->mPeer)->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.
|
2008-11-03 19:23:07 +00:00
|
|
|
if (window->window) {
|
2003-09-16 01:44:41 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> inst = instance;
|
|
|
|
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
|
|
|
|
}
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2000-06-15 01:07:27 +00:00
|
|
|
plugin->setStopped(PR_FALSE);
|
2000-06-13 23:23:13 +00:00
|
|
|
return NS_OK;
|
1999-05-07 22:06:47 +00:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2002-08-12 06:12:29 +00:00
|
|
|
nsresult nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
2001-03-12 02:07:15 +00:00
|
|
|
nsIPluginInstance* aInstance,
|
2001-02-02 23:48:17 +00:00
|
|
|
nsIURI* aURL,
|
2002-06-14 20:45:29 +00:00
|
|
|
PRBool aDefaultPlugin,
|
|
|
|
nsIPluginInstancePeer* peer)
|
2000-09-14 08:22:31 +00:00
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
{
|
2002-08-12 06:12:29 +00:00
|
|
|
nsCAutoString url;
|
2007-10-10 01:24:28 +00:00
|
|
|
// It's OK to not have a URL here, as is the case with the dummy
|
|
|
|
// Java plugin. In that case simply use an empty string...
|
|
|
|
if (aURL)
|
|
|
|
aURL->GetSpec(url);
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2002-08-12 06:12:29 +00:00
|
|
|
// let's find the corresponding plugin tag by matching nsIPlugin pointer
|
2004-10-11 04:01:49 +00:00
|
|
|
// it's legal for XPCOM plugins not to have nsIPlugin implemented but
|
2002-08-12 06:12:29 +00:00
|
|
|
// this is OK, we don't need the plugin tag for XPCOM plugins. It is going
|
|
|
|
// to be used later when we decide whether or not we should delay unloading
|
|
|
|
// NPAPI dll from memory, and XPCOM dlls will stay in memory anyway.
|
2001-04-11 23:08:36 +00:00
|
|
|
nsPluginTag * pluginTag = nsnull;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aPlugin) {
|
|
|
|
for (pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNext) {
|
|
|
|
if (pluginTag->mEntryPoint == aPlugin)
|
2001-04-11 23:08:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
NS_ASSERTION(pluginTag, "Plugin tag not found");
|
|
|
|
}
|
|
|
|
|
2002-06-14 20:45:29 +00:00
|
|
|
nsActivePlugin * plugin = new nsActivePlugin(pluginTag, aInstance, url.get(), aDefaultPlugin, peer);
|
1999-05-07 22:06:47 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin)
|
2002-08-12 06:12:29 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2000-04-26 06:19:26 +00:00
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
mActivePluginList.add(plugin);
|
2002-08-12 06:12:29 +00:00
|
|
|
return NS_OK;
|
1999-05-07 22:06:47 +00:00
|
|
|
}
|
|
|
|
|
2003-02-27 13:51:55 +00:00
|
|
|
void
|
|
|
|
nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
|
|
|
|
nsPluginTag::nsRegisterType aType)
|
2000-07-07 00:10:54 +00:00
|
|
|
{
|
2003-02-27 13:51:55 +00:00
|
|
|
if (!mMimeTypeArray)
|
|
|
|
return;
|
2000-07-07 00:10:54 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
2003-02-27 13:51:55 +00:00
|
|
|
("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
|
2008-03-10 07:07:15 +00:00
|
|
|
mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
|
2002-03-26 06:30:33 +00:00
|
|
|
|
2003-02-27 13:51:55 +00:00
|
|
|
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
|
|
|
if (!catMan)
|
|
|
|
return;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2003-04-25 00:21:12 +00:00
|
|
|
const char *contractId = "@mozilla.org/content/plugin/document-loader-factory;1";
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-02-25 09:05:15 +00:00
|
|
|
nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
|
|
|
if (!psvc)
|
|
|
|
return; // NS_ERROR_OUT_OF_MEMORY
|
|
|
|
|
|
|
|
// A preference controls whether or not the full page plugin is disabled for
|
|
|
|
// a particular type. The string must be in the form:
|
|
|
|
// type1,type2,type3,type4
|
|
|
|
// Note: need an actual interface to control this and subsequent disabling
|
|
|
|
// (and other plugin host settings) so applications can reliably disable
|
|
|
|
// plugins - without relying on implementation details such as prefs/category
|
|
|
|
// manager entries.
|
|
|
|
nsXPIDLCString overrideTypes;
|
|
|
|
psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
|
|
|
|
nsCAutoString overrideTypesFormatted;
|
|
|
|
overrideTypesFormatted.Assign(',');
|
|
|
|
overrideTypesFormatted += overrideTypes;
|
|
|
|
overrideTypesFormatted.Append(',');
|
|
|
|
|
|
|
|
nsACString::const_iterator start, end;
|
2008-11-03 19:23:07 +00:00
|
|
|
for (int i = 0; i < mVariants; i++) {
|
2003-02-27 13:51:55 +00:00
|
|
|
if (aType == ePluginUnregister) {
|
|
|
|
nsXPIDLCString value;
|
|
|
|
if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
|
|
|
|
mMimeTypeArray[i],
|
|
|
|
getter_Copies(value)))) {
|
|
|
|
// Only delete the entry if a plugin registered for it
|
2003-03-22 03:20:23 +00:00
|
|
|
if (strcmp(value, contractId) == 0) {
|
2003-02-27 13:51:55 +00:00
|
|
|
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
|
|
|
|
mMimeTypeArray[i],
|
|
|
|
PR_TRUE);
|
|
|
|
}
|
2002-07-14 00:39:35 +00:00
|
|
|
}
|
2003-02-27 13:51:55 +00:00
|
|
|
} else {
|
2005-02-25 09:05:15 +00:00
|
|
|
overrideTypesFormatted.BeginReading(start);
|
|
|
|
overrideTypesFormatted.EndReading(end);
|
|
|
|
|
|
|
|
nsDependentCString mimeType(mMimeTypeArray[i]);
|
|
|
|
nsCAutoString commaSeparated;
|
|
|
|
commaSeparated.Assign(',');
|
|
|
|
commaSeparated += mimeType;
|
|
|
|
commaSeparated.Append(',');
|
|
|
|
if (!FindInReadable(commaSeparated, start, end)) {
|
|
|
|
catMan->AddCategoryEntry("Gecko-Content-Viewers",
|
|
|
|
mMimeTypeArray[i],
|
|
|
|
contractId,
|
|
|
|
PR_FALSE, /* persist: broken by bug 193031 */
|
|
|
|
aOverrideInternalTypes, /* replace if we're told to */
|
|
|
|
nsnull);
|
|
|
|
}
|
2003-02-27 13:51:55 +00:00
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
2003-02-27 13:51:55 +00:00
|
|
|
("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
|
2008-03-10 07:07:15 +00:00
|
|
|
mMimeTypeArray[i], mFileName.get()));
|
2000-07-07 00:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
2001-03-12 02:07:15 +00:00
|
|
|
nsIURI *aURL,
|
|
|
|
nsIPluginInstanceOwner *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;
|
|
|
|
if (aOwner)
|
|
|
|
aOwner->GetDocument(getter_AddRefs(document));
|
|
|
|
|
|
|
|
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
|
|
|
|
rv = TrySetUpPluginInstance(aMimeType, aURL, aOwner);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-10-10 01:24:28 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHostImpl::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;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aURL != nsnull) (void)aURL->GetSpec(urlSpec);
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
|
2002-05-16 20:47:29 +00:00
|
|
|
("nsPluginHostImpl::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
|
|
|
|
|
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
nsresult result = NS_ERROR_FAILURE;
|
2005-01-05 00:21:06 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instance;
|
2001-03-12 02:07:15 +00:00
|
|
|
nsCOMPtr<nsIPlugin> plugin;
|
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
|
|
|
}
|
2001-03-12 02:07:15 +00:00
|
|
|
else
|
|
|
|
mimetype = aMimeType;
|
1999-03-29 22:18:05 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
NS_ASSERTION(pluginTag, "Must have plugin tag here!");
|
2007-09-04 18:19:31 +00:00
|
|
|
PRBool isJavaPlugin = pluginTag->mIsJavaPlugin;
|
2001-11-29 05:14:11 +00:00
|
|
|
|
2007-10-31 22:52:11 +00:00
|
|
|
if (isJavaPlugin && !pluginTag->mIsNPRuntimeEnabledJavaPlugin) {
|
2008-07-25 16:42:08 +00:00
|
|
|
#if !defined(OJI) && defined(XP_MACOSX)
|
|
|
|
// The MRJ plugin hangs if you try to load it with OJI disabled,
|
|
|
|
// don't even try to go there.
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
|
|
|
|
2007-10-31 22:52:11 +00:00
|
|
|
// We must make sure LiveConnect is started, if needed.
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aOwner->GetDocument(getter_AddRefs(document));
|
|
|
|
if (document) {
|
|
|
|
nsCOMPtr<nsPIDOMWindow> window =
|
|
|
|
do_QueryInterface(document->GetScriptGlobalObject());
|
|
|
|
|
|
|
|
if (window) {
|
|
|
|
window->InitJavaProperties();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:54:52 +00:00
|
|
|
#if defined(OJI) && ((defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_OS2))
|
2007-10-31 22:52:11 +00:00
|
|
|
// This is a work-around on Unix for a LiveConnect problem (bug
|
|
|
|
// 83698).
|
|
|
|
// The problem:
|
|
|
|
// The proxy JNI needs to be created by the browser. If it is
|
|
|
|
// created by someone else (e.g., a plugin) on a different thread,
|
|
|
|
// the proxy JNI will not work, and break LiveConnect. Currently,
|
|
|
|
// on Unix, when instantiating a Java plugin instance (by calling
|
|
|
|
// InstantiateEmbeddedPlugin() next), Java plugin will create the
|
|
|
|
// proxy JNI if it is not created yet. If that happens,
|
|
|
|
// LiveConnect will be broken. Before lazy start JVM was
|
|
|
|
// implemented, since at this point the browser already created
|
|
|
|
// the proxy JNI during startup, the problem did not happen.
|
|
|
|
// But after the lazy start was implemented, at this point the
|
|
|
|
// proxy JNI was not created yet, so the Java plugin created the
|
|
|
|
// proxy JNI, and broke liveConnect.
|
|
|
|
// On Windows and Mac, Java plugin does not create the proxy JNI,
|
|
|
|
// but lets the browser to create it. Hence this is a Unix-only
|
|
|
|
// problem.
|
|
|
|
//
|
|
|
|
// The work-around:
|
|
|
|
// The root cause of the problem is in Java plugin's Unix
|
|
|
|
// implementation, which should not create the proxy JNI. As a
|
|
|
|
// work-around, here we make sure the proxy JNI has been created
|
|
|
|
// by the browser, before plugin gets a chance.
|
|
|
|
//
|
2001-11-29 05:14:11 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// If Java is installed, get proxy JNI.
|
2001-11-29 05:14:11 +00:00
|
|
|
nsCOMPtr<nsIJVMManager> jvmManager = do_GetService(nsIJVMManager::GetCID(),
|
2007-10-31 22:52:11 +00:00
|
|
|
&result);
|
2001-11-29 05:14:11 +00:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
JNIEnv* proxyEnv;
|
|
|
|
// Get proxy JNI, if not created yet, create it.
|
|
|
|
jvmManager->GetProxyJNI(&proxyEnv);
|
|
|
|
}
|
|
|
|
#endif
|
2007-10-31 22:52:11 +00:00
|
|
|
}
|
2001-11-29 05:14:11 +00:00
|
|
|
|
2001-10-16 03:53:44 +00:00
|
|
|
nsCAutoString contractID(
|
|
|
|
NS_LITERAL_CSTRING(NS_INLINE_PLUGIN_CONTRACTID_PREFIX) +
|
|
|
|
nsDependentCString(mimetype));
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2001-10-16 03:53:44 +00:00
|
|
|
GetPluginFactory(mimetype, getter_AddRefs(plugin));
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
instance = do_CreateInstance(contractID.get(), &result);
|
1999-07-25 23:20:03 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// couldn't create an XPCOM plugin, try to create wrapper for a
|
|
|
|
// legacy plugin
|
|
|
|
if (NS_FAILED(result)) {
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin) {
|
2001-06-09 01:03:53 +00:00
|
|
|
#ifdef XP_WIN
|
2005-01-05 00:21:06 +00:00
|
|
|
static BOOL firstJavaPlugin = FALSE;
|
|
|
|
BOOL restoreOrigDir = FALSE;
|
2008-03-11 22:46:26 +00:00
|
|
|
char origDir[_MAX_PATH];
|
2005-01-05 00:21:06 +00:00
|
|
|
if (isJavaPlugin && !firstJavaPlugin) {
|
2008-03-11 22:46:26 +00:00
|
|
|
DWORD dw = ::GetCurrentDirectory(_MAX_PATH, origDir);
|
2005-01-05 00:21:06 +00:00
|
|
|
NS_ASSERTION(dw <= _MAX_PATH, "Falied to obtain the current directory, which may leads to incorrect class laoding");
|
|
|
|
nsCOMPtr<nsIFile> binDirectory;
|
|
|
|
result = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
|
|
|
|
getter_AddRefs(binDirectory));
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
2008-03-11 22:46:26 +00:00
|
|
|
nsCAutoString path;
|
|
|
|
binDirectory->GetNativePath(path);
|
|
|
|
restoreOrigDir = ::SetCurrentDirectory(path.get());
|
2001-06-09 01:03:53 +00:00
|
|
|
}
|
2005-01-05 00:21:06 +00:00
|
|
|
}
|
2001-06-09 01:03:53 +00:00
|
|
|
#endif
|
2005-01-05 00:21:06 +00:00
|
|
|
result = plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)getter_AddRefs(instance));
|
2001-03-12 02:07:15 +00:00
|
|
|
|
2001-06-09 01:03:53 +00:00
|
|
|
#ifdef XP_WIN
|
2005-01-05 00:21:06 +00:00
|
|
|
if (!firstJavaPlugin && restoreOrigDir) {
|
2008-03-11 22:46:26 +00:00
|
|
|
BOOL bCheck = ::SetCurrentDirectory(origDir);
|
2005-01-05 00:21:06 +00:00
|
|
|
NS_ASSERTION(bCheck, " Error restoring driectoy");
|
|
|
|
firstJavaPlugin = TRUE;
|
1999-11-16 04:18:59 +00:00
|
|
|
}
|
2005-01-05 00:21:06 +00:00
|
|
|
#endif
|
1999-07-25 23:20:03 +00:00
|
|
|
}
|
1999-03-29 22:18:05 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
nsCOMPtr<nsIPlugin> bwPlugin =
|
|
|
|
do_GetService("@mozilla.org/blackwood/pluglet-engine;1", &result);
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = bwPlugin->CreatePluginInstance(NULL,
|
|
|
|
kIPluginInstanceIID,
|
|
|
|
aMimeType,
|
|
|
|
(void **)getter_AddRefs(instance));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-03-03 04:10:54 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// neither an XPCOM or legacy plugin could be instantiated,
|
|
|
|
// so return the failure
|
|
|
|
if (NS_FAILED(result))
|
|
|
|
return result;
|
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
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
nsRefPtr<nsPluginInstancePeerImpl> peer = new nsPluginInstancePeerImpl();
|
|
|
|
if (!peer)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// set up the peer for the instance
|
|
|
|
peer->Initialize(aOwner, mimetype);
|
1999-07-25 23:20:03 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
result = instance->Initialize(peer); // this should addref the peer but not the instance or owner
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(result)) // except in some cases not Java, see bug 140931
|
|
|
|
return result; // our COM pointer will free the peer
|
1999-07-25 23:20:03 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// instance and peer will be addreffed here
|
|
|
|
result = AddInstanceToActiveList(plugin, instance, aURL, PR_FALSE, peer);
|
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,
|
2002-05-16 20:47:29 +00:00
|
|
|
("nsPluginHostImpl::TrySetupPluginInstance Finished mime=%s, rv=%d, owner=%p, url=%s\n",
|
2002-03-06 07:48:55 +00:00
|
|
|
aMimeType, result, aOwner, urlSpec2.get()));
|
2001-08-16 02:59:03 +00:00
|
|
|
|
|
|
|
PR_LogFlush();
|
|
|
|
#endif
|
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
return result;
|
1999-03-03 04:10:54 +00:00
|
|
|
}
|
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
nsresult
|
|
|
|
nsPluginHostImpl::SetUpDefaultPluginInstance(const char *aMimeType,
|
|
|
|
nsIURI *aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner)
|
2000-05-26 22:14:39 +00:00
|
|
|
{
|
2005-01-05 00:21:06 +00:00
|
|
|
if (mDefaultPluginDisabled) {
|
|
|
|
// The default plugin is disabled, don't load it.
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-04-17 23:23:19 +00:00
|
|
|
nsCOMPtr<nsIPluginInstance> instance;
|
2005-01-05 00:21:06 +00:00
|
|
|
nsCOMPtr<nsIPlugin> plugin = NULL;
|
|
|
|
const char* mimetype = aMimeType;
|
2001-08-16 02:59:03 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!aURL)
|
2000-05-26 22:14:39 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
GetPluginFactory("*", getter_AddRefs(plugin));
|
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
nsresult result;
|
2004-04-17 23:23:19 +00:00
|
|
|
instance = do_CreateInstance(NS_INLINE_PLUGIN_CONTRACTID_PREFIX "*",
|
|
|
|
&result);
|
2000-05-26 22:14:39 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// couldn't create an XPCOM plugin, try to create wrapper for a
|
|
|
|
// legacy plugin
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
if (plugin)
|
2004-04-17 23:23:19 +00:00
|
|
|
result = plugin->CreateInstance(NULL, kIPluginInstanceIID,
|
|
|
|
getter_AddRefs(instance));
|
2000-05-26 22:14:39 +00:00
|
|
|
}
|
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// neither an XPCOM or legacy plugin could be instantiated, so
|
|
|
|
// return the failure
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(result))
|
2000-05-26 22:14:39 +00:00
|
|
|
return result;
|
|
|
|
|
|
|
|
// it is adreffed here
|
|
|
|
aOwner->SetInstance(instance);
|
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
nsRefPtr<nsPluginInstancePeerImpl> peer = new nsPluginInstancePeerImpl();
|
|
|
|
if (!peer)
|
2000-05-26 22:14:39 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
// if we don't have a mimetype, check by file extension
|
2000-09-22 06:31:29 +00:00
|
|
|
nsXPIDLCString mt;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mimetype || !*mimetype) {
|
2000-09-22 06:31:29 +00:00
|
|
|
nsresult res = NS_OK;
|
2003-11-08 17:01:46 +00:00
|
|
|
nsCOMPtr<nsIMIMEService> ms (do_GetService(NS_MIMESERVICE_CONTRACTID, &res));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(res)) {
|
2004-04-15 20:56:37 +00:00
|
|
|
res = ms->GetTypeFromURI(aURL, mt);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(res))
|
2005-01-05 00:21:06 +00:00
|
|
|
mimetype = mt.get();
|
2000-09-22 06:31:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-05-26 22:14:39 +00:00
|
|
|
// set up the peer for the instance
|
2005-01-05 00:21:06 +00:00
|
|
|
peer->Initialize(aOwner, mimetype);
|
2000-05-26 22:14:39 +00:00
|
|
|
|
2005-01-05 00:21:06 +00:00
|
|
|
// this should addref the peer but not the instance or owner except
|
|
|
|
// in some cases not Java, see bug 140931 our COM pointer will free
|
|
|
|
// the peer
|
|
|
|
result = instance->Initialize(peer);
|
|
|
|
if (NS_FAILED(result))
|
|
|
|
return result;
|
2000-05-26 22:14:39 +00:00
|
|
|
|
2002-08-12 06:12:29 +00:00
|
|
|
// instance and peer will be addreffed here
|
2005-01-05 00:21:06 +00:00
|
|
|
result = AddInstanceToActiveList(plugin, instance, aURL, PR_TRUE, peer);
|
2000-05-26 22:14:39 +00:00
|
|
|
|
2002-08-12 06:12:29 +00:00
|
|
|
return result;
|
2000-05-26 22:14:39 +00:00
|
|
|
}
|
|
|
|
|
1999-03-29 22:18:05 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHostImpl::IsPluginEnabledForType(const char* aMimeType)
|
1999-01-25 08:05:00 +00:00
|
|
|
{
|
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.
|
|
|
|
nsPluginTag *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
|
2004-10-11 04:01:49 +00:00
|
|
|
nsPluginHostImpl::IsPluginEnabledForExtension(const char* aExtension,
|
2000-04-22 20:50:22 +00:00
|
|
|
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 &&
|
|
|
|
NS_SUCCEEDED(prefService->GetBoolPref("plugin.expose_full_path",&bShowPath)) &&
|
2008-11-03 19:23:07 +00:00
|
|
|
bShowPath) {
|
2002-06-24 07:17:42 +00:00
|
|
|
// only show the full path if people have set the pref,
|
|
|
|
// the default should not reveal path information (bug 88183)
|
2005-08-07 07:05:09 +00:00
|
|
|
#if defined(XP_MACOSX)
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mFullPath, aFilename);
|
2002-06-24 07:17:42 +00:00
|
|
|
#else
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mFileName, aFilename);
|
2002-06-24 07:17:42 +00:00
|
|
|
#endif
|
2008-03-10 07:07:15 +00:00
|
|
|
return NS_OK;
|
2002-06-24 07:17:42 +00:00
|
|
|
}
|
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
nsAutoString spec;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!mPluginTag.mFullPath.IsEmpty()) {
|
2005-08-07 07:05:09 +00:00
|
|
|
#if !defined(XP_MACOSX)
|
2002-06-24 07:17:42 +00:00
|
|
|
NS_ERROR("Only MAC should be using nsPluginTag::mFullPath!");
|
2001-11-17 15:26:02 +00:00
|
|
|
#endif
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mFullPath, spec);
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
2008-03-10 07:07:15 +00:00
|
|
|
CopyUTF8toUTF16(mPluginTag.mFileName, spec);
|
2002-06-24 07:17:42 +00:00
|
|
|
}
|
|
|
|
|
2003-03-22 04:04:55 +00:00
|
|
|
nsCString leafName;
|
|
|
|
nsCOMPtr<nsILocalFile> pluginPath;
|
2008-03-10 07:07:15 +00:00
|
|
|
NS_NewLocalFile(spec, PR_TRUE, getter_AddRefs(pluginPath));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
return pluginPath->GetLeafName(aFilename);
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
nsPluginHostImpl::GetPluginCount(PRUint32* aPluginCount)
|
|
|
|
{
|
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
|
2005-01-17 14:41:45 +00:00
|
|
|
nsPluginHostImpl::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
|
|
|
|
nsPluginHostImpl::GetPluginTags(PRUint32* aPluginCount, nsIPluginTag*** aResults)
|
|
|
|
{
|
|
|
|
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*
|
|
|
|
nsPluginHostImpl::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
|
|
|
|
if (nsnull != aMimeType) {
|
1999-03-23 03:18:12 +00:00
|
|
|
plugins = mPlugins;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2000-04-22 20:50:22 +00:00
|
|
|
while (nsnull != 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
|
|
|
}
|
|
|
|
}
|
1999-03-23 03:18:12 +00:00
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
plugins = plugins->mNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginTag*
|
|
|
|
nsPluginHostImpl::FindPluginEnabledForExtension(const char* aExtension,
|
|
|
|
const char*& aMimeType)
|
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2002-11-06 01:24:57 +00:00
|
|
|
#if defined(XP_MACOSX)
|
2008-11-03 19:23:07 +00:00
|
|
|
/* The following code examines the format of a Mac OS X binary, and determines whether it
|
2005-08-08 08:03:41 +00:00
|
|
|
* is compatible with the current executable.
|
2002-11-06 01:24:57 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2006-05-26 17:56:18 +00:00
|
|
|
static inline PRBool is_directory(const char* path)
|
2002-11-06 01:24:57 +00:00
|
|
|
{
|
|
|
|
struct stat sb;
|
2006-05-26 17:56:18 +00:00
|
|
|
return ::stat(path, &sb) == 0 && S_ISDIR(sb.st_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline PRBool is_symbolic_link(const char* path)
|
|
|
|
{
|
|
|
|
struct stat sb;
|
|
|
|
return ::lstat(path, &sb) == 0 && S_ISLNK(sb.st_mode);
|
2002-11-06 01:24:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int open_executable(const char* path)
|
|
|
|
{
|
|
|
|
int fd = 0;
|
2006-05-26 17:56:18 +00:00
|
|
|
char resolvedPath[PATH_MAX] = "\0";
|
|
|
|
|
|
|
|
// If the root of the bundle as referred to by path is a symbolic link,
|
|
|
|
// CFBundleCopyExecutableURL will not return an absolute URL, but will
|
|
|
|
// instead only return the executable name, such as "MRJPlugin". Work
|
|
|
|
// around that by always using a fully-resolved absolute pathname.
|
|
|
|
if (is_symbolic_link(path)) {
|
|
|
|
path = realpath(path, resolvedPath);
|
|
|
|
if (!path)
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2002-11-06 01:24:57 +00:00
|
|
|
// if this is a directory, it must be a bundle, so get the true path using CFBundle...
|
|
|
|
if (is_directory(path)) {
|
|
|
|
CFBundleRef bundle = NULL;
|
|
|
|
CFStringRef pathRef = CFStringCreateWithCString(NULL, path, kCFStringEncodingUTF8);
|
|
|
|
if (pathRef) {
|
|
|
|
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef, kCFURLPOSIXPathStyle, true);
|
|
|
|
CFRelease(pathRef);
|
|
|
|
if (bundleURL != NULL) {
|
|
|
|
bundle = CFBundleCreate(NULL, bundleURL);
|
|
|
|
CFRelease(bundleURL);
|
|
|
|
if (bundle) {
|
|
|
|
CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
|
|
|
|
if (executableURL) {
|
|
|
|
pathRef = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
|
|
|
|
CFRelease(executableURL);
|
|
|
|
if (pathRef) {
|
|
|
|
CFIndex bufferSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(pathRef), kCFStringEncodingUTF8) + 1;
|
|
|
|
char* executablePath = new char[bufferSize];
|
|
|
|
if (executablePath && CFStringGetCString(pathRef, executablePath, bufferSize, kCFStringEncodingUTF8)) {
|
|
|
|
fd = open(executablePath, O_RDONLY, 0);
|
|
|
|
delete[] executablePath;
|
|
|
|
}
|
|
|
|
CFRelease(pathRef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CFRelease(bundle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
fd = open(path, O_RDONLY, 0);
|
|
|
|
}
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PRBool IsCompatibleExecutable(const char* path)
|
|
|
|
{
|
|
|
|
int fd = open_executable(path);
|
2005-08-08 08:03:41 +00:00
|
|
|
if (fd > 0) {
|
|
|
|
// Check the executable header to see if it is something we can use. Currently
|
|
|
|
// we can only use 32-bit mach-o and FAT binaries (FAT headers are always big
|
|
|
|
// endian, so we do network-to-host swap on the bytes from disk).
|
|
|
|
// Note: We assume FAT binaries contain the right arch. Maybe fix that later.
|
|
|
|
UInt32 magic;
|
|
|
|
ssize_t n = read(fd, &magic, sizeof(magic));
|
2002-11-06 01:24:57 +00:00
|
|
|
close(fd);
|
2005-08-08 08:03:41 +00:00
|
|
|
if (n == sizeof(magic)) {
|
|
|
|
if ((magic == MH_MAGIC) || (PR_ntohl(magic) == FAT_MAGIC))
|
2002-11-06 01:24:57 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
inline PRBool IsCompatibleExecutable(const char* path) { return PR_TRUE; }
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-09-15 12:45:01 +00:00
|
|
|
static nsresult CreateNPAPIPlugin(nsIServiceManagerObsolete* aServiceManager,
|
|
|
|
const nsPluginTag *aPluginTag,
|
|
|
|
nsIPlugin **aOutNPAPIPlugnin)
|
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);
|
|
|
|
|
|
|
|
nsCAutoString fileName, fullPath;
|
|
|
|
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->mFileName, fileName);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = ConvertToNative(encoder, aPluginTag->mFullPath, fullPath);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else {
|
|
|
|
fileName = aPluginTag->mFileName;
|
|
|
|
fullPath = aPluginTag->mFullPath;
|
|
|
|
}
|
|
|
|
|
2008-09-15 12:45:01 +00:00
|
|
|
return nsNPAPIPlugin::CreatePlugin(fileName.get(),
|
|
|
|
fullPath.get(),
|
|
|
|
aPluginTag->mLibrary,
|
|
|
|
aOutNPAPIPlugnin);
|
2008-03-10 07:07:15 +00:00
|
|
|
}
|
2002-11-06 01:24:57 +00:00
|
|
|
|
1999-02-25 04:15:39 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(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,
|
|
|
|
("nsPluginHostImpl::GetPluginFactory 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
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!pluginTag->mLibrary) { // if we haven't done this yet
|
2003-03-15 01:04:32 +00:00
|
|
|
nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
2005-08-07 07:05:09 +00:00
|
|
|
#if !defined(XP_MACOSX)
|
2008-03-10 07:07:15 +00:00
|
|
|
file->InitWithPath(NS_ConvertUTF8toUTF16(pluginTag->mFileName));
|
2001-07-18 14:04:28 +00:00
|
|
|
#else
|
2008-03-10 07:07:15 +00:00
|
|
|
if (pluginTag->mFullPath.IsEmpty())
|
2001-07-18 14:04:28 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2008-03-10 07:07:15 +00:00
|
|
|
file->InitWithPath(NS_ConvertUTF8toUTF16(pluginTag->mFullPath));
|
2001-07-18 14:04:28 +00:00
|
|
|
#endif
|
2001-04-17 23:30:25 +00:00
|
|
|
nsPluginFile pluginFile(file);
|
|
|
|
PRLibrary* pluginLibrary = NULL;
|
1999-07-06 04:14:54 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == NULL)
|
2001-08-16 02:59:03 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-07-06 04:14:54 +00:00
|
|
|
|
2002-06-26 04:32:49 +00:00
|
|
|
// remove from unused lib list, if it is there
|
|
|
|
if (mUnusedLibraries.IndexOf(pluginLibrary) > -1)
|
|
|
|
mUnusedLibraries.RemoveElement(pluginLibrary);
|
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
pluginTag->mLibrary = pluginLibrary;
|
|
|
|
}
|
1999-07-06 04:14:54 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
nsIPlugin* plugin = pluginTag->mEntryPoint;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin) {
|
2001-04-17 23:30:25 +00:00
|
|
|
// nsIPlugin* of xpcom plugins can be found thru a call to
|
2004-11-01 18:50:36 +00:00
|
|
|
// nsIComponentManager::GetClassObjectByContractID()
|
2001-10-16 03:53:44 +00:00
|
|
|
nsCAutoString contractID(
|
|
|
|
NS_LITERAL_CSTRING(NS_INLINE_PLUGIN_CONTRACTID_PREFIX) +
|
|
|
|
nsDependentCString(aMimeType));
|
2004-11-01 18:50:36 +00:00
|
|
|
nsresult rv = CallGetClassObject(contractID.get(), &plugin);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && plugin) {
|
2004-11-01 18:50:36 +00:00
|
|
|
// plugin is already addref'd
|
|
|
|
pluginTag->mEntryPoint = plugin;
|
|
|
|
plugin->Initialize();
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
|
|
|
}
|
2001-03-23 23:53:09 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!plugin) {
|
2001-04-17 23:30:25 +00:00
|
|
|
// No, this is not a leak. GetGlobalServiceManager() doesn't
|
|
|
|
// addref the pointer on the way out. It probably should.
|
2001-10-16 03:35:52 +00:00
|
|
|
nsIServiceManagerObsolete* serviceManager;
|
|
|
|
nsServiceManager::GetGlobalServiceManager((nsIServiceManager**)&serviceManager);
|
2001-04-17 23:30:25 +00:00
|
|
|
|
|
|
|
// need to get the plugin factory from this plugin.
|
|
|
|
nsFactoryProc nsGetFactory = nsnull;
|
2003-10-21 22:11:20 +00:00
|
|
|
#ifdef XP_OS2
|
2007-07-17 20:02:43 +00:00
|
|
|
nsGetFactory = (nsFactoryProc) PR_FindFunctionSymbol(pluginTag->mLibrary, "_NSGetFactory");
|
2003-10-21 22:11:20 +00:00
|
|
|
#else
|
2007-07-17 20:02:43 +00:00
|
|
|
nsGetFactory = (nsFactoryProc) PR_FindFunctionSymbol(pluginTag->mLibrary, "NSGetFactory");
|
2003-10-21 22:11:20 +00:00
|
|
|
#endif
|
2008-11-03 19:23:07 +00:00
|
|
|
if (nsGetFactory && IsCompatibleExecutable(pluginTag->mFullPath.get())) {
|
2003-03-11 03:29:47 +00:00
|
|
|
// XPCOM-style plugins (or at least the OJI one) cause crashes on
|
|
|
|
// on windows GCC builds, so we're just turning them off for now.
|
2004-10-11 04:01:49 +00:00
|
|
|
#if !defined(XP_WIN) || !defined(__GNUC__)
|
2001-04-17 23:30:25 +00:00
|
|
|
rv = nsGetFactory(serviceManager, kPluginCID, nsnull, nsnull, // XXX fix ClassName/ContractID
|
|
|
|
(nsIFactory**)&pluginTag->mEntryPoint);
|
|
|
|
plugin = pluginTag->mEntryPoint;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin)
|
2001-04-17 23:30:25 +00:00
|
|
|
plugin->Initialize();
|
2003-03-11 03:29:47 +00:00
|
|
|
#endif
|
2001-04-17 23:30:25 +00:00
|
|
|
}
|
2003-10-21 22:11:20 +00:00
|
|
|
#ifdef XP_OS2
|
|
|
|
// on OS2, first check if this might be legacy XPCOM module.
|
|
|
|
else if (PR_FindSymbol(pluginTag->mLibrary, "NSGetFactory") &&
|
2008-11-03 19:23:07 +00:00
|
|
|
IsCompatibleExecutable(pluginTag->mFullPath.get())) {
|
2003-10-21 22:11:20 +00:00
|
|
|
// Possibly a legacy XPCOM module. We'll need to create a calling
|
|
|
|
// vtable/calling convention wrapper for it.
|
|
|
|
nsCOMPtr<nsILegacyPluginWrapperOS2> wrapper =
|
|
|
|
do_GetService(NS_LEGACY_PLUGIN_WRAPPER_CONTRACTID, &rv);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2003-10-21 22:11:20 +00:00
|
|
|
rv = wrapper->GetFactory(serviceManager, kPluginCID, nsnull, nsnull,
|
|
|
|
pluginTag->mLibrary, &pluginTag->mEntryPoint);
|
|
|
|
plugin = pluginTag->mEntryPoint;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin)
|
2003-10-21 22:11:20 +00:00
|
|
|
plugin->Initialize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-11-03 19:23:07 +00:00
|
|
|
else {
|
2008-03-10 07:07:15 +00:00
|
|
|
// Now lets try to get the entry point from a 4.x plugin
|
2008-09-15 12:45:01 +00:00
|
|
|
rv = CreateNPAPIPlugin(serviceManager, pluginTag, &plugin);
|
2008-03-10 07:07:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
pluginTag->mEntryPoint = plugin;
|
2005-11-06 18:34:03 +00:00
|
|
|
pluginTag->Mark(NS_PLUGIN_FLAG_OLDSCHOOL);
|
2001-04-17 23:30:25 +00:00
|
|
|
// no need to initialize, already done by CreatePlugin()
|
|
|
|
}
|
|
|
|
}
|
1999-02-20 02:24:15 +00:00
|
|
|
|
2005-08-07 07:05:09 +00:00
|
|
|
#if defined (XP_MACOSX)
|
2004-10-11 04:01:49 +00:00
|
|
|
/* Flash 6.0 r50 and older on Mac has a bug which calls ::UseInputWindow(NULL, true)
|
|
|
|
which turn off all our inline IME. Turn it back after the plugin
|
2002-09-13 03:02:23 +00:00
|
|
|
initializtion and hope that future versions will be fixed. See bug 159016
|
|
|
|
*/
|
2008-03-10 07:07:15 +00:00
|
|
|
if (StringBeginsWith(pluginTag->mDescription,
|
|
|
|
NS_LITERAL_CSTRING("Shockwave Flash 6.0"),
|
|
|
|
nsCaseInsensitiveCStringComparator()) &&
|
|
|
|
pluginTag->mDescription.Length() > 21) {
|
|
|
|
int ver = atoi(pluginTag->mDescription.get() + 21);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (ver && ver <= 50)
|
2002-09-13 03:02:23 +00:00
|
|
|
::UseInputWindow(NULL, false);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin) {
|
2001-04-17 23:30:25 +00:00
|
|
|
*aPlugin = plugin;
|
|
|
|
plugin->AddRef();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
1999-02-20 02:24:15 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
|
|
|
("nsPluginHostImpl::GetPluginFactory 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
|
|
|
|
2001-11-20 23:06:50 +00:00
|
|
|
// XXX called from ScanPluginsDirectory only when told to filter
|
2000-06-21 01:44:55 +00:00
|
|
|
// currently 'unwanted' plugins are Java, and all other plugins except
|
2001-11-20 23:06:50 +00:00
|
|
|
// Acrobat, Flash, Quicktime and Shockwave
|
2000-06-21 01:44:55 +00:00
|
|
|
static PRBool isUnwantedPlugin(nsPluginTag * tag)
|
|
|
|
{
|
2008-11-03 19:23:07 +00:00
|
|
|
if (tag->mFileName.IsEmpty())
|
2000-06-21 01:44:55 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
|
2000-07-22 01:58:55 +00:00
|
|
|
for (PRInt32 i = 0; i < tag->mVariants; ++i) {
|
2008-11-03 19:23:07 +00:00
|
|
|
if (nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "application/pdf"))
|
2000-07-22 01:58:55 +00:00
|
|
|
return PR_FALSE;
|
2000-06-21 01:44:55 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "application/x-shockwave-flash"))
|
2000-07-22 01:58:55 +00:00
|
|
|
return PR_FALSE;
|
2001-05-03 02:43:47 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"application/x-director"))
|
2001-05-03 02:43:47 +00:00
|
|
|
return PR_FALSE;
|
2000-07-22 01:58:55 +00:00
|
|
|
}
|
2000-06-21 01:44:55 +00:00
|
|
|
|
2001-07-14 01:01:02 +00:00
|
|
|
// On Windows, we also want to include the Quicktime plugin from the 4.x directory
|
|
|
|
// But because it spans several DLL's, the best check for now is by filename
|
2008-03-10 07:07:15 +00:00
|
|
|
if (tag->mFileName.Find("npqtplugin", PR_TRUE, 0, -1) != kNotFound)
|
2001-07-14 01:01:02 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
|
2000-06-21 01:44:55 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
PRBool nsPluginHostImpl::IsJavaMIMEType(const char* aType)
|
|
|
|
{
|
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
2002-02-13 02:18:57 +00:00
|
|
|
nsPluginTag * nsPluginHostImpl::HaveSamePlugin(nsPluginTag * aPluginTag)
|
|
|
|
{
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool nsPluginHostImpl::IsDuplicatePlugin(nsPluginTag * aPluginTag)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
|
|
|
nsString mFilename;
|
|
|
|
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
|
2008-10-10 15:04:34 +00:00
|
|
|
static int ComparePluginFileInDirectory (const void *v1, const void *v2, void *)
|
2002-01-26 00:44:47 +00:00
|
|
|
{
|
2007-07-08 07:08:04 +00:00
|
|
|
const pluginFileinDirectory* pfd1 = static_cast<const pluginFileinDirectory*>(v1);
|
|
|
|
const pluginFileinDirectory* pfd2 = static_cast<const pluginFileinDirectory*>(v2);
|
2002-01-26 00:44:47 +00:00
|
|
|
|
|
|
|
PRInt32 result = 0;
|
|
|
|
if (LL_EQ(pfd1->mModTime, pfd2->mModTime))
|
2002-02-19 22:49:12 +00:00
|
|
|
result = Compare(pfd1->mFilename, pfd2->mFilename, nsCaseInsensitiveStringComparator());
|
2002-01-26 00:44:47 +00:00
|
|
|
else if (LL_CMP(pfd1->mModTime, >, pfd2->mModTime))
|
|
|
|
result = -1;
|
2004-10-11 04:01:49 +00:00
|
|
|
else
|
2002-01-26 00:44:47 +00:00
|
|
|
result = 1;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
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
|
|
|
|
|
|
|
static nsresult FixUpPluginInfo(nsPluginInfo &aInfo, nsPluginFile &aPluginFile)
|
|
|
|
{
|
|
|
|
#ifndef XP_WIN
|
2002-04-27 02:24:18 +00:00
|
|
|
return NS_OK;
|
2002-04-27 01:47:18 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < aInfo.fVariantCount; i++) {
|
|
|
|
if (PL_strcmp(aInfo.fMimeTypeArray[i], "*"))
|
|
|
|
continue;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// we got "*" type
|
|
|
|
// check if this is an alien plugin (not our default plugin)
|
2002-04-27 01:47:18 +00:00
|
|
|
// by trying to find a special entry point
|
|
|
|
PRLibrary *library = nsnull;
|
|
|
|
if (NS_FAILED(aPluginFile.LoadPlugin(library)) || !library)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2007-07-17 20:02:43 +00:00
|
|
|
NP_GETMIMEDESCRIPTION pf = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(library, "NP_GetMIMEDescription");
|
2002-06-26 04:32:49 +00:00
|
|
|
|
2002-04-27 01:47:18 +00:00
|
|
|
if (pf) {
|
|
|
|
// if we found it, this is the default plugin, return
|
|
|
|
char * mimedescription = pf();
|
|
|
|
if (!PL_strncmp(mimedescription, NS_PLUGIN_DEFAULT_MIME_DESCRIPTION, 1))
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// if we are here that means we have an alien plugin
|
2002-04-27 01:47:18 +00:00
|
|
|
// which wants to take over "*" type
|
|
|
|
|
|
|
|
// change its "*" mime type to "[*]"
|
|
|
|
PL_strfree(aInfo.fMimeTypeArray[i]);
|
|
|
|
aInfo.fMimeTypeArray[i] = PL_strdup("[*]");
|
|
|
|
|
|
|
|
// continue the loop?
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
/* Helper class which automatically deallocates a nsVoidArray of
|
2006-01-19 03:40:06 +00:00
|
|
|
* pluginFileinDirectories when the array goes out of scope.
|
|
|
|
*/
|
|
|
|
class nsAutoPluginFileDeleter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsAutoPluginFileDeleter (nsAutoVoidArray& aPluginFiles)
|
|
|
|
:mPluginFiles(aPluginFiles)
|
|
|
|
{}
|
|
|
|
|
|
|
|
~nsAutoPluginFileDeleter()
|
|
|
|
{
|
|
|
|
for (PRInt32 i = 0; i < mPluginFiles.Count(); ++i) {
|
2007-07-08 07:08:04 +00:00
|
|
|
pluginFileinDirectory* pfd = static_cast<pluginFileinDirectory*>(mPluginFiles[i]);
|
2006-01-19 03:40:06 +00:00
|
|
|
delete pfd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
protected:
|
|
|
|
// A reference to the array for which to perform deallocation.
|
|
|
|
nsAutoVoidArray& mPluginFiles;
|
|
|
|
};
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir,
|
|
|
|
nsIComponentManager * compManager,
|
2002-02-11 23:09:38 +00:00
|
|
|
PRBool aCreatePluginList,
|
|
|
|
PRBool * aPluginsChanged,
|
2001-02-02 23:48:17 +00:00
|
|
|
PRBool checkForUnwantedPlugins)
|
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,
|
2001-11-17 15:26:02 +00:00
|
|
|
("nsPluginHostImpl::ScanPluginsDirectory dir=%s\n", dirPath.get()));
|
|
|
|
#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
|
|
|
|
|
|
|
// Collect all the files in this directory in a void array we can sort later
|
|
|
|
nsAutoVoidArray pluginFilesArray; // array for sorting files in this directory
|
2006-01-19 03:40:06 +00:00
|
|
|
|
|
|
|
// Setup the helper which will cleanup the array.
|
|
|
|
nsAutoPluginFileDeleter pluginFileArrayDeleter(pluginFilesArray);
|
|
|
|
|
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)) {
|
|
|
|
pluginFileinDirectory * item = new pluginFileinDirectory();
|
|
|
|
if (!item)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
// Get file mod time
|
|
|
|
PRInt64 fileModTime = LL_ZERO;
|
|
|
|
dirEntry->GetLastModifiedTime(&fileModTime);
|
|
|
|
|
|
|
|
item->mModTime = fileModTime;
|
|
|
|
item->mFilename = filePath;
|
|
|
|
pluginFilesArray.AppendElement(item);
|
|
|
|
}
|
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
|
|
|
|
pluginFilesArray.Sort(ComparePluginFileInDirectory, nsnull);
|
|
|
|
|
|
|
|
// finally, go through the array, looking at each entry and continue processing it
|
|
|
|
for (PRInt32 i = 0; i < pluginFilesArray.Count(); i++) {
|
2007-07-08 07:08:04 +00:00
|
|
|
pluginFileinDirectory* pfd = static_cast<pluginFileinDirectory*>(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);
|
|
|
|
localfile->InitWithPath(pfd->mFilename);
|
2002-02-11 23:09:38 +00:00
|
|
|
PRInt64 fileModTime = pfd->mModTime;
|
|
|
|
|
|
|
|
// Look for it in our cache
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> pluginTag;
|
|
|
|
RemoveCachedPluginsInfo(NS_ConvertUTF16toUTF8(pfd->mFilename).get(),
|
|
|
|
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
|
2008-11-03 19:23:07 +00:00
|
|
|
if ((checkForUnwantedPlugins && isUnwantedPlugin(pluginTag)) ||
|
2008-07-11 21:28:12 +00:00
|
|
|
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
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
|
|
|
else {
|
2006-11-08 16:43:17 +00:00
|
|
|
// plugin file was added, flag this fact
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if we are not creating the list, just continue the loop
|
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList) {
|
|
|
|
if (*aPluginsChanged)
|
|
|
|
return NS_OK;
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
PRLibrary* pluginLibrary = nsnull;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// load the plugin's library so we can ask it some questions, but not for Windows
|
2000-02-01 00:42:52 +00:00
|
|
|
#ifndef XP_WIN
|
2002-02-11 23:09:38 +00:00
|
|
|
if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == nsnull)
|
|
|
|
continue;
|
2000-02-01 00:42:52 +00:00
|
|
|
#endif
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// create a tag describing this plugin.
|
2008-12-09 17:15:49 +00:00
|
|
|
nsPluginInfo info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
2002-02-11 23:09:38 +00:00
|
|
|
nsresult res = pluginFile.GetPluginInfo(info);
|
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) {
|
2001-10-17 00:39:21 +00:00
|
|
|
pluginFile.FreePluginInfo(info);
|
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
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// Check for any potential '*' mime type handlers which are not our
|
|
|
|
// own default plugin and disable them as they will break the plugin
|
2002-04-27 01:47:18 +00:00
|
|
|
// finder service, see Bugzilla bug 132430
|
|
|
|
if (!mAllowAlienStarHandler)
|
|
|
|
FixUpPluginInfo(info, pluginFile);
|
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag = new nsPluginTag(&info);
|
|
|
|
pluginFile.FreePluginInfo(info);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (pluginTag == nsnull)
|
2002-02-11 23:09:38 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag->mLibrary = pluginLibrary;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!enabled || (pluginTag->mIsJavaPlugin && !mJavaEnabled))
|
|
|
|
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");
|
2008-11-03 19:23:07 +00:00
|
|
|
if ((checkForUnwantedPlugins && isUnwantedPlugin(pluginTag)) ||
|
2008-07-11 21:28:12 +00:00
|
|
|
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
|
|
|
}
|
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;
|
|
|
|
|
|
|
|
// check if this is a specific plugin we don't want
|
2008-11-03 19:23:07 +00:00
|
|
|
if (checkForUnwantedPlugins && isUnwantedPlugin(pluginTag))
|
2002-02-11 23:09:38 +00:00
|
|
|
bAddIt = PR_FALSE;
|
|
|
|
|
|
|
|
// check if we already have this plugin in the list which
|
|
|
|
// is possible if we do refresh
|
2008-11-03 19:23:07 +00:00
|
|
|
if (bAddIt) {
|
2002-02-13 02:18: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;
|
|
|
|
// so there is no need to delete |pluginTag| -- it _is_ from the cache info list.
|
|
|
|
bAddIt = PR_FALSE;
|
2000-09-22 00:58:46 +00:00
|
|
|
}
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
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) {
|
2002-06-26 04:32:49 +00:00
|
|
|
pluginTag->SetHost(this);
|
2002-02-11 23:09:38 +00:00
|
|
|
pluginTag->mNext = mPlugins;
|
|
|
|
mPlugins = pluginTag;
|
2000-09-22 00:58:46 +00:00
|
|
|
|
2008-03-18 10:38:15 +00:00
|
|
|
if (pluginTag->IsEnabled())
|
|
|
|
pluginTag->RegisterWithCategoryManager(mOverrideInternalTypes);
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2005-11-06 18:34:03 +00:00
|
|
|
else if (!pluginTag->HasFlag(NS_PLUGIN_FLAG_UNWANTED)) {
|
2002-02-11 23:09:38 +00:00
|
|
|
// we don't need it, delete it;
|
2004-10-11 04:01:49 +00:00
|
|
|
// but don't delete unwanted plugins since they are cached
|
2002-02-11 23:09:38 +00:00
|
|
|
// in the cache info list and will be deleted later
|
2007-07-03 21:42:35 +00:00
|
|
|
pluginTag = nsnull;
|
2002-02-11 23:09:38 +00:00
|
|
|
}
|
2001-08-16 02:59:03 +00:00
|
|
|
}
|
2000-09-22 00:58:46 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-02-01 00:42:52 +00:00
|
|
|
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult nsPluginHostImpl::ScanPluginsDirectoryList(nsISimpleEnumerator * dirEnum,
|
2004-10-11 04:01:49 +00:00
|
|
|
nsIComponentManager * compManager,
|
2002-02-11 23:09:38 +00:00
|
|
|
PRBool aCreatePluginList,
|
|
|
|
PRBool * aPluginsChanged,
|
2001-11-17 15:26:02 +00:00
|
|
|
PRBool checkForUnwantedPlugins)
|
|
|
|
{
|
|
|
|
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;
|
2002-07-14 00:39:35 +00:00
|
|
|
ScanPluginsDirectory(nextDir, compManager, aCreatePluginList, &pluginschanged, checkForUnwantedPlugins);
|
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
|
|
|
|
2000-09-22 00:58:46 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
|
|
|
|
{
|
|
|
|
// 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
|
|
|
|
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;
|
|
|
|
|
|
|
|
// only if plugins have changed will we ask XPTI to refresh
|
|
|
|
if (pluginschanged) {
|
|
|
|
// rescan XPTI to catch any newly installed interfaces
|
2005-11-10 16:19:44 +00:00
|
|
|
nsCOMPtr<nsIInterfaceInfoManager>
|
|
|
|
iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
|
|
|
|
|
2002-07-01 20:36:57 +00:00
|
|
|
if (iim)
|
|
|
|
iim->AutoRegisterInterfaces();
|
2007-07-14 00:28:05 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService>
|
|
|
|
obsService(do_GetService("@mozilla.org/observer-service;1"));
|
|
|
|
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
|
|
|
|
nsresult nsPluginHostImpl::FindPlugins(PRBool aCreatePluginList, PRBool * aPluginsChanged)
|
|
|
|
{
|
|
|
|
// 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
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
// Read cached plugins info
|
|
|
|
ReadPluginInfo();
|
2001-10-18 12:26:23 +00:00
|
|
|
|
2004-11-23 20:53:38 +00:00
|
|
|
nsCOMPtr<nsIComponentManager> compManager;
|
|
|
|
NS_GetComponentManager(getter_AddRefs(compManager));
|
2004-10-11 04:01:49 +00:00
|
|
|
if (compManager)
|
2002-07-14 00:39:35 +00:00
|
|
|
LoadXPCOMPlugins(compManager);
|
2004-10-11 04:01:49 +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)) {
|
2002-07-14 00:39:35 +00:00
|
|
|
ScanPluginsDirectoryList(dirList, compManager, 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) {
|
2007-07-14 00:28:05 +00:00
|
|
|
mCachedPlugins = nsnull;
|
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)) {
|
|
|
|
ScanPluginsDirectoryList(dirList, compManager, aCreatePluginList, &pluginschanged);
|
|
|
|
|
|
|
|
if (pluginschanged)
|
|
|
|
*aPluginsChanged = PR_TRUE;
|
|
|
|
|
|
|
|
// if we are just looking for possible changes,
|
|
|
|
// no need to proceed if changes are detected
|
|
|
|
if (!aCreatePluginList && *aPluginsChanged) {
|
2007-07-14 00:28:05 +00:00
|
|
|
mCachedPlugins = nsnull;
|
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
|
2003-05-27 21:14:55 +00:00
|
|
|
const char* const prefs[] = {NS_WIN_JRE_SCAN_KEY, nsnull,
|
|
|
|
NS_WIN_ACROBAT_SCAN_KEY, nsnull,
|
|
|
|
NS_WIN_QUICKTIME_SCAN_KEY, nsnull,
|
|
|
|
NS_WIN_WMP_SCAN_KEY, nsnull,
|
|
|
|
NS_WIN_4DOTX_SCAN_KEY, "1" /* second column is flag for 4.x folder */ };
|
2002-05-01 02:01:50 +00:00
|
|
|
|
|
|
|
PRUint32 size = sizeof(prefs) / sizeof(prefs[0]);
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < size; i+=2) {
|
|
|
|
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) {
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
PRBool bFilterUnwanted = PR_FALSE;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// 4.x plugins folder stuff:
|
2002-05-01 02:01:50 +00:00
|
|
|
// Normally we "filter" the 4.x folder through |IsUnwantedPlugin|
|
|
|
|
// Check for a pref to see if we want to scan the entire 4.x plugins folder
|
|
|
|
if (prefs[i+1]) {
|
|
|
|
PRBool bScanEverything;
|
|
|
|
bFilterUnwanted = PR_TRUE; // default to filter 4.x folder
|
2003-05-27 21:14:55 +00:00
|
|
|
if (mPrefService &&
|
|
|
|
NS_SUCCEEDED(mPrefService->GetBoolPref(prefs[i], &bScanEverything)) &&
|
2002-05-01 02:01:50 +00:00
|
|
|
bScanEverything)
|
|
|
|
bFilterUnwanted = PR_FALSE;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
}
|
2002-07-14 00:39:35 +00:00
|
|
|
ScanPluginsDirectory(dirToScan, compManager, aCreatePluginList, &pluginschanged, bFilterUnwanted);
|
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) {
|
2007-07-14 00:28:05 +00:00
|
|
|
mCachedPlugins = nsnull;
|
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
|
|
|
}
|
|
|
|
|
2002-02-11 23:09:38 +00:00
|
|
|
// if we are not creating the list, there is no need to proceed
|
|
|
|
if (!aCreatePluginList) {
|
2007-07-14 00:28:05 +00:00
|
|
|
mCachedPlugins = nsnull;
|
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.
|
2007-07-14 00:28:05 +00:00
|
|
|
mCachedPlugins = nsnull;
|
2002-02-11 23:09:38 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
/*
|
|
|
|
* XXX Big time hack alert!!!!
|
|
|
|
* Because Real Player 8 installs in the components folder, we must have this one off
|
|
|
|
* scan for nppl3260.dll because XPCOM has shut off nsGetFactory type plugins.
|
|
|
|
* When we stop supporting Real 8 or they fix their installer, this can go away.
|
|
|
|
*/
|
|
|
|
if (aCreatePluginList)
|
2002-07-14 00:39:35 +00:00
|
|
|
ScanForRealInComponentsFolder(compManager);
|
2002-05-01 02:01:50 +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
|
|
|
|
|
|
|
nsresult
|
2002-07-14 00:39:35 +00:00
|
|
|
nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager)
|
2002-08-15 00:16:56 +00:00
|
|
|
{
|
|
|
|
// the component reg is a flat file now see 48888
|
|
|
|
// we have to reimplement this method if we need it
|
2002-08-14 22:31:59 +00:00
|
|
|
|
2000-07-22 01:34:13 +00:00
|
|
|
// The "new style" XPCOM plugins have their information stored in
|
|
|
|
// the component registry, under the key
|
|
|
|
//
|
|
|
|
// nsIRegistry::Common/software/plugins
|
|
|
|
//
|
|
|
|
// Enumerate through that list now, creating an nsPluginTag for
|
|
|
|
// each.
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-07-22 01:34:13 +00:00
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
nsresult
|
2007-07-14 00:28:05 +00:00
|
|
|
nsPluginHostImpl::UpdatePluginInfo(nsPluginTag* aPluginTag)
|
2007-07-03 21:42:35 +00:00
|
|
|
{
|
|
|
|
ReadPluginInfo();
|
|
|
|
WritePluginInfo();
|
2007-07-14 00:28:05 +00:00
|
|
|
mCachedPlugins = nsnull;
|
|
|
|
|
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));
|
|
|
|
mActivePluginList.stopRunning(instsToReload, aPluginTag);
|
|
|
|
mActivePluginList.removeAllStopped();
|
|
|
|
|
|
|
|
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
|
|
|
|
nsPluginHostImpl::WritePluginInfo()
|
|
|
|
{
|
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
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
rv = pluginReg->AppendNative(kPluginRegistryFilename);
|
|
|
|
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
|
|
|
|
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
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
PR_fprintf(fd, "\n[HEADER]\nVersion%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,
|
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
|
|
|
}
|
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
if (fd)
|
|
|
|
PR_Close(fd);
|
2000-07-22 01:34:13 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
#define PLUGIN_REG_MIMETYPES_ARRAY_SIZE 12
|
2001-10-18 12:26:23 +00:00
|
|
|
nsresult
|
2002-08-14 22:31:59 +00:00
|
|
|
nsPluginHostImpl::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
|
|
|
|
2003-05-27 21:14:55 +00:00
|
|
|
if (!mPluginRegFile)
|
2004-10-11 04:01:49 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
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
|
|
|
|
2002-08-14 22:31:59 +00:00
|
|
|
PRInt32 flen = nsInt64(fileSize);
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
while (reader.NextLine()) {
|
2002-08-30 00:38:56 +00:00
|
|
|
char *filename = reader.LinePtr();
|
|
|
|
if (!reader.NextLine())
|
2002-08-14 22:31:59 +00:00
|
|
|
return rv;
|
2002-08-30 00:38:56 +00:00
|
|
|
|
|
|
|
char *fullpath = reader.LinePtr();
|
2002-08-14 22:31:59 +00:00
|
|
|
if (!reader.NextLine())
|
|
|
|
return rv;
|
2002-08-22 22:59:43 +00:00
|
|
|
|
2008-11-02 15:49:03 +00:00
|
|
|
char *version;
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
|
2002-08-30 00:38:56 +00:00
|
|
|
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,
|
|
|
|
(*fullpath ? fullpath : 0), // we have to pass 0 prt if it's empty str
|
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);
|
2007-09-04 18:19:31 +00:00
|
|
|
if (tag->mIsJavaPlugin) {
|
2007-07-03 21:42:35 +00:00
|
|
|
if (mJavaEnabled)
|
|
|
|
tag->Mark(NS_PLUGIN_FLAG_ENABLED);
|
|
|
|
else
|
|
|
|
tag->UnMark(NS_PLUGIN_FLAG_ENABLED);
|
|
|
|
}
|
2002-08-14 22:31:59 +00:00
|
|
|
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;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-10-18 12:26:23 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-07-03 21:42:35 +00:00
|
|
|
void
|
|
|
|
nsPluginHostImpl::RemoveCachedPluginsInfo(const char *filename, 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
|
|
|
{
|
|
|
|
// compare filename or else the mFullPath if it exists. Mac seems to use
|
|
|
|
// mFullPath for fullpath and mFileName for just the leafname of fullpath.
|
|
|
|
// On win and unix, mFullPath is never used and mFileName is contains the
|
|
|
|
// full pathname. All this should move to using nsIFile.
|
2008-11-03 19:23:07 +00:00
|
|
|
if (tag->mFileName.Equals(filename) || tag->mFullPath.Equals(filename)) {
|
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
|
|
|
|
nsPluginHostImpl::EnsurePrivateDirServiceProvider()
|
|
|
|
{
|
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
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// Called by GetURL and PostURL
|
1999-04-20 19:29:28 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
|
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
|
|
|
nsIPluginInstance *aInstance,
|
|
|
|
nsIPluginStreamListener* aListener,
|
2001-04-17 23:30:25 +00:00
|
|
|
const char *aPostData,
|
2004-10-11 04:01:49 +00:00
|
|
|
PRBool aIsFile,
|
|
|
|
PRUint32 aPostDataLen,
|
|
|
|
const char *aHeadersData,
|
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
|
|
|
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;
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsIPluginInstancePeer> peer;
|
2007-04-05 01:56:32 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2002-08-23 11:23:49 +00:00
|
|
|
rv = aInstance->GetPeer(getter_AddRefs(peer));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && peer) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> privpeer(do_QueryInterface(peer));
|
|
|
|
rv = privpeer->GetOwner(getter_AddRefs(owner));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (owner) {
|
2000-06-16 22:27:16 +00:00
|
|
|
rv = owner->GetDocument(getter_AddRefs(doc));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && doc) {
|
2000-06-16 22:27:16 +00:00
|
|
|
// Create an absolute URL
|
2004-01-09 23:54:21 +00:00
|
|
|
rv = NS_MakeAbsoluteURI(absUrl, aURL, doc->GetBaseURI());
|
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);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2007-04-05 01:56:32 +00:00
|
|
|
nsCOMPtr<nsIPluginTagInfo2> pti2 = do_QueryInterface(owner);
|
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
|
|
|
if (pti2)
|
|
|
|
pti2->GetDOMElement(getter_AddRefs(element));
|
|
|
|
|
|
|
|
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
|
2007-06-17 13:50:50 +00:00
|
|
|
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OBJECT_SUBREQUEST,
|
2007-04-05 01:56:32 +00:00
|
|
|
url,
|
2007-08-08 01:16:09 +00:00
|
|
|
(doc ? doc->NodePrincipal() : nsnull),
|
2007-04-05 01:56:32 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2000-06-16 22:27:16 +00:00
|
|
|
nsPluginStreamListenerPeer *listenerPeer = new nsPluginStreamListenerPeer;
|
|
|
|
if (listenerPeer == NULL)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
NS_ADDREF(listenerPeer);
|
1999-01-25 08:05:00 +00:00
|
|
|
rv = listenerPeer->Initialize(url, aInstance, aListener);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2000-07-13 02:44:14 +00:00
|
|
|
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (doc) {
|
2005-11-28 23:56:44 +00:00
|
|
|
// Get the script global object owner and use that as the
|
|
|
|
// notification callback.
|
2003-10-22 06:09:48 +00:00
|
|
|
nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (global) {
|
2007-08-09 22:30:30 +00:00
|
|
|
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(global);
|
|
|
|
callbacks = do_QueryInterface(webNav);
|
2000-07-13 02:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
|
|
|
2002-10-02 20:38:46 +00:00
|
|
|
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 |nsWebShell::OnLinkClickSync| bug 166613 */
|
|
|
|
callbacks);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv))
|
2001-04-17 23:30:25 +00:00
|
|
|
return rv;
|
2000-07-13 02:44:14 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (doc) {
|
2000-07-13 02:44:14 +00:00
|
|
|
// Set the owner of channel to the document principal...
|
2006-04-27 18:21:11 +00:00
|
|
|
channel->SetOwner(doc->NodePrincipal());
|
2007-03-02 08:38:31 +00:00
|
|
|
|
|
|
|
// 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);
|
2007-06-13 22:42:07 +00:00
|
|
|
// Plug-ins seem to depend on javascript: URIs running synchronously
|
|
|
|
scriptChannel->SetExecuteAsync(PR_FALSE);
|
2007-03-02 08:38:31 +00:00
|
|
|
}
|
2000-07-13 02:44:14 +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
|
|
|
// deal with headers and post data
|
2001-05-11 21:05:08 +00:00
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (httpChannel) {
|
2001-12-12 01:38:02 +00:00
|
|
|
if (aPostData) {
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2001-04-17 23:30:25 +00:00
|
|
|
nsCOMPtr<nsIInputStream> postDataStream;
|
2004-10-11 04:01:49 +00:00
|
|
|
rv = NS_NewPluginPostDataStream(getter_AddRefs(postDataStream), (const char*)aPostData,
|
2001-12-12 01:38:02 +00:00
|
|
|
aPostDataLen, aIsFile);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!postDataStream) {
|
2001-04-17 23:30:25 +00:00
|
|
|
NS_RELEASE(aInstance);
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
2000-09-20 09:27:54 +00:00
|
|
|
|
2001-04-17 23:30:25 +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.
|
2004-10-11 04:01:49 +00:00
|
|
|
nsCOMPtr<nsISeekableStream>
|
2001-11-14 06:45:27 +00:00
|
|
|
postDataSeekable(do_QueryInterface(postDataStream));
|
|
|
|
if (postDataSeekable)
|
|
|
|
postDataSeekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
2001-09-05 03:52:26 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
|
|
|
|
NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel");
|
|
|
|
|
2004-01-29 22:04:45 +00:00
|
|
|
uploadChannel->SetUploadStream(postDataStream, EmptyCString(), -1);
|
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
|
|
|
}
|
2001-04-17 23:30:25 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
if (aHeadersData)
|
2001-04-17 23:30:25 +00:00
|
|
|
rv = AddHeadersToChannel(aHeadersData, aHeadersDataLen, httpChannel);
|
2000-09-20 09:27:54 +00:00
|
|
|
}
|
2001-04-17 23:30:25 +00:00
|
|
|
rv = channel->AsyncOpen(listenerPeer, nsnull);
|
|
|
|
}
|
2000-06-16 22:27:16 +00:00
|
|
|
NS_RELEASE(listenerPeer);
|
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
|
|
|
|
nsPluginHostImpl::DoURLLoadSecurityCheck(nsIPluginInstance *aInstance,
|
|
|
|
const char* aURL)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (!aURL || *aURL == '\0')
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// get the URL of the document that loaded the plugin
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
nsCOMPtr<nsIPluginInstancePeer> peer;
|
|
|
|
rv = aInstance->GetPeer(getter_AddRefs(peer));
|
|
|
|
if (NS_FAILED(rv) || !peer)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> privpeer(do_QueryInterface(peer));
|
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
|
|
|
rv = privpeer->GetOwner(getter_AddRefs(owner));
|
|
|
|
if (!owner)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
rv = owner->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (!doc)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// Create an absolute URL for the target in case the target is relative
|
|
|
|
nsCOMPtr<nsIURI> targetURL;
|
2004-01-09 23:54:21 +00:00
|
|
|
rv = NS_NewURI(getter_AddRefs(targetURL), aURL, doc->GetBaseURI());
|
2003-04-03 19:11:41 +00:00
|
|
|
|
|
|
|
if (!targetURL)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
NS_IMETHODIMP
|
2004-10-11 04:01:49 +00:00
|
|
|
nsPluginHostImpl::AddHeadersToChannel(const char *aHeadersData,
|
|
|
|
PRUint32 aHeadersDataLen,
|
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
|
|
|
nsIChannel *aGenericChannel)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
|
|
|
|
{
|
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,
|
|
|
|
("nsPluginHostImpl::StopPluginInstance called instance=%p\n",aInstance));
|
|
|
|
|
2000-06-13 23:23:13 +00:00
|
|
|
nsActivePlugin * plugin = mActivePluginList.find(aInstance);
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin) {
|
2001-06-19 01:38:20 +00:00
|
|
|
plugin->setStopped(PR_TRUE); // be sure we set the "stop" bit
|
|
|
|
|
2001-02-02 23:48:17 +00:00
|
|
|
// if the plugin does not want to be 'cached' just remove it
|
|
|
|
PRBool doCache = PR_TRUE;
|
|
|
|
aInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
2001-03-25 00:28:53 +00:00
|
|
|
|
2002-03-25 23:42:32 +00:00
|
|
|
if (!doCache) {
|
2001-04-17 23:30:25 +00:00
|
|
|
PRLibrary * library = nsnull;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (plugin->mPluginTag)
|
2001-04-17 23:30:25 +00:00
|
|
|
library = plugin->mPluginTag->mLibrary;
|
2001-04-03 22:49:38 +00:00
|
|
|
|
2002-06-26 04:32:49 +00:00
|
|
|
mActivePluginList.remove(plugin);
|
2008-11-03 19:23:07 +00:00
|
|
|
} else {
|
2004-10-11 04:01:49 +00:00
|
|
|
// if it is allowed to be cached simply stop it, but first we should check
|
2001-04-11 23:08:36 +00:00
|
|
|
// if we haven't exceeded the maximum allowed number of cached instances
|
|
|
|
|
2001-02-14 23:03:47 +00:00
|
|
|
// try to get the max cached plugins from a pref or use default
|
|
|
|
PRUint32 max_num;
|
2003-05-27 21:14:55 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mPrefService)
|
2003-05-27 21:14:55 +00:00
|
|
|
rv = mPrefService->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS, (int*)&max_num);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
max_num = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
|
2001-02-14 23:03:47 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mActivePluginList.getStoppedCount() >= max_num) {
|
2001-02-02 23:48:17 +00:00
|
|
|
nsActivePlugin * oldest = mActivePluginList.findOldestStopped();
|
2008-11-03 19:23:07 +00:00
|
|
|
if (oldest != nsnull)
|
2002-06-26 04:32:49 +00:00
|
|
|
mActivePluginList.remove(oldest);
|
2001-02-02 23:48:17 +00:00
|
|
|
}
|
2000-06-15 01:07:27 +00:00
|
|
|
}
|
|
|
|
}
|
1999-06-04 22:32:27 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-09-21 19:14:30 +00:00
|
|
|
nsresult nsPluginHostImpl::NewEmbeddedPluginStreamListener(nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner,
|
|
|
|
nsIPluginInstance* aInstance,
|
|
|
|
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
|
|
|
|
2005-09-21 19:14:30 +00:00
|
|
|
nsRefPtr<nsPluginStreamListenerPeer> listener =
|
|
|
|
new nsPluginStreamListenerPeer();
|
1999-07-30 23:51:53 +00:00
|
|
|
if (listener == nsnull)
|
|
|
|
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
|
2008-11-03 19:23:07 +00:00
|
|
|
if (aInstance != nsnull)
|
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)
|
2005-06-08 23:42:15 +00:00
|
|
|
rv = listener->InitializeEmbedded(aURL, nsnull, aOwner, this);
|
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()
|
2005-09-21 19:14:30 +00:00
|
|
|
nsresult nsPluginHostImpl::NewEmbeddedPluginStream(nsIURI* aURL,
|
|
|
|
nsIPluginInstanceOwner *aOwner,
|
|
|
|
nsIPluginInstance* aInstance)
|
|
|
|
{
|
|
|
|
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()
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult nsPluginHostImpl::NewFullPagePluginStream(nsIStreamListener *&aStreamListener,
|
2000-04-22 20:50:22 +00:00
|
|
|
nsIPluginInstance *aInstance)
|
1998-09-15 03:48:58 +00:00
|
|
|
{
|
2005-05-01 13:08:14 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
nsresult rv;
|
1998-09-15 03:48:58 +00:00
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
rv = listener->InitializeFullPage(aInstance);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2005-05-01 13:08:14 +00:00
|
|
|
aStreamListener = listener;
|
|
|
|
NS_ADDREF(listener);
|
1998-09-15 03:48:58 +00:00
|
|
|
|
2005-05-01 13:08:14 +00:00
|
|
|
// add peer to list of stream peers for this instance
|
|
|
|
nsActivePlugin * p = mActivePluginList.find(aInstance);
|
|
|
|
if (p) {
|
|
|
|
if (!p->mStreams && (NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(p->mStreams)))))
|
|
|
|
return rv;
|
|
|
|
p->mStreams->AppendElement(aStreamListener);
|
|
|
|
}
|
2001-06-19 01:38:20 +00:00
|
|
|
|
1998-09-15 03:48:58 +00:00
|
|
|
return rv;
|
1998-08-05 04:21:36 +00:00
|
|
|
}
|
|
|
|
|
1999-01-25 08:05:00 +00:00
|
|
|
|
2001-08-16 02:59:03 +00:00
|
|
|
// nsIFileUtilities interface
|
1999-01-25 08:05:00 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetProgramPath(const char* *result)
|
|
|
|
{
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
|
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
*result = nsnull;
|
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;
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCOMPtr<nsILocalFile> programDir;
|
|
|
|
rv = dirService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(programDir));
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString temp;
|
|
|
|
rv = programDir->GetNativePath(temp);
|
|
|
|
*result = ToNewCString(temp);
|
2001-11-17 15:26:02 +00:00
|
|
|
return rv;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetTempDirPath(const char* *result)
|
|
|
|
{
|
2001-11-17 15:26:02 +00:00
|
|
|
nsresult rv;
|
|
|
|
NS_ENSURE_ARG_POINTER(result);
|
|
|
|
*result = nsnull;
|
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;
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCOMPtr<nsILocalFile> tempDir;
|
|
|
|
rv = dirService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(tempDir));
|
2001-11-17 15:26:02 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString temp;
|
|
|
|
rv = tempDir->GetNativePath(temp);
|
|
|
|
*result = ToNewCString(temp);
|
2001-11-17 15:26:02 +00:00
|
|
|
return rv;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::NewTempFileName(const char* prefix, PRUint32 bufLen, char* resultBuf)
|
|
|
|
{
|
2001-08-16 02:59:03 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-03-20 23:11:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// nsICookieStorage interface
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::GetCookie(const char* inCookieURL, void* inOutCookieBuffer, PRUint32& inOutCookieSize)
|
|
|
|
{
|
1999-10-21 21:09:21 +00:00
|
|
|
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
|
2001-06-29 00:33:01 +00:00
|
|
|
nsXPIDLCString cookieString;
|
|
|
|
PRUint32 cookieStringLen = 0;
|
1999-10-21 21:09:21 +00:00
|
|
|
nsCOMPtr<nsIURI> uriIn;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!inCookieURL || (0 >= inOutCookieSize)) {
|
1999-10-21 21:09:21 +00:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv) || !ioService)
|
1999-10-21 21:09:21 +00:00
|
|
|
return rv;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
nsCOMPtr<nsICookieService> cookieService =
|
2006-06-18 21:18:22 +00:00
|
|
|
do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv) || !cookieService)
|
1999-10-21 21:09:21 +00:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
|
|
|
|
// make an nsURI from the argument url
|
2002-03-06 07:48:55 +00:00
|
|
|
rv = ioService->NewURI(nsDependentCString(inCookieURL), nsnull, nsnull, getter_AddRefs(uriIn));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv))
|
1999-10-21 21:09:21 +00:00
|
|
|
return rv;
|
|
|
|
|
2003-05-05 21:27:02 +00:00
|
|
|
rv = cookieService->GetCookieString(uriIn, nsnull, getter_Copies(cookieString));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv) || !cookieString ||
|
2001-06-29 00:33:01 +00:00
|
|
|
(inOutCookieSize <= (cookieStringLen = PL_strlen(cookieString.get())))) {
|
1999-10-21 21:09:21 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2001-06-29 00:33:01 +00:00
|
|
|
|
|
|
|
PL_strcpy((char *) inOutCookieBuffer, cookieString.get());
|
|
|
|
inOutCookieSize = cookieStringLen;
|
1999-10-21 21:09:21 +00:00
|
|
|
rv = NS_OK;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-10-21 21:09:21 +00:00
|
|
|
return rv;
|
1999-03-20 23:11:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl::SetCookie(const char* inCookieURL, const void* inCookieBuffer, PRUint32 inCookieSize)
|
|
|
|
{
|
1999-10-21 21:09:21 +00:00
|
|
|
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
nsCOMPtr<nsIURI> uriIn;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (!inCookieURL || !inCookieBuffer ||
|
1999-10-21 21:09:21 +00:00
|
|
|
(0 >= inCookieSize)) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv) || !ioService)
|
1999-10-21 21:09:21 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsICookieService> cookieService =
|
2006-06-18 21:18:22 +00:00
|
|
|
do_GetService(NS_COOKIESERVICE_CONTRACTID, &rv);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv) || !cookieService)
|
1999-10-21 21:09:21 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-10-21 21:09:21 +00:00
|
|
|
// make an nsURI from the argument url
|
2002-03-06 07:48:55 +00:00
|
|
|
rv = ioService->NewURI(nsDependentCString(inCookieURL), nsnull, nsnull, getter_AddRefs(uriIn));
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(rv))
|
1999-10-21 21:09:21 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2001-03-29 02:11:48 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsCOMPtr<nsIPrompt> prompt;
|
|
|
|
GetPrompt(nsnull, getter_AddRefs(prompt));
|
|
|
|
|
2001-03-29 02:11:48 +00:00
|
|
|
char * cookie = (char *)inCookieBuffer;
|
|
|
|
char c = cookie[inCookieSize];
|
|
|
|
cookie[inCookieSize] = '\0';
|
2003-05-05 21:27:02 +00:00
|
|
|
rv = cookieService->SetCookieString(uriIn, prompt, cookie, nsnull);
|
2001-03-29 02:11:48 +00:00
|
|
|
cookie[inCookieSize] = c;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
1999-10-21 21:09:21 +00:00
|
|
|
return rv;
|
1999-01-25 08:05:00 +00:00
|
|
|
}
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
NS_IMETHODIMP nsPluginHostImpl::Observe(nsISupports *aSubject,
|
2001-10-19 20:52:59 +00:00
|
|
|
const char *aTopic,
|
2001-03-12 02:07:15 +00:00
|
|
|
const PRUnichar *someData)
|
|
|
|
{
|
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();
|
2002-12-26 22:54:46 +00:00
|
|
|
UnloadUnusedLibraries();
|
2005-11-06 18:34:03 +00:00
|
|
|
sInst->Release();
|
|
|
|
}
|
|
|
|
if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
|
|
|
|
NS_ASSERTION(someData &&
|
|
|
|
nsDependentString(someData).EqualsLiteral("security.enable_java"),
|
|
|
|
"Unexpected pref");
|
|
|
|
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(aSubject);
|
|
|
|
NS_ASSERTION(branch, "Not a pref branch?");
|
|
|
|
PRBool enabled;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (NS_FAILED(branch->GetBoolPref("security.enable_java", &enabled)))
|
2005-11-06 18:34:03 +00:00
|
|
|
enabled = PR_TRUE;
|
|
|
|
|
|
|
|
if (enabled != mJavaEnabled) {
|
|
|
|
mJavaEnabled = enabled;
|
2006-08-12 02:13:24 +00:00
|
|
|
// We want to keep the java PluginTag around so we'll know that it's
|
|
|
|
// actually disabled, not just not present. So just manually mark it as
|
|
|
|
// disabled so at least FindPluginForType/Extension doesn't return
|
2005-11-06 18:34:03 +00:00
|
|
|
// anything.
|
|
|
|
for (nsPluginTag* cur = mPlugins; cur; cur = cur->mNext) {
|
2007-09-04 18:19:31 +00:00
|
|
|
if (cur->mIsJavaPlugin)
|
2007-07-14 00:28:05 +00:00
|
|
|
cur->SetDisabled(!mJavaEnabled);
|
2005-11-06 18:34:03 +00:00
|
|
|
}
|
|
|
|
}
|
2001-03-31 02:26:51 +00:00
|
|
|
}
|
2001-03-12 02:07:15 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP
|
2002-09-26 02:53:27 +00:00
|
|
|
nsPluginHostImpl::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'
|
|
|
|
|
2000-09-14 06:03:37 +00:00
|
|
|
nsresult rv = NS_OK;
|
2000-09-14 23:58:17 +00:00
|
|
|
|
2001-03-12 02:07:15 +00:00
|
|
|
NS_ASSERTION(PR_FALSE, "Plugin performed illegal operation");
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
if (mDontShowBadPluginMessage)
|
2000-09-14 23:58:17 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-26 02:53:27 +00:00
|
|
|
if (aInstance) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsIPluginInstancePeer> peer;
|
2002-09-26 02:53:27 +00:00
|
|
|
rv = aInstance->GetPeer(getter_AddRefs(peer));
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && peer) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> privpeer(do_QueryInterface(peer));
|
|
|
|
privpeer->GetOwner(getter_AddRefs(owner));
|
2002-06-01 00:56:38 +00:00
|
|
|
}
|
|
|
|
}
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsCOMPtr<nsIPrompt> prompt;
|
|
|
|
GetPrompt(owner, getter_AddRefs(prompt));
|
|
|
|
if (prompt) {
|
2007-09-05 13:04:54 +00:00
|
|
|
nsCOMPtr<nsIStringBundleService> strings(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
|
2002-06-01 00:56:38 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsCOMPtr<nsIStringBundle> bundle;
|
2005-01-13 12:46:52 +00:00
|
|
|
rv = strings->CreateBundle(BRAND_PROPERTIES_URL, getter_AddRefs(bundle));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
nsXPIDLString brandName;
|
|
|
|
if (NS_FAILED(rv = bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
|
|
|
|
getter_Copies(brandName))))
|
|
|
|
return rv;
|
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
rv = strings->CreateBundle(PLUGIN_PROPERTIES_URL, getter_AddRefs(bundle));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
nsXPIDLString title, message, checkboxMessage;
|
|
|
|
if (NS_FAILED(rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginTitle").get(),
|
|
|
|
getter_Copies(title))))
|
|
|
|
return rv;
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2005-01-13 12:46:52 +00:00
|
|
|
const PRUnichar *formatStrings[] = { brandName.get() };
|
|
|
|
if (NS_FAILED(rv = bundle->FormatStringFromName(NS_LITERAL_STRING("BadPluginMessage").get(),
|
|
|
|
formatStrings, 1, getter_Copies(message))))
|
2002-06-01 00:56:38 +00:00
|
|
|
return rv;
|
2000-09-14 06:03:37 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
if (NS_FAILED(rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginCheckboxMessage").get(),
|
2002-06-01 00:56:38 +00:00
|
|
|
getter_Copies(checkboxMessage))))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
// add plugin name to the message
|
2008-03-10 07:07:15 +00:00
|
|
|
nsCString pluginname;
|
2002-09-26 02:53:27 +00:00
|
|
|
nsActivePlugin * p = mActivePluginList.find(aInstance);
|
|
|
|
if (p) {
|
|
|
|
nsPluginTag * tag = p->mPluginTag;
|
|
|
|
if (tag) {
|
2008-03-10 07:07:15 +00:00
|
|
|
if (!tag->mName.IsEmpty())
|
2002-06-01 00:56:38 +00:00
|
|
|
pluginname = tag->mName;
|
|
|
|
else
|
|
|
|
pluginname = tag->mFileName;
|
|
|
|
}
|
2002-02-12 22:25:40 +00:00
|
|
|
}
|
|
|
|
|
2008-03-10 07:07:15 +00:00
|
|
|
NS_ConvertUTF8toUTF16 msg(pluginname);
|
2004-06-17 00:13:25 +00:00
|
|
|
msg.AppendLiteral("\n\n");
|
2002-06-01 00:56:38 +00:00
|
|
|
msg.Append(message);
|
2002-02-12 22:25:40 +00:00
|
|
|
|
2002-06-01 00:56:38 +00:00
|
|
|
PRInt32 buttonPressed;
|
|
|
|
PRBool checkboxState = PR_FALSE;
|
|
|
|
rv = prompt->ConfirmEx(title, msg.get(),
|
2001-05-06 15:03:55 +00:00
|
|
|
nsIPrompt::BUTTON_TITLE_OK * nsIPrompt::BUTTON_POS_0,
|
|
|
|
nsnull, nsnull, nsnull,
|
2001-04-21 00:26:18 +00:00
|
|
|
checkboxMessage, &checkboxState, &buttonPressed);
|
2000-09-14 06:03:37 +00:00
|
|
|
|
|
|
|
|
2002-06-01 00:56:38 +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
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// nsPIPluginHost interface
|
2002-01-30 02:40:46 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_IMETHODIMP
|
2002-10-03 21:31:41 +00:00
|
|
|
nsPluginHostImpl::SetIsScriptableInstance(nsIPluginInstance * aPluginInstance, PRBool aScriptable)
|
2002-01-30 02:40:46 +00:00
|
|
|
{
|
2002-10-03 21:31:41 +00:00
|
|
|
nsActivePlugin * p = mActivePluginList.find(aPluginInstance);
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p == nsnull)
|
2002-01-30 02:40:46 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
p->mXPConnected = aScriptable;
|
2008-11-03 19:23:07 +00:00
|
|
|
if (p->mPluginTag)
|
2002-01-30 02:40:46 +00:00
|
|
|
p->mPluginTag->mXPConnected = aScriptable;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHostImpl::ParsePostBufferToFixHeaders(
|
2004-10-11 04:01:49 +00:00
|
|
|
const char *inPostData, PRUint32 inPostDataLen,
|
2002-01-30 02:40:46 +00:00
|
|
|
char **outPostData, PRUint32 *outPostDataLen)
|
|
|
|
{
|
|
|
|
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";
|
|
|
|
|
|
|
|
nsAutoVoidArray singleLF;
|
|
|
|
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) {
|
|
|
|
// from 4.x spec http://developer.netscape.com/docs/manuals/communicator/plugin/pgfn2.htm#1007754
|
|
|
|
// 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) {
|
|
|
|
singleLF.AppendElement((void*)s);
|
|
|
|
}
|
|
|
|
if (pSCntlh && (s+1 < pEod) && (*(s+1) == LF)) {
|
|
|
|
s++;
|
|
|
|
singleLF.AppendElement((void*)s);
|
|
|
|
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
|
|
|
|
int cntSingleLF = singleLF.Count();
|
|
|
|
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++) {
|
|
|
|
const char *plf = (const char*) singleLF.ElementAt(i); // ptr to single LF in headers
|
|
|
|
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
|
2004-10-11 04:01:49 +00:00
|
|
|
nsPluginHostImpl::CreateTmpFileToPost(const char *postDataURL, char **pTmpFileName)
|
2002-01-30 02:40:46 +00:00
|
|
|
{
|
|
|
|
*pTmpFileName = 0;
|
|
|
|
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;
|
|
|
|
rv = NS_GetFileFromURLSpec(nsDependentCString(postDataURL),
|
|
|
|
getter_AddRefs(inFile));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
nsCOMPtr<nsILocalFile> localFile;
|
|
|
|
rv = NS_NewNativeLocalFile(nsDependentCString(postDataURL), PR_FALSE,
|
|
|
|
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
|
|
|
// according to the 4.x spec
|
2002-04-25 21:28:06 +00:00
|
|
|
// http://developer.netscape.com/docs/manuals/communicator/plugin/pgfn2.htm#1007707
|
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,
|
|
|
|
// lets parse it through nsPluginHostImpl::ParsePostBufferToFixHeaders()
|
|
|
|
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();
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2002-04-27 05:33:09 +00:00
|
|
|
nsCAutoString path;
|
|
|
|
if (NS_SUCCEEDED(tempFile->GetNativePath(path)))
|
|
|
|
*pTmpFileName = ToNewCString(path);
|
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
|
|
|
|
nsPluginHostImpl::NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
|
|
|
|
{
|
|
|
|
return PLUG_NewPluginNativeWindow(aPluginNativeWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHostImpl::DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
|
|
|
|
{
|
|
|
|
return PLUG_DeletePluginNativeWindow(aPluginNativeWindow);
|
|
|
|
}
|
|
|
|
|
2007-10-10 01:24:28 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHostImpl::InstantiateDummyJavaPlugin(nsIPluginInstanceOwner *aOwner)
|
|
|
|
{
|
|
|
|
// 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));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPluginInstanceInternal> plugin_internal =
|
|
|
|
do_QueryInterface(instance);
|
|
|
|
|
|
|
|
if (!plugin_internal) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
plugin_internal->DefineJavaProperties();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-04-16 20:06:48 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginHostImpl::GetPluginName(nsIPluginInstance *aPluginInstance,
|
2008-07-08 00:23:04 +00:00
|
|
|
const char** aPluginName)
|
2008-04-16 20:06:48 +00:00
|
|
|
{
|
2008-07-08 00:23:04 +00:00
|
|
|
*aPluginName = GetPluginName(aPluginInstance);
|
2008-04-16 20:06:48 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-11-03 19:23:07 +00:00
|
|
|
// end of nsPIPluginHost implementation
|
2002-09-26 02:53:27 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
nsresult
|
2002-07-14 00:39:35 +00:00
|
|
|
nsPluginHostImpl::ScanForRealInComponentsFolder(nsIComponentManager * aCompManager)
|
2002-05-01 02:01:50 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// First, lets check if we already have Real. No point in doing this if it's installed correctly
|
|
|
|
if (NS_SUCCEEDED(IsPluginEnabledForType("audio/x-pn-realaudio-plugin")))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// Next, maybe the pref wants to override
|
|
|
|
PRBool bSkipRealPlayerHack = PR_FALSE;
|
2003-05-27 21:14:55 +00:00
|
|
|
if (!mPrefService ||
|
|
|
|
(NS_SUCCEEDED(mPrefService->GetBoolPref("plugin.skip_real_player_hack", &bSkipRealPlayerHack)) &&
|
2002-05-01 02:01:50 +00:00
|
|
|
bSkipRealPlayerHack))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// now we need the XPCOM components folder
|
|
|
|
nsCOMPtr<nsIFile> RealPlugin;
|
|
|
|
if (NS_FAILED(NS_GetSpecialDirectory(NS_XPCOM_COMPONENT_DIR, getter_AddRefs(RealPlugin))) || !RealPlugin)
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// make sure the file is actually there
|
2002-05-07 23:07:19 +00:00
|
|
|
RealPlugin->AppendNative(nsDependentCString("nppl3260.dll"));
|
2002-05-01 02:01:50 +00:00
|
|
|
PRBool exists;
|
|
|
|
nsCAutoString filePath;
|
|
|
|
RealPlugin->Exists(&exists);
|
|
|
|
if (!exists || NS_FAILED(RealPlugin->GetNativePath(filePath)))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// now make sure it's a plugin
|
2003-03-15 01:04:32 +00:00
|
|
|
nsCOMPtr<nsILocalFile> localfile;
|
2004-10-11 04:01:49 +00:00
|
|
|
NS_NewNativeLocalFile(filePath,
|
2003-03-15 01:04:32 +00:00
|
|
|
PR_TRUE,
|
|
|
|
getter_AddRefs(localfile));
|
|
|
|
|
|
|
|
if (!nsPluginsDir::IsPluginFile(localfile))
|
2002-05-01 02:01:50 +00:00
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// try to get the mime info and descriptions out of the plugin
|
2003-03-15 01:04:32 +00:00
|
|
|
nsPluginFile pluginFile(localfile);
|
2008-12-09 19:00:09 +00:00
|
|
|
nsPluginInfo info;
|
|
|
|
memset(&info, 0, sizeof(info));
|
2002-05-01 02:01:50 +00:00
|
|
|
if (NS_FAILED(pluginFile.GetPluginInfo(info)))
|
|
|
|
return rv;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2004-11-23 20:53:38 +00:00
|
|
|
nsCOMPtr<nsIComponentManager> compManager;
|
|
|
|
NS_GetComponentManager(getter_AddRefs(compManager));
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// finally, create our "plugin tag" and add it to the list
|
|
|
|
if (info.fMimeTypeArray) {
|
2007-07-03 21:42:35 +00:00
|
|
|
nsRefPtr<nsPluginTag> pluginTag = new nsPluginTag(&info);
|
2002-05-01 02:01:50 +00:00
|
|
|
if (pluginTag) {
|
2002-06-26 04:32:49 +00:00
|
|
|
pluginTag->SetHost(this);
|
2002-05-01 02:01:50 +00:00
|
|
|
pluginTag->mNext = mPlugins;
|
|
|
|
mPlugins = pluginTag;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// last thing we need is to register this plugin with layout so it can be used in full-page mode
|
2008-03-18 10:38:15 +00:00
|
|
|
if (pluginTag->IsEnabled())
|
|
|
|
pluginTag->RegisterWithCategoryManager(mOverrideInternalTypes);
|
2002-05-01 02:01:50 +00:00
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-01 02:01:50 +00:00
|
|
|
// free allocated strings in GetPluginInfo
|
|
|
|
pluginFile.FreePluginInfo(info);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
2002-05-10 18:32:42 +00:00
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult nsPluginHostImpl::AddUnusedLibrary(PRLibrary * aLibrary)
|
2002-06-26 04:32:49 +00:00
|
|
|
{
|
|
|
|
if (mUnusedLibraries.IndexOf(aLibrary) == -1) // don't add duplicates
|
|
|
|
mUnusedLibraries.AppendElement(aLibrary);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-11-06 18:34:03 +00:00
|
|
|
nsresult nsPluginHostImpl::AddPrefObserver()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPrefBranch2> prefBranch(do_QueryInterface(mPrefService));
|
|
|
|
NS_ENSURE_TRUE(prefBranch, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
return prefBranch->AddObserver("security.enable_java", this, PR_TRUE);
|
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
2007-01-28 19:50:37 +00:00
|
|
|
nsISupports* aContext)
|
2002-05-10 18:32:42 +00:00
|
|
|
{
|
|
|
|
if (!mInstance)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// mInstance->Stop calls mPStreamListener->CleanUpStream(), so stream will be properly clean up
|
2002-05-10 18:32:42 +00:00
|
|
|
mInstance->Stop();
|
2004-10-11 04:01:49 +00:00
|
|
|
mInstance->Start();
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsIPluginInstancePeer> peer;
|
|
|
|
mInstance->GetPeer(getter_AddRefs(peer));
|
2002-05-10 18:32:42 +00:00
|
|
|
if (peer) {
|
2002-08-23 11:23:49 +00:00
|
|
|
nsCOMPtr<nsPIPluginInstancePeer> privpeer(do_QueryInterface(peer));
|
2002-05-10 18:32:42 +00:00
|
|
|
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
2002-08-23 11:23:49 +00:00
|
|
|
privpeer->GetOwner(getter_AddRefs(owner));
|
2002-05-10 18:32:42 +00:00
|
|
|
if (owner) {
|
|
|
|
nsPluginWindow *window = nsnull;
|
|
|
|
owner->GetWindow(window);
|
2007-04-30 23:52:44 +00:00
|
|
|
#if defined (MOZ_WIDGET_GTK2)
|
2006-02-14 08:13:51 +00:00
|
|
|
// Should call GetPluginPort() here.
|
|
|
|
// This part is copied from nsPluginInstanceOwner::GetPluginPort().
|
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
((nsPluginNativeWindow*)window)->GetPluginWidget(getter_AddRefs(widget));
|
|
|
|
if (widget) {
|
|
|
|
window->window = (nsPluginPort*) widget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
|
|
|
}
|
|
|
|
#endif
|
2002-05-10 18:32:42 +00:00
|
|
|
if (window->window)
|
2003-09-16 01:44:41 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPluginInstance> inst = mInstance;
|
|
|
|
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
|
|
|
|
}
|
2002-05-10 18:32:42 +00:00
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
mPluginStreamInfo->SetSeekable(0);
|
2004-04-11 05:33:17 +00:00
|
|
|
mPStreamListener->OnStartBinding(mPluginStreamInfo);
|
2002-05-10 18:32:42 +00:00
|
|
|
mPluginStreamInfo->SetStreamOffset(0);
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
// force the plugin use stream as file
|
2002-08-29 22:00:20 +00:00
|
|
|
mStreamType = nsPluginStreamType_AsFile;
|
2002-05-10 18:32:42 +00:00
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
// then check it out if browser cache is not available
|
|
|
|
nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
|
|
|
|
if (!(cacheChannel && (NS_SUCCEEDED(cacheChannel->SetCacheAsFile(PR_TRUE))))) {
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
|
|
if (channel) {
|
|
|
|
SetupPluginCacheFile(channel);
|
|
|
|
}
|
2002-05-10 18:32:42 +00:00
|
|
|
}
|
|
|
|
|
2004-10-11 04:01:49 +00:00
|
|
|
// unset mPendingRequests
|
2002-05-26 22:52:19 +00:00
|
|
|
mPendingRequests = 0;
|
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-03-19 22:05:04 +00:00
|
|
|
NS_IMPL_ISUPPORTS1(nsPluginByteRangeStreamListener, nsIStreamListener)
|
2002-05-26 22:52:19 +00:00
|
|
|
nsPluginByteRangeStreamListener::nsPluginByteRangeStreamListener(nsIWeakReference* aWeakPtr)
|
2002-05-10 18:32:42 +00:00
|
|
|
{
|
2002-05-26 22:52:19 +00:00
|
|
|
mWeakPtrPluginStreamListenerPeer = aWeakPtr;
|
|
|
|
mRemoveMagicNumber = PR_FALSE;
|
2002-05-10 18:32:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPluginByteRangeStreamListener::~nsPluginByteRangeStreamListener()
|
|
|
|
{
|
|
|
|
mStreamConverter = 0;
|
2002-05-26 22:52:19 +00:00
|
|
|
mWeakPtrPluginStreamListenerPeer = 0;
|
2002-05-10 18:32:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginByteRangeStreamListener::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
nsCOMPtr<nsIStreamListener> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
|
|
|
if (!finalStreamListener)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2006-06-18 21:18:22 +00:00
|
|
|
nsCOMPtr<nsIStreamConverterService> serv = do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
|
2002-05-10 18:32:42 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2004-06-29 16:45:07 +00:00
|
|
|
rv = serv->AsyncConvertData(MULTIPART_BYTERANGES,
|
|
|
|
"*/*",
|
2002-05-26 22:52:19 +00:00
|
|
|
finalStreamListener,
|
2002-05-10 18:32:42 +00:00
|
|
|
nsnull,
|
|
|
|
getter_AddRefs(mStreamConverter));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = mStreamConverter->OnStartRequest(request, ctxt);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
}
|
2002-05-26 22:52:19 +00:00
|
|
|
}
|
|
|
|
mStreamConverter = 0;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
|
|
|
|
if (!httpChannel) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
PRUint32 responseCode = 0;
|
|
|
|
rv = httpChannel->GetResponseStatus(&responseCode);
|
2008-08-04 21:17:55 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2002-05-26 22:52:19 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2002-05-10 18:32:42 +00:00
|
|
|
}
|
2008-08-04 21:17:55 +00:00
|
|
|
|
|
|
|
// get nsPluginStreamListenerPeer* ptr from finalStreamListener
|
|
|
|
nsPluginStreamListenerPeer *pslp =
|
|
|
|
reinterpret_cast<nsPluginStreamListenerPeer*>(finalStreamListener.get());
|
|
|
|
|
|
|
|
if (responseCode != 200) {
|
|
|
|
PRBool bWantsAllNetworkStreams = PR_FALSE;
|
|
|
|
pslp->GetPluginInstance()->
|
|
|
|
GetValue(nsPluginInstanceVariable_WantsAllNetworkStreams,
|
|
|
|
(void *)&bWantsAllNetworkStreams);
|
|
|
|
if (!bWantsAllNetworkStreams){
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
2002-05-10 18:32:42 +00:00
|
|
|
|
|
|
|
// if server cannot continue with byte range (206 status) and sending us whole object (200 status)
|
|
|
|
// reset this seekable stream & try serve it to plugin instance as a file
|
2002-05-26 22:52:19 +00:00
|
|
|
mStreamConverter = finalStreamListener;
|
|
|
|
mRemoveMagicNumber = PR_TRUE;
|
|
|
|
|
|
|
|
rv = pslp->ServeStreamAsFile(request, ctxt);
|
2002-05-10 18:32:42 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginByteRangeStreamListener::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
|
|
|
nsresult status)
|
|
|
|
{
|
2002-05-26 22:52:19 +00:00
|
|
|
if (!mStreamConverter)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamListener> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
2004-10-11 04:01:49 +00:00
|
|
|
if (!finalStreamListener)
|
2002-05-26 22:52:19 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
if (mRemoveMagicNumber) {
|
2002-05-10 18:32:42 +00:00
|
|
|
// remove magic number from container
|
|
|
|
nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(ctxt);
|
|
|
|
if (container) {
|
|
|
|
PRUint32 magicNumber = 0;
|
|
|
|
container->GetData(&magicNumber);
|
|
|
|
if (magicNumber == MAGIC_REQUEST_CONTEXT) {
|
2002-05-26 22:52:19 +00:00
|
|
|
// to allow properly finish nsPluginStreamListenerPeer->OnStopRequest()
|
2002-05-10 18:32:42 +00:00
|
|
|
// set it to something that is not the magic number.
|
|
|
|
container->SetData(0);
|
|
|
|
}
|
2002-05-26 22:52:19 +00:00
|
|
|
} else {
|
|
|
|
NS_WARNING("Bad state of nsPluginByteRangeStreamListener");
|
2002-05-10 18:32:42 +00:00
|
|
|
}
|
|
|
|
}
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
return mStreamConverter->OnStopRequest(request, ctxt, status);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPluginByteRangeStreamListener::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
|
|
|
|
nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count)
|
|
|
|
{
|
2002-05-26 22:52:19 +00:00
|
|
|
if (!mStreamConverter)
|
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-26 22:52:19 +00:00
|
|
|
nsCOMPtr<nsIStreamListener> finalStreamListener = do_QueryReferent(mWeakPtrPluginStreamListenerPeer);
|
|
|
|
if (!finalStreamListener)
|
|
|
|
return NS_ERROR_FAILURE;
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-05-10 18:32:42 +00:00
|
|
|
return mStreamConverter->OnDataAvailable(request, ctxt, inStr, sourceOffset, count);
|
|
|
|
}
|
2002-08-29 22:00:20 +00:00
|
|
|
|
|
|
|
PRBool
|
2004-10-11 04:01:49 +00:00
|
|
|
nsPluginStreamInfo::UseExistingPluginCacheFile(nsPluginStreamInfo* psi)
|
2002-08-29 22:00:20 +00:00
|
|
|
{
|
2004-10-11 04:01:49 +00:00
|
|
|
|
2002-08-29 22:00:20 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(psi);
|
|
|
|
|
|
|
|
if ( psi->mLength == mLength &&
|
|
|
|
psi->mModified == mModified &&
|
2002-09-12 19:12:56 +00:00
|
|
|
mStreamComplete &&
|
2002-08-29 22:00:20 +00:00
|
|
|
!PL_strcmp(psi->mURL, mURL))
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
2004-10-11 04:01:49 +00:00
|
|
|
}
|
2002-08-29 22:00:20 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-09-12 19:12:56 +00:00
|
|
|
void
|
2002-09-12 21:59:53 +00:00
|
|
|
nsPluginStreamInfo::SetStreamComplete(const PRBool complete)
|
2002-09-12 19:12:56 +00:00
|
|
|
{
|
|
|
|
mStreamComplete = complete;
|
2004-04-11 05:33:17 +00:00
|
|
|
|
|
|
|
if (complete) {
|
|
|
|
// We're done, release the request.
|
|
|
|
SetRequest(nsnull);
|
|
|
|
}
|
2002-09-12 19:12:56 +00:00
|
|
|
}
|
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()));
|
|
|
|
|
|
|
|
instance->Stop();
|
|
|
|
|
|
|
|
nsRefPtr<nsPluginHostImpl> host = nsPluginHostImpl::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;
|
|
|
|
}
|