mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 22:55:23 +00:00
364 lines
12 KiB
C++
364 lines
12 KiB
C++
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is InnoTek Plugin Wrapper code.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* InnoTek Systemberatung GmbH.
|
|
* Portions created by the Initial Developer are Copyright (C) 2003-2005
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* InnoTek Systemberatung GmbH / Knut St. Osmundsen
|
|
* Peter Weilbacher <mozilla@weilbacher.org>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
/*******************************************************************************
|
|
* Defined Constants And Macros *
|
|
*******************************************************************************/
|
|
/** define this to make a completely freestanding module (i.e. no XPCOM imports).
|
|
* This is handy when making new builds for existing browsers since this
|
|
* doesn't require to have the .libs for the browser in question.
|
|
*
|
|
* - bird 2004-11-02: This must be enabled to support 1.7 / 1.8+!
|
|
*/
|
|
#ifndef _NO_XPCOMDLL_
|
|
# ifdef IPLUGINW_OUTOFTREE
|
|
# define _NO_XPCOMDLL_ 1
|
|
# endif
|
|
#endif
|
|
/** define this to have minimal dependencies on XPCOM. */
|
|
#ifndef _MINIMAL_XPCOMDLL_
|
|
# ifdef _NO_XPCOMDLL_
|
|
# define _MINIMAL_XPCOMDLL_ 1
|
|
# endif
|
|
#endif
|
|
|
|
|
|
/*******************************************************************************
|
|
* Header Files *
|
|
*******************************************************************************/
|
|
#ifdef _NO_XPCOMDLL_
|
|
#define INCL_BASE
|
|
#include <os2.h>
|
|
#endif
|
|
#ifdef DEBUG
|
|
#include <stdio.h>
|
|
#endif
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIPlugin.h"
|
|
#include "nsIGenericFactory.h"
|
|
#include "nsILegacyPluginWrapperOS2.h"
|
|
#include "nsInnoTekPluginWrapper.h"
|
|
|
|
|
|
/*******************************************************************************
|
|
* Global Variables *
|
|
*******************************************************************************/
|
|
static NS_DEFINE_CID(kPluginCID, NS_PLUGIN_CID);
|
|
static NS_DEFINE_CID(kSupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_CID(kLegacyPluginWrapperIID, NS_ILEGACYPLUGINWRAPPEROS2_IID);
|
|
|
|
|
|
/**
|
|
* Implements a plugin wrapper factory.
|
|
*/
|
|
class nsInnoTekPluginWrapper : public nsILegacyPluginWrapperOS2
|
|
{
|
|
#ifdef _MINIMAL_XPCOMDLL_
|
|
public:
|
|
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
|
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
|
NS_IMETHOD_(nsrefcnt) Release(void);
|
|
|
|
protected:
|
|
nsAutoRefCnt mRefCnt;
|
|
#else
|
|
NS_DECL_ISUPPORTS
|
|
#endif
|
|
|
|
public:
|
|
nsInnoTekPluginWrapper();
|
|
static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
|
|
|
/**
|
|
* PR_FindSymbol(,"NSGetFactory") + NSGetFactory().
|
|
*/
|
|
/* void getFactory (in nsIServiceManagerObsolete aServMgr, in REFNSIID aClass, in string aClassName, in string aContractID, in PRLibraryPtr aLibrary, out nsIPlugin aResult); */
|
|
NS_IMETHOD GetFactory(nsIServiceManagerObsolete *aServMgr, REFNSIID aClass, const char *aClassName, const char *aContractID, PRLibrary * aLibrary, nsIPlugin **aResult);
|
|
|
|
/**
|
|
* Create a wrapper for the given interface if it's a legacy interface.
|
|
* @returns NS_OK on success.
|
|
* @returns NS_ERROR_INTERFACE if aIID isn't supported. aOut is nsnull.
|
|
* @returns NS_ERROR_FAILURE on other error. aOut undefined.
|
|
* @param aIID Interface Identifier of aIn and aOut.
|
|
* @param aIn Interface of type aIID which may be a legacy interface
|
|
* requiring a wrapper.
|
|
* @param aOut The native interface.
|
|
* If aIn is a legacy interface, this will be a wrappre.
|
|
* If aIn is not a legacy interface, this is aIn.
|
|
*/
|
|
/* void maybeWrap (in REFNSIID aIID, in nsISupports aIn, out nsISupports aOut); */
|
|
NS_IMETHOD MaybeWrap(REFNSIID aIID, nsISupports *aIn, nsISupports **aOut);
|
|
};
|
|
|
|
|
|
|
|
#ifdef _MINIMAL_XPCOMDLL_
|
|
NS_IMETHODIMP_(nsrefcnt) nsInnoTekPluginWrapper::AddRef(void)
|
|
{
|
|
return ++mRefCnt;
|
|
}
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsInnoTekPluginWrapper::Release(void)
|
|
{
|
|
--mRefCnt;
|
|
if (mRefCnt == 0)
|
|
{
|
|
mRefCnt = 1; /* stabilize */
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return mRefCnt;
|
|
}
|
|
|
|
NS_IMETHODIMP nsInnoTekPluginWrapper::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
if (aIID.Equals(kLegacyPluginWrapperIID))
|
|
{
|
|
*aInstancePtr = static_cast< nsILegacyPluginWrapperOS2 * > (this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aIID.Equals(kSupportsIID))
|
|
{
|
|
*aInstancePtr = static_cast< nsISupports * > (this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
*aInstancePtr = nsnull;
|
|
return NS_ERROR_NO_INTERFACE;
|
|
}
|
|
|
|
#else
|
|
NS_IMPL_ISUPPORTS1(nsInnoTekPluginWrapper, nsILegacyPluginWrapperOS2)
|
|
#endif
|
|
|
|
|
|
|
|
/** Factory Constructor Object - do nothing. */
|
|
nsInnoTekPluginWrapper::nsInnoTekPluginWrapper()
|
|
{
|
|
/* Create semaphores at a safe time */
|
|
npXPCOMInitSems();
|
|
}
|
|
|
|
/**
|
|
* Create the factory.
|
|
* @returns NS_OK on success, with aResult containing the requested interface.
|
|
* @returns NS_ERROR_* on failure, aResult is nsnull.
|
|
*/
|
|
nsresult nsInnoTekPluginWrapper::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|
{
|
|
*aResult = nsnull;
|
|
#ifndef _MINIMAL_XPCOMDLL_
|
|
NS_PRECONDITION(aOuter == nsnull, "no aggregation");
|
|
#endif
|
|
if (aOuter)
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
|
|
#ifdef _MINIMAL_XPCOMDLL_
|
|
nsILegacyPluginWrapperOS2 *
|
|
#else
|
|
nsCOMPtr<nsILegacyPluginWrapperOS2>
|
|
#endif
|
|
factory = new nsInnoTekPluginWrapper();
|
|
if (!factory)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
return factory->QueryInterface(aIID, aResult);
|
|
}
|
|
|
|
|
|
/**
|
|
* This is where we create the initial wrapper.
|
|
*/
|
|
NS_IMETHODIMP nsInnoTekPluginWrapper::GetFactory(nsIServiceManagerObsolete *aServMgr,
|
|
REFNSIID aClass,
|
|
const char *aClassName,
|
|
const char *aContractID,
|
|
PRLibrary * aLibrary,
|
|
nsIPlugin **aResult)
|
|
{
|
|
nsresult rc;
|
|
dprintf(("nsInnoTekPluginWrapper::CreatePlugin: enter"));
|
|
|
|
/*
|
|
* Do NSGetFactory.
|
|
*/
|
|
rc = npXPCOMGenericGetFactory(aServMgr, aClass, aClassName, aContractID, aLibrary, aResult);
|
|
dprintf(("nsInnoTekPluginWrapper::CreatePlugin: npXPCOMGenericGetFactory -> rc=%d and *aResult=%x",
|
|
rc, *aResult));
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a wrapper for the given interface if it's a legacy interface.
|
|
* @returns NS_OK on success.
|
|
* @returns NS_ERROR_NO_INTERFACE if aIID isn't supported. aOut is nsnull.
|
|
* @returns NS_ERROR_FAILURE on other error. aOut undefined.
|
|
* @param aIID Interface Identifier of aIn and aOut.
|
|
* @param aIn Interface of type aIID which may be a legacy interface
|
|
* requiring a wrapper.
|
|
* @param aOut The native interface.
|
|
* If aIn is a legacy interface, this will be a wrappre.
|
|
* If aIn is not a legacy interface, this is aIn.
|
|
* @remark Typically used for the flash plugin.
|
|
*/
|
|
NS_IMETHODIMP nsInnoTekPluginWrapper::MaybeWrap(REFNSIID aIID, nsISupports *aIn, nsISupports **aOut)
|
|
{
|
|
return npXPCOMGenericMaybeWrap(aIID, aIn, aOut);
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Component Info */
|
|
static const nsModuleComponentInfo gComponentInfo[] =
|
|
{
|
|
{
|
|
"InnoTek Legacy XPCOM Plugin Wrapper",
|
|
NS_LEGACY_PLUGIN_WRAPPER_CID,
|
|
NS_LEGACY_PLUGIN_WRAPPER_CONTRACTID,
|
|
nsInnoTekPluginWrapper::Create
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/** NSGetModule(); */
|
|
NS_IMPL_NSGETMODULE(nsInnoTekPluginWrapperModule, gComponentInfo)
|
|
|
|
|
|
#ifdef _NO_XPCOMDLL_
|
|
/**
|
|
* Find the start of the filename.
|
|
*
|
|
* @returns pointer to start of filename.
|
|
* @param pszPath Path to examin.
|
|
*/
|
|
static char *GetBasename(char *pszPath)
|
|
{
|
|
char *pszName;
|
|
char *psz;
|
|
|
|
pszName = strrchr(pszPath, '\\');
|
|
psz = strrchr(pszName ? pszName : pszPath, '/');
|
|
if (psz)
|
|
pszName = psz;
|
|
if (!pszName)
|
|
pszName = strchr(pszPath, ':');
|
|
if (pszName)
|
|
pszName++;
|
|
else
|
|
pszName = pszPath;
|
|
|
|
return pszName;
|
|
}
|
|
|
|
nsresult NS_NewGenericModule2(nsModuleInfo *info, nsIModule* *result)
|
|
{
|
|
HMODULE hmod;
|
|
nsresult rc = NS_ERROR_UNEXPECTED;
|
|
APIRET rc2;
|
|
|
|
/*
|
|
* Because of the LIBPATHSTRICT feature we have to specific the full path
|
|
* of the DLL to make sure we get the right handle.
|
|
* (We're of course making assumptions about the executable and the XPCOM.DLL
|
|
* begin at the same location.)
|
|
*/
|
|
char szXPCOM[CCHMAXPATH];
|
|
char * pszName;
|
|
PPIB ppib;
|
|
PTIB ptib;
|
|
DosGetInfoBlocks(&ptib, &ppib);
|
|
pszName = GetBasename(strcpy(szXPCOM, ppib->pib_pchcmd));
|
|
strcpy(pszName, "XPCOM.DLL");
|
|
rc2 = DosLoadModule(NULL, 0, (PCSZ)szXPCOM, &hmod);
|
|
if (!rc2)
|
|
{
|
|
NS_COM nsresult (* pfnNS_NewGenericModule2)(nsModuleInfo *info, nsIModule* *result);
|
|
|
|
/* demangled name: NS_NewGenericModule2(nsModuleInfo*, nsIModule**) */
|
|
rc2 = DosQueryProcAddr(hmod, 0, (PCSZ)"__Z20NS_NewGenericModule2P12nsModuleInfoPP9nsIModule",
|
|
(PFN*)&pfnNS_NewGenericModule2);
|
|
if (rc2)
|
|
/* demangled name: NS_NewGenericModule2(const nsModuleInfo*, nsIModule**) */
|
|
rc2 = DosQueryProcAddr(hmod, 0, (PCSZ)"__Z20NS_NewGenericModule2PK12nsModuleInfoPP9nsIModule",
|
|
(PFN*)&pfnNS_NewGenericModule2);
|
|
if (rc2)
|
|
{
|
|
/* The mozilla guys have splitt up XPCOM.DLL in 1.8 just to make life difficult. :-) */
|
|
DosFreeModule(hmod);
|
|
strcpy(pszName, "XPCOMCOR.DLL");
|
|
rc2 = DosLoadModule(NULL, 0, (PCSZ)szXPCOM, &hmod);
|
|
if (!rc2)
|
|
{
|
|
rc2 = DosQueryProcAddr(hmod, 0, (PCSZ)"__Z20NS_NewGenericModule2P12nsModuleInfoPP9nsIModule",
|
|
(PFN*)&pfnNS_NewGenericModule2);
|
|
if (rc2)
|
|
/* demangled name: NS_NewGenericModule2(const nsModuleInfo*, nsIModule**) */
|
|
rc2 = DosQueryProcAddr(hmod, 0, (PCSZ)"__Z20NS_NewGenericModule2PK12nsModuleInfoPP9nsIModule",
|
|
(PFN*)&pfnNS_NewGenericModule2);
|
|
}
|
|
}
|
|
if (!rc2)
|
|
rc = pfnNS_NewGenericModule2(info, result);
|
|
#ifdef DEBUG
|
|
else
|
|
fprintf(stderr, "ipluginw: DosQueryProcAddr -> %ld\n", rc2);
|
|
#endif
|
|
DosFreeModule(hmod);
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
fprintf(stderr, "ipluginw: DosLoadModule -> %ld\n", rc2);
|
|
if (rc)
|
|
fprintf(stderr, "ipluginw: NS_NewGenericModule2 -> %#x\n", rc);
|
|
#endif
|
|
|
|
return rc;
|
|
}
|
|
#endif
|
|
|
|
|