Fixed some issues found by winapi_check.
[wine] / dlls / ole32 / ftmarshal.c
1 /*
2  *      free threaded marshaler
3  *
4  *  Copyright 2002  Juergen Schmied
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #include "winbase.h"
29
30 #include "wine/obj_base.h"
31 #include "wine/obj_storage.h"
32 #include "wine/obj_marshal.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(ole);
37
38 typedef struct _FTMarshalImpl {
39         ICOM_VFIELD (IUnknown);
40         DWORD ref;
41         ICOM_VTABLE (IMarshal) * lpvtblFTM;
42
43         IUnknown *pUnkOuter;
44 } FTMarshalImpl;
45
46 #define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl)
47 #define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM)
48
49 #define _IFTMarshall_Offset ((int)(&(((FTMarshalImpl*)0)->lpvtblFTM)))
50 #define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
51
52 /* inner IUnknown to handle aggregation */
53 HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
54 {
55
56     ICOM_THIS (FTMarshalImpl, iface);
57
58     TRACE ("\n");
59     *ppv = NULL;
60
61     if (IsEqualIID (&IID_IUnknown, riid))
62         *ppv = _IFTMUnknown_ (This);
63     else if (IsEqualIID (&IID_IMarshal, riid))
64         *ppv = _IFTMarshal_ (This);
65     else {
66         FIXME ("No interface for %s.\n", debugstr_guid (riid));
67         return E_NOINTERFACE;
68     }
69     IUnknown_AddRef ((IUnknown *) * ppv);
70     return S_OK;
71 }
72
73 ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
74 {
75
76     ICOM_THIS (FTMarshalImpl, iface);
77
78     TRACE ("\n");
79     return InterlockedIncrement (&This->ref);
80 }
81
82 ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
83 {
84
85     ICOM_THIS (FTMarshalImpl, iface);
86
87     TRACE ("\n");
88     if (InterlockedDecrement (&This->ref))
89         return This->ref;
90     HeapFree (GetProcessHeap (), 0, This);
91     return 0;
92 }
93
94 static ICOM_VTABLE (IUnknown) iunkvt =
95 {
96         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
97         IiFTMUnknown_fnQueryInterface,
98         IiFTMUnknown_fnAddRef,
99         IiFTMUnknown_fnRelease
100 };
101
102 HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
103 {
104
105     _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
106
107     TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv);
108     return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
109 }
110
111 ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
112 {
113
114     _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
115
116     TRACE ("\n");
117     return IUnknown_AddRef (This->pUnkOuter);
118 }
119
120 ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
121 {
122
123     _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
124
125     TRACE ("\n");
126     return IUnknown_Release (This->pUnkOuter);
127 }
128
129 HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
130                                                 void *pvDestContext, DWORD mshlflags, CLSID * pCid)
131 {
132     FIXME ("(), stub!\n");
133     return S_OK;
134 }
135
136 HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
137                                                 void *pvDestContext, DWORD mshlflags, DWORD * pSize)
138 {
139
140     IMarshal *pMarshal = NULL;
141     HRESULT hres;
142
143     _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
144
145     FIXME ("(), stub!\n");
146
147     /* if the marshaling happends inside the same process the interface pointer is
148        copied between the appartments */
149     if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
150         *pSize = sizeof (This);
151         return S_OK;
152     }
153
154     /* use the standard marshaler to handle all other cases */
155     CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
156     hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
157     IMarshal_Release (pMarshal);
158     return hres;
159
160     return S_OK;
161 }
162
163 HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
164                                                DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
165 {
166
167     IMarshal *pMarshal = NULL;
168     HRESULT hres;
169
170     _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
171
172     FIXME ("(), stub!\n");
173
174     /* if the marshaling happends inside the same process the interface pointer is
175        copied between the appartments */
176     if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
177         return IStream_Write (pStm, This, sizeof (This), 0);
178     }
179
180     /* use the standard marshaler to handle all other cases */
181     CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
182     hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
183     IMarshal_Release (pMarshal);
184     return hres;
185 }
186
187 HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
188 {
189     FIXME ("(), stub!\n");
190     return S_OK;
191 }
192
193 HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
194 {
195     FIXME ("(), stub!\n");
196     return S_OK;
197 }
198
199 HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
200 {
201     FIXME ("(), stub!\n");
202     return S_OK;
203 }
204
205 ICOM_VTABLE (IMarshal) ftmvtbl =
206 {
207         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
208         FTMarshalImpl_QueryInterface,
209         FTMarshalImpl_AddRef,
210         FTMarshalImpl_Release,
211         FTMarshalImpl_GetUnmarshalClass,
212         FTMarshalImpl_GetMarshalSizeMax,
213         FTMarshalImpl_MarshalInterface,
214         FTMarshalImpl_UnmarshalInterface,
215         FTMarshalImpl_ReleaseMarshalData,
216         FTMarshalImpl_DisconnectObject
217 };
218
219 /***********************************************************************
220  *          CoCreateFreeThreadedMarshaler [OLE32.5]
221  *
222  */
223 HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
224 {
225
226     FTMarshalImpl *ftm;
227
228     TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
229
230     ftm = (FTMarshalImpl *) HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
231     if (!ftm)
232         return E_OUTOFMEMORY;
233
234     ICOM_VTBL (ftm) = &iunkvt;
235     ftm->lpvtblFTM = &ftmvtbl;
236     ftm->ref = 1;
237     ftm->pUnkOuter = punkOuter;
238
239     *ppunkMarshal = _IFTMUnknown_ (ftm);
240     return S_OK;
241 }