msdaps: Implement the marshalling object.
[wine/hramrach.git] / dlls / msdaps / row_server.c
blob017f8c45c02dccaa3a49ce9bc895a62aa46d84b7
1 /*
2 * Row and rowset servers / proxies.
4 * Copyright 2010 Huw Davies
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
21 #include <string.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winerror.h"
32 #include "objbase.h"
33 #include "oleauto.h"
34 #include "oledb.h"
36 #include "row_server.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(oledb);
43 typedef struct
45 const IWineRowServerVtbl *vtbl;
47 LONG ref;
49 CLSID class;
50 IMarshal *marshal;
51 IUnknown *inner_unk;
52 } server;
54 static inline server *impl_from_IWineRowServer(IWineRowServer *iface)
56 return (server *)((char*)iface - FIELD_OFFSET(server, vtbl));
59 static HRESULT WINAPI server_QueryInterface(IWineRowServer *iface, REFIID riid, void **obj)
61 server *This = impl_from_IWineRowServer(iface);
62 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
64 *obj = NULL;
66 if(IsEqualIID(riid, &IID_IUnknown) ||
67 IsEqualIID(riid, &IID_IWineRowServer))
69 *obj = iface;
71 else
73 if(!IsEqualIID(riid, &IID_IMarshal)) /* We use standard marshalling */
74 FIXME("interface %s not implemented\n", debugstr_guid(riid));
75 return E_NOINTERFACE;
78 IWineRowServer_AddRef(iface);
79 return S_OK;
82 static ULONG WINAPI server_AddRef(IWineRowServer *iface)
84 server *This = impl_from_IWineRowServer(iface);
85 TRACE("(%p)\n", This);
87 return InterlockedIncrement(&This->ref);
90 static ULONG WINAPI server_Release(IWineRowServer *iface)
92 server *This = impl_from_IWineRowServer(iface);
93 LONG ref;
95 TRACE("(%p)\n", This);
97 ref = InterlockedDecrement(&This->ref);
98 if(ref == 0)
100 IMarshal_Release(This->marshal);
101 if(This->inner_unk) IUnknown_Release(This->inner_unk);
102 HeapFree(GetProcessHeap(), 0, This);
105 return ref;
108 static HRESULT WINAPI server_SetInnerUnk(IWineRowServer *iface, IUnknown *inner)
110 server *This = impl_from_IWineRowServer(iface);
112 if(This->inner_unk) IUnknown_Release(This->inner_unk);
114 if(inner) IUnknown_AddRef(inner);
115 This->inner_unk = inner;
116 return S_OK;
119 static HRESULT WINAPI server_GetMarshal(IWineRowServer *iface, IMarshal **marshal)
121 server *This = impl_from_IWineRowServer(iface);
123 IMarshal_AddRef(This->marshal);
124 *marshal = This->marshal;
125 return S_OK;
128 static const IWineRowServerVtbl server_vtbl =
130 server_QueryInterface,
131 server_AddRef,
132 server_Release,
133 server_SetInnerUnk,
134 server_GetMarshal
137 static HRESULT create_server(IUnknown *outer, const CLSID *class, void **obj)
139 server *server;
140 TRACE("(%p, %s, %p)\n", outer, debugstr_guid(class), obj);
142 *obj = NULL;
144 server = HeapAlloc(GetProcessHeap(), 0, sizeof(*server));
145 if(!server) return E_OUTOFMEMORY;
147 server->vtbl = &server_vtbl;
148 server->ref = 1;
149 server->class = *class;
150 server->inner_unk = NULL;
151 if(IsEqualGUID(class, &CLSID_wine_row_server))
152 create_row_marshal((IUnknown*)server, (void**)&server->marshal);
153 else if(IsEqualGUID(class, &CLSID_wine_rowset_server))
154 create_rowset_marshal((IUnknown*)server, (void**)&server->marshal);
155 else
156 ERR("create_server called with class %s\n", debugstr_guid(class));
158 *obj = server;
159 return S_OK;
162 HRESULT create_row_server(IUnknown *outer, void **obj)
164 return create_server(outer, &CLSID_wine_row_server, obj);
167 HRESULT create_rowset_server(IUnknown *outer, void **obj)
169 return create_server(outer, &CLSID_wine_rowset_server, obj);
172 HRESULT create_proxy(IWineRowServer *server, const CLSID *class, IUnknown **obj)
174 FIXME("stub\n");
175 *obj = NULL;
176 return E_NOTIMPL;
179 /* Marshal impl */
181 typedef struct
183 const IMarshalVtbl *marshal_vtbl;
185 LONG ref;
186 CLSID unmarshal_class;
187 IUnknown *outer;
188 } marshal;
190 static inline marshal *impl_from_IMarshal(IMarshal *iface)
192 return (marshal *)((char*)iface - FIELD_OFFSET(marshal, marshal_vtbl));
195 static HRESULT WINAPI marshal_QueryInterface(IMarshal *iface, REFIID iid, void **obj)
197 marshal *This = impl_from_IMarshal(iface);
198 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
200 if(IsEqualIID(iid, &IID_IUnknown) ||
201 IsEqualIID(iid, &IID_IMarshal))
203 *obj = iface;
205 else
207 FIXME("interface %s not implemented\n", debugstr_guid(iid));
208 *obj = NULL;
209 return E_NOINTERFACE;
212 IMarshal_AddRef(iface);
213 return S_OK;
216 static ULONG WINAPI marshal_AddRef(IMarshal *iface)
218 marshal *This = impl_from_IMarshal(iface);
219 TRACE("(%p)\n", This);
220 return InterlockedIncrement(&This->ref);
223 static ULONG WINAPI marshal_Release(IMarshal *iface)
225 marshal *This = impl_from_IMarshal(iface);
226 LONG ref;
228 TRACE("(%p)\n", This);
230 ref = InterlockedDecrement(&This->ref);
231 if(ref == 0)
233 HeapFree(GetProcessHeap(), 0, This);
236 return ref;
239 static HRESULT WINAPI marshal_GetUnmarshalClass(IMarshal *iface, REFIID iid, void *obj,
240 DWORD dwDestContext, void *pvDestContext,
241 DWORD mshlflags, CLSID *clsid)
243 marshal *This = impl_from_IMarshal(iface);
244 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
245 pvDestContext, mshlflags, clsid);
247 *clsid = This->unmarshal_class;
248 return S_OK;
251 static HRESULT WINAPI marshal_GetMarshalSizeMax(IMarshal *iface, REFIID iid, void *obj,
252 DWORD dwDestContext, void *pvDestContext,
253 DWORD mshlflags, DWORD *size)
255 marshal *This = impl_from_IMarshal(iface);
256 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
257 pvDestContext, mshlflags, size);
259 return CoGetMarshalSizeMax(size, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext,
260 mshlflags);
263 static HRESULT WINAPI marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID iid,
264 void *obj, DWORD dwDestContext, void *pvDestContext,
265 DWORD mshlflags)
267 marshal *This = impl_from_IMarshal(iface);
268 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This, stream, debugstr_guid(iid), obj, dwDestContext,
269 pvDestContext, mshlflags);
271 return CoMarshalInterface(stream, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext, mshlflags);
274 static HRESULT WINAPI marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
275 REFIID iid, void **obj)
277 marshal *This = impl_from_IMarshal(iface);
278 HRESULT hr;
279 IWineRowServer *server;
280 IUnknown *proxy;
282 TRACE("(%p)->(%p, %s, %p)\n", This, stream, debugstr_guid(iid), obj);
283 *obj = NULL;
285 hr = CoUnmarshalInterface(stream, &IID_IWineRowServer, (void**)&server);
286 if(SUCCEEDED(hr))
288 hr = create_proxy(server, &This->unmarshal_class, &proxy);
289 if(SUCCEEDED(hr))
291 hr = IUnknown_QueryInterface(proxy, iid, obj);
292 IUnknown_Release(proxy);
294 IWineRowServer_Release(server);
297 TRACE("returing %p\n", *obj);
298 return hr;
301 static HRESULT WINAPI marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
303 marshal *This = impl_from_IMarshal(iface);
304 TRACE("(%p)->(%p)\n", This, stream);
305 return CoReleaseMarshalData(stream);
308 static HRESULT WINAPI marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
310 marshal *This = impl_from_IMarshal(iface);
311 FIXME("(%p)->(%08x)\n", This, dwReserved);
313 return E_NOTIMPL;
316 static const IMarshalVtbl marshal_vtbl =
318 marshal_QueryInterface,
319 marshal_AddRef,
320 marshal_Release,
321 marshal_GetUnmarshalClass,
322 marshal_GetMarshalSizeMax,
323 marshal_MarshalInterface,
324 marshal_UnmarshalInterface,
325 marshal_ReleaseMarshalData,
326 marshal_DisconnectObject
329 static HRESULT create_marshal(IUnknown *outer, const CLSID *class, void **obj)
331 marshal *marshal;
333 TRACE("(%p, %p)\n", outer, obj);
334 *obj = NULL;
336 marshal = HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal));
337 if(!marshal) return E_OUTOFMEMORY;
339 marshal->unmarshal_class = *class;
340 marshal->outer = outer; /* don't ref outer unk */
341 marshal->marshal_vtbl = &marshal_vtbl;
342 marshal->ref = 1;
344 *obj = &marshal->marshal_vtbl;
345 TRACE("returing %p\n", *obj);
346 return S_OK;
349 HRESULT create_row_marshal(IUnknown *outer, void **obj)
351 TRACE("(%p, %p)\n", outer, obj);
352 return create_marshal(outer, &CLSID_wine_row_proxy, obj);
355 HRESULT create_rowset_marshal(IUnknown *outer, void **obj)
357 TRACE("(%p, %p)\n", outer, obj);
358 return create_marshal(outer, &CLSID_wine_rowset_proxy, obj);