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
);