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
);
292 static HRESULT
create_proxy(IWineRowServer
*server
, const CLSID
*class, IUnknown
**obj
)
296 if(IsEqualGUID(class, &CLSID_wine_row_proxy
))
297 return create_row_proxy(server
, obj
);
299 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
307 const IMarshalVtbl
*marshal_vtbl
;
310 CLSID unmarshal_class
;
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
))
331 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
333 return E_NOINTERFACE
;
336 IMarshal_AddRef(iface
);
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
);
352 TRACE("(%p)\n", This
);
354 ref
= InterlockedDecrement(&This
->ref
);
357 HeapFree(GetProcessHeap(), 0, This
);
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
;
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
,
387 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
388 void *obj
, DWORD dwDestContext
, void *pvDestContext
,
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
);
403 IWineRowServer
*server
;
406 TRACE("(%p)->(%p, %s, %p)\n", This
, stream
, debugstr_guid(iid
), obj
);
409 hr
= CoUnmarshalInterface(stream
, &IID_IWineRowServer
, (void**)&server
);
412 hr
= create_proxy(server
, &This
->unmarshal_class
, &proxy
);
415 hr
= IUnknown_QueryInterface(proxy
, iid
, obj
);
416 IUnknown_Release(proxy
);
418 IWineRowServer_Release(server
);
421 TRACE("returing %p\n", *obj
);
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
);
440 static const IMarshalVtbl marshal_vtbl
=
442 marshal_QueryInterface
,
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
)
457 TRACE("(%p, %p)\n", outer
, obj
);
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
;
468 *obj
= &marshal
->marshal_vtbl
;
469 TRACE("returing %p\n", *obj
);
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
);