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 HRESULT WINAPI server_GetProperties(IWineRowServer* iface, ULONG cPropertyIDSets,
350 const DBPROPIDSET *rgPropertyIDSets, ULONG *pcPropertySets,
351 DBPROPSET **prgPropertySets)
353 server *This = impl_from_IWineRowServer(iface);
354 IRowsetInfo *rowsetinfo;
357 TRACE("(%p)->(%d, %p, %p, %p)\n", This, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
359 hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowsetInfo, (void**)&rowsetinfo);
360 if(FAILED(hr)) return hr;
362 hr = IRowsetInfo_GetProperties(rowsetinfo, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
363 IRowsetInfo_Release(rowsetinfo);
365 TRACE("returning %08x\n", hr);
369 static HRESULT WINAPI server_GetReferencedRowset(IWineRowServer* iface, DBORDINAL iOrdinal,
370 REFIID riid, IUnknown **ppReferencedRowset)
372 server *This = impl_from_IWineRowServer(iface);
373 FIXME("(%p): stub\n", This);
377 static HRESULT WINAPI server_GetSpecification(IWineRowServer* iface, REFIID riid,
378 IUnknown **ppSpecification)
380 server *This = impl_from_IWineRowServer(iface);
381 FIXME("(%p): stub\n", This);
385 static HRESULT WINAPI server_AddRefAccessor(IWineRowServer* iface, HACCESSOR hAccessor,
386 DBREFCOUNT *pcRefCount)
388 server *This = impl_from_IWineRowServer(iface);
389 FIXME("(%p): stub\n", This);
393 static HRESULT WINAPI server_CreateAccessor(IWineRowServer* iface, DBACCESSORFLAGS dwAccessorFlags,
394 DBCOUNTITEM cBindings, const DBBINDING *rgBindings, DBLENGTH cbRowSize,
395 HACCESSOR *phAccessor, DBBINDSTATUS *rgStatus)
397 server *This = impl_from_IWineRowServer(iface);
401 TRACE("(%p)->(%08x, %d, %p, %d, %p, %p)\n", This, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, rgStatus);
403 hr = IUnknown_QueryInterface(This->inner_unk, &IID_IAccessor, (void**)&accessor);
404 if(FAILED(hr)) return hr;
406 hr = IAccessor_CreateAccessor(accessor, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, rgStatus);
407 IAccessor_Release(accessor);
409 TRACE("returning %08x, accessor %08lx\n", hr, *phAccessor);
413 static HRESULT WINAPI server_GetBindings(IWineRowServer* iface, HACCESSOR hAccessor,
414 DBACCESSORFLAGS *pdwAccessorFlags, DBCOUNTITEM *pcBindings,
415 DBBINDING **prgBindings)
417 server *This = impl_from_IWineRowServer(iface);
421 TRACE("(%p)->(%08lx, %p, %p, %p)\n", This, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);
423 hr = IUnknown_QueryInterface(This->inner_unk, &IID_IAccessor, (void**)&accessor);
424 if(FAILED(hr)) return hr;
426 hr = IAccessor_GetBindings(accessor, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);
427 IAccessor_Release(accessor);
429 TRACE("returning %08x\n", hr);
433 static HRESULT WINAPI server_ReleaseAccessor(IWineRowServer* iface, HACCESSOR hAccessor,
434 DBREFCOUNT *pcRefCount)
436 server *This = impl_from_IWineRowServer(iface);
440 TRACE("(%p)->(%08lx, %p)\n", This, hAccessor, pcRefCount);
442 hr = IUnknown_QueryInterface(This->inner_unk, &IID_IAccessor, (void**)&accessor);
443 if(FAILED(hr)) return hr;
445 hr = IAccessor_ReleaseAccessor(accessor, hAccessor, pcRefCount);
446 IAccessor_Release(accessor);
451 static const IWineRowServerVtbl server_vtbl =
453 server_QueryInterface,
459 server_GetSourceRowset,
466 server_RestartPosition,
469 server_GetRowsByBookmark,
471 server_GetProperties,
472 server_GetReferencedRowset,
473 server_GetSpecification,
474 server_AddRefAccessor,
475 server_CreateAccessor,
477 server_ReleaseAccessor
480 static HRESULT create_server(IUnknown *outer, const CLSID *class, void **obj)
483 TRACE("(%p, %s, %p)\n", outer, debugstr_guid(class), obj);
487 server = HeapAlloc(GetProcessHeap(), 0, sizeof(*server));
488 if(!server) return E_OUTOFMEMORY;
490 server->vtbl = &server_vtbl;
492 server->class = *class;
493 server->inner_unk = NULL;
494 if(IsEqualGUID(class, &CLSID_wine_row_server))
495 create_row_marshal((IUnknown*)server, (void**)&server->marshal);
496 else if(IsEqualGUID(class, &CLSID_wine_rowset_server))
497 create_rowset_marshal((IUnknown*)server, (void**)&server->marshal);
499 ERR("create_server called with class %s\n", debugstr_guid(class));
505 HRESULT create_row_server(IUnknown *outer, void **obj)
507 return create_server(outer, &CLSID_wine_row_server, obj);
510 HRESULT create_rowset_server(IUnknown *outer, void **obj)
512 return create_server(outer, &CLSID_wine_rowset_server, obj);
517 const IRowVtbl *row_vtbl;
518 const IRowChangeVtbl *row_change_vtbl;
522 IWineRowServer *server;
525 static inline row_proxy *impl_from_IRow(IRow *iface)
527 return (row_proxy *)((char*)iface - FIELD_OFFSET(row_proxy, row_vtbl));
530 static inline row_proxy *impl_from_IRowChange(IRowChange *iface)
532 return (row_proxy *)((char*)iface - FIELD_OFFSET(row_proxy, row_change_vtbl));
535 static HRESULT WINAPI row_QueryInterface(IRow *iface, REFIID iid, void **obj)
537 row_proxy *This = impl_from_IRow(iface);
538 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
540 if(IsEqualIID(iid, &IID_IUnknown) ||
541 IsEqualIID(iid, &IID_IRow))
543 *obj = &This->row_vtbl;
545 else if(IsEqualIID(iid, &IID_IRowChange))
547 *obj = &This->row_change_vtbl;
551 FIXME("interface %s not implemented\n", debugstr_guid(iid));
552 return E_NOINTERFACE;
559 static ULONG WINAPI row_AddRef(IRow *iface)
561 row_proxy *This = impl_from_IRow(iface);
562 TRACE("(%p)\n", This);
564 return InterlockedIncrement(&This->ref);
567 static ULONG WINAPI row_Release(IRow *iface)
569 row_proxy *This = impl_from_IRow(iface);
572 TRACE("(%p)\n", This);
574 ref = InterlockedDecrement(&This->ref);
577 if(This->server) IWineRowServer_Release(This->server);
578 HeapFree(GetProcessHeap(), 0, This);
584 static HRESULT WINAPI row_GetColumns(IRow* iface, DBORDINAL cColumns, DBCOLUMNACCESS rgColumns[])
586 row_proxy *This = impl_from_IRow(iface);
588 wine_getcolumns_in *in_data;
589 wine_getcolumns_out *out_data;
592 TRACE("(%p)->(%d, %p)\n", This, cColumns, rgColumns);
594 in_data = CoTaskMemAlloc(cColumns * sizeof(in_data[0]));
595 out_data = CoTaskMemAlloc(cColumns * sizeof(out_data[0]));
597 for(i = 0; i < cColumns; i++)
599 TRACE("%d:\tdata %p data_len %d status %08x max_len %d type %04x\n", i, rgColumns[i].pData,
600 rgColumns[i].cbDataLen, rgColumns[i].dwStatus, rgColumns[i].cbMaxLen, rgColumns[i].wType);
601 in_data[i].columnid = rgColumns[i].columnid;
602 in_data[i].max_len = rgColumns[i].cbMaxLen;
603 in_data[i].type = rgColumns[i].wType;
604 in_data[i].precision = rgColumns[i].bPrecision;
605 in_data[i].scale = rgColumns[i].bScale;
608 hr = IWineRowServer_GetColumns(This->server, cColumns, in_data, out_data);
610 for(i = 0; i < cColumns; i++)
612 rgColumns[i].cbDataLen = out_data[i].data_len;
613 rgColumns[i].dwStatus = out_data[i].status;
614 if(rgColumns[i].dwStatus == DBSTATUS_S_OK)
615 memcpy(rgColumns[i].pData, &V_I1(&out_data[i].v), out_data[i].data_len);
618 CoTaskMemFree(out_data);
619 CoTaskMemFree(in_data);
623 static HRESULT WINAPI row_GetSourceRowset(IRow* iface, REFIID riid, IUnknown **ppRowset,
626 row_proxy *This = impl_from_IRow(iface);
628 FIXME("(%p)->(%s, %p, %p): stub\n", This, debugstr_guid(riid), ppRowset, phRow);
633 static HRESULT WINAPI row_Open(IRow* iface, IUnknown *pUnkOuter,
634 DBID *pColumnID, REFGUID rguidColumnType,
635 DWORD dwBindFlags, REFIID riid, IUnknown **ppUnk)
637 row_proxy *This = impl_from_IRow(iface);
639 FIXME("(%p)->(%p, %p, %s, %08x, %s, %p): stub\n", This, pUnkOuter, pColumnID, debugstr_guid(rguidColumnType),
640 dwBindFlags, debugstr_guid(riid), ppUnk);
645 static const IRowVtbl row_vtbl =
655 static HRESULT WINAPI row_change_QueryInterface(IRowChange *iface, REFIID iid, void **obj)
657 row_proxy *This = impl_from_IRowChange(iface);
658 return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
661 static ULONG WINAPI row_change_AddRef(IRowChange *iface)
663 row_proxy *This = impl_from_IRowChange(iface);
664 return IUnknown_AddRef((IUnknown*)This);
667 static ULONG WINAPI row_change_Release(IRowChange *iface)
669 row_proxy *This = impl_from_IRowChange(iface);
670 return IUnknown_Release((IUnknown*)This);
673 static HRESULT WINAPI row_change_SetColumns(IRowChange *iface, DBORDINAL cColumns,
674 DBCOLUMNACCESS rgColumns[])
676 row_proxy *This = impl_from_IRowChange(iface);
677 FIXME("(%p)->(%d, %p)\n", This, cColumns, rgColumns);
681 static const IRowChangeVtbl row_change_vtbl =
683 row_change_QueryInterface,
686 row_change_SetColumns
689 static HRESULT create_row_proxy(IWineRowServer *server, IUnknown **obj)
693 TRACE("(%p, %p)\n", server, obj);
696 proxy = HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy));
697 if(!proxy) return E_OUTOFMEMORY;
699 proxy->row_vtbl = &row_vtbl;
700 proxy->row_change_vtbl = &row_change_vtbl;
702 IWineRowServer_AddRef(server);
703 proxy->server = server;
705 *obj = (IUnknown*)&proxy->row_vtbl;
706 TRACE("returing %p\n", *obj);
712 const IRowsetVtbl *rowset_vtbl;
713 const IRowsetLocateVtbl *rowsetlocate_vtbl;
714 const IRowsetInfoVtbl *rowsetinfo_vtbl;
715 const IAccessorVtbl *accessor_vtbl;
719 IWineRowServer *server;
722 static inline rowset_proxy *impl_from_IRowset(IRowset *iface)
724 return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowset_vtbl));
727 static inline rowset_proxy *impl_from_IRowsetLocate(IRowsetLocate *iface)
729 return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowsetlocate_vtbl));
732 static inline rowset_proxy *impl_from_IRowsetInfo(IRowsetInfo *iface)
734 return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowsetinfo_vtbl));
737 static inline rowset_proxy *impl_from_IAccessor(IAccessor *iface)
739 return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, accessor_vtbl));
742 static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID iid, void **obj)
744 rowset_proxy *This = impl_from_IRowset(iface);
745 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
749 if(IsEqualIID(iid, &IID_IUnknown) ||
750 IsEqualIID(iid, &IID_IRowset))
752 *obj = &This->rowset_vtbl;
754 else if(IsEqualIID(iid, &IID_IRowsetLocate))
756 *obj = &This->rowsetlocate_vtbl;
758 else if(IsEqualIID(iid, &IID_IRowsetInfo))
760 *obj = &This->rowsetinfo_vtbl;
762 else if(IsEqualIID(iid, &IID_IAccessor))
764 *obj = &This->accessor_vtbl;
768 FIXME("interface %s not implemented\n", debugstr_guid(iid));
769 return E_NOINTERFACE;
772 IRowset_AddRef(iface);
776 static ULONG WINAPI rowset_AddRef(IRowset *iface)
778 rowset_proxy *This = impl_from_IRowset(iface);
779 TRACE("(%p)\n", This);
781 return InterlockedIncrement(&This->ref);
784 static ULONG WINAPI rowset_Release(IRowset *iface)
786 rowset_proxy *This = impl_from_IRowset(iface);
789 TRACE("(%p)\n", This);
791 ref = InterlockedDecrement(&This->ref);
794 if(This->server) IWineRowServer_Release(This->server);
795 HeapFree(GetProcessHeap(), 0, This);
801 static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
802 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
804 rowset_proxy *This = impl_from_IRowset(iface);
806 DBREFCOUNT *refs = rgRefCounts;
807 DBSTATUS *stats = rgRowStatus;
809 TRACE("(%p)->(%d, %p, %p, %p)\n", This, cRows, rghRows, rgRefCounts, rgRowStatus);
811 if(!refs) refs = CoTaskMemAlloc(cRows * sizeof(refs[0]));
812 if(!stats) stats = CoTaskMemAlloc(cRows * sizeof(stats[0]));
814 hr = IWineRowServer_AddRefRows(This->server, cRows, rghRows, refs, stats);
816 if(refs != rgRefCounts) CoTaskMemFree(refs);
817 if(stats != rgRowStatus) CoTaskMemFree(stats);
822 static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
824 rowset_proxy *This = impl_from_IRowset(iface);
826 FIXME("(%p)->(%lx, %lx, %p): stub\n", This, hRow, hAccessor, pData);
831 static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
832 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
834 rowset_proxy *This = impl_from_IRowset(iface);
838 TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);
840 hr = IWineRowServer_GetNextRows(This->server, hReserved, lRowsOffset, cRows, pcRowObtained, &rows);
843 memcpy(*prghRows, rows, *pcRowObtained * sizeof(rows[0]));
852 static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
853 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
855 rowset_proxy *This = impl_from_IRowset(iface);
857 DBROWOPTIONS *options = rgRowOptions;
858 DBREFCOUNT *refs = rgRefCounts;
859 DBROWSTATUS *status = rgRowStatus;
861 TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);
865 options = CoTaskMemAlloc(cRows * sizeof(options[0]));
866 memset(options, 0, cRows * sizeof(options[0]));
868 if(!refs) refs = CoTaskMemAlloc(cRows * sizeof(refs[0]));
869 if(!status) status = CoTaskMemAlloc(cRows * sizeof(status[0]));
871 hr = IWineRowServer_ReleaseRows(This->server, cRows, rghRows, options, refs, status);
873 if(status != rgRowStatus) CoTaskMemFree(status);
874 if(refs != rgRefCounts) CoTaskMemFree(refs);
875 if(options != rgRowOptions) CoTaskMemFree(options);
880 static HRESULT WINAPI rowset_RestartPosition(IRowset* iface, HCHAPTER hReserved)
882 rowset_proxy *This = impl_from_IRowset(iface);
884 FIXME("(%p)->(%lx): stub\n", This, hReserved);
889 static const IRowsetVtbl rowset_vtbl =
891 rowset_QueryInterface,
898 rowset_RestartPosition
901 static HRESULT WINAPI rowsetlocate_QueryInterface(IRowsetLocate *iface, REFIID iid, void **obj)
903 rowset_proxy *This = impl_from_IRowsetLocate(iface);
904 return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
907 static ULONG WINAPI rowsetlocate_AddRef(IRowsetLocate *iface)
909 rowset_proxy *This = impl_from_IRowsetLocate(iface);
910 return IUnknown_AddRef((IUnknown *)This);
913 static ULONG WINAPI rowsetlocate_Release(IRowsetLocate *iface)
915 rowset_proxy *This = impl_from_IRowsetLocate(iface);
916 return IUnknown_Release((IUnknown *)This);
919 static HRESULT WINAPI rowsetlocate_AddRefRows(IRowsetLocate *iface, DBCOUNTITEM cRows, const HROW rghRows[],
920 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
922 rowset_proxy *This = impl_from_IRowsetLocate(iface);
923 return IRowset_AddRefRows((IRowset*)This, cRows, rghRows, rgRefCounts, rgRowStatus);
926 static HRESULT WINAPI rowsetlocate_GetData(IRowsetLocate *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
928 rowset_proxy *This = impl_from_IRowsetLocate(iface);
929 return IRowset_GetData((IRowset*)This, hRow, hAccessor, pData);
932 static HRESULT WINAPI rowsetlocate_GetNextRows(IRowsetLocate *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
933 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
935 rowset_proxy *This = impl_from_IRowsetLocate(iface);
936 return IRowset_GetNextRows((IRowset*)This, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);
939 static HRESULT WINAPI rowsetlocate_ReleaseRows(IRowsetLocate *iface, DBCOUNTITEM cRows, const HROW rghRows[],
940 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
942 rowset_proxy *This = impl_from_IRowsetLocate(iface);
943 return IRowset_ReleaseRows((IRowset*)This, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);
946 static HRESULT WINAPI rowsetlocate_RestartPosition(IRowsetLocate *iface, HCHAPTER hReserved)
948 rowset_proxy *This = impl_from_IRowsetLocate(iface);
949 return IRowset_RestartPosition((IRowset*)This, hReserved);
952 static HRESULT WINAPI rowsetlocate_Compare(IRowsetLocate *iface, HCHAPTER hReserved, DBBKMARK cbBookmark1, const BYTE *pBookmark1,
953 DBBKMARK cbBookmark2, const BYTE *pBookmark2, DBCOMPARE *pComparison)
955 rowset_proxy *This = impl_from_IRowsetLocate(iface);
956 FIXME("(%p)\n", This);
960 static HRESULT WINAPI rowsetlocate_GetRowsAt(IRowsetLocate *iface, HWATCHREGION hReserved1, HCHAPTER hReserved2, DBBKMARK cbBookmark,
961 const BYTE *pBookmark, DBROWOFFSET lRowsOffset, DBROWCOUNT cRows, DBCOUNTITEM *pcRowsObtained,
964 rowset_proxy *This = impl_from_IRowsetLocate(iface);
965 FIXME("(%p)\n", This);
969 static HRESULT WINAPI rowsetlocate_GetRowsByBookmark(IRowsetLocate *iface, HCHAPTER hReserved, DBCOUNTITEM cRows, const DBBKMARK rgcbBookmarks[],
970 const BYTE * rgpBookmarks[], HROW rghRows[], DBROWSTATUS rgRowStatus[])
972 rowset_proxy *This = impl_from_IRowsetLocate(iface);
973 FIXME("(%p)\n", This);
977 static HRESULT WINAPI rowsetlocate_Hash(IRowsetLocate *iface, HCHAPTER hReserved, DBBKMARK cBookmarks, const DBBKMARK rgcbBookmarks[],
978 const BYTE * rgpBookmarks[], DBHASHVALUE rgHashedValues[], DBROWSTATUS rgBookmarkStatus[])
980 rowset_proxy *This = impl_from_IRowsetLocate(iface);
981 FIXME("(%p)\n", This);
985 static const IRowsetLocateVtbl rowsetlocate_vtbl =
987 rowsetlocate_QueryInterface,
989 rowsetlocate_Release,
990 rowsetlocate_AddRefRows,
991 rowsetlocate_GetData,
992 rowsetlocate_GetNextRows,
993 rowsetlocate_ReleaseRows,
994 rowsetlocate_RestartPosition,
995 rowsetlocate_Compare,
996 rowsetlocate_GetRowsAt,
997 rowsetlocate_GetRowsByBookmark,
1001 static HRESULT WINAPI rowsetinfo_QueryInterface(IRowsetInfo *iface, REFIID iid, void **obj)
1003 rowset_proxy *This = impl_from_IRowsetInfo(iface);
1004 return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
1007 static ULONG WINAPI rowsetinfo_AddRef(IRowsetInfo *iface)
1009 rowset_proxy *This = impl_from_IRowsetInfo(iface);
1010 return IUnknown_AddRef((IUnknown *)This);
1013 static ULONG WINAPI rowsetinfo_Release(IRowsetInfo *iface)
1015 rowset_proxy *This = impl_from_IRowsetInfo(iface);
1016 return IUnknown_Release((IUnknown *)This);
1019 static HRESULT WINAPI rowsetinfo_GetProperties(IRowsetInfo *iface, const ULONG cPropertyIDSets,
1020 const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets,
1021 DBPROPSET **prgPropertySets)
1023 rowset_proxy *This = impl_from_IRowsetInfo(iface);
1026 TRACE("(%p)->(%d, %p, %p, %p)\n", This, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
1028 hr = IWineRowServer_GetProperties(This->server, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
1033 static HRESULT WINAPI rowsetinfo_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL iOrdinal, REFIID riid,
1034 IUnknown **ppReferencedRowset)
1036 rowset_proxy *This = impl_from_IRowsetInfo(iface);
1037 FIXME("(%p)\n", This);
1041 static HRESULT WINAPI rowsetinfo_GetSpecification(IRowsetInfo *iface, REFIID riid, IUnknown **ppSpecification)
1043 rowset_proxy *This = impl_from_IRowsetInfo(iface);
1044 FIXME("(%p)\n", This);
1048 static const IRowsetInfoVtbl rowsetinfo_vtbl =
1050 rowsetinfo_QueryInterface,
1053 rowsetinfo_GetProperties,
1054 rowsetinfo_GetReferencedRowset,
1055 rowsetinfo_GetSpecification
1058 static HRESULT WINAPI accessor_QueryInterface(IAccessor *iface, REFIID iid, void **obj)
1060 rowset_proxy *This = impl_from_IAccessor(iface);
1061 return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
1064 static ULONG WINAPI accessor_AddRef(IAccessor *iface)
1066 rowset_proxy *This = impl_from_IAccessor(iface);
1067 return IUnknown_AddRef((IUnknown *)This);
1070 static ULONG WINAPI accessor_Release(IAccessor *iface)
1072 rowset_proxy *This = impl_from_IAccessor(iface);
1073 return IUnknown_Release((IUnknown *)This);
1076 static HRESULT WINAPI accessor_AddRefAccessor(IAccessor *iface, HACCESSOR hAccessor, DBREFCOUNT *pcRefCount)
1078 rowset_proxy *This = impl_from_IAccessor(iface);
1079 FIXME("(%p)\n", This);
1083 static HRESULT WINAPI accessor_CreateAccessor(IAccessor *iface, DBACCESSORFLAGS dwAccessorFlags, DBCOUNTITEM cBindings,
1084 const DBBINDING rgBindings[], DBLENGTH cbRowSize, HACCESSOR *phAccessor,
1085 DBBINDSTATUS rgStatus[])
1087 rowset_proxy *This = impl_from_IAccessor(iface);
1089 DBBINDSTATUS *status;
1091 TRACE("(%p)->(%08x, %d, %p, %d, %p, %p)\n", This, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, rgStatus);
1093 if(!rgStatus) status = CoTaskMemAlloc(cBindings * sizeof(status[0]));
1094 else status = rgStatus;
1096 hr = IWineRowServer_CreateAccessor(This->server, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, status);
1098 if(!rgStatus) CoTaskMemFree(status);
1103 static HRESULT WINAPI accessor_GetBindings(IAccessor *iface, HACCESSOR hAccessor, DBACCESSORFLAGS *pdwAccessorFlags,
1104 DBCOUNTITEM *pcBindings, DBBINDING **prgBindings)
1106 rowset_proxy *This = impl_from_IAccessor(iface);
1109 TRACE("(%p)->(%08lx, %p, %p, %p)\n", This, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);
1111 hr = IWineRowServer_GetBindings(This->server, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);
1116 static HRESULT WINAPI accessor_ReleaseAccessor(IAccessor *iface, HACCESSOR hAccessor, DBREFCOUNT *pcRefCount)
1118 rowset_proxy *This = impl_from_IAccessor(iface);
1122 TRACE("(%p)->(%08lx, %p)\n", This, hAccessor, pcRefCount);
1124 hr = IWineRowServer_ReleaseAccessor(This->server, hAccessor, &ref);
1125 if(pcRefCount) *pcRefCount = ref;
1129 static const IAccessorVtbl accessor_vtbl =
1131 accessor_QueryInterface,
1134 accessor_AddRefAccessor,
1135 accessor_CreateAccessor,
1136 accessor_GetBindings,
1137 accessor_ReleaseAccessor
1140 HRESULT create_rowset_proxy(IWineRowServer *server, IUnknown **obj)
1142 rowset_proxy *proxy;
1144 TRACE("(%p, %p)\n", server, obj);
1147 proxy = HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy));
1148 if(!proxy) return E_OUTOFMEMORY;
1150 proxy->rowset_vtbl = &rowset_vtbl;
1151 proxy->rowsetlocate_vtbl = &rowsetlocate_vtbl;
1152 proxy->rowsetinfo_vtbl = &rowsetinfo_vtbl;
1153 proxy->accessor_vtbl = &accessor_vtbl;
1155 IWineRowServer_AddRef(server);
1156 proxy->server = server;
1158 *obj = (IUnknown *)&proxy->rowset_vtbl;
1159 TRACE("returing %p\n", *obj);
1163 static HRESULT create_proxy(IWineRowServer *server, const CLSID *class, IUnknown **obj)
1167 if(IsEqualGUID(class, &CLSID_wine_row_proxy))
1168 return create_row_proxy(server, obj);
1169 else if(IsEqualGUID(class, &CLSID_wine_rowset_proxy))
1170 return create_rowset_proxy(server, obj);
1172 FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
1180 const IMarshalVtbl *marshal_vtbl;
1183 CLSID unmarshal_class;
1187 static inline marshal *impl_from_IMarshal(IMarshal *iface)
1189 return (marshal *)((char*)iface - FIELD_OFFSET(marshal, marshal_vtbl));
1192 static HRESULT WINAPI marshal_QueryInterface(IMarshal *iface, REFIID iid, void **obj)
1194 marshal *This = impl_from_IMarshal(iface);
1195 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
1197 if(IsEqualIID(iid, &IID_IUnknown) ||
1198 IsEqualIID(iid, &IID_IMarshal))
1204 FIXME("interface %s not implemented\n", debugstr_guid(iid));
1206 return E_NOINTERFACE;
1209 IMarshal_AddRef(iface);
1213 static ULONG WINAPI marshal_AddRef(IMarshal *iface)
1215 marshal *This = impl_from_IMarshal(iface);
1216 TRACE("(%p)\n", This);
1217 return InterlockedIncrement(&This->ref);
1220 static ULONG WINAPI marshal_Release(IMarshal *iface)
1222 marshal *This = impl_from_IMarshal(iface);
1225 TRACE("(%p)\n", This);
1227 ref = InterlockedDecrement(&This->ref);
1230 HeapFree(GetProcessHeap(), 0, This);
1236 static HRESULT WINAPI marshal_GetUnmarshalClass(IMarshal *iface, REFIID iid, void *obj,
1237 DWORD dwDestContext, void *pvDestContext,
1238 DWORD mshlflags, CLSID *clsid)
1240 marshal *This = impl_from_IMarshal(iface);
1241 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
1242 pvDestContext, mshlflags, clsid);
1244 *clsid = This->unmarshal_class;
1248 static HRESULT WINAPI marshal_GetMarshalSizeMax(IMarshal *iface, REFIID iid, void *obj,
1249 DWORD dwDestContext, void *pvDestContext,
1250 DWORD mshlflags, DWORD *size)
1252 marshal *This = impl_from_IMarshal(iface);
1253 TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
1254 pvDestContext, mshlflags, size);
1256 return CoGetMarshalSizeMax(size, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext,
1260 static HRESULT WINAPI marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID iid,
1261 void *obj, DWORD dwDestContext, void *pvDestContext,
1264 marshal *This = impl_from_IMarshal(iface);
1265 TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This, stream, debugstr_guid(iid), obj, dwDestContext,
1266 pvDestContext, mshlflags);
1268 return CoMarshalInterface(stream, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext, mshlflags);
1271 static HRESULT WINAPI marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
1272 REFIID iid, void **obj)
1274 marshal *This = impl_from_IMarshal(iface);
1276 IWineRowServer *server;
1279 TRACE("(%p)->(%p, %s, %p)\n", This, stream, debugstr_guid(iid), obj);
1282 hr = CoUnmarshalInterface(stream, &IID_IWineRowServer, (void**)&server);
1285 hr = create_proxy(server, &This->unmarshal_class, &proxy);
1288 hr = IUnknown_QueryInterface(proxy, iid, obj);
1289 IUnknown_Release(proxy);
1291 IWineRowServer_Release(server);
1294 TRACE("returing %p\n", *obj);
1298 static HRESULT WINAPI marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
1300 marshal *This = impl_from_IMarshal(iface);
1301 TRACE("(%p)->(%p)\n", This, stream);
1302 return CoReleaseMarshalData(stream);
1305 static HRESULT WINAPI marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
1307 marshal *This = impl_from_IMarshal(iface);
1308 FIXME("(%p)->(%08x)\n", This, dwReserved);
1313 static const IMarshalVtbl marshal_vtbl =
1315 marshal_QueryInterface,
1318 marshal_GetUnmarshalClass,
1319 marshal_GetMarshalSizeMax,
1320 marshal_MarshalInterface,
1321 marshal_UnmarshalInterface,
1322 marshal_ReleaseMarshalData,
1323 marshal_DisconnectObject
1326 static HRESULT create_marshal(IUnknown *outer, const CLSID *class, void **obj)
1330 TRACE("(%p, %p)\n", outer, obj);
1333 marshal = HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal));
1334 if(!marshal) return E_OUTOFMEMORY;
1336 marshal->unmarshal_class = *class;
1337 marshal->outer = outer; /* don't ref outer unk */
1338 marshal->marshal_vtbl = &marshal_vtbl;
1341 *obj = &marshal->marshal_vtbl;
1342 TRACE("returing %p\n", *obj);
1346 HRESULT create_row_marshal(IUnknown *outer, void **obj)
1348 TRACE("(%p, %p)\n", outer, obj);
1349 return create_marshal(outer, &CLSID_wine_row_proxy, obj);
1352 HRESULT create_rowset_marshal(IUnknown *outer, void **obj)
1354 TRACE("(%p, %p)\n", outer, obj);
1355 return create_marshal(outer, &CLSID_wine_rowset_proxy, obj);