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
);
42 static inline DBLENGTH
db_type_size(DBTYPE type
, DBLENGTH var_len
)
63 return sizeof(FILETIME
);
71 FIXME("Unhandled type %04x\n", type
);
78 const IWineRowServerVtbl
*vtbl
;
87 static inline server
*impl_from_IWineRowServer(IWineRowServer
*iface
)
89 return (server
*)((char*)iface
- FIELD_OFFSET(server
, vtbl
));
92 static HRESULT WINAPI
server_QueryInterface(IWineRowServer
*iface
, REFIID riid
, void **obj
)
94 server
*This
= impl_from_IWineRowServer(iface
);
95 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
99 if(IsEqualIID(riid
, &IID_IUnknown
) ||
100 IsEqualIID(riid
, &IID_IWineRowServer
))
106 if(!IsEqualIID(riid
, &IID_IMarshal
)) /* We use standard marshalling */
107 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
108 return E_NOINTERFACE
;
111 IWineRowServer_AddRef(iface
);
115 static ULONG WINAPI
server_AddRef(IWineRowServer
*iface
)
117 server
*This
= impl_from_IWineRowServer(iface
);
118 TRACE("(%p)\n", This
);
120 return InterlockedIncrement(&This
->ref
);
123 static ULONG WINAPI
server_Release(IWineRowServer
*iface
)
125 server
*This
= impl_from_IWineRowServer(iface
);
128 TRACE("(%p)\n", This
);
130 ref
= InterlockedDecrement(&This
->ref
);
133 IMarshal_Release(This
->marshal
);
134 if(This
->inner_unk
) IUnknown_Release(This
->inner_unk
);
135 HeapFree(GetProcessHeap(), 0, This
);
141 static HRESULT WINAPI
server_SetInnerUnk(IWineRowServer
*iface
, IUnknown
*inner
)
143 server
*This
= impl_from_IWineRowServer(iface
);
145 if(This
->inner_unk
) IUnknown_Release(This
->inner_unk
);
147 if(inner
) IUnknown_AddRef(inner
);
148 This
->inner_unk
= inner
;
152 static HRESULT WINAPI
server_GetMarshal(IWineRowServer
*iface
, IMarshal
**marshal
)
154 server
*This
= impl_from_IWineRowServer(iface
);
156 IMarshal_AddRef(This
->marshal
);
157 *marshal
= This
->marshal
;
161 static HRESULT WINAPI
server_GetColumns(IWineRowServer
* iface
, DBORDINAL num_cols
,
162 wine_getcolumns_in
*in_data
, wine_getcolumns_out
*out_data
)
164 server
*This
= impl_from_IWineRowServer(iface
);
167 DBCOLUMNACCESS
*cols
;
170 TRACE("(%p)->(%d, %p, %p)\n", This
, num_cols
, in_data
, out_data
);
172 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRow
, (void**)&row
);
173 if(FAILED(hr
)) return hr
;
175 cols
= CoTaskMemAlloc(num_cols
* sizeof(cols
[0]));
177 for(i
= 0; i
< num_cols
; i
++)
179 TRACE("%d:\tmax_len %d type %04x\n", i
, in_data
[i
].max_len
, in_data
[i
].type
);
180 cols
[i
].pData
= CoTaskMemAlloc(db_type_size(in_data
[i
].type
, in_data
[i
].max_len
));
181 cols
[i
].columnid
= in_data
[i
].columnid
;
182 cols
[i
].cbMaxLen
= in_data
[i
].max_len
;
183 cols
[i
].wType
= in_data
[i
].type
;
184 cols
[i
].bPrecision
= in_data
[i
].precision
;
185 cols
[i
].bScale
= in_data
[i
].scale
;
188 hr
= IRow_GetColumns(row
, num_cols
, cols
);
191 for(i
= 0; i
< num_cols
; i
++)
193 VariantInit(&out_data
[i
].v
);
194 if(cols
[i
].dwStatus
== DBSTATUS_S_OK
)
196 V_VT(&out_data
[i
].v
) = in_data
[i
].type
;
197 memcpy(&V_I1(&out_data
[i
].v
), cols
[i
].pData
, cols
[i
].cbDataLen
);
199 CoTaskMemFree(cols
[i
].pData
);
200 out_data
[i
].data_len
= cols
[i
].cbDataLen
;
201 out_data
[i
].status
= cols
[i
].dwStatus
;
209 static HRESULT WINAPI
server_GetSourceRowset(IWineRowServer
* iface
, REFIID riid
, IUnknown
**ppRowset
,
212 server
*This
= impl_from_IWineRowServer(iface
);
213 FIXME("(%p): stub\n", This
);
217 static HRESULT WINAPI
server_Open(IWineRowServer
* iface
, IUnknown
*pUnkOuter
, DBID
*pColumnID
,
218 REFGUID rguidColumnType
, DWORD dwBindFlags
, REFIID riid
,
221 server
*This
= impl_from_IWineRowServer(iface
);
223 FIXME("(%p)->(%p, %p, %s, %08x, %s, %p): stub\n", This
, pUnkOuter
, pColumnID
, debugstr_guid(rguidColumnType
),
224 dwBindFlags
, debugstr_guid(riid
), ppUnk
);
228 static HRESULT WINAPI
server_SetColumns(IWineRowServer
* iface
, DBORDINAL num_cols
,
229 wine_setcolumns_in
*in_data
, DBSTATUS
*status
)
231 server
*This
= impl_from_IWineRowServer(iface
);
232 FIXME("(%p)->(%d, %p, %p): stub\n", This
, num_cols
, in_data
, status
);
236 static HRESULT WINAPI
server_AddRefRows(IWineRowServer
* iface
, DBCOUNTITEM cRows
,
237 const HROW rghRows
[], DBREFCOUNT rgRefCounts
[],
238 DBROWSTATUS rgRowStatus
[])
240 server
*This
= impl_from_IWineRowServer(iface
);
244 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
246 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
247 if(FAILED(hr
)) return hr
;
249 hr
= IRowset_AddRefRows(rowset
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
251 IRowset_Release(rowset
);
252 TRACE("returning %08x\n", hr
);
256 static HRESULT WINAPI
server_GetData(IWineRowServer
* iface
, HROW hRow
,
257 HACCESSOR hAccessor
, BYTE
*pData
, DWORD size
)
259 server
*This
= impl_from_IWineRowServer(iface
);
260 FIXME("(%p)->(%08lx, %08lx, %p, %d): stub\n", This
, hRow
, hAccessor
, pData
, size
);
264 static HRESULT WINAPI
server_GetNextRows(IWineRowServer
* iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
265 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
267 server
*This
= impl_from_IWineRowServer(iface
);
271 TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
273 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
274 if(FAILED(hr
)) return hr
;
278 hr
= IRowset_GetNextRows(rowset
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
279 IRowset_Release(rowset
);
280 TRACE("returning %08x, got %d rows\n", hr
, *pcRowObtained
);
284 static HRESULT WINAPI
server_ReleaseRows(IWineRowServer
* iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
285 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
287 server
*This
= impl_from_IWineRowServer(iface
);
291 TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
293 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
294 if(FAILED(hr
)) return hr
;
296 hr
= IRowset_ReleaseRows(rowset
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
297 IRowset_Release(rowset
);
299 TRACE("returning %08x\n", hr
);
303 static HRESULT WINAPI
server_RestartPosition(IWineRowServer
* iface
, HCHAPTER hReserved
)
305 server
*This
= impl_from_IWineRowServer(iface
);
306 FIXME("(%p)->(%08lx): stub\n", This
, hReserved
);
310 static HRESULT WINAPI
server_Compare(IWineRowServer
*iface
, HCHAPTER hReserved
, DBBKMARK cbBookmark1
,
311 const BYTE
*pBookmark1
, DBBKMARK cbBookmark2
, const BYTE
*pBookmark2
,
312 DBCOMPARE
*pComparison
)
314 server
*This
= impl_from_IWineRowServer(iface
);
315 FIXME("(%p): stub\n", This
);
319 static HRESULT WINAPI
server_GetRowsAt(IWineRowServer
*iface
, HWATCHREGION hReserved1
, HCHAPTER hReserved2
,
320 DBBKMARK cbBookmark
, const BYTE
*pBookmark
, DBROWOFFSET lRowsOffset
,
321 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowsObtained
, HROW
**prghRows
)
323 server
*This
= impl_from_IWineRowServer(iface
);
325 FIXME("(%p)->(%08lx, %08lx, %d, %p, %d, %d, %p, %p): stub\n", This
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
,
326 lRowsOffset
, cRows
, pcRowsObtained
, prghRows
);
331 static HRESULT WINAPI
server_GetRowsByBookmark(IWineRowServer
*iface
, HCHAPTER hReserved
, DBCOUNTITEM cRows
,
332 const DBBKMARK rgcbBookmarks
[], const BYTE
* rgpBookmarks
[],
333 HROW rghRows
[], DBROWSTATUS rgRowStatus
[])
335 server
*This
= impl_from_IWineRowServer(iface
);
336 FIXME("(%p): stub\n", This
);
340 static HRESULT WINAPI
server_Hash(IWineRowServer
*iface
, HCHAPTER hReserved
, DBBKMARK cBookmarks
,
341 const DBBKMARK rgcbBookmarks
[], const BYTE
* rgpBookmarks
[],
342 DBHASHVALUE rgHashedValues
[], DBROWSTATUS rgBookmarkStatus
[])
344 server
*This
= impl_from_IWineRowServer(iface
);
345 FIXME("(%p): stub\n", This
);
349 static const IWineRowServerVtbl server_vtbl
=
351 server_QueryInterface
,
357 server_GetSourceRowset
,
364 server_RestartPosition
,
367 server_GetRowsByBookmark
,
371 static HRESULT
create_server(IUnknown
*outer
, const CLSID
*class, void **obj
)
374 TRACE("(%p, %s, %p)\n", outer
, debugstr_guid(class), obj
);
378 server
= HeapAlloc(GetProcessHeap(), 0, sizeof(*server
));
379 if(!server
) return E_OUTOFMEMORY
;
381 server
->vtbl
= &server_vtbl
;
383 server
->class = *class;
384 server
->inner_unk
= NULL
;
385 if(IsEqualGUID(class, &CLSID_wine_row_server
))
386 create_row_marshal((IUnknown
*)server
, (void**)&server
->marshal
);
387 else if(IsEqualGUID(class, &CLSID_wine_rowset_server
))
388 create_rowset_marshal((IUnknown
*)server
, (void**)&server
->marshal
);
390 ERR("create_server called with class %s\n", debugstr_guid(class));
396 HRESULT
create_row_server(IUnknown
*outer
, void **obj
)
398 return create_server(outer
, &CLSID_wine_row_server
, obj
);
401 HRESULT
create_rowset_server(IUnknown
*outer
, void **obj
)
403 return create_server(outer
, &CLSID_wine_rowset_server
, obj
);
408 const IRowVtbl
*row_vtbl
;
409 const IRowChangeVtbl
*row_change_vtbl
;
413 IWineRowServer
*server
;
416 static inline row_proxy
*impl_from_IRow(IRow
*iface
)
418 return (row_proxy
*)((char*)iface
- FIELD_OFFSET(row_proxy
, row_vtbl
));
421 static inline row_proxy
*impl_from_IRowChange(IRowChange
*iface
)
423 return (row_proxy
*)((char*)iface
- FIELD_OFFSET(row_proxy
, row_change_vtbl
));
426 static HRESULT WINAPI
row_QueryInterface(IRow
*iface
, REFIID iid
, void **obj
)
428 row_proxy
*This
= impl_from_IRow(iface
);
429 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
431 if(IsEqualIID(iid
, &IID_IUnknown
) ||
432 IsEqualIID(iid
, &IID_IRow
))
434 *obj
= &This
->row_vtbl
;
436 else if(IsEqualIID(iid
, &IID_IRowChange
))
438 *obj
= &This
->row_change_vtbl
;
442 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
443 return E_NOINTERFACE
;
450 static ULONG WINAPI
row_AddRef(IRow
*iface
)
452 row_proxy
*This
= impl_from_IRow(iface
);
453 TRACE("(%p)\n", This
);
455 return InterlockedIncrement(&This
->ref
);
458 static ULONG WINAPI
row_Release(IRow
*iface
)
460 row_proxy
*This
= impl_from_IRow(iface
);
463 TRACE("(%p)\n", This
);
465 ref
= InterlockedDecrement(&This
->ref
);
468 if(This
->server
) IWineRowServer_Release(This
->server
);
469 HeapFree(GetProcessHeap(), 0, This
);
475 static HRESULT WINAPI
row_GetColumns(IRow
* iface
, DBORDINAL cColumns
, DBCOLUMNACCESS rgColumns
[])
477 row_proxy
*This
= impl_from_IRow(iface
);
479 wine_getcolumns_in
*in_data
;
480 wine_getcolumns_out
*out_data
;
483 TRACE("(%p)->(%d, %p)\n", This
, cColumns
, rgColumns
);
485 in_data
= CoTaskMemAlloc(cColumns
* sizeof(in_data
[0]));
486 out_data
= CoTaskMemAlloc(cColumns
* sizeof(out_data
[0]));
488 for(i
= 0; i
< cColumns
; i
++)
490 TRACE("%d:\tdata %p data_len %d status %08x max_len %d type %04x\n", i
, rgColumns
[i
].pData
,
491 rgColumns
[i
].cbDataLen
, rgColumns
[i
].dwStatus
, rgColumns
[i
].cbMaxLen
, rgColumns
[i
].wType
);
492 in_data
[i
].columnid
= rgColumns
[i
].columnid
;
493 in_data
[i
].max_len
= rgColumns
[i
].cbMaxLen
;
494 in_data
[i
].type
= rgColumns
[i
].wType
;
495 in_data
[i
].precision
= rgColumns
[i
].bPrecision
;
496 in_data
[i
].scale
= rgColumns
[i
].bScale
;
499 hr
= IWineRowServer_GetColumns(This
->server
, cColumns
, in_data
, out_data
);
501 for(i
= 0; i
< cColumns
; i
++)
503 rgColumns
[i
].cbDataLen
= out_data
[i
].data_len
;
504 rgColumns
[i
].dwStatus
= out_data
[i
].status
;
505 if(rgColumns
[i
].dwStatus
== DBSTATUS_S_OK
)
506 memcpy(rgColumns
[i
].pData
, &V_I1(&out_data
[i
].v
), out_data
[i
].data_len
);
509 CoTaskMemFree(out_data
);
510 CoTaskMemFree(in_data
);
514 static HRESULT WINAPI
row_GetSourceRowset(IRow
* iface
, REFIID riid
, IUnknown
**ppRowset
,
517 row_proxy
*This
= impl_from_IRow(iface
);
519 FIXME("(%p)->(%s, %p, %p): stub\n", This
, debugstr_guid(riid
), ppRowset
, phRow
);
524 static HRESULT WINAPI
row_Open(IRow
* iface
, IUnknown
*pUnkOuter
,
525 DBID
*pColumnID
, REFGUID rguidColumnType
,
526 DWORD dwBindFlags
, REFIID riid
, IUnknown
**ppUnk
)
528 row_proxy
*This
= impl_from_IRow(iface
);
530 FIXME("(%p)->(%p, %p, %s, %08x, %s, %p): stub\n", This
, pUnkOuter
, pColumnID
, debugstr_guid(rguidColumnType
),
531 dwBindFlags
, debugstr_guid(riid
), ppUnk
);
536 static const IRowVtbl row_vtbl
=
546 static HRESULT WINAPI
row_change_QueryInterface(IRowChange
*iface
, REFIID iid
, void **obj
)
548 row_proxy
*This
= impl_from_IRowChange(iface
);
549 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
552 static ULONG WINAPI
row_change_AddRef(IRowChange
*iface
)
554 row_proxy
*This
= impl_from_IRowChange(iface
);
555 return IUnknown_AddRef((IUnknown
*)This
);
558 static ULONG WINAPI
row_change_Release(IRowChange
*iface
)
560 row_proxy
*This
= impl_from_IRowChange(iface
);
561 return IUnknown_Release((IUnknown
*)This
);
564 static HRESULT WINAPI
row_change_SetColumns(IRowChange
*iface
, DBORDINAL cColumns
,
565 DBCOLUMNACCESS rgColumns
[])
567 row_proxy
*This
= impl_from_IRowChange(iface
);
568 FIXME("(%p)->(%d, %p)\n", This
, cColumns
, rgColumns
);
572 static const IRowChangeVtbl row_change_vtbl
=
574 row_change_QueryInterface
,
577 row_change_SetColumns
580 static HRESULT
create_row_proxy(IWineRowServer
*server
, IUnknown
**obj
)
584 TRACE("(%p, %p)\n", server
, obj
);
587 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
588 if(!proxy
) return E_OUTOFMEMORY
;
590 proxy
->row_vtbl
= &row_vtbl
;
591 proxy
->row_change_vtbl
= &row_change_vtbl
;
593 IWineRowServer_AddRef(server
);
594 proxy
->server
= server
;
596 *obj
= (IUnknown
*)&proxy
->row_vtbl
;
597 TRACE("returing %p\n", *obj
);
603 const IRowsetVtbl
*rowset_vtbl
;
607 IWineRowServer
*server
;
610 static inline rowset_proxy
*impl_from_IRowset(IRowset
*iface
)
612 return (rowset_proxy
*)((char*)iface
- FIELD_OFFSET(rowset_proxy
, rowset_vtbl
));
615 static HRESULT WINAPI
rowset_QueryInterface(IRowset
*iface
, REFIID iid
, void **obj
)
617 rowset_proxy
*This
= impl_from_IRowset(iface
);
618 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
622 if(IsEqualIID(iid
, &IID_IUnknown
) ||
623 IsEqualIID(iid
, &IID_IRowset
))
625 *obj
= &This
->rowset_vtbl
;
629 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
630 return E_NOINTERFACE
;
633 IRowset_AddRef(iface
);
637 static ULONG WINAPI
rowset_AddRef(IRowset
*iface
)
639 rowset_proxy
*This
= impl_from_IRowset(iface
);
640 TRACE("(%p)\n", This
);
642 return InterlockedIncrement(&This
->ref
);
645 static ULONG WINAPI
rowset_Release(IRowset
*iface
)
647 rowset_proxy
*This
= impl_from_IRowset(iface
);
650 TRACE("(%p)\n", This
);
652 ref
= InterlockedDecrement(&This
->ref
);
655 if(This
->server
) IWineRowServer_Release(This
->server
);
656 HeapFree(GetProcessHeap(), 0, This
);
662 static HRESULT WINAPI
rowset_AddRefRows(IRowset
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
663 DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
665 rowset_proxy
*This
= impl_from_IRowset(iface
);
667 DBREFCOUNT
*refs
= rgRefCounts
;
668 DBSTATUS
*stats
= rgRowStatus
;
670 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
672 if(!refs
) refs
= CoTaskMemAlloc(cRows
* sizeof(refs
[0]));
673 if(!stats
) stats
= CoTaskMemAlloc(cRows
* sizeof(stats
[0]));
675 hr
= IWineRowServer_AddRefRows(This
->server
, cRows
, rghRows
, refs
, stats
);
677 if(refs
!= rgRefCounts
) CoTaskMemFree(refs
);
678 if(stats
!= rgRowStatus
) CoTaskMemFree(stats
);
683 static HRESULT WINAPI
rowset_GetData(IRowset
*iface
, HROW hRow
, HACCESSOR hAccessor
, void *pData
)
685 rowset_proxy
*This
= impl_from_IRowset(iface
);
687 FIXME("(%p)->(%lx, %lx, %p): stub\n", This
, hRow
, hAccessor
, pData
);
692 static HRESULT WINAPI
rowset_GetNextRows(IRowset
*iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
693 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
695 rowset_proxy
*This
= impl_from_IRowset(iface
);
699 TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
701 hr
= IWineRowServer_GetNextRows(This
->server
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, &rows
);
704 memcpy(*prghRows
, rows
, *pcRowObtained
* sizeof(rows
[0]));
713 static HRESULT WINAPI
rowset_ReleaseRows(IRowset
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
714 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
716 rowset_proxy
*This
= impl_from_IRowset(iface
);
718 DBROWOPTIONS
*options
= rgRowOptions
;
719 DBREFCOUNT
*refs
= rgRefCounts
;
720 DBROWSTATUS
*status
= rgRowStatus
;
722 TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
726 options
= CoTaskMemAlloc(cRows
* sizeof(options
[0]));
727 memset(options
, 0, cRows
* sizeof(options
[0]));
729 if(!refs
) refs
= CoTaskMemAlloc(cRows
* sizeof(refs
[0]));
730 if(!status
) status
= CoTaskMemAlloc(cRows
* sizeof(status
[0]));
732 hr
= IWineRowServer_ReleaseRows(This
->server
, cRows
, rghRows
, options
, refs
, status
);
734 if(status
!= rgRowStatus
) CoTaskMemFree(status
);
735 if(refs
!= rgRefCounts
) CoTaskMemFree(refs
);
736 if(options
!= rgRowOptions
) CoTaskMemFree(options
);
741 static HRESULT WINAPI
rowset_RestartPosition(IRowset
* iface
, HCHAPTER hReserved
)
743 rowset_proxy
*This
= impl_from_IRowset(iface
);
745 FIXME("(%p)->(%lx): stub\n", This
, hReserved
);
750 static const IRowsetVtbl rowset_vtbl
=
752 rowset_QueryInterface
,
759 rowset_RestartPosition
762 HRESULT
create_rowset_proxy(IWineRowServer
*server
, IUnknown
**obj
)
766 TRACE("(%p, %p)\n", server
, obj
);
769 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
770 if(!proxy
) return E_OUTOFMEMORY
;
772 proxy
->rowset_vtbl
= &rowset_vtbl
;
774 IWineRowServer_AddRef(server
);
775 proxy
->server
= server
;
777 *obj
= (IUnknown
*)&proxy
->rowset_vtbl
;
778 TRACE("returing %p\n", *obj
);
782 static HRESULT
create_proxy(IWineRowServer
*server
, const CLSID
*class, IUnknown
**obj
)
786 if(IsEqualGUID(class, &CLSID_wine_row_proxy
))
787 return create_row_proxy(server
, obj
);
788 else if(IsEqualGUID(class, &CLSID_wine_rowset_proxy
))
789 return create_rowset_proxy(server
, obj
);
791 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
799 const IMarshalVtbl
*marshal_vtbl
;
802 CLSID unmarshal_class
;
806 static inline marshal
*impl_from_IMarshal(IMarshal
*iface
)
808 return (marshal
*)((char*)iface
- FIELD_OFFSET(marshal
, marshal_vtbl
));
811 static HRESULT WINAPI
marshal_QueryInterface(IMarshal
*iface
, REFIID iid
, void **obj
)
813 marshal
*This
= impl_from_IMarshal(iface
);
814 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
816 if(IsEqualIID(iid
, &IID_IUnknown
) ||
817 IsEqualIID(iid
, &IID_IMarshal
))
823 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
825 return E_NOINTERFACE
;
828 IMarshal_AddRef(iface
);
832 static ULONG WINAPI
marshal_AddRef(IMarshal
*iface
)
834 marshal
*This
= impl_from_IMarshal(iface
);
835 TRACE("(%p)\n", This
);
836 return InterlockedIncrement(&This
->ref
);
839 static ULONG WINAPI
marshal_Release(IMarshal
*iface
)
841 marshal
*This
= impl_from_IMarshal(iface
);
844 TRACE("(%p)\n", This
);
846 ref
= InterlockedDecrement(&This
->ref
);
849 HeapFree(GetProcessHeap(), 0, This
);
855 static HRESULT WINAPI
marshal_GetUnmarshalClass(IMarshal
*iface
, REFIID iid
, void *obj
,
856 DWORD dwDestContext
, void *pvDestContext
,
857 DWORD mshlflags
, CLSID
*clsid
)
859 marshal
*This
= impl_from_IMarshal(iface
);
860 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This
, debugstr_guid(iid
), obj
, dwDestContext
,
861 pvDestContext
, mshlflags
, clsid
);
863 *clsid
= This
->unmarshal_class
;
867 static HRESULT WINAPI
marshal_GetMarshalSizeMax(IMarshal
*iface
, REFIID iid
, void *obj
,
868 DWORD dwDestContext
, void *pvDestContext
,
869 DWORD mshlflags
, DWORD
*size
)
871 marshal
*This
= impl_from_IMarshal(iface
);
872 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This
, debugstr_guid(iid
), obj
, dwDestContext
,
873 pvDestContext
, mshlflags
, size
);
875 return CoGetMarshalSizeMax(size
, &IID_IWineRowServer
, This
->outer
, dwDestContext
, pvDestContext
,
879 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
880 void *obj
, DWORD dwDestContext
, void *pvDestContext
,
883 marshal
*This
= impl_from_IMarshal(iface
);
884 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This
, stream
, debugstr_guid(iid
), obj
, dwDestContext
,
885 pvDestContext
, mshlflags
);
887 return CoMarshalInterface(stream
, &IID_IWineRowServer
, This
->outer
, dwDestContext
, pvDestContext
, mshlflags
);
890 static HRESULT WINAPI
marshal_UnmarshalInterface(IMarshal
*iface
, IStream
*stream
,
891 REFIID iid
, void **obj
)
893 marshal
*This
= impl_from_IMarshal(iface
);
895 IWineRowServer
*server
;
898 TRACE("(%p)->(%p, %s, %p)\n", This
, stream
, debugstr_guid(iid
), obj
);
901 hr
= CoUnmarshalInterface(stream
, &IID_IWineRowServer
, (void**)&server
);
904 hr
= create_proxy(server
, &This
->unmarshal_class
, &proxy
);
907 hr
= IUnknown_QueryInterface(proxy
, iid
, obj
);
908 IUnknown_Release(proxy
);
910 IWineRowServer_Release(server
);
913 TRACE("returing %p\n", *obj
);
917 static HRESULT WINAPI
marshal_ReleaseMarshalData(IMarshal
*iface
, IStream
*stream
)
919 marshal
*This
= impl_from_IMarshal(iface
);
920 TRACE("(%p)->(%p)\n", This
, stream
);
921 return CoReleaseMarshalData(stream
);
924 static HRESULT WINAPI
marshal_DisconnectObject(IMarshal
*iface
, DWORD dwReserved
)
926 marshal
*This
= impl_from_IMarshal(iface
);
927 FIXME("(%p)->(%08x)\n", This
, dwReserved
);
932 static const IMarshalVtbl marshal_vtbl
=
934 marshal_QueryInterface
,
937 marshal_GetUnmarshalClass
,
938 marshal_GetMarshalSizeMax
,
939 marshal_MarshalInterface
,
940 marshal_UnmarshalInterface
,
941 marshal_ReleaseMarshalData
,
942 marshal_DisconnectObject
945 static HRESULT
create_marshal(IUnknown
*outer
, const CLSID
*class, void **obj
)
949 TRACE("(%p, %p)\n", outer
, obj
);
952 marshal
= HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal
));
953 if(!marshal
) return E_OUTOFMEMORY
;
955 marshal
->unmarshal_class
= *class;
956 marshal
->outer
= outer
; /* don't ref outer unk */
957 marshal
->marshal_vtbl
= &marshal_vtbl
;
960 *obj
= &marshal
->marshal_vtbl
;
961 TRACE("returing %p\n", *obj
);
965 HRESULT
create_row_marshal(IUnknown
*outer
, void **obj
)
967 TRACE("(%p, %p)\n", outer
, obj
);
968 return create_marshal(outer
, &CLSID_wine_row_proxy
, obj
);
971 HRESULT
create_rowset_marshal(IUnknown
*outer
, void **obj
)
973 TRACE("(%p, %p)\n", outer
, obj
);
974 return create_marshal(outer
, &CLSID_wine_rowset_proxy
, obj
);