msdaps: Add a stub rowset proxy object.
[wine/hramrach.git] / dlls / msdaps / row_server.c
blob97e56578be9ef9d61c09829c259c0c1d6bfe56b7
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 typedef struct
294 const IRowsetVtbl *rowset_vtbl;
296 LONG ref;
298 IWineRowServer *server;
299 } rowset_proxy;
301 static inline rowset_proxy *impl_from_IRowset(IRowset *iface)
303 return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowset_vtbl));
306 static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID iid, void **obj)
308 rowset_proxy *This = impl_from_IRowset(iface);
309 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
311 *obj = NULL;
313 if(IsEqualIID(iid, &IID_IUnknown) ||
314 IsEqualIID(iid, &IID_IRowset))
316 *obj = &This->rowset_vtbl;
318 else
320 FIXME("interface %s not implemented\n", debugstr_guid(iid));
321 return E_NOINTERFACE;
324 IRowset_AddRef(iface);
325 return S_OK;
328 static ULONG WINAPI rowset_AddRef(IRowset *iface)
330 rowset_proxy *This = impl_from_IRowset(iface);
331 TRACE("(%p)\n", This);
333 return InterlockedIncrement(&This->ref);
336 static ULONG WINAPI rowset_Release(IRowset *iface)
338 rowset_proxy *This = impl_from_IRowset(iface);
339 LONG ref;
341 TRACE("(%p)\n", This);
343 ref = InterlockedDecrement(&This->ref);
344 if(ref == 0)
346 if(This->server) IWineRowServer_Release(This->server);
347 HeapFree(GetProcessHeap(), 0, This);
350 return ref;
353 static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
354 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
356 rowset_proxy *This = impl_from_IRowset(iface);
358 FIXME("(%p)->(%d, %p, %p, %p): stub\n", This, cRows, rghRows, rgRefCounts, rgRowStatus);
360 return E_NOTIMPL;
363 static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
365 rowset_proxy *This = impl_from_IRowset(iface);
367 FIXME("(%p)->(%lx, %lx, %p): stub\n", This, hRow, hAccessor, pData);
369 return E_NOTIMPL;
372 static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
373 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
375 rowset_proxy *This = impl_from_IRowset(iface);
377 FIXME("(%p)->(%08lx, %d, %d, %p, %p): stub\n", This, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);
379 return E_NOTIMPL;
382 static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
383 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
385 rowset_proxy *This = impl_from_IRowset(iface);
387 FIXME("(%p)->(%d, %p, %p, %p, %p): stub\n", This, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);
389 return E_NOTIMPL;
392 static HRESULT WINAPI rowset_RestartPosition(IRowset* iface, HCHAPTER hReserved)
394 rowset_proxy *This = impl_from_IRowset(iface);
396 FIXME("(%p)->(%lx): stub\n", This, hReserved);
398 return E_NOTIMPL;
401 static const IRowsetVtbl rowset_vtbl =
403 rowset_QueryInterface,
404 rowset_AddRef,
405 rowset_Release,
406 rowset_AddRefRows,
407 rowset_GetData,
408 rowset_GetNextRows,
409 rowset_ReleaseRows,
410 rowset_RestartPosition
413 HRESULT create_rowset_proxy(IWineRowServer *server, IUnknown **obj)
415 rowset_proxy *proxy;
417 TRACE("(%p, %p)\n", server, obj);
418 *obj = NULL;
420 proxy = HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy));
421 if(!proxy) return E_OUTOFMEMORY;
423 proxy->rowset_vtbl = &rowset_vtbl;
424 proxy->ref = 1;
425 IWineRowServer_AddRef(server);
426 proxy->server = server;
428 *obj = (IUnknown *)&proxy->rowset_vtbl;
429 TRACE("returing %p\n", *obj);
430 return S_OK;
433 static HRESULT create_proxy(IWineRowServer *server, const CLSID *class, IUnknown **obj)
435 *obj = NULL;
437 if(IsEqualGUID(class, &CLSID_wine_row_proxy))
438 return create_row_proxy(server, obj);
439 else if(IsEqualGUID(class, &CLSID_wine_rowset_proxy))
440 return create_rowset_proxy(server, obj);
441 else
442 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
443 return E_NOTIMPL;
446 /* Marshal impl */
448 typedef struct
450 const IMarshalVtbl *marshal_vtbl;
452 LONG ref;
453 CLSID unmarshal_class;
454 IUnknown *outer;
455 } marshal;
457 static inline marshal *impl_from_IMarshal(IMarshal *iface)
459 return (marshal *)((char*)iface - FIELD_OFFSET(marshal, marshal_vtbl));
462 static HRESULT WINAPI marshal_QueryInterface(IMarshal *iface, REFIID iid, void **obj)
464 marshal *This = impl_from_IMarshal(iface);
465 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
467 if(IsEqualIID(iid, &IID_IUnknown) ||
468 IsEqualIID(iid, &IID_IMarshal))
470 *obj = iface;
472 else
474 FIXME("interface %s not implemented\n", debugstr_guid(iid));
475 *obj = NULL;
476 return E_NOINTERFACE;
479 IMarshal_AddRef(iface);
480 return S_OK;
483 static ULONG WINAPI marshal_AddRef(IMarshal *iface)
485 marshal *This = impl_from_IMarshal(iface);
486 TRACE("(%p)\n", This);
487 return InterlockedIncrement(&This->ref);
490 static ULONG WINAPI marshal_Release(IMarshal *iface)
492 marshal *This = impl_from_IMarshal(iface);
493 LONG ref;
495 TRACE("(%p)\n", This);
497 ref = InterlockedDecrement(&This->ref);
498 if(ref == 0)
500 HeapFree(GetProcessHeap(), 0, This);
503 return ref;
506 static HRESULT WINAPI marshal_GetUnmarshalClass(IMarshal *iface, REFIID iid, void *obj,
507 DWORD dwDestContext, void *pvDestContext,
508 DWORD mshlflags, CLSID *clsid)
510 marshal *This = impl_from_IMarshal(iface);
511 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
512 pvDestContext, mshlflags, clsid);
514 *clsid = This->unmarshal_class;
515 return S_OK;
518 static HRESULT WINAPI marshal_GetMarshalSizeMax(IMarshal *iface, REFIID iid, void *obj,
519 DWORD dwDestContext, void *pvDestContext,
520 DWORD mshlflags, DWORD *size)
522 marshal *This = impl_from_IMarshal(iface);
523 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
524 pvDestContext, mshlflags, size);
526 return CoGetMarshalSizeMax(size, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext,
527 mshlflags);
530 static HRESULT WINAPI marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID iid,
531 void *obj, DWORD dwDestContext, void *pvDestContext,
532 DWORD mshlflags)
534 marshal *This = impl_from_IMarshal(iface);
535 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This, stream, debugstr_guid(iid), obj, dwDestContext,
536 pvDestContext, mshlflags);
538 return CoMarshalInterface(stream, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext, mshlflags);
541 static HRESULT WINAPI marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
542 REFIID iid, void **obj)
544 marshal *This = impl_from_IMarshal(iface);
545 HRESULT hr;
546 IWineRowServer *server;
547 IUnknown *proxy;
549 TRACE("(%p)->(%p, %s, %p)\n", This, stream, debugstr_guid(iid), obj);
550 *obj = NULL;
552 hr = CoUnmarshalInterface(stream, &IID_IWineRowServer, (void**)&server);
553 if(SUCCEEDED(hr))
555 hr = create_proxy(server, &This->unmarshal_class, &proxy);
556 if(SUCCEEDED(hr))
558 hr = IUnknown_QueryInterface(proxy, iid, obj);
559 IUnknown_Release(proxy);
561 IWineRowServer_Release(server);
564 TRACE("returing %p\n", *obj);
565 return hr;
568 static HRESULT WINAPI marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
570 marshal *This = impl_from_IMarshal(iface);
571 TRACE("(%p)->(%p)\n", This, stream);
572 return CoReleaseMarshalData(stream);
575 static HRESULT WINAPI marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
577 marshal *This = impl_from_IMarshal(iface);
578 FIXME("(%p)->(%08x)\n", This, dwReserved);
580 return E_NOTIMPL;
583 static const IMarshalVtbl marshal_vtbl =
585 marshal_QueryInterface,
586 marshal_AddRef,
587 marshal_Release,
588 marshal_GetUnmarshalClass,
589 marshal_GetMarshalSizeMax,
590 marshal_MarshalInterface,
591 marshal_UnmarshalInterface,
592 marshal_ReleaseMarshalData,
593 marshal_DisconnectObject
596 static HRESULT create_marshal(IUnknown *outer, const CLSID *class, void **obj)
598 marshal *marshal;
600 TRACE("(%p, %p)\n", outer, obj);
601 *obj = NULL;
603 marshal = HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal));
604 if(!marshal) return E_OUTOFMEMORY;
606 marshal->unmarshal_class = *class;
607 marshal->outer = outer; /* don't ref outer unk */
608 marshal->marshal_vtbl = &marshal_vtbl;
609 marshal->ref = 1;
611 *obj = &marshal->marshal_vtbl;
612 TRACE("returing %p\n", *obj);
613 return S_OK;
616 HRESULT create_row_marshal(IUnknown *outer, void **obj)
618 TRACE("(%p, %p)\n", outer, obj);
619 return create_marshal(outer, &CLSID_wine_row_proxy, obj);
622 HRESULT create_rowset_marshal(IUnknown *outer, void **obj)
624 TRACE("(%p, %p)\n", outer, obj);
625 return create_marshal(outer, &CLSID_wine_rowset_proxy, obj);