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
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
36 #include "row_server.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(oledb
);
45 const IWineRowServerVtbl
*vtbl
;
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
);
66 if(IsEqualIID(riid
, &IID_IUnknown
) ||
67 IsEqualIID(riid
, &IID_IWineRowServer
))
73 if(!IsEqualIID(riid
, &IID_IMarshal
)) /* We use standard marshalling */
74 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
78 IWineRowServer_AddRef(iface
);
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
);
95 TRACE("(%p)\n", This
);
97 ref
= InterlockedDecrement(&This
->ref
);
100 IMarshal_Release(This
->marshal
);
101 if(This
->inner_unk
) IUnknown_Release(This
->inner_unk
);
102 HeapFree(GetProcessHeap(), 0, This
);
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
;
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
;
128 static const IWineRowServerVtbl server_vtbl
=
130 server_QueryInterface
,
137 static HRESULT
create_server(IUnknown
*outer
, const CLSID
*class, void **obj
)
140 TRACE("(%p, %s, %p)\n", outer
, debugstr_guid(class), obj
);
144 server
= HeapAlloc(GetProcessHeap(), 0, sizeof(*server
));
145 if(!server
) return E_OUTOFMEMORY
;
147 server
->vtbl
= &server_vtbl
;
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
);
156 ERR("create_server called with class %s\n", debugstr_guid(class));
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
);
174 const IRowVtbl
*row_vtbl
;
178 IWineRowServer
*server
;
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
;
198 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
199 return E_NOINTERFACE
;
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
);
219 TRACE("(%p)\n", This
);
221 ref
= InterlockedDecrement(&This
->ref
);
224 if(This
->server
) IWineRowServer_Release(This
->server
);
225 HeapFree(GetProcessHeap(), 0, This
);
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
);
240 static HRESULT WINAPI
row_GetSourceRowset(IRow
* iface
, REFIID riid
, IUnknown
**ppRowset
,
243 row_proxy
*This
= impl_from_IRow(iface
);
245 FIXME("(%p)->(%s, %p, %p): stub\n", This
, debugstr_guid(riid
), ppRowset
, phRow
);
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
);
262 static const IRowVtbl row_vtbl
=
272 static HRESULT
create_row_proxy(IWineRowServer
*server
, IUnknown
**obj
)
276 TRACE("(%p, %p)\n", server
, obj
);
279 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
280 if(!proxy
) return E_OUTOFMEMORY
;
282 proxy
->row_vtbl
= &row_vtbl
;
284 IWineRowServer_AddRef(server
);
285 proxy
->server
= server
;
287 *obj
= (IUnknown
*)&proxy
->row_vtbl
;
288 TRACE("returing %p\n", *obj
);
294 const IRowsetVtbl
*rowset_vtbl
;
298 IWineRowServer
*server
;
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
);
313 if(IsEqualIID(iid
, &IID_IUnknown
) ||
314 IsEqualIID(iid
, &IID_IRowset
))
316 *obj
= &This
->rowset_vtbl
;
320 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
321 return E_NOINTERFACE
;
324 IRowset_AddRef(iface
);
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
);
341 TRACE("(%p)\n", This
);
343 ref
= InterlockedDecrement(&This
->ref
);
346 if(This
->server
) IWineRowServer_Release(This
->server
);
347 HeapFree(GetProcessHeap(), 0, This
);
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
);
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
);
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
);
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
);
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
);
401 static const IRowsetVtbl rowset_vtbl
=
403 rowset_QueryInterface
,
410 rowset_RestartPosition
413 HRESULT
create_rowset_proxy(IWineRowServer
*server
, IUnknown
**obj
)
417 TRACE("(%p, %p)\n", server
, obj
);
420 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
421 if(!proxy
) return E_OUTOFMEMORY
;
423 proxy
->rowset_vtbl
= &rowset_vtbl
;
425 IWineRowServer_AddRef(server
);
426 proxy
->server
= server
;
428 *obj
= (IUnknown
*)&proxy
->rowset_vtbl
;
429 TRACE("returing %p\n", *obj
);
433 static HRESULT
create_proxy(IWineRowServer
*server
, const CLSID
*class, IUnknown
**obj
)
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
);
442 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
450 const IMarshalVtbl
*marshal_vtbl
;
453 CLSID unmarshal_class
;
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
))
474 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
476 return E_NOINTERFACE
;
479 IMarshal_AddRef(iface
);
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
);
495 TRACE("(%p)\n", This
);
497 ref
= InterlockedDecrement(&This
->ref
);
500 HeapFree(GetProcessHeap(), 0, This
);
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
;
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
,
530 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
531 void *obj
, DWORD dwDestContext
, void *pvDestContext
,
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
);
546 IWineRowServer
*server
;
549 TRACE("(%p)->(%p, %s, %p)\n", This
, stream
, debugstr_guid(iid
), obj
);
552 hr
= CoUnmarshalInterface(stream
, &IID_IWineRowServer
, (void**)&server
);
555 hr
= create_proxy(server
, &This
->unmarshal_class
, &proxy
);
558 hr
= IUnknown_QueryInterface(proxy
, iid
, obj
);
559 IUnknown_Release(proxy
);
561 IWineRowServer_Release(server
);
564 TRACE("returing %p\n", *obj
);
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
);
583 static const IMarshalVtbl marshal_vtbl
=
585 marshal_QueryInterface
,
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
)
600 TRACE("(%p, %p)\n", outer
, obj
);
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
;
611 *obj
= &marshal
->marshal_vtbl
;
612 TRACE("returing %p\n", *obj
);
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
);