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
34 #include "row_server.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(oledb
);
40 static inline DBLENGTH
db_type_size(DBTYPE type
, DBLENGTH var_len
)
61 return sizeof(FILETIME
);
69 FIXME("Unhandled type %04x\n", type
);
76 IWineRowServer IWineRowServer_iface
;
85 static inline server
*impl_from_IWineRowServer(IWineRowServer
*iface
)
87 return CONTAINING_RECORD(iface
, server
, IWineRowServer_iface
);
90 static HRESULT WINAPI
server_QueryInterface(IWineRowServer
*iface
, REFIID riid
, void **obj
)
92 server
*This
= impl_from_IWineRowServer(iface
);
93 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
97 if(IsEqualIID(riid
, &IID_IUnknown
) ||
98 IsEqualIID(riid
, &IID_IWineRowServer
))
104 if(!IsEqualIID(riid
, &IID_IMarshal
)) /* We use standard marshalling */
105 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
106 return E_NOINTERFACE
;
109 IWineRowServer_AddRef(iface
);
113 static ULONG WINAPI
server_AddRef(IWineRowServer
*iface
)
115 server
*This
= impl_from_IWineRowServer(iface
);
116 TRACE("(%p)\n", This
);
118 return InterlockedIncrement(&This
->ref
);
121 static ULONG WINAPI
server_Release(IWineRowServer
*iface
)
123 server
*This
= impl_from_IWineRowServer(iface
);
126 TRACE("(%p)\n", This
);
128 ref
= InterlockedDecrement(&This
->ref
);
131 IMarshal_Release(This
->marshal
);
132 if(This
->inner_unk
) IUnknown_Release(This
->inner_unk
);
133 HeapFree(GetProcessHeap(), 0, This
);
139 static HRESULT WINAPI
server_SetInnerUnk(IWineRowServer
*iface
, IUnknown
*inner
)
141 server
*This
= impl_from_IWineRowServer(iface
);
143 if(This
->inner_unk
) IUnknown_Release(This
->inner_unk
);
145 if(inner
) IUnknown_AddRef(inner
);
146 This
->inner_unk
= inner
;
150 static HRESULT WINAPI
server_GetMarshal(IWineRowServer
*iface
, IMarshal
**marshal
)
152 server
*This
= impl_from_IWineRowServer(iface
);
154 IMarshal_AddRef(This
->marshal
);
155 *marshal
= This
->marshal
;
159 static HRESULT WINAPI
server_GetColumns(IWineRowServer
* iface
, DBORDINAL num_cols
,
160 wine_getcolumns_in
*in_data
, wine_getcolumns_out
*out_data
)
162 server
*This
= impl_from_IWineRowServer(iface
);
165 DBCOLUMNACCESS
*cols
;
168 TRACE("(%p)->(%ld, %p, %p)\n", This
, num_cols
, in_data
, out_data
);
170 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRow
, (void**)&row
);
171 if(FAILED(hr
)) return hr
;
173 cols
= CoTaskMemAlloc(num_cols
* sizeof(cols
[0]));
175 for(i
= 0; i
< num_cols
; i
++)
177 TRACE("%ld:\tmax_len %ld type %04x\n", i
, in_data
[i
].max_len
, in_data
[i
].type
);
178 cols
[i
].pData
= CoTaskMemAlloc(db_type_size(in_data
[i
].type
, in_data
[i
].max_len
));
179 cols
[i
].columnid
= in_data
[i
].columnid
;
180 cols
[i
].cbMaxLen
= in_data
[i
].max_len
;
181 cols
[i
].wType
= in_data
[i
].type
;
182 cols
[i
].bPrecision
= in_data
[i
].precision
;
183 cols
[i
].bScale
= in_data
[i
].scale
;
186 hr
= IRow_GetColumns(row
, num_cols
, cols
);
189 for(i
= 0; i
< num_cols
; i
++)
191 VariantInit(&out_data
[i
].v
);
192 if(cols
[i
].dwStatus
== DBSTATUS_S_OK
)
194 V_VT(&out_data
[i
].v
) = in_data
[i
].type
;
195 memcpy(&V_I1(&out_data
[i
].v
), cols
[i
].pData
, cols
[i
].cbDataLen
);
197 CoTaskMemFree(cols
[i
].pData
);
198 out_data
[i
].data_len
= cols
[i
].cbDataLen
;
199 out_data
[i
].status
= cols
[i
].dwStatus
;
207 static HRESULT WINAPI
server_GetSourceRowset(IWineRowServer
* iface
, REFIID riid
, IUnknown
**ppRowset
,
210 server
*This
= impl_from_IWineRowServer(iface
);
211 FIXME("(%p): stub\n", This
);
215 static HRESULT WINAPI
server_Open(IWineRowServer
* iface
, IUnknown
*pUnkOuter
, DBID
*pColumnID
,
216 REFGUID rguidColumnType
, DWORD dwBindFlags
, REFIID riid
,
219 server
*This
= impl_from_IWineRowServer(iface
);
222 IWineRowServer
*new_server
;
226 TRACE("(%p)->(%p, %p, %s, %08x, %s, %p)\n", This
, pUnkOuter
, pColumnID
, debugstr_guid(rguidColumnType
),
227 dwBindFlags
, debugstr_guid(riid
), ppUnk
);
231 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRow
, (void**)&row
);
232 if(FAILED(hr
)) return hr
;
234 if(IsEqualGUID(rguidColumnType
, &DBGUID_ROWSET
))
235 hr
= CoCreateInstance(&CLSID_wine_rowset_server
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWineRowServer
, (void**)&new_server
);
238 FIXME("Unhandled object %s\n", debugstr_guid(rguidColumnType
));
248 IWineRowServer_GetMarshal(new_server
, &marshal
);
249 hr
= IRow_Open(row
, (IUnknown
*)marshal
, pColumnID
, rguidColumnType
, dwBindFlags
, &IID_IUnknown
, &obj
);
250 IMarshal_Release(marshal
);
255 IWineRowServer_Release(new_server
);
259 IWineRowServer_SetInnerUnk(new_server
, obj
);
260 hr
= IUnknown_QueryInterface(obj
, riid
, (void**)ppUnk
);
261 IUnknown_Release(obj
);
263 TRACE("returning %08x\n", hr
);
267 static HRESULT WINAPI
server_SetColumns(IWineRowServer
* iface
, DBORDINAL num_cols
,
268 wine_setcolumns_in
*in_data
, DBSTATUS
*status
)
270 server
*This
= impl_from_IWineRowServer(iface
);
273 DBCOLUMNACCESS
*cols
;
274 IRowChange
*row_change
;
276 TRACE("(%p)->(%ld, %p, %p)\n", This
, num_cols
, in_data
, status
);
277 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowChange
, (void**)&row_change
);
278 if(FAILED(hr
)) return hr
;
280 cols
= CoTaskMemAlloc(num_cols
* sizeof(cols
[0]));
282 for(i
= 0; i
< num_cols
; i
++)
284 TRACE("%ld:\ttype %04x\n", i
, in_data
[i
].type
);
285 cols
[i
].pData
= CoTaskMemAlloc(db_type_size(in_data
[i
].type
, in_data
[i
].max_len
));
286 memcpy(cols
[i
].pData
, &V_I1(&in_data
[i
].v
), db_type_size(in_data
[i
].type
, in_data
[i
].max_len
));
287 cols
[i
].columnid
= in_data
[i
].columnid
;
288 cols
[i
].cbDataLen
= in_data
[i
].data_len
;
289 cols
[i
].dwStatus
= in_data
[i
].status
;
290 cols
[i
].cbMaxLen
= in_data
[i
].max_len
;
291 cols
[i
].wType
= in_data
[i
].type
;
292 cols
[i
].bPrecision
= in_data
[i
].precision
;
293 cols
[i
].bScale
= in_data
[i
].scale
;
296 hr
= IRowChange_SetColumns(row_change
, num_cols
, cols
);
297 IRowChange_Release(row_change
);
299 for(i
= 0; i
< num_cols
; i
++)
301 CoTaskMemFree(cols
[i
].pData
);
302 status
[i
] = cols
[i
].dwStatus
;
310 static HRESULT WINAPI
server_AddRefRows(IWineRowServer
* iface
, DBCOUNTITEM cRows
,
311 const HROW rghRows
[], DBREFCOUNT rgRefCounts
[],
312 DBROWSTATUS rgRowStatus
[])
314 server
*This
= impl_from_IWineRowServer(iface
);
318 TRACE("(%p)->(%ld, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
320 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
321 if(FAILED(hr
)) return hr
;
323 hr
= IRowset_AddRefRows(rowset
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
325 IRowset_Release(rowset
);
326 TRACE("returning %08x\n", hr
);
330 static HRESULT WINAPI
server_GetData(IWineRowServer
* iface
, HROW hRow
,
331 HACCESSOR hAccessor
, BYTE
*pData
, DWORD size
)
333 server
*This
= impl_from_IWineRowServer(iface
);
337 TRACE("(%p)->(%08lx, %08lx, %p, %d)\n", This
, hRow
, hAccessor
, pData
, size
);
339 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
340 if(FAILED(hr
)) return hr
;
342 hr
= IRowset_GetData(rowset
, hRow
, hAccessor
, pData
);
344 IRowset_Release(rowset
);
345 TRACE("returning %08x\n", hr
);
349 static HRESULT WINAPI
server_GetNextRows(IWineRowServer
* iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
350 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
352 server
*This
= impl_from_IWineRowServer(iface
);
356 TRACE("(%p)->(%08lx, %ld, %ld, %p, %p)\n", This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
358 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
359 if(FAILED(hr
)) return hr
;
363 hr
= IRowset_GetNextRows(rowset
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
364 IRowset_Release(rowset
);
365 TRACE("returning %08x, got %ld rows\n", hr
, *pcRowObtained
);
369 static HRESULT WINAPI
server_ReleaseRows(IWineRowServer
* iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
370 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
372 server
*This
= impl_from_IWineRowServer(iface
);
376 TRACE("(%p)->(%ld, %p, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
378 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
379 if(FAILED(hr
)) return hr
;
381 hr
= IRowset_ReleaseRows(rowset
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
382 IRowset_Release(rowset
);
384 TRACE("returning %08x\n", hr
);
388 static HRESULT WINAPI
server_RestartPosition(IWineRowServer
* iface
, HCHAPTER hReserved
)
390 server
*This
= impl_from_IWineRowServer(iface
);
391 FIXME("(%p)->(%08lx): stub\n", This
, hReserved
);
395 static HRESULT WINAPI
server_Compare(IWineRowServer
*iface
, HCHAPTER hReserved
, DBBKMARK cbBookmark1
,
396 const BYTE
*pBookmark1
, DBBKMARK cbBookmark2
, const BYTE
*pBookmark2
,
397 DBCOMPARE
*pComparison
)
399 server
*This
= impl_from_IWineRowServer(iface
);
400 FIXME("(%p): stub\n", This
);
404 static HRESULT WINAPI
server_GetRowsAt(IWineRowServer
*iface
, HWATCHREGION hReserved1
, HCHAPTER hReserved2
,
405 DBBKMARK cbBookmark
, const BYTE
*pBookmark
, DBROWOFFSET lRowsOffset
,
406 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowsObtained
, HROW
**prghRows
)
408 server
*This
= impl_from_IWineRowServer(iface
);
409 IRowsetLocate
*rowsetlocate
;
412 TRACE("(%p)->(%08lx, %08lx, %ld, %p, %ld, %ld, %p, %p\n", This
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
, cRows
,
413 pcRowsObtained
, prghRows
);
417 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowsetLocate
, (void**)&rowsetlocate
);
418 if(FAILED(hr
)) return hr
;
420 hr
= IRowsetLocate_GetRowsAt(rowsetlocate
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
,
421 cRows
, pcRowsObtained
, prghRows
);
422 IRowsetLocate_Release(rowsetlocate
);
424 TRACE("returning %08x\n", hr
);
428 static HRESULT WINAPI
server_GetRowsByBookmark(IWineRowServer
*iface
, HCHAPTER hReserved
, DBCOUNTITEM cRows
,
429 const DBBKMARK rgcbBookmarks
[], const BYTE
* rgpBookmarks
[],
430 HROW rghRows
[], DBROWSTATUS rgRowStatus
[])
432 server
*This
= impl_from_IWineRowServer(iface
);
433 FIXME("(%p): stub\n", This
);
437 static HRESULT WINAPI
server_Hash(IWineRowServer
*iface
, HCHAPTER hReserved
, DBBKMARK cBookmarks
,
438 const DBBKMARK rgcbBookmarks
[], const BYTE
* rgpBookmarks
[],
439 DBHASHVALUE rgHashedValues
[], DBROWSTATUS rgBookmarkStatus
[])
441 server
*This
= impl_from_IWineRowServer(iface
);
442 FIXME("(%p): stub\n", This
);
446 static HRESULT WINAPI
server_GetProperties(IWineRowServer
* iface
, ULONG cPropertyIDSets
,
447 const DBPROPIDSET
*rgPropertyIDSets
, ULONG
*pcPropertySets
,
448 DBPROPSET
**prgPropertySets
)
450 server
*This
= impl_from_IWineRowServer(iface
);
451 IRowsetInfo
*rowsetinfo
;
454 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
456 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowsetInfo
, (void**)&rowsetinfo
);
457 if(FAILED(hr
)) return hr
;
459 hr
= IRowsetInfo_GetProperties(rowsetinfo
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
460 IRowsetInfo_Release(rowsetinfo
);
462 TRACE("returning %08x\n", hr
);
466 static HRESULT WINAPI
server_GetReferencedRowset(IWineRowServer
* iface
, DBORDINAL iOrdinal
,
467 REFIID riid
, IUnknown
**ppReferencedRowset
)
469 server
*This
= impl_from_IWineRowServer(iface
);
470 FIXME("(%p): stub\n", This
);
474 static HRESULT WINAPI
server_GetSpecification(IWineRowServer
* iface
, REFIID riid
,
475 IUnknown
**ppSpecification
)
477 server
*This
= impl_from_IWineRowServer(iface
);
478 FIXME("(%p): stub\n", This
);
482 static HRESULT WINAPI
server_AddRefAccessor(IWineRowServer
* iface
, HACCESSOR hAccessor
,
483 DBREFCOUNT
*pcRefCount
)
485 server
*This
= impl_from_IWineRowServer(iface
);
486 FIXME("(%p): stub\n", This
);
490 static HRESULT WINAPI
server_CreateAccessor(IWineRowServer
* iface
, DBACCESSORFLAGS dwAccessorFlags
,
491 DBCOUNTITEM cBindings
, const DBBINDING
*rgBindings
, DBLENGTH cbRowSize
,
492 HACCESSOR
*phAccessor
, DBBINDSTATUS
*rgStatus
)
494 server
*This
= impl_from_IWineRowServer(iface
);
498 TRACE("(%p)->(%08x, %ld, %p, %ld, %p, %p)\n", This
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, rgStatus
);
500 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IAccessor
, (void**)&accessor
);
501 if(FAILED(hr
)) return hr
;
503 hr
= IAccessor_CreateAccessor(accessor
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, rgStatus
);
504 IAccessor_Release(accessor
);
506 TRACE("returning %08x, accessor %08lx\n", hr
, *phAccessor
);
510 static HRESULT WINAPI
server_GetBindings(IWineRowServer
* iface
, HACCESSOR hAccessor
,
511 DBACCESSORFLAGS
*pdwAccessorFlags
, DBCOUNTITEM
*pcBindings
,
512 DBBINDING
**prgBindings
)
514 server
*This
= impl_from_IWineRowServer(iface
);
518 TRACE("(%p)->(%08lx, %p, %p, %p)\n", This
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
520 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IAccessor
, (void**)&accessor
);
521 if(FAILED(hr
)) return hr
;
523 hr
= IAccessor_GetBindings(accessor
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
524 IAccessor_Release(accessor
);
526 TRACE("returning %08x\n", hr
);
530 static HRESULT WINAPI
server_ReleaseAccessor(IWineRowServer
* iface
, HACCESSOR hAccessor
,
531 DBREFCOUNT
*pcRefCount
)
533 server
*This
= impl_from_IWineRowServer(iface
);
537 TRACE("(%p)->(%08lx, %p)\n", This
, hAccessor
, pcRefCount
);
539 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IAccessor
, (void**)&accessor
);
540 if(FAILED(hr
)) return hr
;
542 hr
= IAccessor_ReleaseAccessor(accessor
, hAccessor
, pcRefCount
);
543 IAccessor_Release(accessor
);
548 static const IWineRowServerVtbl server_vtbl
=
550 server_QueryInterface
,
556 server_GetSourceRowset
,
563 server_RestartPosition
,
566 server_GetRowsByBookmark
,
568 server_GetProperties
,
569 server_GetReferencedRowset
,
570 server_GetSpecification
,
571 server_AddRefAccessor
,
572 server_CreateAccessor
,
574 server_ReleaseAccessor
577 static HRESULT
create_server(IUnknown
*outer
, const CLSID
*class, void **obj
)
580 TRACE("(%p, %s, %p)\n", outer
, debugstr_guid(class), obj
);
584 server
= HeapAlloc(GetProcessHeap(), 0, sizeof(*server
));
585 if(!server
) return E_OUTOFMEMORY
;
587 server
->IWineRowServer_iface
.lpVtbl
= &server_vtbl
;
589 server
->class = *class;
590 server
->inner_unk
= NULL
;
591 if(IsEqualGUID(class, &CLSID_wine_row_server
))
592 create_row_marshal((IUnknown
*)server
, (void**)&server
->marshal
);
593 else if(IsEqualGUID(class, &CLSID_wine_rowset_server
))
594 create_rowset_marshal((IUnknown
*)server
, (void**)&server
->marshal
);
596 ERR("create_server called with class %s\n", debugstr_guid(class));
602 HRESULT
create_row_server(IUnknown
*outer
, void **obj
)
604 return create_server(outer
, &CLSID_wine_row_server
, obj
);
607 HRESULT
create_rowset_server(IUnknown
*outer
, void **obj
)
609 return create_server(outer
, &CLSID_wine_rowset_server
, obj
);
615 IRowChange IRowChange_iface
;
619 IWineRowServer
*server
;
622 static inline row_proxy
*impl_from_IRow(IRow
*iface
)
624 return CONTAINING_RECORD(iface
, row_proxy
, IRow_iface
);
627 static inline row_proxy
*impl_from_IRowChange(IRowChange
*iface
)
629 return CONTAINING_RECORD(iface
, row_proxy
, IRowChange_iface
);
632 static HRESULT WINAPI
row_QueryInterface(IRow
*iface
, REFIID iid
, void **obj
)
634 row_proxy
*This
= impl_from_IRow(iface
);
635 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
637 if(IsEqualIID(iid
, &IID_IUnknown
) ||
638 IsEqualIID(iid
, &IID_IRow
))
640 *obj
= &This
->IRow_iface
;
642 else if(IsEqualIID(iid
, &IID_IRowChange
))
644 *obj
= &This
->IRowChange_iface
;
648 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
649 return E_NOINTERFACE
;
656 static ULONG WINAPI
row_AddRef(IRow
*iface
)
658 row_proxy
*This
= impl_from_IRow(iface
);
659 TRACE("(%p)\n", This
);
661 return InterlockedIncrement(&This
->ref
);
664 static ULONG WINAPI
row_Release(IRow
*iface
)
666 row_proxy
*This
= impl_from_IRow(iface
);
669 TRACE("(%p)\n", This
);
671 ref
= InterlockedDecrement(&This
->ref
);
674 if(This
->server
) IWineRowServer_Release(This
->server
);
675 HeapFree(GetProcessHeap(), 0, This
);
681 static HRESULT WINAPI
row_GetColumns(IRow
* iface
, DBORDINAL cColumns
, DBCOLUMNACCESS rgColumns
[])
683 row_proxy
*This
= impl_from_IRow(iface
);
685 wine_getcolumns_in
*in_data
;
686 wine_getcolumns_out
*out_data
;
689 TRACE("(%p)->(%ld, %p)\n", This
, cColumns
, rgColumns
);
691 in_data
= CoTaskMemAlloc(cColumns
* sizeof(in_data
[0]));
692 out_data
= CoTaskMemAlloc(cColumns
* sizeof(out_data
[0]));
694 for(i
= 0; i
< cColumns
; i
++)
696 TRACE("%ld:\tdata %p data_len %ld status %08x max_len %ld type %04x\n", i
, rgColumns
[i
].pData
,
697 rgColumns
[i
].cbDataLen
, rgColumns
[i
].dwStatus
, rgColumns
[i
].cbMaxLen
, rgColumns
[i
].wType
);
698 in_data
[i
].columnid
= rgColumns
[i
].columnid
;
699 in_data
[i
].max_len
= rgColumns
[i
].cbMaxLen
;
700 in_data
[i
].type
= rgColumns
[i
].wType
;
701 in_data
[i
].precision
= rgColumns
[i
].bPrecision
;
702 in_data
[i
].scale
= rgColumns
[i
].bScale
;
705 hr
= IWineRowServer_GetColumns(This
->server
, cColumns
, in_data
, out_data
);
707 for(i
= 0; i
< cColumns
; i
++)
709 rgColumns
[i
].cbDataLen
= out_data
[i
].data_len
;
710 rgColumns
[i
].dwStatus
= out_data
[i
].status
;
711 if(rgColumns
[i
].dwStatus
== DBSTATUS_S_OK
)
712 memcpy(rgColumns
[i
].pData
, &V_I1(&out_data
[i
].v
), out_data
[i
].data_len
);
715 CoTaskMemFree(out_data
);
716 CoTaskMemFree(in_data
);
720 static HRESULT WINAPI
row_GetSourceRowset(IRow
* iface
, REFIID riid
, IUnknown
**ppRowset
,
723 row_proxy
*This
= impl_from_IRow(iface
);
725 FIXME("(%p)->(%s, %p, %p): stub\n", This
, debugstr_guid(riid
), ppRowset
, phRow
);
730 static HRESULT WINAPI
row_Open(IRow
* iface
, IUnknown
*pUnkOuter
,
731 DBID
*pColumnID
, REFGUID rguidColumnType
,
732 DWORD dwBindFlags
, REFIID riid
, IUnknown
**ppUnk
)
734 row_proxy
*This
= impl_from_IRow(iface
);
736 TRACE("(%p)->(%p, %p, %s, %08x, %s, %p)\n", This
, pUnkOuter
, pColumnID
, debugstr_guid(rguidColumnType
),
737 dwBindFlags
, debugstr_guid(riid
), ppUnk
);
740 FIXME("Aggregation not supported\n");
741 return CLASS_E_NOAGGREGATION
;
744 return IWineRowServer_Open(This
->server
, pUnkOuter
, pColumnID
, rguidColumnType
, dwBindFlags
, riid
, ppUnk
);
747 static const IRowVtbl row_vtbl
=
757 static HRESULT WINAPI
row_change_QueryInterface(IRowChange
*iface
, REFIID iid
, void **obj
)
759 row_proxy
*This
= impl_from_IRowChange(iface
);
760 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
763 static ULONG WINAPI
row_change_AddRef(IRowChange
*iface
)
765 row_proxy
*This
= impl_from_IRowChange(iface
);
766 return IUnknown_AddRef((IUnknown
*)This
);
769 static ULONG WINAPI
row_change_Release(IRowChange
*iface
)
771 row_proxy
*This
= impl_from_IRowChange(iface
);
772 return IUnknown_Release((IUnknown
*)This
);
775 static HRESULT WINAPI
row_change_SetColumns(IRowChange
*iface
, DBORDINAL cColumns
,
776 DBCOLUMNACCESS rgColumns
[])
778 row_proxy
*This
= impl_from_IRowChange(iface
);
780 wine_setcolumns_in
*in_data
;
784 TRACE("(%p)->(%ld, %p)\n", This
, cColumns
, rgColumns
);
786 in_data
= CoTaskMemAlloc(cColumns
* sizeof(in_data
[0]));
787 status
= CoTaskMemAlloc(cColumns
* sizeof(status
[0]));
789 for(i
= 0; i
< cColumns
; i
++)
791 TRACE("%ld: wtype %04x max %08lx len %08lx\n", i
, rgColumns
[i
].wType
, rgColumns
[i
].cbMaxLen
, rgColumns
[i
].cbDataLen
);
792 V_VT(&in_data
[i
].v
) = rgColumns
[i
].wType
;
793 memcpy(&V_I1(&in_data
[i
].v
), rgColumns
[i
].pData
, db_type_size(rgColumns
[i
].wType
, rgColumns
[i
].cbDataLen
));
794 in_data
[i
].columnid
= rgColumns
[i
].columnid
;
795 in_data
[i
].data_len
= rgColumns
[i
].cbDataLen
;
796 in_data
[i
].status
= rgColumns
[i
].dwStatus
;
797 in_data
[i
].max_len
= rgColumns
[i
].cbMaxLen
;
798 in_data
[i
].type
= rgColumns
[i
].wType
;
799 in_data
[i
].precision
= rgColumns
[i
].bPrecision
;
800 in_data
[i
].scale
= rgColumns
[i
].bScale
;
803 hr
= IWineRowServer_SetColumns(This
->server
, cColumns
, in_data
, status
);
805 for(i
= 0; i
< cColumns
; i
++)
806 rgColumns
[i
].dwStatus
= status
[i
];
808 CoTaskMemFree(status
);
809 CoTaskMemFree(in_data
);
814 static const IRowChangeVtbl row_change_vtbl
=
816 row_change_QueryInterface
,
819 row_change_SetColumns
822 static HRESULT
create_row_proxy(IWineRowServer
*server
, IUnknown
**obj
)
826 TRACE("(%p, %p)\n", server
, obj
);
829 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
830 if(!proxy
) return E_OUTOFMEMORY
;
832 proxy
->IRow_iface
.lpVtbl
= &row_vtbl
;
833 proxy
->IRowChange_iface
.lpVtbl
= &row_change_vtbl
;
835 IWineRowServer_AddRef(server
);
836 proxy
->server
= server
;
838 *obj
= (IUnknown
*)&proxy
->IRow_iface
;
839 TRACE("returning %p\n", *obj
);
845 IRowsetLocate IRowsetLocate_iface
;
846 IRowsetInfo IRowsetInfo_iface
;
847 IAccessor IAccessor_iface
;
851 IWineRowServer
*server
;
854 static inline rowset_proxy
*impl_from_IRowsetLocate(IRowsetLocate
*iface
)
856 return CONTAINING_RECORD(iface
, rowset_proxy
, IRowsetLocate_iface
);
859 static inline rowset_proxy
*impl_from_IRowsetInfo(IRowsetInfo
*iface
)
861 return CONTAINING_RECORD(iface
, rowset_proxy
, IRowsetInfo_iface
);
864 static inline rowset_proxy
*impl_from_IAccessor(IAccessor
*iface
)
866 return CONTAINING_RECORD(iface
, rowset_proxy
, IAccessor_iface
);
869 static HRESULT WINAPI
rowsetlocate_QueryInterface(IRowsetLocate
*iface
, REFIID iid
, void **obj
)
871 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
872 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
876 if(IsEqualIID(iid
, &IID_IUnknown
) ||
877 IsEqualIID(iid
, &IID_IRowset
) ||
878 IsEqualIID(iid
, &IID_IRowsetLocate
))
880 *obj
= &This
->IRowsetLocate_iface
;
882 else if(IsEqualIID(iid
, &IID_IRowsetInfo
))
884 *obj
= &This
->IRowsetInfo_iface
;
886 else if(IsEqualIID(iid
, &IID_IAccessor
))
888 *obj
= &This
->IAccessor_iface
;
892 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
893 return E_NOINTERFACE
;
896 IRowsetLocate_AddRef(iface
);
900 static ULONG WINAPI
rowsetlocate_AddRef(IRowsetLocate
*iface
)
902 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
903 TRACE("(%p)\n", This
);
905 return InterlockedIncrement(&This
->ref
);
908 static ULONG WINAPI
rowsetlocate_Release(IRowsetLocate
*iface
)
910 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
913 TRACE("(%p)\n", This
);
915 ref
= InterlockedDecrement(&This
->ref
);
918 if(This
->server
) IWineRowServer_Release(This
->server
);
919 HeapFree(GetProcessHeap(), 0, This
);
925 static HRESULT WINAPI
rowsetlocate_AddRefRows(IRowsetLocate
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
926 DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
928 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
930 DBREFCOUNT
*refs
= rgRefCounts
;
931 DBSTATUS
*stats
= rgRowStatus
;
933 TRACE("(%p)->(%ld, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
935 if(!refs
) refs
= CoTaskMemAlloc(cRows
* sizeof(refs
[0]));
936 if(!stats
) stats
= CoTaskMemAlloc(cRows
* sizeof(stats
[0]));
938 hr
= IWineRowServer_AddRefRows(This
->server
, cRows
, rghRows
, refs
, stats
);
940 if(refs
!= rgRefCounts
) CoTaskMemFree(refs
);
941 if(stats
!= rgRowStatus
) CoTaskMemFree(stats
);
946 static HRESULT WINAPI
rowsetlocate_GetData(IRowsetLocate
*iface
, HROW hRow
, HACCESSOR hAccessor
, void *pData
)
948 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
951 DBACCESSORFLAGS flags
;
952 DBCOUNTITEM count
, i
;
956 TRACE("(%p)->(%lx, %lx, %p)\n", This
, hRow
, hAccessor
, pData
);
958 hr
= IRowsetLocate_QueryInterface(iface
, &IID_IAccessor
, (void**)&accessor
);
959 if(FAILED(hr
)) return hr
;
961 hr
= IAccessor_GetBindings(accessor
, hAccessor
, &flags
, &count
, &bindings
);
962 IAccessor_Release(accessor
);
963 if(FAILED(hr
)) return hr
;
965 TRACE("got %ld bindings\n", count
);
966 for(i
= 0; i
< count
; i
++)
968 TRACE("%ld\tord %ld offs: val %ld len %ld stat %ld, part %x, max len %ld type %04x\n",
969 i
, bindings
[i
].iOrdinal
, bindings
[i
].obValue
, bindings
[i
].obLength
, bindings
[i
].obStatus
,
970 bindings
[i
].dwPart
, bindings
[i
].cbMaxLen
, bindings
[i
].wType
);
971 if(bindings
[i
].dwPart
& DBPART_LENGTH
&& bindings
[i
].obLength
>= max_len
)
972 max_len
= bindings
[i
].obLength
+ sizeof(DBLENGTH
);
973 if(bindings
[i
].dwPart
& DBPART_STATUS
&& bindings
[i
].obStatus
>= max_len
)
974 max_len
= bindings
[i
].obStatus
+ sizeof(DWORD
);
975 if(bindings
[i
].dwPart
& DBPART_VALUE
&& bindings
[i
].obValue
>= max_len
)
976 max_len
= bindings
[i
].obValue
+ db_type_size(bindings
[i
].wType
, bindings
[i
].cbMaxLen
);
979 TRACE("max_len %d\n", max_len
);
981 CoTaskMemFree(bindings
);
983 hr
= IWineRowServer_GetData(This
->server
, hRow
, hAccessor
, pData
, max_len
);
988 static HRESULT WINAPI
rowsetlocate_GetNextRows(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
989 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
991 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
995 TRACE("(%p)->(%08lx, %ld, %ld, %p, %p)\n", This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
997 hr
= IWineRowServer_GetNextRows(This
->server
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, &rows
);
1000 memcpy(*prghRows
, rows
, *pcRowObtained
* sizeof(rows
[0]));
1001 CoTaskMemFree(rows
);
1009 static HRESULT WINAPI
rowsetlocate_ReleaseRows(IRowsetLocate
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
1010 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
1012 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1014 DBROWOPTIONS
*options
= rgRowOptions
;
1015 DBREFCOUNT
*refs
= rgRefCounts
;
1016 DBROWSTATUS
*status
= rgRowStatus
;
1018 TRACE("(%p)->(%ld, %p, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
1022 options
= CoTaskMemAlloc(cRows
* sizeof(options
[0]));
1023 memset(options
, 0, cRows
* sizeof(options
[0]));
1025 if(!refs
) refs
= CoTaskMemAlloc(cRows
* sizeof(refs
[0]));
1026 if(!status
) status
= CoTaskMemAlloc(cRows
* sizeof(status
[0]));
1028 hr
= IWineRowServer_ReleaseRows(This
->server
, cRows
, rghRows
, options
, refs
, status
);
1030 if(status
!= rgRowStatus
) CoTaskMemFree(status
);
1031 if(refs
!= rgRefCounts
) CoTaskMemFree(refs
);
1032 if(options
!= rgRowOptions
) CoTaskMemFree(options
);
1037 static HRESULT WINAPI
rowsetlocate_RestartPosition(IRowsetLocate
* iface
, HCHAPTER hReserved
)
1039 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1041 FIXME("(%p)->(%lx): stub\n", This
, hReserved
);
1046 static HRESULT WINAPI
rowsetlocate_Compare(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBBKMARK cbBookmark1
, const BYTE
*pBookmark1
,
1047 DBBKMARK cbBookmark2
, const BYTE
*pBookmark2
, DBCOMPARE
*pComparison
)
1049 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1050 FIXME("(%p)\n", This
);
1054 static HRESULT WINAPI
rowsetlocate_GetRowsAt(IRowsetLocate
*iface
, HWATCHREGION hReserved1
, HCHAPTER hReserved2
, DBBKMARK cbBookmark
,
1055 const BYTE
*pBookmark
, DBROWOFFSET lRowsOffset
, DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowsObtained
,
1058 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1062 TRACE("(%p)->(%08lx, %08lx, %ld, %p, %ld, %ld, %p, %p\n", This
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
, cRows
,
1063 pcRowsObtained
, prghRows
);
1065 hr
= IWineRowServer_GetRowsAt(This
->server
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
, cRows
, pcRowsObtained
, &rows
);
1069 memcpy(*prghRows
, rows
, *pcRowsObtained
* sizeof(rows
[0]));
1070 CoTaskMemFree(rows
);
1078 static HRESULT WINAPI
rowsetlocate_GetRowsByBookmark(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBCOUNTITEM cRows
, const DBBKMARK rgcbBookmarks
[],
1079 const BYTE
* rgpBookmarks
[], HROW rghRows
[], DBROWSTATUS rgRowStatus
[])
1081 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1082 FIXME("(%p)\n", This
);
1086 static HRESULT WINAPI
rowsetlocate_Hash(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBBKMARK cBookmarks
, const DBBKMARK rgcbBookmarks
[],
1087 const BYTE
* rgpBookmarks
[], DBHASHVALUE rgHashedValues
[], DBROWSTATUS rgBookmarkStatus
[])
1089 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1090 FIXME("(%p)\n", This
);
1094 static const IRowsetLocateVtbl rowsetlocate_vtbl
=
1096 rowsetlocate_QueryInterface
,
1097 rowsetlocate_AddRef
,
1098 rowsetlocate_Release
,
1099 rowsetlocate_AddRefRows
,
1100 rowsetlocate_GetData
,
1101 rowsetlocate_GetNextRows
,
1102 rowsetlocate_ReleaseRows
,
1103 rowsetlocate_RestartPosition
,
1104 rowsetlocate_Compare
,
1105 rowsetlocate_GetRowsAt
,
1106 rowsetlocate_GetRowsByBookmark
,
1110 static HRESULT WINAPI
rowsetinfo_QueryInterface(IRowsetInfo
*iface
, REFIID iid
, void **obj
)
1112 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1113 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
1116 static ULONG WINAPI
rowsetinfo_AddRef(IRowsetInfo
*iface
)
1118 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1119 return IUnknown_AddRef((IUnknown
*)This
);
1122 static ULONG WINAPI
rowsetinfo_Release(IRowsetInfo
*iface
)
1124 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1125 return IUnknown_Release((IUnknown
*)This
);
1128 static HRESULT WINAPI
rowsetinfo_GetProperties(IRowsetInfo
*iface
, const ULONG cPropertyIDSets
,
1129 const DBPROPIDSET rgPropertyIDSets
[], ULONG
*pcPropertySets
,
1130 DBPROPSET
**prgPropertySets
)
1132 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1135 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
1137 hr
= IWineRowServer_GetProperties(This
->server
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
1142 static HRESULT WINAPI
rowsetinfo_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL iOrdinal
, REFIID riid
,
1143 IUnknown
**ppReferencedRowset
)
1145 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1146 FIXME("(%p)\n", This
);
1150 static HRESULT WINAPI
rowsetinfo_GetSpecification(IRowsetInfo
*iface
, REFIID riid
, IUnknown
**ppSpecification
)
1152 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1153 FIXME("(%p)\n", This
);
1157 static const IRowsetInfoVtbl rowsetinfo_vtbl
=
1159 rowsetinfo_QueryInterface
,
1162 rowsetinfo_GetProperties
,
1163 rowsetinfo_GetReferencedRowset
,
1164 rowsetinfo_GetSpecification
1167 static HRESULT WINAPI
accessor_QueryInterface(IAccessor
*iface
, REFIID iid
, void **obj
)
1169 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1170 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
1173 static ULONG WINAPI
accessor_AddRef(IAccessor
*iface
)
1175 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1176 return IUnknown_AddRef((IUnknown
*)This
);
1179 static ULONG WINAPI
accessor_Release(IAccessor
*iface
)
1181 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1182 return IUnknown_Release((IUnknown
*)This
);
1185 static HRESULT WINAPI
accessor_AddRefAccessor(IAccessor
*iface
, HACCESSOR hAccessor
, DBREFCOUNT
*pcRefCount
)
1187 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1188 FIXME("(%p)\n", This
);
1192 static HRESULT WINAPI
accessor_CreateAccessor(IAccessor
*iface
, DBACCESSORFLAGS dwAccessorFlags
, DBCOUNTITEM cBindings
,
1193 const DBBINDING rgBindings
[], DBLENGTH cbRowSize
, HACCESSOR
*phAccessor
,
1194 DBBINDSTATUS rgStatus
[])
1196 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1198 DBBINDSTATUS
*status
;
1200 TRACE("(%p)->(%08x, %ld, %p, %ld, %p, %p)\n", This
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, rgStatus
);
1202 if(!rgStatus
) status
= CoTaskMemAlloc(cBindings
* sizeof(status
[0]));
1203 else status
= rgStatus
;
1205 hr
= IWineRowServer_CreateAccessor(This
->server
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, status
);
1207 if(!rgStatus
) CoTaskMemFree(status
);
1212 static HRESULT WINAPI
accessor_GetBindings(IAccessor
*iface
, HACCESSOR hAccessor
, DBACCESSORFLAGS
*pdwAccessorFlags
,
1213 DBCOUNTITEM
*pcBindings
, DBBINDING
**prgBindings
)
1215 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1218 TRACE("(%p)->(%08lx, %p, %p, %p)\n", This
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
1220 hr
= IWineRowServer_GetBindings(This
->server
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
1225 static HRESULT WINAPI
accessor_ReleaseAccessor(IAccessor
*iface
, HACCESSOR hAccessor
, DBREFCOUNT
*pcRefCount
)
1227 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1231 TRACE("(%p)->(%08lx, %p)\n", This
, hAccessor
, pcRefCount
);
1233 hr
= IWineRowServer_ReleaseAccessor(This
->server
, hAccessor
, &ref
);
1234 if(pcRefCount
) *pcRefCount
= ref
;
1238 static const IAccessorVtbl accessor_vtbl
=
1240 accessor_QueryInterface
,
1243 accessor_AddRefAccessor
,
1244 accessor_CreateAccessor
,
1245 accessor_GetBindings
,
1246 accessor_ReleaseAccessor
1249 static HRESULT
create_rowset_proxy(IWineRowServer
*server
, IUnknown
**obj
)
1251 rowset_proxy
*proxy
;
1253 TRACE("(%p, %p)\n", server
, obj
);
1256 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
1257 if(!proxy
) return E_OUTOFMEMORY
;
1259 proxy
->IRowsetLocate_iface
.lpVtbl
= &rowsetlocate_vtbl
;
1260 proxy
->IRowsetInfo_iface
.lpVtbl
= &rowsetinfo_vtbl
;
1261 proxy
->IAccessor_iface
.lpVtbl
= &accessor_vtbl
;
1263 IWineRowServer_AddRef(server
);
1264 proxy
->server
= server
;
1266 *obj
= (IUnknown
*)&proxy
->IRowsetLocate_iface
;
1267 TRACE("returning %p\n", *obj
);
1271 static HRESULT
create_proxy(IWineRowServer
*server
, const CLSID
*class, IUnknown
**obj
)
1275 if(IsEqualGUID(class, &CLSID_wine_row_proxy
))
1276 return create_row_proxy(server
, obj
);
1277 else if(IsEqualGUID(class, &CLSID_wine_rowset_proxy
))
1278 return create_rowset_proxy(server
, obj
);
1280 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
1288 IMarshal IMarshal_iface
;
1291 CLSID unmarshal_class
;
1295 static inline marshal
*impl_from_IMarshal(IMarshal
*iface
)
1297 return CONTAINING_RECORD(iface
, marshal
, IMarshal_iface
);
1300 static HRESULT WINAPI
marshal_QueryInterface(IMarshal
*iface
, REFIID iid
, void **obj
)
1302 marshal
*This
= impl_from_IMarshal(iface
);
1303 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
1305 if(IsEqualIID(iid
, &IID_IUnknown
) ||
1306 IsEqualIID(iid
, &IID_IMarshal
))
1312 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
1314 return E_NOINTERFACE
;
1317 IMarshal_AddRef(iface
);
1321 static ULONG WINAPI
marshal_AddRef(IMarshal
*iface
)
1323 marshal
*This
= impl_from_IMarshal(iface
);
1324 TRACE("(%p)\n", This
);
1325 return InterlockedIncrement(&This
->ref
);
1328 static ULONG WINAPI
marshal_Release(IMarshal
*iface
)
1330 marshal
*This
= impl_from_IMarshal(iface
);
1333 TRACE("(%p)\n", This
);
1335 ref
= InterlockedDecrement(&This
->ref
);
1338 HeapFree(GetProcessHeap(), 0, This
);
1344 static HRESULT WINAPI
marshal_GetUnmarshalClass(IMarshal
*iface
, REFIID iid
, void *obj
,
1345 DWORD dwDestContext
, void *pvDestContext
,
1346 DWORD mshlflags
, CLSID
*clsid
)
1348 marshal
*This
= impl_from_IMarshal(iface
);
1349 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This
, debugstr_guid(iid
), obj
, dwDestContext
,
1350 pvDestContext
, mshlflags
, clsid
);
1352 *clsid
= This
->unmarshal_class
;
1356 static HRESULT WINAPI
marshal_GetMarshalSizeMax(IMarshal
*iface
, REFIID iid
, void *obj
,
1357 DWORD dwDestContext
, void *pvDestContext
,
1358 DWORD mshlflags
, DWORD
*size
)
1360 marshal
*This
= impl_from_IMarshal(iface
);
1361 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This
, debugstr_guid(iid
), obj
, dwDestContext
,
1362 pvDestContext
, mshlflags
, size
);
1364 return CoGetMarshalSizeMax(size
, &IID_IWineRowServer
, This
->outer
, dwDestContext
, pvDestContext
,
1368 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
1369 void *obj
, DWORD dwDestContext
, void *pvDestContext
,
1372 marshal
*This
= impl_from_IMarshal(iface
);
1373 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This
, stream
, debugstr_guid(iid
), obj
, dwDestContext
,
1374 pvDestContext
, mshlflags
);
1376 return CoMarshalInterface(stream
, &IID_IWineRowServer
, This
->outer
, dwDestContext
, pvDestContext
, mshlflags
);
1379 static HRESULT WINAPI
marshal_UnmarshalInterface(IMarshal
*iface
, IStream
*stream
,
1380 REFIID iid
, void **obj
)
1382 marshal
*This
= impl_from_IMarshal(iface
);
1384 IWineRowServer
*server
;
1387 TRACE("(%p)->(%p, %s, %p)\n", This
, stream
, debugstr_guid(iid
), obj
);
1390 hr
= CoUnmarshalInterface(stream
, &IID_IWineRowServer
, (void**)&server
);
1393 hr
= create_proxy(server
, &This
->unmarshal_class
, &proxy
);
1396 hr
= IUnknown_QueryInterface(proxy
, iid
, obj
);
1397 IUnknown_Release(proxy
);
1399 IWineRowServer_Release(server
);
1402 TRACE("returning %p\n", *obj
);
1406 static HRESULT WINAPI
marshal_ReleaseMarshalData(IMarshal
*iface
, IStream
*stream
)
1408 marshal
*This
= impl_from_IMarshal(iface
);
1409 TRACE("(%p)->(%p)\n", This
, stream
);
1410 return CoReleaseMarshalData(stream
);
1413 static HRESULT WINAPI
marshal_DisconnectObject(IMarshal
*iface
, DWORD dwReserved
)
1415 marshal
*This
= impl_from_IMarshal(iface
);
1416 FIXME("(%p)->(%08x)\n", This
, dwReserved
);
1421 static const IMarshalVtbl marshal_vtbl
=
1423 marshal_QueryInterface
,
1426 marshal_GetUnmarshalClass
,
1427 marshal_GetMarshalSizeMax
,
1428 marshal_MarshalInterface
,
1429 marshal_UnmarshalInterface
,
1430 marshal_ReleaseMarshalData
,
1431 marshal_DisconnectObject
1434 static HRESULT
create_marshal(IUnknown
*outer
, const CLSID
*class, void **obj
)
1438 TRACE("(%p, %p)\n", outer
, obj
);
1441 marshal
= HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal
));
1442 if(!marshal
) return E_OUTOFMEMORY
;
1444 marshal
->unmarshal_class
= *class;
1445 marshal
->outer
= outer
; /* don't ref outer unk */
1446 marshal
->IMarshal_iface
.lpVtbl
= &marshal_vtbl
;
1449 *obj
= &marshal
->IMarshal_iface
;
1450 TRACE("returning %p\n", *obj
);
1454 HRESULT
create_row_marshal(IUnknown
*outer
, void **obj
)
1456 TRACE("(%p, %p)\n", outer
, obj
);
1457 return create_marshal(outer
, &CLSID_wine_row_proxy
, obj
);
1460 HRESULT
create_rowset_marshal(IUnknown
*outer
, void **obj
)
1462 TRACE("(%p, %p)\n", outer
, obj
);
1463 return create_marshal(outer
, &CLSID_wine_rowset_proxy
, obj
);