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