/*
 *    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

#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
{
    IWineRowServer IWineRowServer_iface;

    LONG ref;

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

static inline server *impl_from_IWineRowServer(IWineRowServer *iface)
{
    return CONTAINING_RECORD(iface, server, IWineRowServer_iface);
}

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)->(%ld, %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("%ld:\tmax_len %ld 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)->(%ld, %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("%ld:\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)->(%ld, %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, %ld, %ld, %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 %ld 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)->(%ld, %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, %ld, %p, %ld, %ld, %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, %ld, %p, %ld, %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->IWineRowServer_iface.lpVtbl = &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
{
    IRow IRow_iface;
    IRowChange IRowChange_iface;

    LONG ref;

    IWineRowServer *server;
} row_proxy;

static inline row_proxy *impl_from_IRow(IRow *iface)
{
    return CONTAINING_RECORD(iface, row_proxy, IRow_iface);
}

static inline row_proxy *impl_from_IRowChange(IRowChange *iface)
{
    return CONTAINING_RECORD(iface, row_proxy, IRowChange_iface);
}

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->IRow_iface;
    }
    else if(IsEqualIID(iid, &IID_IRowChange))
    {
        *obj = &This->IRowChange_iface;
    }
    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)->(%ld, %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("%ld:\tdata %p data_len %ld status %08x max_len %ld 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)->(%ld, %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("%ld: wtype %04x max %08lx len %08lx\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->IRow_iface.lpVtbl = &row_vtbl;
    proxy->IRowChange_iface.lpVtbl = &row_change_vtbl;
    proxy->ref = 1;
    IWineRowServer_AddRef(server);
    proxy->server = server;

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

typedef struct
{
    IRowsetLocate IRowsetLocate_iface;
    IRowsetInfo IRowsetInfo_iface;
    IAccessor IAccessor_iface;

    LONG ref;

    IWineRowServer *server;
} rowset_proxy;

static inline rowset_proxy *impl_from_IRowsetLocate(IRowsetLocate *iface)
{
    return CONTAINING_RECORD(iface, rowset_proxy, IRowsetLocate_iface);
}

static inline rowset_proxy *impl_from_IRowsetInfo(IRowsetInfo *iface)
{
    return CONTAINING_RECORD(iface, rowset_proxy, IRowsetInfo_iface);
}

static inline rowset_proxy *impl_from_IAccessor(IAccessor *iface)
{
    return CONTAINING_RECORD(iface, rowset_proxy, IAccessor_iface);
}

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

    *obj = NULL;

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

    IRowsetLocate_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI rowsetlocate_AddRef(IRowsetLocate *iface)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    TRACE("(%p)\n", This);

    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI rowsetlocate_Release(IRowsetLocate *iface)
{
    rowset_proxy *This = impl_from_IRowsetLocate(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 rowsetlocate_AddRefRows(IRowsetLocate *iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                              DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    HRESULT hr;
    DBREFCOUNT *refs = rgRefCounts;
    DBSTATUS *stats = rgRowStatus;

    TRACE("(%p)->(%ld, %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 rowsetlocate_GetData(IRowsetLocate *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
{
    rowset_proxy *This = impl_from_IRowsetLocate(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 = IRowsetLocate_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 %ld bindings\n", count);
    for(i = 0; i < count; i++)
    {
        TRACE("%ld\tord %ld offs: val %ld len %ld stat %ld, part %x, max len %ld 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 rowsetlocate_GetNextRows(IRowsetLocate *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
                                               DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    HRESULT hr;
    HROW *rows = NULL;

    TRACE("(%p)->(%08lx, %ld, %ld, %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 rowsetlocate_ReleaseRows(IRowsetLocate *iface, DBCOUNTITEM cRows, const HROW rghRows[],
                                               DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);
    HRESULT hr;
    DBROWOPTIONS *options = rgRowOptions;
    DBREFCOUNT *refs = rgRefCounts;
    DBROWSTATUS *status = rgRowStatus;

    TRACE("(%p)->(%ld, %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 rowsetlocate_RestartPosition(IRowsetLocate* iface, HCHAPTER hReserved)
{
    rowset_proxy *This = impl_from_IRowsetLocate(iface);

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

    return E_NOTIMPL;
}

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, %ld, %p, %ld, %ld, %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, %ld, %p, %ld, %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
};

static 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->IRowsetLocate_iface.lpVtbl = &rowsetlocate_vtbl;
    proxy->IRowsetInfo_iface.lpVtbl = &rowsetinfo_vtbl;
    proxy->IAccessor_iface.lpVtbl = &accessor_vtbl;
    proxy->ref = 1;
    IWineRowServer_AddRef(server);
    proxy->server = server;

    *obj = (IUnknown *)&proxy->IRowsetLocate_iface;
    TRACE("returning %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
{
    IMarshal IMarshal_iface;

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

static inline marshal *impl_from_IMarshal(IMarshal *iface)
{
    return CONTAINING_RECORD(iface, marshal, IMarshal_iface);
}

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("returning %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->IMarshal_iface.lpVtbl = &marshal_vtbl;
    marshal->ref = 1;

    *obj = &marshal->IMarshal_iface;
    TRACE("returning %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);
}
