nsPluginHostImpl.cpp - Revision 1.254

There were 41 changes made.
Legend
   Added lines
   Changed lines
   Removed lines

nsPluginHostImpl.cpp,1.254
.
Disk File
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
.
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
.
 *
 * The contents of this file are subject to the Netscape Public
.
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
.
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
.
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/
.
 * the License at http://www.mozilla.org/NPL/
 *
.
 *
 * Software distributed under the License is distributed on an "AS
.
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
.
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
.
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
.
 * rights and limitations under the License.
 *
.
 *
 * The Original Code is mozilla.org code.
.
 * The Original Code is mozilla.org code.
 *
.
 *
 * The Initial Developer of the Original Code is Netscape
.
 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
.
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation. All
.
 * Copyright (C) 1998 Netscape Communications Corporation. All
 * Rights Reserved.
.
 * Rights Reserved.
 *
.
 *
 * Contributor(s): 
.
 * Contributor(s): 
 *   Sean Echevarria <sean@beatnik.com>
.
 *   Sean Echevarria <sean@beatnik.com>
 *   Håkan Waara <hwaara@chello.se>
.
 *   Håkan Waara <hwaara@chello.se>
 */
.
 */
 
.
 
#include "nsPluginHostImpl.h"
.
#include "nsPluginHostImpl.h"
#include "nsPluginProxyImpl.h"
.
#include "nsPluginProxyImpl.h"
#include <stdio.h>
.
#include <stdio.h>
#include "prio.h"
.
#include "prio.h"
#include "prmem.h"
.
#include "prmem.h"
#include "ns4xPlugin.h"
.
#include "ns4xPlugin.h"
#include "nsPluginInstancePeer.h"
.
#include "nsPluginInstancePeer.h"
 
.
 
#include "nsIPlugin.h"
.
#include "nsIPlugin.h"
#include "nsIJVMPlugin.h"
.
#include "nsIJVMPlugin.h"
#include "nsIPluginStreamListener.h"
.
#include "nsIPluginStreamListener.h"
#include "nsIHTTPHeaderListener.h" 
.
#include "nsIHTTPHeaderListener.h" 
#include "nsIObserverService.h"
.
#include "nsIObserverService.h"
#include "nsIHttpProtocolHandler.h"
.
#include "nsIHttpProtocolHandler.h"
#include "nsIHttpChannel.h"
.
#include "nsIHttpChannel.h"
 
.
#include "nsIByteRangeRequest.h"
#include "nsIStreamListener.h"
.
#include "nsIStreamListener.h"
#include "nsIInputStream.h"
.
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
.
#include "nsIOutputStream.h"
#include "nsIURL.h"
.
#include "nsIURL.h"
#include "nsXPIDLString.h"
.
#include "nsXPIDLString.h"
#include "nsIPref.h"
.
#include "nsIPref.h"
#include "nsIProtocolProxyService.h"
.
#include "nsIProtocolProxyService.h"
 
.
#include "nsIStreamConverterService.h"
#include "nsIFile.h"
.
#include "nsIFile.h"
#include "nsIInputStream.h"
.
#include "nsIInputStream.h"
#include "nsIIOService.h"
.
#include "nsIIOService.h"
#include "nsIURL.h"
.
#include "nsIURL.h"
#include "nsIChannel.h"
.
#include "nsIChannel.h"
#include "nsIFileStream.h" // for nsIRandomAccessStore
.
#include "nsIFileStream.h" // for nsIRandomAccessStore
#include "nsNetUtil.h"
.
#include "nsNetUtil.h"
#include "nsIProgressEventSink.h"
.
#include "nsIProgressEventSink.h"
#include "nsIDocument.h"
.
#include "nsIDocument.h"
#include "nsIScriptablePlugin.h"
.
#include "nsIScriptablePlugin.h"
#include "nsICachingChannel.h"
.
#include "nsICachingChannel.h"
 
.
#include "nsHashtable.h"
 
.
 
 
.
 
// Friggin' X11 has to "#define None". Lame!
.
// Friggin' X11 has to "#define None". Lame!
#ifdef None
.
#ifdef None
#undef None
.
#undef None
#endif
.
#endif
 
.
 
#include "nsIRegistry.h"
.
#include "nsIRegistry.h"
#include "nsEnumeratorUtils.h"
.
#include "nsEnumeratorUtils.h"
 
.
#include "nsISupportsPrimitives.h"
// for the dialog
.
// for the dialog
#include "nsIStringBundle.h"
.
#include "nsIStringBundle.h"
#include "nsIPrompt.h"
.
#include "nsIPrompt.h"
#include "nsIWindowWatcher.h"
.
#include "nsIWindowWatcher.h"
#include "nsHashtable.h"
.
 
 
.
 
#include "nsIScriptGlobalObject.h"
.
#include "nsIScriptGlobalObject.h"
#include "nsIScriptGlobalObjectOwner.h"
.
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIPrincipal.h"
.
#include "nsIPrincipal.h"
 
.
 
#include "nsIServiceManager.h"
.
#include "nsIServiceManager.h"
#include "nsICookieStorage.h"
.
#include "nsICookieStorage.h"
#include "nsICookieService.h"
.
#include "nsICookieService.h"
#include "nsIDOMPlugin.h"
.
#include "nsIDOMPlugin.h"
#include "nsIDOMMimeType.h"
.
#include "nsIDOMMimeType.h"
#include "prprf.h"
.
#include "prprf.h"
 
.
 
#if defined(XP_PC) && !defined(XP_OS2)
.
#if defined(XP_PC) && !defined(XP_OS2)
#include "windows.h"
.
#include "windows.h"
#include "winbase.h"
.
#include "winbase.h"
#endif
.
#endif
 
.
 
#include "nsSpecialSystemDirectory.h"
.
#include "nsSpecialSystemDirectory.h"
#include "nsFileSpec.h"
.
#include "nsFileSpec.h"
 
.
 
#include "nsPluginDocLoaderFactory.h"
.
#include "nsPluginDocLoaderFactory.h"
#include "nsIDocumentLoaderFactory.h"
.
#include "nsIDocumentLoaderFactory.h"
 
.
 
#include "nsIMIMEService.h"
.
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
.
#include "nsCExternalHandlerService.h"
#include "nsILocalFile.h"
.
#include "nsILocalFile.h"
#include "nsIFileChannel.h"
.
#include "nsIFileChannel.h"
 
.
 
#ifdef XP_UNIX
.
#ifdef XP_UNIX
#if defined(MOZ_WIDGET_GTK)
.
#if defined(MOZ_WIDGET_GTK)
#include <gdk/gdkx.h> // for GDK_DISPLAY()
.
#include <gdk/gdkx.h> // for GDK_DISPLAY()
#elif defined(MOZ_WIDGET_QT)
.
#elif defined(MOZ_WIDGET_QT)
#include <qwindowdefs.h> // for qt_xdisplay()
.
#include <qwindowdefs.h> // for qt_xdisplay()
#endif
.
#endif
#endif
.
#endif
 
.
 
#if defined(XP_MAC) && TARGET_CARBON
.
#if defined(XP_MAC) && TARGET_CARBON
#include "nsIClassicPluginFactory.h"
.
#include "nsIClassicPluginFactory.h"
#endif
.
#endif
 
.
 
#if defined(XP_MAC) && TARGET_CARBON
.
#if defined(XP_MAC) && TARGET_CARBON
#include "nsIClassicPluginFactory.h"
.
#include "nsIClassicPluginFactory.h"
#endif
.
#endif
 
.
 
// We need this hackery so that we can dynamically register doc
.
// We need this hackery so that we can dynamically register doc
// loaders for the 4.x plugins that we discover.
.
// loaders for the 4.x plugins that we discover.
#if defined(XP_PC)
.
#if defined(XP_PC)
#define PLUGIN_DLL "gkplugin.dll"
.
#define PLUGIN_DLL "gkplugin.dll"
#elif defined(XP_UNIX) || defined(XP_BEOS)
.
#elif defined(XP_UNIX) || defined(XP_BEOS)
#define PLUGIN_DLL "libgkplugin" MOZ_DLL_SUFFIX
.
#define PLUGIN_DLL "libgkplugin" MOZ_DLL_SUFFIX
#elif defined(XP_MAC)
.
#elif defined(XP_MAC)
#if defined(NS_DEBUG)
.
#if defined(NS_DEBUG)
#define PLUGIN_DLL "pluginDebug.shlb"
.
#define PLUGIN_DLL "pluginDebug.shlb"
#else
.
#else
#define PLUGIN_DLL "plugin.shlb"
.
#define PLUGIN_DLL "plugin.shlb"
#endif // ifdef NS_DEBUG
.
#endif // ifdef NS_DEBUG
#endif
.
#endif
 
.
 
#define REL_PLUGIN_DLL "rel:" PLUGIN_DLL
.
#define REL_PLUGIN_DLL "rel:" PLUGIN_DLL
 
.
 
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
.
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
static NS_DEFINE_IID(kIPluginInstancePeerIID, NS_IPLUGININSTANCEPEER_IID); 
.
static NS_DEFINE_IID(kIPluginInstancePeerIID, NS_IPLUGININSTANCEPEER_IID); 
static NS_DEFINE_IID(kIPluginStreamInfoIID, NS_IPLUGINSTREAMINFO_IID);
.
static NS_DEFINE_IID(kIPluginStreamInfoIID, NS_IPLUGINSTREAMINFO_IID);
static NS_DEFINE_CID(kPluginCID, NS_PLUGIN_CID);
.
static NS_DEFINE_CID(kPluginCID, NS_PLUGIN_CID);
static NS_DEFINE_IID(kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID); 
.
static NS_DEFINE_IID(kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID); 
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
.
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kProtocolProxyServiceCID, NS_PROTOCOLPROXYSERVICE_CID);
.
static NS_DEFINE_CID(kProtocolProxyServiceCID, NS_PROTOCOLPROXYSERVICE_CID);
static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
.
static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
.
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
.
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
static NS_DEFINE_IID(kIRequestObserverIID, NS_IREQUESTOBSERVER_IID);
.
static NS_DEFINE_IID(kIRequestObserverIID, NS_IREQUESTOBSERVER_IID);
 
.
 
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
.
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kHttpHandlerCID, NS_HTTPPROTOCOLHANDLER_CID);
.
static NS_DEFINE_CID(kHttpHandlerCID, NS_HTTPPROTOCOLHANDLER_CID);
static NS_DEFINE_CID(kIHttpHeaderVisitorIID, NS_IHTTPHEADERVISITOR_IID);
.
static NS_DEFINE_CID(kIHttpHeaderVisitorIID, NS_IHTTPHEADERVISITOR_IID);
 
 
.
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID
);
 
.
 
static NS_DEFINE_IID(kIFileUtilitiesIID, NS_IFILEUTILITIES_IID);
.
static NS_DEFINE_IID(kIFileUtilitiesIID, NS_IFILEUTILITIES_IID);
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
.
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
 
.
 
static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
.
static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
 
.
 
// for the dialog
.
// for the dialog
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
.
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
 
.
 
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
.
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
 
.
 
#define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.propert
ies"
.
#define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.propert
ies"
#define PLUGIN_REGIONAL_URL "chrome://global-region/locale/region.properties"
.
#define PLUGIN_REGIONAL_URL "chrome://global-region/locale/region.properties"
 
.
 
// #defines for reading prefs and extra search plugin paths from windows regis
try
.
// #defines for reading prefs and extra search plugin paths from windows regis
try
#define _MAXKEYVALUE_ 8196
.
#define _MAXKEYVALUE_ 8196
#define _NS_PREF_COMMON_PLUGIN_REG_KEY_ "browser.plugins.registry_plugins_fold
er_key_location"
.
#define _NS_PREF_COMMON_PLUGIN_REG_KEY_ "browser.plugins.registry_plugins_fold
er_key_location"
#define _NS_COMMON_PLUGIN_KEY_NAME_ "Plugins Folders"
.
#define _NS_COMMON_PLUGIN_KEY_NAME_ "Plugins Folders"
 
.
 
// #defines for plugin cache and prefs
.
// #defines for plugin cache and prefs
#define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins
"
.
#define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins
"
#define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
.
#define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
 
.
 
 
.
#define MAGIC_REQUEST_CONTEXT 0x01020304
 
.
 
void DisplayNoDefaultPluginDialog(const char *mimeType);
.
void DisplayNoDefaultPluginDialog(const char *mimeType);
 
.
 
/**
.
/**
 * Used in DisplayNoDefaultPlugindialog to prevent showing the dialog twice
.
 * Used in DisplayNoDefaultPlugindialog to prevent showing the dialog twice
 * for the same mimetype.
.
 * for the same mimetype.
 */
.
 */
 
.
 
static nsHashtable *mimeTypesSeen = nsnull;
.
static nsHashtable *mimeTypesSeen = nsnull;
 
.
 
/**
.
/**
 * placeholder value for mimeTypesSeen hashtable
.
 * placeholder value for mimeTypesSeen hashtable
 */
.
 */
 
.
 
static const char *hashValue = "value";
.
static const char *hashValue = "value";
 
.
 
/**
.
/**
 * Default number of entries in the mimeTypesSeen hashtable
.
 * Default number of entries in the mimeTypesSeen hashtable
 */ 
.
 */ 
#define NS_MIME_TYPES_HASH_NUM (20)
.
#define NS_MIME_TYPES_HASH_NUM (20)
 
.
 
 
.
 
void DisplayNoDefaultPluginDialog(const char *mimeType)
.
void DisplayNoDefaultPluginDialog(const char *mimeType)
{
.
{
  nsresult rv;
.
  nsresult rv;
 
.
 
  if (nsnull == mimeTypesSeen) {
.
  if (nsnull == mimeTypesSeen) {
    mimeTypesSeen = new nsHashtable(NS_MIME_TYPES_HASH_NUM);
.
    mimeTypesSeen = new nsHashtable(NS_MIME_TYPES_HASH_NUM);
  }
.
  }
  if ((mimeTypesSeen != nsnull) && (mimeType != nsnull)) {
.
  if ((mimeTypesSeen != nsnull) && (mimeType != nsnull)) {
    nsCStringKey key(mimeType);
.
    nsCStringKey key(mimeType);
    // if we've seen this mimetype before
.
    // if we've seen this mimetype before
    if (mimeTypesSeen->Get(&key)) {
.
    if (mimeTypesSeen->Get(&key)) {
      // don't display the dialog
.
      // don't display the dialog
      return;
.
      return;
    }
.
    }
    else {
.
    else {
      mimeTypesSeen->Put(&key, (void *) hashValue);
.
      mimeTypesSeen->Put(&key, (void *) hashValue);
    }
.
    }
  }
.
  }
 
.
 
  nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
.
  nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
  nsCOMPtr<nsIPrompt> prompt;
.
  nsCOMPtr<nsIPrompt> prompt;
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/wind
ow-watcher;1"));
.
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/wind
ow-watcher;1"));
  if (wwatch)
.
  if (wwatch)
    wwatch->GetNewPrompter(0, getter_AddRefs(prompt));
.
    wwatch->GetNewPrompter(0, getter_AddRefs(prompt));
 
.
 
  nsCOMPtr<nsIIOService> io(do_GetService(kIOServiceCID));
.
  nsCOMPtr<nsIIOService> io(do_GetService(kIOServiceCID));
  nsCOMPtr<nsIStringBundleService> strings(do_GetService(kStringBundleServiceC
ID));
.
  nsCOMPtr<nsIStringBundleService> strings(do_GetService(kStringBundleServiceC
ID));
  nsCOMPtr<nsIStringBundle> bundle;
.
  nsCOMPtr<nsIStringBundle> bundle;
  nsCOMPtr<nsIStringBundle> regionalBundle;
.
  nsCOMPtr<nsIStringBundle> regionalBundle;
  nsCOMPtr<nsIURI> uri;
.
  nsCOMPtr<nsIURI> uri;
  char *spec = nsnull;
.
  char *spec = nsnull;
  PRBool displayDialogPrefValue = PR_FALSE, checkboxState = PR_FALSE;
.
  PRBool displayDialogPrefValue = PR_FALSE, checkboxState = PR_FALSE;
 
.
 
  if (!prefs || !prompt || !io || !strings) {
.
  if (!prefs || !prompt || !io || !strings) {
    return;
.
    return;
  }
.
  }
 
.
 
  rv = prefs->GetBoolPref("plugin.display_plugin_downloader_dialog", 
.
  rv = prefs->GetBoolPref("plugin.display_plugin_downloader_dialog", 
                          &displayDialogPrefValue);
.
                          &displayDialogPrefValue);
  if (NS_SUCCEEDED(rv)) {
.
  if (NS_SUCCEEDED(rv)) {
    // if the pref is false, don't display the dialog
.
    // if the pref is false, don't display the dialog
    if (!displayDialogPrefValue) {
.
    if (!displayDialogPrefValue) {
      return;
.
      return;
    }
.
    }
  }
.
  }
  
.
  
  // Taken from mozilla\extensions\wallet\src\wallet.cpp
.
  // Taken from mozilla\extensions\wallet\src\wallet.cpp
  // WalletLocalize().
.
  // WalletLocalize().
  rv = strings->CreateBundle(PLUGIN_PROPERTIES_URL, getter_AddRefs(bundle));
.
  rv = strings->CreateBundle(PLUGIN_PROPERTIES_URL, getter_AddRefs(bundle));
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    return;
.
    return;
  }
.
  }
  rv = strings->CreateBundle(PLUGIN_REGIONAL_URL, 
.
  rv = strings->CreateBundle(PLUGIN_REGIONAL_URL, 
                             getter_AddRefs(regionalBundle));
.
                             getter_AddRefs(regionalBundle));
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    return;
.
    return;
  }
.
  }
 
.
 
  PRUnichar *titleUni = nsnull;
.
  PRUnichar *titleUni = nsnull;
  PRUnichar *messageUni = nsnull;
.
  PRUnichar *messageUni = nsnull;
  PRUnichar *checkboxMessageUni = nsnull;
.
  PRUnichar *checkboxMessageUni = nsnull;
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("noDefaultPluginTitle").get
(), 
.
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("noDefaultPluginTitle").get
(), 
                                 &titleUni);
.
                                 &titleUni);
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    goto EXIT_DNDPD;
.
    goto EXIT_DNDPD;
  }
.
  }
  rv = regionalBundle->GetStringFromName(NS_LITERAL_STRING("noDefaultPluginMes
sage").get(), 
.
  rv = regionalBundle->GetStringFromName(NS_LITERAL_STRING("noDefaultPluginMes
sage").get(), 
                                         &messageUni);
.
                                         &messageUni);
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    goto EXIT_DNDPD;
.
    goto EXIT_DNDPD;
  }
.
  }
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("noDefaultPluginCheckboxMes
sage").get(), 
.
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("noDefaultPluginCheckboxMes
sage").get(), 
                                 &checkboxMessageUni);
.
                                 &checkboxMessageUni);
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    goto EXIT_DNDPD;
.
    goto EXIT_DNDPD;
  }
.
  }
 
.
 
  PRInt32 buttonPressed;
.
  PRInt32 buttonPressed;
  rv = prompt->ConfirmEx(titleUni, messageUni,
.
  rv = prompt->ConfirmEx(titleUni, messageUni,
                         nsIPrompt::BUTTON_TITLE_OK * nsIPrompt::BUTTON_POS_0,
.
                         nsIPrompt::BUTTON_TITLE_OK * nsIPrompt::BUTTON_POS_0,
                         nsnull, nsnull, nsnull,
.
                         nsnull, nsnull, nsnull,
                         checkboxMessageUni, &checkboxState, &buttonPressed);
.
                         checkboxMessageUni, &checkboxState, &buttonPressed);
 
.
 
  // if the user checked the checkbox, make it so the dialog doesn't
.
  // if the user checked the checkbox, make it so the dialog doesn't
  // display again.
.
  // display again.
  if (checkboxState) {
.
  if (checkboxState) {
    prefs->SetBoolPref("plugin.display_plugin_downloader_dialog",
.
    prefs->SetBoolPref("plugin.display_plugin_downloader_dialog",
                       !checkboxState);
.
                       !checkboxState);
  }
.
  }
 EXIT_DNDPD:
.
 EXIT_DNDPD:
  nsMemory::Free((void *)titleUni);
.
  nsMemory::Free((void *)titleUni);
  nsMemory::Free((void *)messageUni);
.
  nsMemory::Free((void *)messageUni);
  nsMemory::Free((void *)checkboxMessageUni);
.
  nsMemory::Free((void *)checkboxMessageUni);
  return;
.
  return;
}
.
}
 
.
 
nsActivePlugin::nsActivePlugin(nsPluginTag* aPluginTag,
.
nsActivePlugin::nsActivePlugin(nsPluginTag* aPluginTag,
                               nsIPluginInstance* aInstance, 
.
                               nsIPluginInstance* aInstance, 
                               char * url,
.
                               char * url,
                               PRBool aDefaultPlugin)
.
                               PRBool aDefaultPlugin)
{
.
{
  mNext = nsnull;
.
  mNext = nsnull;
  mPeer = nsnull;
.
  mPeer = nsnull;
  mPluginTag = aPluginTag;
.
  mPluginTag = aPluginTag;
 
.
 
  mURL = PL_strdup(url);
.
  mURL = PL_strdup(url);
  mInstance = aInstance;
.
  mInstance = aInstance;
  if(aInstance != nsnull)
.
  if(aInstance != nsnull)
  {
.
  {
    aInstance->GetPeer(&mPeer);
.
    aInstance->GetPeer(&mPeer);
    NS_ADDREF(aInstance);
.
    NS_ADDREF(aInstance);
  }
.
  }
  mXPConnected = PR_FALSE;
.
  mXPConnected = PR_FALSE;
  mDefaultPlugin = aDefaultPlugin;
.
  mDefaultPlugin = aDefaultPlugin;
  mStopped = PR_FALSE;
.
  mStopped = PR_FALSE;
  mllStopTime = LL_ZERO;
.
  mllStopTime = LL_ZERO;
}
.
}
 
.
 
nsActivePlugin::~nsActivePlugin()
.
nsActivePlugin::~nsActivePlugin()
{
.
{
  mPluginTag = nsnull;
.
  mPluginTag = nsnull;
  if(mInstance != nsnull)
.
  if(mInstance != nsnull)
  {
.
  {
    mInstance->Destroy();
.
    mInstance->Destroy();
    NS_RELEASE(mInstance);
.
    NS_RELEASE(mInstance);
    NS_RELEASE(mPeer);
.
    NS_RELEASE(mPeer);
  }
.
  }
  PL_strfree(mURL);
.
  PL_strfree(mURL);
}
.
}
 
.
 
void nsActivePlugin::setStopped(PRBool stopped)
.
void nsActivePlugin::setStopped(PRBool stopped)
{
.
{
  mStopped = stopped;
.
  mStopped = stopped;
  if(mStopped)
.
  if(mStopped)
    mllStopTime = PR_Now();
.
    mllStopTime = PR_Now();
  else
.
  else
    mllStopTime = LL_ZERO;
.
    mllStopTime = LL_ZERO;
}
.
}
 
.
 
nsActivePluginList::nsActivePluginList()
.
nsActivePluginList::nsActivePluginList()
{
.
{
  mFirst = nsnull;
.
  mFirst = nsnull;
  mLast = nsnull;
.
  mLast = nsnull;
  mCount = 0;
.
  mCount = 0;
}
.
}
 
.
 
nsActivePluginList::~nsActivePluginList()
.
nsActivePluginList::~nsActivePluginList()
{
.
{
  if(mFirst == nsnull)
.
  if(mFirst == nsnull)
    return;
.
    return;
  shut();
.
  shut();
}
.
}
 
.
 
void nsActivePluginList::shut()
.
void nsActivePluginList::shut()
{
.
{
  if(mFirst == nsnull)
.
  if(mFirst == nsnull)
    return;
.
    return;
 
.
 
  for(nsActivePlugin * plugin = mFirst; plugin != nsnull;)
.
  for(nsActivePlugin * plugin = mFirst; plugin != nsnull;)
  {
.
  {
    nsActivePlugin * next = plugin->mNext;
.
    nsActivePlugin * next = plugin->mNext;
 
.
 
    PRBool unloadLibLater = PR_FALSE;
.
    PRBool unloadLibLater = PR_FALSE;
    remove(plugin, &unloadLibLater);
.
    remove(plugin, &unloadLibLater);
    NS_ASSERTION(!unloadLibLater, "Plugin doesn't want to be unloaded");
.
    NS_ASSERTION(!unloadLibLater, "Plugin doesn't want to be unloaded");
    
.
    
    plugin = next;
.
    plugin = next;
  }
.
  }
  mFirst = nsnull;
.
  mFirst = nsnull;
  mLast = nsnull;
.
  mLast = nsnull;
}
.
}
 
.
 
PRInt32 nsActivePluginList::add(nsActivePlugin * plugin)
.
PRInt32 nsActivePluginList::add(nsActivePlugin * plugin)
{
.
{
  if (mFirst == nsnull)
.
  if (mFirst == nsnull)
  {
.
  {
    mFirst = plugin;
.
    mFirst = plugin;
    mLast = plugin;
.
    mLast = plugin;
    mFirst->mNext = nsnull;
.
    mFirst->mNext = nsnull;
  }
.
  }
  else
.
  else
  {
.
  {
    mLast->mNext = plugin;
.
    mLast->mNext = plugin;
    mLast = plugin;
.
    mLast = plugin;
  }
.
  }
  mLast->mNext = nsnull;
.
  mLast->mNext = nsnull;
  mCount++;
.
  mCount++;
  return mCount;
.
  return mCount;
}
.
}
 
.
 
PRBool nsActivePluginList::IsLastInstance(nsActivePlugin * plugin)
.
PRBool nsActivePluginList::IsLastInstance(nsActivePlugin * plugin)
{
.
{
  if(!plugin)
.
  if(!plugin)
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  if(!plugin->mPluginTag)
.
  if(!plugin->mPluginTag)
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
.
    if((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
      return PR_FALSE;
.
      return PR_FALSE;
  }
.
  }
  return PR_TRUE;
.
  return PR_TRUE;
}
.
}
 
.
 
PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * aUnloadLib
raryLater)
.
PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * aUnloadLib
raryLater)
{
.
{
  if(mFirst == nsnull)
.
  if(mFirst == nsnull)
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  nsActivePlugin * prev = nsnull;
.
  nsActivePlugin * prev = nsnull;
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if(p == plugin)
.
    if(p == plugin)
    {
.
    {
      PRBool lastInstance = IsLastInstance(p);
.
      PRBool lastInstance = IsLastInstance(p);
 
.
 
      if(p == mFirst)
.
      if(p == mFirst)
        mFirst = p->mNext;
.
        mFirst = p->mNext;
      else
.
      else
        prev->mNext = p->mNext;
.
        prev->mNext = p->mNext;
 
.
 
      if((prev != nsnull) && (prev->mNext == nsnull))
.
      if((prev != nsnull) && (prev->mNext == nsnull))
        mLast = prev;
.
        mLast = prev;
 
.
 
      // see if this is going to be the last instance of a plugin
.
      // see if this is going to be the last instance of a plugin
      // if so we should perform nsIPlugin::Shutdown and unload the library
.
      // if so we should perform nsIPlugin::Shutdown and unload the library
      // by calling nsPluginTag::TryUnloadPlugin()
.
      // by calling nsPluginTag::TryUnloadPlugin()
      if(lastInstance)
.
      if(lastInstance)
      {
.
      {
        // cache some things as we are going to destroy it right now
.
        // cache some things as we are going to destroy it right now
        nsPluginTag *pluginTag = p->mPluginTag;
.
        nsPluginTag *pluginTag = p->mPluginTag;
        
.
        
        delete p; // plugin instance is destroyed here
.
        delete p; // plugin instance is destroyed here
        
.
        
        if(pluginTag)
.
        if(pluginTag)
        {
.
        {
          // xpconnected plugins from the old world should postpone unloading 
library 
.
          // xpconnected plugins from the old world should postpone unloading 
library 
          // to avoid crash check, if so add library to the list of unloaded l
ibraries
.
          // to avoid crash check, if so add library to the list of unloaded l
ibraries
          if(pluginTag->mXPConnected && (pluginTag->mFlags & NS_PLUGIN_FLAG_OL
DSCHOOL))
.
          if(pluginTag->mXPConnected && (pluginTag->mFlags & NS_PLUGIN_FLAG_OL
DSCHOOL))
          {
.
          {
            pluginTag->mCanUnloadLibrary = PR_FALSE;
.
            pluginTag->mCanUnloadLibrary = PR_FALSE;
 
.
 
            if(aUnloadLibraryLater)
.
            if(aUnloadLibraryLater)
              *aUnloadLibraryLater = PR_TRUE;
.
              *aUnloadLibraryLater = PR_TRUE;
          }
.
          }
        
.
        
          pluginTag->TryUnloadPlugin();
.
          pluginTag->TryUnloadPlugin();
        }
.
        }
        else
.
        else
          NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown"
);
.
          NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown"
);
 
.
 
      }
.
      }
      else
.
      else
        delete p;
.
        delete p;
 
.
 
      mCount--;
.
      mCount--;
      return PR_TRUE;
.
      return PR_TRUE;
    }
.
    }
    prev = p;
.
    prev = p;
  }
.
  }
  return PR_FALSE;
.
  return PR_FALSE;
}
.
}
 
.
 
void nsActivePluginList::stopRunning()
.
void nsActivePluginList::stopRunning()
{
.
{
  if(mFirst == nsnull)
.
  if(mFirst == nsnull)
    return;
.
    return;
 
.
 
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if(!p->mStopped && p->mInstance)
.
    if(!p->mStopped && p->mInstance)
    {
.
    {
      p->mInstance->SetWindow(nsnull);
.
      p->mInstance->SetWindow(nsnull);
      p->mInstance->Stop();
.
      p->mInstance->Stop();
      p->setStopped(PR_TRUE);
.
      p->setStopped(PR_TRUE);
    }
.
    }
  }
.
  }
}
.
}
 
.
 
void nsActivePluginList::removeAllStopped()
.
void nsActivePluginList::removeAllStopped()
{
.
{
  if(mFirst == nsnull)
.
  if(mFirst == nsnull)
    return;
.
    return;
 
.
 
  nsActivePlugin * next = nsnull;
.
  nsActivePlugin * next = nsnull;
 
.
 
  for(nsActivePlugin * p = mFirst; p != nsnull;)
.
  for(nsActivePlugin * p = mFirst; p != nsnull;)
  {
.
  {
    next = p->mNext;
.
    next = p->mNext;
 
.
 
    if(p->mStopped)
.
    if(p->mStopped)
    {
.
    {
      // we don't care about unloading library problem for 
.
      // we don't care about unloading library problem for 
      // plugins that are already in the 'stop' state
.
      // plugins that are already in the 'stop' state
      PRBool unloadLibLater = PR_FALSE;
.
      PRBool unloadLibLater = PR_FALSE;
      remove(p, &unloadLibLater);
.
      remove(p, &unloadLibLater);
    }
.
    }
 
.
 
    p = next;
.
    p = next;
  }
.
  }
  return;
.
  return;
}
.
}
 
.
 
nsActivePlugin * nsActivePluginList::find(nsIPluginInstance* instance)
.
nsActivePlugin * nsActivePluginList::find(nsIPluginInstance* instance)
{
.
{
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if(p->mInstance == instance)
.
    if(p->mInstance == instance)
    {
.
    {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      PRBool doCache = PR_TRUE;
.
      PRBool doCache = PR_TRUE;
      p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
.
      p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
      NS_ASSERTION(!p->mStopped || doCache, "This plugin is not supposed to be
 cached!");
.
      NS_ASSERTION(!p->mStopped || doCache, "This plugin is not supposed to be
 cached!");
#endif
.
#endif
      return p;
.
      return p;
    }
.
    }
  }
.
  }
  return nsnull;
.
  return nsnull;
}
.
}
 
.
 
nsActivePlugin * nsActivePluginList::find(char * mimetype)
.
nsActivePlugin * nsActivePluginList::find(char * mimetype)
{
.
{
  PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
.
  PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
 
.
 
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    // give it some special treatment for the default plugin first
.
    // give it some special treatment for the default plugin first
    // because we cannot tell the default plugin by asking peer for a mime typ
e
.
    // because we cannot tell the default plugin by asking peer for a mime typ
e
    if(defaultplugin && p->mDefaultPlugin)
.
    if(defaultplugin && p->mDefaultPlugin)
      return p;
.
      return p;
 
.
 
    if(!p->mPeer)
.
    if(!p->mPeer)
      continue;
.
      continue;
 
.
 
    nsMIMEType mt;
.
    nsMIMEType mt;
 
.
 
    nsresult res = p->mPeer->GetMIMEType(&mt);
.
    nsresult res = p->mPeer->GetMIMEType(&mt);
 
.
 
    if(NS_FAILED(res))
.
    if(NS_FAILED(res))
      continue;
.
      continue;
 
.
 
    if(PL_strcasecmp(mt, mimetype) == 0)
.
    if(PL_strcasecmp(mt, mimetype) == 0)
    {
.
    {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      PRBool doCache = PR_TRUE;
.
      PRBool doCache = PR_TRUE;
      p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
.
      p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
      NS_ASSERTION(!p->mStopped || doCache, "This plugin is not supposed to be
 cached!");
.
      NS_ASSERTION(!p->mStopped || doCache, "This plugin is not supposed to be
 cached!");
#endif
.
#endif
       return p;
.
       return p;
    }
.
    }
  }
.
  }
  return nsnull;
.
  return nsnull;
}
.
}
 
.
 
nsActivePlugin * nsActivePluginList::findStopped(char * url)
.
nsActivePlugin * nsActivePluginList::findStopped(char * url)
{
.
{
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if(!PL_strcmp(url, p->mURL) && p->mStopped)
.
    if(!PL_strcmp(url, p->mURL) && p->mStopped)
    {
.
    {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      PRBool doCache = PR_TRUE;
.
      PRBool doCache = PR_TRUE;
      p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
.
      p->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
      NS_ASSERTION(doCache, "This plugin is not supposed to be cached!");
.
      NS_ASSERTION(doCache, "This plugin is not supposed to be cached!");
#endif
.
#endif
       return p;
.
       return p;
    }
.
    }
  }
.
  }
  return nsnull;
.
  return nsnull;
}
.
}
 
.
 
PRUint32 nsActivePluginList::getStoppedCount()
.
PRUint32 nsActivePluginList::getStoppedCount()
{
.
{
  PRUint32 stoppedCount = 0;
.
  PRUint32 stoppedCount = 0;
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if(p->mStopped)
.
    if(p->mStopped)
      stoppedCount++;
.
      stoppedCount++;
  }
.
  }
  return stoppedCount;
.
  return stoppedCount;
}
.
}
 
.
 
nsActivePlugin * nsActivePluginList::findOldestStopped()
.
nsActivePlugin * nsActivePluginList::findOldestStopped()
{
.
{
  nsActivePlugin * res = nsnull;
.
  nsActivePlugin * res = nsnull;
  PRInt64 llTime = LL_MAXINT;
.
  PRInt64 llTime = LL_MAXINT;
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
.
  for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
  {
.
  {
    if(!p->mStopped)
.
    if(!p->mStopped)
      continue;
.
      continue;
 
.
 
    if(LL_CMP(p->mllStopTime, <, llTime))
.
    if(LL_CMP(p->mllStopTime, <, llTime))
    {
.
    {
      llTime = p->mllStopTime;
.
      llTime = p->mllStopTime;
      res = p;
.
      res = p;
    }
.
    }
  }
.
  }
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  if(res)
.
  if(res)
  {
.
  {
    PRBool doCache = PR_TRUE;
.
    PRBool doCache = PR_TRUE;
    res->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
.
    res->mInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &d
oCache);
    NS_ASSERTION(doCache, "This plugin is not supposed to be cached!");
.
    NS_ASSERTION(doCache, "This plugin is not supposed to be cached!");
  }
.
  }
#endif
.
#endif
 
.
 
  return res;
.
  return res;
}
.
}
 
.
 
nsUnusedLibrary::nsUnusedLibrary(PRLibrary * aLibrary)
.
nsUnusedLibrary::nsUnusedLibrary(PRLibrary * aLibrary)
{
.
{
  mLibrary = aLibrary;
.
  mLibrary = aLibrary;
}
.
}
 
.
 
