/*
 *    Row and rowset servers / proxies.
 *
 * Copyright 2010 Huw Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>
#include <string.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "oleauto.h"
#include "oledb.h"

#include "row_server.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(oledb);

static inline DBLENGTH db_type_size(DBTYPE type, DBLENGTH var_len)
{
    switch(type)
    {
    case DBTYPE_I1:
    case DBTYPE_UI1:
        return 1;
    case DBTYPE_I2:
    case DBTYPE_UI2:
        return 2;
    case DBTYPE_I4:
    case DBTYPE_UI4:
    case DBTYPE_R4:
        return 4;
    case DBTYPE_I8:
    case DBTYPE_UI8:
    case DBTYPE_R8:
        return 8;
    case DBTYPE_CY:
        return sizeof(CY);
    case DBTYPE_FILETIME:
        return sizeof(FILETIME);
    case DBTYPE_BSTR:
        return sizeof(BSTR);
    case DBTYPE_GUID:
        return sizeof(GUID);
    case DBTYPE_WSTR:
        return var_len;
    default:
        FIXME("Unhandled type %04x\n", type);
        return 0;
    }
}

typedef struct
{
    const IWineRowServerVtbl *vtbl;

    LONG ref;

    CLSID class;
    IMarshal *marshal;
    IUnknown *inner_unk;
} server;

static inline server *impl_from_IWineRowServer(IWineRowServer *iface)
{
    return (server *)((char*)iface - FIELD_OFFSET(server, vtbl));
}

static HRESULT WINAPI server_QueryInterface(IWineRowServer *iface, REFIID riid, void **obj)
{
    server *This = impl_from_IWineRowServer(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if(IsEqualIID(riid, &IID_IUnknown) ||
       IsEqualIID(riid, &IID_IWineRowServer))
    {
        *obj = iface;
    }
    else
    {
        if(!IsEqualIID(riid, &IID_IMarshal)) /* We use standard marshalling */
            FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IWineRowServer_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI server_AddRef(IWineRowServer *iface)
{
    server *This = impl_from_IWineRowServer(iface);
    TRACE("(%p)\n", This);

    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI server_Release(IWineRowServer *iface)
{
    server *This = impl_from_IWineRowServer(iface);
    LONG ref;

    TRACE("(%p)\n", This);

    ref = InterlockedDecrement(&This->ref);
    if(ref == 0)
    {
        IMarshal_Release(This->marshal);
        if(This->inner_unk) IUnknown_Release(This->inner_unk);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI server_SetInnerUnk(IWineRowServer *iface, IUnknown *inner)
{
    server *This = impl_from_IWineRowServer(iface);

    if(This->inner_unk) IUnknown_Release(This->inner_unk);

    if(inner) IUnknown_AddRef(inner);
    This->inner_unk = inner;
    return S_OK;
}

static HRESULT WINAPI server_GetMarshal(IWineRowServer *iface, IMarshal **marshal)
{
    server *This = impl_from_IWineRowServer(iface);

    IMarshal_AddRef(This->marshal);
    *marshal = This->marshal;
    return S_OK;
}

static HRESULT WINAPI server_GetColumns(IWineRowServer* iface, DBORDINAL num_cols,
                                        wine_getcolumns_in *in_data, wine_getcolumns_out *out_data)
{
    server *This = impl_from_IWineRowServer(iface);
    HRESULT hr;
    DBORDINAL i;
    DBCOLUMNACCESS *cols;
    IRow *row;

    TRACE("(%p)->(%d, %p, %p)\n", This, num_cols, in_data, out_data);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRow, (void**)&row);
    if(FAILED(hr)) return hr;

    cols = CoTaskMemAlloc(num_cols * sizeof(cols[0]));

    for(i = 0; i < num_cols; i++)
    {
        TRACE("%d:\tmax_len %d type %04x\n", i, in_data[i].max_len, in_data[i].type);
        cols[i].pData        = CoTaskMemAlloc(db_type_size(in_data[i].type, in_data[i].max_len));
        cols[i].columnid     = in_data[i].columnid;
        cols[i].cbMaxLen     = in_data[i].max_len;
        cols[i].wType        = in_data[i].type;
        cols[i].bPrecision   = in_data[i].precision;
        cols[i].bScale       = in_data[i].scale;
    }

    hr = IRow_GetColumns(row, num_cols, cols);
    IRow_Release(row);

    for(i = 0; i < num_cols; i++)
    {
        VariantInit(&out_data[i].v);
        if(cols[i].dwStatus == DBSTATUS_S_OK)
        {
            V_VT(&out_data[i].v) = in_data[i].type;
            memcpy(&V_I1(&out_data[i].v), cols[i].pData, cols[i].cbDataLen);
        }
        CoTaskMemFree(cols[i].pData);
        out_data[i].data_len = cols[i].cbDataLen;
        out_data[i].status   = cols[i].dwStatus;
    }

    CoTaskMemFree(cols);

    return hr;
}

static HRESULT WINAPI server_GetSourceRowset(IWineRowServer* iface, REFIID riid, IUnknown **ppRowset,
                                             HROW *phRow)
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_Open(IWineRowServer* iface, IUnknown *pUnkOuter, DBID *pColumnID,
                                  REFGUID rguidColumnType, DWORD dwBindFlags, REFIID riid,
                                  IUnknown **ppUnk)
{
    server *This = impl_from_IWineRowServer(iface);
    IRow *row;
    HRESULT hr;
    IWineRowServer *new_server;
    IMarshal *marshal;
    IUnknown *obj;

    TRACE("(%p)->(%p, %p, %s, %08x, %s, %p)\n", This, pUnkOuter, pColumnID, debugstr_guid(rguidColumnType),
          dwBindFlags, debugstr_guid(riid), ppUnk);

    *ppUnk = NULL;

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRow, (void**)&row);
    if(FAILED(hr)) return hr;

    if(IsEqualGUID(rguidColumnType, &DBGUID_ROWSET))
        hr = CoCreateInstance(&CLSID_wine_rowset_server, NULL, CLSCTX_INPROC_SERVER, &IID_IWineRowServer, (void**)&new_server);
    else
    {
        FIXME("Unhandled object %s\n", debugstr_guid(rguidColumnType));
        hr = E_NOTIMPL;
    }

    if(FAILED(hr))
    {
        IRow_Release(row);
        return hr;
    }

    IWineRowServer_GetMarshal(new_server, &marshal);
    hr = IRow_Open(row, (IUnknown*)marshal, pColumnID, rguidColumnType, dwBindFlags, &IID_IUnknown, &obj);
    IMarshal_Release(marshal);
    IRow_Release(row);

    if(FAILED(hr))
    {
        IWineRowServer_Release(new_server);
        return hr;
    }

    IWineRowServer_SetInnerUnk(new_server, obj);
    hr = IUnknown_QueryInterface(obj, riid, (void**)ppUnk);
    IUnknown_Release(obj);

    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_SetColumns(IWineRowServer* iface, DBORDINAL num_cols,
                                        wine_setcolumns_in *in_data, DBSTATUS *status)
{
    server *This = impl_from_IWineRowServer(iface);
    HRESULT hr;
    DBORDINAL i;
    DBCOLUMNACCESS *cols;
    IRowChange *row_change;

    TRACE("(%p)->(%d, %p, %p)\n", This, num_cols, in_data, status);
    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowChange, (void**)&row_change);
    if(FAILED(hr)) return hr;

    cols = CoTaskMemAlloc(num_cols * sizeof(cols[0]));

    for(i = 0; i < num_cols; i++)
    {
        TRACE("%d:\ttype %04x\n", i, in_data[i].type);
        cols[i].pData        = CoTaskMemAlloc(db_type_size(in_data[i].type, in_data[i].max_len));
        memcpy(cols[i].pData, &V_I1(&in_data[i].v), db_type_size(in_data[i].type, in_data[i].max_len));
        cols[i].columnid     = in_data[i].columnid;
        cols[i].cbDataLen    = in_data[i].data_len;
        cols[i].dwStatus     = in_data[i].status;
        cols[i].cbMaxLen     = in_data[i].max_len;
        cols[i].wType        = in_data[i].type;
        cols[i].bPrecision   = in_data[i].precision;
        cols[i].bScale       = in_data[i].scale;
    }

    hr = IRowChange_SetColumns(row_change, num_cols, cols);
    IRowChange_Release(row_change);

    for(i = 0; i < num_cols; i++)
    {
        CoTaskMemFree(cols[i].pData);
        status[i] = cols[i].dwStatus;
    }

    CoTaskMemFree(cols);

    return hr;
}

static HRESULT WINAPI server_AddRefRows(IWineRowServer* iface, DBCOUNTITEM cRows,
                                        const HROW rghRows[], DBREFCOUNT rgRefCounts[],
                                        DBROWSTATUS rgRowStatus[])
{
    server *This = impl_from_IWineRowServer(iface);
    IRowset *rowset;
    HRESULT hr;

    TRACE("(%p)->(%d, %p, %p, %p)\n", This, cRows, rghRows, rgRefCounts, rgRowStatus);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowset, (void**)&rowset);
    if(FAILED(hr)) return hr;

    hr = IRowset_AddRefRows(rowset, cRows, rghRows, rgRefCounts, rgRowStatus);

    IRowset_Release(rowset);
    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_GetData(IWineRowServer* iface, HROW hRow,
                                     HACCESSOR hAccessor, BYTE *pData, DWORD size)
{
    server *This = impl_from_IWineRowServer(iface);
    IRowset *rowset;
    HRESULT hr;

    TRACE("(%p)->(%08lx, %08lx, %p, %d)\n", This, hRow, hAccessor, pData, size);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowset, (void**)&rowset);
    if(FAILED(hr)) return hr;

    hr = IRowset_GetData(rowset, hRow, hAccessor, pData);

    IRowset_Release(rowset);
    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_GetNextRows(IWineRowServer* iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
                                         DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
{
    server *This = impl_from_IWineRowServer(iface);
    IRowset *rowset;
    HRESULT hr;

    TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowset, (void**)&rowset);
    if(FAILED(hr)) return hr;

    *prghRows = NULL;

    hr = IRowset_GetNextRows(rowset, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);
    IRowset_Release(rowset);
    TRACE("returning %08x, got %d rows\n", hr, *pcRowObtained);
    return hr;
}

static HRESULT WINAPI server_ReleaseRows(IWineRowServer* iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                         DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    server *This = impl_from_IWineRowServer(iface);
    IRowset *rowset;
    HRESULT hr;

    TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowset, (void**)&rowset);
    if(FAILED(hr)) return hr;

    hr = IRowset_ReleaseRows(rowset, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);
    IRowset_Release(rowset);

    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_RestartPosition(IWineRowServer* iface, HCHAPTER hReserved)
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p)->(%08lx): stub\n", This, hReserved);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_Compare(IWineRowServer *iface, HCHAPTER hReserved, DBBKMARK cbBookmark1,
                                     const BYTE *pBookmark1, DBBKMARK cbBookmark2, const BYTE *pBookmark2,
                                     DBCOMPARE *pComparison)
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_GetRowsAt(IWineRowServer *iface, HWATCHREGION hReserved1, HCHAPTER hReserved2,
                                       DBBKMARK cbBookmark, const BYTE *pBookmark, DBROWOFFSET lRowsOffset,
                                       DBROWCOUNT cRows, DBCOUNTITEM *pcRowsObtained, HROW **prghRows)
{
    server *This = impl_from_IWineRowServer(iface);
    IRowsetLocate *rowsetlocate;
    HRESULT hr;

    TRACE("(%p)->(%08lx, %08lx, %d, %p, %d, %d, %p, %p\n", This, hReserved1, hReserved2, cbBookmark, pBookmark, lRowsOffset, cRows,
          pcRowsObtained, prghRows);

    *prghRows = NULL;

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowsetLocate, (void**)&rowsetlocate);
    if(FAILED(hr)) return hr;

    hr = IRowsetLocate_GetRowsAt(rowsetlocate, hReserved1, hReserved2, cbBookmark, pBookmark, lRowsOffset,
                                 cRows, pcRowsObtained, prghRows);
    IRowsetLocate_Release(rowsetlocate);

    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_GetRowsByBookmark(IWineRowServer *iface, HCHAPTER hReserved, DBCOUNTITEM cRows,
                                               const DBBKMARK rgcbBookmarks[], const BYTE * rgpBookmarks[],
                                               HROW rghRows[], DBROWSTATUS rgRowStatus[])
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_Hash(IWineRowServer *iface, HCHAPTER hReserved, DBBKMARK cBookmarks,
                                  const DBBKMARK rgcbBookmarks[], const BYTE * rgpBookmarks[],
                                  DBHASHVALUE rgHashedValues[], DBROWSTATUS rgBookmarkStatus[])
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_GetProperties(IWineRowServer* iface, ULONG cPropertyIDSets,
                                           const DBPROPIDSET *rgPropertyIDSets, ULONG *pcPropertySets,
                                           DBPROPSET **prgPropertySets)
{
    server *This = impl_from_IWineRowServer(iface);
    IRowsetInfo *rowsetinfo;
    HRESULT hr;

    TRACE("(%p)->(%d, %p, %p, %p)\n", This, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IRowsetInfo, (void**)&rowsetinfo);
    if(FAILED(hr)) return hr;

    hr = IRowsetInfo_GetProperties(rowsetinfo, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);
    IRowsetInfo_Release(rowsetinfo);

    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_GetReferencedRowset(IWineRowServer* iface, DBORDINAL iOrdinal,
                                                 REFIID riid, IUnknown **ppReferencedRowset)
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_GetSpecification(IWineRowServer* iface, REFIID riid,
                                               IUnknown **ppSpecification)
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_AddRefAccessor(IWineRowServer* iface, HACCESSOR hAccessor,
                                            DBREFCOUNT *pcRefCount)
{
    server *This = impl_from_IWineRowServer(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI server_CreateAccessor(IWineRowServer* iface, DBACCESSORFLAGS dwAccessorFlags,
                                            DBCOUNTITEM cBindings, const DBBINDING *rgBindings, DBLENGTH cbRowSize,
                                            HACCESSOR *phAccessor, DBBINDSTATUS *rgStatus)
{
    server *This = impl_from_IWineRowServer(iface);
    HRESULT hr;
    IAccessor *accessor;

    TRACE("(%p)->(%08x, %d, %p, %d, %p, %p)\n", This, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, rgStatus);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IAccessor, (void**)&accessor);
    if(FAILED(hr)) return hr;

    hr = IAccessor_CreateAccessor(accessor, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, rgStatus);
    IAccessor_Release(accessor);

    TRACE("returning %08x, accessor %08lx\n", hr, *phAccessor);
    return hr;
}

static HRESULT WINAPI server_GetBindings(IWineRowServer* iface, HACCESSOR hAccessor,
                                         DBACCESSORFLAGS *pdwAccessorFlags, DBCOUNTITEM *pcBindings,
                                         DBBINDING **prgBindings)
{
    server *This = impl_from_IWineRowServer(iface);
    HRESULT hr;
    IAccessor *accessor;

    TRACE("(%p)->(%08lx, %p, %p, %p)\n", This, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IAccessor, (void**)&accessor);
    if(FAILED(hr)) return hr;

    hr = IAccessor_GetBindings(accessor, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);
    IAccessor_Release(accessor);

    TRACE("returning %08x\n", hr);
    return hr;
}

static HRESULT WINAPI server_ReleaseAccessor(IWineRowServer* iface, HACCESSOR hAccessor,
                                             DBREFCOUNT *pcRefCount)
{
    server *This = impl_from_IWineRowServer(iface);
    HRESULT hr;
    IAccessor *accessor;

    TRACE("(%p)->(%08lx, %p)\n", This, hAccessor, pcRefCount);

    hr = IUnknown_QueryInterface(This->inner_unk, &IID_IAccessor, (void**)&accessor);
    if(FAILED(hr)) return hr;

    hr = IAccessor_ReleaseAccessor(accessor, hAccessor, pcRefCount);
    IAccessor_Release(accessor);

    return hr;
}

static const IWineRowServerVtbl server_vtbl =
{
    server_QueryInterface,
    server_AddRef,
    server_Release,
    server_SetInnerUnk,
    server_GetMarshal,
    server_GetColumns,
    server_GetSourceRowset,
    server_Open,
    server_SetColumns,
    server_AddRefRows,
    server_GetData,
    server_GetNextRows,
    server_ReleaseRows,
    server_RestartPosition,
    server_Compare,
    server_GetRowsAt,
    server_GetRowsByBookmark,
    server_Hash,
    server_GetProperties,
    server_GetReferencedRowset,
    server_GetSpecification,
    server_AddRefAccessor,
    server_CreateAccessor,
    server_GetBindings,
    server_ReleaseAccessor
};

static HRESULT create_server(IUnknown *outer, const CLSID *class, void **obj)
{
    server *server;
    TRACE("(%p, %s, %p)\n", outer, debugstr_guid(class), obj);

    *obj = NULL;

    server = HeapAlloc(GetProcessHeap(), 0, sizeof(*server));
    if(!server) return E_OUTOFMEMORY;

    server->vtbl = &server_vtbl;
    server->ref = 1;
    server->class = *class;
    server->inner_unk = NULL;
    if(IsEqualGUID(class, &CLSID_wine_row_server))
        create_row_marshal((IUnknown*)server, (void**)&server->marshal);
    else if(IsEqualGUID(class, &CLSID_wine_rowset_server))
        create_rowset_marshal((IUnknown*)server, (void**)&server->marshal);
    else
        ERR("create_server called with class %s\n", debugstr_guid(class));

    *obj = server;
    return S_OK;
}

HRESULT create_row_server(IUnknown *outer, void **obj)
{
    return create_server(outer, &CLSID_wine_row_server, obj);
}

HRESULT create_rowset_server(IUnknown *outer, void **obj)
{
    return create_server(outer, &CLSID_wine_rowset_server, obj);
}

typedef struct
{
    const IRowVtbl *row_vtbl;
    const IRowChangeVtbl *row_change_vtbl;

    LONG ref;

    IWineRowServer *server;
} row_proxy;

static inline row_proxy *impl_from_IRow(IRow *iface)
{
    return (row_proxy *)((char*)iface - FIELD_OFFSET(row_proxy, row_vtbl));
}

static inline row_proxy *impl_from_IRowChange(IRowChange *iface)
{
    return (row_proxy *)((char*)iface - FIELD_OFFSET(row_proxy, row_change_vtbl));
}

static HRESULT WINAPI row_QueryInterface(IRow *iface, REFIID iid, void **obj)
{
    row_proxy *This = impl_from_IRow(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);

    if(IsEqualIID(iid, &IID_IUnknown) ||
       IsEqualIID(iid, &IID_IRow))
    {
        *obj = &This->row_vtbl;
    }
    else if(IsEqualIID(iid, &IID_IRowChange))
    {
        *obj = &This->row_change_vtbl;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(iid));
        return E_NOINTERFACE;
    }

    IRow_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI row_AddRef(IRow *iface)
{
    row_proxy *This = impl_from_IRow(iface);
    TRACE("(%p)\n", This);

    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI row_Release(IRow *iface)
{
    row_proxy *This = impl_from_IRow(iface);
    LONG ref;

    TRACE("(%p)\n", This);

    ref = InterlockedDecrement(&This->ref);
    if(ref == 0)
    {
        if(This->server) IWineRowServer_Release(This->server);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI row_GetColumns(IRow* iface, DBORDINAL cColumns, DBCOLUMNACCESS rgColumns[])
{
    row_proxy *This = impl_from_IRow(iface);
    DBORDINAL i;
    wine_getcolumns_in *in_data;
    wine_getcolumns_out *out_data;
    HRESULT hr;

    TRACE("(%p)->(%d, %p)\n", This, cColumns, rgColumns);

    in_data = CoTaskMemAlloc(cColumns * sizeof(in_data[0]));
    out_data = CoTaskMemAlloc(cColumns * sizeof(out_data[0]));

    for(i = 0; i < cColumns; i++)
    {
        TRACE("%d:\tdata %p data_len %d status %08x max_len %d type %04x\n", i, rgColumns[i].pData,
              rgColumns[i].cbDataLen, rgColumns[i].dwStatus, rgColumns[i].cbMaxLen, rgColumns[i].wType);
        in_data[i].columnid     = rgColumns[i].columnid;
        in_data[i].max_len      = rgColumns[i].cbMaxLen;
        in_data[i].type         = rgColumns[i].wType;
        in_data[i].precision    = rgColumns[i].bPrecision;
        in_data[i].scale        = rgColumns[i].bScale;
    }

    hr = IWineRowServer_GetColumns(This->server, cColumns, in_data, out_data);

    for(i = 0; i < cColumns; i++)
    {
        rgColumns[i].cbDataLen = out_data[i].data_len;
        rgColumns[i].dwStatus  = out_data[i].status;
        if(rgColumns[i].dwStatus == DBSTATUS_S_OK)
            memcpy(rgColumns[i].pData, &V_I1(&out_data[i].v), out_data[i].data_len);
    }

    CoTaskMemFree(out_data);
    CoTaskMemFree(in_data);
    return hr;
}

static HRESULT WINAPI row_GetSourceRowset(IRow* iface, REFIID riid, IUnknown **ppRowset,
                                          HROW *phRow)
{
    row_proxy *This = impl_from_IRow(iface);

    FIXME("(%p)->(%s, %p, %p): stub\n", This, debugstr_guid(riid), ppRowset, phRow);

    return E_NOTIMPL;
}

static HRESULT WINAPI row_Open(IRow* iface, IUnknown *pUnkOuter,
                               DBID *pColumnID, REFGUID rguidColumnType,
                               DWORD dwBindFlags, REFIID riid, IUnknown **ppUnk)
{
    row_proxy *This = impl_from_IRow(iface);

    TRACE("(%p)->(%p, %p, %s, %08x, %s, %p)\n", This, pUnkOuter, pColumnID, debugstr_guid(rguidColumnType),
          dwBindFlags, debugstr_guid(riid), ppUnk);
    if(pUnkOuter)
    {
        FIXME("Aggregation not supported\n");
        return CLASS_E_NOAGGREGATION;
    }

    return IWineRowServer_Open(This->server, pUnkOuter, pColumnID, rguidColumnType, dwBindFlags, riid, ppUnk);
}

static const IRowVtbl row_vtbl =
{
    row_QueryInterface,
    row_AddRef,
    row_Release,
    row_GetColumns,
    row_GetSourceRowset,
    row_Open
};

static HRESULT WINAPI row_change_QueryInterface(IRowChange *iface, REFIID iid, void **obj)
{
    row_proxy *This = impl_from_IRowChange(iface);
    return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
}

static ULONG WINAPI row_change_AddRef(IRowChange *iface)
{
    row_proxy *This = impl_from_IRowChange(iface);
    return IUnknown_AddRef((IUnknown*)This);
}

static ULONG WINAPI row_change_Release(IRowChange *iface)
{
    row_proxy *This = impl_from_IRowChange(iface);
    return IUnknown_Release((IUnknown*)This);
}

static HRESULT WINAPI row_change_SetColumns(IRowChange *iface, DBORDINAL cColumns,
                                            DBCOLUMNACCESS rgColumns[])
{
    row_proxy *This = impl_from_IRowChange(iface);
    HRESULT hr;
    wine_setcolumns_in *in_data;
    DBSTATUS *status;
    DBORDINAL i;

    TRACE("(%p)->(%d, %p)\n", This, cColumns, rgColumns);

    in_data = CoTaskMemAlloc(cColumns * sizeof(in_data[0]));
    status = CoTaskMemAlloc(cColumns * sizeof(status[0]));

    for(i = 0; i < cColumns; i++)
    {
        TRACE("%d: wtype %04x max %08x len %08x\n", i, rgColumns[i].wType, rgColumns[i].cbMaxLen, rgColumns[i].cbDataLen);
        V_VT(&in_data[i].v) = rgColumns[i].wType;
        memcpy(&V_I1(&in_data[i].v), rgColumns[i].pData, db_type_size(rgColumns[i].wType, rgColumns[i].cbDataLen));
        in_data[i].columnid = rgColumns[i].columnid;
        in_data[i].data_len = rgColumns[i].cbDataLen;
        in_data[i].status = rgColumns[i].dwStatus;
        in_data[i].max_len = rgColumns[i].cbMaxLen;
        in_data[i].type = rgColumns[i].wType;
        in_data[i].precision = rgColumns[i].bPrecision;
        in_data[i].scale = rgColumns[i].bScale;
    }

    hr = IWineRowServer_SetColumns(This->server, cColumns, in_data, status);

    for(i = 0; i < cColumns; i++)
        rgColumns[i].dwStatus = status[i];

    CoTaskMemFree(status);
    CoTaskMemFree(in_data);

    return hr;
}

static const IRowChangeVtbl row_change_vtbl =
{
    row_change_QueryInterface,
    row_change_AddRef,
    row_change_Release,
    row_change_SetColumns
};

static HRESULT create_row_proxy(IWineRowServer *server, IUnknown **obj)
{
    row_proxy *proxy;

    TRACE("(%p, %p)\n", server, obj);
    *obj = NULL;

    proxy = HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy));
    if(!proxy) return E_OUTOFMEMORY;

    proxy->row_vtbl = &row_vtbl;
    proxy->row_change_vtbl = &row_change_vtbl;
    proxy->ref = 1;
    IWineRowServer_AddRef(server);
    proxy->server = server;

    *obj = (IUnknown*)&proxy->row_vtbl;
    TRACE("returing %p\n", *obj);
    return S_OK;
}

typedef struct
{
    const IRowsetVtbl *rowset_vtbl;
    const IRowsetLocateVtbl *rowsetlocate_vtbl;
    const IRowsetInfoVtbl *rowsetinfo_vtbl;
    const IAccessorVtbl *accessor_vtbl;

    LONG ref;

    IWineRowServer *server;
} rowset_proxy;

static inline rowset_proxy *impl_from_IRowset(IRowset *iface)
{
    return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowset_vtbl));
}

static inline rowset_proxy *impl_from_IRowsetLocate(IRowsetLocate *iface)
{
    return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowsetlocate_vtbl));
}

