2 * A basic implementation for COM DLL implementor.
4 * Copyright (C) 2002 Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef WINE_COMIMPL_H
22 #define WINE_COMIMPL_H
25 This code provides a basic thread-safe COM implementation
26 including aggregation(and an IClassFactory implementation).
27 This code is based on my quartz code.
29 The usage of this library is:
31 1) copy comimpl.h and comimpl.c.
32 2) implement the global class entries 'COMIMPL_ClassList'.
33 3) export COMIMPL_DllMain, COMIMPL_DllGetClassObject and
34 COMIMPL_DllCanUnloadNow.
35 4) add 'comimpl' to your debug channels.
36 5) implement your IUnknown as a thunk to call
37 COMIMPL_IUnkImpl.punk methods.
38 6) provide pointers of vtables in constructor.
39 7) optionally, you can edit comimpl.h and/or comimpl.c.
41 A sample allocator of class COne that supports
42 two interface IOne and ITwo is:
44 const COMIMPL_CLASSENTRY COMIMPL_ClassList[] =
46 { &CLSID_COne, &COne_AllocObj },
47 { NULL, NULL } << the last entry must be NULL >>
52 COMIMPL_IUnkImpl vfunk; << must be the first member of this struct >>
53 struct { ICOM_VFIELD(IOne); } vfone;
54 struct { ICOM_VFIELD(ITwo); } vftwo;
57 #define COne_THIS(iface,member) COne* This = ((COne*)(((char*)iface)-offsetof(COne,member)))
59 static COMIMPL_IFEntry IFEntries[] =
61 << all supported interfaces >>
62 { &IID_IOne, offsetof(COne,vfone)-offsetof(COne,vfunk) },
63 { &IID_ITwo, offsetof(COne,vftwo)-offsetof(COne,vfunk) },
66 static void COne_Destructor(IUnknown* iface)
68 COne_THIS(iface,vfunk);
70 << ... implement destructor ... >>
73 HRESULT COne_AllocObj(IUnknown* punkOuter,void** ppobj)
77 This = (COne*)COMIMPL_AllocObj( sizeof(COne) );
78 if ( This == NULL ) return E_OUTOFMEMORY;
79 COMIMPL_IUnkInit( &This->vfunk, punkOuter );
80 This->vfunk.pEntries = IFEntries;
81 This->vfunk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
82 This->vfunk.pOnFinalRelease = COne_Destructor;
84 ICOM_VTBL(&This->vfone) = &ione;
85 ICOM_VTBL(&This->vftwo) = &itwo;
87 << ... implement constructor ... >>
88 << if error occurs in constructing, you can call simply
89 punk::Release() and return HRESULT. >>
91 *ppobj = (void*)(&This->vfunk);
93 return S_OK; << return S_OK if succeeded >>
97 /* if per-thread initialization is needed, uncomment the following line */
98 /*#define COMIMPL_PERTHREAD_INIT*/
99 /* If an own heap is needed, customize the following line */
100 #define COMIMPL_hHeap GetProcessHeap()
103 typedef HRESULT (*COMIMPL_pCreateIUnknown)(IUnknown* punkOuter,void** ppobj);
104 typedef void (*COMIMPL_pOnFinalRelease)(IUnknown* punkInner);
106 typedef struct COMIMPL_IFEntry COMIMPL_IFEntry;
107 typedef struct COMIMPL_IFDelegation COMIMPL_IFDelegation;
108 typedef struct COMIMPL_IUnkImpl COMIMPL_IUnkImpl;
110 struct COMIMPL_IFEntry
112 const IID* piid; /* interface ID. */
113 size_t ofsVTPtr; /* offset from IUnknown. */
116 struct COMIMPL_IFDelegation
118 struct COMIMPL_IFDelegation* pNext;
119 HRESULT (*pOnQueryInterface)(
120 IUnknown* punk, const IID* piid, void** ppobj );
123 /* COMIMPL_IUnkimpl must be aligned for InterlockedExchangeAdd. */
124 #include <pshpack4.h>
126 struct COMIMPL_IUnkImpl
128 /* pointer of IUnknown interface. */
129 ICOM_VFIELD(IUnknown);
131 /* array of supported IIDs and offsets. */
132 const COMIMPL_IFEntry* pEntries;
134 /* list of delegation handlers. */
135 COMIMPL_IFDelegation* pDelegationFirst;
136 /* called on final release. */
137 COMIMPL_pOnFinalRelease pOnFinalRelease;
139 /* IUnknown fields. */
141 IUnknown* punkControl;
146 typedef struct COMIMPL_CLASSENTRY
149 COMIMPL_pCreateIUnknown pCreateIUnk;
150 } COMIMPL_CLASSENTRY;
153 extern const COMIMPL_CLASSENTRY COMIMPL_ClassList[]; /* must be provided */
155 void COMIMPL_IUnkInit( COMIMPL_IUnkImpl* pImpl, IUnknown* punkOuter );
156 void COMIMPL_IUnkAddDelegationHandler(
157 COMIMPL_IUnkImpl* pImpl, COMIMPL_IFDelegation* pDelegation );
159 BOOL WINAPI COMIMPL_DllMain(
160 HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved );
161 HRESULT WINAPI COMIMPL_DllGetClassObject(
162 const CLSID* pclsid,const IID* piid,void** ppv);
163 HRESULT WINAPI COMIMPL_DllCanUnloadNow(void);
165 void* COMIMPL_AllocObj( DWORD dwSize );
166 void COMIMPL_FreeObj( void* pobj ); /* for internal use only. */
171 #endif /* WINE_COMIMPL_H */