msdaps: Add a stub row proxy object.
[wine/hramrach.git] / dlls / msdaps / row_server.c
blob92c82fba3f31430facba11ec8fdf0ccd50ea4671
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 typedef struct
174 const IRowVtbl *row_vtbl;
176 LONG ref;
178 IWineRowServer *server;
179 } row_proxy;
181 static inline row_proxy *impl_from_IRow(IRow *iface)
183 return (row_proxy *)((char*)iface - FIELD_OFFSET(row_proxy, row_vtbl));
186 static HRESULT WINAPI row_QueryInterface(IRow *iface, REFIID iid, void **obj)
188 row_proxy *This = impl_from_IRow(iface);
189 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
191 if(IsEqualIID(iid, &IID_IUnknown) ||
192 IsEqualIID(iid, &IID_IRow))
194 *obj = &This->row_vtbl;
196 else
198 FIXME("interface %s not implemented\n", debugstr_guid(iid));
199 return E_NOINTERFACE;
202 IRow_AddRef(iface);
203 return S_OK;
206 static ULONG WINAPI row_AddRef(IRow *iface)
208 row_proxy *This = impl_from_IRow(iface);
209 TRACE("(%p)\n", This);
211 return InterlockedIncrement(&This->ref);
214 static ULONG WINAPI row_Release(IRow *iface)
216 row_proxy *This = impl_from_IRow(iface);
217 LONG ref;
219 TRACE("(%p)\n", This);
221 ref = InterlockedDecrement(&This->ref);
222 if(ref == 0)
224 if(This->server) IWineRowServer_Release(This->server);
225 HeapFree(GetProcessHeap(), 0, This);
228 return ref;
231 static HRESULT WINAPI row_GetColumns(IRow* iface, DBORDINAL cColumns, DBCOLUMNACCESS rgColumns[])
233 row_proxy *This = impl_from_IRow(iface);
235 FIXME("(%p)->(%d, %p): stub\n", This, cColumns, rgColumns);
237 return E_NOTIMPL;
240 static HRESULT WINAPI row_GetSourceRowset(IRow* iface, REFIID riid, IUnknown **ppRowset,
241 HROW *phRow)
243 row_proxy *This = impl_from_IRow(iface);
245 FIXME("(%p)->(%s, %p, %p): stub\n", This, debugstr_guid(riid), ppRowset, phRow);
247 return E_NOTIMPL;
250 static HRESULT WINAPI row_Open(IRow* iface, IUnknown *pUnkOuter,
251 DBID *pColumnID, REFGUID rguidColumnType,
252 DWORD dwBindFlags, REFIID riid, IUnknown **ppUnk)
254 row_proxy *This = impl_from_IRow(iface);
256 FIXME("(%p)->(%p, %p, %s, %08x, %s, %p): stub\n", This, pUnkOuter, pColumnID, debugstr_guid(rguidColumnType),
257 dwBindFlags, debugstr_guid(riid), ppUnk);
259 return E_NOTIMPL;
262 static const IRowVtbl row_vtbl =
264 row_QueryInterface,
265 row_AddRef,
266 row_Release,
267 row_GetColumns,
268 row_GetSourceRowset,
269 row_Open
272 static HRESULT create_row_proxy(IWineRowServer *server, IUnknown **obj)
274 row_proxy *proxy;
276 TRACE("(%p, %p)\n", server, obj);
277 *obj = NULL;
279 proxy = HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy));
280 if(!proxy) return E_OUTOFMEMORY;
282 proxy->row_vtbl = &row_vtbl;
283 proxy->ref = 1;
284 IWineRowServer_AddRef(server);
285 proxy->server = server;
287 *obj = (IUnknown*)&proxy->row_vtbl;
288 TRACE("returing %p\n", *obj);
289 return S_OK;
292 static HRESULT create_proxy(IWineRowServer *server, const CLSID *class, IUnknown **obj)
294 *obj = NULL;
296 if(IsEqualGUID(class, &CLSID_wine_row_proxy))
297 return create_row_proxy(server, obj);
298 else
299 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
300 return E_NOTIMPL;
303 /* Marshal impl */
305 typedef struct
307 const IMarshalVtbl *marshal_vtbl;
309 LONG ref;
310 CLSID unmarshal_class;
311 IUnknown *outer;
312 } marshal;
314 static inline marshal *impl_from_IMarshal(IMarshal *iface)
316 return (marshal *)((char*)iface - FIELD_OFFSET(marshal, marshal_vtbl));
319 static HRESULT WINAPI marshal_QueryInterface(IMarshal *iface, REFIID iid, void **obj)
321 marshal *This = impl_from_IMarshal(iface);
322 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
324 if(IsEqualIID(iid, &IID_IUnknown) ||
325 IsEqualIID(iid, &IID_IMarshal))
327 *obj = iface;
329 else
331 FIXME("interface %s not implemented\n", debugstr_guid(iid));
332 *obj = NULL;
333 return E_NOINTERFACE;
336 IMarshal_AddRef(iface);
337 return S_OK;
340 static ULONG WINAPI marshal_AddRef(IMarshal *iface)
342 marshal *This = impl_from_IMarshal(iface);
343 TRACE("(%p)\n", This);
344 return InterlockedIncrement(&This->ref);
347 static ULONG WINAPI marshal_Release(IMarshal *iface)
349 marshal *This = impl_from_IMarshal(iface);
350 LONG ref;
352 TRACE("(%p)\n", This);
354 ref = InterlockedDecrement(&This->ref);
355 if(ref == 0)
357 HeapFree(GetProcessHeap(), 0, This);
360 return ref;
363 static HRESULT WINAPI marshal_GetUnmarshalClass(IMarshal *iface, REFIID iid, void *obj,
364 DWORD dwDestContext, void *pvDestContext,
365 DWORD mshlflags, CLSID *clsid)
367 marshal *This = impl_from_IMarshal(iface);
368 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
369 pvDestContext, mshlflags, clsid);
371 *clsid = This->unmarshal_class;
372 return S_OK;
375 static HRESULT WINAPI marshal_GetMarshalSizeMax(IMarshal *iface, REFIID iid, void *obj,
376 DWORD dwDestContext, void *pvDestContext,
377 DWORD mshlflags, DWORD *size)
379 marshal *This = impl_from_IMarshal(iface);
380 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
381 pvDestContext, mshlflags, size);
383 return CoGetMarshalSizeMax(size, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext,
384 mshlflags);
387 static HRESULT WINAPI marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID iid,
388 void *obj, DWORD dwDestContext, void *pvDestContext,
389 DWORD mshlflags)
391 marshal *This = impl_from_IMarshal(iface);
392 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This, stream, debugstr_guid(iid), obj, dwDestContext,
393 pvDestContext, mshlflags);
395 return CoMarshalInterface(stream, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext, mshlflags);
398 static HRESULT WINAPI marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
399 REFIID iid, void **obj)
401 marshal *This = impl_from_IMarshal(iface);
402 HRESULT hr;
403 IWineRowServer *server;
404 IUnknown *proxy;
406 TRACE("(%p)->(%p, %s, %p)\n", This, stream, debugstr_guid(iid), obj);
407 *obj = NULL;
409 hr = CoUnmarshalInterface(stream, &IID_IWineRowServer, (void**)&server);
410 if(SUCCEEDED(hr))
412 hr = create_proxy(server, &This->unmarshal_class, &proxy);
413 if(SUCCEEDED(hr))
415 hr = IUnknown_QueryInterface(proxy, iid, obj);
416 IUnknown_Release(proxy);
418 IWineRowServer_Release(server);
421 TRACE("returing %p\n", *obj);
422 return hr;
425 static HRESULT WINAPI marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
427 marshal *This = impl_from_IMarshal(iface);
428 TRACE("(%p)->(%p)\n", This, stream);
429 return CoReleaseMarshalData(stream);
432 static HRESULT WINAPI marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
434 marshal *This = impl_from_IMarshal(iface);
435 FIXME("(%p)->(%08x)\n", This, dwReserved);
437 return E_NOTIMPL;
440 static const IMarshalVtbl marshal_vtbl =
442 marshal_QueryInterface,
443 marshal_AddRef,
444 marshal_Release,
445 marshal_GetUnmarshalClass,
446 marshal_GetMarshalSizeMax,
447 marshal_MarshalInterface,
448 marshal_UnmarshalInterface,
449 marshal_ReleaseMarshalData,
450 marshal_DisconnectObject
453 static HRESULT create_marshal(IUnknown *outer, const CLSID *class, void **obj)
455 marshal *marshal;
457 TRACE("(%p, %p)\n", outer, obj);
458 *obj = NULL;
460 marshal = HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal));
461 if(!marshal) return E_OUTOFMEMORY;
463 marshal->unmarshal_class = *class;
464 marshal->outer = outer; /* don't ref outer unk */
465 marshal->marshal_vtbl = &marshal_vtbl;
466 marshal->ref = 1;
468 *obj = &marshal->marshal_vtbl;
469 TRACE("returing %p\n", *obj);
470 return S_OK;
473 HRESULT create_row_marshal(IUnknown *outer, void **obj)
475 TRACE("(%p, %p)\n", outer, obj);
476 return create_marshal(outer, &CLSID_wine_row_proxy, obj);
479 HRESULT create_rowset_marshal(IUnknown *outer, void **obj)
481 TRACE("(%p, %p)\n", outer, obj);
482 return create_marshal(outer, &CLSID_wine_rowset_proxy, obj);