static inline rowset_proxy *impl_from_IRowsetInfo(IRowsetInfo *iface)
{
    return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, rowsetinfo_vtbl));
}

static inline rowset_proxy *impl_from_IAccessor(IAccessor *iface)
{
    return (rowset_proxy *)((char*)iface - FIELD_OFFSET(rowset_proxy, accessor_vtbl));
}

static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID iid, void **obj)
{
    rowset_proxy *This = impl_from_IRowset(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);

    *obj = NULL;

    if(IsEqualIID(iid, &IID_IUnknown) ||
       IsEqualIID(iid, &IID_IRowset))
    {
        *obj = &This->rowset_vtbl;
    }
    else if(IsEqualIID(iid, &IID_IRowsetLocate))
    {
        *obj = &This->rowsetlocate_vtbl;
    }
    else if(IsEqualIID(iid, &IID_IRowsetInfo))
    {
        *obj = &This->rowsetinfo_vtbl;
    }
    else if(IsEqualIID(iid, &IID_IAccessor))
    {
        *obj = &This->accessor_vtbl;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(iid));
        return E_NOINTERFACE;
    }

    IRowset_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI rowset_AddRef(IRowset *iface)
{
    rowset_proxy *This = impl_from_IRowset(iface);
    TRACE("(%p)\n", This);

    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI rowset_Release(IRowset *iface)
{
    rowset_proxy *This = impl_from_IRowset(iface);
    LONG ref;

    TRACE("(%p)\n", This);

    ref = InterlockedDecrement(&This->ref);
    if(ref == 0)
    {
        if(This->server) IWineRowServer_Release(This->server);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                        DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowset(iface);
    HRESULT hr;
    DBREFCOUNT *refs = rgRefCounts;
    DBSTATUS *stats = rgRowStatus;

    TRACE("(%p)->(%d, %p, %p, %p)\n", This, cRows, rghRows, rgRefCounts, rgRowStatus);

    if(!refs) refs = CoTaskMemAlloc(cRows * sizeof(refs[0]));
    if(!stats) stats = CoTaskMemAlloc(cRows * sizeof(stats[0]));

    hr = IWineRowServer_AddRefRows(This->server, cRows, rghRows, refs, stats);

    if(refs != rgRefCounts) CoTaskMemFree(refs);
    if(stats != rgRowStatus) CoTaskMemFree(stats);

    return hr;
}

static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
{
    rowset_proxy *This = impl_from_IRowset(iface);
    HRESULT hr;
    IAccessor *accessor;
    DBACCESSORFLAGS flags;
    DBCOUNTITEM count, i;
    DBBINDING *bindings;
    DWORD max_len = 0;

    TRACE("(%p)->(%lx, %lx, %p)\n", This, hRow, hAccessor, pData);

    hr = IRowset_QueryInterface(iface, &IID_IAccessor, (void**)&accessor);
    if(FAILED(hr)) return hr;

    hr = IAccessor_GetBindings(accessor, hAccessor, &flags, &count, &bindings);
    IAccessor_Release(accessor);
    if(FAILED(hr)) return hr;

    TRACE("got %d bindings\n", count);
    for(i = 0; i < count; i++)
    {
        TRACE("%d\tord %d offs: val %d len %d stat %d, part %x, max len %d type %04x\n",
              i, bindings[i].iOrdinal, bindings[i].obValue, bindings[i].obLength, bindings[i].obStatus,
              bindings[i].dwPart, bindings[i].cbMaxLen, bindings[i].wType);
        if(bindings[i].dwPart & DBPART_LENGTH && bindings[i].obLength >= max_len)
            max_len = bindings[i].obLength + sizeof(DBLENGTH);
        if(bindings[i].dwPart & DBPART_STATUS && bindings[i].obStatus >= max_len)
            max_len = bindings[i].obStatus + sizeof(DWORD);
        if(bindings[i].dwPart & DBPART_VALUE && bindings[i].obValue >= max_len)
            max_len = bindings[i].obValue + db_type_size(bindings[i].wType, bindings[i].cbMaxLen);

    }
    TRACE("max_len %d\n", max_len);

    CoTaskMemFree(bindings);

    hr = IWineRowServer_GetData(This->server, hRow, hAccessor, pData, max_len);

    return hr;
}

static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
                                         DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
{
    rowset_proxy *This = impl_from_IRowset(iface);
    HRESULT hr;
    HROW *rows = NULL;

    TRACE("(%p)->(%08lx, %d, %d, %p, %p)\n", This, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);

    hr = IWineRowServer_GetNextRows(This->server, hReserved, lRowsOffset, cRows, pcRowObtained, &rows);
    if(*prghRows)
    {
        memcpy(*prghRows, rows, *pcRowObtained * sizeof(rows[0]));
        CoTaskMemFree(rows);
    }
    else
        *prghRows = rows;

    return hr;
}

static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                         DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowset(iface);
    HRESULT hr;
    DBROWOPTIONS *options = rgRowOptions;
    DBREFCOUNT *refs = rgRefCounts;
    DBROWSTATUS *status = rgRowStatus;

    TRACE("(%p)->(%d, %p, %p, %p, %p)\n", This, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);

    if(!options)
    {
        options = CoTaskMemAlloc(cRows * sizeof(options[0]));
        memset(options, 0, cRows * sizeof(options[0]));
    }
    if(!refs) refs = CoTaskMemAlloc(cRows * sizeof(refs[0]));
    if(!status) status = CoTaskMemAlloc(cRows * sizeof(status[0]));

    hr = IWineRowServer_ReleaseRows(This->server, cRows, rghRows, options, refs, status);

    if(status != rgRowStatus) CoTaskMemFree(status);
    if(refs != rgRefCounts) CoTaskMemFree(refs);
    if(options != rgRowOptions) CoTaskMemFree(options);

    return hr;
}

static HRESULT WINAPI rowset_RestartPosition(IRowset* iface, HCHAPTER hReserved)
{
    rowset_proxy *This = impl_from_IRowset(iface);

    FIXME("(%p)->(%lx): stub\n", This, hReserved);

    return E_NOTIMPL;
}

static const IRowsetVtbl rowset_vtbl =
{
    rowset_QueryInterface,
    rowset_AddRef,
    rowset_Release,
    rowset_AddRefRows,
    rowset_GetData,
    rowset_GetNextRows,
    rowset_ReleaseRows,
    rowset_RestartPosition
};

static HRESULT WINAPI rowsetlocate_QueryInterface(IRowsetLocate *iface, REFIID iid, void **obj)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
}

