8707ae95de706d2d9012710a69bac4a5851fbe36
[gpgme.git] / complus / obj_base.h
1 /* obj_base.h - This file defines the macros and types necessary to
2                 define COM interfaces, and the three most basic COM interfaces:
3                 IUnknown, IMalloc and IClassFactory.
4
5  Copyright (c) 1993-2000 the Wine project authors (see the file WINE-AUTHORS
6  for a complete list)
7  
8  Permission is hereby granted, free of charge, to any person obtaining a copy
9  of this software and associated documentation files (the "Software"), to deal
10  in the Software without restriction, including without limitation the rights
11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  copies of the Software, and to permit persons to whom the Software is
13  furnished to do so, subject to the following conditions:
14  
15  The above copyright notice and this permission notice shall be included in
16  all copies or substantial portions of the Software.
17  
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
21  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 #ifndef __WINE_WINE_OBJ_BASE_H
27 #define __WINE_WINE_OBJ_BASE_H
28
29 /* check these values! */
30 #define E_NOINTERFACE 0x80040002
31 #define E_OUTOFMEMORY 0x8007000E
32
33 /*****************************************************************************
34  * define ICOM_MSVTABLE_COMPAT
35  * to implement the microsoft com vtable compatibility workaround for g++.
36  *
37  * NOTE: Turning this option on will produce a winelib that is incompatible
38  * with the binary emulator.
39  *
40  * If the compiler supports the com_interface attribute, leave this off, and
41  * define the ICOM_USE_COM_INTERFACE_ATTRIBUTE macro below. This may also
42  * require the addition of the -vtable-thunks option for g++.
43  *
44  * If you aren't interested in Winelib C++ compatibility at all, leave both
45  * options off.
46  *
47  * The preferable method for using ICOM_USE_COM_INTERFACE_ATTRIBUTE macro
48  * would be to define it only for your Winelib application. This allows you
49  * to have both binary and Winelib compatibility for C and C++ at the same 
50  * time :)
51  */
52 /* #define ICOM_MSVTABLE_COMPAT 1 */
53 /* #define ICOM_USE_COM_INTERFACE_ATTRIBUTE 1 */
54
55 /*****************************************************************************
56  * Defines the basic types
57  */
58 #include "wtypes.h"
59 #include "guiddef.h"
60
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
64
65
66 #ifndef NONAMELESSSTRUCT
67 #define LISet32(li, v)   ((li).HighPart = (v) < 0 ? -1 : 0, (li).LowPart = (v))
68 #define ULISet32(li, v)  ((li).HighPart = 0, (li).LowPart = (v))
69 #else
70 #define LISet32(li, v)   ((li).s.HighPart = (v) < 0 ? -1 : 0, (li).s.LowPart = (v))
71 #define ULISet32(li, v)  ((li).s.HighPart = 0, (li).s.LowPart = (v))
72 #endif
73
74 /*****************************************************************************
75  * GUID API
76  */
77 HRESULT WINAPI StringFromCLSID16(REFCLSID id, LPOLESTR16*);
78 HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR*);
79
80 HRESULT WINAPI CLSIDFromString16(LPCOLESTR16, CLSID *);
81 HRESULT WINAPI CLSIDFromString(LPCOLESTR, CLSID *);
82
83 HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid);
84 HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid);
85
86 HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID);
87
88
89 INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax);
90
91
92 /*****************************************************************************
93  * Macros to define a COM interface
94  */
95 /*
96  * The goal of the following set of definitions is to provide a way to use the same 
97  * header file definitions to provide both a C interface and a C++ object oriented 
98  * interface to COM interfaces. The type of interface is selected automatically 
99  * depending on the language but it is always possible to get the C interface in C++ 
100  * by defining CINTERFACE.
101  *
102  * It is based on the following assumptions:
103  *  - all COM interfaces derive from IUnknown, this should not be a problem.
104  *  - the header file only defines the interface, the actual fields are defined 
105  *    separately in the C file implementing the interface.
106  *
107  * The natural approach to this problem would be to make sure we get a C++ class and 
108  * virtual methods in C++ and a structure with a table of pointer to functions in C.
109  * Unfortunately the layout of the virtual table is compiler specific, the layout of 
110  * g++ virtual tables is not the same as that of an egcs virtual table which is not the 
111  * same as that generated by Visual C+. There are workarounds to make the virtual tables 
112  * compatible via padding but unfortunately the one which is imposed to the WINE emulator
113  * by the Windows binaries, i.e. the Visual C++ one, is the most compact of all.
114  *
115  * So the solution I finally adopted does not use virtual tables. Instead I use inline 
116  * non virtual methods that dereference the method pointer themselves and perform the call.
117  *
118  * Let's take Direct3D as an example:
119  *
120  *    #define ICOM_INTERFACE IDirect3D
121  *    #define IDirect3D_METHODS \
122  *        ICOM_METHOD1(HRESULT,Initialize,    REFIID,) \
123  *        ICOM_METHOD2(HRESULT,EnumDevices,   LPD3DENUMDEVICESCALLBACK,, LPVOID,) \
124  *        ICOM_METHOD2(HRESULT,CreateLight,   LPDIRECT3DLIGHT*,, IUnknown*,) \
125  *        ICOM_METHOD2(HRESULT,CreateMaterial,LPDIRECT3DMATERIAL*,, IUnknown*,) \
126  *        ICOM_METHOD2(HRESULT,CreateViewport,LPDIRECT3DVIEWPORT*,, IUnknown*,) \
127  *        ICOM_METHOD2(HRESULT,FindDevice,    LPD3DFINDDEVICESEARCH,, LPD3DFINDDEVICERESULT,)
128  *    #define IDirect3D_IMETHODS \
129  *        IUnknown_IMETHODS \
130  *        IDirect3D_METHODS
131  *    ICOM_DEFINE(IDirect3D,IUnknown)
132  *    #undef ICOM_INTERFACE
133  *
134  *    #ifdef ICOM_CINTERFACE
135  *    // *** IUnknown methods *** //
136  *    #define IDirect3D_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
137  *    #define IDirect3D_AddRef(p)             ICOM_CALL (AddRef,p)
138  *    #define IDirect3D_Release(p)            ICOM_CALL (Release,p)
139  *    // *** IDirect3D methods *** //
140  *    #define IDirect3D_Initialize(p,a)       ICOM_CALL1(Initialize,p,a)
141  *    #define IDirect3D_EnumDevices(p,a,b)    ICOM_CALL2(EnumDevice,p,a,b)
142  *    #define IDirect3D_CreateLight(p,a,b)    ICOM_CALL2(CreateLight,p,a,b)
143  *    #define IDirect3D_CreateMaterial(p,a,b) ICOM_CALL2(CreateMaterial,p,a,b)
144  *    #define IDirect3D_CreateViewport(p,a,b) ICOM_CALL2(CreateViewport,p,a,b)
145  *    #define IDirect3D_FindDevice(p,a,b)     ICOM_CALL2(FindDevice,p,a,b)
146  *    #endif
147  *
148  * Comments:
149  *  - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this' 
150  *    pointer. Defining this macro here saves us the trouble of having to repeat the interface 
151  *    name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1 
152  *    cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not 
153  *    'IDirect3D_VTABLE'.
154  *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the 
155  *    inherited methods to form ICOM_IMETHODS.
156  *  - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must 
157  *    be written manually (rather than using a macro to generate the equivalent code) to avoid 
158  *    macro recursion (which compilers don't like).
159  *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to 
160  *    explicitly use the interface name for macro expansion reasons again.
161  *    Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's 
162  *    Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance 
163  *    is taken care of by the language.
164  *  - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer 
165  *    method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The 
166  *    only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and 
167  *    to have it take only the type information (with const if necessary) as parameters.
168  *    The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following 
169  *    macros will not work. This time it's because the ICOM_CALL macro expansion is done only once 
170  *    the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone 
171  *    anyway.
172  *  - You may have noticed the double commas after each parameter type. This allows you to put the 
173  *    name of that parameter which I think is good for documentation. It is not required and since 
174  *    I did not know what to put there for this example (I could only find doc about IDirect3D2), 
175  *    I left them blank.
176  *  - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access 
177  *    to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate 
178  *    the inherited method definitions there. This time I could have used a trick to use only one 
179  *    macro whatever the number of parameters but I prefered to have it work the same way as above.
180  *  - You probably have noticed that we don't define the fields we need to actually implement this 
181  *    interface: reference count, pointer to other resources and miscellaneous fields. That's 
182  *    because these interfaces are just that: interfaces. They may be implemented more than once, in 
183  *    different contexts and sometimes not even in Wine. Thus it would not make sense to impose 
184  *    that the interface contains some specific fields.
185  *
186  *
187  * In C this gives:
188  *    typedef struct IDirect3DVtbl IDirect3DVtbl;
189  *    struct IDirect3D {
190  *        IDirect3DVtbl* lpVtbl;
191  *    };
192  *    struct IDirect3DVtbl {
193  *        HRESULT (*fnQueryInterface)(IDirect3D* me, REFIID riid, LPVOID* ppvObj);
194  *        ULONG (*fnQueryInterface)(IDirect3D* me);
195  *        ULONG (*fnQueryInterface)(IDirect3D* me);
196  *        HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
197  *        HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
198  *        HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
199  *        HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
200  *        HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
201  *        HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
202  *    }; 
203  *
204  *    #ifdef ICOM_CINTERFACE
205  *    // *** IUnknown methods *** //
206  *    #define IDirect3D_QueryInterface(p,a,b) (p)->lpVtbl->fnQueryInterface(p,a,b)
207  *    #define IDirect3D_AddRef(p)             (p)->lpVtbl->fnAddRef(p)
208  *    #define IDirect3D_Release(p)            (p)->lpVtbl->fnRelease(p)
209  *    // *** IDirect3D methods *** //
210  *    #define IDirect3D_Initialize(p,a)       (p)->lpVtbl->fnInitialize(p,a)
211  *    #define IDirect3D_EnumDevices(p,a,b)    (p)->lpVtbl->fnEnumDevice(p,a,b)
212  *    #define IDirect3D_CreateLight(p,a,b)    (p)->lpVtbl->fnCreateLight(p,a,b)
213  *    #define IDirect3D_CreateMaterial(p,a,b) (p)->lpVtbl->fnCreateMaterial(p,a,b)
214  *    #define IDirect3D_CreateViewport(p,a,b) (p)->lpVtbl->fnCreateViewport(p,a,b)
215  *    #define IDirect3D_FindDevice(p,a,b)     (p)->lpVtbl->fnFindDevice(p,a,b)
216  *    #endif
217  *
218  * Comments:
219  *  - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing 
220  *    the user needs to know to use the interface. Of course the structure we will define to 
221  *    implement this interface will have more fields but the first one will match this pointer.
222  *  - The code generated by ICOM_DEFINE defines both the structure representing the interface and 
223  *    the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to 
224  *    automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS 
225  *    to define the IDirect3D methods.
226  *  - Each method is declared as a pointer to function field in the jump table. The implementation 
227  *    will fill this jump table with appropriate values, probably using a static variable, and 
228  *    initialize the lpVtbl field to point to this variable.
229  *  - The IDirect3D_Xxx macros then just derefence the lpVtbl pointer and use the function pointer 
230  *    corresponding to the macro name. This emulates the behavior of a virtual table and should be 
231  *    just as fast.
232  *  - This C code should be quite compatible with the Windows headers both for code that uses COM 
233  *    interfaces and for code implementing a COM interface.
234  *
235  *
236  * And in C++ (with gcc's g++):
237  *
238  *    typedef struct IDirect3D: public IUnknown {
239  *        private: HRESULT (*fnInitialize)(IDirect3D* me, REFIID a);
240  *        public: inline HRESULT Initialize(REFIID a) { return ((IDirect3D*)t.lpVtbl)->fnInitialize(this,a); };
241  *        private: HRESULT (*fnEnumDevices)(IDirect3D* me, LPD3DENUMDEVICESCALLBACK a, LPVOID b);
242  *        public: inline HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK a, LPVOID b)
243  *            { return ((IDirect3D*)t.lpVtbl)->fnEnumDevices(this,a,b); };
244  *        private: HRESULT (*fnCreateLight)(IDirect3D* me, LPDIRECT3DLIGHT* a, IUnknown* b);
245  *        public: inline HRESULT CreateLight(LPDIRECT3DLIGHT* a, IUnknown* b)
246  *            { return ((IDirect3D*)t.lpVtbl)->fnCreateLight(this,a,b); };
247  *        private: HRESULT (*fnCreateMaterial)(IDirect3D* me, LPDIRECT3DMATERIAL* a, IUnknown* b);
248  *        public: inline HRESULT CreateMaterial(LPDIRECT3DMATERIAL* a, IUnknown* b)
249  *            { return ((IDirect3D*)t.lpVtbl)->fnCreateMaterial(this,a,b); };
250  *        private: HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
251  *        public: inline HRESULT CreateViewport(LPDIRECT3DVIEWPORT* a, IUnknown* b)
252  *            { return ((IDirect3D*)t.lpVtbl)->fnCreateViewport(this,a,b); };
253  *        private:  HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
254  *        public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
255  *            { return ((IDirect3D*)t.lpVtbl)->fnFindDevice(this,a,b); };
256  *    }; 
257  *
258  * Comments:
259  *  - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface 
260  *    definition. The reason for this is to avoid having to duplicate the mehod definitions: once 
261  *    to have the function pointers in the jump table and once to have the methods in the interface 
262  *    class. Here one macro can generate both. This means though that the first pointer, t.lpVtbl 
263  *    defined in IUnknown,  must be interpreted as the jump table pointer if we interpret the 
264  *    structure as the the interface class, and as the function pointer to the QueryInterface 
265  *    method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this 
266  *    gymnastic is entirely taken care of in the header of IUnknown.
267  *  - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions. 
268  *  - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and 
269  *    a non-vritual inline method which dereferences it and calls it. This way this method behaves 
270  *    just like a virtual method but does not create a true C++ virtual table which would break the 
271  *    structure layout. If you look at the implementation of these methods you'll notice that they 
272  *    would not work for void functions. We have to return something and fortunately this seems to 
273  *    be what all the COM methods do (otherwise we would need another set of macros).
274  *  - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter 
275  *    names and the method invocation using only the formal parameter name. This is the reason why 
276  *    we need different macros to handle different numbers of parameters.
277  *  - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE 
278  *    macro is defined in which case we would not be here.
279  *  - This C++ code works well for code that just uses COM interfaces. But it will not work with 
280  *    C++ code implement a COM interface. That's because such code assumes the interface methods 
281  *    are declared as virtual C++ methods which is not the case here.
282  *
283  *
284  * Implementing a COM interface.
285  *
286  * This continues the above example. This example assumes that the implementation is in C.
287  *
288  *    typedef struct _IDirect3D {
289  *        void* lpVtbl;
290  *        // ...
291  *
292  *    } _IDirect3D;
293  *
294  *    static ICOM_VTABLE(IDirect3D) d3dvt;
295  *
296  *    // implement the IDirect3D methods here
297  *
298  *    int IDirect3D_fnQueryInterface(IDirect3D* me)
299  *    {
300  *        ICOM_THIS(IDirect3D,me);
301  *        // ...
302  *    }
303  *
304  *    // ...
305  *
306  *    static ICOM_VTABLE(IDirect3D) d3dvt = {
307  *        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
308  *        IDirect3D_fnQueryInterface,
309  *        IDirect3D_fnAdd,
310  *        IDirect3D_fnAdd2,
311  *        IDirect3D_fnInitialize,
312  *        IDirect3D_fnSetWidth
313  *    };
314  *
315  * Comments:
316  *  - We first define what the interface really contains. This is th e_IDirect3D structure. The 
317  *    first field must of course be the virtual table pointer. Everything else is free.
318  *  - Then we predeclare our static virtual table variable, we will need its address in some 
319  *    methods to initialize the virtual table pointer of the returned interface objects.
320  *  - Then we implement the interface methods. To match what has been declared in the header file 
321  *    they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that 
322  *    we can manipulate the fields. This is performed by the ICOM_THIS macro.
323  *  - Finally we initialize the virtual table.
324  */
325
326
327 #define ICOM_VTABLE(iface)       iface##Vtbl
328 #define ICOM_VFIELD(iface)       ICOM_VTABLE(iface)* lpVtbl
329 #define ICOM_VTBL(iface)         (iface)->lpVtbl
330
331
332 #if !defined(__cplusplus) || defined(CINTERFACE)
333 #define ICOM_CINTERFACE 1
334 #endif
335
336 #ifndef ICOM_CINTERFACE
337 /* C++ interface */
338
339 #define ICOM_METHOD(ret,xfn) \
340      public: virtual ret CALLBACK (xfn)(void) = 0;
341 #define ICOM_METHOD1(ret,xfn,ta,na) \
342      public: virtual ret CALLBACK (xfn)(ta a) = 0;
343 #define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
344      public: virtual ret CALLBACK (xfn)(ta a,tb b) = 0;
345 #define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
346      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c) = 0;
347 #define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
348      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d) = 0;
349 #define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
350      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e) = 0;
351 #define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
352      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
353 #define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
354      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
355 #define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
356      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
357 #define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
358      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0;
359 #define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
360      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j) = 0;
361 #define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
362      public: virtual ret CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k) = 0;
363
364
365 #define ICOM_VMETHOD(xfn) \
366      public: virtual void CALLBACK (xfn)(void) = 0;
367 #define ICOM_VMETHOD1(xfn,ta,na) \
368      public: virtual void CALLBACK (xfn)(ta a) = 0;
369 #define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
370      public: virtual void CALLBACK (xfn)(ta a,tb b) = 0;
371 #define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
372      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c) = 0;
373 #define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
374      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d) = 0;
375 #define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
376      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e) = 0;
377 #define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
378      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
379 #define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
380      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
381 #define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
382      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
383 #define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
384      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0;
385 #define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
386      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i, tj j) = 0;
387 #define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
388      public: virtual void CALLBACK (xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i, tj j, tk k) = 0;
389
390
391 #ifdef ICOM_USE_COM_INTERFACE_ATTRIBUTE
392
393 #define ICOM_DEFINE(iface,ibase) \
394     typedef struct iface: public ibase { \
395         iface##_METHODS \
396             } __attribute__ ((com_interface));
397
398 #else
399
400 #define ICOM_DEFINE(iface,ibase) \
401     typedef struct iface: public ibase { \
402         iface##_METHODS \
403     };
404
405 #endif /* ICOM_USE_COM_INTERFACE_ATTRIBUTE */
406
407 #define ICOM_CALL(xfn, p)                         (p)->xfn()
408 #define ICOM_CALL1(xfn, p,a)                      (p)->xfn(a)
409 #define ICOM_CALL2(xfn, p,a,b)                    (p)->xfn(a,b)
410 #define ICOM_CALL3(xfn, p,a,b,c)                  (p)->xfn(a,b,c)
411 #define ICOM_CALL4(xfn, p,a,b,c,d)                (p)->xfn(a,b,c,d)
412 #define ICOM_CALL5(xfn, p,a,b,c,d,e)              (p)->xfn(a,b,c,d,e)
413 #define ICOM_CALL6(xfn, p,a,b,c,d,e,f)            (p)->xfn(a,b,c,d,e,f)
414 #define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g)          (p)->xfn(a,b,c,d,e,f,g)
415 #define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h)        (p)->xfn(a,b,c,d,e,f,g,h)
416 #define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i)      (p)->xfn(a,b,c,d,e,f,g,h,i)
417 #define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j)   (p)->xfn(a,b,c,d,e,f,g,h,i,j)
418 #define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) (p)->xfn(a,b,c,d,e,f,g,h,i,j,k)
419
420
421 #else
422 /* C interface */
423
424
425 #ifdef __WINE__
426
427 #define ICOM_METHOD(ret,xfn) \
428     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me);
429 #define ICOM_METHOD1(ret,xfn,ta,na) \
430     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a);
431 #define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
432     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b);
433 #define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
434     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
435 #define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
436     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
437 #define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
438     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
439 #define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
440     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
441 #define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
442     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
443 #define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
444     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
445 #define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
446     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
447 #define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
448     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
449 #define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
450     ret CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
451
452 #define ICOM_VMETHOD(xfn) \
453     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me);
454 #define ICOM_VMETHOD1(xfn,ta,na) \
455     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a);
456 #define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
457     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b);
458 #define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
459     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
460 #define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
461     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
462 #define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
463     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
464 #define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
465     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
466 #define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
467     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
468 #define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,nh) \
469     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
470 #define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ni) \
471     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
472 #define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,nj) \
473     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
474 #define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,nk) \
475     void CALLBACK (*fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
476
477 #define ICOM_CALL(xfn, p)                         ICOM_VTBL(p)->fn##xfn(p)
478 #define ICOM_CALL1(xfn, p,a)                      ICOM_VTBL(p)->fn##xfn(p,a)
479 #define ICOM_CALL2(xfn, p,a,b)                    ICOM_VTBL(p)->fn##xfn(p,a,b)
480 #define ICOM_CALL3(xfn, p,a,b,c)                  ICOM_VTBL(p)->fn##xfn(p,a,b,c)
481 #define ICOM_CALL4(xfn, p,a,b,c,d)                ICOM_VTBL(p)->fn##xfn(p,a,b,c,d)
482 #define ICOM_CALL5(xfn, p,a,b,c,d,e)              ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e)
483 #define ICOM_CALL6(xfn, p,a,b,c,d,e,f)            ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f)
484 #define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g)          ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g)
485 #define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h)        ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h)
486 #define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i)      ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h,i)
487 #define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j)   ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h,i,j)
488 #define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) ICOM_VTBL(p)->fn##xfn(p,a,b,c,d,e,f,g,h,i,j,k)
489
490 #else
491
492 /* WINELIB case */
493
494 #define ICOM_METHOD(ret,xfn) \
495     ret CALLBACK (*xfn)(ICOM_INTERFACE* me);
496 #define ICOM_METHOD1(ret,xfn,ta,na) \
497     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a);
498 #define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
499     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b);
500 #define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
501     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
502 #define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
503     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
504 #define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
505     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
506 #define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
507     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
508 #define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
509     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
510 #define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
511     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
512 #define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
513     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
514 #define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
515     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
516 #define ICOM_METHOD11(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
517     ret CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
518
519 #define ICOM_VMETHOD(xfn) \
520     void CALLBACK (*xfn)(ICOM_INTERFACE* me);
521 #define ICOM_VMETHOD1(xfn,ta,na) \
522     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a);
523 #define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
524     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b);
525 #define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
526     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c);
527 #define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
528     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
529 #define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
530     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
531 #define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
532     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
533 #define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
534     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
535 #define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,nh) \
536     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
537 #define ICOM_VMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ni) \
538     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
539 #define ICOM_VMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,nj) \
540     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
541 #define ICOM_VMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,nk) \
542     void CALLBACK (*xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
543
544 #define ICOM_CVMETHOD(xfn) \
545         void CALLBACK (*xfn)(const ICOM_INTERFACE* me);
546 #define ICOM_CVMETHOD1(xfn,ta,na) \
547     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a);
548 #define ICOM_CVMETHOD2(xfn,ta,na,tb,nb) \
549     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b);
550 #define ICOM_CVMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
551     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c);
552 #define ICOM_CVMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
553     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d);
554 #define ICOM_CVMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
555     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e);
556 #define ICOM_CVMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
557     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f);
558 #define ICOM_CVMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
559     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g);
560 #define ICOM_CVMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
561     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h);
562
563 #define ICOM_CVMETHOD9(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
564     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i);
565 #define ICOM_CVMETHOD10(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
566     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j);
567 #define ICOM_CVMETHOD11(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj,tk,nk) \
568     void CALLBACK (*xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j,tk k);
569
570 #define ICOM_CALL(xfn, p)                         ICOM_VTBL(p)->xfn(p)
571 #define ICOM_CALL1(xfn, p,a)                      ICOM_VTBL(p)->xfn(p,a)
572 #define ICOM_CALL2(xfn, p,a,b)                    ICOM_VTBL(p)->xfn(p,a,b)
573 #define ICOM_CALL3(xfn, p,a,b,c)                  ICOM_VTBL(p)->xfn(p,a,b,c)
574 #define ICOM_CALL4(xfn, p,a,b,c,d)                ICOM_VTBL(p)->xfn(p,a,b,c,d)
575 #define ICOM_CALL5(xfn, p,a,b,c,d,e)              ICOM_VTBL(p)->xfn(p,a,b,c,d,e)
576 #define ICOM_CALL6(xfn, p,a,b,c,d,e,f)            ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f)
577 #define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g)          ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g)
578 #define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h)        ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h)
579 #define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i)      ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i)
580 #define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j)   ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i,j)
581 #define ICOM_CALL11(xfn, p,a,b,c,d,e,f,g,h,i,j,k) ICOM_VTBL(p)->xfn(p,a,b,c,d,e,f,g,h,i,j,k)
582
583 #endif /* __WINE__ */
584
585 #ifdef ICOM_MSVTABLE_COMPAT
586 #define ICOM_DEFINE(iface,ibase) \
587     typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \
588     struct iface { \
589         const ICOM_VFIELD(iface); \
590     }; \
591     struct ICOM_VTABLE(iface) { \
592         long dummyRTTI1; \
593         long dummyRTTI2; \
594         ibase##_IMETHODS \
595         iface##_METHODS \
596     };
597 #define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 0,0,
598
599 #else
600 #define ICOM_DEFINE(iface,ibase) \
601     typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \
602     struct iface { \
603         const ICOM_VFIELD(iface); \
604     }; \
605     struct ICOM_VTABLE(iface) { \
606         ibase##_IMETHODS \
607         iface##_METHODS \
608     };
609 #define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
610 #endif /* ICOM_MSVTABLE_COMPAT */
611
612
613 #define ICOM_THIS(impl,iface)          impl* const This=(impl*)iface
614 #define ICOM_CTHIS(impl,iface)         const impl* const This=(const impl*)iface
615
616 #endif
617
618
619 /*****************************************************************************
620  * Predeclare the interfaces
621  */
622 DEFINE_OLEGUID(IID_IClassFactory,       0x00000001L, 0, 0);
623 typedef struct IClassFactory IClassFactory, *LPCLASSFACTORY;
624
625 DEFINE_OLEGUID(IID_IMalloc,             0x00000002L, 0, 0);
626 typedef struct IMalloc IMalloc,*LPMALLOC;
627
628 DEFINE_OLEGUID(IID_IUnknown,            0x00000000L, 0, 0);
629 typedef struct IUnknown IUnknown, *LPUNKNOWN;
630
631
632 /*****************************************************************************
633  * IUnknown interface
634  */
635 #define ICOM_INTERFACE IUnknown
636 #define IUnknown_IMETHODS \
637     ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj) \
638     ICOM_METHOD (ULONG,AddRef) \
639     ICOM_METHOD (ULONG,Release)
640 #ifdef ICOM_CINTERFACE
641 typedef struct ICOM_VTABLE(IUnknown) ICOM_VTABLE(IUnknown);
642 struct IUnknown {
643     ICOM_VFIELD(IUnknown);
644 #if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE)
645 } __attribute__ ((com_interface)); 
646 #else
647 };
648 #endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE */
649
650 struct ICOM_VTABLE(IUnknown) {
651 #ifdef ICOM_MSVTABLE_COMPAT
652     long dummyRTTI1;
653     long dummyRTTI2;
654 #endif /* ICOM_MSVTABLE_COMPAT */
655
656 #else /* ICOM_CINTERFACE */
657 struct IUnknown {
658
659 #endif /* ICOM_CINTERFACE */
660
661     ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj)
662     ICOM_METHOD (ULONG,AddRef)
663     ICOM_METHOD (ULONG,Release)
664 #if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE)
665 } __attribute__ ((com_interface)); 
666 #else
667 };
668 #endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE */
669
670 #undef ICOM_INTERFACE
671
672 /*** IUnknown methods ***/
673 #define IUnknown_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
674 #define IUnknown_AddRef(p)             ICOM_CALL (AddRef,p)
675 #define IUnknown_Release(p)            ICOM_CALL (Release,p)
676
677 /*****************************************************************************
678  * IClassFactory interface
679  */
680 #define ICOM_INTERFACE IClassFactory
681 #define IClassFactory_METHODS \
682     ICOM_METHOD3(HRESULT,CreateInstance, LPUNKNOWN,pUnkOuter, REFIID,riid, LPVOID*,ppvObject) \
683     ICOM_METHOD1(HRESULT,LockServer,     BOOL,fLock)
684 #define IClassFactory_IMETHODS \
685     IUnknown_IMETHODS \
686     IClassFactory_METHODS
687 ICOM_DEFINE(IClassFactory,IUnknown)
688 #undef ICOM_INTERFACE
689
690 /*** IUnknown methods ***/
691 #define IClassFactory_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
692 #define IClassFactory_AddRef(p)             ICOM_CALL (AddRef,p)
693 #define IClassFactory_Release(p)            ICOM_CALL (Release,p)
694 /*** IClassFactory methods ***/
695 #define IClassFactory_CreateInstance(p,a,b,c) ICOM_CALL3(CreateInstance,p,a,b,c)
696 #define IClassFactory_LockServer(p,a)         ICOM_CALL1(LockServer,p,a)
697
698
699 /*****************************************************************************
700  * IMalloc interface
701  */
702 #define ICOM_INTERFACE IMalloc
703 #define IMalloc_METHODS \
704     ICOM_METHOD1 (LPVOID,Alloc,       DWORD,cb) \
705     ICOM_METHOD2 (LPVOID,Realloc,     LPVOID,pv, DWORD,cb) \
706     ICOM_VMETHOD1(       Free,        LPVOID,pv) \
707     ICOM_METHOD1(DWORD, GetSize,     LPVOID,pv) \
708     ICOM_METHOD1(INT, DidAlloc,    LPVOID,pv) \
709     ICOM_METHOD  (VOID,  HeapMinimize)
710 #define IMalloc_IMETHODS \
711     IUnknown_IMETHODS \
712     IMalloc_METHODS
713 ICOM_DEFINE(IMalloc,IUnknown)
714 #undef ICOM_INTERFACE
715
716 /*** IUnknown methods ***/
717 #define IMalloc_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
718 #define IMalloc_AddRef(p)             ICOM_CALL (AddRef,p)
719 #define IMalloc_Release(p)            ICOM_CALL (Release,p)
720 /*** IMalloc32 methods ***/
721 #define IMalloc_Alloc(p,a)      ICOM_CALL1(Alloc,p,a)
722 #define IMalloc_Realloc(p,a,b)  ICOM_CALL2(Realloc,p,a,b)
723 #define IMalloc_Free(p,a)       ICOM_CALL1(Free,p,a)
724 #define IMalloc_GetSize(p,a)    ICOM_CALL1(GetSize,p,a)
725 #define IMalloc_DidAlloc(p,a)   ICOM_CALL1(DidAlloc,p,a)
726 #define IMalloc_HeapMinimize(p) ICOM_CALL (HeapMinimize,p)
727
728
729 HRESULT WINAPI CoGetMalloc(DWORD dwMemContext,LPMALLOC* lpMalloc);
730
731 LPVOID WINAPI CoTaskMemAlloc(ULONG size);
732
733 void WINAPI CoTaskMemFree(LPVOID ptr);
734
735 /* FIXME: unimplemented */
736 LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, ULONG size);
737
738
739 /*****************************************************************************
740  * Additional API
741  */
742
743 HRESULT WINAPI CoCreateGuid(GUID* pguid);
744
745 HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree);
746
747 void WINAPI CoFreeAllLibraries(void);
748
749 void WINAPI CoFreeLibrary(HINSTANCE hLibrary);
750
751 void WINAPI CoFreeUnusedLibraries(void);
752
753 HRESULT WINAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv);
754
755 HRESULT WINAPI CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, LPVOID pvReserved, REFIID iid, LPVOID *ppv);
756
757 HRESULT WINAPI CoInitialize(LPVOID lpReserved);
758 HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit);
759
760 void WINAPI CoUninitialize(void);
761
762 typedef enum tagCOINIT
763 {
764     COINIT_APARTMENTTHREADED  = 0x2, /* Apartment model */
765     COINIT_MULTITHREADED      = 0x0, /* OLE calls objects on any thread */
766     COINIT_DISABLE_OLE1DDE    = 0x4, /* Don't use DDE for Ole1 support */
767     COINIT_SPEED_OVER_MEMORY  = 0x8  /* Trade memory for speed */
768 } COINIT;
769
770
771 /* FIXME: not implemented */
772 BOOL WINAPI CoIsOle1Class(REFCLSID rclsid);
773
774 HRESULT WINAPI CoLockObjectExternal(LPUNKNOWN pUnk, BOOL fLock, BOOL fLastUnlockReleases);
775
776 /* class registration flags; passed to CoRegisterClassObject */
777 typedef enum tagREGCLS
778 {
779     REGCLS_SINGLEUSE = 0,
780     REGCLS_MULTIPLEUSE = 1,
781     REGCLS_MULTI_SEPARATE = 2,
782     REGCLS_SUSPENDED = 4
783 } REGCLS;
784
785 HRESULT WINAPI CoResumeClassObjects (void);
786 HRESULT WINAPI CoRegisterClassObject(REFCLSID rclsid,LPUNKNOWN pUnk,DWORD dwClsContext,DWORD flags,LPDWORD lpdwRegister);
787
788 HRESULT WINAPI CoRevokeClassObject(DWORD dwRegister);
789
790 /*****************************************************************************
791  *      COM Server dll - exports
792  */
793 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv);
794 HRESULT WINAPI DllCanUnloadNow(void);
795
796 #ifdef __cplusplus
797 } /* extern "C" */
798 #endif
799
800 #endif /* __WINE_WINE_OBJ_BASE_H */