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
);
224 IWineRowServer
*new_server
;
228 TRACE("(%p)->(%p, %p, %s, %08x, %s, %p)\n", This
, pUnkOuter
, pColumnID
, debugstr_guid(rguidColumnType
),
229 dwBindFlags
, debugstr_guid(riid
), ppUnk
);
233 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRow
, (void**)&row
);
234 if(FAILED(hr
)) return hr
;
236 if(IsEqualGUID(rguidColumnType
, &DBGUID_ROWSET
))
237 hr
= CoCreateInstance(&CLSID_wine_rowset_server
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWineRowServer
, (void**)&new_server
);
240 FIXME("Unhandled object %s\n", debugstr_guid(rguidColumnType
));
250 IWineRowServer_GetMarshal(new_server
, &marshal
);
251 hr
= IRow_Open(row
, (IUnknown
*)marshal
, pColumnID
, rguidColumnType
, dwBindFlags
, &IID_IUnknown
, &obj
);
252 IMarshal_Release(marshal
);
257 IWineRowServer_Release(new_server
);
261 IWineRowServer_SetInnerUnk(new_server
, obj
);
262 hr
= IUnknown_QueryInterface(obj
, riid
, (void**)ppUnk
);
263 IUnknown_Release(obj
);
265 TRACE("returning %08x\n", hr
);
269 static HRESULT WINAPI
server_SetColumns(IWineRowServer
* iface
, DBORDINAL num_cols
,
270 wine_setcolumns_in
*in_data
, DBSTATUS
*status
)
272 server
*This
= impl_from_IWineRowServer(iface
);
275 DBCOLUMNACCESS
*cols
;
276 IRowChange
*row_change
;
278 TRACE("(%p)->(%d, %p, %p)\n", This
, num_cols
, in_data
, status
);
279 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowChange
, (void**)&row_change
);
280 if(FAILED(hr
)) return hr
;
282 cols
= CoTaskMemAlloc(num_cols
* sizeof(cols
[0]));
284 for(i
= 0; i
< num_cols
; i
++)
286 TRACE("%d:\ttype %04x\n", i
, in_data
[i
].type
);
287 cols
[i
].pData
= CoTaskMemAlloc(db_type_size(in_data
[i
].type
, in_data
[i
].max_len
));
288 memcpy(cols
[i
].pData
, &V_I1(&in_data
[i
].v
), db_type_size(in_data
[i
].type
, in_data
[i
].max_len
));
289 cols
[i
].columnid
= in_data
[i
].columnid
;
290 cols
[i
].cbDataLen
= in_data
[i
].data_len
;
291 cols
[i
].dwStatus
= in_data
[i
].status
;
292 cols
[i
].cbMaxLen
= in_data
[i
].max_len
;
293 cols
[i
].wType
= in_data
[i
].type
;
294 cols
[i
].bPrecision
= in_data
[i
].precision
;
295 cols
[i
].bScale
= in_data
[i
].scale
;
298 hr
= IRowChange_SetColumns(row_change
, num_cols
, cols
);
299 IRowChange_Release(row_change
);
301 for(i
= 0; i
< num_cols
; i
++)
303 CoTaskMemFree(cols
[i
].pData
);
304 status
[i
] = cols
[i
].dwStatus
;
312 static HRESULT WINAPI
server_AddRefRows(IWineRowServer
* iface
, DBCOUNTITEM cRows
,
313 const HROW rghRows
[], DBREFCOUNT rgRefCounts
[],
314 DBROWSTATUS rgRowStatus
[])
316 server
*This
= impl_from_IWineRowServer(iface
);
320 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
322 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
323 if(FAILED(hr
)) return hr
;
325 hr
= IRowset_AddRefRows(rowset
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
327 IRowset_Release(rowset
);
328 TRACE("returning %08x\n", hr
);
332 static HRESULT WINAPI
server_GetData(IWineRowServer
* iface
, HROW hRow
,
333 HACCESSOR hAccessor
, BYTE
*pData
, DWORD size
)
335 server
*This
= impl_from_IWineRowServer(iface
);
339 TRACE("(%p)->(%08lx, %08lx, %p, %d)\n", This
, hRow
, hAccessor
, pData
, size
);
341 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
342 if(FAILED(hr
)) return hr
;
344 hr
= IRowset_GetData(rowset
, hRow
, hAccessor
, pData
);
346 IRowset_Release(rowset
);
347 TRACE("returning %08x\n", hr
);
351 static HRESULT WINAPI
server_GetNextRows(IWineRowServer
* iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
352 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
354 server
*This
= impl_from_IWineRowServer(iface
);
358 TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
360 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
361 if(FAILED(hr
)) return hr
;
365 hr
= IRowset_GetNextRows(rowset
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
366 IRowset_Release(rowset
);
367 TRACE("returning %08x, got %d rows\n", hr
, *pcRowObtained
);
371 static HRESULT WINAPI
server_ReleaseRows(IWineRowServer
* iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
372 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
374 server
*This
= impl_from_IWineRowServer(iface
);
378 TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
380 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowset
, (void**)&rowset
);
381 if(FAILED(hr
)) return hr
;
383 hr
= IRowset_ReleaseRows(rowset
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
384 IRowset_Release(rowset
);
386 TRACE("returning %08x\n", hr
);
390 static HRESULT WINAPI
server_RestartPosition(IWineRowServer
* iface
, HCHAPTER hReserved
)
392 server
*This
= impl_from_IWineRowServer(iface
);
393 FIXME("(%p)->(%08lx): stub\n", This
, hReserved
);
397 static HRESULT WINAPI
server_Compare(IWineRowServer
*iface
, HCHAPTER hReserved
, DBBKMARK cbBookmark1
,
398 const BYTE
*pBookmark1
, DBBKMARK cbBookmark2
, const BYTE
*pBookmark2
,
399 DBCOMPARE
*pComparison
)
401 server
*This
= impl_from_IWineRowServer(iface
);
402 FIXME("(%p): stub\n", This
);
406 static HRESULT WINAPI
server_GetRowsAt(IWineRowServer
*iface
, HWATCHREGION hReserved1
, HCHAPTER hReserved2
,
407 DBBKMARK cbBookmark
, const BYTE
*pBookmark
, DBROWOFFSET lRowsOffset
,
408 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowsObtained
, HROW
**prghRows
)
410 server
*This
= impl_from_IWineRowServer(iface
);
411 IRowsetLocate
*rowsetlocate
;
414 TRACE("(%p)->(%08lx, %08lx, %d, %p, %d, %d, %p, %p\n", This
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
, cRows
,
415 pcRowsObtained
, prghRows
);
419 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowsetLocate
, (void**)&rowsetlocate
);
420 if(FAILED(hr
)) return hr
;
422 hr
= IRowsetLocate_GetRowsAt(rowsetlocate
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
,
423 cRows
, pcRowsObtained
, prghRows
);
424 IRowsetLocate_Release(rowsetlocate
);
426 TRACE("returning %08x\n", hr
);
430 static HRESULT WINAPI
server_GetRowsByBookmark(IWineRowServer
*iface
, HCHAPTER hReserved
, DBCOUNTITEM cRows
,
431 const DBBKMARK rgcbBookmarks
[], const BYTE
* rgpBookmarks
[],
432 HROW rghRows
[], DBROWSTATUS rgRowStatus
[])
434 server
*This
= impl_from_IWineRowServer(iface
);
435 FIXME("(%p): stub\n", This
);
439 static HRESULT WINAPI
server_Hash(IWineRowServer
*iface
, HCHAPTER hReserved
, DBBKMARK cBookmarks
,
440 const DBBKMARK rgcbBookmarks
[], const BYTE
* rgpBookmarks
[],
441 DBHASHVALUE rgHashedValues
[], DBROWSTATUS rgBookmarkStatus
[])
443 server
*This
= impl_from_IWineRowServer(iface
);
444 FIXME("(%p): stub\n", This
);
448 static HRESULT WINAPI
server_GetProperties(IWineRowServer
* iface
, ULONG cPropertyIDSets
,
449 const DBPROPIDSET
*rgPropertyIDSets
, ULONG
*pcPropertySets
,
450 DBPROPSET
**prgPropertySets
)
452 server
*This
= impl_from_IWineRowServer(iface
);
453 IRowsetInfo
*rowsetinfo
;
456 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
458 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IRowsetInfo
, (void**)&rowsetinfo
);
459 if(FAILED(hr
)) return hr
;
461 hr
= IRowsetInfo_GetProperties(rowsetinfo
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
462 IRowsetInfo_Release(rowsetinfo
);
464 TRACE("returning %08x\n", hr
);
468 static HRESULT WINAPI
server_GetReferencedRowset(IWineRowServer
* iface
, DBORDINAL iOrdinal
,
469 REFIID riid
, IUnknown
**ppReferencedRowset
)
471 server
*This
= impl_from_IWineRowServer(iface
);
472 FIXME("(%p): stub\n", This
);
476 static HRESULT WINAPI
server_GetSpecification(IWineRowServer
* iface
, REFIID riid
,
477 IUnknown
**ppSpecification
)
479 server
*This
= impl_from_IWineRowServer(iface
);
480 FIXME("(%p): stub\n", This
);
484 static HRESULT WINAPI
server_AddRefAccessor(IWineRowServer
* iface
, HACCESSOR hAccessor
,
485 DBREFCOUNT
*pcRefCount
)
487 server
*This
= impl_from_IWineRowServer(iface
);
488 FIXME("(%p): stub\n", This
);
492 static HRESULT WINAPI
server_CreateAccessor(IWineRowServer
* iface
, DBACCESSORFLAGS dwAccessorFlags
,
493 DBCOUNTITEM cBindings
, const DBBINDING
*rgBindings
, DBLENGTH cbRowSize
,
494 HACCESSOR
*phAccessor
, DBBINDSTATUS
*rgStatus
)
496 server
*This
= impl_from_IWineRowServer(iface
);
500 TRACE("(%p)->(%08x, %d, %p, %d, %p, %p)\n", This
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, rgStatus
);
502 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IAccessor
, (void**)&accessor
);
503 if(FAILED(hr
)) return hr
;
505 hr
= IAccessor_CreateAccessor(accessor
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, rgStatus
);
506 IAccessor_Release(accessor
);
508 TRACE("returning %08x, accessor %08lx\n", hr
, *phAccessor
);
512 static HRESULT WINAPI
server_GetBindings(IWineRowServer
* iface
, HACCESSOR hAccessor
,
513 DBACCESSORFLAGS
*pdwAccessorFlags
, DBCOUNTITEM
*pcBindings
,
514 DBBINDING
**prgBindings
)
516 server
*This
= impl_from_IWineRowServer(iface
);
520 TRACE("(%p)->(%08lx, %p, %p, %p)\n", This
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
522 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IAccessor
, (void**)&accessor
);
523 if(FAILED(hr
)) return hr
;
525 hr
= IAccessor_GetBindings(accessor
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
526 IAccessor_Release(accessor
);
528 TRACE("returning %08x\n", hr
);
532 static HRESULT WINAPI
server_ReleaseAccessor(IWineRowServer
* iface
, HACCESSOR hAccessor
,
533 DBREFCOUNT
*pcRefCount
)
535 server
*This
= impl_from_IWineRowServer(iface
);
539 TRACE("(%p)->(%08lx, %p)\n", This
, hAccessor
, pcRefCount
);
541 hr
= IUnknown_QueryInterface(This
->inner_unk
, &IID_IAccessor
, (void**)&accessor
);
542 if(FAILED(hr
)) return hr
;
544 hr
= IAccessor_ReleaseAccessor(accessor
, hAccessor
, pcRefCount
);
545 IAccessor_Release(accessor
);
550 static const IWineRowServerVtbl server_vtbl
=
552 server_QueryInterface
,
558 server_GetSourceRowset
,
565 server_RestartPosition
,
568 server_GetRowsByBookmark
,
570 server_GetProperties
,
571 server_GetReferencedRowset
,
572 server_GetSpecification
,
573 server_AddRefAccessor
,
574 server_CreateAccessor
,
576 server_ReleaseAccessor
579 static HRESULT
create_server(IUnknown
*outer
, const CLSID
*class, void **obj
)
582 TRACE("(%p, %s, %p)\n", outer
, debugstr_guid(class), obj
);
586 server
= HeapAlloc(GetProcessHeap(), 0, sizeof(*server
));
587 if(!server
) return E_OUTOFMEMORY
;
589 server
->vtbl
= &server_vtbl
;
591 server
->class = *class;
592 server
->inner_unk
= NULL
;
593 if(IsEqualGUID(class, &CLSID_wine_row_server
))
594 create_row_marshal((IUnknown
*)server
, (void**)&server
->marshal
);
595 else if(IsEqualGUID(class, &CLSID_wine_rowset_server
))
596 create_rowset_marshal((IUnknown
*)server
, (void**)&server
->marshal
);
598 ERR("create_server called with class %s\n", debugstr_guid(class));
604 HRESULT
create_row_server(IUnknown
*outer
, void **obj
)
606 return create_server(outer
, &CLSID_wine_row_server
, obj
);
609 HRESULT
create_rowset_server(IUnknown
*outer
, void **obj
)
611 return create_server(outer
, &CLSID_wine_rowset_server
, obj
);
616 const IRowVtbl
*row_vtbl
;
617 const IRowChangeVtbl
*row_change_vtbl
;
621 IWineRowServer
*server
;
624 static inline row_proxy
*impl_from_IRow(IRow
*iface
)
626 return (row_proxy
*)((char*)iface
- FIELD_OFFSET(row_proxy
, row_vtbl
));
629 static inline row_proxy
*impl_from_IRowChange(IRowChange
*iface
)
631 return (row_proxy
*)((char*)iface
- FIELD_OFFSET(row_proxy
, row_change_vtbl
));
634 static HRESULT WINAPI
row_QueryInterface(IRow
*iface
, REFIID iid
, void **obj
)
636 row_proxy
*This
= impl_from_IRow(iface
);
637 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
639 if(IsEqualIID(iid
, &IID_IUnknown
) ||
640 IsEqualIID(iid
, &IID_IRow
))
642 *obj
= &This
->row_vtbl
;
644 else if(IsEqualIID(iid
, &IID_IRowChange
))
646 *obj
= &This
->row_change_vtbl
;
650 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
651 return E_NOINTERFACE
;
658 static ULONG WINAPI
row_AddRef(IRow
*iface
)
660 row_proxy
*This
= impl_from_IRow(iface
);
661 TRACE("(%p)\n", This
);
663 return InterlockedIncrement(&This
->ref
);
666 static ULONG WINAPI
row_Release(IRow
*iface
)
668 row_proxy
*This
= impl_from_IRow(iface
);
671 TRACE("(%p)\n", This
);
673 ref
= InterlockedDecrement(&This
->ref
);
676 if(This
->server
) IWineRowServer_Release(This
->server
);
677 HeapFree(GetProcessHeap(), 0, This
);
683 static HRESULT WINAPI
row_GetColumns(IRow
* iface
, DBORDINAL cColumns
, DBCOLUMNACCESS rgColumns
[])
685 row_proxy
*This
= impl_from_IRow(iface
);
687 wine_getcolumns_in
*in_data
;
688 wine_getcolumns_out
*out_data
;
691 TRACE("(%p)->(%d, %p)\n", This
, cColumns
, rgColumns
);
693 in_data
= CoTaskMemAlloc(cColumns
* sizeof(in_data
[0]));
694 out_data
= CoTaskMemAlloc(cColumns
* sizeof(out_data
[0]));
696 for(i
= 0; i
< cColumns
; i
++)
698 TRACE("%d:\tdata %p data_len %d status %08x max_len %d type %04x\n", i
, rgColumns
[i
].pData
,
699 rgColumns
[i
].cbDataLen
, rgColumns
[i
].dwStatus
, rgColumns
[i
].cbMaxLen
, rgColumns
[i
].wType
);
700 in_data
[i
].columnid
= rgColumns
[i
].columnid
;
701 in_data
[i
].max_len
= rgColumns
[i
].cbMaxLen
;
702 in_data
[i
].type
= rgColumns
[i
].wType
;
703 in_data
[i
].precision
= rgColumns
[i
].bPrecision
;
704 in_data
[i
].scale
= rgColumns
[i
].bScale
;
707 hr
= IWineRowServer_GetColumns(This
->server
, cColumns
, in_data
, out_data
);
709 for(i
= 0; i
< cColumns
; i
++)
711 rgColumns
[i
].cbDataLen
= out_data
[i
].data_len
;
712 rgColumns
[i
].dwStatus
= out_data
[i
].status
;
713 if(rgColumns
[i
].dwStatus
== DBSTATUS_S_OK
)
714 memcpy(rgColumns
[i
].pData
, &V_I1(&out_data
[i
].v
), out_data
[i
].data_len
);
717 CoTaskMemFree(out_data
);
718 CoTaskMemFree(in_data
);
722 static HRESULT WINAPI
row_GetSourceRowset(IRow
* iface
, REFIID riid
, IUnknown
**ppRowset
,
725 row_proxy
*This
= impl_from_IRow(iface
);
727 FIXME("(%p)->(%s, %p, %p): stub\n", This
, debugstr_guid(riid
), ppRowset
, phRow
);
732 static HRESULT WINAPI
row_Open(IRow
* iface
, IUnknown
*pUnkOuter
,
733 DBID
*pColumnID
, REFGUID rguidColumnType
,
734 DWORD dwBindFlags
, REFIID riid
, IUnknown
**ppUnk
)
736 row_proxy
*This
= impl_from_IRow(iface
);
738 TRACE("(%p)->(%p, %p, %s, %08x, %s, %p)\n", This
, pUnkOuter
, pColumnID
, debugstr_guid(rguidColumnType
),
739 dwBindFlags
, debugstr_guid(riid
), ppUnk
);
742 FIXME("Aggregation not supported\n");
743 return CLASS_E_NOAGGREGATION
;
746 return IWineRowServer_Open(This
->server
, pUnkOuter
, pColumnID
, rguidColumnType
, dwBindFlags
, riid
, ppUnk
);
749 static const IRowVtbl row_vtbl
=
759 static HRESULT WINAPI
row_change_QueryInterface(IRowChange
*iface
, REFIID iid
, void **obj
)
761 row_proxy
*This
= impl_from_IRowChange(iface
);
762 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
765 static ULONG WINAPI
row_change_AddRef(IRowChange
*iface
)
767 row_proxy
*This
= impl_from_IRowChange(iface
);
768 return IUnknown_AddRef((IUnknown
*)This
);
771 static ULONG WINAPI
row_change_Release(IRowChange
*iface
)
773 row_proxy
*This
= impl_from_IRowChange(iface
);
774 return IUnknown_Release((IUnknown
*)This
);
777 static HRESULT WINAPI
row_change_SetColumns(IRowChange
*iface
, DBORDINAL cColumns
,
778 DBCOLUMNACCESS rgColumns
[])
780 row_proxy
*This
= impl_from_IRowChange(iface
);
782 wine_setcolumns_in
*in_data
;
786 TRACE("(%p)->(%d, %p)\n", This
, cColumns
, rgColumns
);
788 in_data
= CoTaskMemAlloc(cColumns
* sizeof(in_data
[0]));
789 status
= CoTaskMemAlloc(cColumns
* sizeof(status
[0]));
791 for(i
= 0; i
< cColumns
; i
++)
793 TRACE("%d: wtype %04x max %08x len %08x\n", i
, rgColumns
[i
].wType
, rgColumns
[i
].cbMaxLen
, rgColumns
[i
].cbDataLen
);
794 V_VT(&in_data
[i
].v
) = rgColumns
[i
].wType
;
795 memcpy(&V_I1(&in_data
[i
].v
), rgColumns
[i
].pData
, db_type_size(rgColumns
[i
].wType
, rgColumns
[i
].cbDataLen
));
796 in_data
[i
].columnid
= rgColumns
[i
].columnid
;
797 in_data
[i
].data_len
= rgColumns
[i
].cbDataLen
;
798 in_data
[i
].status
= rgColumns
[i
].dwStatus
;
799 in_data
[i
].max_len
= rgColumns
[i
].cbMaxLen
;
800 in_data
[i
].type
= rgColumns
[i
].wType
;
801 in_data
[i
].precision
= rgColumns
[i
].bPrecision
;
802 in_data
[i
].scale
= rgColumns
[i
].bScale
;
805 hr
= IWineRowServer_SetColumns(This
->server
, cColumns
, in_data
, status
);
807 for(i
= 0; i
< cColumns
; i
++)
808 rgColumns
[i
].dwStatus
= status
[i
];
810 CoTaskMemFree(status
);
811 CoTaskMemFree(in_data
);
816 static const IRowChangeVtbl row_change_vtbl
=
818 row_change_QueryInterface
,
821 row_change_SetColumns
824 static HRESULT
create_row_proxy(IWineRowServer
*server
, IUnknown
**obj
)
828 TRACE("(%p, %p)\n", server
, obj
);
831 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
832 if(!proxy
) return E_OUTOFMEMORY
;
834 proxy
->row_vtbl
= &row_vtbl
;
835 proxy
->row_change_vtbl
= &row_change_vtbl
;
837 IWineRowServer_AddRef(server
);
838 proxy
->server
= server
;
840 *obj
= (IUnknown
*)&proxy
->row_vtbl
;
841 TRACE("returning %p\n", *obj
);
847 const IRowsetVtbl
*rowset_vtbl
;
848 const IRowsetLocateVtbl
*rowsetlocate_vtbl
;
849 const IRowsetInfoVtbl
*rowsetinfo_vtbl
;
850 const IAccessorVtbl
*accessor_vtbl
;
854 IWineRowServer
*server
;
857 static inline rowset_proxy
*impl_from_IRowset(IRowset
*iface
)
859 return (rowset_proxy
*)((char*)iface
- FIELD_OFFSET(rowset_proxy
, rowset_vtbl
));
862 static inline rowset_proxy
*impl_from_IRowsetLocate(IRowsetLocate
*iface
)
864 return (rowset_proxy
*)((char*)iface
- FIELD_OFFSET(rowset_proxy
, rowsetlocate_vtbl
));
867 static inline rowset_proxy
*impl_from_IRowsetInfo(IRowsetInfo
*iface
)
869 return (rowset_proxy
*)((char*)iface
- FIELD_OFFSET(rowset_proxy
, rowsetinfo_vtbl
));
872 static inline rowset_proxy
*impl_from_IAccessor(IAccessor
*iface
)
874 return (rowset_proxy
*)((char*)iface
- FIELD_OFFSET(rowset_proxy
, accessor_vtbl
));
877 static HRESULT WINAPI
rowset_QueryInterface(IRowset
*iface
, REFIID iid
, void **obj
)
879 rowset_proxy
*This
= impl_from_IRowset(iface
);
880 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
884 if(IsEqualIID(iid
, &IID_IUnknown
) ||
885 IsEqualIID(iid
, &IID_IRowset
))
887 *obj
= &This
->rowset_vtbl
;
889 else if(IsEqualIID(iid
, &IID_IRowsetLocate
))
891 *obj
= &This
->rowsetlocate_vtbl
;
893 else if(IsEqualIID(iid
, &IID_IRowsetInfo
))
895 *obj
= &This
->rowsetinfo_vtbl
;
897 else if(IsEqualIID(iid
, &IID_IAccessor
))
899 *obj
= &This
->accessor_vtbl
;
903 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
904 return E_NOINTERFACE
;
907 IRowset_AddRef(iface
);
911 static ULONG WINAPI
rowset_AddRef(IRowset
*iface
)
913 rowset_proxy
*This
= impl_from_IRowset(iface
);
914 TRACE("(%p)\n", This
);
916 return InterlockedIncrement(&This
->ref
);
919 static ULONG WINAPI
rowset_Release(IRowset
*iface
)
921 rowset_proxy
*This
= impl_from_IRowset(iface
);
924 TRACE("(%p)\n", This
);
926 ref
= InterlockedDecrement(&This
->ref
);
929 if(This
->server
) IWineRowServer_Release(This
->server
);
930 HeapFree(GetProcessHeap(), 0, This
);
936 static HRESULT WINAPI
rowset_AddRefRows(IRowset
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
937 DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
939 rowset_proxy
*This
= impl_from_IRowset(iface
);
941 DBREFCOUNT
*refs
= rgRefCounts
;
942 DBSTATUS
*stats
= rgRowStatus
;
944 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
946 if(!refs
) refs
= CoTaskMemAlloc(cRows
* sizeof(refs
[0]));
947 if(!stats
) stats
= CoTaskMemAlloc(cRows
* sizeof(stats
[0]));
949 hr
= IWineRowServer_AddRefRows(This
->server
, cRows
, rghRows
, refs
, stats
);
951 if(refs
!= rgRefCounts
) CoTaskMemFree(refs
);
952 if(stats
!= rgRowStatus
) CoTaskMemFree(stats
);
957 static HRESULT WINAPI
rowset_GetData(IRowset
*iface
, HROW hRow
, HACCESSOR hAccessor
, void *pData
)
959 rowset_proxy
*This
= impl_from_IRowset(iface
);
962 DBACCESSORFLAGS flags
;
963 DBCOUNTITEM count
, i
;
967 TRACE("(%p)->(%lx, %lx, %p)\n", This
, hRow
, hAccessor
, pData
);
969 hr
= IRowset_QueryInterface(iface
, &IID_IAccessor
, (void**)&accessor
);
970 if(FAILED(hr
)) return hr
;
972 hr
= IAccessor_GetBindings(accessor
, hAccessor
, &flags
, &count
, &bindings
);
973 IAccessor_Release(accessor
);
974 if(FAILED(hr
)) return hr
;
976 TRACE("got %d bindings\n", count
);
977 for(i
= 0; i
< count
; i
++)
979 TRACE("%d\tord %d offs: val %d len %d stat %d, part %x, max len %d type %04x\n",
980 i
, bindings
[i
].iOrdinal
, bindings
[i
].obValue
, bindings
[i
].obLength
, bindings
[i
].obStatus
,
981 bindings
[i
].dwPart
, bindings
[i
].cbMaxLen
, bindings
[i
].wType
);
982 if(bindings
[i
].dwPart
& DBPART_LENGTH
&& bindings
[i
].obLength
>= max_len
)
983 max_len
= bindings
[i
].obLength
+ sizeof(DBLENGTH
);
984 if(bindings
[i
].dwPart
& DBPART_STATUS
&& bindings
[i
].obStatus
>= max_len
)
985 max_len
= bindings
[i
].obStatus
+ sizeof(DWORD
);
986 if(bindings
[i
].dwPart
& DBPART_VALUE
&& bindings
[i
].obValue
>= max_len
)
987 max_len
= bindings
[i
].obValue
+ db_type_size(bindings
[i
].wType
, bindings
[i
].cbMaxLen
);
990 TRACE("max_len %d\n", max_len
);
992 CoTaskMemFree(bindings
);
994 hr
= IWineRowServer_GetData(This
->server
, hRow
, hAccessor
, pData
, max_len
);
999 static HRESULT WINAPI
rowset_GetNextRows(IRowset
*iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
1000 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
1002 rowset_proxy
*This
= impl_from_IRowset(iface
);
1006 TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
1008 hr
= IWineRowServer_GetNextRows(This
->server
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, &rows
);
1011 memcpy(*prghRows
, rows
, *pcRowObtained
* sizeof(rows
[0]));
1012 CoTaskMemFree(rows
);
1020 static HRESULT WINAPI
rowset_ReleaseRows(IRowset
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
1021 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
1023 rowset_proxy
*This
= impl_from_IRowset(iface
);
1025 DBROWOPTIONS
*options
= rgRowOptions
;
1026 DBREFCOUNT
*refs
= rgRefCounts
;
1027 DBROWSTATUS
*status
= rgRowStatus
;
1029 TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
1033 options
= CoTaskMemAlloc(cRows
* sizeof(options
[0]));
1034 memset(options
, 0, cRows
* sizeof(options
[0]));
1036 if(!refs
) refs
= CoTaskMemAlloc(cRows
* sizeof(refs
[0]));
1037 if(!status
) status
= CoTaskMemAlloc(cRows
* sizeof(status
[0]));
1039 hr
= IWineRowServer_ReleaseRows(This
->server
, cRows
, rghRows
, options
, refs
, status
);
1041 if(status
!= rgRowStatus
) CoTaskMemFree(status
);
1042 if(refs
!= rgRefCounts
) CoTaskMemFree(refs
);
1043 if(options
!= rgRowOptions
) CoTaskMemFree(options
);
1048 static HRESULT WINAPI
rowset_RestartPosition(IRowset
* iface
, HCHAPTER hReserved
)
1050 rowset_proxy
*This
= impl_from_IRowset(iface
);
1052 FIXME("(%p)->(%lx): stub\n", This
, hReserved
);
1057 static const IRowsetVtbl rowset_vtbl
=
1059 rowset_QueryInterface
,
1066 rowset_RestartPosition
1069 static HRESULT WINAPI
rowsetlocate_QueryInterface(IRowsetLocate
*iface
, REFIID iid
, void **obj
)
1071 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1072 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
1075 static ULONG WINAPI
rowsetlocate_AddRef(IRowsetLocate
*iface
)
1077 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1078 return IUnknown_AddRef((IUnknown
*)This
);
1081 static ULONG WINAPI
rowsetlocate_Release(IRowsetLocate
*iface
)
1083 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1084 return IUnknown_Release((IUnknown
*)This
);
1087 static HRESULT WINAPI
rowsetlocate_AddRefRows(IRowsetLocate
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
1088 DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
1090 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1091 return IRowset_AddRefRows((IRowset
*)This
, cRows
, rghRows
, rgRefCounts
, rgRowStatus
);
1094 static HRESULT WINAPI
rowsetlocate_GetData(IRowsetLocate
*iface
, HROW hRow
, HACCESSOR hAccessor
, void *pData
)
1096 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1097 return IRowset_GetData((IRowset
*)This
, hRow
, hAccessor
, pData
);
1100 static HRESULT WINAPI
rowsetlocate_GetNextRows(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
1101 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
1103 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1104 return IRowset_GetNextRows((IRowset
*)This
, hReserved
, lRowsOffset
, cRows
, pcRowObtained
, prghRows
);
1107 static HRESULT WINAPI
rowsetlocate_ReleaseRows(IRowsetLocate
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
1108 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
1110 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1111 return IRowset_ReleaseRows((IRowset
*)This
, cRows
, rghRows
, rgRowOptions
, rgRefCounts
, rgRowStatus
);
1114 static HRESULT WINAPI
rowsetlocate_RestartPosition(IRowsetLocate
*iface
, HCHAPTER hReserved
)
1116 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1117 return IRowset_RestartPosition((IRowset
*)This
, hReserved
);
1120 static HRESULT WINAPI
rowsetlocate_Compare(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBBKMARK cbBookmark1
, const BYTE
*pBookmark1
,
1121 DBBKMARK cbBookmark2
, const BYTE
*pBookmark2
, DBCOMPARE
*pComparison
)
1123 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1124 FIXME("(%p)\n", This
);
1128 static HRESULT WINAPI
rowsetlocate_GetRowsAt(IRowsetLocate
*iface
, HWATCHREGION hReserved1
, HCHAPTER hReserved2
, DBBKMARK cbBookmark
,
1129 const BYTE
*pBookmark
, DBROWOFFSET lRowsOffset
, DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowsObtained
,
1132 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1136 TRACE("(%p)->(%08lx, %08lx, %d, %p, %d, %d, %p, %p\n", This
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
, cRows
,
1137 pcRowsObtained
, prghRows
);
1139 hr
= IWineRowServer_GetRowsAt(This
->server
, hReserved1
, hReserved2
, cbBookmark
, pBookmark
, lRowsOffset
, cRows
, pcRowsObtained
, &rows
);
1143 memcpy(*prghRows
, rows
, *pcRowsObtained
* sizeof(rows
[0]));
1144 CoTaskMemFree(rows
);
1152 static HRESULT WINAPI
rowsetlocate_GetRowsByBookmark(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBCOUNTITEM cRows
, const DBBKMARK rgcbBookmarks
[],
1153 const BYTE
* rgpBookmarks
[], HROW rghRows
[], DBROWSTATUS rgRowStatus
[])
1155 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1156 FIXME("(%p)\n", This
);
1160 static HRESULT WINAPI
rowsetlocate_Hash(IRowsetLocate
*iface
, HCHAPTER hReserved
, DBBKMARK cBookmarks
, const DBBKMARK rgcbBookmarks
[],
1161 const BYTE
* rgpBookmarks
[], DBHASHVALUE rgHashedValues
[], DBROWSTATUS rgBookmarkStatus
[])
1163 rowset_proxy
*This
= impl_from_IRowsetLocate(iface
);
1164 FIXME("(%p)\n", This
);
1168 static const IRowsetLocateVtbl rowsetlocate_vtbl
=
1170 rowsetlocate_QueryInterface
,
1171 rowsetlocate_AddRef
,
1172 rowsetlocate_Release
,
1173 rowsetlocate_AddRefRows
,
1174 rowsetlocate_GetData
,
1175 rowsetlocate_GetNextRows
,
1176 rowsetlocate_ReleaseRows
,
1177 rowsetlocate_RestartPosition
,
1178 rowsetlocate_Compare
,
1179 rowsetlocate_GetRowsAt
,
1180 rowsetlocate_GetRowsByBookmark
,
1184 static HRESULT WINAPI
rowsetinfo_QueryInterface(IRowsetInfo
*iface
, REFIID iid
, void **obj
)
1186 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1187 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
1190 static ULONG WINAPI
rowsetinfo_AddRef(IRowsetInfo
*iface
)
1192 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1193 return IUnknown_AddRef((IUnknown
*)This
);
1196 static ULONG WINAPI
rowsetinfo_Release(IRowsetInfo
*iface
)
1198 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1199 return IUnknown_Release((IUnknown
*)This
);
1202 static HRESULT WINAPI
rowsetinfo_GetProperties(IRowsetInfo
*iface
, const ULONG cPropertyIDSets
,
1203 const DBPROPIDSET rgPropertyIDSets
[], ULONG
*pcPropertySets
,
1204 DBPROPSET
**prgPropertySets
)
1206 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1209 TRACE("(%p)->(%d, %p, %p, %p)\n", This
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
1211 hr
= IWineRowServer_GetProperties(This
->server
, cPropertyIDSets
, rgPropertyIDSets
, pcPropertySets
, prgPropertySets
);
1216 static HRESULT WINAPI
rowsetinfo_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL iOrdinal
, REFIID riid
,
1217 IUnknown
**ppReferencedRowset
)
1219 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1220 FIXME("(%p)\n", This
);
1224 static HRESULT WINAPI
rowsetinfo_GetSpecification(IRowsetInfo
*iface
, REFIID riid
, IUnknown
**ppSpecification
)
1226 rowset_proxy
*This
= impl_from_IRowsetInfo(iface
);
1227 FIXME("(%p)\n", This
);
1231 static const IRowsetInfoVtbl rowsetinfo_vtbl
=
1233 rowsetinfo_QueryInterface
,
1236 rowsetinfo_GetProperties
,
1237 rowsetinfo_GetReferencedRowset
,
1238 rowsetinfo_GetSpecification
1241 static HRESULT WINAPI
accessor_QueryInterface(IAccessor
*iface
, REFIID iid
, void **obj
)
1243 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1244 return IUnknown_QueryInterface((IUnknown
*)This
, iid
, obj
);
1247 static ULONG WINAPI
accessor_AddRef(IAccessor
*iface
)
1249 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1250 return IUnknown_AddRef((IUnknown
*)This
);
1253 static ULONG WINAPI
accessor_Release(IAccessor
*iface
)
1255 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1256 return IUnknown_Release((IUnknown
*)This
);
1259 static HRESULT WINAPI
accessor_AddRefAccessor(IAccessor
*iface
, HACCESSOR hAccessor
, DBREFCOUNT
*pcRefCount
)
1261 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1262 FIXME("(%p)\n", This
);
1266 static HRESULT WINAPI
accessor_CreateAccessor(IAccessor
*iface
, DBACCESSORFLAGS dwAccessorFlags
, DBCOUNTITEM cBindings
,
1267 const DBBINDING rgBindings
[], DBLENGTH cbRowSize
, HACCESSOR
*phAccessor
,
1268 DBBINDSTATUS rgStatus
[])
1270 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1272 DBBINDSTATUS
*status
;
1274 TRACE("(%p)->(%08x, %d, %p, %d, %p, %p)\n", This
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, rgStatus
);
1276 if(!rgStatus
) status
= CoTaskMemAlloc(cBindings
* sizeof(status
[0]));
1277 else status
= rgStatus
;
1279 hr
= IWineRowServer_CreateAccessor(This
->server
, dwAccessorFlags
, cBindings
, rgBindings
, cbRowSize
, phAccessor
, status
);
1281 if(!rgStatus
) CoTaskMemFree(status
);
1286 static HRESULT WINAPI
accessor_GetBindings(IAccessor
*iface
, HACCESSOR hAccessor
, DBACCESSORFLAGS
*pdwAccessorFlags
,
1287 DBCOUNTITEM
*pcBindings
, DBBINDING
**prgBindings
)
1289 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1292 TRACE("(%p)->(%08lx, %p, %p, %p)\n", This
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
1294 hr
= IWineRowServer_GetBindings(This
->server
, hAccessor
, pdwAccessorFlags
, pcBindings
, prgBindings
);
1299 static HRESULT WINAPI
accessor_ReleaseAccessor(IAccessor
*iface
, HACCESSOR hAccessor
, DBREFCOUNT
*pcRefCount
)
1301 rowset_proxy
*This
= impl_from_IAccessor(iface
);
1305 TRACE("(%p)->(%08lx, %p)\n", This
, hAccessor
, pcRefCount
);
1307 hr
= IWineRowServer_ReleaseAccessor(This
->server
, hAccessor
, &ref
);
1308 if(pcRefCount
) *pcRefCount
= ref
;
1312 static const IAccessorVtbl accessor_vtbl
=
1314 accessor_QueryInterface
,
1317 accessor_AddRefAccessor
,
1318 accessor_CreateAccessor
,
1319 accessor_GetBindings
,
1320 accessor_ReleaseAccessor
1323 HRESULT
create_rowset_proxy(IWineRowServer
*server
, IUnknown
**obj
)
1325 rowset_proxy
*proxy
;
1327 TRACE("(%p, %p)\n", server
, obj
);
1330 proxy
= HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy
));
1331 if(!proxy
) return E_OUTOFMEMORY
;
1333 proxy
->rowset_vtbl
= &rowset_vtbl
;
1334 proxy
->rowsetlocate_vtbl
= &rowsetlocate_vtbl
;
1335 proxy
->rowsetinfo_vtbl
= &rowsetinfo_vtbl
;
1336 proxy
->accessor_vtbl
= &accessor_vtbl
;
1338 IWineRowServer_AddRef(server
);
1339 proxy
->server
= server
;
1341 *obj
= (IUnknown
*)&proxy
->rowset_vtbl
;
1342 TRACE("returning %p\n", *obj
);
1346 static HRESULT
create_proxy(IWineRowServer
*server
, const CLSID
*class, IUnknown
**obj
)
1350 if(IsEqualGUID(class, &CLSID_wine_row_proxy
))
1351 return create_row_proxy(server
, obj
);
1352 else if(IsEqualGUID(class, &CLSID_wine_rowset_proxy
))
1353 return create_rowset_proxy(server
, obj
);
1355 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
1363 const IMarshalVtbl
*marshal_vtbl
;
1366 CLSID unmarshal_class
;
1370 static inline marshal
*impl_from_IMarshal(IMarshal
*iface
)
1372 return (marshal
*)((char*)iface
- FIELD_OFFSET(marshal
, marshal_vtbl
));
1375 static HRESULT WINAPI
marshal_QueryInterface(IMarshal
*iface
, REFIID iid
, void **obj
)
1377 marshal
*This
= impl_from_IMarshal(iface
);
1378 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(iid
), obj
);
1380 if(IsEqualIID(iid
, &IID_IUnknown
) ||
1381 IsEqualIID(iid
, &IID_IMarshal
))
1387 FIXME("interface %s not implemented\n", debugstr_guid(iid
));
1389 return E_NOINTERFACE
;
1392 IMarshal_AddRef(iface
);
1396 static ULONG WINAPI
marshal_AddRef(IMarshal
*iface
)
1398 marshal
*This
= impl_from_IMarshal(iface
);
1399 TRACE("(%p)\n", This
);
1400 return InterlockedIncrement(&This
->ref
);
1403 static ULONG WINAPI
marshal_Release(IMarshal
*iface
)
1405 marshal
*This
= impl_from_IMarshal(iface
);
1408 TRACE("(%p)\n", This
);
1410 ref
= InterlockedDecrement(&This
->ref
);
1413 HeapFree(GetProcessHeap(), 0, This
);
1419 static HRESULT WINAPI
marshal_GetUnmarshalClass(IMarshal
*iface
, REFIID iid
, void *obj
,
1420 DWORD dwDestContext
, void *pvDestContext
,
1421 DWORD mshlflags
, CLSID
*clsid
)
1423 marshal
*This
= impl_from_IMarshal(iface
);
1424 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This
, debugstr_guid(iid
), obj
, dwDestContext
,
1425 pvDestContext
, mshlflags
, clsid
);
1427 *clsid
= This
->unmarshal_class
;
1431 static HRESULT WINAPI
marshal_GetMarshalSizeMax(IMarshal
*iface
, REFIID iid
, void *obj
,
1432 DWORD dwDestContext
, void *pvDestContext
,
1433 DWORD mshlflags
, DWORD
*size
)
1435 marshal
*This
= impl_from_IMarshal(iface
);
1436 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This
, debugstr_guid(iid
), obj
, dwDestContext
,
1437 pvDestContext
, mshlflags
, size
);
1439 return CoGetMarshalSizeMax(size
, &IID_IWineRowServer
, This
->outer
, dwDestContext
, pvDestContext
,
1443 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
1444 void *obj
, DWORD dwDestContext
, void *pvDestContext
,
1447 marshal
*This
= impl_from_IMarshal(iface
);
1448 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This
, stream
, debugstr_guid(iid
), obj
, dwDestContext
,
1449 pvDestContext
, mshlflags
);
1451 return CoMarshalInterface(stream
, &IID_IWineRowServer
, This
->outer
, dwDestContext
, pvDestContext
, mshlflags
);
1454 static HRESULT WINAPI
marshal_UnmarshalInterface(IMarshal
*iface
, IStream
*stream
,
1455 REFIID iid
, void **obj
)
1457 marshal
*This
= impl_from_IMarshal(iface
);
1459 IWineRowServer
*server
;
1462 TRACE("(%p)->(%p, %s, %p)\n", This
, stream
, debugstr_guid(iid
), obj
);
1465 hr
= CoUnmarshalInterface(stream
, &IID_IWineRowServer
, (void**)&server
);
1468 hr
= create_proxy(server
, &This
->unmarshal_class
, &proxy
);
1471 hr
= IUnknown_QueryInterface(proxy
, iid
, obj
);
1472 IUnknown_Release(proxy
);
1474 IWineRowServer_Release(server
);
1477 TRACE("returning %p\n", *obj
);
1481 static HRESULT WINAPI
marshal_ReleaseMarshalData(IMarshal
*iface
, IStream
*stream
)
1483 marshal
*This
= impl_from_IMarshal(iface
);
1484 TRACE("(%p)->(%p)\n", This
, stream
);
1485 return CoReleaseMarshalData(stream
);
1488 static HRESULT WINAPI
marshal_DisconnectObject(IMarshal
*iface
, DWORD dwReserved
)
1490 marshal
*This
= impl_from_IMarshal(iface
);
1491 FIXME("(%p)->(%08x)\n", This
, dwReserved
);
1496 static const IMarshalVtbl marshal_vtbl
=
1498 marshal_QueryInterface
,
1501 marshal_GetUnmarshalClass
,
1502 marshal_GetMarshalSizeMax
,
1503 marshal_MarshalInterface
,
1504 marshal_UnmarshalInterface
,
1505 marshal_ReleaseMarshalData
,
1506 marshal_DisconnectObject
1509 static HRESULT
create_marshal(IUnknown
*outer
, const CLSID
*class, void **obj
)
1513 TRACE("(%p, %p)\n", outer
, obj
);
1516 marshal
= HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal
));
1517 if(!marshal
) return E_OUTOFMEMORY
;
1519 marshal
->unmarshal_class
= *class;
1520 marshal
->outer
= outer
; /* don't ref outer unk */
1521 marshal
->marshal_vtbl
= &marshal_vtbl
;
1524 *obj
= &marshal
->marshal_vtbl
;
1525 TRACE("returning %p\n", *obj
);
1529 HRESULT
create_row_marshal(IUnknown
*outer
, void **obj
)
1531 TRACE("(%p, %p)\n", outer
, obj
);
1532 return create_marshal(outer
, &CLSID_wine_row_proxy
, obj
);
1535 HRESULT
create_rowset_marshal(IUnknown
*outer
, void **obj
)
1537 TRACE("(%p, %p)\n", outer
, obj
);
1538 return create_marshal(outer
, &CLSID_wine_rowset_proxy
, obj
);