static ULONG WINAPI rowsetlocate_AddRef(IRowsetLocate *iface)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IUnknown_AddRef((IUnknown *)This);
}

static ULONG WINAPI rowsetlocate_Release(IRowsetLocate *iface)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IUnknown_Release((IUnknown *)This);
}

static HRESULT WINAPI rowsetlocate_AddRefRows(IRowsetLocate *iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                              DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IRowset_AddRefRows((IRowset*)This, cRows, rghRows, rgRefCounts, rgRowStatus);
}

static HRESULT WINAPI rowsetlocate_GetData(IRowsetLocate *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IRowset_GetData((IRowset*)This, hRow, hAccessor, pData);
}

static HRESULT WINAPI rowsetlocate_GetNextRows(IRowsetLocate *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
                                               DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IRowset_GetNextRows((IRowset*)This, hReserved, lRowsOffset, cRows, pcRowObtained, prghRows);
}

static HRESULT WINAPI rowsetlocate_ReleaseRows(IRowsetLocate *iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                               DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IRowset_ReleaseRows((IRowset*)This, cRows, rghRows, rgRowOptions, rgRefCounts, rgRowStatus);
}

static HRESULT WINAPI rowsetlocate_RestartPosition(IRowsetLocate *iface, HCHAPTER hReserved)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    return IRowset_RestartPosition((IRowset*)This, hReserved);
}