nsUnusedLibrary::~nsUnusedLibrary()
.
nsUnusedLibrary::~nsUnusedLibrary()
{
.
{
  if(mLibrary)
.
  if(mLibrary)
    PR_UnloadLibrary(mLibrary);
.
    PR_UnloadLibrary(mLibrary);
}
.
}
 
.
 
nsPluginTag::nsPluginTag()
.
nsPluginTag::nsPluginTag()
{
.
{
  mNext = nsnull;
.
  mNext = nsnull;
  mName = nsnull;
.
  mName = nsnull;
  mDescription = nsnull;
.
  mDescription = nsnull;
  mVariants = 0;
.
  mVariants = 0;
  mMimeTypeArray = nsnull;
.
  mMimeTypeArray = nsnull;
  mMimeDescriptionArray = nsnull;
.
  mMimeDescriptionArray = nsnull;
  mExtensionsArray = nsnull;
.
  mExtensionsArray = nsnull;
  mLibrary = nsnull;
.
  mLibrary = nsnull;
  mCanUnloadLibrary = PR_TRUE;
.
  mCanUnloadLibrary = PR_TRUE;
  mEntryPoint = nsnull;
.
  mEntryPoint = nsnull;
  mFlags = NS_PLUGIN_FLAG_ENABLED;
.
  mFlags = NS_PLUGIN_FLAG_ENABLED;
  mXPConnected = PR_FALSE;
.
  mXPConnected = PR_FALSE;
  mFileName = nsnull;
.
  mFileName = nsnull;
}
.
}
 
.
 
inline char* new_str(const char* str)
.
inline char* new_str(const char* str)
{
.
{
  if(str == nsnull)
.
  if(str == nsnull)
    return nsnull;
.
    return nsnull;
 
.
 
	char* result = new char[strlen(str) + 1];
.
	char* result = new char[strlen(str) + 1];
	if (result != nsnull)
.
	if (result != nsnull)
		return strcpy(result, str);
.
		return strcpy(result, str);
	return result;
.
	return result;
}
.
}
 
.
 
nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
.
nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
{
.
{
  mNext = nsnull;
.
  mNext = nsnull;
  mName = new_str(aPluginTag->mName);
.
  mName = new_str(aPluginTag->mName);
  mDescription = new_str(aPluginTag->mDescription);
.
  mDescription = new_str(aPluginTag->mDescription);
  mVariants = aPluginTag->mVariants;
.
  mVariants = aPluginTag->mVariants;
 
.
 
  mMimeTypeArray = nsnull;
.
  mMimeTypeArray = nsnull;
  mMimeDescriptionArray = nsnull;
.
  mMimeDescriptionArray = nsnull;
  mExtensionsArray = nsnull;
.
  mExtensionsArray = nsnull;
 
.
 
  if(aPluginTag->mMimeTypeArray != nsnull)
.
  if(aPluginTag->mMimeTypeArray != nsnull)
  {
.
  {
    mMimeTypeArray = new char*[mVariants];
.
    mMimeTypeArray = new char*[mVariants];
    for (int i = 0; i < mVariants; i++)
.
    for (int i = 0; i < mVariants; i++)
      mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
.
      mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
  }
.
  }
 
.
 
  if(aPluginTag->mMimeDescriptionArray != nsnull) 
.
  if(aPluginTag->mMimeDescriptionArray != nsnull) 
  {
.
  {
    mMimeDescriptionArray = new char*[mVariants];
.
    mMimeDescriptionArray = new char*[mVariants];
    for (int i = 0; i < mVariants; i++)
.
    for (int i = 0; i < mVariants; i++)
      mMimeDescriptionArray[i] = new_str(aPluginTag->mMimeDescriptionArray[i])
;
.
      mMimeDescriptionArray[i] = new_str(aPluginTag->mMimeDescriptionArray[i])
;
  }
.
  }
 
.
 
  if(aPluginTag->mExtensionsArray != nsnull) 
.
  if(aPluginTag->mExtensionsArray != nsnull) 
  {
.
  {
    mExtensionsArray = new char*[mVariants];
.
    mExtensionsArray = new char*[mVariants];
    for (int i = 0; i < mVariants; i++)
.
    for (int i = 0; i < mVariants; i++)
      mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
.
      mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
	}
.
	}
 
.
 
  mLibrary = nsnull;
.
  mLibrary = nsnull;
  mCanUnloadLibrary = PR_TRUE;
.
  mCanUnloadLibrary = PR_TRUE;
  mEntryPoint = nsnull;
.
  mEntryPoint = nsnull;
  mFlags = NS_PLUGIN_FLAG_ENABLED;
.
  mFlags = NS_PLUGIN_FLAG_ENABLED;
  mXPConnected = PR_FALSE;
.
  mXPConnected = PR_FALSE;
  mFileName = new_str(aPluginTag->mFileName);
.
  mFileName = new_str(aPluginTag->mFileName);
}
.
}
 
.
 
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
.
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
{
.
{
  mNext = nsnull;
.
  mNext = nsnull;
  mName = new_str(aPluginInfo->fName);
.
  mName = new_str(aPluginInfo->fName);
  mDescription = new_str(aPluginInfo->fDescription);
.
  mDescription = new_str(aPluginInfo->fDescription);
  mVariants = aPluginInfo->fVariantCount;
.
  mVariants = aPluginInfo->fVariantCount;
 
.
 
  mMimeTypeArray = nsnull;
.
  mMimeTypeArray = nsnull;
  mMimeDescriptionArray = nsnull;
.
  mMimeDescriptionArray = nsnull;
  mExtensionsArray = nsnull;
.
  mExtensionsArray = nsnull;
 
.
 
  if(aPluginInfo->fMimeTypeArray != nsnull)
.
  if(aPluginInfo->fMimeTypeArray != nsnull)
  {
.
  {
    mMimeTypeArray = new char*[mVariants];
.
    mMimeTypeArray = new char*[mVariants];
    for (int i = 0; i < mVariants; i++)
.
    for (int i = 0; i < mVariants; i++)
      mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
.
      mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
  }
.
  }
 
.
 
  if(aPluginInfo->fMimeDescriptionArray != nsnull) 
.
  if(aPluginInfo->fMimeDescriptionArray != nsnull) 
  {
.
  {
    mMimeDescriptionArray = new char*[mVariants];
.
    mMimeDescriptionArray = new char*[mVariants];
    for (int i = 0; i < mVariants; i++)
.
    for (int i = 0; i < mVariants; i++)
      mMimeDescriptionArray[i] = new_str(aPluginInfo->fMimeDescriptionArray[i]
);
.
      mMimeDescriptionArray[i] = new_str(aPluginInfo->fMimeDescriptionArray[i]
);
  }
.
  }
 
.
 
  if(aPluginInfo->fExtensionArray != nsnull) 
.
  if(aPluginInfo->fExtensionArray != nsnull) 
  {
.
  {
    mExtensionsArray = new char*[mVariants];
.
    mExtensionsArray = new char*[mVariants];
    for (int i = 0; i < mVariants; i++)
.
    for (int i = 0; i < mVariants; i++)
      mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
.
      mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
	}
.
	}
 
.
 
  mFileName = new_str(aPluginInfo->fFileName);
.
  mFileName = new_str(aPluginInfo->fFileName);
 
.
 
  mLibrary = nsnull;
.
  mLibrary = nsnull;
  mCanUnloadLibrary = PR_TRUE;
.
  mCanUnloadLibrary = PR_TRUE;
  mEntryPoint = nsnull;
.
  mEntryPoint = nsnull;
  mFlags = NS_PLUGIN_FLAG_ENABLED;
.
  mFlags = NS_PLUGIN_FLAG_ENABLED;
  mXPConnected = PR_FALSE;
.
  mXPConnected = PR_FALSE;
}
.
}
 
.
 
 
.
 
nsPluginTag::nsPluginTag(const char* aName,
.
nsPluginTag::nsPluginTag(const char* aName,
                         const char* aDescription,
.
                         const char* aDescription,
                         const char* aFileName,
.
                         const char* aFileName,
                         const char* const* aMimeTypes,
.
                         const char* const* aMimeTypes,
                         const char* const* aMimeDescriptions,
.
                         const char* const* aMimeDescriptions,
                         const char* const* aExtensions,
.
                         const char* const* aExtensions,
                         PRInt32 aVariants)
.
                         PRInt32 aVariants)
  : mNext(nsnull),
.
  : mNext(nsnull),
    mVariants(aVariants),
.
    mVariants(aVariants),
    mMimeTypeArray(nsnull),
.
    mMimeTypeArray(nsnull),
    mMimeDescriptionArray(nsnull),
.
    mMimeDescriptionArray(nsnull),
    mExtensionsArray(nsnull),
.
    mExtensionsArray(nsnull),
    mLibrary(nsnull),
.
    mLibrary(nsnull),
    mCanUnloadLibrary(PR_TRUE),
.
    mCanUnloadLibrary(PR_TRUE),
    mEntryPoint(nsnull),
.
    mEntryPoint(nsnull),
    mFlags(0),
.
    mFlags(0),
    mXPConnected(PR_FALSE)
.
    mXPConnected(PR_FALSE)
 
.
 
{
.
{
  mName            = new_str(aName);
.
  mName            = new_str(aName);
  mDescription     = new_str(aDescription);
.
  mDescription     = new_str(aDescription);
  mFileName        = new_str(aFileName);
.
  mFileName        = new_str(aFileName);
 
.
 
  if (mVariants) {
.
  if (mVariants) {
    mMimeTypeArray        = new char*[mVariants];
.
    mMimeTypeArray        = new char*[mVariants];
    mMimeDescriptionArray = new char*[mVariants];
.
    mMimeDescriptionArray = new char*[mVariants];
    mExtensionsArray      = new char*[mVariants];
.
    mExtensionsArray      = new char*[mVariants];
 
.
 
    for (PRInt32 i = 0; i < aVariants; ++i) {
.
    for (PRInt32 i = 0; i < aVariants; ++i) {
      mMimeTypeArray[i]        = new_str(aMimeTypes[i]);
.
      mMimeTypeArray[i]        = new_str(aMimeTypes[i]);
      mMimeDescriptionArray[i] = new_str(aMimeDescriptions[i]);
.
      mMimeDescriptionArray[i] = new_str(aMimeDescriptions[i]);
      mExtensionsArray[i]      = new_str(aExtensions[i]);
.
      mExtensionsArray[i]      = new_str(aExtensions[i]);
    }
.
    }
  }
.
  }
}
.
}
 
.
 
nsPluginTag::~nsPluginTag()
.
nsPluginTag::~nsPluginTag()
{
.
{
  TryUnloadPlugin(PR_TRUE);
.
  TryUnloadPlugin(PR_TRUE);
 
.
 
  if (nsnull != mName) {
.
  if (nsnull != mName) {
    delete[] (mName);
.
    delete[] (mName);
    mName = nsnull;
.
    mName = nsnull;
  }
.
  }
 
.
 
  if (nsnull != mDescription) {
.
  if (nsnull != mDescription) {
    delete[] (mDescription);
.
    delete[] (mDescription);
    mDescription = nsnull;
.
    mDescription = nsnull;
  }
.
  }
 
.
 
  if (nsnull != mMimeTypeArray) {
.
  if (nsnull != mMimeTypeArray) {
		for (int i = 0; i < mVariants; i++)
.
		for (int i = 0; i < mVariants; i++)
			delete[] mMimeTypeArray[i];
.
			delete[] mMimeTypeArray[i];
 
.
 
    delete[] (mMimeTypeArray);
.
    delete[] (mMimeTypeArray);
    mMimeTypeArray = nsnull;
.
    mMimeTypeArray = nsnull;
  }
.
  }
 
.
 
  if (nsnull != mMimeDescriptionArray) {
.
  if (nsnull != mMimeDescriptionArray) {
		for (int i = 0; i < mVariants; i++)
.
		for (int i = 0; i < mVariants; i++)
			delete[] mMimeDescriptionArray[i];
.
			delete[] mMimeDescriptionArray[i];
 
.
 
    delete[] (mMimeDescriptionArray);
.
    delete[] (mMimeDescriptionArray);
    mMimeDescriptionArray = nsnull;
.
    mMimeDescriptionArray = nsnull;
  }
.
  }
 
.
 
  if (nsnull != mExtensionsArray) {
.
  if (nsnull != mExtensionsArray) {
		for (int i = 0; i < mVariants; i++)
.
		for (int i = 0; i < mVariants; i++)
			delete[] mExtensionsArray[i];
.
			delete[] mExtensionsArray[i];
 
.
 
    delete[] (mExtensionsArray);
.
    delete[] (mExtensionsArray);
    mExtensionsArray = nsnull;
.
    mExtensionsArray = nsnull;
  }
.
  }
 
.
 
  if(nsnull != mFileName)
.
  if(nsnull != mFileName)
  {
.
  {
    delete [] mFileName;
.
    delete [] mFileName;
    mFileName = nsnull;
.
    mFileName = nsnull;
  }
.
  }
}
.
}
 
.
 
