/*
 * A basic implementation for COM DLL implementor.
 *
 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef WINE_COMIMPL_H
#define WINE_COMIMPL_H

/*
	This code provides a basic thread-safe COM implementation
	including aggregation(and an IClassFactory implementation).
	This code is based on my quartz code.

    The usage of this library is:

	1) copy comimpl.h and comimpl.c.
	2) implement the global class entries 'COMIMPL_ClassList'.
	3) export COMIMPL_DllMain, COMIMPL_DllGetClassObject and
	   COMIMPL_DllCanUnloadNow.
	4) add 'comimpl' to your debug channels.
	5) implement your IUnknown as a thunk to call
	   COMIMPL_IUnkImpl.punk methods.
	6) provide pointers of vtables in constructor.
	7) optionally, you can edit comimpl.h and/or comimpl.c.

	A sample allocator of class COne that supports
	two interface IOne and ITwo is:

	const COMIMPL_CLASSENTRY COMIMPL_ClassList[] =
	{
	  { &CLSID_COne, &COne_AllocObj },
	  { NULL, NULL } << the last entry must be NULL >>
	};

	typedef struct COne
	{
	  COMIMPL_IUnkImpl vfunk; << must be the first member of this struct >>
	  struct { ICOM_VFIELD(IOne); } vfone;
	  struct { ICOM_VFIELD(ITwo); } vftwo;
	  << ... >>
	} COne;
	#define COne_THIS(iface,member) COne* This = ((COne*)(((char*)iface)-offsetof(COne,member)))

	static COMIMPL_IFEntry IFEntries[] =
	{
	    << all supported interfaces >>
	  { &IID_IOne, offsetof(COne,vfone)-offsetof(COne,vfunk) },
	  { &IID_ITwo, offsetof(COne,vftwo)-offsetof(COne,vfunk) },
	};

	static void COne_Destructor(IUnknown* iface)
	{
	    COne_THIS(iface,vfunk);

	    << ... implement destructor ... >>
	}

	HRESULT COne_AllocObj(IUnknown* punkOuter,void** ppobj)
	{
	    COne* This;

	    This = (COne*)COMIMPL_AllocObj( sizeof(COne) );
	    if ( This == NULL ) return E_OUTOFMEMORY;
	    COMIMPL_IUnkInit( &This->vfunk, punkOuter );
	    This->vfunk.pEntries = IFEntries;
	    This->vfunk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
	    This->vfunk.pOnFinalRelease = COne_Destructor;

	    ICOM_VTBL(&This->vfone) = &ione;
	    ICOM_VTBL(&This->vftwo) = &itwo;

	    << ... implement constructor ... >>
	    << if error occurs in constructing, you can call simply
	       punk::Release() and return HRESULT. >>

	    *ppobj = (void*)(&This->vfunk);

	    return S_OK; << return S_OK if succeeded >>
	}
 */

/* if per-thread initialization is needed, uncomment the following line */
/*#define COMIMPL_PERTHREAD_INIT*/
/* If an own heap is needed, customize the following line */
#define COMIMPL_hHeap	GetProcessHeap()


typedef HRESULT (*COMIMPL_pCreateIUnknown)(IUnknown* punkOuter,void** ppobj);
typedef void (*COMIMPL_pOnFinalRelease)(IUnknown* punkInner);

typedef struct COMIMPL_IFEntry COMIMPL_IFEntry;
typedef struct COMIMPL_IFDelegation COMIMPL_IFDelegation;
typedef struct COMIMPL_IUnkImpl COMIMPL_IUnkImpl;

struct COMIMPL_IFEntry
{
	const IID*	piid;		/* interface ID. */
	size_t		ofsVTPtr;	/* offset from IUnknown. */
};

struct COMIMPL_IFDelegation
{
	struct COMIMPL_IFDelegation*	pNext;
	HRESULT (*pOnQueryInterface)(
		IUnknown* punk, const IID* piid, void** ppobj );
};

/* COMIMPL_IUnkimpl must be aligned for InterlockedExchangeAdd. */
#include <pshpack4.h>

struct COMIMPL_IUnkImpl
{
	/* pointer of IUnknown interface. */
	ICOM_VFIELD(IUnknown);

	/* array of supported IIDs and offsets. */
	const COMIMPL_IFEntry*	pEntries;
	DWORD	dwEntries;
	/* list of delegation handlers. */
	COMIMPL_IFDelegation*	pDelegationFirst;
	/* called on final release. */
	COMIMPL_pOnFinalRelease	pOnFinalRelease;

	/* IUnknown fields. */
	LONG	ref;
	IUnknown*	punkControl;
};

#include <poppack.h>

typedef struct COMIMPL_CLASSENTRY
{
	const CLSID*	pclsid;
	COMIMPL_pCreateIUnknown	pCreateIUnk;
} COMIMPL_CLASSENTRY;


extern const COMIMPL_CLASSENTRY COMIMPL_ClassList[]; /* must be provided  */

void COMIMPL_IUnkInit( COMIMPL_IUnkImpl* pImpl, IUnknown* punkOuter );
void COMIMPL_IUnkAddDelegationHandler(
	COMIMPL_IUnkImpl* pImpl, COMIMPL_IFDelegation* pDelegation );

BOOL WINAPI COMIMPL_DllMain(
	HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved );
HRESULT WINAPI COMIMPL_DllGetClassObject(
		const CLSID* pclsid,const IID* piid,void** ppv);
HRESULT WINAPI COMIMPL_DllCanUnloadNow(void);

void* COMIMPL_AllocObj( DWORD dwSize );
void COMIMPL_FreeObj( void* pobj ); /* for internal use only. */




#endif	/* WINE_COMIMPL_H */