static HRESULT WINAPI rowsetlocate_Compare(IRowsetLocate *iface, HCHAPTER hReserved, DBBKMARK cbBookmark1, const BYTE *pBookmark1,
                                           DBBKMARK cbBookmark2, const BYTE *pBookmark2, DBCOMPARE *pComparison)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI rowsetlocate_GetRowsAt(IRowsetLocate *iface, HWATCHREGION hReserved1, HCHAPTER hReserved2, DBBKMARK cbBookmark,
                                             const BYTE *pBookmark, DBROWOFFSET lRowsOffset, DBROWCOUNT cRows, DBCOUNTITEM *pcRowsObtained,
                                             HROW **prghRows)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    HRESULT hr;
    HROW *rows = NULL;

    TRACE("(%p)->(%08lx, %08lx, %d, %p, %d, %d, %p, %p\n", This, hReserved1, hReserved2, cbBookmark, pBookmark, lRowsOffset, cRows,
          pcRowsObtained, prghRows);

    hr = IWineRowServer_GetRowsAt(This->server, hReserved1, hReserved2, cbBookmark, pBookmark, lRowsOffset, cRows, pcRowsObtained, &rows);

    if(*prghRows)
    {
        memcpy(*prghRows, rows, *pcRowsObtained * sizeof(rows[0]));
        CoTaskMemFree(rows);
    }
    else
        *prghRows = rows;

    return hr;
}

