From 55ae26173af40b0651fb4d7df2501b7af7bda53b Mon Sep 17 00:00:00 2001 From: warren Date: Sat, 11 Jul 1998 01:39:51 +0000 Subject: [PATCH] Fixed up and moved backward adapter from oji dir. --- modules/plugin/bad/badapter.cpp | 1395 ++++++++++++++++++ modules/plugin/samples/backward/badapter.cpp | 1395 ++++++++++++++++++ 2 files changed, 2790 insertions(+) create mode 100644 modules/plugin/bad/badapter.cpp create mode 100644 modules/plugin/samples/backward/badapter.cpp diff --git a/modules/plugin/bad/badapter.cpp b/modules/plugin/bad/badapter.cpp new file mode 100644 index 000000000000..9aad2c653909 --- /dev/null +++ b/modules/plugin/bad/badapter.cpp @@ -0,0 +1,1395 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +//////////////////////////////////////////////////////////////////////////////// +// Backward Adapter +// This acts as a adapter layer to allow 5.0 plugins work with the 4.0/3.0 +// browser. +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 1 - Includes +//////////////////////////////////////////////////////////////////////////////// + +extern "C" { +#include "npapi.h" +}; +#include "nsplugin.h" +#include "nsDebug.h" + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 3 - Classes +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginManager +// +// This is the dummy plugin manager that interacts with the 5.0 plugin. +// +class CPluginManager : public nsIPluginManager { +public: + + CPluginManager(void); + virtual ~CPluginManager(void); + + NS_DECL_ISUPPORTS + + NS_IMETHOD_(void) + ReloadPlugins(PRBool reloadPages); + + NS_IMETHOD_(void* ) + MemAlloc(PRUint32 size); + + NS_IMETHOD_(void) + MemFree(void* ptr); + + NS_IMETHOD_(PRUint32) + MemFlush(PRUint32 size); + + // (Corresponds to NPN_GetValue.) + NS_IMETHOD_(nsPluginError) + GetValue(nsPluginManagerVariable variable, void *value); + + // (Corresponds to NPN_SetValue.) + NS_IMETHOD_(nsPluginError) + SetValue(nsPluginManagerVariable variable, void *value); + + // (Corresponds to NPN_UserAgent.) + NS_IMETHOD_(const char*) + UserAgent(void); + + // (Corresponds to NPN_GetURL and NPN_GetURLNotify.) + // notifyData: When present, URLNotify is called passing the notifyData back + // to the client. When NULL, this call behaves like NPN_GetURL. + // New arguments: + // peer: A plugin instance peer. The peer's window will be used to display + // progress information. If NULL, the load happens in the background. + // altHost: An IP-address string that will be used instead of the host + // specified in the URL. This is used to prevent DNS-spoofing attacks. + // Can be defaulted to NULL meaning use the host in the URL. + // referrer: + // forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, + // even if the user currently has JavaScript disabled. + NS_IMETHOD_(nsPluginError) + GetURL(nsISupports* peer, const char* url, const char* target, void* notifyData = NULL, + const char* altHost = NULL, const char* referrer = NULL, + PRBool forceJSEnabled = PR_FALSE); + + // (Corresponds to NPN_PostURL and NPN_PostURLNotify.) + // notifyData: When present, URLNotify is called passing the notifyData back + // to the client. When NULL, this call behaves like NPN_GetURL. + // New arguments: + // peer: A plugin instance peer. The peer's window will be used to display + // progress information. If NULL, the load happens in the background. + // altHost: An IP-address string that will be used instead of the host + // specified in the URL. This is used to prevent DNS-spoofing attacks. + // Can be defaulted to NULL meaning use the host in the URL. + // referrer: + // forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, + // even if the user currently has JavaScript disabled. + // postHeaders: A string containing post headers. + // postHeadersLength: The length of the post headers string. + NS_IMETHOD_(nsPluginError) + PostURL(nsISupports* peer, const char* url, const char* target, PRUint32 bufLen, + const char* buf, PRBool file, void* notifyData = NULL, + const char* altHost = NULL, const char* referrer = NULL, + PRBool forceJSEnabled = PR_FALSE, + PRUint32 postHeadersLength = 0, const char* postHeaders = NULL); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginManagerStream +// +// This is the dummy plugin manager stream that interacts with the 5.0 plugin. +// +class CPluginManagerStream : public nsIOutputStream { + +public: + + CPluginManagerStream(NPP npp, NPStream* pstr); + virtual ~CPluginManagerStream(void); + + NS_DECL_ISUPPORTS + + ////////////////////////////////////////////////////////////////////////// + // + // Taken from nsIStream + // + + // The Release function in nsISupport will take care of destroying the stream. + + NS_IMETHOD_(PRInt32) + Write (const char* buffer, PRInt32 offset, PRInt32 len, nsresult* error); + // XXX - Hmm? Why is there an extra parameter offset? + // (NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer); + + ////////////////////////////////////////////////////////////////////////// + // + // Specific methods to nsIPluginManagerStream. + // + + // Corresponds to NPStream's url field. + NS_IMETHOD_(const char* ) + GetURL(void); + + // Corresponds to NPStream's end field. + NS_IMETHOD_(PRUint32) + GetEnd(void); + + // Corresponds to NPStream's lastmodfied field. + NS_IMETHOD_(PRUint32) + GetLastModified(void); + + // Corresponds to NPStream's notifyData field. + NS_IMETHOD_(void* ) + GetNotifyData(void); + + // Corresponds to NPStream's url field. + NS_IMETHOD Close(void); + +protected: + + // npp + // The plugin instance that the manager stream belongs to. + NPP npp; + + // pstream + // The stream the class is using. + NPStream* pstream; + +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginInstancePeer +// +// This is the dummy instance peer that interacts with the 5.0 plugin. +// In order to do LiveConnect, the class subclasses nsILiveConnectPluginInstancePeer. +// +class CPluginInstancePeer : public nsIPluginInstancePeer, public nsIPluginTagInfo { + +public: + + // XXX - I add parameters to the constructor because I wasn't sure if + // XXX - the 4.0 browser had the npp_instance struct implemented. + // XXX - If so, then I can access npp_instance through npp->ndata. + CPluginInstancePeer(NPP npp, nsMIMEType typeString, nsPluginType type, + PRUint16 attribute_cnt, const char** attribute_list, const char** values_list); + virtual ~CPluginInstancePeer(void); + + NS_DECL_ISUPPORTS + + // Corresponds to NPP_New's MIMEType argument. + NS_IMETHOD_(nsMIMEType) + GetMIMEType(void); + + // Corresponds to NPP_New's mode argument. + NS_IMETHOD_(nsPluginType) + GetMode(void); + + // Get a ptr to the paired list of attribute names and values, + // returns the length of the array. + // + // Each name or value is a null-terminated string. + NS_IMETHOD_(nsPluginError) + GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values); + + // Get the value for the named attribute. Returns null + // if the attribute was not set. + NS_IMETHOD_(const char*) + GetAttribute(const char* name); + + // Corresponds to NPN_NewStream. + NS_IMETHOD_(nsPluginError) + NewStream(nsMIMEType type, const char* target, nsIOutputStream* *result); + + // Corresponds to NPN_ShowStatus. + NS_IMETHOD_(void) + ShowStatus(const char* message); + + // XXX - Where did this go? + NS_IMETHOD_(void) + Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor); + + NPP GetNPPInstance(void) { + return npp; + } +protected: + + NPP npp; + // XXX - The next five variables may need to be here since I + // XXX - don't think np_instance is available in 4.0X. + nsMIMEType typeString; + nsPluginType type; + PRUint16 attribute_cnt; + char** attribute_list; + char** values_list; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginStreamPeer +// +// This is the dummy stream peer that interacts with the 5.0 plugin. +// +class CPluginStreamPeer : public nsISeekablePluginStreamPeer, public nsIPluginStreamPeer { + +public: + + CPluginStreamPeer(nsMIMEType type, NPStream* npStream, + PRBool seekable, PRUint16* stype); + virtual ~CPluginStreamPeer(); + + NS_DECL_ISUPPORTS + + // (Corresponds to NPStream's url field.) + NS_IMETHOD_(const char*) + GetURL(void); + + // (Corresponds to NPStream's end field.) + NS_IMETHOD_(PRUint32) + GetEnd(void); + + // (Corresponds to NPStream's lastmodified field.) + NS_IMETHOD_(PRUint32) + GetLastModified(void); + + // (Corresponds to NPStream's notifyData field.) + NS_IMETHOD_(void*) + GetNotifyData(void); + + ////////////////////////////////////////////////////////////////////////// + // + // From nsIPluginStreamPeer + // + + // Corresponds to NPP_DestroyStream's reason argument. + NS_IMETHOD_(nsPluginReason) + GetReason(void); + + // Corresponds to NPP_NewStream's MIMEType argument. + NS_IMETHOD_(nsMIMEType) + GetMIMEType(void); + + ////////////////////////////////////////////////////////////////////////// + // + // From nsISeekablePluginStreamPeer + // + + // Corresponds to NPN_RequestRead. + NS_IMETHOD_(nsPluginError) + RequestRead(nsByteRange* rangeList); + +protected: + + nsMIMEType type; + NPStream* npStream; + PRBool seekable; + PRUint16* stype; + nsPluginReason reason; + +}; + +////////////////////////////////////////////////////////////////////////////// + +#ifdef XP_UNIX +#define TRACE(foo) trace(foo) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 1 - Includes +//////////////////////////////////////////////////////////////////////////////// + +#ifdef XP_UNIX +#include +#include +#include +#else +#include +#endif + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 2 - Globar Variables +//////////////////////////////////////////////////////////////////////////////// + +// +// thePlugin and thePluginManager are used in the life of the plugin. +// +// These two will be created on NPP_Initialize and destroyed on NPP_Shutdown. +// +nsIPluginManager* thePluginManager = NULL; +nsIPlugin* thePlugin = NULL; + +// +// nsISupports IDs +// +// Interface IDs for nsISupports +// +NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +NS_DEFINE_IID(kPluginIID, NS_IPLUGIN_IID); +NS_DEFINE_IID(kPluginInstanceIID, NS_IPLUGININSTANCE_IID); +NS_DEFINE_IID(kPluginManagerIID, NS_IPLUGINMANAGER_IID); +NS_DEFINE_IID(kPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); +NS_DEFINE_IID(kOutputStreamIID, NS_IOUTPUTSTREAM_IID); +NS_DEFINE_IID(kPluginInstancePeerIID, NS_IPLUGININSTANCEPEER_IID); +NS_DEFINE_IID(kPluginStreamPeerIID, NS_IPLUGINSTREAMPEER_IID); +NS_DEFINE_IID(kSeekablePluginStreamPeerIID, NS_ISEEKABLEPLUGINSTREAMPEER_IID); + + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 4 - API Shim Plugin Implementations +// Glue code to the 5.0x Plugin. +// +// Most of the NPP_* functions that interact with the plug-in will need to get +// the instance peer from npp->pdata so it can get the plugin instance from the +// peer. Once the plugin instance is available, the appropriate 5.0 plug-in +// function can be called: +// +// CPluginInstancePeer* peer = (CPluginInstancePeer* )instance->pdata; +// nsIPluginInstance* inst = peer->GetUserInstance(); +// inst->NewPluginAPIFunction(); +// +// Similar steps takes place with streams. The stream peer is stored in NPStream's +// pdata. Get the peer, get the stream, call the function. +// + +//////////////////////////////////////////////////////////////////////////////// +// UNIX-only API calls +//////////////////////////////////////////////////////////////////////////////// +#ifdef XP_UNIX +char* NPP_GetMIMEDescription(void) +{ + int freeFac = 0; + fprintf(stderr, "MIME description\n"); + if (thePlugin == NULL) { + freeFac = 1; + NSGetFactory(kPluginIID, (nsIFactory** )(&thePlugin)); + } + fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin); + char * ret = (char *) thePlugin->GetMIMEDescription(); + fprintf(stderr, "Get response %s\n", ret); + if (freeFac) { + fprintf(stderr, "Freeing plugin..."); + thePlugin->Release(); + thePlugin = NULL; + } + fprintf(stderr, "Done\n"); + return ret; +} + + +//------------------------------------------------------------------------------ +// Cross-Platform Plug-in API Calls +//------------------------------------------------------------------------------ + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_SetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_SetValue(NPP instance, NPNVariable variable, void *value) +{ + return (NPError)nsPluginError_NoError; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_GetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_GetValue(NPP instance, NPPVariable variable, void *value) { + int freeFac = 0; + fprintf(stderr, "MIME description\n"); + if (thePlugin == NULL) { + freeFac = 1; + if (NSGetFactory(kPluginIID, (nsIFactory** )(&thePlugin)) != NS_OK) + return NPERR_GENERIC_ERROR; + } + fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin); + NPError ret = (NPError) thePlugin->GetValue((nsPluginVariable)variable, value); + fprintf(stderr, "Get response %08x\n", ret); + if (freeFac) { + fprintf(stderr, "Freeing plugin..."); + thePlugin->Release(); + thePlugin = NULL; + } + fprintf(stderr, "Done\n"); + return ret; +} +#endif +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Initialize: +// Provides global initialization for a plug-in, and returns an error value. +// +// This function is called once when a plug-in is loaded, before the first instance +// is created. thePluginManager and thePlugin are both initialized. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_Initialize(void) +{ +// TRACE("NPP_Initialize\n"); + + // Only call initialize the plugin if it hasn't been created. + // This could happen if GetJavaClass() is called before + // NPP Initialize. + if (thePluginManager == NULL) { + // Create the plugin manager and plugin classes. + thePluginManager = new CPluginManager(); + if ( thePluginManager == NULL ) + return NPERR_OUT_OF_MEMORY_ERROR; + thePluginManager->AddRef(); + } + nsresult error = NS_OK; + // On UNIX the plugin might have been created when calling NPP_GetMIMEType. + if (thePlugin == NULL) + // create nsIPlugin factory + error = (NPError)NSGetFactory(kPluginIID, (nsIFactory**) &thePlugin); + if (error == NS_OK) + thePlugin->Initialize(thePluginManager); + + return (NPError) error; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_GetJavaClass: +// New in Netscape Navigator 3.0. +// +// NPP_GetJavaClass is called during initialization to ask your plugin +// what its associated Java class is. If you don't have one, just return +// NULL. Otherwise, use the javah-generated "use_" function to both +// initialize your class and return it. If you can't find your class, an +// error will be signalled by "use_" and will cause the Navigator to +// complain to the user. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +jref +NPP_GetJavaClass(void) +{ + // Only call initialize the plugin if it hasn't been `d. + /* if (thePluginManager == NULL) { + // Create the plugin manager and plugin objects. + NPError result = CPluginManager::Create(); + if (result) return NULL; + assert( thePluginManager != NULL ); + thePluginManager->AddRef(); + NP_CreatePlugin(thePluginManager, (nsIPlugin** )(&thePlugin)); + assert( thePlugin != NULL ); + } +*/ +// return thePlugin->GetJavaClass(); + return NULL; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Shutdown: +// Provides global deinitialization for a plug-in. +// +// This function is called once after the last instance of your plug-in +// is destroyed. thePluginManager and thePlugin are delete at this time. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_Shutdown(void) +{ +// TRACE("NPP_Shutdown\n"); + + if (thePlugin) + { + thePlugin->Shutdown(); + thePlugin->Release(); + thePlugin = NULL; + } + + if (thePluginManager) { + thePluginManager->Release(); + thePluginManager = NULL; + } + + return; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_New: +// Creates a new instance of a plug-in and returns an error value. +// +// A plugin instance peer and instance peer is created. After +// a successful instansiation, the peer is stored in the plugin +// instance's pdata. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_New(NPMIMEType pluginType, + NPP instance, + PRUint16 mode, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved) +{ +// TRACE("NPP_New\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + // Create a new plugin instance and start it. + nsIPluginInstance* pluginInstance = NULL; + thePlugin->CreateInstance(NULL, kPluginInstanceIID, (void**)&pluginInstance); + if (pluginInstance == NULL) { + return NPERR_OUT_OF_MEMORY_ERROR; + } + + // Create a new plugin instance peer, + // XXX - Since np_instance is not implemented in the 4.0x browser, I + // XXX - had to save the plugin parameter in the peer class. + // XXX - Ask Warren about np_instance. + CPluginInstancePeer* peer = + new CPluginInstancePeer(instance, (nsMIMEType)pluginType, + (nsPluginType)mode, (PRUint16)argc, + (const char** )argn, (const char** )argv); + assert( peer != NULL ); + if (!peer) return NPERR_OUT_OF_MEMORY_ERROR; + peer->AddRef(); + pluginInstance->Initialize(peer); + pluginInstance->Start(); + // Set the user instance and store the peer in npp->pdata. + instance->pdata = pluginInstance; + peer->Release(); + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Destroy: +// Deletes a specific instance of a plug-in and returns an error value. +// +// The plugin instance peer and plugin instance are destroyed. +// The instance's pdata is set to NULL. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_Destroy(NPP instance, NPSavedData** save) +{ +// TRACE("NPP_Destroy\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance* pluginInstance = (nsIPluginInstance* )instance->pdata; + pluginInstance->Stop(); + pluginInstance->Destroy(); + pluginInstance->Release(); + instance->pdata = NULL; + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_SetWindow: +// Sets the window in which a plug-in draws, and returns an error value. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_SetWindow(NPP instance, NPWindow* window) +{ +// TRACE("NPP_SetWindow\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance* pluginInstance = (nsIPluginInstance* )instance->pdata; + + if( pluginInstance == 0 ) + return NPERR_INVALID_PLUGIN_ERROR; + + return (NPError)pluginInstance->SetWindow((nsPluginWindow* ) window ); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_NewStream: +// Notifies an instance of a new data stream and returns an error value. +// +// Create a stream peer and stream. If succesful, save +// the stream peer in NPStream's pdata. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_NewStream(NPP instance, + NPMIMEType type, + NPStream *stream, + NPBool seekable, + PRUint16 *stype) +{ + // XXX - How do you set the fields of the peer stream and stream? + // XXX - Looks like these field will have to be created since + // XXX - We are not using np_stream. + +// TRACE("NPP_NewStream\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + // Create a new plugin stream peer and plugin stream. + CPluginStreamPeer* speer = new CPluginStreamPeer((nsMIMEType)type, stream, + (PRBool)seekable, stype); + if (speer == NULL) return NPERR_OUT_OF_MEMORY_ERROR; + speer->AddRef(); + nsIPluginStream* pluginStream = NULL; + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + NPError result = (NPError)pluginInstance->NewStream(speer, &pluginStream); + speer->Release(); + + if (pluginStream == NULL) + return NPERR_OUT_OF_MEMORY_ERROR; + + stream->pdata = (void*) pluginStream; + *stype = pluginStream->GetStreamType(); + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_WriteReady: +// Returns the maximum number of bytes that an instance is prepared to accept +// from the stream. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +int32 +NPP_WriteReady(NPP instance, NPStream *stream) +{ +// TRACE("NPP_WriteReady\n"); + + if (instance == NULL) + return -1; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return -1; + + return 8192; +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Write: +// Delivers data from a stream and returns the number of bytes written. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +int32 +NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) +{ +// TRACE("NPP_Write\n"); + + if (instance == NULL) + return -1; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return -1; + + nsresult result; + return theStream->Write((const char* )buffer, offset, len, &result); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_DestroyStream: +// Indicates the closure and deletion of a stream, and returns an error value. +// +// The stream peer and stream are destroyed. NPStream's +// pdata is set to NULL. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) +{ +// TRACE("NPP_DestroyStream\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return NPERR_GENERIC_ERROR; + + theStream->Release(); + stream->pdata = NULL; + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_StreamAsFile: +// Provides a local file name for the data from a stream. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname) +{ +// TRACE("NPP_StreamAsFile\n"); + + if (instance == NULL) + return; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return; + + theStream->AsFile( fname ); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Print: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_Print(NPP instance, NPPrint* printInfo) +{ +// TRACE("NPP_Print\n"); + + if(printInfo == NULL) // trap invalid parm + return; + + if (instance != NULL) + { + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + pluginInstance->Print((nsPluginPrint* ) printInfo ); + } +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_URLNotify: +// Notifies the instance of the completion of a URL request. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) +{ +// TRACE("NPP_URLNotify\n"); + + if( instance != NULL ) + { + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + pluginInstance->URLNotify(url, NULL, (nsPluginReason)reason, notifyData); + + } +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_HandleEvent: +// Mac-only, but stub must be present for Windows +// Delivers a platform-specific event to the instance. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +#ifndef XP_UNIX +int16 +NPP_HandleEvent(NPP instance, void* event) +{ +// TRACE("NPP_HandleEvent\n"); + + int16 eventHandled = FALSE; + if (instance == NULL) + return eventHandled; + + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + if( pluginInstance ) + eventHandled = (int16) pluginInstance->HandleEvent((nsPluginEvent*) event ); + + return eventHandled; +} +#endif // ndef XP_UNIX +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// SECTION 5 - API Browser Implementations +// +// Glue code to the 4.0x Browser. +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginManager +// + +//****************************************************************************** +// +// Once we moved to the new APIs, we need to implement fJVMMgr. +// +//****************************************************************************** + +CPluginManager::CPluginManager(void) +{ + // Set reference count to 0. + NS_INIT_REFCNT(); +} + +CPluginManager::~CPluginManager(void) +{ +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// MemAlloc: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void* NP_LOADDS +CPluginManager::MemAlloc(PRUint32 size) +{ + return NPN_MemAlloc(size); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// MemFree: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginManager::MemFree(void* ptr) +{ + assert( ptr != NULL ); + + NPN_MemFree(ptr); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// MemFlush: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 NP_LOADDS +CPluginManager::MemFlush(PRUint32 size) +{ +#ifdef XP_MAC + return NPN_MemFlush(size); +#else + return 0; +#endif +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// ReloadPlugins: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginManager::ReloadPlugins(PRBool reloadPages) +{ + NPN_ReloadPlugins(reloadPages); +} + + +// (Corresponds to NPN_GetURL and NPN_GetURLNotify.) +// notifyData: When present, URLNotify is called passing the notifyData back +// to the client. When NULL, this call behaves like NPN_GetURL. +// New arguments: +// peer: A plugin instance peer. The peer's window will be used to display +// progress information. If NULL, the load happens in the background. +// altHost: An IP-address string that will be used instead of the host +// specified in the URL. This is used to prevent DNS-spoofing attacks. +// Can be defaulted to NULL meaning use the host in the URL. +// referrer: +// forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, +// even if the user currently has JavaScript disabled. +nsPluginError NP_LOADDS +CPluginManager::GetURL(nsISupports* peer, const char* url, const char* target, void* notifyData, + const char* altHost, const char* referrer, PRBool forceJSEnabled) +{ + // assert( npp != NULL ); + // assert( url != NULL ); + assert( peer != NULL); + + CPluginInstancePeer* instancePeer = (CPluginInstancePeer*)(nsIPluginInstancePeer*) peer; + NPP npp = instancePeer->GetNPPInstance(); + + + // Call the correct GetURL* function. + // This is determinded by checking notifyData. + if (notifyData == NULL) { + return (nsPluginError)NPN_GetURL(npp, url, target); + } else { + return (nsPluginError)NPN_GetURLNotify(npp, url, target, notifyData); + } +} + +// (Corresponds to NPN_PostURL and NPN_PostURLNotify.) +// notifyData: When present, URLNotify is called passing the notifyData back +// to the client. When NULL, this call behaves like NPN_GetURL. +// New arguments: +// peer: A plugin instance peer. The peer's window will be used to display +// progress information. If NULL, the load happens in the background. +// altHost: An IP-address string that will be used instead of the host +// specified in the URL. This is used to prevent DNS-spoofing attacks. +// Can be defaulted to NULL meaning use the host in the URL. +// referrer: +// forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, +// even if the user currently has JavaScript disabled. +// postHeaders: A string containing post headers. +// postHeadersLength: The length of the post headers string. +nsPluginError NP_LOADDS +CPluginManager::PostURL(nsISupports* peer, const char* url, const char* target, PRUint32 bufLen, + const char* buf, PRBool file, void* notifyData, const char* altHost, + const char* referrer, PRBool forceJSEnabled, PRUint32 postHeadersLength, + const char* postHeaders) +{ + assert( peer != NULL); + + CPluginInstancePeer* instancePeer = (CPluginInstancePeer*)(nsIPluginInstancePeer*)peer; + NPP npp = instancePeer->GetNPPInstance(); + + // Call the correct PostURL* function. + // This is determinded by checking notifyData. + if (notifyData == NULL) { + return (nsPluginError)NPN_PostURL(npp, url, target, bufLen, buf, file); + } else { + return (nsPluginError)NPN_PostURLNotify(npp, url, target, bufLen, buf, file, notifyData); + } +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// UserAgent: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +const char* NP_LOADDS +CPluginManager::UserAgent(void) +{ + return NPN_UserAgent(NULL); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginManager::GetValue(nsPluginManagerVariable variable, void *value) +{ + // XXX - This may need to be stubbed out for + // XXX - other platforms than Unix. + // XXX - Change this to return NPPPlugin_Error; +#ifdef XP_UNIX + return (nsPluginError)NPN_GetValue(NULL, (NPNVariable)variable, value); +#else + // XXX - Need to check this on the new API. + return nsPluginError_NoData; +#endif // XP_UNIX +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// SetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginManager::SetValue(nsPluginManagerVariable variable, void *value) +{ + // XXX - This should do something like this. + // XXX - return (nsPluginError)npn_setvalue(npp, (NPPVariable)variable, value); + // XXX - Is this XP in 4.0x? + // XXX - Need to check this on the new API. + return nsPluginError_NoData; +} + + + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginManager); +NS_IMPL_RELEASE(CPluginManager); +//NS_IMPL_QUERY_INTERFACE(CPluginManager, kPluginManagerIID); +nsresult CPluginManager::QueryInterface(const nsIID& iid, void** ptr) +{ + if (NULL == ptr) { + return NS_ERROR_NULL_POINTER; + } + + if (iid.Equals(kPluginManagerIID)) { + *ptr = (void*) this; + AddRef(); + return NS_OK; + } + if (iid.Equals(kISupportsIID)) { + *ptr = (void*) ((nsISupports*)this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginInstancePeer +// + +CPluginInstancePeer::CPluginInstancePeer(NPP npp, + nsMIMEType typeString, + nsPluginType type, + PRUint16 attr_cnt, + const char** attr_list, + const char** val_list) + : npp(npp), typeString(typeString), type(type), attribute_cnt(attr_cnt), + attribute_list(NULL), values_list(NULL) +{ + // Set the reference count to 0. + NS_INIT_REFCNT(); + + attribute_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*)); + values_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*)); + + for (int i=0; i < attribute_cnt; i++) { + attribute_list[i] = (char*) NPN_MemAlloc(sizeof(char) + strlen(attr_list[i] + 1)); + values_list[i] = (char*) NPN_MemAlloc(sizeof(char) + strlen(val_list[i] + 1)); + + strcpy(attribute_list[i], attr_list[i]); + strcpy(values_list[i], val_list[i]); + } +} + +CPluginInstancePeer::~CPluginInstancePeer(void) +{ + for (int i=0; i < attribute_cnt; i++) { + NPN_MemFree(attribute_list[i]); + NPN_MemFree(values_list[i]); + } + + NPN_MemFree(attribute_list); + NPN_MemFree(values_list); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetMIMEType: +// Corresponds to NPP_New's MIMEType argument. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsMIMEType NP_LOADDS +CPluginInstancePeer::GetMIMEType(void) +{ + return typeString; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetMode: +// Corresponds to NPP_New's mode argument. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginType NP_LOADDS +CPluginInstancePeer::GetMode(void) +{ + return type; +} + + +// Get a ptr to the paired list of attribute names and values, +// returns the length of the array. +// +// Each name or value is a null-terminated string. +nsPluginError NP_LOADDS +CPluginInstancePeer::GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values) +{ + n = attribute_cnt; + names = attribute_list; + values = values_list; + + return nsPluginError_NoError; +} + + +// Get the value for the named attribute. Returns null +// if the attribute was not set. +const char* NP_LOADDS +CPluginInstancePeer::GetAttribute(const char* name) +{ + for (int i=0; i < attribute_cnt; i++) { +#ifdef XP_UNIX + if (strcasecmp(name, attribute_list[i]) == 0) +#else + if (stricmp(name, attribute_list[i]) == 0) +#endif + return values_list[i]; + } + + return NULL; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// Version: +// +// XXX - Where did this go in the new API? +// +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginInstancePeer::Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor) +{ + NPN_Version(plugin_major, plugin_minor, netscape_major, netscape_minor); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NewStream: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginInstancePeer::NewStream(nsMIMEType type, const char* target, + nsIOutputStream* *result) +{ + assert( npp != NULL ); + + // Create a new NPStream. + NPStream* ptr = NULL; + nsPluginError error = (nsPluginError)NPN_NewStream(npp, (NPMIMEType)type, target, &ptr); + if (error) return error; + + // Create a new Plugin Manager Stream. + // XXX - Do we have to Release() the manager stream before doing this? + // XXX - See the BAM doc for more info. + CPluginManagerStream* mstream = new CPluginManagerStream(npp, ptr); + if (mstream == NULL) return nsPluginError_OutOfMemoryError; + mstream->AddRef(); + *result = (nsIOutputStream* )mstream; + + return nsPluginError_NoError; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// ShowStatus: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginInstancePeer::ShowStatus(const char* message) +{ + assert( message != NULL ); + + NPN_Status(npp, message); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginInstancePeer); +NS_IMPL_RELEASE(CPluginInstancePeer); + + +nsresult CPluginInstancePeer::QueryInterface(const nsIID& iid, void** ptr) +{ + if (NULL == ptr) { + return NS_ERROR_NULL_POINTER; + } + + if (iid.Equals(kPluginInstancePeerIID)) { + *ptr = (void*) this; + AddRef(); + return NS_OK; + } + if (iid.Equals(kPluginTagInfoIID) || iid.Equals(kISupportsIID)) { + *ptr = (void*) ((nsIPluginTagInfo*)this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginManagerStream +// + +CPluginManagerStream::CPluginManagerStream(NPP npp, NPStream* pstr) + : npp(npp), pstream(pstr) +{ + // Set the reference count to 0. + NS_INIT_REFCNT(); +} + +CPluginManagerStream::~CPluginManagerStream(void) +{ + //pstream = NULL; + NPN_DestroyStream(npp, pstream, NPRES_DONE); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// Write: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRInt32 NP_LOADDS +CPluginManagerStream::Write(const char* buffer, PRInt32 offset, PRInt32 len, nsresult* error) +{ + assert( npp != NULL ); + assert( pstream != NULL ); + + return NPN_Write(npp, pstream, len, (void* )buffer); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetURL: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +const char* NP_LOADDS +CPluginManagerStream::GetURL(void) +{ + assert( pstream != NULL ); + + return pstream->url; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetEnd: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 NP_LOADDS +CPluginManagerStream::GetEnd(void) +{ + assert( pstream != NULL ); + + return pstream->end; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetLastModified: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 NP_LOADDS +CPluginManagerStream::GetLastModified(void) +{ + assert( pstream != NULL ); + + return pstream->lastmodified; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetNotifyData: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void* NP_LOADDS +CPluginManagerStream::GetNotifyData(void) +{ + assert( pstream != NULL ); + + return pstream->notifyData; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetNotifyData: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsresult NP_LOADDS +CPluginManagerStream::Close(void) +{ + assert( pstream != NULL ); + + return NS_OK; +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginManagerStream); +//NS_IMPL_RELEASE(CPluginManagerStream); +nsrefcnt CPluginManagerStream::Release(void) +{ + if (--mRefCnt == 0) { + delete this; + return 0; + } + return mRefCnt; +} +NS_IMPL_QUERY_INTERFACE(CPluginManagerStream, kOutputStreamIID); + +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginStreamPeer +// + +CPluginStreamPeer::CPluginStreamPeer(nsMIMEType type, NPStream* npStream, + PRBool seekable, PRUint16* stype) + : type(type), npStream(npStream), seekable(seekable), + stype(stype), reason(nsPluginReason_NoReason) +{ + // Set the reference count to 0. + NS_INIT_REFCNT(); +} + +CPluginStreamPeer::~CPluginStreamPeer(void) +{ +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetURL: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +const char* CPluginStreamPeer::GetURL(void) +{ + return npStream->url; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetEnd: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 CPluginStreamPeer::GetEnd(void) +{ + return npStream->end; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetLastModified: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 CPluginStreamPeer::GetLastModified(void) +{ + return npStream->lastmodified; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetNotifyData: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void* CPluginStreamPeer::GetNotifyData(void) +{ + return npStream->notifyData; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetReason: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginReason CPluginStreamPeer::GetReason(void) +{ + return reason; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetMIMEType: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsMIMEType NP_LOADDS +CPluginStreamPeer::GetMIMEType(void) +{ + return type; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// RequestRead: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginStreamPeer::RequestRead(nsByteRange* rangeList) +{ + return (nsPluginError)NPN_RequestRead(npStream, (NPByteRange* )rangeList); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginStreamPeer); +NS_IMPL_RELEASE(CPluginStreamPeer); +//NS_IMPL_QUERY_INTERFACE(CPluginStreamPeer, kSeekablePluginStreamPeerIID); +nsresult CPluginStreamPeer::QueryInterface(const nsIID& iid, void** ptr) +{ + if (NULL == ptr) { + return NS_ERROR_NULL_POINTER; + } + if (iid.Equals(kSeekablePluginStreamPeerIID)) { + *ptr = (void*) ((nsISeekablePluginStreamPeer*)this); + AddRef(); + return NS_OK; + } else if (iid.Equals(kPluginStreamPeerIID) || + iid.Equals(kISupportsIID)) { + *ptr = (void*) ((nsIPluginStreamPeer*)this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +////////////////////////////////////////////////////////////////////////////// + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + diff --git a/modules/plugin/samples/backward/badapter.cpp b/modules/plugin/samples/backward/badapter.cpp new file mode 100644 index 000000000000..9aad2c653909 --- /dev/null +++ b/modules/plugin/samples/backward/badapter.cpp @@ -0,0 +1,1395 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +//////////////////////////////////////////////////////////////////////////////// +// Backward Adapter +// This acts as a adapter layer to allow 5.0 plugins work with the 4.0/3.0 +// browser. +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 1 - Includes +//////////////////////////////////////////////////////////////////////////////// + +extern "C" { +#include "npapi.h" +}; +#include "nsplugin.h" +#include "nsDebug.h" + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 3 - Classes +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginManager +// +// This is the dummy plugin manager that interacts with the 5.0 plugin. +// +class CPluginManager : public nsIPluginManager { +public: + + CPluginManager(void); + virtual ~CPluginManager(void); + + NS_DECL_ISUPPORTS + + NS_IMETHOD_(void) + ReloadPlugins(PRBool reloadPages); + + NS_IMETHOD_(void* ) + MemAlloc(PRUint32 size); + + NS_IMETHOD_(void) + MemFree(void* ptr); + + NS_IMETHOD_(PRUint32) + MemFlush(PRUint32 size); + + // (Corresponds to NPN_GetValue.) + NS_IMETHOD_(nsPluginError) + GetValue(nsPluginManagerVariable variable, void *value); + + // (Corresponds to NPN_SetValue.) + NS_IMETHOD_(nsPluginError) + SetValue(nsPluginManagerVariable variable, void *value); + + // (Corresponds to NPN_UserAgent.) + NS_IMETHOD_(const char*) + UserAgent(void); + + // (Corresponds to NPN_GetURL and NPN_GetURLNotify.) + // notifyData: When present, URLNotify is called passing the notifyData back + // to the client. When NULL, this call behaves like NPN_GetURL. + // New arguments: + // peer: A plugin instance peer. The peer's window will be used to display + // progress information. If NULL, the load happens in the background. + // altHost: An IP-address string that will be used instead of the host + // specified in the URL. This is used to prevent DNS-spoofing attacks. + // Can be defaulted to NULL meaning use the host in the URL. + // referrer: + // forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, + // even if the user currently has JavaScript disabled. + NS_IMETHOD_(nsPluginError) + GetURL(nsISupports* peer, const char* url, const char* target, void* notifyData = NULL, + const char* altHost = NULL, const char* referrer = NULL, + PRBool forceJSEnabled = PR_FALSE); + + // (Corresponds to NPN_PostURL and NPN_PostURLNotify.) + // notifyData: When present, URLNotify is called passing the notifyData back + // to the client. When NULL, this call behaves like NPN_GetURL. + // New arguments: + // peer: A plugin instance peer. The peer's window will be used to display + // progress information. If NULL, the load happens in the background. + // altHost: An IP-address string that will be used instead of the host + // specified in the URL. This is used to prevent DNS-spoofing attacks. + // Can be defaulted to NULL meaning use the host in the URL. + // referrer: + // forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, + // even if the user currently has JavaScript disabled. + // postHeaders: A string containing post headers. + // postHeadersLength: The length of the post headers string. + NS_IMETHOD_(nsPluginError) + PostURL(nsISupports* peer, const char* url, const char* target, PRUint32 bufLen, + const char* buf, PRBool file, void* notifyData = NULL, + const char* altHost = NULL, const char* referrer = NULL, + PRBool forceJSEnabled = PR_FALSE, + PRUint32 postHeadersLength = 0, const char* postHeaders = NULL); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginManagerStream +// +// This is the dummy plugin manager stream that interacts with the 5.0 plugin. +// +class CPluginManagerStream : public nsIOutputStream { + +public: + + CPluginManagerStream(NPP npp, NPStream* pstr); + virtual ~CPluginManagerStream(void); + + NS_DECL_ISUPPORTS + + ////////////////////////////////////////////////////////////////////////// + // + // Taken from nsIStream + // + + // The Release function in nsISupport will take care of destroying the stream. + + NS_IMETHOD_(PRInt32) + Write (const char* buffer, PRInt32 offset, PRInt32 len, nsresult* error); + // XXX - Hmm? Why is there an extra parameter offset? + // (NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer); + + ////////////////////////////////////////////////////////////////////////// + // + // Specific methods to nsIPluginManagerStream. + // + + // Corresponds to NPStream's url field. + NS_IMETHOD_(const char* ) + GetURL(void); + + // Corresponds to NPStream's end field. + NS_IMETHOD_(PRUint32) + GetEnd(void); + + // Corresponds to NPStream's lastmodfied field. + NS_IMETHOD_(PRUint32) + GetLastModified(void); + + // Corresponds to NPStream's notifyData field. + NS_IMETHOD_(void* ) + GetNotifyData(void); + + // Corresponds to NPStream's url field. + NS_IMETHOD Close(void); + +protected: + + // npp + // The plugin instance that the manager stream belongs to. + NPP npp; + + // pstream + // The stream the class is using. + NPStream* pstream; + +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginInstancePeer +// +// This is the dummy instance peer that interacts with the 5.0 plugin. +// In order to do LiveConnect, the class subclasses nsILiveConnectPluginInstancePeer. +// +class CPluginInstancePeer : public nsIPluginInstancePeer, public nsIPluginTagInfo { + +public: + + // XXX - I add parameters to the constructor because I wasn't sure if + // XXX - the 4.0 browser had the npp_instance struct implemented. + // XXX - If so, then I can access npp_instance through npp->ndata. + CPluginInstancePeer(NPP npp, nsMIMEType typeString, nsPluginType type, + PRUint16 attribute_cnt, const char** attribute_list, const char** values_list); + virtual ~CPluginInstancePeer(void); + + NS_DECL_ISUPPORTS + + // Corresponds to NPP_New's MIMEType argument. + NS_IMETHOD_(nsMIMEType) + GetMIMEType(void); + + // Corresponds to NPP_New's mode argument. + NS_IMETHOD_(nsPluginType) + GetMode(void); + + // Get a ptr to the paired list of attribute names and values, + // returns the length of the array. + // + // Each name or value is a null-terminated string. + NS_IMETHOD_(nsPluginError) + GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values); + + // Get the value for the named attribute. Returns null + // if the attribute was not set. + NS_IMETHOD_(const char*) + GetAttribute(const char* name); + + // Corresponds to NPN_NewStream. + NS_IMETHOD_(nsPluginError) + NewStream(nsMIMEType type, const char* target, nsIOutputStream* *result); + + // Corresponds to NPN_ShowStatus. + NS_IMETHOD_(void) + ShowStatus(const char* message); + + // XXX - Where did this go? + NS_IMETHOD_(void) + Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor); + + NPP GetNPPInstance(void) { + return npp; + } +protected: + + NPP npp; + // XXX - The next five variables may need to be here since I + // XXX - don't think np_instance is available in 4.0X. + nsMIMEType typeString; + nsPluginType type; + PRUint16 attribute_cnt; + char** attribute_list; + char** values_list; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// CPluginStreamPeer +// +// This is the dummy stream peer that interacts with the 5.0 plugin. +// +class CPluginStreamPeer : public nsISeekablePluginStreamPeer, public nsIPluginStreamPeer { + +public: + + CPluginStreamPeer(nsMIMEType type, NPStream* npStream, + PRBool seekable, PRUint16* stype); + virtual ~CPluginStreamPeer(); + + NS_DECL_ISUPPORTS + + // (Corresponds to NPStream's url field.) + NS_IMETHOD_(const char*) + GetURL(void); + + // (Corresponds to NPStream's end field.) + NS_IMETHOD_(PRUint32) + GetEnd(void); + + // (Corresponds to NPStream's lastmodified field.) + NS_IMETHOD_(PRUint32) + GetLastModified(void); + + // (Corresponds to NPStream's notifyData field.) + NS_IMETHOD_(void*) + GetNotifyData(void); + + ////////////////////////////////////////////////////////////////////////// + // + // From nsIPluginStreamPeer + // + + // Corresponds to NPP_DestroyStream's reason argument. + NS_IMETHOD_(nsPluginReason) + GetReason(void); + + // Corresponds to NPP_NewStream's MIMEType argument. + NS_IMETHOD_(nsMIMEType) + GetMIMEType(void); + + ////////////////////////////////////////////////////////////////////////// + // + // From nsISeekablePluginStreamPeer + // + + // Corresponds to NPN_RequestRead. + NS_IMETHOD_(nsPluginError) + RequestRead(nsByteRange* rangeList); + +protected: + + nsMIMEType type; + NPStream* npStream; + PRBool seekable; + PRUint16* stype; + nsPluginReason reason; + +}; + +////////////////////////////////////////////////////////////////////////////// + +#ifdef XP_UNIX +#define TRACE(foo) trace(foo) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 1 - Includes +//////////////////////////////////////////////////////////////////////////////// + +#ifdef XP_UNIX +#include +#include +#include +#else +#include +#endif + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 2 - Globar Variables +//////////////////////////////////////////////////////////////////////////////// + +// +// thePlugin and thePluginManager are used in the life of the plugin. +// +// These two will be created on NPP_Initialize and destroyed on NPP_Shutdown. +// +nsIPluginManager* thePluginManager = NULL; +nsIPlugin* thePlugin = NULL; + +// +// nsISupports IDs +// +// Interface IDs for nsISupports +// +NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +NS_DEFINE_IID(kPluginIID, NS_IPLUGIN_IID); +NS_DEFINE_IID(kPluginInstanceIID, NS_IPLUGININSTANCE_IID); +NS_DEFINE_IID(kPluginManagerIID, NS_IPLUGINMANAGER_IID); +NS_DEFINE_IID(kPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); +NS_DEFINE_IID(kOutputStreamIID, NS_IOUTPUTSTREAM_IID); +NS_DEFINE_IID(kPluginInstancePeerIID, NS_IPLUGININSTANCEPEER_IID); +NS_DEFINE_IID(kPluginStreamPeerIID, NS_IPLUGINSTREAMPEER_IID); +NS_DEFINE_IID(kSeekablePluginStreamPeerIID, NS_ISEEKABLEPLUGINSTREAMPEER_IID); + + +//////////////////////////////////////////////////////////////////////////////// +// SECTION 4 - API Shim Plugin Implementations +// Glue code to the 5.0x Plugin. +// +// Most of the NPP_* functions that interact with the plug-in will need to get +// the instance peer from npp->pdata so it can get the plugin instance from the +// peer. Once the plugin instance is available, the appropriate 5.0 plug-in +// function can be called: +// +// CPluginInstancePeer* peer = (CPluginInstancePeer* )instance->pdata; +// nsIPluginInstance* inst = peer->GetUserInstance(); +// inst->NewPluginAPIFunction(); +// +// Similar steps takes place with streams. The stream peer is stored in NPStream's +// pdata. Get the peer, get the stream, call the function. +// + +//////////////////////////////////////////////////////////////////////////////// +// UNIX-only API calls +//////////////////////////////////////////////////////////////////////////////// +#ifdef XP_UNIX +char* NPP_GetMIMEDescription(void) +{ + int freeFac = 0; + fprintf(stderr, "MIME description\n"); + if (thePlugin == NULL) { + freeFac = 1; + NSGetFactory(kPluginIID, (nsIFactory** )(&thePlugin)); + } + fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin); + char * ret = (char *) thePlugin->GetMIMEDescription(); + fprintf(stderr, "Get response %s\n", ret); + if (freeFac) { + fprintf(stderr, "Freeing plugin..."); + thePlugin->Release(); + thePlugin = NULL; + } + fprintf(stderr, "Done\n"); + return ret; +} + + +//------------------------------------------------------------------------------ +// Cross-Platform Plug-in API Calls +//------------------------------------------------------------------------------ + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_SetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_SetValue(NPP instance, NPNVariable variable, void *value) +{ + return (NPError)nsPluginError_NoError; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_GetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_GetValue(NPP instance, NPPVariable variable, void *value) { + int freeFac = 0; + fprintf(stderr, "MIME description\n"); + if (thePlugin == NULL) { + freeFac = 1; + if (NSGetFactory(kPluginIID, (nsIFactory** )(&thePlugin)) != NS_OK) + return NPERR_GENERIC_ERROR; + } + fprintf(stderr, "Allocated Plugin 0x%08x\n", thePlugin); + NPError ret = (NPError) thePlugin->GetValue((nsPluginVariable)variable, value); + fprintf(stderr, "Get response %08x\n", ret); + if (freeFac) { + fprintf(stderr, "Freeing plugin..."); + thePlugin->Release(); + thePlugin = NULL; + } + fprintf(stderr, "Done\n"); + return ret; +} +#endif +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Initialize: +// Provides global initialization for a plug-in, and returns an error value. +// +// This function is called once when a plug-in is loaded, before the first instance +// is created. thePluginManager and thePlugin are both initialized. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_Initialize(void) +{ +// TRACE("NPP_Initialize\n"); + + // Only call initialize the plugin if it hasn't been created. + // This could happen if GetJavaClass() is called before + // NPP Initialize. + if (thePluginManager == NULL) { + // Create the plugin manager and plugin classes. + thePluginManager = new CPluginManager(); + if ( thePluginManager == NULL ) + return NPERR_OUT_OF_MEMORY_ERROR; + thePluginManager->AddRef(); + } + nsresult error = NS_OK; + // On UNIX the plugin might have been created when calling NPP_GetMIMEType. + if (thePlugin == NULL) + // create nsIPlugin factory + error = (NPError)NSGetFactory(kPluginIID, (nsIFactory**) &thePlugin); + if (error == NS_OK) + thePlugin->Initialize(thePluginManager); + + return (NPError) error; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_GetJavaClass: +// New in Netscape Navigator 3.0. +// +// NPP_GetJavaClass is called during initialization to ask your plugin +// what its associated Java class is. If you don't have one, just return +// NULL. Otherwise, use the javah-generated "use_" function to both +// initialize your class and return it. If you can't find your class, an +// error will be signalled by "use_" and will cause the Navigator to +// complain to the user. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +jref +NPP_GetJavaClass(void) +{ + // Only call initialize the plugin if it hasn't been `d. + /* if (thePluginManager == NULL) { + // Create the plugin manager and plugin objects. + NPError result = CPluginManager::Create(); + if (result) return NULL; + assert( thePluginManager != NULL ); + thePluginManager->AddRef(); + NP_CreatePlugin(thePluginManager, (nsIPlugin** )(&thePlugin)); + assert( thePlugin != NULL ); + } +*/ +// return thePlugin->GetJavaClass(); + return NULL; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Shutdown: +// Provides global deinitialization for a plug-in. +// +// This function is called once after the last instance of your plug-in +// is destroyed. thePluginManager and thePlugin are delete at this time. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_Shutdown(void) +{ +// TRACE("NPP_Shutdown\n"); + + if (thePlugin) + { + thePlugin->Shutdown(); + thePlugin->Release(); + thePlugin = NULL; + } + + if (thePluginManager) { + thePluginManager->Release(); + thePluginManager = NULL; + } + + return; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_New: +// Creates a new instance of a plug-in and returns an error value. +// +// A plugin instance peer and instance peer is created. After +// a successful instansiation, the peer is stored in the plugin +// instance's pdata. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_New(NPMIMEType pluginType, + NPP instance, + PRUint16 mode, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved) +{ +// TRACE("NPP_New\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + // Create a new plugin instance and start it. + nsIPluginInstance* pluginInstance = NULL; + thePlugin->CreateInstance(NULL, kPluginInstanceIID, (void**)&pluginInstance); + if (pluginInstance == NULL) { + return NPERR_OUT_OF_MEMORY_ERROR; + } + + // Create a new plugin instance peer, + // XXX - Since np_instance is not implemented in the 4.0x browser, I + // XXX - had to save the plugin parameter in the peer class. + // XXX - Ask Warren about np_instance. + CPluginInstancePeer* peer = + new CPluginInstancePeer(instance, (nsMIMEType)pluginType, + (nsPluginType)mode, (PRUint16)argc, + (const char** )argn, (const char** )argv); + assert( peer != NULL ); + if (!peer) return NPERR_OUT_OF_MEMORY_ERROR; + peer->AddRef(); + pluginInstance->Initialize(peer); + pluginInstance->Start(); + // Set the user instance and store the peer in npp->pdata. + instance->pdata = pluginInstance; + peer->Release(); + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Destroy: +// Deletes a specific instance of a plug-in and returns an error value. +// +// The plugin instance peer and plugin instance are destroyed. +// The instance's pdata is set to NULL. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_Destroy(NPP instance, NPSavedData** save) +{ +// TRACE("NPP_Destroy\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance* pluginInstance = (nsIPluginInstance* )instance->pdata; + pluginInstance->Stop(); + pluginInstance->Destroy(); + pluginInstance->Release(); + instance->pdata = NULL; + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_SetWindow: +// Sets the window in which a plug-in draws, and returns an error value. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_SetWindow(NPP instance, NPWindow* window) +{ +// TRACE("NPP_SetWindow\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance* pluginInstance = (nsIPluginInstance* )instance->pdata; + + if( pluginInstance == 0 ) + return NPERR_INVALID_PLUGIN_ERROR; + + return (NPError)pluginInstance->SetWindow((nsPluginWindow* ) window ); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_NewStream: +// Notifies an instance of a new data stream and returns an error value. +// +// Create a stream peer and stream. If succesful, save +// the stream peer in NPStream's pdata. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_NewStream(NPP instance, + NPMIMEType type, + NPStream *stream, + NPBool seekable, + PRUint16 *stype) +{ + // XXX - How do you set the fields of the peer stream and stream? + // XXX - Looks like these field will have to be created since + // XXX - We are not using np_stream. + +// TRACE("NPP_NewStream\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + // Create a new plugin stream peer and plugin stream. + CPluginStreamPeer* speer = new CPluginStreamPeer((nsMIMEType)type, stream, + (PRBool)seekable, stype); + if (speer == NULL) return NPERR_OUT_OF_MEMORY_ERROR; + speer->AddRef(); + nsIPluginStream* pluginStream = NULL; + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + NPError result = (NPError)pluginInstance->NewStream(speer, &pluginStream); + speer->Release(); + + if (pluginStream == NULL) + return NPERR_OUT_OF_MEMORY_ERROR; + + stream->pdata = (void*) pluginStream; + *stype = pluginStream->GetStreamType(); + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_WriteReady: +// Returns the maximum number of bytes that an instance is prepared to accept +// from the stream. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +int32 +NPP_WriteReady(NPP instance, NPStream *stream) +{ +// TRACE("NPP_WriteReady\n"); + + if (instance == NULL) + return -1; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return -1; + + return 8192; +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Write: +// Delivers data from a stream and returns the number of bytes written. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +int32 +NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) +{ +// TRACE("NPP_Write\n"); + + if (instance == NULL) + return -1; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return -1; + + nsresult result; + return theStream->Write((const char* )buffer, offset, len, &result); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_DestroyStream: +// Indicates the closure and deletion of a stream, and returns an error value. +// +// The stream peer and stream are destroyed. NPStream's +// pdata is set to NULL. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NPError +NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) +{ +// TRACE("NPP_DestroyStream\n"); + + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return NPERR_GENERIC_ERROR; + + theStream->Release(); + stream->pdata = NULL; + + return NPERR_NO_ERROR; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_StreamAsFile: +// Provides a local file name for the data from a stream. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname) +{ +// TRACE("NPP_StreamAsFile\n"); + + if (instance == NULL) + return; + + nsIPluginStream* theStream = (nsIPluginStream*) stream->pdata; + if( theStream == 0 ) + return; + + theStream->AsFile( fname ); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_Print: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_Print(NPP instance, NPPrint* printInfo) +{ +// TRACE("NPP_Print\n"); + + if(printInfo == NULL) // trap invalid parm + return; + + if (instance != NULL) + { + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + pluginInstance->Print((nsPluginPrint* ) printInfo ); + } +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_URLNotify: +// Notifies the instance of the completion of a URL request. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void +NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) +{ +// TRACE("NPP_URLNotify\n"); + + if( instance != NULL ) + { + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + pluginInstance->URLNotify(url, NULL, (nsPluginReason)reason, notifyData); + + } +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NPP_HandleEvent: +// Mac-only, but stub must be present for Windows +// Delivers a platform-specific event to the instance. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +#ifndef XP_UNIX +int16 +NPP_HandleEvent(NPP instance, void* event) +{ +// TRACE("NPP_HandleEvent\n"); + + int16 eventHandled = FALSE; + if (instance == NULL) + return eventHandled; + + nsIPluginInstance* pluginInstance = (nsIPluginInstance*) instance->pdata; + if( pluginInstance ) + eventHandled = (int16) pluginInstance->HandleEvent((nsPluginEvent*) event ); + + return eventHandled; +} +#endif // ndef XP_UNIX +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// SECTION 5 - API Browser Implementations +// +// Glue code to the 4.0x Browser. +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginManager +// + +//****************************************************************************** +// +// Once we moved to the new APIs, we need to implement fJVMMgr. +// +//****************************************************************************** + +CPluginManager::CPluginManager(void) +{ + // Set reference count to 0. + NS_INIT_REFCNT(); +} + +CPluginManager::~CPluginManager(void) +{ +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// MemAlloc: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void* NP_LOADDS +CPluginManager::MemAlloc(PRUint32 size) +{ + return NPN_MemAlloc(size); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// MemFree: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginManager::MemFree(void* ptr) +{ + assert( ptr != NULL ); + + NPN_MemFree(ptr); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// MemFlush: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 NP_LOADDS +CPluginManager::MemFlush(PRUint32 size) +{ +#ifdef XP_MAC + return NPN_MemFlush(size); +#else + return 0; +#endif +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// ReloadPlugins: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginManager::ReloadPlugins(PRBool reloadPages) +{ + NPN_ReloadPlugins(reloadPages); +} + + +// (Corresponds to NPN_GetURL and NPN_GetURLNotify.) +// notifyData: When present, URLNotify is called passing the notifyData back +// to the client. When NULL, this call behaves like NPN_GetURL. +// New arguments: +// peer: A plugin instance peer. The peer's window will be used to display +// progress information. If NULL, the load happens in the background. +// altHost: An IP-address string that will be used instead of the host +// specified in the URL. This is used to prevent DNS-spoofing attacks. +// Can be defaulted to NULL meaning use the host in the URL. +// referrer: +// forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, +// even if the user currently has JavaScript disabled. +nsPluginError NP_LOADDS +CPluginManager::GetURL(nsISupports* peer, const char* url, const char* target, void* notifyData, + const char* altHost, const char* referrer, PRBool forceJSEnabled) +{ + // assert( npp != NULL ); + // assert( url != NULL ); + assert( peer != NULL); + + CPluginInstancePeer* instancePeer = (CPluginInstancePeer*)(nsIPluginInstancePeer*) peer; + NPP npp = instancePeer->GetNPPInstance(); + + + // Call the correct GetURL* function. + // This is determinded by checking notifyData. + if (notifyData == NULL) { + return (nsPluginError)NPN_GetURL(npp, url, target); + } else { + return (nsPluginError)NPN_GetURLNotify(npp, url, target, notifyData); + } +} + +// (Corresponds to NPN_PostURL and NPN_PostURLNotify.) +// notifyData: When present, URLNotify is called passing the notifyData back +// to the client. When NULL, this call behaves like NPN_GetURL. +// New arguments: +// peer: A plugin instance peer. The peer's window will be used to display +// progress information. If NULL, the load happens in the background. +// altHost: An IP-address string that will be used instead of the host +// specified in the URL. This is used to prevent DNS-spoofing attacks. +// Can be defaulted to NULL meaning use the host in the URL. +// referrer: +// forceJSEnabled: Forces JavaScript to be enabled for 'javascript:' URLs, +// even if the user currently has JavaScript disabled. +// postHeaders: A string containing post headers. +// postHeadersLength: The length of the post headers string. +nsPluginError NP_LOADDS +CPluginManager::PostURL(nsISupports* peer, const char* url, const char* target, PRUint32 bufLen, + const char* buf, PRBool file, void* notifyData, const char* altHost, + const char* referrer, PRBool forceJSEnabled, PRUint32 postHeadersLength, + const char* postHeaders) +{ + assert( peer != NULL); + + CPluginInstancePeer* instancePeer = (CPluginInstancePeer*)(nsIPluginInstancePeer*)peer; + NPP npp = instancePeer->GetNPPInstance(); + + // Call the correct PostURL* function. + // This is determinded by checking notifyData. + if (notifyData == NULL) { + return (nsPluginError)NPN_PostURL(npp, url, target, bufLen, buf, file); + } else { + return (nsPluginError)NPN_PostURLNotify(npp, url, target, bufLen, buf, file, notifyData); + } +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// UserAgent: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +const char* NP_LOADDS +CPluginManager::UserAgent(void) +{ + return NPN_UserAgent(NULL); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginManager::GetValue(nsPluginManagerVariable variable, void *value) +{ + // XXX - This may need to be stubbed out for + // XXX - other platforms than Unix. + // XXX - Change this to return NPPPlugin_Error; +#ifdef XP_UNIX + return (nsPluginError)NPN_GetValue(NULL, (NPNVariable)variable, value); +#else + // XXX - Need to check this on the new API. + return nsPluginError_NoData; +#endif // XP_UNIX +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// SetValue: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginManager::SetValue(nsPluginManagerVariable variable, void *value) +{ + // XXX - This should do something like this. + // XXX - return (nsPluginError)npn_setvalue(npp, (NPPVariable)variable, value); + // XXX - Is this XP in 4.0x? + // XXX - Need to check this on the new API. + return nsPluginError_NoData; +} + + + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginManager); +NS_IMPL_RELEASE(CPluginManager); +//NS_IMPL_QUERY_INTERFACE(CPluginManager, kPluginManagerIID); +nsresult CPluginManager::QueryInterface(const nsIID& iid, void** ptr) +{ + if (NULL == ptr) { + return NS_ERROR_NULL_POINTER; + } + + if (iid.Equals(kPluginManagerIID)) { + *ptr = (void*) this; + AddRef(); + return NS_OK; + } + if (iid.Equals(kISupportsIID)) { + *ptr = (void*) ((nsISupports*)this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginInstancePeer +// + +CPluginInstancePeer::CPluginInstancePeer(NPP npp, + nsMIMEType typeString, + nsPluginType type, + PRUint16 attr_cnt, + const char** attr_list, + const char** val_list) + : npp(npp), typeString(typeString), type(type), attribute_cnt(attr_cnt), + attribute_list(NULL), values_list(NULL) +{ + // Set the reference count to 0. + NS_INIT_REFCNT(); + + attribute_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*)); + values_list = (char**) NPN_MemAlloc(attr_cnt * sizeof(const char*)); + + for (int i=0; i < attribute_cnt; i++) { + attribute_list[i] = (char*) NPN_MemAlloc(sizeof(char) + strlen(attr_list[i] + 1)); + values_list[i] = (char*) NPN_MemAlloc(sizeof(char) + strlen(val_list[i] + 1)); + + strcpy(attribute_list[i], attr_list[i]); + strcpy(values_list[i], val_list[i]); + } +} + +CPluginInstancePeer::~CPluginInstancePeer(void) +{ + for (int i=0; i < attribute_cnt; i++) { + NPN_MemFree(attribute_list[i]); + NPN_MemFree(values_list[i]); + } + + NPN_MemFree(attribute_list); + NPN_MemFree(values_list); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetMIMEType: +// Corresponds to NPP_New's MIMEType argument. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsMIMEType NP_LOADDS +CPluginInstancePeer::GetMIMEType(void) +{ + return typeString; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetMode: +// Corresponds to NPP_New's mode argument. +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginType NP_LOADDS +CPluginInstancePeer::GetMode(void) +{ + return type; +} + + +// Get a ptr to the paired list of attribute names and values, +// returns the length of the array. +// +// Each name or value is a null-terminated string. +nsPluginError NP_LOADDS +CPluginInstancePeer::GetAttributes(PRUint16& n, const char* const*& names, const char* const*& values) +{ + n = attribute_cnt; + names = attribute_list; + values = values_list; + + return nsPluginError_NoError; +} + + +// Get the value for the named attribute. Returns null +// if the attribute was not set. +const char* NP_LOADDS +CPluginInstancePeer::GetAttribute(const char* name) +{ + for (int i=0; i < attribute_cnt; i++) { +#ifdef XP_UNIX + if (strcasecmp(name, attribute_list[i]) == 0) +#else + if (stricmp(name, attribute_list[i]) == 0) +#endif + return values_list[i]; + } + + return NULL; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// Version: +// +// XXX - Where did this go in the new API? +// +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginInstancePeer::Version(int* plugin_major, int* plugin_minor, + int* netscape_major, int* netscape_minor) +{ + NPN_Version(plugin_major, plugin_minor, netscape_major, netscape_minor); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// NewStream: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginInstancePeer::NewStream(nsMIMEType type, const char* target, + nsIOutputStream* *result) +{ + assert( npp != NULL ); + + // Create a new NPStream. + NPStream* ptr = NULL; + nsPluginError error = (nsPluginError)NPN_NewStream(npp, (NPMIMEType)type, target, &ptr); + if (error) return error; + + // Create a new Plugin Manager Stream. + // XXX - Do we have to Release() the manager stream before doing this? + // XXX - See the BAM doc for more info. + CPluginManagerStream* mstream = new CPluginManagerStream(npp, ptr); + if (mstream == NULL) return nsPluginError_OutOfMemoryError; + mstream->AddRef(); + *result = (nsIOutputStream* )mstream; + + return nsPluginError_NoError; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// ShowStatus: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void NP_LOADDS +CPluginInstancePeer::ShowStatus(const char* message) +{ + assert( message != NULL ); + + NPN_Status(npp, message); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginInstancePeer); +NS_IMPL_RELEASE(CPluginInstancePeer); + + +nsresult CPluginInstancePeer::QueryInterface(const nsIID& iid, void** ptr) +{ + if (NULL == ptr) { + return NS_ERROR_NULL_POINTER; + } + + if (iid.Equals(kPluginInstancePeerIID)) { + *ptr = (void*) this; + AddRef(); + return NS_OK; + } + if (iid.Equals(kPluginTagInfoIID) || iid.Equals(kISupportsIID)) { + *ptr = (void*) ((nsIPluginTagInfo*)this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginManagerStream +// + +CPluginManagerStream::CPluginManagerStream(NPP npp, NPStream* pstr) + : npp(npp), pstream(pstr) +{ + // Set the reference count to 0. + NS_INIT_REFCNT(); +} + +CPluginManagerStream::~CPluginManagerStream(void) +{ + //pstream = NULL; + NPN_DestroyStream(npp, pstream, NPRES_DONE); +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// Write: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRInt32 NP_LOADDS +CPluginManagerStream::Write(const char* buffer, PRInt32 offset, PRInt32 len, nsresult* error) +{ + assert( npp != NULL ); + assert( pstream != NULL ); + + return NPN_Write(npp, pstream, len, (void* )buffer); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetURL: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +const char* NP_LOADDS +CPluginManagerStream::GetURL(void) +{ + assert( pstream != NULL ); + + return pstream->url; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetEnd: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 NP_LOADDS +CPluginManagerStream::GetEnd(void) +{ + assert( pstream != NULL ); + + return pstream->end; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetLastModified: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 NP_LOADDS +CPluginManagerStream::GetLastModified(void) +{ + assert( pstream != NULL ); + + return pstream->lastmodified; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetNotifyData: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void* NP_LOADDS +CPluginManagerStream::GetNotifyData(void) +{ + assert( pstream != NULL ); + + return pstream->notifyData; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetNotifyData: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsresult NP_LOADDS +CPluginManagerStream::Close(void) +{ + assert( pstream != NULL ); + + return NS_OK; +} + + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginManagerStream); +//NS_IMPL_RELEASE(CPluginManagerStream); +nsrefcnt CPluginManagerStream::Release(void) +{ + if (--mRefCnt == 0) { + delete this; + return 0; + } + return mRefCnt; +} +NS_IMPL_QUERY_INTERFACE(CPluginManagerStream, kOutputStreamIID); + +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// +// CPluginStreamPeer +// + +CPluginStreamPeer::CPluginStreamPeer(nsMIMEType type, NPStream* npStream, + PRBool seekable, PRUint16* stype) + : type(type), npStream(npStream), seekable(seekable), + stype(stype), reason(nsPluginReason_NoReason) +{ + // Set the reference count to 0. + NS_INIT_REFCNT(); +} + +CPluginStreamPeer::~CPluginStreamPeer(void) +{ +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetURL: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +const char* CPluginStreamPeer::GetURL(void) +{ + return npStream->url; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetEnd: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 CPluginStreamPeer::GetEnd(void) +{ + return npStream->end; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetLastModified: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +PRUint32 CPluginStreamPeer::GetLastModified(void) +{ + return npStream->lastmodified; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetNotifyData: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +void* CPluginStreamPeer::GetNotifyData(void) +{ + return npStream->notifyData; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetReason: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginReason CPluginStreamPeer::GetReason(void) +{ + return reason; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// GetMIMEType: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsMIMEType NP_LOADDS +CPluginStreamPeer::GetMIMEType(void) +{ + return type; +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// RequestRead: +//+++++++++++++++++++++++++++++++++++++++++++++++++ +nsPluginError NP_LOADDS +CPluginStreamPeer::RequestRead(nsByteRange* rangeList) +{ + return (nsPluginError)NPN_RequestRead(npStream, (NPByteRange* )rangeList); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++ +// nsISupports functions +//+++++++++++++++++++++++++++++++++++++++++++++++++ +NS_IMPL_ADDREF(CPluginStreamPeer); +NS_IMPL_RELEASE(CPluginStreamPeer); +//NS_IMPL_QUERY_INTERFACE(CPluginStreamPeer, kSeekablePluginStreamPeerIID); +nsresult CPluginStreamPeer::QueryInterface(const nsIID& iid, void** ptr) +{ + if (NULL == ptr) { + return NS_ERROR_NULL_POINTER; + } + if (iid.Equals(kSeekablePluginStreamPeerIID)) { + *ptr = (void*) ((nsISeekablePluginStreamPeer*)this); + AddRef(); + return NS_OK; + } else if (iid.Equals(kPluginStreamPeerIID) || + iid.Equals(kISupportsIID)) { + *ptr = (void*) ((nsIPluginStreamPeer*)this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +////////////////////////////////////////////////////////////////////////////// + +#if defined(__cplusplus) +} /* extern "C" */ +#endif +