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);
172 HRESULT create_proxy(IWineRowServer *server, const CLSID *class, IUnknown **obj)
183 const IMarshalVtbl *marshal_vtbl;
186 CLSID unmarshal_class;
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))
207 FIXME("interface %s not implemented\n", debugstr_guid(iid));
209 return E_NOINTERFACE;
212 IMarshal_AddRef(iface);
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);
228 TRACE("(%p)\n", This);
230 ref = InterlockedDecrement(&This->ref);
233 HeapFree(GetProcessHeap(), 0, This);
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;
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,
263 static HRESULT WINAPI marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID iid,
264 void *obj, DWORD dwDestContext, void *pvDestContext,
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);
279 IWineRowServer *server;
282 TRACE("(%p)->(%p, %s, %p)\n", This, stream, debugstr_guid(iid), obj);
285 hr = CoUnmarshalInterface(stream, &IID_IWineRowServer, (void**)&server);
288 hr = create_proxy(server, &This->unmarshal_class, &proxy);
291 hr = IUnknown_QueryInterface(proxy, iid, obj);
292 IUnknown_Release(proxy);
294 IWineRowServer_Release(server);
297 TRACE("returing %p\n", *obj);
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);
316 static const IMarshalVtbl marshal_vtbl =
318 marshal_QueryInterface,
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)
333 TRACE("(%p, %p)\n", outer, obj);
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;
344 *obj = &marshal->marshal_vtbl;
345 TRACE("returing %p\n", *obj);
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);