static HRESULT WINAPI rowsetlocate_GetRowsByBookmark(IRowsetLocate *iface, HCHAPTER hReserved, DBCOUNTITEM cRows, const DBBKMARK rgcbBookmarks[],
                                                     const BYTE * rgpBookmarks[], HROW rghRows[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI rowsetlocate_Hash(IRowsetLocate *iface, HCHAPTER hReserved, DBBKMARK cBookmarks, const DBBKMARK rgcbBookmarks[],
                                        const BYTE * rgpBookmarks[], DBHASHVALUE rgHashedValues[], DBROWSTATUS rgBookmarkStatus[])
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static const IRowsetLocateVtbl rowsetlocate_vtbl =
{
    rowsetlocate_QueryInterface,
    rowsetlocate_AddRef,
    rowsetlocate_Release,
    rowsetlocate_AddRefRows,
    rowsetlocate_GetData,
    rowsetlocate_GetNextRows,
    rowsetlocate_ReleaseRows,
    rowsetlocate_RestartPosition,
    rowsetlocate_Compare,
    rowsetlocate_GetRowsAt,
    rowsetlocate_GetRowsByBookmark,
    rowsetlocate_Hash
};

static HRESULT WINAPI rowsetinfo_QueryInterface(IRowsetInfo *iface, REFIID iid, void **obj)
{
    rowset_proxy *This = impl_from_IRowsetInfo(iface);
    return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
}

static ULONG WINAPI rowsetinfo_AddRef(IRowsetInfo *iface)
{
    rowset_proxy *This = impl_from_IRowsetInfo(iface);
    return IUnknown_AddRef((IUnknown *)This);
}

static ULONG WINAPI rowsetinfo_Release(IRowsetInfo *iface)
{
    rowset_proxy *This = impl_from_IRowsetInfo(iface);
    return IUnknown_Release((IUnknown *)This);
}

static HRESULT WINAPI rowsetinfo_GetProperties(IRowsetInfo *iface, const ULONG cPropertyIDSets,
                                               const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets,
                                               DBPROPSET **prgPropertySets)
{
    rowset_proxy *This = impl_from_IRowsetInfo(iface);
    HRESULT hr;

    TRACE("(%p)->(%d, %p, %p, %p)\n", This, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);

    hr = IWineRowServer_GetProperties(This->server, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets);

    return hr;
}

static HRESULT WINAPI rowsetinfo_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL iOrdinal, REFIID riid,
                                                     IUnknown **ppReferencedRowset)
{
    rowset_proxy *This = impl_from_IRowsetInfo(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI rowsetinfo_GetSpecification(IRowsetInfo *iface, REFIID riid, IUnknown **ppSpecification)
{
    rowset_proxy *This = impl_from_IRowsetInfo(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static const IRowsetInfoVtbl rowsetinfo_vtbl =
{
    rowsetinfo_QueryInterface,
    rowsetinfo_AddRef,
    rowsetinfo_Release,
    rowsetinfo_GetProperties,
    rowsetinfo_GetReferencedRowset,
    rowsetinfo_GetSpecification
};

static HRESULT WINAPI accessor_QueryInterface(IAccessor *iface, REFIID iid, void **obj)
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    return IUnknown_QueryInterface((IUnknown *)This, iid, obj);
}

static ULONG WINAPI accessor_AddRef(IAccessor *iface)
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    return IUnknown_AddRef((IUnknown *)This);
}

static ULONG WINAPI accessor_Release(IAccessor *iface)
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    return IUnknown_Release((IUnknown *)This);
}

static HRESULT WINAPI accessor_AddRefAccessor(IAccessor *iface, HACCESSOR hAccessor, DBREFCOUNT *pcRefCount)
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI accessor_CreateAccessor(IAccessor *iface, DBACCESSORFLAGS dwAccessorFlags, DBCOUNTITEM cBindings,
                                              const DBBINDING rgBindings[], DBLENGTH cbRowSize, HACCESSOR *phAccessor,
                                              DBBINDSTATUS rgStatus[])
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    HRESULT hr;
    DBBINDSTATUS *status;

    TRACE("(%p)->(%08x, %d, %p, %d, %p, %p)\n", This, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, rgStatus);

    if(!rgStatus) status = CoTaskMemAlloc(cBindings * sizeof(status[0]));
    else status = rgStatus;

    hr = IWineRowServer_CreateAccessor(This->server, dwAccessorFlags, cBindings, rgBindings, cbRowSize, phAccessor, status);

    if(!rgStatus) CoTaskMemFree(status);

    return hr;
}

static HRESULT WINAPI accessor_GetBindings(IAccessor *iface, HACCESSOR hAccessor, DBACCESSORFLAGS *pdwAccessorFlags,
                                           DBCOUNTITEM *pcBindings, DBBINDING **prgBindings)
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    HRESULT hr;

    TRACE("(%p)->(%08lx, %p, %p, %p)\n", This, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);

    hr = IWineRowServer_GetBindings(This->server, hAccessor, pdwAccessorFlags, pcBindings, prgBindings);

    return hr;
}