void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown)
.
void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown)
{
.
{
  PRBool isXPCOM = PR_FALSE;
.
  PRBool isXPCOM = PR_FALSE;
  if (!(mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
.
  if (!(mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
    isXPCOM = PR_TRUE;
.
    isXPCOM = PR_TRUE;
 
.
 
  if (isXPCOM && !aForceShutdown) return;
.
  if (isXPCOM && !aForceShutdown) return;
 
.
 
  if (mEntryPoint)
.
  if (mEntryPoint)
  {
.
  {
    mEntryPoint->Shutdown();
.
    mEntryPoint->Shutdown();
    mEntryPoint->Release();
.
    mEntryPoint->Release();
    mEntryPoint = nsnull;
.
    mEntryPoint = nsnull;
  }
.
  }
 
.
 
  // before we unload check if we are allowed to, see bug #61388
.
  // before we unload check if we are allowed to, see bug #61388
  if (mLibrary && mCanUnloadLibrary)
.
  if (mLibrary && mCanUnloadLibrary)
    PR_UnloadLibrary(mLibrary);
.
    PR_UnloadLibrary(mLibrary);
 
.
 
  // we should zero it anyway, it is going to be unloaded by 
.
  // we should zero it anyway, it is going to be unloaded by 
  // CleanUnsedLibraries before we need to call the library 
.
  // CleanUnsedLibraries before we need to call the library 
  // again so the calling code should not be fooled and reload 
.
  // again so the calling code should not be fooled and reload 
  // the library fresh
.
  // the library fresh
  mLibrary = nsnull;
.
  mLibrary = nsnull;
}
.
}
 
.
 
 
.
class nsPluginStreamListenerPeer;
 
.
 
class nsPluginStreamInfo : public nsIPluginStreamInfo
.
class nsPluginStreamInfo : public nsIPluginStreamInfo
{
.
{
public:
.
public:
 
.
 
	nsPluginStreamInfo();
.
	nsPluginStreamInfo();
	virtual ~nsPluginStreamInfo();
.
	virtual ~nsPluginStreamInfo();
 
.
 
	NS_DECL_ISUPPORTS
.
	NS_DECL_ISUPPORTS
 
.
 
	// nsIPluginStreamInfo interface
.
	// nsIPluginStreamInfo interface
 
.
 
	NS_IMETHOD
.
	NS_IMETHOD
	GetContentType(nsMIMEType* result);
.
	GetContentType(nsMIMEType* result);
 
.
 
	NS_IMETHOD
.
	NS_IMETHOD
	IsSeekable(PRBool* result);
.
	IsSeekable(PRBool* result);
 
.
 
	NS_IMETHOD
.
	NS_IMETHOD
	GetLength(PRUint32* result);
.
	GetLength(PRUint32* result);
 
.
 
	NS_IMETHOD
.
	NS_IMETHOD
	GetLastModified(PRUint32* result);
.
	GetLastModified(PRUint32* result);
 
.
 
	NS_IMETHOD
.
	NS_IMETHOD
	GetURL(const char** result);
.
	GetURL(const char** result);
 
.
 
	NS_IMETHOD
.
	NS_IMETHOD
	RequestRead(nsByteRange* rangeList);
.
	RequestRead(nsByteRange* rangeList);
 
.
 
	// local methods
.
	// local methods
 
.
 
	void
.
	void
	SetContentType(const nsMIMEType contentType);
.
	SetContentType(const nsMIMEType contentType);
 
.
 
	void
.
	void
	SetSeekable(const PRBool seekable);
.
	SetSeekable(const PRBool seekable);
 
.
 
	void
.
	void
	SetLength(const PRUint32 length);
.
	SetLength(const PRUint32 length);
 
.
 
	void
.
	void
	SetLastModified(const PRUint32 modified);
.
	SetLastModified(const PRUint32 modified);
 
.
 
	void
.
	void
	SetURL(const char* url);
.
	SetURL(const char* url);
 
.
 
 
.
    void 
 
.
    SetPluginInstance(nsIPluginInstance * aPluginInstance);
 
.
    
 
.
    void 
 
 
.
    SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * aPluginStreamList
enerPeer);
 
.
 
 
.
    void
 
 
.
    MakeByteRangeString(nsByteRange* aRangeList, char** string, PRInt32 *numRe
quests);
 
.
 
 
.
    void
 
.
    SetLocalCachedFile(const char* path);
 
.
 
 
.
    void
 
.
    GetLocalCachedFile(char** path);
 
.
 
private:
.
private:
 
.
 
	char* mContentType;
.
	char* mContentType;
	char* mURL;
.
	char* mURL;
	PRBool mSeekable;
.
	char* mFilePath;
 
.
    PRBool mSeekable;
	PRUint32 mLength;
.
	PRUint32 mLength;
	PRUint32 mModified;
.
	PRUint32 mModified;
 
.
    nsIPluginInstance * mPluginInstance;
 
.
    nsPluginStreamListenerPeer * mPluginStreamListenerPeer;
 
.
};
 
.
 
 
 
.
//////////////////////////////////////////////////////////////////////////////
/////////////////////
 
.
 
 
.
class nsPluginStreamListenerPeer : public nsIStreamListener,
 
.
                                   public nsIProgressEventSink,
 
.
                                   public nsIHttpHeaderVisitor
 
.
{
 
.
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)
 
.
  nsresult Initialize(nsIURI *aURL, 
 
.
                      nsIPluginInstance *aInstance, 
 
.
                      nsIPluginStreamListener *aListener,
 
.
                      PRInt32 requestCount = 1);
 
.
 
 
.
  nsresult InitializeEmbeded(nsIURI *aURL, 
 
.
                             nsIPluginInstance* aInstance, 
 
.
                             nsIPluginInstanceOwner *aOwner = nsnull,
 
.
                             nsIPluginHost *aHost = nsnull);
 
.
 
 
.
  nsresult InitializeFullPage(nsIPluginInstance *aInstance);
 
.
 
 
.
  nsresult OnFileAvailable(const char* aFilename);
 
.
 
 
.
  nsILoadGroup* GetLoadGroup();
 
.
 
 
.
  nsresult SetLocalFile(const char* aFilename);
 
.
 
 
.
private:
 
.
  nsresult SetUpCache(nsIURI* aURL);
 
.
  nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
 
.
 
 
.
  nsIURI                  *mURL;
 
.
 
 
.
  
 
.
  nsIPluginInstanceOwner  *mOwner;
 
.
  nsIPluginInstance       *mInstance;
 
.
  nsIPluginStreamListener *mPStreamListener;
 
.
  nsPluginStreamInfo	  *mPluginStreamInfo;
 
.
  PRBool		  mSetUpListener;
 
.
 
 
.
  /*
 
.
   * 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.
 
.
   */
 
.
  PRPackedBool		  mStartBinding;
 
.
  PRPackedBool		  mHaveFiredOnStartRequest;
 
.
  // these get passed to the plugin stream listener
 
.
  char                    *mMIMEType;
 
.
  PRUint32                mLength;
 
.
  nsPluginStreamType      mStreamType;
 
.
  nsIPluginHost           *mHost;
 
.
 
 
 
.
  // local file which was used to post data and which should be deleted after 
that
 
.
  char                    *mLocalFile;
 
.
  nsHashtable             *mDataForwardToRequest;
 
.
 
 
.
public:
 
.
  PRBool                  mAbort;
 
.
  PRInt32                 mPendingRequests;
 
.
 
};
.
};
 
.
 
nsPluginStreamInfo::nsPluginStreamInfo()
.
nsPluginStreamInfo::nsPluginStreamInfo()
{
.
{
	NS_INIT_REFCNT();
.
	NS_INIT_REFCNT();
 
.
 
 
.
    mPluginInstance = nsnull;
 
.
    mPluginStreamListenerPeer = nsnull;
 
.
 
	mContentType = nsnull;
.
	mContentType = nsnull;
	mURL = nsnull;
.
	mURL = nsnull;
	mSeekable = PR_FALSE;
.
	mFilePath = nsnull;
 
.
    mSeekable = PR_FALSE;
	mLength = 0;
.
	mLength = 0;
	mModified = 0;
.
	mModified = 0;
}
.
}
 
.
 
nsPluginStreamInfo::~nsPluginStreamInfo()
.
nsPluginStreamInfo::~nsPluginStreamInfo()
{
.
{
	if(mContentType != nsnull)
.
	if(mContentType != nsnull)
		PL_strfree(mContentType);
.
		PL_strfree(mContentType);
    if(mURL != nsnull)
.
    if(mURL != nsnull)
		PL_strfree(mURL);
.
		PL_strfree(mURL);
 
.
    if(mFilePath != nsnull)
 
.
		PL_strfree(mFilePath);
 
.
 
 
.
    NS_IF_RELEASE(mPluginInstance);
 
.
    NS_IF_RELEASE(mPluginStreamListenerPeer);
}
.
}
 
.
 
NS_IMPL_ADDREF(nsPluginStreamInfo)
.
NS_IMPL_ADDREF(nsPluginStreamInfo)
NS_IMPL_RELEASE(nsPluginStreamInfo)
.
NS_IMPL_RELEASE(nsPluginStreamInfo)
 
.
 
nsresult nsPluginStreamInfo::QueryInterface(const nsIID& aIID,
.
nsresult nsPluginStreamInfo::QueryInterface(const nsIID& aIID,
                                            void** aInstancePtrResult)
.
                                            void** aInstancePtrResult)
{
.
{
  NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
.
  NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
 
.
 
  if (nsnull == aInstancePtrResult)
.
  if (nsnull == aInstancePtrResult)
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
 
.
 
  if (aIID.Equals(kIPluginStreamInfoIID))
.
  if (aIID.Equals(kIPluginStreamInfoIID))
  {
.
  {
    *aInstancePtrResult = (void *)((nsIPluginStreamInfo *)this);
.
    *aInstancePtrResult = (void *)((nsIPluginStreamInfo *)this);
    AddRef();
.
    AddRef();
    return NS_OK;
.
    return NS_OK;
  }
.
  }
 
.
 
  if (aIID.Equals(kISupportsIID))
.
  if (aIID.Equals(kISupportsIID))
  {
.
  {
    *aInstancePtrResult = (void *)((nsISupports *)((nsIStreamListener *)this))
;
.
    *aInstancePtrResult = (void *)((nsISupports *)((nsIStreamListener *)this))
;
    AddRef();
.
    AddRef();
    return NS_OK;
.
    return NS_OK;
  }
.
  }
 
.
 
  return NS_NOINTERFACE;
.
  return NS_NOINTERFACE;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamInfo::GetContentType(nsMIMEType* result)
.
nsPluginStreamInfo::GetContentType(nsMIMEType* result)
{
.
{
	*result = mContentType;
.
	*result = mContentType;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamInfo::IsSeekable(PRBool* result)
.
nsPluginStreamInfo::IsSeekable(PRBool* result)
{
.
{
	*result = mSeekable;
.
	*result = mSeekable;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamInfo::GetLength(PRUint32* result)
.
nsPluginStreamInfo::GetLength(PRUint32* result)
{
.
{
	*result = mLength;
.
	*result = mLength;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamInfo::GetLastModified(PRUint32* result)
.
nsPluginStreamInfo::GetLastModified(PRUint32* result)
{
.
{
	*result = mModified;
.
	*result = mModified;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamInfo::GetURL(const char** result)
.
nsPluginStreamInfo::GetURL(const char** result)
{
.
{
	*result = mURL;
.
	*result = mURL;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
 
.
 
 
.
void
 
 
.
nsPluginStreamInfo::MakeByteRangeString(nsByteRange* aRangeList, char** rangeR
equest, PRInt32 *numRequests)
 
.
{
 
.
  *rangeRequest = nsnull;
 
.
  *numRequests  = 0;
 
.
  //the string should look like this: bytes=500-700,601-999
 
.
  if(!aRangeList)
 
.
    return;
 
.
 
 
.
  PRInt32 requestCnt = 0;
 
.
  // XXX needs to be smarter than that
 
.
  char * string = new char[1024];
 
.
 
 
.
  string[0] = '\0';
 
.
  PL_strcat(string, "bytes=");
 
.
 
 
.
  for(nsByteRange * range = aRangeList; range != nsnull; range = range->next)
 
.
  {
 
.
    char firstbyte[80];
 
.
    char lastbyte[80];
 
.
 
 
.
    // XXX zero length?
 
.
    if(!range->length)
 
.
      continue;
 
.
 
 
.
    // XXX needs to be fixed for negative offsets
 
.
    // XXX is itoa good enough?
 
.
    itoa(range->offset, firstbyte, 10);
 
 
.
    itoa(range->offset + range->length - 1/*XXX is this correct? */, lastbyte,
 10);
 
.
 
 
.
    PL_strcat(string, firstbyte);
 
.
    PL_strcat(string, "-");
 
.
    PL_strcat(string, lastbyte);
 
.
    if(range->next)
 
.
      PL_strcat(string, ",");
 
.
    
 
.
    requestCnt++;
 
.
  }
 
.
 
 
.
  // get rid of possible tailing comma
 
.
  PRInt32 len = PL_strlen(string);
 
.
  if(string[len - 1] == ',')
 
.
    string[len - 1] = '\0';
 
.
 
 
.
  *rangeRequest = string;
 
.
  *numRequests  = requestCnt;
 
.
  
 
.
  return;
 
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamInfo::RequestRead(nsByteRange* rangeList)
.
nsPluginStreamInfo::RequestRead(nsByteRange* rangeList)
{
.
{
	return NS_ERROR_NOT_IMPLEMENTED;
.
  mPluginStreamListenerPeer->mAbort = PR_TRUE;
 
.
 
 
.
  nsresult rv = NS_OK;
 
.
  nsCOMPtr<nsIURI> url;
 
.
 
 
.
  rv = NS_NewURI(getter_AddRefs(url), mURL);
 
.
 
 
.
  nsCOMPtr<nsIChannel> channel;
 
.
  rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull, nsnull);
 
.
  if (NS_FAILED(rv)) 
 
.
    return rv;
 
.
 
 
.
  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
 
.
  if(!httpChannel)
 
.
    return NS_ERROR_FAILURE;
 
.
 
 
.
  char *rangeString;
 
.
  PRInt32 numRequests;
 
.
 
 
.
  MakeByteRangeString(rangeList, &rangeString, &numRequests);
 
.
  
 
.
  if(!rangeString)
 
.
    return NS_ERROR_FAILURE;
 
.
 
 
.
  httpChannel->SetRequestHeader("Range", rangeString);
 
.
 
 
.
  delete [] rangeString;
 
.
 
 
.
  // instruct old stream listener to cancel the request on the next
 
.
  // attempt to write. 
 
.
 
 
.
  nsCOMPtr<nsIStreamListener> converter = mPluginStreamListenerPeer;
 
.
 
 
.
  if (numRequests > 1) {
 
 
.
    nsCOMPtr<nsIStreamConverterService> serv = do_GetService(kStreamConverterS
erviceCID, &rv);
 
.
    if (NS_FAILED(rv))
 
.
        return rv;
 
.
  
 
 
.
    rv = serv->AsyncConvertData(NS_LITERAL_STRING("multipart/byteranges").get(
),
 
.
                                NS_LITERAL_STRING("*/*").get(),
 
.
                                mPluginStreamListenerPeer,
 
.
                                nsnull,
 
.
                                getter_AddRefs(converter));
 
.
    if (NS_FAILED(rv))
 
.
        return rv;
 
.
  }
 
.
 
 
.
  mPluginStreamListenerPeer->mPendingRequests += numRequests;
 
.
 
 
 
.
   nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRU
INT32_CONTRACTID, &rv);
 
.
   if (NS_FAILED(rv)) return rv;
 
.
   rv = container->SetData(MAGIC_REQUEST_CONTEXT);
 
.
   if (NS_FAILED(rv)) return rv;
 
.
 
 
.
   return channel->AsyncOpen(converter, container);
}
.
}
 
.
 
// local methods
.
// local methods
 
.
 
void
.
void
nsPluginStreamInfo::SetContentType(const nsMIMEType contentType)
.
nsPluginStreamInfo::SetContentType(const nsMIMEType contentType)
{	
.
{	
	if(mContentType != nsnull)
.
	if(mContentType != nsnull)
		PL_strfree(mContentType);
.
		PL_strfree(mContentType);
 
.
 
	mContentType = PL_strdup(contentType);
.
	mContentType = PL_strdup(contentType);
}
.
}
 
.
 
void
.
void
nsPluginStreamInfo::SetSeekable(const PRBool seekable)
.
nsPluginStreamInfo::SetSeekable(const PRBool seekable)
{
.
{
	mSeekable = seekable;
.
	mSeekable = seekable;
}
.
}
 
.
 
void
.
void
nsPluginStreamInfo::SetLength(const PRUint32 length)
.
nsPluginStreamInfo::SetLength(const PRUint32 length)
{
.
{
	mLength = length;
.
	mLength = length;
}
.
}
 
.
 
void
.
void
nsPluginStreamInfo::SetLastModified(const PRUint32 modified)
.
nsPluginStreamInfo::SetLastModified(const PRUint32 modified)
{
.
{
	mModified = modified;
.
	mModified = modified;
}
.
}
 
.
 
void
.
void
nsPluginStreamInfo::SetURL(const char* url)
.
nsPluginStreamInfo::SetURL(const char* url)
{	
.
{	
	if(mURL != nsnull)
.
	if(mURL != nsnull)
		PL_strfree(mURL);
.
		PL_strfree(mURL);
 
.
 
	mURL = PL_strdup(url);
.
	mURL = PL_strdup(url);
}
.
}
 
.
 
//////////////////////////////////////////////////////////////////////////////
/////////////////////
.
 
 
 
.
 
class nsPluginStreamListenerPeer : public nsIStreamListener,
.
 
                                   public nsIProgressEventSink,
.
 
                                   public nsIHttpHeaderVisitor
.
 
{
.
 
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)
.
void
  nsresult Initialize(nsIURI *aURL, 
.
nsPluginStreamInfo::SetLocalCachedFile(const char* path)
                      nsIPluginInstance *aInstance, 
.
{	
                      nsIPluginStreamListener *aListener);
.
	if(mFilePath != nsnull)
 
.
		PL_strfree(mFilePath);
  nsresult InitializeEmbeded(nsIURI *aURL, 
.
 
                             nsIPluginInstance* aInstance, 
.
 
                             nsIPluginInstanceOwner *aOwner = nsnull,
.
 
                             nsIPluginHost *aHost = nsnull);
.
 
 
.
 
  nsresult InitializeFullPage(nsIPluginInstance *aInstance);
.
 
 
.
 
  nsresult OnFileAvailable(const char* aFilename);
.
 
 
.
 
  nsILoadGroup* GetLoadGroup();
.
 
 
.
 
  nsresult SetLocalFile(const char* aFilename);
.
 
 
.
 
private:
.
 
  nsresult SetUpCache(nsIURI* aURL);
.
 
  nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL);
.
 
 
.
 
  nsIURI                  *mURL;
.
	mFilePath = PL_strdup(path);
  nsIPluginInstanceOwner  *mOwner;
.
}
  nsIPluginInstance       *mInstance;
.
 
  nsIPluginStreamListener *mPStreamListener;
.
 
  nsPluginStreamInfo	  *mPluginStreamInfo;
.
 
  PRBool		  mSetUpListener;
.
 
 
.
 
  /*
.
void
   * Set to PR_TRUE after nsIPluginInstancePeer::OnStartBinding() has
.
nsPluginStreamInfo::GetLocalCachedFile(char** path)
   * been called.  Checked in ::OnStopRequest so we can call the
.
{	
   * plugin's OnStartBinding if, for some reason, it has not already
.
	*path = PL_strdup(mFilePath);
   * been called.
.
}
   */
.
 
  PRBool		  mStartBinding;
.
 
 
.
 
  // these get passed to the plugin stream listener
.
void
  char                    *mMIMEType;
.
nsPluginStreamInfo::SetPluginInstance(nsIPluginInstance * aPluginInstance)
  PRUint32                mLength;
.
{
  nsPluginStreamType      mStreamType;
.
    NS_IF_ADDREF(mPluginInstance = aPluginInstance);
  nsIPluginHost           *mHost;
.
}
 
.
 
  // local file which was used to post data and which should be deleted after 
that
.
void 
 
  char                    *mLocalFile;
 
.
nsPluginStreamInfo::SetPluginStreamListenerPeer(nsPluginStreamListenerPeer * a
PluginStreamListenerPeer)
};
.
{
 
.
    NS_IF_ADDREF(mPluginStreamListenerPeer = aPluginStreamListenerPeer);
 
.
}
 
.
 
//////////////////////////////////////////////////////////////////////////////
/////////////////////
.
//////////////////////////////////////////////////////////////////////////////
/////////////////////
 
.
 
class nsPluginCacheListener : public nsIStreamListener
.
class nsPluginCacheListener : public nsIStreamListener
{
.
{
public:
.
public:
  nsPluginCacheListener(nsPluginStreamListenerPeer* aListener);
.
  nsPluginCacheListener(nsPluginStreamListenerPeer* aListener);
  virtual ~nsPluginCacheListener();
.
  virtual ~nsPluginCacheListener();
 
.
 
  NS_DECL_ISUPPORTS
.
  NS_DECL_ISUPPORTS
 
.
 
  NS_DECL_NSIREQUESTOBSERVER
.
  NS_DECL_NSIREQUESTOBSERVER
  NS_DECL_NSISTREAMLISTENER
.
  NS_DECL_NSISTREAMLISTENER
 
.
 
private:
.
private:
  nsPluginStreamListenerPeer* mListener;
.
  nsPluginStreamListenerPeer* mListener;
};
.
};
 
.
 
nsPluginCacheListener::nsPluginCacheListener(nsPluginStreamListenerPeer* aList
ener)
.
nsPluginCacheListener::nsPluginCacheListener(nsPluginStreamListenerPeer* aList
ener)
{
.
{
  NS_INIT_REFCNT();
.
  NS_INIT_REFCNT();
 
.
 
  mListener = aListener;
.
  mListener = aListener;
  NS_ADDREF(mListener);
.
  NS_ADDREF(mListener);
}
.
}
 
.
 
nsPluginCacheListener::~nsPluginCacheListener()
.
nsPluginCacheListener::~nsPluginCacheListener()
{
.
{
  NS_IF_RELEASE(mListener);
.
  NS_IF_RELEASE(mListener);
}
.
}
 
.
 
NS_IMPL_ISUPPORTS(nsPluginCacheListener, kIStreamListenerIID);
.
NS_IMPL_ISUPPORTS(nsPluginCacheListener, kIStreamListenerIID);
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginCacheListener::OnStartRequest(nsIRequest *request, nsISupports* ctxt)
.
nsPluginCacheListener::OnStartRequest(nsIRequest *request, nsISupports* ctxt)
{
.
{
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP 
.
NS_IMETHODIMP 
nsPluginCacheListener::OnDataAvailable(nsIRequest *request, nsISupports* ctxt,
 
.
nsPluginCacheListener::OnDataAvailable(nsIRequest *request, nsISupports* ctxt,
 
                                       nsIInputStream* aIStream, 
.
                                       nsIInputStream* aIStream, 
                                       PRUint32 sourceOffset, 
.
                                       PRUint32 sourceOffset, 
                                       PRUint32 aLength)
.
                                       PRUint32 aLength)
{
.
{
 
.
 
  PRUint32 readlen;
.
  PRUint32 readlen;
  char* buffer = (char*) PR_Malloc(aLength);
.
  char* buffer = (char*) PR_Malloc(aLength);
 
.
 
  // if we don't read from the stream, OnStopRequest will never be called
.
  // if we don't read from the stream, OnStopRequest will never be called
  if(!buffer)
.
  if(!buffer)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  nsresult rv = aIStream->Read(buffer, aLength, &readlen);
.
  nsresult rv = aIStream->Read(buffer, aLength, &readlen);
 
.
 
  NS_ASSERTION(aLength == readlen, "nsCacheListener->OnDataAvailable: "
.
  NS_ASSERTION(aLength == readlen, "nsCacheListener->OnDataAvailable: "
               "readlen != aLength");
.
               "readlen != aLength");
 
.
 
  PR_Free(buffer);
.
  PR_Free(buffer);
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP 
.
NS_IMETHODIMP 
nsPluginCacheListener::OnStopRequest(nsIRequest *request, 
.
nsPluginCacheListener::OnStopRequest(nsIRequest *request, 
                                     nsISupports* aContext, 
.
                                     nsISupports* aContext, 
                                     nsresult aStatus)
.
                                     nsresult aStatus)
{
.
{
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
//////////////////////////////////////////////////////////////////////////////
/////////////////////////
.
//////////////////////////////////////////////////////////////////////////////
/////////////////////////
 
.
 
nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
.
nsPluginStreamListenerPeer::nsPluginStreamListenerPeer()
{
.
{
  NS_INIT_REFCNT();
.
  NS_INIT_REFCNT();
 
.
 
  mURL = nsnull;
.
  mURL = nsnull;
  mOwner = nsnull;
.
  mOwner = nsnull;
  mInstance = nsnull;
.
  mInstance = nsnull;
  mPStreamListener = nsnull;
.
  mPStreamListener = nsnull;
  mPluginStreamInfo = nsnull;
.
  mPluginStreamInfo = nsnull;
  mSetUpListener = PR_FALSE;
.
  mSetUpListener = PR_FALSE;
  mHost = nsnull;
.
  mHost = nsnull;
  mStreamType = nsPluginStreamType_Normal;
.
  mStreamType = nsPluginStreamType_Normal;
  mStartBinding = PR_FALSE;
.
  mStartBinding = PR_FALSE;
  mLocalFile = nsnull;
.
  mLocalFile = nsnull;
 
.
  mAbort = PR_FALSE;
 
.
 
 
.
  mPendingRequests = 0;
 
.
  mHaveFiredOnStartRequest = PR_FALSE;
}
.
}
 
.
 
nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
.
nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  if(mURL != nsnull)
.
  if(mURL != nsnull)
  {
.
  {
    char* spec;
.
    char* spec;
	(void)mURL->GetSpec(&spec);
.
	(void)mURL->GetSpec(&spec);
	printf("killing stream for %s\n", mURL ? spec : "(unknown URL)");
.
	printf("killing stream for %s\n", mURL ? spec : "(unknown URL)");
	nsCRT::free(spec);
.
	nsCRT::free(spec);
  }
.
  }
#endif
.
#endif
 
.
 
  NS_IF_RELEASE(mURL);
.
  NS_IF_RELEASE(mURL);
  NS_IF_RELEASE(mOwner);
.
  NS_IF_RELEASE(mOwner);
  NS_IF_RELEASE(mInstance);
.
  NS_IF_RELEASE(mInstance);
  NS_IF_RELEASE(mPStreamListener);
.
  NS_IF_RELEASE(mPStreamListener);
  NS_IF_RELEASE(mHost);
.
  NS_IF_RELEASE(mHost);
 
.
 
  // if we have mLocalFile (temp file used to post data) it should be
.
  // if we have mLocalFile (temp file used to post data) it should be
  // safe to delete it now, and hopefully the owner doesn't hold it.
.
  // safe to delete it now, and hopefully the owner doesn't hold it.
  if(mLocalFile)
.
  if(mLocalFile)
  {
.
  {
    nsCOMPtr<nsILocalFile> localFile;
.
    nsCOMPtr<nsILocalFile> localFile;
    nsresult res = NS_NewLocalFile(mLocalFile, PR_FALSE, getter_AddRefs(localF
ile));
.
    nsresult res = NS_NewLocalFile(mLocalFile, PR_FALSE, getter_AddRefs(localF
ile));
    if(NS_SUCCEEDED(res))
.
    if(NS_SUCCEEDED(res))
      localFile->Delete(PR_FALSE);
.
      localFile->Delete(PR_FALSE);
    delete [] mLocalFile;
.
    delete [] mLocalFile;
  }
.
  }
}
.
}
 
.
 
NS_IMPL_ADDREF(nsPluginStreamListenerPeer);
.
NS_IMPL_ISUPPORTS3(nsPluginStreamListenerPeer,
NS_IMPL_RELEASE(nsPluginStreamListenerPeer);
.
                   nsIStreamListener,
 
.
                   nsIRequestObserver,
nsresult nsPluginStreamListenerPeer::QueryInterface(const nsIID& aIID,
.
                   nsIHttpHeaderVisitor)
                                                    void** aInstancePtrResult)
.
 
 
{
.
 
  NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
.
 
 
.
 
  if (nsnull == aInstancePtrResult)
.
 
    return NS_ERROR_NULL_POINTER;
.
 
 
.
 
  if (aIID.Equals(kIStreamListenerIID))
.
 
  {
.
 
    *aInstancePtrResult = (void *)((nsIStreamListener *)this);
.
 
    AddRef();
.
 
    return NS_OK;
.
 
  }
.
 
 
.
 
  if (aIID.Equals(kIRequestObserverIID))
.
 
  {
.
 
    *aInstancePtrResult = (void *)((nsIRequestObserver *)this);
.
 
    AddRef();
.
 
    return NS_OK;
.
 
  }
.
 
 
.
 
  if (aIID.Equals(kIHttpHeaderVisitorIID))
.
 
  {
.
 
    *aInstancePtrResult = (void *)((nsIHttpHeaderVisitor *)this);
.
 
    AddRef();
.
 
    return NS_OK;
.
 
  }
.
 
 
.
 
  if (aIID.Equals(kISupportsIID))
.
 
  {
.
 
    *aInstancePtrResult = (void *)((nsISupports *)((nsIStreamListener *)this))
;
.
 
 
    AddRef();
.
 
    return NS_OK;
.
 
  }
.
 
 
.
 
  return NS_NOINTERFACE;
.
 
}
.
 
 
.
 
/* Called as a result of GetURL and PostURL */
.
/* Called as a result of GetURL and PostURL */
 
.
 
nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL, 
.
nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL, 
                                                nsIPluginInstance *aInstance,
.
                                                nsIPluginInstance *aInstance,
                                                nsIPluginStreamListener* aList
ener)
.
                                                nsIPluginStreamListener* aList
ener,
 
.
                                                PRInt32 requestCount)
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  char* spec;
.
  char* spec;
  (void)aURL->GetSpec(&spec);
.
  (void)aURL->GetSpec(&spec);
  printf("created stream for %s\n", spec);
.
  printf("created stream for %s\n", spec);
  nsCRT::free(spec);
.
  nsCRT::free(spec);
#endif
.
#endif
 
.
 
  mURL = aURL;
.
  mURL = aURL;
  NS_ADDREF(mURL);
.
  NS_ADDREF(mURL);
 
.
 
  mInstance = aInstance;
.
  mInstance = aInstance;
  NS_ADDREF(mInstance);
.
  NS_ADDREF(mInstance);
  
.
  
  mPStreamListener = aListener;
.
  mPStreamListener = aListener;
  NS_ADDREF(mPStreamListener);
.
  NS_ADDREF(mPStreamListener);
 
.
 
  mPluginStreamInfo = new nsPluginStreamInfo();
.
  mPluginStreamInfo = new nsPluginStreamInfo();
 
.
 
 
.
  mPluginStreamInfo->SetPluginInstance(aInstance);
 
.
  mPluginStreamInfo->SetPluginStreamListenerPeer(this);
 
.
 
 
.
  mPendingRequests = requestCount;
 
.
 
 
.
  mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
 
.
  if (!mDataForwardToRequest) 
 
.
      return NS_ERROR_FAILURE;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* 
.
/* 
	Called by NewEmbededPluginStream() - if this is called, we weren't 
.
	Called by NewEmbededPluginStream() - if this is called, we weren't 
    able to load the plugin, so we need to load it later once we figure 
.
    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 
.
    out the mimetype.  In order to load it later, we need the plugin 
    host and instance owner.
.
    host and instance owner.
*/
.
*/
 
.
 
nsresult nsPluginStreamListenerPeer::InitializeEmbeded(nsIURI *aURL, 
.
nsresult nsPluginStreamListenerPeer::InitializeEmbeded(nsIURI *aURL, 
                                                       nsIPluginInstance* aIns
tance, 
.
                                                       nsIPluginInstance* aIns
tance, 
                                                       nsIPluginInstanceOwner 
*aOwner,
.
                                                       nsIPluginInstanceOwner 
*aOwner,
                                                       nsIPluginHost *aHost)
.
                                                       nsIPluginHost *aHost)
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  char* spec;
.
  char* spec;
  (void)aURL->GetSpec(&spec);
.
  (void)aURL->GetSpec(&spec);
  printf("created stream for %s\n", spec);
.
  printf("created stream for %s\n", spec);
  nsCRT::free(spec);
.
  nsCRT::free(spec);
#endif
.
#endif
 
.
 
  mURL = aURL;
.
  mURL = aURL;
  NS_ADDREF(mURL);
.
  NS_ADDREF(mURL);
 
.
 
  if(aInstance != nsnull)
.
  if(aInstance != nsnull)
  {
.
  {
    NS_ASSERTION(mInstance == nsnull, "nsPluginStreamListenerPeer::InitializeE
mbeded mInstance != nsnull");
.
    NS_ASSERTION(mInstance == nsnull, "nsPluginStreamListenerPeer::InitializeE
mbeded mInstance != nsnull");
	  mInstance = aInstance;
.
	  mInstance = aInstance;
	  NS_ADDREF(mInstance);
.
	  NS_ADDREF(mInstance);
  }
.
  }
  else
.
  else
  {
.
  {
	  mOwner = aOwner;
.
	  mOwner = aOwner;
	  NS_IF_ADDREF(mOwner);
.
	  NS_IF_ADDREF(mOwner);
 
.
 
	  mHost = aHost;
.
	  mHost = aHost;
	  NS_IF_ADDREF(mHost);
.
	  NS_IF_ADDREF(mHost);
  }
.
  }
 
.
 
  mPluginStreamInfo = new nsPluginStreamInfo();
.
  mPluginStreamInfo = new nsPluginStreamInfo();
 
.
 
 
.
  mPluginStreamInfo->SetPluginInstance(aInstance);
 
.
  mPluginStreamInfo->SetPluginStreamListenerPeer(this);
 
.
 
 
.
  mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
 
.
  if (!mDataForwardToRequest) 
 
.
      return NS_ERROR_FAILURE;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* Called by NewFullPagePluginStream() */
.
/* Called by NewFullPagePluginStream() */
 
.
 
nsresult nsPluginStreamListenerPeer::InitializeFullPage(nsIPluginInstance *aIn
stance)
.
nsresult nsPluginStreamListenerPeer::InitializeFullPage(nsIPluginInstance *aIn
stance)
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("created stream for (unknown URL)\n");
.
  printf("created stream for (unknown URL)\n");
  printf("Inside nsPluginStreamListenerPeer::InitializeFullPage...\n");
.
  printf("Inside nsPluginStreamListenerPeer::InitializeFullPage...\n");
#endif
.
#endif
 
.
 
  NS_ASSERTION(mInstance == nsnull, "nsPluginStreamListenerPeer::InitializeFul
lPage mInstance != nsnull");
.
  NS_ASSERTION(mInstance == nsnull, "nsPluginStreamListenerPeer::InitializeFul
lPage mInstance != nsnull");
  mInstance = aInstance;
.
  mInstance = aInstance;
  NS_ADDREF(mInstance);
.
  NS_ADDREF(mInstance);
 
.
 
  mPluginStreamInfo = new nsPluginStreamInfo();
.
  mPluginStreamInfo = new nsPluginStreamInfo();
 
.
 
 
.
  mPluginStreamInfo->SetPluginInstance(aInstance);
 
.
  mPluginStreamInfo->SetPluginStreamListenerPeer(this);
 
.
 
 
.
  mDataForwardToRequest = new nsHashtable(16, PR_FALSE);
 
.
  if (!mDataForwardToRequest) 
 
.
      return NS_ERROR_FAILURE;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, nsISupports* a
Context)
.
nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, nsISupports* a
Context)
{
.
{
  nsresult  rv = NS_OK;
.
  nsresult  rv = NS_OK;
 
.
 
 
.
  if (mHaveFiredOnStartRequest) {
 
.
      return NS_OK;
 
.
  }
 
.
 
 
.
  mHaveFiredOnStartRequest = PR_TRUE;
 
.
 
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
.
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
 
.
 
  if (!channel)
.
  if (!channel)
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
 
.
 
    nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(channel);
.
    nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(channel);
    if (cacheChannel) {
.
    if (cacheChannel) {
        rv = cacheChannel->SetCacheAsFile(PR_TRUE);
.
        rv = cacheChannel->SetCacheAsFile(PR_TRUE);
        if (NS_FAILED(rv)) {
.
        if (NS_FAILED(rv)) {
           // FIX: Cache must be disabled.  We should try to stream this file
.
           // FIX: Cache must be disabled.  We should try to stream this file
           // to disk ourselves otherwise OnFileAvailable will never be fired.
.
           // to disk ourselves otherwise OnFileAvailable will never be fired.
           NS_ASSERTION(PR_FALSE, "No Disk Cache Aval.  Some plugins wont work
.");
.
           NS_ASSERTION(PR_FALSE, "No Disk Cache Aval.  Some plugins wont work
.");
        }
.
        }
    }
.
    }
 
.
 
  char* aContentType = nsnull;
.
  char* aContentType = nsnull;
  rv = channel->GetContentType(&aContentType);
.
  rv = channel->GetContentType(&aContentType);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
  nsCOMPtr<nsIURI> aURL;
.
  nsCOMPtr<nsIURI> aURL;
  rv = channel->GetURI(getter_AddRefs(aURL));
.
  rv = channel->GetURI(getter_AddRefs(aURL));
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  if (nsnull != aContentType)
.
  if (nsnull != aContentType)
	  mPluginStreamInfo->SetContentType(aContentType);
.
	  mPluginStreamInfo->SetContentType(aContentType);
 
.
 
  nsPluginWindow    *window = nsnull;
.
  nsPluginWindow    *window = nsnull;
 
.
 
  // if we don't have an nsIPluginInstance (mInstance), it means
.
  // if we don't have an nsIPluginInstance (mInstance), it means
  // we weren't able to load a plugin previously because we
.
  // we weren't able to load a plugin previously because we
  // didn't have the mimetype.  Now that we do (aContentType),
.
  // didn't have the mimetype.  Now that we do (aContentType),
  // we'll try again with SetUpPluginInstance() 
.
  // we'll try again with SetUpPluginInstance() 
  // which is called by InstantiateEmbededPlugin()
.
  // which is called by InstantiateEmbededPlugin()
  // NOTE: we don't want to try again if we didn't get the MIME type this time
.
  // NOTE: we don't want to try again if we didn't get the MIME type this time
 
.
 
  if ((nsnull == mInstance) && (nsnull != mOwner) && (nsnull != aContentType))
.
  if ((nsnull == mInstance) && (nsnull != mOwner) && (nsnull != aContentType))
  {
.
  {
    mOwner->GetInstance(mInstance);
.
    mOwner->GetInstance(mInstance);
    mOwner->GetWindow(window);
.
    mOwner->GetWindow(window);
 
.
 
    if ((nsnull == mInstance) && (nsnull != mHost) && (nsnull != window))
.
    if ((nsnull == mInstance) && (nsnull != mHost) && (nsnull != window))
    {
.
    {
      // determine if we need to try embedded again. FullPage takes a differen
t code path
.
      // determine if we need to try embedded again. FullPage takes a differen
t code path
      nsPluginMode mode;
.
      nsPluginMode mode;
      mOwner->GetMode(&mode);
.
      mOwner->GetMode(&mode);
      if (mode == nsPluginMode_Embedded)
.
      if (mode == nsPluginMode_Embedded)
        rv = mHost->InstantiateEmbededPlugin(aContentType, aURL, mOwner);
.
        rv = mHost->InstantiateEmbededPlugin(aContentType, aURL, mOwner);
      else
.
      else
        rv = mHost->SetUpPluginInstance(aContentType, aURL, mOwner);
.
        rv = mHost->SetUpPluginInstance(aContentType, aURL, mOwner);
 
.
 
      if (NS_OK == rv)
.
      if (NS_OK == rv)
      {
.
      {
		// GetInstance() adds a ref
.
		// GetInstance() adds a ref
        mOwner->GetInstance(mInstance);
.
        mOwner->GetInstance(mInstance);
 
.
 
        if (nsnull != mInstance)
.
        if (nsnull != mInstance)
        {
.
        {
          mInstance->Start();
.
          mInstance->Start();
          mOwner->CreateWidget();
.
          mOwner->CreateWidget();
 
.
 
          // If we've got a native window, the let the plugin know
.
          // If we've got a native window, the let the plugin know
          // about it.
.
          // about it.
          if (window->window)
.
          if (window->window)
            mInstance->SetWindow(window);
.
            mInstance->SetWindow(window);
        }
.
        }
      }
.
      }
    }
.
    }
  }
.
  }
 
.
 
  nsCRT::free(aContentType);
.
  nsCRT::free(aContentType);
 
.
 
  //
.
  //
  // Set up the stream listener...
.
  // Set up the stream listener...
  //
.
  //
  PRInt32 length;
.
  PRInt32 length;
 
.
 
  rv = channel->GetContentLength(&length);
.
  rv = channel->GetContentLength(&length);
 
.
 
  // it's possible for the server to not send a Content-Length.  We should
.
  // it's possible for the server to not send a Content-Length.  We should
  // still work in this case.
.
  // still work in this case.
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    mPluginStreamInfo->SetLength(-1);
.
    mPluginStreamInfo->SetLength(-1);
  }
.
  }
  else {
.
  else {
    mPluginStreamInfo->SetLength(length);
.
    mPluginStreamInfo->SetLength(length);
  }
.
  }
 
.
 
 
.
 
  rv = SetUpStreamListener(request, aURL);
.
  rv = SetUpStreamListener(request, aURL);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
 
.
 
NS_IMETHODIMP nsPluginStreamListenerPeer::OnProgress(nsIRequest *request, 
.
NS_IMETHODIMP nsPluginStreamListenerPeer::OnProgress(nsIRequest *request, 
                                                     nsISupports* aContext, 
.
                                                     nsISupports* aContext, 
                                                     PRUint32 aProgress, 
.
                                                     PRUint32 aProgress, 
                                                     PRUint32 aProgressMax)
.
                                                     PRUint32 aProgressMax)
{
.
{
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStatus(nsIRequest *request, 
.
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStatus(nsIRequest *request, 
                                                   nsISupports* aContext,
.
                                                   nsISupports* aContext,
                                                   nsresult aStatus,
.
                                                   nsresult aStatus,
                                                   const PRUnichar* aStatusArg
)
.
                                                   const PRUnichar* aStatusArg
)
{
.
{
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
 
.
 
 
.
 
 
.
class nsPRUintKey : public nsHashKey {
 
.
protected:
 
.
    PRUint32 mKey;
 
.
public:
 
.
    nsPRUintKey(PRUint32 key) : mKey(key) {}
 
.
 
 
.
    PRUint32 HashCode(void) const {
 
.
        return mKey;
 
.
    }
 
.
 
 
.
    PRBool Equals(const nsHashKey *aKey) const {
 
.
        return mKey == ((const nsPRUintKey *) aKey)->mKey;
 
.
    }
 
.
    nsHashKey *Clone() const {
 
.
        return new nsPRUintKey(mKey);
 
.
    }
 
.
    PRUint32 GetValue() { return mKey; }
 
.
};
 
.
 
 
.
 
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
 
.
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request,
 
                                                          nsISupports* aContex
t, 
.
                                                          nsISupports* aContex
t, 
                                                          nsIInputStream *aISt
ream, 
.
                                                          nsIInputStream *aISt
ream, 
                                                          PRUint32 sourceOffse
t, 
.
                                                          PRUint32 sourceOffse
t, 
                                                          PRUint32 aLength)
.
                                                          PRUint32 aLength)
{
.
{
 
.
  
 
.
 
 
.
  if(mAbort)
 
.
  {
 
 
.
      PRUint32 magicNumber = 0;  // set it to something that is not the magic 
number.
 
.
      nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
 
.
      if (container)
 
.
        container->GetData(&magicNumber);
 
.
      
 
.
      if (magicNumber != MAGIC_REQUEST_CONTEXT)
 
.
      {
 
.
        // this is not one of our range requests
 
.
        mAbort = PR_FALSE;
 
.
        return NS_BINDING_ABORTED;
 
.
      }
 
.
  }
 
.
 
 
.
 
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
  nsCOMPtr<nsIURI> aURL;
.
  nsCOMPtr<nsIURI> aURL;
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
.
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  if (!channel) 
.
  if (!channel) 
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
  
.
  
  rv = channel->GetURI(getter_AddRefs(aURL));
.
  rv = channel->GetURI(getter_AddRefs(aURL));
  if (NS_FAILED(rv)) 
.
  if (NS_FAILED(rv)) 
    return rv;
.
    return rv;
 
.
 
  if(!mPStreamListener)
.
  if(!mPStreamListener)
	  return NS_ERROR_FAILURE;
.
	  return NS_ERROR_FAILURE;
 
.
 
  char* urlString;
.
  char* urlString;
  aURL->GetSpec(&urlString);
.
  aURL->GetSpec(&urlString);
  mPluginStreamInfo->SetURL(urlString);
.
  mPluginStreamInfo->SetURL(urlString);
  nsCRT::free(urlString);
.
  nsCRT::free(urlString);
 
.
 
  // if the plugin has requested an AsFileOnly stream, then don't 
.
  // if the plugin has requested an AsFileOnly stream, then don't 
  // call OnDataAvailable
.
  // call OnDataAvailable
  if(mStreamType != nsPluginStreamType_AsFileOnly)
.
  if(mStreamType != nsPluginStreamType_AsFileOnly)
  {
.
  {
    // It's up to the plugin to read from the stream 
.
    // get the absolute offset of the request, if one exists.
    //  If it doesn't, OnStopRequest will never be called
.
    nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
    rv =  mPStreamListener->OnDataAvailable((nsIPluginStreamInfo*)mPluginStrea
mInfo, aIStream, aLength);
.
    PRInt32 absoluteOffset = 0;
 
 
.
    PRInt32 amtForwardToPlugin = 0;
 
.
    if (brr) {
 
.
        brr->GetStartRange(&absoluteOffset);
 
.
        
 
.
        // we need to track how much data we have forward on to the plugin.  
 
.
        nsPRUintKey key(absoluteOffset);
 
.
 
 
.
        if (!mDataForwardToRequest)
 
.
            return NS_ERROR_FAILURE;
 
.
 
 
.
        if (mDataForwardToRequest->Exists(&key))
 
 
.
            amtForwardToPlugin = (PRInt32) mDataForwardToRequest->Remove(&key)
;
 
.
    
 
 
.
        mDataForwardToRequest->Put(&key, (void*) (amtForwardToPlugin+aLength))
;
 
.
    }
 
.
 
 
 
.
    rv =  mPStreamListener->OnDataAvailable((nsIPluginStreamInfo*)mPluginStrea
mInfo, 
 
.
                                            aIStream, 
 
 
.
                                            absoluteOffset+amtForwardToPlugin,
 
 
.
                                            aLength);
 
.
 
    // if a plugin returns an error, the peer must kill the stream
.
    // if a plugin returns an error, the peer must kill the stream
    //   else the stream and PluginStreamListener leak
.
    //   else the stream and PluginStreamListener leak
    if (NS_FAILED(rv))
.
    if (NS_FAILED(rv))
      request->Cancel(rv);
.
      request->Cancel(rv);
  }
.
  }
  else
.
  else
  {
.
  {
    // if we don't read from the stream, OnStopRequest will never be called
.
    // if we don't read from the stream, OnStopRequest will never be called
    char* buffer = new char[aLength];
.
    char* buffer = new char[aLength];
    PRUint32 amountRead;
.
    PRUint32 amountRead;
    rv = aIStream->Read(buffer, aLength, &amountRead);
.
    rv = aIStream->Read(buffer, aLength, &amountRead);
    delete [] buffer;
.
    delete [] buffer;
  }
.
  }
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request, 
.
NS_IMETHODIMP nsPluginStreamListenerPeer::OnStopRequest(nsIRequest *request, 
                                                        nsISupports* aContext,
.
                                                        nsISupports* aContext,
                                                        nsresult aStatus)
.
                                                        nsresult aStatus)
{
.
{
 
.
  
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
  nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(request);
 
.
  nsCOMPtr<nsIFile> localFile;
 
.
  nsXPIDLCString pathAndFilename;
 
.
 
 
 
.
  // doing multiple requests, the main url load (the cacheable entry) could co
me
 
 
.
  // out of order.  Here we will check to see if the request is main url load.
 
.
  
 
.
  if (cacheChannel) {
 
.
    rv = cacheChannel->GetCacheFile(getter_AddRefs(localFile));
 
.
    if (NS_SUCCEEDED(rv)) {
 
.
        localFile->GetPath(getter_Copies(pathAndFilename));
 
.
        mPluginStreamInfo->SetLocalCachedFile(pathAndFilename);
 
.
    }
 
.
  }
 
.
 
 
.
  // remove the request from our data forwarding count hash.
 
.
  nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request);
 
.
  if (brr) {
 
.
    PRInt32 absoluteOffset = 0;
 
.
    brr->GetStartRange(&absoluteOffset);
 
.
    
 
.
    nsPRUintKey key(absoluteOffset);
 
.
 
 
.
    if (!mDataForwardToRequest)
 
.
        return NS_ERROR_FAILURE;
 
.
    
 
.
    (void) mDataForwardToRequest->Remove(&key);
 
.
  }
 
.
 
 
.
 
 
.
  // if we still have pending stuff to do, lets not close the plugin socket.
 
.
  if (--mPendingRequests > 0)
 
.
      return NS_OK;
 
.
  
 
.
  // we keep our connections around...
 
 
.
  PRUint32 magicNumber = 0;  // set it to something that is not the magic numb
er.
 
.
  nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext);
 
.
  if (container)
 
.
    container->GetData(&magicNumber);
 
.
      
 
.
  if (magicNumber == MAGIC_REQUEST_CONTEXT)
 
.
  {
 
.
    // this is one of our range requests
 
.
    return NS_OK;
 
.
  }
 
.
  
 
.
  if(!mPStreamListener)
 
.
      return NS_ERROR_FAILURE;
 
.
 
 
.
  if (!pathAndFilename)
 
.
    mPluginStreamInfo->GetLocalCachedFile(getter_Copies(pathAndFilename));
 
.
 
 
.
  if (!pathAndFilename) {
 
.
    // see if it is a file channel.
 
.
    nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request);
 
.
    if (fileChannel)
 
.
      fileChannel->GetFile(getter_AddRefs(localFile));
 
.
    if (localFile)
 
.
        localFile->GetPath(getter_Copies(pathAndFilename));
 
.
 
 
.
    mPluginStreamInfo->SetLocalCachedFile(pathAndFilename);
 
.
  }
 
.
 
 
.
  if (pathAndFilename)
 
.
    OnFileAvailable(pathAndFilename);
 
.
  
  nsCOMPtr<nsIURI> aURL;
.
  nsCOMPtr<nsIURI> aURL;
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
.
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  if (!channel) 
.
  if (!channel) 
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  rv = channel->GetURI(getter_AddRefs(aURL));
.
  rv = channel->GetURI(getter_AddRefs(aURL));
  if (NS_FAILED(rv)) 
.
  if (NS_FAILED(rv)) 
    return rv;
.
    return rv;
 
.
  
 
.
  nsXPIDLCString urlString;
 
.
  rv = aURL->GetSpec(getter_Copies(urlString));
 
.
  if (NS_SUCCEEDED(rv)) 
 
.
    mPluginStreamInfo->SetURL(urlString);
 
.
  
 
.
  // Set the content type to ensure we don't pass null to the plugin
 
.
  nsXPIDLCString aContentType;
 
.
  rv = channel->GetContentType(getter_Copies(aContentType));
 
.
  if (NS_FAILED(rv)) 
 
.
    return rv;
 
.
 
  if(nsnull != mPStreamListener)
.
  if (aContentType)
  {
.
    mPluginStreamInfo->SetContentType(aContentType);
    char* urlString;
.
 
    nsCOMPtr<nsIFile> localFile;
.
 
 
.
 
    nsCOMPtr<nsICachingChannel> cacheChannel = do_QueryInterface(channel);
.
 
    if (cacheChannel)
.
 
        rv = cacheChannel->GetCacheFile(getter_AddRefs(localFile));
.
 
    if (NS_SUCCEEDED(rv) && localFile)
.
 
    {
.
 
      char* pathAndFilename;
.
 
      rv = localFile->GetPath(&pathAndFilename);
.
 
      if (NS_SUCCEEDED(rv))
.
 
      {
.
 
        OnFileAvailable(pathAndFilename);
.
 
        nsMemory::Free(pathAndFilename);
.
 
      }
.
 
    }
.
 
 
.
 
    rv = aURL->GetSpec(&urlString);
.
 
    if (NS_SUCCEEDED(rv)) 
.
 
    {
.
 
      mPluginStreamInfo->SetURL(urlString);
.
 
      nsCRT::free(urlString);
.
 
    }
.
 
 
.
 
    // Set the content type to ensure we don't pass null to the plugin
.
 
    char* aContentType = nsnull;
.
 
    rv = channel->GetContentType(&aContentType);
.
 
    if (NS_FAILED(rv)) 
.
 
      return rv;
.
 
 
.
 
    if (nsnull != aContentType)
.
 
      mPluginStreamInfo->SetContentType(aContentType);
.
 
 
.
 
    if (mStartBinding)
.
  if (mStartBinding)
    {
.
  {
      // On start binding has been called
.
    // On start binding has been called
      mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo,
 aStatus);
.
    mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, a
Status);
    }
.
  }
    else
.
  else
    {
.
  {
      // OnStartBinding hasn't been called, so complete the action.
.
    // OnStartBinding hasn't been called, so complete the action.
      mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInfo
);
.
    mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInfo);
      mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo,
 aStatus);
.
    mPStreamListener->OnStopBinding((nsIPluginStreamInfo*)mPluginStreamInfo, a
Status);
    }
.
 
 
.
 
    if (aContentType)
.
 
      nsCRT::free(aContentType);
.
 
  }
.
  }
 
.
 
  return rv;
.
  return NS_OK;
}
.
}
 
.
 
// private methods for nsPluginStreamListenerPeer
.
// private methods for nsPluginStreamListenerPeer
 
.
 
nsresult nsPluginStreamListenerPeer::SetUpCache(nsIURI* aURL)
.
nsresult nsPluginStreamListenerPeer::SetUpCache(nsIURI* aURL)
{
.
{
  nsPluginCacheListener* cacheListener = new nsPluginCacheListener(this);
.
  nsPluginCacheListener* cacheListener = new nsPluginCacheListener(this);
  // XXX: Null LoadGroup?
.
  // XXX: Null LoadGroup?
  return NS_OpenURI(cacheListener, nsnull, aURL, nsnull);
.
  return NS_OpenURI(cacheListener, nsnull, aURL, nsnull);
}
.
}
 
.
 
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
.
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request,
                                                         nsIURI* aURL)
.
                                                         nsIURI* aURL)
{
.
{
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  // If we don't yet have a stream listener, we need to get 
.
  // If we don't yet have a stream listener, we need to get 
  // one from the plugin.
.
  // one from the plugin.
  // NOTE: this should only happen when a stream was NOT created 
.
  // NOTE: this should only happen when a stream was NOT created 
  // with GetURL or PostURL (i.e. it's the initial stream we 
.
  // with GetURL or PostURL (i.e. it's the initial stream we 
  // send to the plugin as determined by the SRC or DATA attribute)
.
  // send to the plugin as determined by the SRC or DATA attribute)
  if(mPStreamListener == nsnull && mInstance != nsnull)	  
.
  if(mPStreamListener == nsnull && mInstance != nsnull)	  
	   rv = mInstance->NewStream(&mPStreamListener);
.
	   rv = mInstance->NewStream(&mPStreamListener);
 
.
 
  if(rv != NS_OK)
.
  if(rv != NS_OK)
	   return rv;
.
	   return rv;
 
.
 
  if(mPStreamListener == nsnull)
.
  if(mPStreamListener == nsnull)
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
  
.
  
 
.
 
  // get httpChannel to retrieve some info we need for nsIPluginStreamInfo set
up
.
  // get httpChannel to retrieve some info we need for nsIPluginStreamInfo set
up
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
.
  nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
.
  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
 
.
 
  /*
.
  /*
   * Assumption
.
   * Assumption
   * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
.
   * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets
   * called, all the headers have been read.
.
   * called, all the headers have been read.
   */
.
   */
  if (httpChannel) 
.
  if (httpChannel) 
    httpChannel->VisitResponseHeaders(this);
.
    httpChannel->VisitResponseHeaders(this);
  
.
  
  mSetUpListener = PR_TRUE;
.
  mSetUpListener = PR_TRUE;
  
.
  
  // set seekability
.
  // set seekability
  PRBool bSeekable = PR_FALSE;
.
  PRBool bSeekable = PR_FALSE;
  if (httpChannel)
.
  if (httpChannel)
  {
.
  {
    nsXPIDLCString range;
.
    nsXPIDLCString range;
    if(NS_SUCCEEDED(httpChannel->GetResponseHeader("accept-ranges", getter_Cop
ies(range))))
.
    if(NS_SUCCEEDED(httpChannel->GetResponseHeader("accept-ranges", getter_Cop
ies(range))))
    {
.
    {
      if (0 == PL_strcmp(range.get(), "bytes"))
.
      if (0 == PL_strcmp(range.get(), "bytes"))
        bSeekable = PR_TRUE;
.
        bSeekable = PR_TRUE;
    }
.
    }
  }
.
  }
 
.
 
  mPluginStreamInfo->SetSeekable(bSeekable);
.
  mPluginStreamInfo->SetSeekable(bSeekable);
 
.
 
  // get Last-Modified header for plugin info
.
  // get Last-Modified header for plugin info
  if (httpChannel) 
.
  if (httpChannel) 
  {
.
  {
    char * lastModified = nsnull;
.
    char * lastModified = nsnull;
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader("last-modified", &lastModi
fied)) &&
.
    if (NS_SUCCEEDED(httpChannel->GetResponseHeader("last-modified", &lastModi
fied)) &&
        lastModified)
.
        lastModified)
    {
.
    {
      PRTime time64;
.
      PRTime time64;
      PR_ParseTimeString(lastModified, PR_TRUE, &time64);  //convert string ti
me to interger time
.
      PR_ParseTimeString(lastModified, PR_TRUE, &time64);  //convert string ti
me to interger time
 
.
 
      // Convert PRTime to unix-style time_t, i.e. seconds since the epoch
.
      // Convert PRTime to unix-style time_t, i.e. seconds since the epoch
      double fpTime;
.
      double fpTime;
      LL_L2D(fpTime, time64);
.
      LL_L2D(fpTime, time64);
      mPluginStreamInfo->SetLastModified((PRUint32)(fpTime * 1e-6 + 0.5));
.
      mPluginStreamInfo->SetLastModified((PRUint32)(fpTime * 1e-6 + 0.5));
      nsCRT::free(lastModified);
.
      nsCRT::free(lastModified);
    }
.
    }
  } 
.
  } 
 
.
 
  char* urlString;
.
  char* urlString;
  aURL->GetSpec(&urlString);
.
  aURL->GetSpec(&urlString);
  mPluginStreamInfo->SetURL(urlString);
.
  mPluginStreamInfo->SetURL(urlString);
  nsCRT::free(urlString);
.
  nsCRT::free(urlString);
 
.
 
  rv = mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInf
o);
.
  rv = mPStreamListener->OnStartBinding((nsIPluginStreamInfo*)mPluginStreamInf
o);
 
.
 
  mStartBinding = PR_TRUE;
.
  mStartBinding = PR_TRUE;
 
.
 
  if(rv == NS_OK)
.
  if(rv == NS_OK)
  {
.
  {
    mPStreamListener->GetStreamType(&mStreamType);
.
    mPStreamListener->GetStreamType(&mStreamType);
    // check to see if we need to cache the file as well
.
    // check to see if we need to cache the file as well
    if ((mStreamType == nsPluginStreamType_AsFile) || 
.
    if ((mStreamType == nsPluginStreamType_AsFile) || 
        (mStreamType == nsPluginStreamType_AsFileOnly))
.
        (mStreamType == nsPluginStreamType_AsFileOnly))
    rv = SetUpCache(aURL);
.
    rv = SetUpCache(aURL);
  }
.
  }
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
nsresult
.
nsresult
nsPluginStreamListenerPeer::OnFileAvailable(const char* aFilename)
.
nsPluginStreamListenerPeer::OnFileAvailable(const char* aFilename)
{
.
{
  nsresult rv;
.
  nsresult rv;
  if (!mPStreamListener)
.
  if (!mPStreamListener)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  rv = mPStreamListener->OnFileAvailable((nsIPluginStreamInfo*)mPluginStreamIn
fo, aFilename);
.
  rv = mPStreamListener->OnFileAvailable((nsIPluginStreamInfo*)mPluginStreamIn
fo, aFilename);
  return rv;
.
  return rv;
}
.
}
 
.
 
nsILoadGroup*
.
nsILoadGroup*
nsPluginStreamListenerPeer::GetLoadGroup()
.
nsPluginStreamListenerPeer::GetLoadGroup()
{
.
{
  nsILoadGroup* loadGroup = nsnull;
.
  nsILoadGroup* loadGroup = nsnull;
  nsIDocument* doc;
.
  nsIDocument* doc;
  nsresult rv = mOwner->GetDocument(&doc);
.
  nsresult rv = mOwner->GetDocument(&doc);
  if (NS_SUCCEEDED(rv)) {
.
  if (NS_SUCCEEDED(rv)) {
    doc->GetDocumentLoadGroup(&loadGroup);
.
    doc->GetDocumentLoadGroup(&loadGroup);
    NS_RELEASE(doc);
.
    NS_RELEASE(doc);
  }
.
  }
  return loadGroup;
.
  return loadGroup;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginStreamListenerPeer::VisitHeader(const char *header, const char *value)
.
nsPluginStreamListenerPeer::VisitHeader(const char *header, const char *value)
{
.
{
  nsCOMPtr<nsIHTTPHeaderListener> listener = do_QueryInterface(mPStreamListene
r);
.
  nsCOMPtr<nsIHTTPHeaderListener> listener = do_QueryInterface(mPStreamListene
r);
  if (!listener)
.
  if (!listener)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  return listener->NewResponseHeader(header, value);
.
  return listener->NewResponseHeader(header, value);
}
.
}
 
.
 
nsresult nsPluginStreamListenerPeer::SetLocalFile(const char* aFilename)
.
nsresult nsPluginStreamListenerPeer::SetLocalFile(const char* aFilename)
{
.
{
  NS_ENSURE_ARG_POINTER(aFilename);
.
  NS_ENSURE_ARG_POINTER(aFilename);
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  if(mLocalFile)
.
  if(mLocalFile)
  {
.
  {
    NS_ASSERTION(!mLocalFile, "nsPluginStreamListenerPeer::SetLocalFile -- pat
h already set, cleaning...");
.
    NS_ASSERTION(!mLocalFile, "nsPluginStreamListenerPeer::SetLocalFile -- pat
h already set, cleaning...");
    delete [] mLocalFile;
.
    delete [] mLocalFile;
    mLocalFile = nsnull;
.
    mLocalFile = nsnull;
  }
.
  }
 
.
 
  mLocalFile = new char[PL_strlen(aFilename) + 1];
.
  mLocalFile = new char[PL_strlen(aFilename) + 1];
  if(!mLocalFile)
.
  if(!mLocalFile)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  PL_strcpy(mLocalFile, aFilename);
.
  PL_strcpy(mLocalFile, aFilename);
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
/////////////////////////////////////////////////////////////////////////
.
/////////////////////////////////////////////////////////////////////////
 
.
 
nsPluginHostImpl::nsPluginHostImpl()
.
nsPluginHostImpl::nsPluginHostImpl()
{
.
{
  NS_INIT_REFCNT();
.
  NS_INIT_REFCNT();
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("nsPluginHostImpl ctor\n");
.
  printf("nsPluginHostImpl ctor\n");
#endif
.
#endif
  mPluginsLoaded = PR_FALSE;
.
  mPluginsLoaded = PR_FALSE;
  mDontShowBadPluginMessage = PR_FALSE;
.
  mDontShowBadPluginMessage = PR_FALSE;
  mIsDestroyed = PR_FALSE;
.
  mIsDestroyed = PR_FALSE;
  mUnusedLibraries = nsnull;
.
  mUnusedLibraries = nsnull;
 
.
 
  nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_C
ONTRACTID);
.
  nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_C
ONTRACTID);
  if (obsService)
.
  if (obsService)
  {
.
  {
    obsService->AddObserver(this, NS_LITERAL_STRING("quit-application").get())
;
.
    obsService->AddObserver(this, NS_LITERAL_STRING("quit-application").get())
;
    obsService->AddObserver(this, NS_ConvertASCIItoUCS2(NS_XPCOM_SHUTDOWN_OBSE
RVER_ID).get());
.
    obsService->AddObserver(this, NS_ConvertASCIItoUCS2(NS_XPCOM_SHUTDOWN_OBSE
RVER_ID).get());
  }
.
  }
}
.
}
 
.
 
nsPluginHostImpl::~nsPluginHostImpl()
.
nsPluginHostImpl::~nsPluginHostImpl()
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("nsPluginHostImpl dtor\n");
.
  printf("nsPluginHostImpl dtor\n");
#endif
.
#endif
  nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_C
ONTRACTID);
.
  nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_C
ONTRACTID);
  if (obsService)
.
  if (obsService)
  {
.
  {
    obsService->RemoveObserver(this, NS_LITERAL_STRING("quit-application").get
());
.
    obsService->RemoveObserver(this, NS_LITERAL_STRING("quit-application").get
());
    obsService->RemoveObserver(this, NS_ConvertASCIItoUCS2(NS_XPCOM_SHUTDOWN_O
BSERVER_ID).get());
.
    obsService->RemoveObserver(this, NS_ConvertASCIItoUCS2(NS_XPCOM_SHUTDOWN_O
BSERVER_ID).get());
  }
.
  }
  Destroy();
.
  Destroy();
}
.
}
 
.
 
NS_IMPL_ISUPPORTS7(nsPluginHostImpl,
.
NS_IMPL_ISUPPORTS7(nsPluginHostImpl,
                   nsIPluginManager,
.
                   nsIPluginManager,
                   nsIPluginManager2,
.
                   nsIPluginManager2,
                   nsIPluginHost,
.
                   nsIPluginHost,
                   nsIFileUtilities,
.
                   nsIFileUtilities,
                   nsICookieStorage,
.
                   nsICookieStorage,
                   nsIObserver,
.
                   nsIObserver,
                   nsPIPluginHost);
.
                   nsPIPluginHost);
 
.
 
NS_METHOD
.
NS_METHOD
nsPluginHostImpl::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
.
nsPluginHostImpl::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
.
{
  NS_PRECONDITION(aOuter == nsnull, "no aggregation");
.
  NS_PRECONDITION(aOuter == nsnull, "no aggregation");
  if (aOuter)
.
  if (aOuter)
    return NS_ERROR_NO_AGGREGATION;
.
    return NS_ERROR_NO_AGGREGATION;
 
.
 
  nsPluginHostImpl* host = new nsPluginHostImpl();
.
  nsPluginHostImpl* host = new nsPluginHostImpl();
  if (! host)
.
  if (! host)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  nsresult rv;
.
  nsresult rv;
  NS_ADDREF(host);
.
  NS_ADDREF(host);
  rv = host->QueryInterface(aIID, aResult);
.
  rv = host->QueryInterface(aIID, aResult);
  NS_RELEASE(host);
.
  NS_RELEASE(host);
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetValue(nsPluginManagerVariable aVariable, vo
id *aValue)
.
NS_IMETHODIMP nsPluginHostImpl::GetValue(nsPluginManagerVariable aVariable, vo
id *aValue)
{
.
{
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  NS_ENSURE_ARG_POINTER(aValue);
.
  NS_ENSURE_ARG_POINTER(aValue);
 
.
 
#if defined(XP_UNIX) && !defined(MACOSX)
.
#if defined(XP_UNIX) && !defined(MACOSX)
  if (nsPluginManagerVariable_XDisplay == aVariable) {
.
  if (nsPluginManagerVariable_XDisplay == aVariable) {
    Display** value = NS_REINTERPRET_CAST(Display**, aValue);
.
    Display** value = NS_REINTERPRET_CAST(Display**, aValue);
#if defined(MOZ_WIDGET_GTK)
.
#if defined(MOZ_WIDGET_GTK)
    *value = GDK_DISPLAY();
.
    *value = GDK_DISPLAY();
#elif defined(MOZ_WIDGET_QT)
.
#elif defined(MOZ_WIDGET_QT)
    *value = qt_xdisplay();
.
    *value = qt_xdisplay();
#endif
.
#endif
    if (!(*value)) {
.
    if (!(*value)) {
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
    }
.
    }
  }
.
  }
#endif
.
#endif
  return rv;
.
  return rv;
}
.
}
 
.
 
PRBool nsPluginHostImpl::IsRunningPlugin(nsPluginTag * plugin)
.
PRBool nsPluginHostImpl::IsRunningPlugin(nsPluginTag * plugin)
{
.
{
  if(!plugin)
.
  if(!plugin)
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  // we can check for mLibrary to be non-zero and then querry nsIPluginInstanc
ePeer
.
  // we can check for mLibrary to be non-zero and then querry nsIPluginInstanc
ePeer
  // in nsActivePluginList to see if plugin with matching mime type is not sto
pped
.
  // in nsActivePluginList to see if plugin with matching mime type is not sto
pped
  if(!plugin->mLibrary)
.
  if(!plugin->mLibrary)
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  for(int i = 0; i < plugin->mVariants; i++)
.
  for(int i = 0; i < plugin->mVariants; i++)
  {
.
  {
    nsActivePlugin * p = mActivePluginList.find(plugin->mMimeTypeArray[i]);
.
    nsActivePlugin * p = mActivePluginList.find(plugin->mMimeTypeArray[i]);
    if(p && !p->mStopped)
.
    if(p && !p->mStopped)
      return PR_TRUE;
.
      return PR_TRUE;
  }
.
  }
 
.
 
  return PR_FALSE;
.
  return PR_FALSE;
}
.
}
 
.
 
void nsPluginHostImpl::AddToUnusedLibraryList(PRLibrary * aLibrary)
.
void nsPluginHostImpl::AddToUnusedLibraryList(PRLibrary * aLibrary)
{
.
{
  NS_ASSERTION(aLibrary, "nsPluginHostImpl::AddToUnusedLibraryList: Nothing to
 add");
.
  NS_ASSERTION(aLibrary, "nsPluginHostImpl::AddToUnusedLibraryList: Nothing to
 add");
  if(!aLibrary)
.
  if(!aLibrary)
    return;
.
    return;
 
.
 
  nsUnusedLibrary * unusedLibrary = new nsUnusedLibrary(aLibrary);
.
  nsUnusedLibrary * unusedLibrary = new nsUnusedLibrary(aLibrary);
  if(unusedLibrary)
.
  if(unusedLibrary)
  {
.
  {
    unusedLibrary->mNext = mUnusedLibraries;
.
    unusedLibrary->mNext = mUnusedLibraries;
    mUnusedLibraries = unusedLibrary;
.
    mUnusedLibraries = unusedLibrary;
  }
.
  }
}
.
}
 
.
 
// this will unload loaded but no longer needed libs which are
.
// this will unload loaded but no longer needed libs which are
// gathered in mUnusedLibraries list, see bug #61388
.
// gathered in mUnusedLibraries list, see bug #61388
void nsPluginHostImpl::CleanUnusedLibraries()
.
void nsPluginHostImpl::CleanUnusedLibraries()
{
.
{
  if(!mUnusedLibraries)
.
  if(!mUnusedLibraries)
    return;
.
    return;
 
.
 
  while (nsnull != mUnusedLibraries)
.
  while (nsnull != mUnusedLibraries)
  {
.
  {
    nsUnusedLibrary *temp = mUnusedLibraries->mNext;
.
    nsUnusedLibrary *temp = mUnusedLibraries->mNext;
    delete mUnusedLibraries;
.
    delete mUnusedLibraries;
    mUnusedLibraries = temp;
.
    mUnusedLibraries = temp;
  }
.
  }
}
.
}
 
.
 
nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
.
nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
{
.
{
  // we are re-scanning plugins. New plugins may have been added, also some
.
  // 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
.
  // plugins may have been removed, so we should probably shut everything down
  // but don't touch running (active and  not stopped) plugins
.
  // but don't touch running (active and  not stopped) plugins
  if(reloadPages)
.
  if(reloadPages)
  {
.
  {
    // if we have currently running plugins we should set a flag not to
.
    // if we have currently running plugins we should set a flag not to
    // unload them from memory, see bug #61388
.
    // unload them from memory, see bug #61388
    // and form a list of libs to be unloaded later
.
    // and form a list of libs to be unloaded later
    for(nsPluginTag * p = mPlugins; p != nsnull; p = p->mNext)
.
    for(nsPluginTag * p = mPlugins; p != nsnull; p = p->mNext)
    {
.
    {
      if(IsRunningPlugin(p) && (p->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
.
      if(IsRunningPlugin(p) && (p->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
      {
.
      {
        p->mCanUnloadLibrary = PR_FALSE;
.
        p->mCanUnloadLibrary = PR_FALSE;
        AddToUnusedLibraryList(p->mLibrary);
.
        AddToUnusedLibraryList(p->mLibrary);
      }
.
      }
    }
.
    }
 
.
 
    // then stop any running plugins
.
    // then stop any running plugins
    mActivePluginList.stopRunning();
.
    mActivePluginList.stopRunning();
  }
.
  }
 
.
 
  // clean active plugin list
.
  // clean active plugin list
  mActivePluginList.removeAllStopped();
.
  mActivePluginList.removeAllStopped();
 
.
 
  // shutdown plugins and kill the list if there are no running plugins
.
  // shutdown plugins and kill the list if there are no running plugins
  nsPluginTag * prev = nsnull;
.
  nsPluginTag * prev = nsnull;
  nsPluginTag * next = nsnull;
.
  nsPluginTag * next = nsnull;
 
.
 
  for(nsPluginTag * p = mPlugins; p != nsnull;)
.
  for(nsPluginTag * p = mPlugins; p != nsnull;)
  {
.
  {
    next = p->mNext;
.
    next = p->mNext;
 
.
 
    if(!IsRunningPlugin(p))
.
    if(!IsRunningPlugin(p))
    {
.
    {
      if(p == mPlugins)
.
      if(p == mPlugins)
        mPlugins = next;
.
        mPlugins = next;
      else
.
      else
        prev->mNext = next;
.
        prev->mNext = next;
 
.
 
      delete p;
.
      delete p;
      p = next;
.
      p = next;
      continue;
.
      continue;
    }
.
    }
 
.
 
    prev = p;
.
    prev = p;
    p = next;
.
    p = next;
  }
.
  }
 
.
 
  // set flags
.
  // set flags
  mPluginsLoaded = PR_FALSE;
.
  mPluginsLoaded = PR_FALSE;
 
.
 
  // load them again
.
  // load them again
  nsresult rv = LoadPlugins();
.
  nsresult rv = LoadPlugins();
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
#define NS_RETURN_UASTRING_SIZE 128
.
#define NS_RETURN_UASTRING_SIZE 128
 
.
 
nsresult nsPluginHostImpl::UserAgent(const char **retstring)
.
nsresult nsPluginHostImpl::UserAgent(const char **retstring)
{
.
{
  static char resultString[NS_RETURN_UASTRING_SIZE];
.
  static char resultString[NS_RETURN_UASTRING_SIZE];
  nsresult res;
.
  nsresult res;
 
.
 
  nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(kHttpHandlerCID, &res)
;
.
  nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(kHttpHandlerCID, &res)
;
  if (NS_FAILED(res)) 
.
  if (NS_FAILED(res)) 
    return res;
.
    return res;
 
.
 
  nsXPIDLCString uaString;
.
  nsXPIDLCString uaString;
  res = http->GetUserAgent(getter_Copies(uaString));
.
  res = http->GetUserAgent(getter_Copies(uaString));
 
.
 
  if (NS_SUCCEEDED(res)) 
.
  if (NS_SUCCEEDED(res)) 
  {
.
  {
    if(NS_RETURN_UASTRING_SIZE > PL_strlen(uaString))
.
    if(NS_RETURN_UASTRING_SIZE > PL_strlen(uaString))
    {
.
    {
      PL_strcpy(resultString, uaString);
.
      PL_strcpy(resultString, uaString);
      *retstring = resultString;
.
      *retstring = resultString;
    }
.
    }
    else
.
    else
    {
.
    {
      *retstring = nsnull;
.
      *retstring = nsnull;
      res = NS_ERROR_OUT_OF_MEMORY;
.
      res = NS_ERROR_OUT_OF_MEMORY;
    }
.
    }
  } 
.
  } 
  else
.
  else
    *retstring = nsnull;
.
    *retstring = nsnull;
 
.
 
  return res;
.
  return res;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetURL(nsISupports* pluginInst, 
.
NS_IMETHODIMP nsPluginHostImpl::GetURL(nsISupports* pluginInst, 
									   const char* url, 
.
									   const char* url, 
									   const char* target,
.
									   const char* target,
									   nsIPluginStreamListener* streamListener,
.
									   nsIPluginStreamListener* streamListener,
									   const char* altHost,
.
									   const char* altHost,
									   const char* referrer,
.
									   const char* referrer,
									   PRBool forceJSEnabled)
.
									   PRBool forceJSEnabled)
{
.
{
  return GetURLWithHeaders(pluginInst, url, target, streamListener, 
.
  return GetURLWithHeaders(pluginInst, url, target, streamListener, 
                           altHost, referrer, forceJSEnabled, nsnull, nsnull);
.
                           altHost, referrer, forceJSEnabled, nsnull, nsnull);
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetURLWithHeaders(nsISupports* pluginInst, 
.
NS_IMETHODIMP nsPluginHostImpl::GetURLWithHeaders(nsISupports* pluginInst, 
									   const char* url, 
.
									   const char* url, 
									   const char* target,
.
									   const char* target,
									   nsIPluginStreamListener* streamListener,
.
									   nsIPluginStreamListener* streamListener,
									   const char* altHost,
.
									   const char* altHost,
									   const char* referrer,
.
									   const char* referrer,
									   PRBool forceJSEnabled,
.
									   PRBool forceJSEnabled,
                     PRUint32 getHeadersLength, 
.
                     PRUint32 getHeadersLength, 
                     const char* getHeaders)
.
                     const char* getHeaders)
{
.
{
  nsAutoString      string; string.AssignWithConversion(url);
.
  nsAutoString      string; string.AssignWithConversion(url);
  nsIPluginInstance *instance;
.
  nsIPluginInstance *instance;
  nsresult          rv;
.
  nsresult          rv;
 
.
 
  // we can only send a stream back to the plugin (as specified by a 
.
  // we can only send a stream back to the plugin (as specified by a 
  // null target) if we also have a nsIPluginStreamListener to talk to also
.
  // null target) if we also have a nsIPluginStreamListener to talk to also
  if(target == nsnull && streamListener == nsnull)
.
  if(target == nsnull && streamListener == nsnull)
	  return NS_ERROR_ILLEGAL_VALUE;
.
	  return NS_ERROR_ILLEGAL_VALUE;
 
.
 
  rv = pluginInst->QueryInterface(kIPluginInstanceIID, (void **)&instance);
.
  rv = pluginInst->QueryInterface(kIPluginInstanceIID, (void **)&instance);
 
.
 
  if (NS_SUCCEEDED(rv))
.
  if (NS_SUCCEEDED(rv))
  {
.
  {
    if (nsnull != target)
.
    if (nsnull != target)
    {
.
    {
      nsPluginInstancePeerImpl *peer;
.
      nsPluginInstancePeerImpl *peer;
 
.
 
      rv = instance->GetPeer(NS_REINTERPRET_CAST(nsIPluginInstancePeer **, &pe
er));
.
      rv = instance->GetPeer(NS_REINTERPRET_CAST(nsIPluginInstancePeer **, &pe
er));
 
.
 
      if (NS_SUCCEEDED(rv))
.
      if (NS_SUCCEEDED(rv))
      {
.
      {
        nsCOMPtr<nsIPluginInstanceOwner> owner;
.
        nsCOMPtr<nsIPluginInstanceOwner> owner;
 
.
 
        rv = peer->GetOwner(*getter_AddRefs(owner));
.
        rv = peer->GetOwner(*getter_AddRefs(owner));
 
.
 
        if (NS_SUCCEEDED(rv))
.
        if (NS_SUCCEEDED(rv))
        {
.
        {
          if ((0 == PL_strcmp(target, "newwindow")) || 
.
          if ((0 == PL_strcmp(target, "newwindow")) || 
              (0 == PL_strcmp(target, "_new")))
.
              (0 == PL_strcmp(target, "_new")))
            target = "_blank";
.
            target = "_blank";
          else if (0 == PL_strcmp(target, "_current"))
.
          else if (0 == PL_strcmp(target, "_current"))
            target = "_self";
.
            target = "_self";
 
.
 
          rv = owner->GetURL(url, target, nsnull, 0, (void *) getHeaders, 
.
          rv = owner->GetURL(url, target, nsnull, 0, (void *) getHeaders, 
                             getHeadersLength);
.
                             getHeadersLength);
        }
.
        }
 
.
 
        NS_RELEASE(peer);
.
        NS_RELEASE(peer);
      }
.
      }
    }
.
    }
 
.
 
    if (nsnull != streamListener)
.
    if (nsnull != streamListener)
      rv = NewPluginURLStream(string, instance, streamListener, nsnull, 
.
      rv = NewPluginURLStream(string, instance, streamListener, nsnull, 
                              PR_FALSE, nsnull, getHeaders, getHeadersLength);
.
                              PR_FALSE, nsnull, getHeaders, getHeadersLength);
 
.
 
    NS_RELEASE(instance);
.
    NS_RELEASE(instance);
  }
.
  }
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::PostURL(nsISupports* pluginInst,
.
NS_IMETHODIMP nsPluginHostImpl::PostURL(nsISupports* pluginInst,
										const char* url,
.
										const char* url,
										PRUint32 postDataLen, 
.
										PRUint32 postDataLen, 
										const char* postData,
.
										const char* postData,
										PRBool isFile,
.
										PRBool isFile,
										const char* target,
.
										const char* target,
										nsIPluginStreamListener* streamListener,
.
										nsIPluginStreamListener* streamListener,
										const char* altHost, 
.
										const char* altHost, 
										const char* referrer,
.
										const char* referrer,
										PRBool forceJSEnabled,
.
										PRBool forceJSEnabled,
										PRUint32 postHeadersLength, 
.
										PRUint32 postHeadersLength, 
										const char* postHeaders)
.
										const char* postHeaders)
{
.
{
  nsAutoString      string; string.AssignWithConversion(url);
.
  nsAutoString      string; string.AssignWithConversion(url);
  nsIPluginInstance *instance;
.
  nsIPluginInstance *instance;
  nsresult          rv;
.
  nsresult          rv;
  
.
  
  // we can only send a stream back to the plugin (as specified 
.
  // we can only send a stream back to the plugin (as specified 
  // by a null target) if we also have a nsIPluginStreamListener 
.
  // by a null target) if we also have a nsIPluginStreamListener 
  // to talk to also
.
  // to talk to also
  if(target == nsnull && streamListener == nsnull)
.
  if(target == nsnull && streamListener == nsnull)
	  return NS_ERROR_ILLEGAL_VALUE;
.
	  return NS_ERROR_ILLEGAL_VALUE;
  
.
  
  rv = pluginInst->QueryInterface(kIPluginInstanceIID, (void **)&instance);
.
  rv = pluginInst->QueryInterface(kIPluginInstanceIID, (void **)&instance);
  
.
  
  if (NS_SUCCEEDED(rv))
.
  if (NS_SUCCEEDED(rv))
  {
.
  {
      nsPluginInstancePeerImpl *peer;
.
      nsPluginInstancePeerImpl *peer;
 
.
 
      if (nsnull != target)
.
      if (nsnull != target)
        {
.
        {
          
.
          
          rv = instance->GetPeer(NS_REINTERPRET_CAST(nsIPluginInstancePeer **,
 &peer));
.
          rv = instance->GetPeer(NS_REINTERPRET_CAST(nsIPluginInstancePeer **,
 &peer));
          
.
          
          if (NS_SUCCEEDED(rv))
.
          if (NS_SUCCEEDED(rv))
            {
.
            {
              nsCOMPtr<nsIPluginInstanceOwner> owner;
.
              nsCOMPtr<nsIPluginInstanceOwner> owner;
              
.
              
              rv = peer->GetOwner(*getter_AddRefs(owner));
.
              rv = peer->GetOwner(*getter_AddRefs(owner));
              
.
              
              if (NS_SUCCEEDED(rv))
.
              if (NS_SUCCEEDED(rv))
                {
.
                {
                  if (!target) {
.
                  if (!target) {
                    target = "_self";
.
                    target = "_self";
                  }
.
                  }
                  else {
.
                  else {
                    if ((0 == PL_strcmp(target, "newwindow")) || 
.
                    if ((0 == PL_strcmp(target, "newwindow")) || 
                        (0 == PL_strcmp(target, "_new")))
.
                        (0 == PL_strcmp(target, "_new")))
                      target = "_blank";
.
                      target = "_blank";
                    else if (0 == PL_strcmp(target, "_current"))
.
                    else if (0 == PL_strcmp(target, "_current"))
                      target = "_self";
.
                      target = "_self";
                  }
.
                  }
                  rv = owner->GetURL(url, target, (void*)postData, postDataLen
,
.
                  rv = owner->GetURL(url, target, (void*)postData, postDataLen
,
                                     (void*) postHeaders, postHeadersLength);
.
                                     (void*) postHeaders, postHeadersLength);
                }
.
                }
              
.
              
              NS_RELEASE(peer);
.
              NS_RELEASE(peer);
            }
.
            }
        }
.
        }
    
.
    
      // if we don't have a target, just create a stream.  This does
.
      // if we don't have a target, just create a stream.  This does
      // NS_OpenURI()!
.
      // NS_OpenURI()!
      if (streamListener != nsnull)
.
      if (streamListener != nsnull)
        rv = NewPluginURLStream(string, instance, streamListener,
.
        rv = NewPluginURLStream(string, instance, streamListener,
                                postData, isFile, postDataLen,
.
                                postData, isFile, postDataLen,
                                postHeaders, postHeadersLength);
.
                                postHeaders, postHeadersLength);
      NS_RELEASE(instance);
.
      NS_RELEASE(instance);
  }
.
  }
  
.
  
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
.
NS_IMETHODIMP nsPluginHostImpl::RegisterPlugin(REFNSIID aCID,
                                               const char* aPluginName,
.
                                               const char* aPluginName,
                                               const char* aDescription,
.
                                               const char* aDescription,
                                               const char** aMimeTypes,
.
                                               const char** aMimeTypes,
                                               const char** aMimeDescriptions,
.
                                               const char** aMimeDescriptions,
                                               const char** aFileExtensions,
.
                                               const char** aFileExtensions,
                                               PRInt32 aCount)
.
                                               PRInt32 aCount)
{
.
{
  nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
.
  nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
  if (! registry)
.
  if (! registry)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  nsresult rv;
.
  nsresult rv;
  rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegist
ry);
.
  rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegist
ry);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  nsCAutoString path("software/plugins/");
.
  nsCAutoString path("software/plugins/");
  char* cid = aCID.ToString();
.
  char* cid = aCID.ToString();
  if (! cid)
.
  if (! cid)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  path += cid;
.
  path += cid;
  nsMemory::Free(cid);
.
  nsMemory::Free(cid);
 
.
 
  nsRegistryKey pluginKey;
.
  nsRegistryKey pluginKey;
  rv = registry->AddSubtree(nsIRegistry::Common, path.get(), &pluginKey);
.
  rv = registry->AddSubtree(nsIRegistry::Common, path.get(), &pluginKey);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  registry->SetStringUTF8(pluginKey, "name", aPluginName);
.
  registry->SetStringUTF8(pluginKey, "name", aPluginName);
  registry->SetStringUTF8(pluginKey, "description", aDescription);
.
  registry->SetStringUTF8(pluginKey, "description", aDescription);
 
.
 
  for (PRInt32 i = 0; i < aCount; ++i) {
.
  for (PRInt32 i = 0; i < aCount; ++i) {
    nsCAutoString mimepath;
.
    nsCAutoString mimepath;
    mimepath.AppendInt(i);
.
    mimepath.AppendInt(i);
 
.
 
    nsRegistryKey key;
.
    nsRegistryKey key;
    registry->AddSubtree(pluginKey, mimepath.get(), &key);
.
    registry->AddSubtree(pluginKey, mimepath.get(), &key);
 
.
 
    registry->SetStringUTF8(key, "mimetype",    aMimeTypes[i]);
.
    registry->SetStringUTF8(key, "mimetype",    aMimeTypes[i]);
    registry->SetStringUTF8(key, "description", aMimeDescriptions[i]);
.
    registry->SetStringUTF8(key, "description", aMimeDescriptions[i]);
    registry->SetStringUTF8(key, "extension",   aFileExtensions[i]);
.
    registry->SetStringUTF8(key, "extension",   aFileExtensions[i]);
  }
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::UnregisterPlugin(REFNSIID aCID)
.
NS_IMETHODIMP nsPluginHostImpl::UnregisterPlugin(REFNSIID aCID)
{
.
{
  nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
.
  nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
  if (! registry)
.
  if (! registry)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  nsresult rv;
.
  nsresult rv;
  rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegist
ry);
.
  rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegist
ry);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  nsCAutoString path("software/plugins/");
.
  nsCAutoString path("software/plugins/");
  char* cid = aCID.ToString();
.
  char* cid = aCID.ToString();
  if (! cid)
.
  if (! cid)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  path += cid;
.
  path += cid;
  nsMemory::Free(cid);
.
  nsMemory::Free(cid);
 
.
 
  return registry->RemoveSubtree(nsIRegistry::Common, path.get());
.
  return registry->RemoveSubtree(nsIRegistry::Common, path.get());
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::BeginWaitCursor(void)
.
NS_IMETHODIMP nsPluginHostImpl::BeginWaitCursor(void)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::EndWaitCursor(void)
.
NS_IMETHODIMP nsPluginHostImpl::EndWaitCursor(void)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::SupportsURLProtocol(const char* protocol, PRBo
ol *result)
.
NS_IMETHODIMP nsPluginHostImpl::SupportsURLProtocol(const char* protocol, PRBo
ol *result)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::NotifyStatusChange(nsIPlugin* plugin, nsresult
 errorStatus)
.
NS_IMETHODIMP nsPluginHostImpl::NotifyStatusChange(nsIPlugin* plugin, nsresult
 errorStatus)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
/**
.
/**
 * This method queries the prefs for proxy information.
.
 * This method queries the prefs for proxy information.
 * It has been tested and is known to work in the following three cases
.
 * It has been tested and is known to work in the following three cases
 * when no proxy host or port is specified
.
 * when no proxy host or port is specified
 * when only the proxy host is specified
.
 * when only the proxy host is specified
 * when only the proxy port is specified
.
 * when only the proxy port is specified
 * This method conforms to the return code specified in 
.
 * This method conforms to the return code specified in 
 * http://developer.netscape.com/docs/manuals/proxy/adminnt/autoconf.htm#10209
23
.
 * http://developer.netscape.com/docs/manuals/proxy/adminnt/autoconf.htm#10209
23
 * with the exception that multiple values are not implemented.
.
 * with the exception that multiple values are not implemented.
 */
.
 */
 
.
 
NS_IMETHODIMP nsPluginHostImpl::FindProxyForURL(const char* url, char* *result
)
.
NS_IMETHODIMP nsPluginHostImpl::FindProxyForURL(const char* url, char* *result
)
{
.
{
  if (!url || !result) {
.
  if (!url || !result) {
    return NS_ERROR_INVALID_ARG;
.
    return NS_ERROR_INVALID_ARG;
  }
.
  }
  nsresult res;
.
  nsresult res;
 
.
 
  nsCOMPtr<nsIURI> uriIn;
.
  nsCOMPtr<nsIURI> uriIn;
  nsCOMPtr<nsIProtocolProxyService> proxyService;
.
  nsCOMPtr<nsIProtocolProxyService> proxyService;
  nsCOMPtr<nsIIOService> ioService;
.
  nsCOMPtr<nsIIOService> ioService;
  PRBool isProxyEnabled;
.
  PRBool isProxyEnabled;
  nsXPIDLCString proxyHost, proxyType;
.
  nsXPIDLCString proxyHost, proxyType;
  PRInt32 proxyPort;
.
  PRInt32 proxyPort;
 
.
 
  proxyService = do_GetService(kProtocolProxyServiceCID, &res);
.
  proxyService = do_GetService(kProtocolProxyServiceCID, &res);
  if (NS_FAILED(res) || !proxyService) {
.
  if (NS_FAILED(res) || !proxyService) {
    return res;
.
    return res;
  }
.
  }
  
.
  
  if (NS_FAILED(proxyService->GetProxyEnabled(&isProxyEnabled))) {
.
  if (NS_FAILED(proxyService->GetProxyEnabled(&isProxyEnabled))) {
    return res;
.
    return res;
  }
.
  }
 
.
 
  if (!isProxyEnabled) {
.
  if (!isProxyEnabled) {
    *result = PL_strdup("DIRECT");
.
    *result = PL_strdup("DIRECT");
    if (nsnull == *result) {
.
    if (nsnull == *result) {
      res = NS_ERROR_OUT_OF_MEMORY;
.
      res = NS_ERROR_OUT_OF_MEMORY;
    }
.
    }
    return res;
.
    return res;
  }
.
  }
  
.
  
  ioService = do_GetService(kIOServiceCID, &res);
.
  ioService = do_GetService(kIOServiceCID, &res);
  if (NS_FAILED(res) || !ioService) {
.
  if (NS_FAILED(res) || !ioService) {
    return res;
.
    return res;
  }
.
  }
  
.
  
  // make an nsURI from the argument url
.
  // make an nsURI from the argument url
  res = ioService->NewURI(url, nsnull, getter_AddRefs(uriIn));
.
  res = ioService->NewURI(url, nsnull, getter_AddRefs(uriIn));
  if (NS_FAILED(res)) {
.
  if (NS_FAILED(res)) {
    return res;
.
    return res;
  }
.
  }
 
.
 
  res = proxyService->ExamineForProxy(uriIn, 
.
  res = proxyService->ExamineForProxy(uriIn, 
                                      getter_Copies(proxyHost), 
.
                                      getter_Copies(proxyHost), 
                                      &proxyPort, 
.
                                      &proxyPort, 
                                      getter_Copies(proxyType));
.
                                      getter_Copies(proxyType));
  if (NS_FAILED(res)) {
.
  if (NS_FAILED(res)) {
    return res;
.
    return res;
  }
.
  }
 
.
 
  if (!isProxyEnabled || !proxyHost.get() || proxyPort <= 0) {
.
  if (!isProxyEnabled || !proxyHost.get() || proxyPort <= 0) {
    *result = PL_strdup("DIRECT");
.
    *result = PL_strdup("DIRECT");
  }
.
  }
  else {
.
  else {
    *result = PR_smprintf("PROXY %s:%d", (const char *) proxyHost, proxyPort);
.
    *result = PR_smprintf("PROXY %s:%d", (const char *) proxyHost, proxyPort);
  }
.
  }
 
.
 
  if (nsnull == *result) {
.
  if (nsnull == *result) {
    res = NS_ERROR_OUT_OF_MEMORY;
.
    res = NS_ERROR_OUT_OF_MEMORY;
  }
.
  }
  
.
  
  return res;
.
  return res;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::RegisterWindow(nsIEventHandler* handler, nsPlu
ginPlatformWindowRef window)
.
NS_IMETHODIMP nsPluginHostImpl::RegisterWindow(nsIEventHandler* handler, nsPlu
ginPlatformWindowRef window)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::UnregisterWindow(nsIEventHandler* handler, nsP
luginPlatformWindowRef window)
.
NS_IMETHODIMP nsPluginHostImpl::UnregisterWindow(nsIEventHandler* handler, nsP
luginPlatformWindowRef window)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::AllocateMenuID(nsIEventHandler* handler, PRBoo
l isSubmenu, PRInt16 *result)
.
NS_IMETHODIMP nsPluginHostImpl::AllocateMenuID(nsIEventHandler* handler, PRBoo
l isSubmenu, PRInt16 *result)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::DeallocateMenuID(nsIEventHandler* handler, PRI
nt16 menuID)
.
NS_IMETHODIMP nsPluginHostImpl::DeallocateMenuID(nsIEventHandler* handler, PRI
nt16 menuID)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::HasAllocatedMenuID(nsIEventHandler* handler, P
RInt16 menuID, PRBool *result)
.
NS_IMETHODIMP nsPluginHostImpl::HasAllocatedMenuID(nsIEventHandler* handler, P
RInt16 menuID, PRBool *result)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::ProcessNextEvent(PRBool *bEventHandled)
.
NS_IMETHODIMP nsPluginHostImpl::ProcessNextEvent(PRBool *bEventHandled)
{
.
{
  return NS_ERROR_NOT_IMPLEMENTED;
.
  return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::CreateInstance(nsISupports *aOuter,
.
NS_IMETHODIMP nsPluginHostImpl::CreateInstance(nsISupports *aOuter,
                                               REFNSIID aIID,
.
                                               REFNSIID aIID,
                                               void **aResult)
.
                                               void **aResult)
{
.
{
  NS_NOTREACHED("how'd I get here?");
.
  NS_NOTREACHED("how'd I get here?");
  return NS_ERROR_UNEXPECTED;
.
  return NS_ERROR_UNEXPECTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::LockFactory(PRBool aLock)
.
NS_IMETHODIMP nsPluginHostImpl::LockFactory(PRBool aLock)
{
.
{
  NS_NOTREACHED("how'd I get here?");
.
  NS_NOTREACHED("how'd I get here?");
  return NS_ERROR_UNEXPECTED;
.
  return NS_ERROR_UNEXPECTED;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::Init(void)
.
NS_IMETHODIMP nsPluginHostImpl::Init(void)
{
.
{
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
.
NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
{
.
{
  if (mIsDestroyed)
.
  if (mIsDestroyed)
    return NS_OK;
.
    return NS_OK;
 
.
 
  mIsDestroyed = PR_TRUE;
.
  mIsDestroyed = PR_TRUE;
 
.
 
  // we should call nsIPluginInstance::Stop and nsIPluginInstance::SetWindow 
.
  // we should call nsIPluginInstance::Stop and nsIPluginInstance::SetWindow 
  // for those plugins who want it
.
  // for those plugins who want it
  mActivePluginList.stopRunning();  
.
  mActivePluginList.stopRunning();  
 
.
 
  // at this point nsIPlugin::Shutdown calls will be performed if needed
.
  // at this point nsIPlugin::Shutdown calls will be performed if needed
  mActivePluginList.shut();
.
  mActivePluginList.shut();
 
.
 
  if (nsnull != mPluginPath)
.
  if (nsnull != mPluginPath)
  {
.
  {
    PR_Free(mPluginPath);
.
    PR_Free(mPluginPath);
    mPluginPath = nsnull;
.
    mPluginPath = nsnull;
  }
.
  }
 
.
 
  while (nsnull != mPlugins)
.
  while (nsnull != mPlugins)
  {
.
  {
    nsPluginTag *temp = mPlugins->mNext;
.
    nsPluginTag *temp = mPlugins->mNext;
 
.
 
    // while walking through the list of the plugins see if we still have anyt
hing 
.
    // while walking through the list of the plugins see if we still have anyt
hing 
    // to shutdown some plugins may have never created an instance but still e
xpect 
.
    // to shutdown some plugins may have never created an instance but still e
xpect 
    // the shutdown call see bugzilla bug 73071
.
    // the shutdown call see bugzilla bug 73071
    // with current logic, no need to do anything special as nsIPlugin::Shutdo
wn 
.
    // with current logic, no need to do anything special as nsIPlugin::Shutdo
wn 
    // will be performed in the destructor
.
    // will be performed in the destructor
 
.
 
    delete mPlugins;
.
    delete mPlugins;
    mPlugins = temp;
.
    mPlugins = temp;
  }
.
  }
 
.
 
  CleanUnusedLibraries();
.
  CleanUnusedLibraries();
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* Called by nsPluginInstanceOwner (nsObjectFrame.cpp - embeded case) */
.
/* Called by nsPluginInstanceOwner (nsObjectFrame.cpp - embeded case) */
NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType
, 
.
NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType
, 
                                                         nsIURI* aURL,
.
                                                         nsIURI* aURL,
                                                         nsIPluginInstanceOwne
r *aOwner)
.
                                                         nsIPluginInstanceOwne
r *aOwner)
{
.
{
  nsresult  rv;
.
  nsresult  rv;
  nsIPluginInstance *instance = nsnull;
.
  nsIPluginInstance *instance = nsnull;
  nsCOMPtr<nsIPluginTagInfo2> pti2 = nsnull;
.
  nsCOMPtr<nsIPluginTagInfo2> pti2 = nsnull;
  nsPluginTagType tagType;
.
  nsPluginTagType tagType;
  PRBool isJavaEnabled = PR_TRUE;
.
  PRBool isJavaEnabled = PR_TRUE;
  
.
  
  rv = aOwner->QueryInterface(kIPluginTagInfo2IID, getter_AddRefs(pti2));
.
  rv = aOwner->QueryInterface(kIPluginTagInfo2IID, getter_AddRefs(pti2));
  
.
  
  if(rv != NS_OK) {
.
  if(rv != NS_OK) {
    return rv;
.
    return rv;
  }
.
  }
  
.
  
  rv = pti2->GetTagType(&tagType);
.
  rv = pti2->GetTagType(&tagType);
 
.
 
  if((rv != NS_OK) || !((tagType == nsPluginTagType_Embed)
.
  if((rv != NS_OK) || !((tagType == nsPluginTagType_Embed)
                        || (tagType == nsPluginTagType_Applet)
.
                        || (tagType == nsPluginTagType_Applet)
                        || (tagType == nsPluginTagType_Object)))
.
                        || (tagType == nsPluginTagType_Object)))
  {
.
  {
    return rv;
.
    return rv;
  }
.
  }
 
.
 
  if (tagType == nsPluginTagType_Applet) {
.
  if (tagType == nsPluginTagType_Applet) {
    nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
.
    nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
    // see if java is enabled
.
    // see if java is enabled
    if (prefs) {
.
    if (prefs) {
      rv = prefs->GetBoolPref("security.enable_java", &isJavaEnabled);
.
      rv = prefs->GetBoolPref("security.enable_java", &isJavaEnabled);
      if (NS_SUCCEEDED(rv)) {
.
      if (NS_SUCCEEDED(rv)) {
        // if not, don't show this plugin
.
        // if not, don't show this plugin
        if (!isJavaEnabled) {
.
        if (!isJavaEnabled) {
          return NS_ERROR_FAILURE;
.
          return NS_ERROR_FAILURE;
        }
.
        }
      }
.
      }
      else {
.
      else {
        // if we were unable to get the pref, assume java is enabled
.
        // if we were unable to get the pref, assume java is enabled
        // and rely on the "find the plugin or not" logic.
.
        // and rely on the "find the plugin or not" logic.
        
.
        
        // make sure the value wasn't modified in GetBoolPref
.
        // make sure the value wasn't modified in GetBoolPref
        isJavaEnabled = PR_TRUE;
.
        isJavaEnabled = PR_TRUE;
      }
.
      }
    }
.
    }
  }
.
  }
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  if(aMimeType)
.
  if(aMimeType)
    printf("InstantiateEmbededPlugin for %s\n",aMimeType);
.
    printf("InstantiateEmbededPlugin for %s\n",aMimeType);
#endif
.
#endif
 
.
 
  if(FindStoppedPluginForURL(aURL, aOwner) == NS_OK)
.
  if(FindStoppedPluginForURL(aURL, aOwner) == NS_OK)
  {
.
  {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      printf("InstantiateEmbededPlugin find stopped\n");
.
      printf("InstantiateEmbededPlugin find stopped\n");
#endif
.
#endif
 
.
 
	  aOwner->GetInstance(instance);
.
	  aOwner->GetInstance(instance);
    if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
.
    if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
	    rv = NewEmbededPluginStream(aURL, nsnull, instance);
.
	    rv = NewEmbededPluginStream(aURL, nsnull, instance);
 
.
 
    // notify Java DOM component 
.
    // notify Java DOM component 
    nsresult res;
.
    nsresult res;
    NS_WITH_SERVICE(nsIPluginInstanceOwner, javaDOM, "@mozilla.org/blackwood/j
ava-dom;1", &res);
.
    NS_WITH_SERVICE(nsIPluginInstanceOwner, javaDOM, "@mozilla.org/blackwood/j
ava-dom;1", &res);
    if (NS_SUCCEEDED(res) && javaDOM)
.
    if (NS_SUCCEEDED(res) && javaDOM)
      javaDOM->SetInstance(instance);
.
      javaDOM->SetInstance(instance);
 
.
 
    NS_IF_RELEASE(instance);
.
    NS_IF_RELEASE(instance);
    return NS_OK;
.
    return NS_OK;
  }
.
  }
 
.
 
  // if we don't have a MIME type at this point, we still have one more chance
 by 
.
  // 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 
.
  // opening the stream and seeing if the server hands one back 
  if (!aMimeType)
.
  if (!aMimeType)
    if (aURL)
.
    if (aURL)
    {
.
    {
       rv = NewEmbededPluginStream(aURL, aOwner, nsnull);
.
       rv = NewEmbededPluginStream(aURL, aOwner, nsnull);
       return rv;
.
       return rv;
    } else
.
    } else
       return NS_ERROR_FAILURE;
.
       return NS_ERROR_FAILURE;
 
.
 
  rv = SetUpPluginInstance(aMimeType, aURL, aOwner);
.
  rv = SetUpPluginInstance(aMimeType, aURL, aOwner);
 
.
 
  if(rv == NS_OK)
.
  if(rv == NS_OK)
	  rv = aOwner->GetInstance(instance);
.
	  rv = aOwner->GetInstance(instance);
  else 
.
  else 
  {
.
  {
    // We have the mime type either supplied in source or from the header.
.
    // We have the mime type either supplied in source or from the header.
    // Let's try to render the default plugin.  See bug 41197
.
    // Let's try to render the default plugin.  See bug 41197
    
.
    
    // We were unable to find a plug-in yet we 
.
    // We were unable to find a plug-in yet we 
    // really do have mime type. Return the error
.
    // really do have mime type. Return the error
    // so that the nsObjectFrame can render any 
.
    // so that the nsObjectFrame can render any 
    // alternate content.
.
    // alternate content.
 
.
 
    // but try to load the default plugin first. We need to do this
.
    // but try to load the default plugin first. We need to do this
    // for <embed> tag leaving <object> to play with its alt content.
.
    // for <embed> tag leaving <object> to play with its alt content.
    // but before we return an error let's see if this is an <embed>
.
    // but before we return an error let's see if this is an <embed>
    // tag and try to launch the default plugin
.
    // tag and try to launch the default plugin
 
.
 
    // but to comply with the spec don't do it for <object> tag
.
    // but to comply with the spec don't do it for <object> tag
    if(tagType == nsPluginTagType_Object)
.
    if(tagType == nsPluginTagType_Object)
      return rv;
.
      return rv;
 
.
 
    nsresult result;
.
    nsresult result;
 
.
 
    result = SetUpDefaultPluginInstance(aMimeType, aURL, aOwner);
.
    result = SetUpDefaultPluginInstance(aMimeType, aURL, aOwner);
 
.
 
    if(result == NS_OK)
.
    if(result == NS_OK)
	    result = aOwner->GetInstance(instance);
.
	    result = aOwner->GetInstance(instance);
 
.
 
    if(result != NS_OK) {
.
    if(result != NS_OK) {
      DisplayNoDefaultPluginDialog(aMimeType);
.
      DisplayNoDefaultPluginDialog(aMimeType);
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
    }
.
    }
 
.
 
    rv = NS_OK;
.
    rv = NS_OK;
  }
.
  }
 
.
 
  // if we have a failure error, it means we found a plugin for the mimetype,
.
  // if we have a failure error, it means we found a plugin for the mimetype,
  // but we had a problem with the entry point
.
  // but we had a problem with the entry point
  if(rv == NS_ERROR_FAILURE)
.
  if(rv == NS_ERROR_FAILURE)
	  return rv;
.
	  return rv;
 
.
 
   // if we are here then we have loaded a plugin for this mimetype
.
   // if we are here then we have loaded a plugin for this mimetype
   // and it could be the Default plugin
.
   // and it could be the Default plugin
  
.
  
    nsPluginWindow    *window = nsnull;
.
    nsPluginWindow    *window = nsnull;
 
.
 
    //we got a plugin built, now stream
.
    //we got a plugin built, now stream
    aOwner->GetWindow(window);
.
    aOwner->GetWindow(window);
 
.
 
    if (nsnull != instance)
.
    if (nsnull != instance)
    {
.
    {
      instance->Start();
.
      instance->Start();
      aOwner->CreateWidget();
.
      aOwner->CreateWidget();
 
.
 
      // If we've got a native window, the let the plugin know about it.
.
      // If we've got a native window, the let the plugin know about it.
      if (window->window)
.
      if (window->window)
        instance->SetWindow(window);
.
        instance->SetWindow(window);
 
.
 
      // don't make an initial steam if it's a java applet
.
      // don't make an initial steam if it's a java applet
      if(!aMimeType || 
.
      if(!aMimeType || 
         (PL_strcasecmp(aMimeType, "application/x-java-vm") != 0 && 
.
         (PL_strcasecmp(aMimeType, "application/x-java-vm") != 0 && 
          PL_strcasecmp(aMimeType, "application/x-java-applet") != 0))
.
          PL_strcasecmp(aMimeType, "application/x-java-applet") != 0))
        rv = NewEmbededPluginStream(aURL, nsnull, instance);
.
        rv = NewEmbededPluginStream(aURL, nsnull, instance);
 
.
 
      // notify Java DOM component 
.
      // notify Java DOM component 
      nsresult res;
.
      nsresult res;
      NS_WITH_SERVICE(nsIPluginInstanceOwner, javaDOM, "@mozilla.org/blackwood
/java-dom;1", &res);
.
      NS_WITH_SERVICE(nsIPluginInstanceOwner, javaDOM, "@mozilla.org/blackwood
/java-dom;1", &res);
      if (NS_SUCCEEDED(res) && javaDOM)
.
      if (NS_SUCCEEDED(res) && javaDOM)
        javaDOM->SetInstance(instance);
.
        javaDOM->SetInstance(instance);
 
.
 
      NS_RELEASE(instance);
.
      NS_RELEASE(instance);
    }
.
    }
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("InstantiateEmbededPlugin.. returning\n");
.
  printf("InstantiateEmbededPlugin.. returning\n");
#endif
.
#endif
  return rv;
.
  return rv;
}
.
}
 
.
 
/* Called by nsPluginViewer.cpp (full-page case) */
.
/* Called by nsPluginViewer.cpp (full-page case) */
 
.
 
NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeTyp
e, 
.
NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeTyp
e, 
                                                          nsString& aURLSpec,
.
                                                          nsString& aURLSpec,
                                                          nsIStreamListener *&
aStreamListener,
.
                                                          nsIStreamListener *&
aStreamListener,
                                                          nsIPluginInstanceOwn
er *aOwner)
.
                                                          nsIPluginInstanceOwn
er *aOwner)
{
.
{
  nsresult  rv;
.
  nsresult  rv;
  nsIURI    *url;
.
  nsIURI    *url;
  PRBool isJavaEnabled = PR_TRUE;
.
  PRBool isJavaEnabled = PR_TRUE;
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("InstantiateFullPagePlugin for %s\n",aMimeType);
.
  printf("InstantiateFullPagePlugin for %s\n",aMimeType);
#endif
.
#endif
  
.
  
  //create a URL so that the instantiator can do file ext.
.
  //create a URL so that the instantiator can do file ext.
  //based plugin lookups...
.
  //based plugin lookups...
  rv = NS_NewURI(&url, aURLSpec);
.
  rv = NS_NewURI(&url, aURLSpec);
 
.
 
  if (rv != NS_OK)
.
  if (rv != NS_OK)
    url = nsnull;
.
    url = nsnull;
 
.
 
  if(FindStoppedPluginForURL(url, aOwner) == NS_OK)
.
  if(FindStoppedPluginForURL(url, aOwner) == NS_OK)
  {
.
  {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
      printf("InstantiateFullPagePlugin, got a stopped plugin\n");
.
      printf("InstantiateFullPagePlugin, got a stopped plugin\n");
#endif
.
#endif
 
.
 
    nsIPluginInstance* instance;
.
    nsIPluginInstance* instance;
	  aOwner->GetInstance(instance);
.
	  aOwner->GetInstance(instance);
    if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
.
    if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
	    rv = NewFullPagePluginStream(aStreamListener, instance);
.
	    rv = NewFullPagePluginStream(aStreamListener, instance);
    NS_IF_RELEASE(instance);
.
    NS_IF_RELEASE(instance);
    return NS_OK;
.
    return NS_OK;
  }  
.
  }  
 
.
 
  rv = SetUpPluginInstance(aMimeType, url, aOwner);
.
  rv = SetUpPluginInstance(aMimeType, url, aOwner);
 
.
 
  NS_IF_RELEASE(url);
.
  NS_IF_RELEASE(url);
 
.
 
  if (NS_OK == rv)
.
  if (NS_OK == rv)
  {
.
  {
    nsIPluginInstance *instance = nsnull;
.
    nsIPluginInstance *instance = nsnull;
    nsPluginWindow    *window = nsnull;
.
    nsPluginWindow    *window = nsnull;
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
    printf("InstantiateFullPagePlugin, got it... now stream\n");
.
    printf("InstantiateFullPagePlugin, got it... now stream\n");
#endif
.
#endif
    //we got a plugin built, now stream
.
    //we got a plugin built, now stream
 
.
 
    aOwner->GetInstance(instance);
.
    aOwner->GetInstance(instance);
    aOwner->GetWindow(window);
.
    aOwner->GetWindow(window);
 
.
 
    if (nsnull != instance)
.
    if (nsnull != instance)
    {
.
    {
      instance->Start();
.
      instance->Start();
      aOwner->CreateWidget();
.
      aOwner->CreateWidget();
 
.
 
      // If we've got a native window, the let the plugin know about it.
.
      // If we've got a native window, the let the plugin know about it.
      if (window->window)
.
      if (window->window)
        instance->SetWindow(window);
.
        instance->SetWindow(window);
 
.
 
      rv = NewFullPagePluginStream(aStreamListener, instance);
.
      rv = NewFullPagePluginStream(aStreamListener, instance);
 
.
 
      // If we've got a native window, the let the plugin know about it.
.
      // If we've got a native window, the let the plugin know about it.
      if (window->window)
.
      if (window->window)
        instance->SetWindow(window);
.
        instance->SetWindow(window);
 
.
 
      NS_RELEASE(instance);
.
      NS_RELEASE(instance);
    }
.
    }
  }
.
  }
 
.
 
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("Falling out of InstantiateFullPagePlugin...\n");
.
  printf("Falling out of InstantiateFullPagePlugin...\n");
#endif
.
#endif
  return rv;
.
  return rv;
}
.
}
 
.
 
nsresult nsPluginHostImpl::FindStoppedPluginForURL(nsIURI* aURL, 
.
nsresult nsPluginHostImpl::FindStoppedPluginForURL(nsIURI* aURL, 
                                                   nsIPluginInstanceOwner *aOw
ner)
.
                                                   nsIPluginInstanceOwner *aOw
ner)
{
.
{
  char* url;
.
  char* url;
  if(!aURL)
.
  if(!aURL)
  	return NS_ERROR_FAILURE;
.
  	return NS_ERROR_FAILURE;
  	
.
  	
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  printf("Inside nsPluginHostImpl::FindStoppedPluginForURL...\n");
.
  printf("Inside nsPluginHostImpl::FindStoppedPluginForURL...\n");
#endif
.
#endif
 
.
 
  (void)aURL->GetSpec(&url);
.
  (void)aURL->GetSpec(&url);
  
.
  
  nsActivePlugin * plugin = mActivePluginList.findStopped(url);
.
  nsActivePlugin * plugin = mActivePluginList.findStopped(url);
 
.
 
  if((plugin != nsnull) && (plugin->mStopped))
.
  if((plugin != nsnull) && (plugin->mStopped))
  {
.
  {
    nsIPluginInstance* instance = plugin->mInstance;
.
    nsIPluginInstance* instance = plugin->mInstance;
    nsPluginWindow    *window = nsnull;
.
    nsPluginWindow    *window = nsnull;
    aOwner->GetWindow(window);
.
    aOwner->GetWindow(window);
 
.
 
    aOwner->SetInstance(instance);
.
    aOwner->SetInstance(instance);
 
.
 
    // we have to reset the owner and instance in the plugin instance peer
.
    // we have to reset the owner and instance in the plugin instance peer
    //instance->GetPeer(&peer);
.
    //instance->GetPeer(&peer);
    ((nsPluginInstancePeerImpl*)plugin->mPeer)->SetOwner(aOwner);
.
    ((nsPluginInstancePeerImpl*)plugin->mPeer)->SetOwner(aOwner);
 
.
 
    instance->Start();
.
    instance->Start();
    aOwner->CreateWidget();
.
    aOwner->CreateWidget();
 
.
 
    // If we've got a native window, the let the plugin know about it.
.
    // If we've got a native window, the let the plugin know about it.
    if (window->window)
.
    if (window->window)
      instance->SetWindow(window);
.
      instance->SetWindow(window);
 
.
 
    plugin->setStopped(PR_FALSE);
.
    plugin->setStopped(PR_FALSE);
    nsCRT::free(url);
.
    nsCRT::free(url);
    return NS_OK;
.
    return NS_OK;
  }
.
  }
  nsCRT::free(url);
.
  nsCRT::free(url);
  return NS_ERROR_FAILURE;
.
  return NS_ERROR_FAILURE;
}
.
}
 
.
 
void nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
.
void nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
                                               nsIPluginInstance* aInstance,
.
                                               nsIPluginInstance* aInstance,
                                               nsIURI* aURL,
.
                                               nsIURI* aURL,
                                               PRBool aDefaultPlugin)
.
                                               PRBool aDefaultPlugin)
 
.
 
{
.
{
  char* url;
.
  char* url;
 
.
 
  if(!aURL)
.
  if(!aURL)
  	return;
.
  	return;
  	
.
  	
  (void)aURL->GetSpec(&url);
.
  (void)aURL->GetSpec(&url);
 
.
 
  // find corresponding plugin tag
.
  // find corresponding plugin tag
  // this is legal for xpcom plugins not to have nsIPlugin implemented
.
  // this is legal for xpcom plugins not to have nsIPlugin implemented
  nsPluginTag * pluginTag = nsnull;
.
  nsPluginTag * pluginTag = nsnull;
  if(aPlugin)
.
  if(aPlugin)
  {
.
  {
    for(pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNex
t)
.
    for(pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNex
t)
    {
.
    {
      if(pluginTag->mEntryPoint == aPlugin)
.
      if(pluginTag->mEntryPoint == aPlugin)
        break;
.
        break;
    }
.
    }
    NS_ASSERTION(pluginTag, "Plugin tag not found");
.
    NS_ASSERTION(pluginTag, "Plugin tag not found");
  }
.
  }
  else
.
  else
  {
.
  {
    // we don't need it for xpcom plugins because the only purpose to have it
.
    // we don't need it for xpcom plugins because the only purpose to have it
    // is to be able to postpone unloading library dll in some circumstances
.
    // is to be able to postpone unloading library dll in some circumstances
    // which we don't do for xpcom plugins. In case we need it in the future
.
    // which we don't do for xpcom plugins. In case we need it in the future
    // we can probably use the following
.
    // we can probably use the following
    /*
.
    /*
    FindPluginEnabledForType(mimetype, pluginTag);
.
    FindPluginEnabledForType(mimetype, pluginTag);
    */
.
    */
  }
.
  }
 
.
 
  nsActivePlugin * plugin = new nsActivePlugin(pluginTag, aInstance, url, aDef
aultPlugin);
.
  nsActivePlugin * plugin = new nsActivePlugin(pluginTag, aInstance, url, aDef
aultPlugin);
 
.
 
  if(plugin == nsnull)
.
  if(plugin == nsnull)
    return;
.
    return;
 
.
 
  mActivePluginList.add(plugin);
.
  mActivePluginList.add(plugin);
 
.
 
  nsCRT::free(url);
.
  nsCRT::free(url);
}
.
}
 
.
 
nsresult nsPluginHostImpl::RegisterPluginMimeTypesWithLayout(nsPluginTag * plu
ginTag, 
.
nsresult nsPluginHostImpl::RegisterPluginMimeTypesWithLayout(nsPluginTag * plu
ginTag, 
                                                             nsIComponentManag
er * compManager, 
.
                                                             nsIComponentManag
er * compManager, 
                                                             nsIFile * path)
.
                                                             nsIFile * path)
{
.
{
  NS_ENSURE_ARG_POINTER(pluginTag);
.
  NS_ENSURE_ARG_POINTER(pluginTag);
  NS_ENSURE_ARG_POINTER(pluginTag->mMimeTypeArray);
.
  NS_ENSURE_ARG_POINTER(pluginTag->mMimeTypeArray);
  NS_ENSURE_ARG_POINTER(compManager);
.
  NS_ENSURE_ARG_POINTER(compManager);
 
.
 
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  for(int i = 0; i < pluginTag->mVariants; i++)
.
  for(int i = 0; i < pluginTag->mVariants; i++)
  {
.
  {
    static NS_DEFINE_CID(kPluginDocLoaderFactoryCID, NS_PLUGINDOCLOADERFACTORY
_CID);
.
    static NS_DEFINE_CID(kPluginDocLoaderFactoryCID, NS_PLUGINDOCLOADERFACTORY
_CID);
 
.
 
    nsCAutoString contractid(NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "vie
w;1?type=");
.
    nsCAutoString contractid(NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "vie
w;1?type=");
    contractid += pluginTag->mMimeTypeArray[i];
.
    contractid += pluginTag->mMimeTypeArray[i];
 
.
 
    rv = compManager->RegisterComponentSpec(kPluginDocLoaderFactoryCID,
.
    rv = compManager->RegisterComponentSpec(kPluginDocLoaderFactoryCID,
                                            "Plugin Loader Stub",
.
                                            "Plugin Loader Stub",
                                            contractid.get(),
.
                                            contractid.get(),
                                            path,
.
                                            path,
                                            PR_TRUE,
.
                                            PR_TRUE,
                                            PR_FALSE);
.
                                            PR_FALSE);
  }
.
  }
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType, 
.
NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType, 
                                                    nsIURI *aURL,
.
                                                    nsIURI *aURL,
                                                    nsIPluginInstanceOwner *aO
wner)
.
                                                    nsIPluginInstanceOwner *aO
wner)
{
.
{
  nsresult result = NS_ERROR_FAILURE;
.
  nsresult result = NS_ERROR_FAILURE;
  nsIPluginInstance* instance = NULL;
.
  nsIPluginInstance* instance = NULL;
  nsCOMPtr<nsIPlugin> plugin;
.
  nsCOMPtr<nsIPlugin> plugin;
  const char* mimetype;
.
  const char* mimetype;
  nsString strContractID; strContractID.AssignWithConversion (NS_INLINE_PLUGIN
_CONTRACTID_PREFIX);
.
  nsString strContractID; strContractID.AssignWithConversion (NS_INLINE_PLUGIN
_CONTRACTID_PREFIX);
  char buf[255];  // todo: need to use a const
.
  char buf[255];  // todo: need to use a const
		
.
		
  if(!aURL)
.
  if(!aURL)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
	// if don't have a mimetype, check by file extension
.
	// if don't have a mimetype, check by file extension
  if(!aMimeType)
.
  if(!aMimeType)
  {
.
  {
    char* extension;
.
    char* extension;
 
.
 
    char* filename;
.
    char* filename;
    aURL->GetPath(&filename);
.
    aURL->GetPath(&filename);
    extension = PL_strrchr(filename, '.');
.
    extension = PL_strrchr(filename, '.');
    if(extension)
.
    if(extension)
      ++extension;
.
      ++extension;
    else
.
    else
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
 
.
 
    if(IsPluginEnabledForExtension(extension, mimetype) != NS_OK)
.
    if(IsPluginEnabledForExtension(extension, mimetype) != NS_OK)
    {
.
    {
      nsCRT::free(filename);
.
      nsCRT::free(filename);
      return NS_ERROR_FAILURE;
.
      return NS_ERROR_FAILURE;
    }
.
    }
    nsCRT::free(filename);
.
    nsCRT::free(filename);
	}
.
	}
  else
.
  else
    mimetype = aMimeType;
.
    mimetype = aMimeType;
 
.
 
    strContractID.AppendWithConversion(mimetype);
.
    strContractID.AppendWithConversion(mimetype);
    strContractID.ToCString(buf, 255);     // todo: need to use a const
.
    strContractID.ToCString(buf, 255);     // todo: need to use a const
 
.
 
    GetPluginFactory(mimetype, getter_AddRefs(plugin));
.
    GetPluginFactory(mimetype, getter_AddRefs(plugin));
 
.
 
    result = nsComponentManager::CreateInstance(buf,
.
    result = nsComponentManager::CreateInstance(buf,
                                                nsnull,
.
                                                nsnull,
                                                nsIPluginInstance::GetIID(),
.
                                                nsIPluginInstance::GetIID(),
                                                (void**)&instance);
.
                                                (void**)&instance);
 
.
 
 
.
 
    // couldn't create an XPCOM plugin, try to create wrapper for a legacy plu
gin
.
    // couldn't create an XPCOM plugin, try to create wrapper for a legacy plu
gin
    if (NS_FAILED(result)) 
.
    if (NS_FAILED(result)) 
    {
.
    {
      if(plugin)
.
      if(plugin)
        result = plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&i
nstance);
.
        result = plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&i
nstance);
 
.
 
      if (NS_FAILED(result)) 
.
      if (NS_FAILED(result)) 
      {
.
      {
        NS_WITH_SERVICE(nsIPlugin, bwPlugin, "@mozilla.org/blackwood/pluglet-e
ngine;1",&result);
.
        NS_WITH_SERVICE(nsIPlugin, bwPlugin, "@mozilla.org/blackwood/pluglet-e
ngine;1",&result);
        if (NS_SUCCEEDED(result)) 
.
        if (NS_SUCCEEDED(result)) 
        {
.
        {
          result = bwPlugin->CreatePluginInstance(NULL,
.
          result = bwPlugin->CreatePluginInstance(NULL,
                                                  kIPluginInstanceIID,
.
                                                  kIPluginInstanceIID,
                                                  aMimeType,
.
                                                  aMimeType,
                                                  (void **)&instance);
.
                                                  (void **)&instance);
        }
.
        }
      }
.
      }
    }
.
    }
 
.
 
    // neither an XPCOM or legacy plugin could be instantiated, 
.
    // neither an XPCOM or legacy plugin could be instantiated, 
    // so return the failure
.
    // so return the failure
    if (NS_FAILED(result))
.
    if (NS_FAILED(result))
      return result;
.
      return result;
 
.
 
    // it is adreffed here
.
    // it is adreffed here
    aOwner->SetInstance(instance);
.
    aOwner->SetInstance(instance);
 
.
 
    nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl();
.
    nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl();
    if(peer == nsnull)
.
    if(peer == nsnull)
      return NS_ERROR_OUT_OF_MEMORY;
.
      return NS_ERROR_OUT_OF_MEMORY;
 
.
 
    // set up the peer for the instance
.
    // set up the peer for the instance
    peer->Initialize(aOwner, mimetype);   
.
    peer->Initialize(aOwner, mimetype);   
 
.
 
    nsIPluginInstancePeer *pi;
.
    nsIPluginInstancePeer *pi;
 
.
 
    result = peer->QueryInterface(kIPluginInstancePeerIID, (void **)&pi);
.
    result = peer->QueryInterface(kIPluginInstancePeerIID, (void **)&pi);
 
.
 
    if(result != NS_OK)
.
    if(result != NS_OK)
      return result;
.
      return result;
 
.
 
    // tell the plugin instance to initialize itself and pass in the peer.
.
    // tell the plugin instance to initialize itself and pass in the peer.
    instance->Initialize(pi);  // this will not add a ref to the instance (or 
owner). MMP
.
    instance->Initialize(pi);  // this will not add a ref to the instance (or 
owner). MMP
 
.
 
    NS_RELEASE(pi);
.
    NS_RELEASE(pi);
 
.
 
    // we should addref here
.
    // we should addref here
    AddInstanceToActiveList(plugin, instance, aURL, PR_FALSE);
.
    AddInstanceToActiveList(plugin, instance, aURL, PR_FALSE);
 
.
 
    //release what was addreffed in Create(Plugin)Instance
.
    //release what was addreffed in Create(Plugin)Instance
    NS_RELEASE(instance);
.
    NS_RELEASE(instance);
 
.
 
    return NS_OK;
.
    return NS_OK;
}
.
}
 
.
 
nsresult nsPluginHostImpl::SetUpDefaultPluginInstance(const char *aMimeType, n
sIURI *aURL,
.
nsresult nsPluginHostImpl::SetUpDefaultPluginInstance(const char *aMimeType, n
sIURI *aURL,
                                                      nsIPluginInstanceOwner *
aOwner)
.
                                                      nsIPluginInstanceOwner *
aOwner)
{
.
{
  nsresult result = NS_ERROR_FAILURE;
.
  nsresult result = NS_ERROR_FAILURE;
  nsIPluginInstance* instance = NULL;
.
  nsIPluginInstance* instance = NULL;
  nsCOMPtr<nsIPlugin> plugin = NULL;
.
  nsCOMPtr<nsIPlugin> plugin = NULL;
  const char* mimetype;
.
  const char* mimetype;
  nsString strContractID; strContractID.AssignWithConversion (NS_INLINE_PLUGIN
_CONTRACTID_PREFIX);
.
  nsString strContractID; strContractID.AssignWithConversion (NS_INLINE_PLUGIN
_CONTRACTID_PREFIX);
  char buf[255];  // todo: need to use a const
.
  char buf[255];  // todo: need to use a const
		
.
		
  if(!aURL)
.
  if(!aURL)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  mimetype = aMimeType;
.
  mimetype = aMimeType;
 
.
 
  strContractID.AppendWithConversion("*");
.
  strContractID.AppendWithConversion("*");
  strContractID.ToCString(buf, 255);     // todo: need to use a const
.
  strContractID.ToCString(buf, 255);     // todo: need to use a const
  
.
  
  GetPluginFactory("*", getter_AddRefs(plugin));
.
  GetPluginFactory("*", getter_AddRefs(plugin));
 
.
 
  result = nsComponentManager::CreateInstance(buf, nsnull, nsIPluginInstance::
GetIID(), (void**)&instance);
.
  result = nsComponentManager::CreateInstance(buf, nsnull, nsIPluginInstance::
GetIID(), (void**)&instance);
 
.
 
  // couldn't create an XPCOM plugin, try to create wrapper for a legacy plugi
n
.
  // couldn't create an XPCOM plugin, try to create wrapper for a legacy plugi
n
  if (NS_FAILED(result)) 
.
  if (NS_FAILED(result)) 
  {
.
  {
    if(plugin)
.
    if(plugin)
      result = plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&ins
tance);
.
      result = plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&ins
tance);
  }
.
  }
 
.
 
  // neither an XPCOM or legacy plugin could be instantiated, so return the fa
ilure
.
  // neither an XPCOM or legacy plugin could be instantiated, so return the fa
ilure
  if(NS_FAILED(result))
.
  if(NS_FAILED(result))
    return result;
.
    return result;
 
.
 
  // it is adreffed here
.
  // it is adreffed here
  aOwner->SetInstance(instance);
.
  aOwner->SetInstance(instance);
 
.
 
  nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl();
.
  nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl();
  if(peer == nsnull)
.
  if(peer == nsnull)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
	// if we don't have a mimetype, check by file extension
.
	// if we don't have a mimetype, check by file extension
  nsXPIDLCString mt;
.
  nsXPIDLCString mt;
  if(mimetype == nsnull)
.
  if(mimetype == nsnull)
  {
.
  {
    nsresult res = NS_OK;
.
    nsresult res = NS_OK;
    nsCOMPtr<nsIURL> url = do_QueryInterface(aURL);
.
    nsCOMPtr<nsIURL> url = do_QueryInterface(aURL);
    if(url)
.
    if(url)
    {
.
    {
      nsXPIDLCString extension;
.
      nsXPIDLCString extension;
      url->GetFileExtension(getter_Copies(extension));
.
      url->GetFileExtension(getter_Copies(extension));
    
.
    
      if(extension)
.
      if(extension)
      {
.
      {
        nsCOMPtr<nsIMIMEService> ms (do_GetService(NS_MIMESERVICE_CONTRACTID, 
&res));
.
        nsCOMPtr<nsIMIMEService> ms (do_GetService(NS_MIMESERVICE_CONTRACTID, 
&res));
        if(NS_SUCCEEDED(res) && ms)
.
        if(NS_SUCCEEDED(res) && ms)
        {
.
        {
          res = ms->GetTypeFromExtension(extension, getter_Copies(mt));
.
          res = ms->GetTypeFromExtension(extension, getter_Copies(mt));
          if(NS_SUCCEEDED(res))
.
          if(NS_SUCCEEDED(res))
            mimetype = mt;
.
            mimetype = mt;
        }
.
        }
      }
.
      }
    }
.
    }
  }
.
  }
 
.
 
  // set up the peer for the instance
.
  // set up the peer for the instance
  peer->Initialize(aOwner, mimetype);   
.
  peer->Initialize(aOwner, mimetype);   
 
.
 
  nsIPluginInstancePeer *pi;
.
  nsIPluginInstancePeer *pi;
 
.
 
  result = peer->QueryInterface(kIPluginInstancePeerIID, (void **)&pi);
.
  result = peer->QueryInterface(kIPluginInstancePeerIID, (void **)&pi);
 
.
 
  if(result != NS_OK)
.
  if(result != NS_OK)
    return result;
.
    return result;
 
.
 
  // tell the plugin instance to initialize itself and pass in the peer.
.
  // tell the plugin instance to initialize itself and pass in the peer.
  instance->Initialize(pi);  // this will not add a ref to the instance (or ow
ner). MMP
.
  instance->Initialize(pi);  // this will not add a ref to the instance (or ow
ner). MMP
 
.
 
  NS_RELEASE(pi);
.
  NS_RELEASE(pi);
 
.
 
  // we should addref here
.
  // we should addref here
  AddInstanceToActiveList(plugin, instance, aURL, PR_TRUE);
.
  AddInstanceToActiveList(plugin, instance, aURL, PR_TRUE);
 
.
 
  //release what was addreffed in Create(Plugin)Instance
.
  //release what was addreffed in Create(Plugin)Instance
  NS_RELEASE(instance);
.
  NS_RELEASE(instance);
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginHostImpl::IsPluginEnabledForType(const char* aMimeType)
.
nsPluginHostImpl::IsPluginEnabledForType(const char* aMimeType)
{
.
{
  nsPluginTag *plugins = nsnull;
.
  nsPluginTag *plugins = nsnull;
  PRInt32     variants, cnt;
.
  PRInt32     variants, cnt;
 
.
 
  LoadPlugins();
.
  LoadPlugins();
 
.
 
  // if we have a mimetype passed in, search the mPlugins linked 
.
  // if we have a mimetype passed in, search the mPlugins linked 
  // list for a match
.
  // list for a match
  if (nsnull != aMimeType)
.
  if (nsnull != aMimeType)
  {
.
  {
    plugins = mPlugins;
.
    plugins = mPlugins;
 
.
 
    while (nsnull != plugins)
.
    while (nsnull != plugins)
    {
.
    {
      variants = plugins->mVariants;
.
      variants = plugins->mVariants;
 
.
 
      for (cnt = 0; cnt < variants; cnt++)
.
      for (cnt = 0; cnt < variants; cnt++)
        if (plugins->mMimeTypeArray[cnt] && (0 == strcmp(plugins->mMimeTypeArr
ay[cnt], aMimeType)))
.
        if (plugins->mMimeTypeArray[cnt] && (0 == strcmp(plugins->mMimeTypeArr
ay[cnt], aMimeType)))
          return NS_OK;
.
          return NS_OK;
 
.
 
      if (cnt < variants)
.
      if (cnt < variants)
        break;
.
        break;
 
.
 
      plugins = plugins->mNext;
.
      plugins = plugins->mNext;
    }
.
    }
  }
.
  }
 
.
 
  return NS_ERROR_FAILURE;
.
  return NS_ERROR_FAILURE;
}
.
}
 
.
 
// check comma delimetered extensions
.
// check comma delimetered extensions
static int CompareExtensions(const char *aExtensionList, const char *aExtensio
n)
.
static int CompareExtensions(const char *aExtensionList, const char *aExtensio
n)
{
.
{
  if((aExtensionList == nsnull) || (aExtension == nsnull))
.
  if((aExtensionList == nsnull) || (aExtension == nsnull))
    return -1;
.
    return -1;
 
.
 
  const char *pExt = aExtensionList;
.
  const char *pExt = aExtensionList;
  const char *pComma = strchr(pExt, ',');
.
  const char *pComma = strchr(pExt, ',');
 
.
 
  if(pComma == nsnull)
.
  if(pComma == nsnull)
    return strcmp(pExt, aExtension);
.
    return strcmp(pExt, aExtension);
 
.
 
  while(pComma != nsnull)
.
  while(pComma != nsnull)
  {
.
  {
    int length = pComma - pExt;
.
    int length = pComma - pExt;
    if(0 == strncmp(pExt, aExtension, length))
.
    if(0 == strncmp(pExt, aExtension, length))
      return 0;
.
      return 0;
 
.
 
    pComma++;
.
    pComma++;
    pExt = pComma;
.
    pExt = pComma;
    pComma = strchr(pExt, ',');
.
    pComma = strchr(pExt, ',');
  }
.
  }
 
.
 
  // the last one
.
  // the last one
  return strcmp(pExt, aExtension);
.
  return strcmp(pExt, aExtension);
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginHostImpl::IsPluginEnabledForExtension(const char* aExtension, 
.
nsPluginHostImpl::IsPluginEnabledForExtension(const char* aExtension, 
                                              const char* &aMimeType)
.
                                              const char* &aMimeType)
{
.
{
  nsPluginTag *plugins = nsnull;
.
  nsPluginTag *plugins = nsnull;
  PRInt32     variants, cnt;
.
  PRInt32     variants, cnt;
 
.
 
  LoadPlugins();
.
  LoadPlugins();
 
.
 
  // if we have a mimetype passed in, search the mPlugins linked 
.
  // if we have a mimetype passed in, search the mPlugins linked 
  // list for a match
.
  // list for a match
  if (nsnull != aExtension)
.
  if (nsnull != aExtension)
  {
.
  {
    plugins = mPlugins;
.
    plugins = mPlugins;
 
.
 
    while (nsnull != plugins)
.
    while (nsnull != plugins)
    {
.
    {
      variants = plugins->mVariants;
.
      variants = plugins->mVariants;
 
.
 
      for (cnt = 0; cnt < variants; cnt++)
.
      for (cnt = 0; cnt < variants; cnt++)
      {
.
      {
        //if (0 == strcmp(plugins->mExtensionsArray[cnt], aExtension))
.
        //if (0 == strcmp(plugins->mExtensionsArray[cnt], aExtension))
        // mExtensionsArray[cnt] could be not a single extension but 
.
        // mExtensionsArray[cnt] could be not a single extension but 
        // rather a list separated by commas
.
        // rather a list separated by commas
        if (0 == CompareExtensions(plugins->mExtensionsArray[cnt], aExtension)
)
.
        if (0 == CompareExtensions(plugins->mExtensionsArray[cnt], aExtension)
)
		    {
.
		    {
			    aMimeType = plugins->mMimeTypeArray[cnt];
.
			    aMimeType = plugins->mMimeTypeArray[cnt];
			    return NS_OK;
.
			    return NS_OK;
		    }
.
		    }
	    }	
.
	    }	
 
.
 
      if (cnt < variants)
.
      if (cnt < variants)
        break;
.
        break;
 
.
 
      plugins = plugins->mNext;
.
      plugins = plugins->mNext;
    }
.
    }
  }
.
  }
 
.
 
  return NS_ERROR_FAILURE;
.
  return NS_ERROR_FAILURE;
}
.
}
 
.
 
class DOMMimeTypeImpl : public nsIDOMMimeType {
.
class DOMMimeTypeImpl : public nsIDOMMimeType {
public:
.
public:
	NS_DECL_ISUPPORTS
.
	NS_DECL_ISUPPORTS
 
.
 
	DOMMimeTypeImpl(nsPluginTag* aPluginTag, PRUint32 aMimeTypeIndex)
.
	DOMMimeTypeImpl(nsPluginTag* aPluginTag, PRUint32 aMimeTypeIndex)
	{
.
	{
		NS_INIT_ISUPPORTS();
.
		NS_INIT_ISUPPORTS();
		mDescription.AssignWithConversion(aPluginTag->mMimeDescriptionArray[aMimeTyp
eIndex]);
.
		mDescription.AssignWithConversion(aPluginTag->mMimeDescriptionArray[aMimeTyp
eIndex]);
		mSuffixes.AssignWithConversion(aPluginTag->mExtensionsArray[aMimeTypeIndex])
;
.
		mSuffixes.AssignWithConversion(aPluginTag->mExtensionsArray[aMimeTypeIndex])
;
		mType.AssignWithConversion(aPluginTag->mMimeTypeArray[aMimeTypeIndex]);
.
		mType.AssignWithConversion(aPluginTag->mMimeTypeArray[aMimeTypeIndex]);
	}
.
	}
	
.
	
	virtual ~DOMMimeTypeImpl() {
.
	virtual ~DOMMimeTypeImpl() {
	}
.
	}
 
.
 
	NS_METHOD GetDescription(nsAWritableString& aDescription)
.
	NS_METHOD GetDescription(nsAWritableString& aDescription)
	{
.
	{
		aDescription.Assign(mDescription);
.
		aDescription.Assign(mDescription);
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD GetEnabledPlugin(nsIDOMPlugin** aEnabledPlugin)
.
	NS_METHOD GetEnabledPlugin(nsIDOMPlugin** aEnabledPlugin)
	{
.
	{
		// this has to be implemented by the DOM version.
.
		// this has to be implemented by the DOM version.
		*aEnabledPlugin = nsnull;
.
		*aEnabledPlugin = nsnull;
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD GetSuffixes(nsAWritableString& aSuffixes)
.
	NS_METHOD GetSuffixes(nsAWritableString& aSuffixes)
	{
.
	{
		aSuffixes.Assign(mSuffixes);
.
		aSuffixes.Assign(mSuffixes);
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD GetType(nsAWritableString& aType)
.
	NS_METHOD GetType(nsAWritableString& aType)
	{
.
	{
		aType.Assign(mType);
.
		aType.Assign(mType);
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
private:
.
private:
	nsString mDescription;
.
	nsString mDescription;
	nsString mSuffixes;
.
	nsString mSuffixes;
	nsString mType;
.
	nsString mType;
};
.
};
 
.
 
NS_IMPL_ISUPPORTS(DOMMimeTypeImpl, nsIDOMMimeType::GetIID());
.
NS_IMPL_ISUPPORTS(DOMMimeTypeImpl, nsIDOMMimeType::GetIID());
 
.
 
class DOMPluginImpl : public nsIDOMPlugin {
.
class DOMPluginImpl : public nsIDOMPlugin {
public:
.
public:
	NS_DECL_ISUPPORTS
.
	NS_DECL_ISUPPORTS
	
.
	
	DOMPluginImpl(nsPluginTag* aPluginTag) : mPluginTag(aPluginTag)
.
	DOMPluginImpl(nsPluginTag* aPluginTag) : mPluginTag(aPluginTag)
	{
.
	{
		NS_INIT_ISUPPORTS();
.
		NS_INIT_ISUPPORTS();
	}
.
	}
	
.
	
	virtual ~DOMPluginImpl() {
.
	virtual ~DOMPluginImpl() {
	}
.
	}
 
.
 
	NS_METHOD GetDescription(nsAWritableString& aDescription)
.
	NS_METHOD GetDescription(nsAWritableString& aDescription)
	{
.
	{
		aDescription.Assign(NS_ConvertASCIItoUCS2(mPluginTag.mDescription));
.
		aDescription.Assign(NS_ConvertASCIItoUCS2(mPluginTag.mDescription));
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD GetFilename(nsAWritableString& aFilename)
.
	NS_METHOD GetFilename(nsAWritableString& aFilename)
	{
.
	{
		aFilename.Assign(NS_ConvertASCIItoUCS2(mPluginTag.mFileName));
.
		aFilename.Assign(NS_ConvertASCIItoUCS2(mPluginTag.mFileName));
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD GetName(nsAWritableString& aName)
.
	NS_METHOD GetName(nsAWritableString& aName)
	{
.
	{
		aName.Assign(NS_ConvertASCIItoUCS2(mPluginTag.mName));
.
		aName.Assign(NS_ConvertASCIItoUCS2(mPluginTag.mName));
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD GetLength(PRUint32* aLength)
.
	NS_METHOD GetLength(PRUint32* aLength)
	{
.
	{
		*aLength = mPluginTag.mVariants;
.
		*aLength = mPluginTag.mVariants;
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD Item(PRUint32 aIndex, nsIDOMMimeType** aReturn)
.
	NS_METHOD Item(PRUint32 aIndex, nsIDOMMimeType** aReturn)
	{
.
	{
		nsIDOMMimeType* mimeType = new DOMMimeTypeImpl(&mPluginTag, aIndex);
.
		nsIDOMMimeType* mimeType = new DOMMimeTypeImpl(&mPluginTag, aIndex);
		NS_IF_ADDREF(mimeType);
.
		NS_IF_ADDREF(mimeType);
		*aReturn = mimeType;
.
		*aReturn = mimeType;
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
	NS_METHOD NamedItem(const nsAReadableString& aName, nsIDOMMimeType** aReturn)
.
	NS_METHOD NamedItem(const nsAReadableString& aName, nsIDOMMimeType** aReturn)
	{
.
	{
		for (int index = mPluginTag.mVariants - 1; index >= 0; --index) {
.
		for (int index = mPluginTag.mVariants - 1; index >= 0; --index) {
			if (aName.Equals(NS_ConvertASCIItoUCS2(mPluginTag.mMimeTypeArray[index])))
.
			if (aName.Equals(NS_ConvertASCIItoUCS2(mPluginTag.mMimeTypeArray[index])))
				return Item(index, aReturn);
.
				return Item(index, aReturn);
		}
.
		}
		return NS_OK;
.
		return NS_OK;
	}
.
	}
 
.
 
private:
.
private:
	nsPluginTag mPluginTag;
.
	nsPluginTag mPluginTag;
};
.
};
 
.
 
NS_IMPL_ISUPPORTS(DOMPluginImpl, nsIDOMPlugin::GetIID());
.
NS_IMPL_ISUPPORTS(DOMPluginImpl, nsIDOMPlugin::GetIID());
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginHostImpl::GetPluginCount(PRUint32* aPluginCount)
.
nsPluginHostImpl::GetPluginCount(PRUint32* aPluginCount)
{
.
{
  LoadPlugins();
.
  LoadPlugins();
 
.
 
  PRUint32 count = 0;
.
  PRUint32 count = 0;
 
.
 
  nsPluginTag* plugin = mPlugins;
.
  nsPluginTag* plugin = mPlugins;
  while (plugin != nsnull) {
.
  while (plugin != nsnull) {
    ++count;
.
    ++count;
    plugin = plugin->mNext;
.
    plugin = plugin->mNext;
  }
.
  }
 
.
 
  *aPluginCount = count;
.
  *aPluginCount = count;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginHostImpl::GetPlugins(PRUint32 aPluginCount, 
.
nsPluginHostImpl::GetPlugins(PRUint32 aPluginCount, 
                             nsIDOMPlugin* aPluginArray[])
.
                             nsIDOMPlugin* aPluginArray[])
{
.
{
  LoadPlugins();
.
  LoadPlugins();
  
.
  
  nsPluginTag* plugin = mPlugins;
.
  nsPluginTag* plugin = mPlugins;
  for (PRUint32 i = 0; i < aPluginCount && plugin != nsnull; 
.
  for (PRUint32 i = 0; i < aPluginCount && plugin != nsnull; 
       i++, plugin = plugin->mNext) {
.
       i++, plugin = plugin->mNext) {
    nsIDOMPlugin* domPlugin = new DOMPluginImpl(plugin);
.
    nsIDOMPlugin* domPlugin = new DOMPluginImpl(plugin);
    NS_IF_ADDREF(domPlugin);
.
    NS_IF_ADDREF(domPlugin);
    aPluginArray[i] = domPlugin;
.
    aPluginArray[i] = domPlugin;
  }
.
  }
  
.
  
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
nsresult
.
nsresult
nsPluginHostImpl::FindPluginEnabledForType(const char* aMimeType, 
.
nsPluginHostImpl::FindPluginEnabledForType(const char* aMimeType, 
                                           nsPluginTag* &aPlugin)
.
                                           nsPluginTag* &aPlugin)
{
.
{
  nsPluginTag *plugins = nsnull;
.
  nsPluginTag *plugins = nsnull;
  PRInt32     variants, cnt;
.
  PRInt32     variants, cnt;
  
.
  
  aPlugin = nsnull;
.
  aPlugin = nsnull;
  
.
  
  LoadPlugins();
.
  LoadPlugins();
  
.
  
  // if we have a mimetype passed in, search the mPlugins 
.
  // if we have a mimetype passed in, search the mPlugins 
  // linked list for a match
.
  // linked list for a match
  if (nsnull != aMimeType) {
.
  if (nsnull != aMimeType) {
    plugins = mPlugins;
.
    plugins = mPlugins;
    
.
    
    while (nsnull != plugins) {
.
    while (nsnull != plugins) {
      variants = plugins->mVariants;
.
      variants = plugins->mVariants;
      
.
      
      for (cnt = 0; cnt < variants; cnt++) {
.
      for (cnt = 0; cnt < variants; cnt++) {
        if (plugins->mMimeTypeArray[cnt] && (0 == strcmp(plugins->mMimeTypeArr
ay[cnt], aMimeType))) {
.
        if (plugins->mMimeTypeArray[cnt] && (0 == strcmp(plugins->mMimeTypeArr
ay[cnt], aMimeType))) {
          aPlugin = plugins;
.
          aPlugin = plugins;
          return NS_OK;
.
          return NS_OK;
        }
.
        }
      }
.
      }
 
.
 
      if (cnt < variants)
.
      if (cnt < variants)
        break;
.
        break;
    
.
    
      plugins = plugins->mNext;
.
      plugins = plugins->mNext;
    }
.
    }
  }
.
  }
 
.
 
  return NS_ERROR_FAILURE;
.
  return NS_ERROR_FAILURE;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlu
gin** aPlugin)
.
NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlu
gin** aPlugin)
{
.
{
  nsresult rv = NS_ERROR_FAILURE;
.
  nsresult rv = NS_ERROR_FAILURE;
  *aPlugin = NULL;
.
  *aPlugin = NULL;
 
.
 
  if(!aMimeType)
.
  if(!aMimeType)
    return NS_ERROR_ILLEGAL_VALUE;
.
    return NS_ERROR_ILLEGAL_VALUE;
 
.
 
  // unload any libs that can remain after plugins.refresh(1), see #61388
.
  // unload any libs that can remain after plugins.refresh(1), see #61388
  CleanUnusedLibraries();
.
  CleanUnusedLibraries();
 
.
 
  // If plugins haven't been scanned yet, do so now
.
  // If plugins haven't been scanned yet, do so now
  LoadPlugins();
.
  LoadPlugins();
 
.
 
  nsPluginTag* pluginTag;
.
  nsPluginTag* pluginTag;
  if((rv = FindPluginEnabledForType(aMimeType, pluginTag)) == NS_OK)
.
  if((rv = FindPluginEnabledForType(aMimeType, pluginTag)) == NS_OK)
  {
.
  {
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
    if(aMimeType && pluginTag->mFileName)
.
    if(aMimeType && pluginTag->mFileName)
      printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName);
.
      printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName);
#endif
.
#endif
 
.
 
    if (nsnull == pluginTag->mLibrary)		// if we haven't done this yet
.
    if (nsnull == pluginTag->mLibrary)		// if we haven't done this yet
    {
.
    {
      nsFileSpec file(pluginTag->mFileName);
.
      nsFileSpec file(pluginTag->mFileName);
 
.
 
      nsPluginFile pluginFile(file);
.
      nsPluginFile pluginFile(file);
      PRLibrary* pluginLibrary = NULL;
.
      PRLibrary* pluginLibrary = NULL;
 
.
 
      if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == NU
LL)
.
      if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == NU
LL)
	      return NS_ERROR_FAILURE;
.
	      return NS_ERROR_FAILURE;
 
.
 
      pluginTag->mLibrary = pluginLibrary;
.
      pluginTag->mLibrary = pluginLibrary;
    }
.
    }
 
.
 
    nsIPlugin* plugin = pluginTag->mEntryPoint;
.
    nsIPlugin* plugin = pluginTag->mEntryPoint;
    if(plugin == NULL)
.
    if(plugin == NULL)
    {
.
    {
      // nsIPlugin* of xpcom plugins can be found thru a call to
.
      // nsIPlugin* of xpcom plugins can be found thru a call to
      //  nsComponentManager::GetClassObject()
.
      //  nsComponentManager::GetClassObject()
      nsCID clsid;
.
      nsCID clsid;
      char buf[255];
.
      char buf[255];
      nsString strContractID; 
.
      nsString strContractID; 
      strContractID.AssignWithConversion (NS_INLINE_PLUGIN_CONTRACTID_PREFIX);
.
      strContractID.AssignWithConversion (NS_INLINE_PLUGIN_CONTRACTID_PREFIX);
      strContractID.AppendWithConversion(aMimeType);
.
      strContractID.AppendWithConversion(aMimeType);
      strContractID.ToCString(buf, 255);
.
      strContractID.ToCString(buf, 255);
      nsresult rv = nsComponentManager::ContractIDToClassID(buf, &clsid);
.
      nsresult rv = nsComponentManager::ContractIDToClassID(buf, &clsid);
      if (NS_SUCCEEDED(rv))
.
      if (NS_SUCCEEDED(rv))
      {
.
      {
        rv = nsComponentManager::GetClassObject(clsid, nsIPlugin::GetIID(), (v
oid**)&plugin);
.
        rv = nsComponentManager::GetClassObject(clsid, nsIPlugin::GetIID(), (v
oid**)&plugin);
        if (NS_SUCCEEDED(rv) && plugin)
.
        if (NS_SUCCEEDED(rv) && plugin)
        {
.
        {
          // plugin was addref'd by nsComponentManager::GetClassObject
.
          // plugin was addref'd by nsComponentManager::GetClassObject
          pluginTag->mEntryPoint = plugin;
.
          pluginTag->mEntryPoint = plugin;
          plugin->Initialize();
.
          plugin->Initialize();
        }
.
        }
      }
.
      }
    }
.
    }
 
.
 
    if (plugin == NULL)
.
    if (plugin == NULL)
    {
.
    {
      // No, this is not a leak. GetGlobalServiceManager() doesn't
.
      // No, this is not a leak. GetGlobalServiceManager() doesn't
      // addref the pointer on the way out. It probably should.
.
      // addref the pointer on the way out. It probably should.
      nsIServiceManager* serviceManager;
.
      nsIServiceManager* serviceManager;
      nsServiceManager::GetGlobalServiceManager(&serviceManager);
.
      nsServiceManager::GetGlobalServiceManager(&serviceManager);
 
.
 
      // need to get the plugin factory from this plugin.
.
      // need to get the plugin factory from this plugin.
      nsFactoryProc nsGetFactory = nsnull;
.
      nsFactoryProc nsGetFactory = nsnull;
      nsGetFactory = (nsFactoryProc) PR_FindSymbol(pluginTag->mLibrary, "NSGet
Factory");
.
      nsGetFactory = (nsFactoryProc) PR_FindSymbol(pluginTag->mLibrary, "NSGet
Factory");
      if(nsGetFactory != nsnull)
.
      if(nsGetFactory != nsnull)
      {
.
      {
        rv = nsGetFactory(serviceManager, kPluginCID, nsnull, nsnull,    // XX
X fix ClassName/ContractID
.
        rv = nsGetFactory(serviceManager, kPluginCID, nsnull, nsnull,    // XX
X fix ClassName/ContractID
                          (nsIFactory**)&pluginTag->mEntryPoint);
.
                          (nsIFactory**)&pluginTag->mEntryPoint);
        plugin = pluginTag->mEntryPoint;
.
        plugin = pluginTag->mEntryPoint;
        if (plugin != NULL)
.
        if (plugin != NULL)
          plugin->Initialize();
.
          plugin->Initialize();
      }
.
      }
      else
.
      else
      {
.
      {
#if defined(XP_MAC) && TARGET_CARBON
.
#if defined(XP_MAC) && TARGET_CARBON
        // should we also look for a 'carb' resource?
.
        // should we also look for a 'carb' resource?
        if (PR_FindSymbol(pluginTag->mLibrary, "mainRD") != NULL) 
.
        if (PR_FindSymbol(pluginTag->mLibrary, "mainRD") != NULL) 
        {
.
        {
          NS_WITH_SERVICE(nsIClassicPluginFactory, factory, NS_CLASSIC_PLUGIN_
FACTORY_CONTRACTID, &rv);
.
          NS_WITH_SERVICE(nsIClassicPluginFactory, factory, NS_CLASSIC_PLUGIN_
FACTORY_CONTRACTID, &rv);
          if (NS_SUCCEEDED(rv)) 
.
          if (NS_SUCCEEDED(rv)) 
            rv = factory->CreatePlugin(serviceManager, 
.
            rv = factory->CreatePlugin(serviceManager, 
                                       pluginTag->mFileName, 
.
                                       pluginTag->mFileName, 
                                       pluginTag->mLibrary, 
.
                                       pluginTag->mLibrary, 
                                       &pluginTag->mEntryPoint);
.
                                       &pluginTag->mEntryPoint);
        } 
.
        } 
        else
.
        else
#endif
.
#endif
          rv = ns4xPlugin::CreatePlugin(serviceManager,
.
          rv = ns4xPlugin::CreatePlugin(serviceManager,
                                        pluginTag->mFileName,
.
                                        pluginTag->mFileName,
                                        pluginTag->mLibrary,
.
                                        pluginTag->mLibrary,
                                        &pluginTag->mEntryPoint);
.
                                        &pluginTag->mEntryPoint);
 
.
 
        plugin = pluginTag->mEntryPoint;
.
        plugin = pluginTag->mEntryPoint;
        pluginTag->mFlags |= NS_PLUGIN_FLAG_OLDSCHOOL;
.
        pluginTag->mFlags |= NS_PLUGIN_FLAG_OLDSCHOOL;
        // no need to initialize, already done by CreatePlugin()
.
        // no need to initialize, already done by CreatePlugin()
      }
.
      }
    }
.
    }
 
.
 
    if (plugin != nsnull)
.
    if (plugin != nsnull)
    {
.
    {
      *aPlugin = plugin;
.
      *aPlugin = plugin;
      plugin->AddRef();
.
      plugin->AddRef();
      return NS_OK;
.
      return NS_OK;
    }
.
    }
  }
.
  }
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
static PRBool areTheSameFileNames(char * aPath1, char * aPath2)
.
static PRBool areTheSameFileNames(char * aPath1, char * aPath2)
{
.
{
  if((aPath1 == nsnull) || (aPath2 == nsnull))
.
  if((aPath1 == nsnull) || (aPath2 == nsnull))
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  nsXPIDLCString filename1;
.
  nsXPIDLCString filename1;
  nsXPIDLCString filename2;
.
  nsXPIDLCString filename2;
 
.
 
  nsCOMPtr<nsILocalFile> file1;
.
  nsCOMPtr<nsILocalFile> file1;
  nsCOMPtr<nsILocalFile> file2;
.
  nsCOMPtr<nsILocalFile> file2;
 
.
 
  rv = NS_NewLocalFile(aPath1, PR_FALSE, getter_AddRefs(file1));
.
  rv = NS_NewLocalFile(aPath1, PR_FALSE, getter_AddRefs(file1));
  if(NS_FAILED(rv))
.
  if(NS_FAILED(rv))
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  rv = NS_NewLocalFile(aPath2, PR_FALSE, getter_AddRefs(file2));
.
  rv = NS_NewLocalFile(aPath2, PR_FALSE, getter_AddRefs(file2));
  if(NS_FAILED(rv))
.
  if(NS_FAILED(rv))
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  file1->GetLeafName(getter_Copies(filename1));
.
  file1->GetLeafName(getter_Copies(filename1));
  file2->GetLeafName(getter_Copies(filename2));
.
  file2->GetLeafName(getter_Copies(filename2));
  
.
  
  if(PL_strlen(filename1.get()) != PL_strlen(filename2.get()))
.
  if(PL_strlen(filename1.get()) != PL_strlen(filename2.get()))
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  // XXX this one MUST be case insensitive for Windows and MUST be case 
.
  // XXX this one MUST be case insensitive for Windows and MUST be case 
  // sensitive for Unix. How about Win2000?
.
  // sensitive for Unix. How about Win2000?
  return (nsnull == PL_strncasecmp(filename1.get(), filename2.get(), PL_strlen
(filename1.get())));
.
  return (nsnull == PL_strncasecmp(filename1.get(), filename2.get(), PL_strlen
(filename1.get())));
}
.
}
 
.
 
static PRBool isJavaPlugin(nsPluginTag * tag)
.
static PRBool isJavaPlugin(nsPluginTag * tag)
{
.
{
  if(tag->mFileName == nsnull)
.
  if(tag->mFileName == nsnull)
    return PR_FALSE;
.
    return PR_FALSE;
 
.
 
  char * filename = PL_strrchr(tag->mFileName, '\\');
.
  char * filename = PL_strrchr(tag->mFileName, '\\');
 
.
 
  if(filename != nsnull)
.
  if(filename != nsnull)
		filename++;
.
		filename++;
	else
.
	else
		filename = tag->mFileName;
.
		filename = tag->mFileName;
 
.
 
  return (nsnull == PL_strncasecmp(filename, "npjava", 6));
.
  return (nsnull == PL_strncasecmp(filename, "npjava", 6));
}
.
}
 
.
 
// currently 'unwanted' plugins are Java, and all other plugins except
.
// currently 'unwanted' plugins are Java, and all other plugins except
// RealPlayer, Acrobat, Flash
.
// RealPlayer, Acrobat, Flash
static PRBool isUnwantedPlugin(nsPluginTag * tag)
.
static PRBool isUnwantedPlugin(nsPluginTag * tag)
{
.
{
  if(tag->mFileName == nsnull)
.
  if(tag->mFileName == nsnull)
    return PR_TRUE;
.
    return PR_TRUE;
 
.
 
  for (PRInt32 i = 0; i < tag->mVariants; ++i) {
.
  for (PRInt32 i = 0; i < tag->mVariants; ++i) {
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "audio/x-pn-realaudio-p
lugin"))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "audio/x-pn-realaudio-p
lugin"))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "application/pdf"))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "application/pdf"))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "application/x-shockwav
e-flash"))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i], "application/x-shockwav
e-flash"))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"application/x-director"
))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"application/x-director"
))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
    // these are Quicktime-only types so that wav and midi will register indir
ectly
.
    // these are Quicktime-only types so that wav and midi will register indir
ectly
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"image/x-quicktime"))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"image/x-quicktime"))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"image/x-macpaint"))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"image/x-macpaint"))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"video/quicktime"))
.
    if(nsnull == PL_strcasecmp(tag->mMimeTypeArray[i],"video/quicktime"))
      return PR_FALSE;
.
      return PR_FALSE;
 
.
 
  }
.
  }
 
.
 
  return PR_TRUE;
.
  return PR_TRUE;
}
.
}
 
.
 
nsresult nsPluginHostImpl::ScanPluginsDirectory(nsPluginsDir& pluginsDir, 
.
nsresult nsPluginHostImpl::ScanPluginsDirectory(nsPluginsDir& pluginsDir, 
                                                nsIComponentManager * compMana
ger, 
.
                                                nsIComponentManager * compMana
ger, 
                                                nsIFile * layoutPath,
.
                                                nsIFile * layoutPath,
                                                PRBool checkForUnwantedPlugins
)
.
                                                PRBool checkForUnwantedPlugins
)
{
.
{
  for (nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++) 
.
  for (nsDirectoryIterator iter(pluginsDir, PR_TRUE); iter.Exists(); iter++) 
  {
.
  {
		const nsFileSpec& file = iter;
.
		const nsFileSpec& file = iter;
		if (pluginsDir.IsPluginFile(file)) 
.
		if (pluginsDir.IsPluginFile(file)) 
    {
.
    {
			nsPluginFile pluginFile(file);
.
			nsPluginFile pluginFile(file);
			PRLibrary* pluginLibrary = nsnull;
.
			PRLibrary* pluginLibrary = nsnull;
 
.
 
      // load the plugin's library so we can ask it some questions, but not fo
r Windows
.
      // load the plugin's library so we can ask it some questions, but not fo
r Windows
#ifndef XP_WIN
.
#ifndef XP_WIN
      if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == ns
null)
.
      if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == ns
null)
        continue;
.
        continue;
#endif
.
#endif
 
.
 
      // create a tag describing this plugin.
.
      // create a tag describing this plugin.
      nsPluginInfo info = { sizeof(info) };
.
      nsPluginInfo info = { sizeof(info) };
      nsresult res = pluginFile.GetPluginInfo(info);
.
      nsresult res = pluginFile.GetPluginInfo(info);
      if(NS_FAILED(res))
.
      if(NS_FAILED(res))
        continue;
.
        continue;
 
.
 
      nsPluginTag* pluginTag = new nsPluginTag(&info);
.
      nsPluginTag* pluginTag = new nsPluginTag(&info);
      pluginFile.FreePluginInfo(info);
.
      pluginFile.FreePluginInfo(info);
 
.
 
      if(pluginTag == nsnull)
.
      if(pluginTag == nsnull)
        return NS_ERROR_OUT_OF_MEMORY;
.
        return NS_ERROR_OUT_OF_MEMORY;
 
.
 
      pluginTag->mLibrary = pluginLibrary;
.
      pluginTag->mLibrary = pluginLibrary;
 
.
 
      PRBool bAddIt = PR_TRUE;
.
      PRBool bAddIt = PR_TRUE;
 
.
 
      // check if there are specific plugins we don't want
.
      // check if there are specific plugins we don't want
      if(checkForUnwantedPlugins)
.
      if(checkForUnwantedPlugins)
      {
.
      {
        if(isUnwantedPlugin(pluginTag))
.
        if(isUnwantedPlugin(pluginTag))
          bAddIt = PR_FALSE;
.
          bAddIt = PR_FALSE;
      }
.
      }
 
.
 
      // check if we already have this plugin in the list which
.
      // check if we already have this plugin in the list which
      // is possible if we do refresh
.
      // is possible if we do refresh
      if(bAddIt)
.
      if(bAddIt)
      {
.
      {
        for(nsPluginTag* tag = mPlugins; tag != nsnull; tag = tag->mNext)
.
        for(nsPluginTag* tag = mPlugins; tag != nsnull; tag = tag->mNext)
        {
.
        {
          if(areTheSameFileNames(tag->mFileName, pluginTag->mFileName))
.
          if(areTheSameFileNames(tag->mFileName, pluginTag->mFileName))
          {
.
          {
            bAddIt = PR_FALSE;
.
            bAddIt = PR_FALSE;
            break;
.
            break;
          }
.
          }
        }
.
        }
      }
.
      }
 
.
 
      // so if we still want it -- do it
.
      // so if we still want it -- do it
      if(bAddIt)
.
      if(bAddIt)
      {
.
      {
        pluginTag->mNext = mPlugins;
.
        pluginTag->mNext = mPlugins;
			  mPlugins = pluginTag;
.
			  mPlugins = pluginTag;
 
.
 
        if(layoutPath)
.
        if(layoutPath)
          RegisterPluginMimeTypesWithLayout(pluginTag, compManager, layoutPath
);
.
          RegisterPluginMimeTypesWithLayout(pluginTag, compManager, layoutPath
);
      }
.
      }
      else
.
      else
        delete pluginTag;
.
        delete pluginTag;
		}
.
		}
	}
.
	}
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
.
NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
{
.
{
  // do not do anything if it is already done
.
  // do not do anything if it is already done
  // use nsPluginHostImpl::ReloadPlugins to enforce loading
.
  // use nsPluginHostImpl::ReloadPlugins to enforce loading
  if(mPluginsLoaded)
.
  if(mPluginsLoaded)
    return NS_OK;
.
    return NS_OK;
 
.
 
  // retrieve a path for layout module. Needed for plugin mime types registrat
ion
.
  // retrieve a path for layout module. Needed for plugin mime types registrat
ion
  nsCOMPtr<nsIFile> path;
.
  nsCOMPtr<nsIFile> path;
  PRBool isLayoutPath = PR_FALSE;
.
  PRBool isLayoutPath = PR_FALSE;
  nsresult rv;
.
  nsresult rv;
  nsCOMPtr<nsIComponentManager> compManager = do_GetService(kComponentManagerC
ID, &rv);
.
  nsCOMPtr<nsIComponentManager> compManager = do_GetService(kComponentManagerC
ID, &rv);
  if (NS_SUCCEEDED(rv) && compManager) 
.
  if (NS_SUCCEEDED(rv) && compManager) 
  {
.
  {
    isLayoutPath = NS_SUCCEEDED(compManager->SpecForRegistryLocation(REL_PLUGI
N_DLL, getter_AddRefs(path)));
.
    isLayoutPath = NS_SUCCEEDED(compManager->SpecForRegistryLocation(REL_PLUGI
N_DLL, getter_AddRefs(path)));
    rv = LoadXPCOMPlugins(compManager, path);
.
    rv = LoadXPCOMPlugins(compManager, path);
  }
.
  }
 
.
 
	// scan the 4x plugins directory for eligible legacy plugin libraries
.
	// scan the 4x plugins directory for eligible legacy plugin libraries
 
.
 
#ifndef XP_WIN // old plugin finding logic
.
#ifndef XP_WIN // old plugin finding logic
 
.
 
  // scan Mozilla plugins dir
.
  // scan Mozilla plugins dir
  nsPluginsDir pluginsDir;
.
  nsPluginsDir pluginsDir;
 
.
 
  if (pluginsDir.Valid())
.
  if (pluginsDir.Valid())
  {
.
  {
    nsCOMPtr<nsIFile> lpath = nsnull;
.
    nsCOMPtr<nsIFile> lpath = nsnull;
    if(isLayoutPath)
.
    if(isLayoutPath)
      lpath = path;
.
      lpath = path;
 
.
 
    ScanPluginsDirectory(pluginsDir, compManager, lpath);
.
    ScanPluginsDirectory(pluginsDir, compManager, lpath);
  }
.
  }
 
.
 
#ifdef XP_MAC
.
#ifdef XP_MAC
  // try to scan old-spelled plugins dir ("Plug-ins") for Mac
.
  // try to scan old-spelled plugins dir ("Plug-ins") for Mac
  // should we check for duplicate plugins here? We probably should.
.
  // should we check for duplicate plugins here? We probably should.
  nsPluginsDir pluginsDirMacOld(PLUGINS_DIR_LOCATION_MAC_OLD);
.
  nsPluginsDir pluginsDirMacOld(PLUGINS_DIR_LOCATION_MAC_OLD);
	
.
	
  if (pluginsDirMacOld.Valid())
.
  if (pluginsDirMacOld.Valid())
  {
.
  {
    nsCOMPtr<nsIFile> lpath = nsnull;
.
    nsCOMPtr<nsIFile> lpath = nsnull;
    if(isLayoutPath)
.
    if(isLayoutPath)
      lpath = path;
.
      lpath = path;
 
.
 
    ScanPluginsDirectory(pluginsDirMacOld, 
.
    ScanPluginsDirectory(pluginsDirMacOld, 
                         compManager, 
.
                         compManager, 
                         lpath, 
.
                         lpath, 
                         PR_FALSE); // don't check for specific plugins
.
                         PR_FALSE); // don't check for specific plugins
  }
.
  }
#endif // XP_MAC
.
#endif // XP_MAC
 
.
 
#else //  XP_WIN go for new plugin finding logic on Windows
.
#else //  XP_WIN go for new plugin finding logic on Windows
 
.
 
  // currently we decided to look in both local plugins dir and 
.
  // currently we decided to look in both local plugins dir and 
  // that of the previous 4.x installation combining plugins from both places.
.
  // that of the previous 4.x installation combining plugins from both places.
  // See bug #21938
.
  // See bug #21938
  // As of 1.27.00 this selective mechanism is natively supported in Windows 
.
  // As of 1.27.00 this selective mechanism is natively supported in Windows 
  // native implementation of nsPluginsDir.
.
  // native implementation of nsPluginsDir.
 
.
 
  // first, make a list from MOZ_LOCAL installation
.
  // first, make a list from MOZ_LOCAL installation
  nsPluginsDir pluginsDirMoz(PLUGINS_DIR_LOCATION_MOZ_LOCAL);
.
  nsPluginsDir pluginsDirMoz(PLUGINS_DIR_LOCATION_MOZ_LOCAL);
 
.
 
  if (pluginsDirMoz.Valid())
.
  if (pluginsDirMoz.Valid())
  {
.
  {
    nsCOMPtr<nsIFile> lpath = nsnull;
.
    nsCOMPtr<nsIFile> lpath = nsnull;
    if(isLayoutPath)
.
    if(isLayoutPath)
      lpath = path;
.
      lpath = path;
 
.
 
    ScanPluginsDirectory(pluginsDirMoz, compManager, lpath);
.
    ScanPluginsDirectory(pluginsDirMoz, compManager, lpath);
  }
.
  }
 
.
 
  // now check the 4.x plugins dir and add new files
.
  // now check the 4.x plugins dir and add new files
  // Specifying the last two params as PR_TRUE we make sure that:
.
  // Specifying the last two params as PR_TRUE we make sure that:
  //   1. we search for a match in the list of MOZ_LOCAL plugins, ignore if fo
und, 
.
  //   1. we search for a match in the list of MOZ_LOCAL plugins, ignore if fo
und, 
  //      add if not found (check for dups)
.
  //      add if not found (check for dups)
  //   2. we ignore 4.x Java plugins no matter what and other 
.
  //   2. we ignore 4.x Java plugins no matter what and other 
  //      unwanted plugins as per temporary decision described in bug #23856
.
  //      unwanted plugins as per temporary decision described in bug #23856
 	nsPluginsDir pluginsDir4x(PLUGINS_DIR_LOCATION_4DOTX);
.
 	nsPluginsDir pluginsDir4x(PLUGINS_DIR_LOCATION_4DOTX);
	if (pluginsDir4x.Valid())
.
	if (pluginsDir4x.Valid())
  {
.
  {
    nsCOMPtr<nsIFile> lpath = nsnull;
.
    nsCOMPtr<nsIFile> lpath = nsnull;
    if(isLayoutPath)
.
    if(isLayoutPath)
      lpath = path;
.
      lpath = path;
 
.
 
    ScanPluginsDirectory(pluginsDir4x, 
.
    ScanPluginsDirectory(pluginsDir4x, 
                         compManager, 
.
                         compManager, 
                         lpath, 
.
                         lpath, 
                         PR_TRUE);  // check for specific plugins
.
                         PR_TRUE);  // check for specific plugins
  }
.
  }
#endif
.
#endif
 
.
 
  mPluginsLoaded = PR_TRUE; // at this point 'some' plugins have been loaded,
.
  mPluginsLoaded = PR_TRUE; // at this point 'some' plugins have been loaded,
                            // the rest is optional
.
                            // the rest is optional
 
.
 
#ifdef XP_WIN
.
#ifdef XP_WIN
  // Checks the installation path of Sun's JRE in scanning for plugins if the 
prefs are enabled
.
  // Checks the installation path of Sun's JRE in scanning for plugins if the 
prefs are enabled
 
.
 
  nsCOMPtr<nsIPref> theprefs = do_GetService(NS_PREF_CONTRACTID);
.
  nsCOMPtr<nsIPref> theprefs = do_GetService(NS_PREF_CONTRACTID);
  if (theprefs)     // we got the pref service
.
  if (theprefs)     // we got the pref service
  {
.
  {
    PRBool javaEnabled = PR_FALSE;         // don't bother the scan if java is
 OFF
.
    PRBool javaEnabled = PR_FALSE;         // don't bother the scan if java is
 OFF
    PRBool doJREPluginScan = PR_FALSE;
.
    PRBool doJREPluginScan = PR_FALSE;
    
.
    
    if (NS_SUCCEEDED(theprefs->GetBoolPref("security.enable_java",&javaEnabled
)) &&
.
    if (NS_SUCCEEDED(theprefs->GetBoolPref("security.enable_java",&javaEnabled
)) &&
        NS_SUCCEEDED(theprefs->GetBoolPref("plugin.do_JRE_Plugin_Scan",&doJREP
luginScan)) &&
.
        NS_SUCCEEDED(theprefs->GetBoolPref("plugin.do_JRE_Plugin_Scan",&doJREP
luginScan)) &&
        javaEnabled && doJREPluginScan)
.
        javaEnabled && doJREPluginScan)
    {
.
    {
      nsPluginsDir pluginsDirJavaJRE(PLUGINS_DIR_LOCATION_JAVA_JRE);
.
      nsPluginsDir pluginsDirJavaJRE(PLUGINS_DIR_LOCATION_JAVA_JRE);
 
.
 
      if (pluginsDirJavaJRE.Valid())
.
      if (pluginsDirJavaJRE.Valid())
      {
.
      {
        nsCOMPtr<nsIFile> lpath = nsnull;
.
        nsCOMPtr<nsIFile> lpath = nsnull;
        if(isLayoutPath)
.
        if(isLayoutPath)
          lpath = path;
.
          lpath = path;
        ScanPluginsDirectory(pluginsDirJavaJRE, compManager, lpath);
.
        ScanPluginsDirectory(pluginsDirJavaJRE, compManager, lpath);
      }
.
      }
    }
.
    }
  }
.
  }
  
.
  
  
.
  
  // Check the windows registry for extra paths to scan for plugins
.
  // Check the windows registry for extra paths to scan for plugins
  //
.
  //
  // We are going to get this registry key location from the pref:
.
  // We are going to get this registry key location from the pref:
  //    browser.plugins.registry_plugins_folder_key_location
.
  //    browser.plugins.registry_plugins_folder_key_location
  // The key name is "Plugins Folders"
.
  // The key name is "Plugins Folders"
  //
.
  //
  // So, for example, in winprefs.js put in this line:
.
  // So, for example, in winprefs.js put in this line:
  // pref ("browser.plugins.registry_plugins_folder_key_location","Software\\M
ozilla\\Common");
.
  // pref ("browser.plugins.registry_plugins_folder_key_location","Software\\M
ozilla\\Common");
  // Then, in HKEY_LOCAL_MACHINE\Software\Mozilla\Common
.
  // Then, in HKEY_LOCAL_MACHINE\Software\Mozilla\Common
  // Make a string key "Plugins Folder" who's value is a list of paths sperate
d by semi-colons
.
  // Make a string key "Plugins Folder" who's value is a list of paths sperate
d by semi-colons
 
.
 
  nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
.
  nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
  if (!prefs) return NS_OK;     // if we can't get to the prefs, bail
.
  if (!prefs) return NS_OK;     // if we can't get to the prefs, bail
  
.
  
  char * regkey;
.
  char * regkey;
  rv = prefs->CopyCharPref(_NS_PREF_COMMON_PLUGIN_REG_KEY_,®key);
.
  rv = prefs->CopyCharPref(_NS_PREF_COMMON_PLUGIN_REG_KEY_,®key);
  if (!NS_SUCCEEDED(rv) || regkey == nsnull) return NS_OK; //if pref isn't set
, bail
.
  if (!NS_SUCCEEDED(rv) || regkey == nsnull) return NS_OK; //if pref isn't set
, bail
  
.
  
  unsigned char valbuf[_MAXKEYVALUE_];
.
  unsigned char valbuf[_MAXKEYVALUE_];
  char* pluginPath;
.
  char* pluginPath;
  HKEY  newkey;
.
  HKEY  newkey;
  LONG  result;
.
  LONG  result;
  DWORD type   = REG_SZ;
.
  DWORD type   = REG_SZ;
  DWORD length = _MAXKEYVALUE_;
.
  DWORD length = _MAXKEYVALUE_;
 
.
 
  // set up layout path (if not done above)
.
  // set up layout path (if not done above)
  nsCOMPtr<nsIFile> lpath = nsnull;
.
  nsCOMPtr<nsIFile> lpath = nsnull;
  if(isLayoutPath)
.
  if(isLayoutPath)
    lpath = path;
.
    lpath = path;
 
.
 
  result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, regkey, NULL, KEY_QUERY_VALUE, &n
ewkey );
.
  result = RegOpenKeyEx( HKEY_LOCAL_MACHINE, regkey, NULL, KEY_QUERY_VALUE, &n
ewkey );
  
.
  
  if ( ERROR_SUCCESS == result ) {
.
  if ( ERROR_SUCCESS == result ) {
      result = RegQueryValueEx( newkey, _NS_COMMON_PLUGIN_KEY_NAME_, nsnull, &
type, valbuf, &length );
.
      result = RegQueryValueEx( newkey, _NS_COMMON_PLUGIN_KEY_NAME_, nsnull, &
type, valbuf, &length );
      RegCloseKey( newkey );
.
      RegCloseKey( newkey );
      if ( ERROR_SUCCESS == result ) {
.
      if ( ERROR_SUCCESS == result ) {
          // tokenize reg key value by semi-colons
.
          // tokenize reg key value by semi-colons
        for ( pluginPath = strtok((char *)&valbuf, ";"); pluginPath; pluginPat
h = strtok(NULL, ";") ) {
.
        for ( pluginPath = strtok((char *)&valbuf, ";"); pluginPath; pluginPat
h = strtok(NULL, ";") ) {
          nsFileSpec winRegPluginPath (pluginPath);
.
          nsFileSpec winRegPluginPath (pluginPath);
          if (winRegPluginPath.Exists()) {     // check for validity of path f
irst
.
          if (winRegPluginPath.Exists()) {     // check for validity of path f
irst
#ifdef DEBUG
.
#ifdef DEBUG
printf("found some more plugins at: %s\n", pluginPath);
.
printf("found some more plugins at: %s\n", pluginPath);
#endif
.
#endif
              ScanPluginsDirectory( (nsPluginsDir)winRegPluginPath,
.
              ScanPluginsDirectory( (nsPluginsDir)winRegPluginPath,
                                                  compManager,
.
                                                  compManager,
                                                  lpath,
.
                                                  lpath,
                                                  PR_FALSE);  // check for eve
n unwanted plugins                                                  
.
                                                  PR_FALSE);  // check for eve
n unwanted plugins                                                  
            } 
.
            } 
         }  
.
         }  
      }      
.
      }      
  }
.
  }
  free (regkey);  // clean up
.
  free (regkey);  // clean up
 
.
 
#endif // !XP_WIN
.
#endif // !XP_WIN
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
static nsresult
.
static nsresult
LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
.
LoadXPCOMPlugin(nsIComponentManager* aComponentManager,
                nsIRegistry* aRegistry,
.
                nsIRegistry* aRegistry,
                const char* aCID,
.
                const char* aCID,
                nsRegistryKey aPluginKey,
.
                nsRegistryKey aPluginKey,
                nsPluginTag** aResult)
.
                nsPluginTag** aResult)
{
.
{
  nsresult rv;
.
  nsresult rv;
 
.
 
  // The name, description, MIME types, MIME descriptions, and
.
  // The name, description, MIME types, MIME descriptions, and
  // supported file extensions will all hang off of the plugin's key
.
  // supported file extensions will all hang off of the plugin's key
  // in the registry. Pull these out now.
.
  // in the registry. Pull these out now.
  nsXPIDLCString name;
.
  nsXPIDLCString name;
  aRegistry->GetStringUTF8(aPluginKey, "name", getter_Copies(name));
.
  aRegistry->GetStringUTF8(aPluginKey, "name", getter_Copies(name));
 
.
 
  nsXPIDLCString description;
.
  nsXPIDLCString description;
  aRegistry->GetStringUTF8(aPluginKey, "description", getter_Copies(descriptio
n));
.
  aRegistry->GetStringUTF8(aPluginKey, "description", getter_Copies(descriptio
n));
 
.
 
  nsXPIDLCString filename;
.
  nsXPIDLCString filename;
 
.
 
  // To figure out the filename of the plugin, we'll need to get the
.
  // To figure out the filename of the plugin, we'll need to get the
  // plugin's CID, and then navigate through the XPCOM registry to
.
  // plugin's CID, and then navigate through the XPCOM registry to
  // pull out the DLL name to which the CID is registered.
.
  // pull out the DLL name to which the CID is registered.
  nsAutoString path(NS_LITERAL_STRING("software/mozilla/XPCOM/classID/") + NS_
ConvertASCIItoUCS2(aCID));
.
  nsAutoString path(NS_LITERAL_STRING("software/mozilla/XPCOM/classID/") + NS_
ConvertASCIItoUCS2(aCID));
 
.
 
  nsRegistryKey cidKey;
.
  nsRegistryKey cidKey;
  rv = aRegistry->GetKey(nsIRegistry::Common, path.GetUnicode(), &cidKey);
.
  rv = aRegistry->GetKey(nsIRegistry::Common, path.GetUnicode(), &cidKey);
 
.
 
  if (NS_SUCCEEDED(rv)) {
.
  if (NS_SUCCEEDED(rv)) {
    PRUint8* library;
.
    PRUint8* library;
    PRUint32 count;
.
    PRUint32 count;
    // XXX Good grief, what does "GetBytesUTF8()" mean? They're bytes!
.
    // XXX Good grief, what does "GetBytesUTF8()" mean? They're bytes!
    rv = aRegistry->GetBytesUTF8(cidKey, "InprocServer", &count, &library);
.
    rv = aRegistry->GetBytesUTF8(cidKey, "InprocServer", &count, &library);
    if (NS_SUCCEEDED(rv)) {
.
    if (NS_SUCCEEDED(rv)) {
      nsCOMPtr<nsIFile> file;
.
      nsCOMPtr<nsIFile> file;
      rv = aComponentManager->SpecForRegistryLocation(NS_REINTERPRET_CAST(cons
t char*, library),
.
      rv = aComponentManager->SpecForRegistryLocation(NS_REINTERPRET_CAST(cons
t char*, library),
                                                      getter_AddRefs(file));
.
                                                      getter_AddRefs(file));
 
.
 
      if (NS_SUCCEEDED(rv)) {
.
      if (NS_SUCCEEDED(rv)) {
        file->GetPath(getter_Copies(filename));
.
        file->GetPath(getter_Copies(filename));
      }
.
      }
 
.
 
      nsCRT::free(NS_REINTERPRET_CAST(char*, library));
.
      nsCRT::free(NS_REINTERPRET_CAST(char*, library));
    }
.
    }
  }
.
  }
 
.
 
  nsCOMPtr<nsIEnumerator> enumerator;
.
  nsCOMPtr<nsIEnumerator> enumerator;
  rv = aRegistry->EnumerateAllSubtrees(aPluginKey, getter_AddRefs(enumerator))
;
.
  rv = aRegistry->EnumerateAllSubtrees(aPluginKey, getter_AddRefs(enumerator))
;
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  nsCOMPtr<nsISimpleEnumerator> subtrees;
.
  nsCOMPtr<nsISimpleEnumerator> subtrees;
  rv = NS_NewAdapterEnumerator(getter_AddRefs(subtrees), enumerator);
.
  rv = NS_NewAdapterEnumerator(getter_AddRefs(subtrees), enumerator);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  char** mimetypes = nsnull;
.
  char** mimetypes = nsnull;
  char** mimedescriptions = nsnull;
.
  char** mimedescriptions = nsnull;
  char** extensions = nsnull;
.
  char** extensions = nsnull;
  PRInt32 count = 0;
.
  PRInt32 count = 0;
  PRInt32 capacity = 0;
.
  PRInt32 capacity = 0;
 
.
 
  for (;;) {
.
  for (;;) {
    PRBool hasmore;
.
    PRBool hasmore;
    subtrees->HasMoreElements(&hasmore);
.
    subtrees->HasMoreElements(&hasmore);
    if (! hasmore)
.
    if (! hasmore)
      break;
.
      break;
 
.
 
    nsCOMPtr<nsISupports> isupports;
.
    nsCOMPtr<nsISupports> isupports;
    subtrees->GetNext(getter_AddRefs(isupports));
.
    subtrees->GetNext(getter_AddRefs(isupports));
 
.
 
    nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
.
    nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
    NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
.
    NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
    if (! node)
.
    if (! node)
      continue;
.
      continue;
 
.
 
    nsRegistryKey key;
.
    nsRegistryKey key;
    node->GetKey(&key);
.
    node->GetKey(&key);
 
.
 
    if (count >= capacity) {
.
    if (count >= capacity) {
      capacity += capacity ? capacity : 4;
.
      capacity += capacity ? capacity : 4;
 
.
 
      char** newmimetypes        = new char*[capacity];
.
      char** newmimetypes        = new char*[capacity];
      char** newmimedescriptions = new char*[capacity];
.
      char** newmimedescriptions = new char*[capacity];
      char** newextensions       = new char*[capacity];
.
      char** newextensions       = new char*[capacity];
 
.
 
      if (!newmimetypes || !newmimedescriptions || !newextensions) {
.
      if (!newmimetypes || !newmimedescriptions || !newextensions) {
        rv = NS_ERROR_OUT_OF_MEMORY;
.
        rv = NS_ERROR_OUT_OF_MEMORY;
        delete[] newmimetypes;
.
        delete[] newmimetypes;
        delete[] newmimedescriptions;
.
        delete[] newmimedescriptions;
        delete[] newextensions;
.
        delete[] newextensions;
        break;
.
        break;
      }
.
      }
 
.
 
      for (PRInt32 i = 0; i < count; ++i) {
.
      for (PRInt32 i = 0; i < count; ++i) {
        newmimetypes[i]        = mimetypes[i];
.
        newmimetypes[i]        = mimetypes[i];
        newmimedescriptions[i] = mimedescriptions[i];
.
        newmimedescriptions[i] = mimedescriptions[i];
        newextensions[i]       = extensions[i];
.
        newextensions[i]       = extensions[i];
      }
.
      }
 
.
 
      delete[] mimetypes;
.
      delete[] mimetypes;
      delete[] mimedescriptions;
.
      delete[] mimedescriptions;
      delete[] extensions;
.
      delete[] extensions;
 
.
 
      mimetypes        = newmimetypes;
.
      mimetypes        = newmimetypes;
      mimedescriptions = newmimedescriptions;
.
      mimedescriptions = newmimedescriptions;
      extensions       = newextensions;
.
      extensions       = newextensions;
    }
.
    }
 
.
 
    aRegistry->GetStringUTF8(key, "mimetype",    &mimetypes[count]);
.
    aRegistry->GetStringUTF8(key, "mimetype",    &mimetypes[count]);
    aRegistry->GetStringUTF8(key, "description", &mimedescriptions[count]);
.
    aRegistry->GetStringUTF8(key, "description", &mimedescriptions[count]);
    aRegistry->GetStringUTF8(key, "extension",   &extensions[count]);
.
    aRegistry->GetStringUTF8(key, "extension",   &extensions[count]);
    ++count;
.
    ++count;
  }
.
  }
 
.
 
  if (NS_SUCCEEDED(rv)) {
.
  if (NS_SUCCEEDED(rv)) {
    // All done! Create the new nsPluginTag info and send it back.
.
    // All done! Create the new nsPluginTag info and send it back.
    nsPluginTag* tag
.
    nsPluginTag* tag
      = new nsPluginTag(name.get(),
.
      = new nsPluginTag(name.get(),
                        description.get(),
.
                        description.get(),
                        filename.get(),
.
                        filename.get(),
                        (const char* const*)mimetypes,
.
                        (const char* const*)mimetypes,
                        (const char* const*)mimedescriptions,
.
                        (const char* const*)mimedescriptions,
                        (const char* const*)extensions,
.
                        (const char* const*)extensions,
                        count);
.
                        count);
 
.
 
    if (! tag)
.
    if (! tag)
      rv = NS_ERROR_OUT_OF_MEMORY;
.
      rv = NS_ERROR_OUT_OF_MEMORY;
 
.
 
    *aResult = tag;
.
    *aResult = tag;
  }
.
  }
 
.
 
  for (PRInt32 i = 0; i < count; ++i) {
.
  for (PRInt32 i = 0; i < count; ++i) {
    CRTFREEIF(mimetypes[i]);
.
    CRTFREEIF(mimetypes[i]);
    CRTFREEIF(mimedescriptions[i]);
.
    CRTFREEIF(mimedescriptions[i]);
    CRTFREEIF(extensions[i]);
.
    CRTFREEIF(extensions[i]);
  }
.
  }
 
.
 
  delete[] mimetypes;
.
  delete[] mimetypes;
  delete[] mimedescriptions;
.
  delete[] mimedescriptions;
  delete[] extensions;
.
  delete[] extensions;
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
nsresult
.
nsresult
nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsI
File* aPath)
.
nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsI
File* aPath)
{
.
{
  // The "new style" XPCOM plugins have their information stored in
.
  // The "new style" XPCOM plugins have their information stored in
  // the component registry, under the key
.
  // the component registry, under the key
  //
.
  //
  //   nsIRegistry::Common/software/plugins
.
  //   nsIRegistry::Common/software/plugins
  //
.
  //
  // Enumerate through that list now, creating an nsPluginTag for
.
  // Enumerate through that list now, creating an nsPluginTag for
  // each.
.
  // each.
  nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
.
  nsCOMPtr<nsIRegistry> registry = do_CreateInstance(kRegistryCID);
  if (! registry)
.
  if (! registry)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  nsresult rv;
.
  nsresult rv;
  rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegist
ry);
.
  rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegist
ry);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
  
.
  
  nsRegistryKey pluginsKey;
.
  nsRegistryKey pluginsKey;
  rv = registry->GetSubtree(nsIRegistry::Common, "software/plugins", &pluginsK
ey);
.
  rv = registry->GetSubtree(nsIRegistry::Common, "software/plugins", &pluginsK
ey);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  // XXX get rid nsIEnumerator someday!
.
  // XXX get rid nsIEnumerator someday!
  nsCOMPtr<nsIEnumerator> enumerator;
.
  nsCOMPtr<nsIEnumerator> enumerator;
  rv = registry->EnumerateSubtrees(pluginsKey, getter_AddRefs(enumerator));
.
  rv = registry->EnumerateSubtrees(pluginsKey, getter_AddRefs(enumerator));
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  nsCOMPtr<nsISimpleEnumerator> plugins;
.
  nsCOMPtr<nsISimpleEnumerator> plugins;
  rv = NS_NewAdapterEnumerator(getter_AddRefs(plugins), enumerator);
.
  rv = NS_NewAdapterEnumerator(getter_AddRefs(plugins), enumerator);
  if (NS_FAILED(rv)) return rv;
.
  if (NS_FAILED(rv)) return rv;
 
.
 
  for (;;) {
.
  for (;;) {
    PRBool hasMore;
.
    PRBool hasMore;
    plugins->HasMoreElements(&hasMore);
.
    plugins->HasMoreElements(&hasMore);
    if (! hasMore)
.
    if (! hasMore)
      break;
.
      break;
 
.
 
    nsCOMPtr<nsISupports> isupports;
.
    nsCOMPtr<nsISupports> isupports;
    plugins->GetNext(getter_AddRefs(isupports));
.
    plugins->GetNext(getter_AddRefs(isupports));
 
.
 
    nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
.
    nsCOMPtr<nsIRegistryNode> node = do_QueryInterface(isupports);
    NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
.
    NS_ASSERTION(node != nsnull, "not an nsIRegistryNode");
    if (! node)
.
    if (! node)
      continue;
.
      continue;
 
.
 
    // Pull out the information for an individual plugin, and link it
.
    // Pull out the information for an individual plugin, and link it
    // in to the mPlugins list.
.
    // in to the mPlugins list.
    nsXPIDLCString cid;
.
    nsXPIDLCString cid;
    node->GetNameUTF8(getter_Copies(cid));
.
    node->GetNameUTF8(getter_Copies(cid));
 
.
 
    nsRegistryKey key;
.
    nsRegistryKey key;
    node->GetKey(&key);
.
    node->GetKey(&key);
 
.
 
    nsPluginTag* tag = nsnull;
.
    nsPluginTag* tag = nsnull;
    rv = LoadXPCOMPlugin(aComponentManager, registry, cid, key, &tag);
.
    rv = LoadXPCOMPlugin(aComponentManager, registry, cid, key, &tag);
    if (NS_FAILED(rv))
.
    if (NS_FAILED(rv))
      continue;
.
      continue;
 
.
 
    // skip it if we already have it
.
    // skip it if we already have it
    PRBool bAddIt = PR_TRUE;
.
    PRBool bAddIt = PR_TRUE;
    for(nsPluginTag* existingtag = mPlugins; existingtag != nsnull; existingta
g = existingtag->mNext)
.
    for(nsPluginTag* existingtag = mPlugins; existingtag != nsnull; existingta
g = existingtag->mNext)
    {
.
    {
      if(areTheSameFileNames(tag->mFileName, existingtag->mFileName))
.
      if(areTheSameFileNames(tag->mFileName, existingtag->mFileName))
      {
.
      {
        bAddIt = PR_FALSE;
.
        bAddIt = PR_FALSE;
        break;
.
        break;
      }
.
      }
    }
.
    }
 
.
 
    if(!bAddIt)
.
    if(!bAddIt)
    {
.
    {
      if(tag)
.
      if(tag)
        delete tag;
.
        delete tag;
      continue;
.
      continue;
    }
.
    }
 
.
 
    tag->mNext = mPlugins;
.
    tag->mNext = mPlugins;
    mPlugins = tag;
.
    mPlugins = tag;
 
.
 
    // Create an nsIDocumentLoaderFactory wrapper in case we ever see
.
    // Create an nsIDocumentLoaderFactory wrapper in case we ever see
    // any naked streams.
.
    // any naked streams.
    RegisterPluginMimeTypesWithLayout(tag, aComponentManager, aPath);
.
    RegisterPluginMimeTypesWithLayout(tag, aComponentManager, aPath);
  }
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* Called by GetURL and PostURL */
.
/* Called by GetURL and PostURL */
 
.
 
NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
.
NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
                                                   nsIPluginInstance *aInstanc
e,
.
                                                   nsIPluginInstance *aInstanc
e,
                                                   nsIPluginStreamListener* aL
istener,
.
                                                   nsIPluginStreamListener* aL
istener,
                                                   const char *aPostData,
.
                                                   const char *aPostData,
                                                   PRBool aIsFile, 
.
                                                   PRBool aIsFile, 
                                                   PRUint32 aPostDataLen, 
.
                                                   PRUint32 aPostDataLen, 
                                                   const char *aHeadersData, 
.
                                                   const char *aHeadersData, 
                                                   PRUint32 aHeadersDataLen)
.
                                                   PRUint32 aHeadersDataLen)
{
.
{
  nsCOMPtr<nsIURI> url;
.
  nsCOMPtr<nsIURI> url;
  nsAutoString absUrl;
.
  nsAutoString absUrl;
  nsresult rv;
.
  nsresult rv;
  char *newPostData = nsnull;
.
  char *newPostData = nsnull;
  PRUint32 newPostDataLen = 0;
.
  PRUint32 newPostDataLen = 0;
 
.
 
  if (aURL.Length() <= 0)
.
  if (aURL.Length() <= 0)
    return NS_OK;
.
    return NS_OK;
 
.
 
  // get the full URL of the document that the plugin is embedded
.
  // get the full URL of the document that the plugin is embedded
  //   in to create an absolute url in case aURL is relative
.
  //   in to create an absolute url in case aURL is relative
  nsCOMPtr<nsIDocument> doc;
.
  nsCOMPtr<nsIDocument> doc;
  nsPluginInstancePeerImpl *peer;
.
  nsPluginInstancePeerImpl *peer;
  rv = aInstance->GetPeer(NS_REINTERPRET_CAST(nsIPluginInstancePeer **, &peer)
);
.
  rv = aInstance->GetPeer(NS_REINTERPRET_CAST(nsIPluginInstancePeer **, &peer)
);
  if (NS_SUCCEEDED(rv) && peer)
.
  if (NS_SUCCEEDED(rv) && peer)
  {
.
  {
    nsCOMPtr<nsIPluginInstanceOwner> owner;
.
    nsCOMPtr<nsIPluginInstanceOwner> owner;
    rv = peer->GetOwner(*getter_AddRefs(owner));
.
    rv = peer->GetOwner(*getter_AddRefs(owner));
    if (NS_SUCCEEDED(rv) && owner)
.
    if (NS_SUCCEEDED(rv) && owner)
    {
.
    {
      rv = owner->GetDocument(getter_AddRefs(doc));
.
      rv = owner->GetDocument(getter_AddRefs(doc));
      if (NS_SUCCEEDED(rv) && doc)
.
      if (NS_SUCCEEDED(rv) && doc)
      {
.
      {
        nsCOMPtr<nsIURI> docURL( getter_AddRefs(doc->GetDocumentURL()) );
.
        nsCOMPtr<nsIURI> docURL( getter_AddRefs(doc->GetDocumentURL()) );
 
.
 
        // Create an absolute URL
.
        // Create an absolute URL
        rv = NS_MakeAbsoluteURI(absUrl, aURL, docURL);
.
        rv = NS_MakeAbsoluteURI(absUrl, aURL, docURL);
      }
.
      }
    }
.
    }
    NS_RELEASE(peer);
.
    NS_RELEASE(peer);
  }
.
  }
 
.
 
  if (absUrl.IsEmpty())
.
  if (absUrl.IsEmpty())
    absUrl.Assign(aURL);
.
    absUrl.Assign(aURL);
 
.
 
  rv = NS_NewURI(getter_AddRefs(url), absUrl);
.
  rv = NS_NewURI(getter_AddRefs(url), absUrl);
 
.
 
  if (NS_SUCCEEDED(rv))
.
  if (NS_SUCCEEDED(rv))
  {
.
  {
    nsPluginStreamListenerPeer *listenerPeer = new nsPluginStreamListenerPeer;
.
    nsPluginStreamListenerPeer *listenerPeer = new nsPluginStreamListenerPeer;
    if (listenerPeer == NULL)
.
    if (listenerPeer == NULL)
      return NS_ERROR_OUT_OF_MEMORY;
.
      return NS_ERROR_OUT_OF_MEMORY;
 
.
 
    NS_ADDREF(listenerPeer);
.
    NS_ADDREF(listenerPeer);
    rv = listenerPeer->Initialize(url, aInstance, aListener);
.
    rv = listenerPeer->Initialize(url, aInstance, aListener);
 
.
 
    if (NS_SUCCEEDED(rv)) 
.
    if (NS_SUCCEEDED(rv)) 
    {
.
    {
      nsCOMPtr<nsIInterfaceRequestor> callbacks;
.
      nsCOMPtr<nsIInterfaceRequestor> callbacks;
 
.
 
      if (doc) 
.
      if (doc) 
      {
.
      {
        // Get the script global object owner and use that as the notification
 callback
.
        // Get the script global object owner and use that as the notification
 callback
        nsCOMPtr<nsIScriptGlobalObject> global;
.
        nsCOMPtr<nsIScriptGlobalObject> global;
        doc->GetScriptGlobalObject(getter_AddRefs(global));
.
        doc->GetScriptGlobalObject(getter_AddRefs(global));
 
.
 
        if (global) 
.
        if (global) 
        {
.
        {
          nsCOMPtr<nsIScriptGlobalObjectOwner> owner;
.
          nsCOMPtr<nsIScriptGlobalObjectOwner> owner;
          global->GetGlobalObjectOwner(getter_AddRefs(owner));
.
          global->GetGlobalObjectOwner(getter_AddRefs(owner));
 
.
 
          callbacks = do_QueryInterface(owner);
.
          callbacks = do_QueryInterface(owner);
        }
.
        }
      }
.
      }
 
.
 
      nsCOMPtr<nsIChannel> channel;
.
      nsCOMPtr<nsIChannel> channel;
 
.
 
      // XXX: Null LoadGroup?
.
      // XXX: Null LoadGroup?
      rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull, callbacks)
;
.
      rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull, callbacks)
;
      if (NS_FAILED(rv)) 
.
      if (NS_FAILED(rv)) 
        return rv;
.
        return rv;
 
.
 
      if (doc) 
.
      if (doc) 
      {
.
      {
        // Set the owner of channel to the document principal...
.
        // Set the owner of channel to the document principal...
        nsCOMPtr<nsIPrincipal> principal;
.
        nsCOMPtr<nsIPrincipal> principal;
        doc->GetPrincipal(getter_AddRefs(principal));
.
        doc->GetPrincipal(getter_AddRefs(principal));
 
.
 
        channel->SetOwner(principal);
.
        channel->SetOwner(principal);
      }
.
      }
 
.
 
      // deal with headers and post data
.
      // deal with headers and post data
      nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
.
      nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
      if(httpChannel)
.
      if(httpChannel)
      {
.
      {
 
.
 
        // figure out if we need to set the post data stream on the
.
        // figure out if we need to set the post data stream on the
        // channel...  right now, this is only done for http
.
        // channel...  right now, this is only done for http
        // channels.....
.
        // channels.....
        if(aPostData)
.
        if(aPostData)
        {
.
        {
          nsCOMPtr<nsIInputStream> postDataStream;
.
          nsCOMPtr<nsIInputStream> postDataStream;
 
.
 
          // In the file case, hand the filename off to NewPostDataStream
.
          // In the file case, hand the filename off to NewPostDataStream
          if (aIsFile) 
.
          if (aIsFile) 
          {
.
          {
            nsXPIDLCString filename;
.
            nsXPIDLCString filename;
 
.
 
            nsCOMPtr<nsIURI> url;
.
            nsCOMPtr<nsIURI> url;
            NS_NewURI(getter_AddRefs(url), aPostData);
.
            NS_NewURI(getter_AddRefs(url), aPostData);
            nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(url));
.
            nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(url));
            if (fileURL) {
.
            if (fileURL) {
              nsCOMPtr<nsIFile> file;
.
              nsCOMPtr<nsIFile> file;
              fileURL->GetFile(getter_AddRefs(file));
.
              fileURL->GetFile(getter_AddRefs(file));
              nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
.
              nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(file));
              if (localFile) {
.
              if (localFile) {
                localFile->GetPath(getter_Copies(filename));
.
                localFile->GetPath(getter_Copies(filename));
 
.
 
                // tell the listener about it so it will delete the file later
.
                // tell the listener about it so it will delete the file later
                listenerPeer->SetLocalFile(filename);
.
                listenerPeer->SetLocalFile(filename);
 
.
 
                NS_NewPostDataStream(getter_AddRefs(postDataStream), aIsFile, 
filename, 0);
.
                NS_NewPostDataStream(getter_AddRefs(postDataStream), aIsFile, 
filename, 0);
              }
.
              }
            }
.
            }
          }
.
          }
          else
.
          else
          {
.
          {
            // In the string case, we create a string buffer stream
.
            // In the string case, we create a string buffer stream
            //Make sure there is "r\n\r\n" before the post data
.
            //Make sure there is "r\n\r\n" before the post data
            if (!PL_strstr(aPostData, "\r\n\r\n")) 
.
            if (!PL_strstr(aPostData, "\r\n\r\n")) 
            {
.
            {
              if (NS_SUCCEEDED(FixPostData(aPostData, aPostDataLen, &newPostDa
ta, &newPostDataLen))) 
.
              if (NS_SUCCEEDED(FixPostData(aPostData, aPostDataLen, &newPostDa
ta, &newPostDataLen))) 
              {
.
              {
                aPostData = newPostData;
.
                aPostData = newPostData;
                aPostDataLen = newPostDataLen;
.
                aPostDataLen = newPostDataLen;
              }   
.
              }   
            }
.
            }
            if (aPostData)
.
            if (aPostData)
              NS_NewPostDataStream(getter_AddRefs(postDataStream), aIsFile, aP
ostData, 0);
.
              NS_NewPostDataStream(getter_AddRefs(postDataStream), aIsFile, aP
ostData, 0);
          }
.
          }
              
.
              
          if (!postDataStream) 
.
          if (!postDataStream) 
          {
.
          {
            NS_RELEASE(aInstance);
.
            NS_RELEASE(aInstance);
            return NS_ERROR_UNEXPECTED;
.
            return NS_ERROR_UNEXPECTED;
          }
.
          }
 
.
 
          // XXX it's a bit of a hack to rewind the postdata stream
.
          // 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
.
          // here but it has to be done in case the post data is
          // being reused multiple times.
.
          // being reused multiple times.
          nsCOMPtr<nsIRandomAccessStore> 
.
          nsCOMPtr<nsIRandomAccessStore> 
          postDataRandomAccess(do_QueryInterface(postDataStream));
.
          postDataRandomAccess(do_QueryInterface(postDataStream));
          if (postDataRandomAccess)
.
          if (postDataRandomAccess)
            postDataRandomAccess->Seek(PR_SEEK_SET, 0);
.
            postDataRandomAccess->Seek(PR_SEEK_SET, 0);
          
.
          
          httpChannel->SetUploadStream(postDataStream);
.
          httpChannel->SetUploadStream(postDataStream);
 
.
 
          if (newPostData)
.
          if (newPostData)
          {
.
          {
            delete [] (char *)newPostData;
.
            delete [] (char *)newPostData;
            newPostData = nsnull;
.
            newPostData = nsnull;
          }
.
          }
        }
.
        }
 
.
 
        if (aHeadersData) 
.
        if (aHeadersData) 
          rv = AddHeadersToChannel(aHeadersData, aHeadersDataLen, httpChannel)
;
.
          rv = AddHeadersToChannel(aHeadersData, aHeadersDataLen, httpChannel)
;
      }
.
      }
      rv = channel->AsyncOpen(listenerPeer, nsnull);
.
      rv = channel->AsyncOpen(listenerPeer, nsnull);
    }
.
    }
    NS_RELEASE(listenerPeer);
.
    NS_RELEASE(listenerPeer);
  }
.
  }
  return rv;
.
  return rv;
}
.
}
 
.
 
nsresult
.
nsresult
nsPluginHostImpl::FixPostData(const char *inPostData, PRUint32 inPostDataLen,
.
nsPluginHostImpl::FixPostData(const char *inPostData, PRUint32 inPostDataLen,
                              char **outPostData, PRUint32 *outPostDataLen)
.
                              char **outPostData, PRUint32 *outPostDataLen)
{
.
{
  NS_ENSURE_ARG_POINTER(inPostData);
.
  NS_ENSURE_ARG_POINTER(inPostData);
  NS_ENSURE_ARG_POINTER(outPostData);
.
  NS_ENSURE_ARG_POINTER(outPostData);
  NS_ENSURE_ARG_POINTER(outPostDataLen);
.
  NS_ENSURE_ARG_POINTER(outPostDataLen);
  if(inPostDataLen <= 0)
.
  if(inPostDataLen <= 0)
    return NS_ERROR_UNEXPECTED;
.
    return NS_ERROR_UNEXPECTED;
 
.
 
  const char *postData = inPostData;
.
  const char *postData = inPostData;
  const char *crlf = nsnull;
.
  const char *crlf = nsnull;
  const char *crlfcrlf = "\r\n\r\n";
.
  const char *crlfcrlf = "\r\n\r\n";
  const char *t;
.
  const char *t;
  char *newBuf;
.
  char *newBuf;
  PRInt32 headersLen = 0, dataLen = 0;
.
  PRInt32 headersLen = 0, dataLen = 0;
 
.
 
  if (!(newBuf = new char[inPostDataLen + 4])) {
.
  if (!(newBuf = new char[inPostDataLen + 4])) {
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
  }
.
  }
  nsCRT::memset(newBuf, 0, inPostDataLen + 4);
.
  nsCRT::memset(newBuf, 0, inPostDataLen + 4);
 
.
 
  if (!(crlf = PL_strstr(postData, "\r\n\n"))) {
.
  if (!(crlf = PL_strstr(postData, "\r\n\n"))) {
    delete [] newBuf;
.
    delete [] newBuf;
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
  }
.
  }
  headersLen = crlf - postData;
.
  headersLen = crlf - postData;
 
.
 
  // find the next non-whitespace char
.
  // find the next non-whitespace char
  t = crlf + 3;
.
  t = crlf + 3;
  while (*t == '\r' || *t == '\n' || *t == '\t' || *t == ' ' && *t) {
.
  while (*t == '\r' || *t == '\n' || *t == '\t' || *t == ' ' && *t) {
    t++;
.
    t++;
  }
.
  }
  if (*t) {
.
  if (*t) {
    // copy the headers
.
    // copy the headers
    nsCRT::memcpy(newBuf, postData, headersLen);
.
    nsCRT::memcpy(newBuf, postData, headersLen);
    // copy the correct crlfcrlf
.
    // copy the correct crlfcrlf
    nsCRT::memcpy(newBuf + headersLen, crlfcrlf, 4);
.
    nsCRT::memcpy(newBuf + headersLen, crlfcrlf, 4);
    // copy the rest of the postData
.
    // copy the rest of the postData
    dataLen = inPostDataLen - (t - postData);
.
    dataLen = inPostDataLen - (t - postData);
    nsCRT::memcpy(newBuf + headersLen + 4, t, dataLen);
.
    nsCRT::memcpy(newBuf + headersLen + 4, t, dataLen);
    *outPostDataLen = headersLen + 4 + dataLen;
.
    *outPostDataLen = headersLen + 4 + dataLen;
    *outPostData = newBuf;
.
    *outPostData = newBuf;
  }
.
  }
  else {
.
  else {
    delete [] newBuf;
.
    delete [] newBuf;
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
  }
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginHostImpl::AddHeadersToChannel(const char *aHeadersData, 
.
nsPluginHostImpl::AddHeadersToChannel(const char *aHeadersData, 
                                      PRUint32 aHeadersDataLen, 
.
                                      PRUint32 aHeadersDataLen, 
                                      nsIChannel *aGenericChannel)
.
                                      nsIChannel *aGenericChannel)
{
.
{
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  nsCOMPtr<nsIHttpChannel> aChannel = do_QueryInterface(aGenericChannel);
.
  nsCOMPtr<nsIHttpChannel> aChannel = do_QueryInterface(aGenericChannel);
  if (!aChannel) {
.
  if (!aChannel) {
    return NS_ERROR_NULL_POINTER;
.
    return NS_ERROR_NULL_POINTER;
  }
.
  }
 
.
 
  // used during the manipulation of the String from the aHeadersData
.
  // used during the manipulation of the String from the aHeadersData
  nsCAutoString headersString;
.
  nsCAutoString headersString;
  nsCAutoString oneHeader;
.
  nsCAutoString oneHeader;
  nsCAutoString headerName;
.
  nsCAutoString headerName;
  nsCAutoString headerValue;
.
  nsCAutoString headerValue;
  PRInt32 crlf = 0;
.
  PRInt32 crlf = 0;
  PRInt32 colon = 0;
.
  PRInt32 colon = 0;
  
.
  
  //
.
  //
  // Turn the char * buffer into an nsString.
.
  // Turn the char * buffer into an nsString.
  //
.
  //
  headersString = aHeadersData;
.
  headersString = aHeadersData;
 
.
 
  //
.
  //
  // Iterate over the nsString: for each "\r\n" delimeted chunk,
.
  // Iterate over the nsString: for each "\r\n" delimeted chunk,
  // add the value as a header to the nsIHTTPChannel
.
  // add the value as a header to the nsIHTTPChannel
  //
.
  //
  
.
  
  while (PR_TRUE) {
.
  while (PR_TRUE) {
    crlf = headersString.Find("\r\n", PR_TRUE);
.
    crlf = headersString.Find("\r\n", PR_TRUE);
    if (-1 == crlf) {
.
    if (-1 == crlf) {
      rv = NS_OK;
.
      rv = NS_OK;
      return rv;
.
      return rv;
    }
.
    }
    headersString.Mid(oneHeader, 0, crlf);
.
    headersString.Mid(oneHeader, 0, crlf);
    headersString.Cut(0, crlf + 2);
.
    headersString.Cut(0, crlf + 2);
    oneHeader.StripWhitespace();
.
    oneHeader.StripWhitespace();
    colon = oneHeader.Find(":");
.
    colon = oneHeader.Find(":");
    if (-1 == colon) {
.
    if (-1 == colon) {
      rv = NS_ERROR_NULL_POINTER;
.
      rv = NS_ERROR_NULL_POINTER;
      return rv;
.
      return rv;
    }
.
    }
    oneHeader.Left(headerName, colon);
.
    oneHeader.Left(headerName, colon);
    colon++;
.
    colon++;
    oneHeader.Mid(headerValue, colon, oneHeader.Length() - colon);
.
    oneHeader.Mid(headerValue, colon, oneHeader.Length() - colon);
    
.
    
    //
.
    //
    // FINALLY: we can set the header!
.
    // FINALLY: we can set the header!
    // 
.
    // 
    
.
    
    rv =aChannel->SetRequestHeader(headerName.get(), headerValue.get());
.
    rv =aChannel->SetRequestHeader(headerName.get(), headerValue.get());
    if (NS_FAILED(rv)) {
.
    if (NS_FAILED(rv)) {
      rv = NS_ERROR_NULL_POINTER;
.
      rv = NS_ERROR_NULL_POINTER;
      return rv;
.
      return rv;
    }
.
    }
  }    
.
  }    
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP
.
NS_IMETHODIMP
nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
.
nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
{
.
{
  nsActivePlugin * plugin = mActivePluginList.find(aInstance);
.
  nsActivePlugin * plugin = mActivePluginList.find(aInstance);
 
.
 
  if(plugin != nsnull)
.
  if(plugin != nsnull)
  {
.
  {
    // if the plugin does not want to be 'cached' just remove it
.
    // if the plugin does not want to be 'cached' just remove it
    PRBool doCache = PR_TRUE;
.
    PRBool doCache = PR_TRUE;
    aInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCach
e);
.
    aInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCach
e);
 
.
 
    // we also do that for 4x plugin, shall we? Let's see if it is
.
    // we also do that for 4x plugin, shall we? Let's see if it is
    PRBool oldSchool = PR_TRUE;
.
    PRBool oldSchool = PR_TRUE;
    if(plugin->mPluginTag)
.
    if(plugin->mPluginTag)
      oldSchool = plugin->mPluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL ? PR_T
RUE : PR_FALSE;
.
      oldSchool = plugin->mPluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL ? PR_T
RUE : PR_FALSE;
 
.
 
    if (!doCache || oldSchool)
.
    if (!doCache || oldSchool)
      {
.
      {
      PRLibrary * library = nsnull;
.
      PRLibrary * library = nsnull;
      if(plugin->mPluginTag)
.
      if(plugin->mPluginTag)
        library = plugin->mPluginTag->mLibrary;
.
        library = plugin->mPluginTag->mLibrary;
 
.
 
      PRBool unloadLibLater = PR_FALSE;
.
      PRBool unloadLibLater = PR_FALSE;
      mActivePluginList.remove(plugin, &unloadLibLater);
.
      mActivePluginList.remove(plugin, &unloadLibLater);
 
.
 
      if(unloadLibLater)
.
      if(unloadLibLater)
        AddToUnusedLibraryList(library);
.
        AddToUnusedLibraryList(library);
        }
.
        }
    else
.
    else
    {
.
    {
      // if it is allowed to be cached simply stop it, but first we should che
ck 
.
      // if it is allowed to be cached simply stop it, but first we should che
ck 
      // if we haven't exceeded the maximum allowed number of cached instances
.
      // if we haven't exceeded the maximum allowed number of cached instances
 
.
 
      // try to get the max cached plugins from a pref or use default
.
      // try to get the max cached plugins from a pref or use default
      PRUint32 max_num;
.
      PRUint32 max_num;
      nsresult rv;
.
      nsresult rv;
      nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
.
      nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
      if (prefs) rv = prefs->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS,(int *)
&max_num);
.
      if (prefs) rv = prefs->GetIntPref(NS_PREF_MAX_NUM_CACHED_PLUGINS,(int *)
&max_num);
      if (!NS_SUCCEEDED(rv)) max_num = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
.
      if (!NS_SUCCEEDED(rv)) max_num = DEFAULT_NUMBER_OF_STOPPED_PLUGINS;
 
.
 
      if(mActivePluginList.getStoppedCount() >= max_num)
.
      if(mActivePluginList.getStoppedCount() >= max_num)
      {
.
      {
        nsActivePlugin * oldest = mActivePluginList.findOldestStopped();
.
        nsActivePlugin * oldest = mActivePluginList.findOldestStopped();
        if(oldest != nsnull)
.
        if(oldest != nsnull)
        {
.
        {
          PRLibrary * library = oldest->mPluginTag->mLibrary;
.
          PRLibrary * library = oldest->mPluginTag->mLibrary;
 
.
 
          PRBool unloadLibLater = PR_FALSE;
.
          PRBool unloadLibLater = PR_FALSE;
          mActivePluginList.remove(oldest, &unloadLibLater);
.
          mActivePluginList.remove(oldest, &unloadLibLater);
 
.
 
          if(unloadLibLater)
.
          if(unloadLibLater)
            AddToUnusedLibraryList(library);
.
            AddToUnusedLibraryList(library);
        }
.
        }
      }
.
      }
 
.
 
      plugin->setStopped(PR_TRUE);
.
      plugin->setStopped(PR_TRUE);
    }
.
    }
  }
.
  }
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
/* Called by InstantiateEmbededPlugin() */
.
/* Called by InstantiateEmbededPlugin() */
 
.
 
nsresult nsPluginHostImpl::NewEmbededPluginStream(nsIURI* aURL,
.
nsresult nsPluginHostImpl::NewEmbededPluginStream(nsIURI* aURL,
                                                  nsIPluginInstanceOwner *aOwn
er,
.
                                                  nsIPluginInstanceOwner *aOwn
er,
                                                  nsIPluginInstance* aInstance
)
.
                                                  nsIPluginInstance* aInstance
)
{
.
{
  nsPluginStreamListenerPeer  *listener = (nsPluginStreamListenerPeer *)new ns
PluginStreamListenerPeer();
.
  nsPluginStreamListenerPeer  *listener = (nsPluginStreamListenerPeer *)new ns
PluginStreamListenerPeer();
  if (listener == nsnull)
.
  if (listener == nsnull)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  nsresult rv;
.
  nsresult rv;
 
.
 
  if (!aURL)
.
  if (!aURL)
    return NS_OK;
.
    return NS_OK;
 
.
 
  // if we have an instance, everything has been set up
.
  // if we have an instance, everything has been set up
  // if we only have an owner, then we need to pass it in
.
  // if we only have an owner, then we need to pass it in
  // so the listener can set up the instance later after
.
  // so the listener can set up the instance later after
  // we've determined the mimetype of the stream
.
  // we've determined the mimetype of the stream
  if(aInstance != nsnull)
.
  if(aInstance != nsnull)
    rv = listener->InitializeEmbeded(aURL, aInstance);
.
    rv = listener->InitializeEmbeded(aURL, aInstance);
  else if(aOwner != nsnull)
.
  else if(aOwner != nsnull)
    rv = listener->InitializeEmbeded(aURL, nsnull, aOwner, (nsIPluginHost *)th
is);
.
    rv = listener->InitializeEmbeded(aURL, nsnull, aOwner, (nsIPluginHost *)th
is);
  else
.
  else
    rv = NS_ERROR_ILLEGAL_VALUE;
.
    rv = NS_ERROR_ILLEGAL_VALUE;
 
.
 
  if (NS_OK == rv) {
.
  if (NS_OK == rv) {
    // XXX: Null LoadGroup?
.
    // XXX: Null LoadGroup?
    rv = NS_OpenURI(listener, nsnull, aURL, nsnull);
.
    rv = NS_OpenURI(listener, nsnull, aURL, nsnull);
  }
.
  }
 
.
 
  //NS_RELEASE(aURL);
.
  //NS_RELEASE(aURL);
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
/* Called by InstantiateFullPagePlugin() */
.
/* Called by InstantiateFullPagePlugin() */
 
.
 
nsresult nsPluginHostImpl::NewFullPagePluginStream(nsIStreamListener *&aStream
Listener, 
.
nsresult nsPluginHostImpl::NewFullPagePluginStream(nsIStreamListener *&aStream
Listener, 
                                                   nsIPluginInstance *aInstanc
e)
.
                                                   nsIPluginInstance *aInstanc
e)
{
.
{
  nsPluginStreamListenerPeer  *listener = (nsPluginStreamListenerPeer *)new ns
PluginStreamListenerPeer();
.
  nsPluginStreamListenerPeer  *listener = (nsPluginStreamListenerPeer *)new ns
PluginStreamListenerPeer();
  if (listener == nsnull)
.
  if (listener == nsnull)
    return NS_ERROR_OUT_OF_MEMORY;
.
    return NS_ERROR_OUT_OF_MEMORY;
 
.
 
  nsresult rv;
.
  nsresult rv;
 
.
 
  rv = listener->InitializeFullPage(aInstance);
.
  rv = listener->InitializeFullPage(aInstance);
 
.
 
  aStreamListener = (nsIStreamListener *)listener;
.
  aStreamListener = (nsIStreamListener *)listener;
  NS_IF_ADDREF(listener);
.
  NS_IF_ADDREF(listener);
 
.
 
  return rv;
.
  return rv;
}
.
}
 
.
 
// nsIFileUtilities interface
.
// nsIFileUtilities interface
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetProgramPath(const char* *result)
.
NS_IMETHODIMP nsPluginHostImpl::GetProgramPath(const char* *result)
{
.
{
	static nsSpecialSystemDirectory programDir(nsSpecialSystemDirectory::OS_Curre
ntProcessDirectory);
.
	static nsSpecialSystemDirectory programDir(nsSpecialSystemDirectory::OS_Curre
ntProcessDirectory);
	*result = programDir;
.
	*result = programDir;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetTempDirPath(const char* *result)
.
NS_IMETHODIMP nsPluginHostImpl::GetTempDirPath(const char* *result)
{
.
{
	static nsSpecialSystemDirectory tempDir(nsSpecialSystemDirectory::OS_Temporar
yDirectory);
.
	static nsSpecialSystemDirectory tempDir(nsSpecialSystemDirectory::OS_Temporar
yDirectory);
	*result = tempDir;
.
	*result = tempDir;
	return NS_OK;
.
	return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::NewTempFileName(const char* prefix, PRUint32 b
ufLen, char* resultBuf)
.
NS_IMETHODIMP nsPluginHostImpl::NewTempFileName(const char* prefix, PRUint32 b
ufLen, char* resultBuf)
{
.
{
	return NS_ERROR_NOT_IMPLEMENTED;
.
	return NS_ERROR_NOT_IMPLEMENTED;
}
.
}
 
.
 
// nsICookieStorage interface
.
// nsICookieStorage interface
 
.
 
NS_IMETHODIMP nsPluginHostImpl::GetCookie(const char* inCookieURL, void* inOut
CookieBuffer, PRUint32& inOutCookieSize)
.
NS_IMETHODIMP nsPluginHostImpl::GetCookie(const char* inCookieURL, void* inOut
CookieBuffer, PRUint32& inOutCookieSize)
{
.
{
  nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
.
  nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
  nsString cookieString;
.
  nsString cookieString;
  nsCOMPtr<nsIURI> uriIn;
.
  nsCOMPtr<nsIURI> uriIn;
  char *bufPtr;
.
  char *bufPtr;
  
.
  
  if ((nsnull == inCookieURL) || (0 >= inOutCookieSize)) {
.
  if ((nsnull == inCookieURL) || (0 >= inOutCookieSize)) {
    return NS_ERROR_INVALID_ARG;
.
    return NS_ERROR_INVALID_ARG;
  }
.
  }
 
.
 
  NS_WITH_SERVICE(nsIIOService, ioService, kIOServiceCID, &rv);
.
  NS_WITH_SERVICE(nsIIOService, ioService, kIOServiceCID, &rv);
  
.
  
  if (NS_FAILED(rv) || (nsnull == ioService)) {
.
  if (NS_FAILED(rv) || (nsnull == ioService)) {
    return rv;
.
    return rv;
  }
.
  }
 
.
 
  NS_WITH_SERVICE(nsICookieService, cookieService, kCookieServiceCID, &rv);
.
  NS_WITH_SERVICE(nsICookieService, cookieService, kCookieServiceCID, &rv);
  
.
  
  if (NS_FAILED(rv) || (nsnull == cookieService)) {
.
  if (NS_FAILED(rv) || (nsnull == cookieService)) {
    return NS_ERROR_INVALID_ARG;
.
    return NS_ERROR_INVALID_ARG;
  }
.
  }
 
.
 
  // make an nsURI from the argument url
.
  // make an nsURI from the argument url
  rv = ioService->NewURI(inCookieURL, nsnull, getter_AddRefs(uriIn));
.
  rv = ioService->NewURI(inCookieURL, nsnull, getter_AddRefs(uriIn));
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    return rv;
.
    return rv;
  }
.
  }
 
.
 
  rv = cookieService->GetCookieString(uriIn, &bufPtr);
.
  rv = cookieService->GetCookieString(uriIn, &bufPtr);
  
.
  
  if (NS_FAILED(rv) || (nsnull == bufPtr) ||
.
  if (NS_FAILED(rv) || (nsnull == bufPtr) ||
      (inOutCookieSize < PL_strlen(bufPtr))) {
.
      (inOutCookieSize < PL_strlen(bufPtr))) {
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
  }
.
  }
  bufPtr = cookieString.ToCString((char *) inOutCookieBuffer, 
.
  bufPtr = cookieString.ToCString((char *) inOutCookieBuffer, 
                                  inOutCookieSize);
.
                                  inOutCookieSize);
  inOutCookieSize = PL_strlen(bufPtr);
.
  inOutCookieSize = PL_strlen(bufPtr);
  rv = NS_OK;
.
  rv = NS_OK;
  
.
  
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::SetCookie(const char* inCookieURL, const void*
 inCookieBuffer, PRUint32 inCookieSize)
.
NS_IMETHODIMP nsPluginHostImpl::SetCookie(const char* inCookieURL, const void*
 inCookieBuffer, PRUint32 inCookieSize)
{
.
{
  nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
.
  nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
  nsCOMPtr<nsIURI> uriIn;
.
  nsCOMPtr<nsIURI> uriIn;
  
.
  
  if ((nsnull == inCookieURL) || (nsnull == inCookieBuffer) || 
.
  if ((nsnull == inCookieURL) || (nsnull == inCookieBuffer) || 
      (0 >= inCookieSize)) {
.
      (0 >= inCookieSize)) {
    return NS_ERROR_INVALID_ARG;
.
    return NS_ERROR_INVALID_ARG;
  }
.
  }
  
.
  
  NS_WITH_SERVICE(nsIIOService, ioService, kIOServiceCID, &rv);
.
  NS_WITH_SERVICE(nsIIOService, ioService, kIOServiceCID, &rv);
  
.
  
  if (NS_FAILED(rv) || (nsnull == ioService)) {
.
  if (NS_FAILED(rv) || (nsnull == ioService)) {
    return rv;
.
    return rv;
  }
.
  }
  
.
  
  NS_WITH_SERVICE(nsICookieService, cookieService, kCookieServiceCID, &rv);
.
  NS_WITH_SERVICE(nsICookieService, cookieService, kCookieServiceCID, &rv);
  
.
  
  if (NS_FAILED(rv) || (nsnull == cookieService)) {
.
  if (NS_FAILED(rv) || (nsnull == cookieService)) {
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
  }
.
  }
  
.
  
  // make an nsURI from the argument url
.
  // make an nsURI from the argument url
  rv = ioService->NewURI(inCookieURL, nsnull, getter_AddRefs(uriIn));
.
  rv = ioService->NewURI(inCookieURL, nsnull, getter_AddRefs(uriIn));
  if (NS_FAILED(rv)) {
.
  if (NS_FAILED(rv)) {
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
  }
.
  }
 
.
 
  char * cookie = (char *)inCookieBuffer;
.
  char * cookie = (char *)inCookieBuffer;
  char c = cookie[inCookieSize];
.
  char c = cookie[inCookieSize];
  cookie[inCookieSize] = '\0';
.
  cookie[inCookieSize] = '\0';
  rv = cookieService->SetCookieString(uriIn, nsnull, cookie); // needs an nsIP
rompt parameter
.
  rv = cookieService->SetCookieString(uriIn, nsnull, cookie); // needs an nsIP
rompt parameter
  cookie[inCookieSize] = c;
.
  cookie[inCookieSize] = c;
  
.
  
  return rv;
.
  return rv;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::Observe(nsISupports *aSubject,
.
NS_IMETHODIMP nsPluginHostImpl::Observe(nsISupports *aSubject,
                                        const PRUnichar *aTopic,
.
                                        const PRUnichar *aTopic,
                                        const PRUnichar *someData)
.
                                        const PRUnichar *someData)
{
.
{
#ifdef NS_DEBUG
.
#ifdef NS_DEBUG
  nsAutoString topic(aTopic);
.
  nsAutoString topic(aTopic);
  char * newString = topic.ToNewCString();
.
  char * newString = topic.ToNewCString();
  printf("nsPluginHostImpl::Observe \"%s\"\n", newString ? newString : "");
.
  printf("nsPluginHostImpl::Observe \"%s\"\n", newString ? newString : "");
  if (newString)
.
  if (newString)
    nsCRT::free(newString);
.
    nsCRT::free(newString);
#endif
.
#endif
  if (NS_ConvertASCIItoUCS2(NS_XPCOM_SHUTDOWN_OBSERVER_ID).Equals(aTopic) ||
.
  if (NS_ConvertASCIItoUCS2(NS_XPCOM_SHUTDOWN_OBSERVER_ID).Equals(aTopic) ||
      NS_LITERAL_STRING("quit-application").Equals(aTopic))
.
      NS_LITERAL_STRING("quit-application").Equals(aTopic))
  {
.
  {
    Destroy();
.
    Destroy();
  }
.
  }
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP 
.
NS_IMETHODIMP 
nsPluginHostImpl::SetIsScriptableInstance(nsCOMPtr<nsIPluginInstance> aPluginI
nstance, 
.
nsPluginHostImpl::SetIsScriptableInstance(nsCOMPtr<nsIPluginInstance> aPluginI
nstance, 
                                        PRBool aScriptable)
.
                                        PRBool aScriptable)
{
.
{
  nsActivePlugin * p = mActivePluginList.find(aPluginInstance.get());
.
  nsActivePlugin * p = mActivePluginList.find(aPluginInstance.get());
  if(p == nsnull)
.
  if(p == nsnull)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  p->mXPConnected = aScriptable;
.
  p->mXPConnected = aScriptable;
  if(p->mPluginTag)
.
  if(p->mPluginTag)
    p->mPluginTag->mXPConnected = aScriptable;
.
    p->mPluginTag->mXPConnected = aScriptable;
 
.
 
  return NS_OK;
.
  return NS_OK;
}
.
}
 
.
 
NS_IMETHODIMP nsPluginHostImpl::HandleBadPlugin(PRLibrary* aLibrary)
.
NS_IMETHODIMP nsPluginHostImpl::HandleBadPlugin(PRLibrary* aLibrary)
{
.
{
  nsresult rv = NS_OK;
.
  nsresult rv = NS_OK;
 
.
 
  NS_ASSERTION(PR_FALSE, "Plugin performed illegal operation");
.
  NS_ASSERTION(PR_FALSE, "Plugin performed illegal operation");
 
.
 
  if(mDontShowBadPluginMessage)
.
  if(mDontShowBadPluginMessage)
    return rv;
.
    return rv;
  
.
  
  nsCOMPtr<nsIPrompt> prompt;
.
  nsCOMPtr<nsIPrompt> prompt;
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/wind
ow-watcher;1"));
.
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/wind
ow-watcher;1"));
  if (wwatch)
.
  if (wwatch)
    wwatch->GetNewPrompter(0, getter_AddRefs(prompt));
.
    wwatch->GetNewPrompter(0, getter_AddRefs(prompt));
 
.
 
  nsCOMPtr<nsIIOService> io(do_GetService(kIOServiceCID));
.
  nsCOMPtr<nsIIOService> io(do_GetService(kIOServiceCID));
  nsCOMPtr<nsIStringBundleService> strings(do_GetService(kStringBundleServiceC
ID));
.
  nsCOMPtr<nsIStringBundleService> strings(do_GetService(kStringBundleServiceC
ID));
 
.
 
  if (!prompt || !io || !strings)
.
  if (!prompt || !io || !strings)
    return NS_ERROR_FAILURE;
.
    return NS_ERROR_FAILURE;
 
.
 
  nsCOMPtr<nsIStringBundle> bundle;
.
  nsCOMPtr<nsIStringBundle> bundle;
  nsCOMPtr<nsIURI> uri;
.
  nsCOMPtr<nsIURI> uri;
  char *spec = nsnull;
.
  char *spec = nsnull;
 
.
 
  PRInt32 buttonPressed;
.
  PRInt32 buttonPressed;
  PRBool checkboxState = PR_FALSE;
.
  PRBool checkboxState = PR_FALSE;
  
.
  
  rv = io->NewURI(PLUGIN_PROPERTIES_URL, nsnull, getter_AddRefs(uri));
.
  rv = io->NewURI(PLUGIN_PROPERTIES_URL, nsnull, getter_AddRefs(uri));
  if (NS_FAILED(rv))
.
  if (NS_FAILED(rv))
    return rv;
.
    return rv;
 
.
 
  rv = uri->GetSpec(&spec);
.
  rv = uri->GetSpec(&spec);
  if (NS_FAILED(rv)) 
.
  if (NS_FAILED(rv)) 
  {
.
  {
    nsCRT::free(spec);
.
    nsCRT::free(spec);
    return rv;
.
    return rv;
  }
.
  }
 
.
 
  rv = strings->CreateBundle(spec, getter_AddRefs(bundle));
.
  rv = strings->CreateBundle(spec, getter_AddRefs(bundle));
  nsCRT::free(spec);
.
  nsCRT::free(spec);
  if (NS_FAILED(rv))
.
  if (NS_FAILED(rv))
    return rv;
.
    return rv;
 
.
 
  PRUnichar *title = nsnull;
.
  PRUnichar *title = nsnull;
  PRUnichar *message = nsnull;
.
  PRUnichar *message = nsnull;
  PRUnichar *checkboxMessage = nsnull;
.
  PRUnichar *checkboxMessage = nsnull;
 
.
 
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginTitle").get(), 
.
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginTitle").get(), 
                                 &title);
.
                                 &title);
  if (NS_FAILED(rv))
.
  if (NS_FAILED(rv))
    return rv;
.
    return rv;
 
.
 
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginMessage").get(), 
.
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginMessage").get(), 
                                 &message);
.
                                 &message);
  if (NS_FAILED(rv))
.
  if (NS_FAILED(rv))
  {
.
  {
    nsMemory::Free((void *)title);
.
    nsMemory::Free((void *)title);
    return rv;
.
    return rv;
  }
.
  }
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginCheckboxMessage")
.get(), 
.
  rv = bundle->GetStringFromName(NS_LITERAL_STRING("BadPluginCheckboxMessage")
.get(), 
                                 &checkboxMessage);
.
                                 &checkboxMessage);
  if (NS_FAILED(rv))
.
  if (NS_FAILED(rv))
  {
.
  {
    nsMemory::Free((void *)title);
.
    nsMemory::Free((void *)title);
    nsMemory::Free((void *)message);
.
    nsMemory::Free((void *)message);
    return rv;
.
    return rv;
  }
.
  }
                               
.
                               
  rv = prompt->ConfirmEx(title, message,
.
  rv = prompt->ConfirmEx(title, message,
                         nsIPrompt::BUTTON_TITLE_OK * nsIPrompt::BUTTON_POS_0,
.
                         nsIPrompt::BUTTON_TITLE_OK * nsIPrompt::BUTTON_POS_0,
                         nsnull, nsnull, nsnull,
.
                         nsnull, nsnull, nsnull,
                         checkboxMessage, &checkboxState, &buttonPressed);
.
                         checkboxMessage, &checkboxState, &buttonPressed);
 
.
 
 
.
 
  if (checkboxState)
.
  if (checkboxState)
    mDontShowBadPluginMessage = PR_TRUE;
.
    mDontShowBadPluginMessage = PR_TRUE;
 
.
 
  nsMemory::Free((void *)title);
.
  nsMemory::Free((void *)title);
  nsMemory::Free((void *)message);
.
  nsMemory::Free((void *)message);
  nsMemory::Free((void *)checkboxMessage);
.
  nsMemory::Free((void *)checkboxMessage);
  return rv;
.
  return rv;
}
.
}