static HRESULT WINAPI accessor_ReleaseAccessor(IAccessor *iface, HACCESSOR hAccessor, DBREFCOUNT *pcRefCount)
{
    rowset_proxy *This = impl_from_IAccessor(iface);
    HRESULT hr;
    DBREFCOUNT ref;

    TRACE("(%p)->(%08lx, %p)\n", This, hAccessor, pcRefCount);

    hr = IWineRowServer_ReleaseAccessor(This->server, hAccessor, &ref);
    if(pcRefCount) *pcRefCount = ref;
    return hr;
}

static const IAccessorVtbl accessor_vtbl =
{
    accessor_QueryInterface,
    accessor_AddRef,
    accessor_Release,
    accessor_AddRefAccessor,
    accessor_CreateAccessor,
    accessor_GetBindings,
    accessor_ReleaseAccessor
};

HRESULT create_rowset_proxy(IWineRowServer *server, IUnknown **obj)
{
    rowset_proxy *proxy;

    TRACE("(%p, %p)\n", server, obj);
    *obj = NULL;

    proxy = HeapAlloc(GetProcessHeap(), 0, sizeof(*proxy));
    if(!proxy) return E_OUTOFMEMORY;

    proxy->rowset_vtbl = &rowset_vtbl;
    proxy->rowsetlocate_vtbl = &rowsetlocate_vtbl;
    proxy->rowsetinfo_vtbl = &rowsetinfo_vtbl;
    proxy->accessor_vtbl = &accessor_vtbl;
    proxy->ref = 1;
    IWineRowServer_AddRef(server);
    proxy->server = server;

    *obj = (IUnknown *)&proxy->rowset_vtbl;
    TRACE("returing %p\n", *obj);
    return S_OK;
}

static HRESULT create_proxy(IWineRowServer *server, const CLSID *class, IUnknown **obj)
{
    *obj = NULL;

    if(IsEqualGUID(class, &CLSID_wine_row_proxy))
        return create_row_proxy(server, obj);
    else if(IsEqualGUID(class, &CLSID_wine_rowset_proxy))
        return create_rowset_proxy(server, obj);
    else
        FIXME("Unhandled proxy class %s\n", debugstr_guid(class));
    return E_NOTIMPL;
}

/* Marshal impl */

typedef struct
{
    const IMarshalVtbl *marshal_vtbl;

    LONG ref;
    CLSID unmarshal_class;
    IUnknown *outer;
} marshal;

static inline marshal *impl_from_IMarshal(IMarshal *iface)
{
    return (marshal *)((char*)iface - FIELD_OFFSET(marshal, marshal_vtbl));
}

static HRESULT WINAPI marshal_QueryInterface(IMarshal *iface, REFIID iid, void **obj)
{
    marshal *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);

    if(IsEqualIID(iid, &IID_IUnknown) ||
       IsEqualIID(iid, &IID_IMarshal))
    {
        *obj = iface;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(iid));
        *obj = NULL;
        return E_NOINTERFACE;
    }

    IMarshal_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI marshal_AddRef(IMarshal *iface)
{
    marshal *This = impl_from_IMarshal(iface);
    TRACE("(%p)\n", This);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI marshal_Release(IMarshal *iface)
{
    marshal *This = impl_from_IMarshal(iface);
    LONG ref;

    TRACE("(%p)\n", This);

    ref = InterlockedDecrement(&This->ref);
    if(ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI marshal_GetUnmarshalClass(IMarshal *iface, REFIID iid, void *obj,
                                                DWORD dwDestContext, void *pvDestContext,
                                                DWORD mshlflags, CLSID *clsid)
{
    marshal *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
          pvDestContext, mshlflags, clsid);

    *clsid = This->unmarshal_class;
    return S_OK;
}

static HRESULT WINAPI marshal_GetMarshalSizeMax(IMarshal *iface, REFIID iid, void *obj,
                                                DWORD dwDestContext, void *pvDestContext,
                                                DWORD mshlflags, DWORD *size)
{
    marshal *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%s, %p, %08x, %p, %08x, %p)\n", This, debugstr_guid(iid), obj, dwDestContext,
          pvDestContext, mshlflags, size);

    return CoGetMarshalSizeMax(size, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext,
                               mshlflags);
}

static HRESULT WINAPI marshal_MarshalInterface(IMarshal *iface, IStream *stream, REFIID iid,
                                               void *obj, DWORD dwDestContext, void *pvDestContext,
                                               DWORD mshlflags)
{
    marshal *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%p, %s, %p, %08x, %p, %08x)\n", This, stream, debugstr_guid(iid), obj, dwDestContext,
          pvDestContext, mshlflags);

    return CoMarshalInterface(stream, &IID_IWineRowServer, This->outer, dwDestContext, pvDestContext, mshlflags);
}

static HRESULT WINAPI marshal_UnmarshalInterface(IMarshal *iface, IStream *stream,
                                                 REFIID iid, void **obj)
{
    marshal *This = impl_from_IMarshal(iface);
    HRESULT hr;
    IWineRowServer *server;
    IUnknown *proxy;

    TRACE("(%p)->(%p, %s, %p)\n", This, stream, debugstr_guid(iid), obj);
    *obj = NULL;

    hr = CoUnmarshalInterface(stream, &IID_IWineRowServer, (void**)&server);
    if(SUCCEEDED(hr))
    {
        hr = create_proxy(server, &This->unmarshal_class, &proxy);
        if(SUCCEEDED(hr))
        {
            hr = IUnknown_QueryInterface(proxy, iid, obj);
            IUnknown_Release(proxy);
        }
        IWineRowServer_Release(server);
    }

    TRACE("returing %p\n", *obj);
    return hr;
}

static HRESULT WINAPI marshal_ReleaseMarshalData(IMarshal *iface, IStream *stream)
{
    marshal *This = impl_from_IMarshal(iface);
    TRACE("(%p)->(%p)\n", This, stream);
    return CoReleaseMarshalData(stream);
}

static HRESULT WINAPI marshal_DisconnectObject(IMarshal *iface, DWORD dwReserved)
{
    marshal *This = impl_from_IMarshal(iface);
    FIXME("(%p)->(%08x)\n", This, dwReserved);

    return E_NOTIMPL;
}

static const IMarshalVtbl marshal_vtbl =
{
    marshal_QueryInterface,
    marshal_AddRef,
    marshal_Release,
    marshal_GetUnmarshalClass,
    marshal_GetMarshalSizeMax,
    marshal_MarshalInterface,
    marshal_UnmarshalInterface,
    marshal_ReleaseMarshalData,
    marshal_DisconnectObject
};

static HRESULT create_marshal(IUnknown *outer, const CLSID *class, void **obj)
{
    marshal *marshal;

    TRACE("(%p, %p)\n", outer, obj);
    *obj = NULL;

    marshal = HeapAlloc(GetProcessHeap(), 0, sizeof(*marshal));
    if(!marshal) return E_OUTOFMEMORY;

    marshal->unmarshal_class = *class;
    marshal->outer = outer; /* don't ref outer unk */
    marshal->marshal_vtbl = &marshal_vtbl;
    marshal->ref = 1;

    *obj = &marshal->marshal_vtbl;
    TRACE("returing %p\n", *obj);
    return S_OK;
}

HRESULT create_row_marshal(IUnknown *outer, void **obj)
{
    TRACE("(%p, %p)\n", outer, obj);
    return create_marshal(outer, &CLSID_wine_row_proxy, obj);
}

HRESULT create_rowset_marshal(IUnknown *outer, void **obj)
{
    TRACE("(%p, %p)\n", outer, obj);
    return create_marshal(outer, &CLSID_wine_rowset_proxy, obj);
}
