From 83eb77928841a8db41ed400d36376025c88ce568 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Wed, 3 Feb 2010 11:48:21 +0000 Subject: [PATCH] msdaps: Add support for remoting IRow_GetColumns. --- .gitignore | 1 + dlls/msdaps/Makefile.in | 3 +- dlls/msdaps/row_server.c | 139 ++++++++++++++++++++++++++++++++++++++++++++- dlls/msdaps/row_server.idl | 36 ++++++++++++ 4 files changed, 175 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 6c268839124..b11e8b5b76b 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ dlls/msdaps/msdaps_i.c dlls/msdaps/msdaps_p.c dlls/msdaps/row_server.h dlls/msdaps/row_server_i.c +dlls/msdaps/row_server_p.c dlls/mshtml.tlb/mshtml_tlb.tlb dlls/mshtml/nsiface.h dlls/msi/cond.tab.c diff --git a/dlls/msdaps/Makefile.in b/dlls/msdaps/Makefile.in index 7287cd6f6d3..8836f589b79 100644 --- a/dlls/msdaps/Makefile.in +++ b/dlls/msdaps/Makefile.in @@ -20,7 +20,8 @@ IDL_I_SRCS = \ row_server.idl IDL_P_SRCS = \ - msdaps.idl + msdaps.idl \ + row_server.idl @MAKE_DLL_RULES@ diff --git a/dlls/msdaps/row_server.c b/dlls/msdaps/row_server.c index 97e56578be9..8a88d8c80fa 100644 --- a/dlls/msdaps/row_server.c +++ b/dlls/msdaps/row_server.c @@ -39,6 +39,39 @@ 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 { @@ -125,13 +158,83 @@ static HRESULT WINAPI server_GetMarshal(IWineRowServer *iface, IMarshal **marsha 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); + + FIXME("(%p)->(%p, %p, %s, %08x, %s, %p): stub\n", This, pUnkOuter, pColumnID, debugstr_guid(rguidColumnType), + dwBindFlags, debugstr_guid(riid), ppUnk); + return E_NOTIMPL; +} + static const IWineRowServerVtbl server_vtbl = { server_QueryInterface, server_AddRef, server_Release, server_SetInnerUnk, - server_GetMarshal + server_GetMarshal, + server_GetColumns, + server_GetSourceRowset, + server_Open }; static HRESULT create_server(IUnknown *outer, const CLSID *class, void **obj) @@ -231,10 +334,40 @@ static ULONG WINAPI row_Release(IRow *iface) 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; - FIXME("(%p)->(%d, %p): stub\n", This, cColumns, rgColumns); + TRACE("(%p)->(%d, %p)\n", This, cColumns, rgColumns); - return E_NOTIMPL; + 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, diff --git a/dlls/msdaps/row_server.idl b/dlls/msdaps/row_server.idl index f6d63038342..1242aee67fd 100644 --- a/dlls/msdaps/row_server.idl +++ b/dlls/msdaps/row_server.idl @@ -30,6 +30,42 @@ interface IWineRowServer : IUnknown [local] HRESULT SetInnerUnk([in] IUnknown *unknown); [local] HRESULT GetMarshal([out] IMarshal **marshal); + + + /* IRow */ + +typedef struct +{ + DBID columnid; + DBLENGTH max_len; + DBTYPE type; + BYTE precision; + BYTE scale; +} wine_getcolumns_in; + +typedef struct +{ + VARIANT v; + DBLENGTH data_len; + DBSTATUS status; +} wine_getcolumns_out; + + HRESULT GetColumns([in] DBORDINAL num_cols, + [in, size_is(num_cols)] wine_getcolumns_in *in_data, + [out, size_is(num_cols)] wine_getcolumns_out *out_cols); + + HRESULT GetSourceRowset([in] REFIID riid, + [out, iid_is(riid)] IUnknown **ppRowset, + [out] HROW *phRow); + + HRESULT Open([in, unique] IUnknown *pUnkOuter, + [in] DBID *pColumnID, + [in] REFGUID rguidColumnType, + [in] DWORD dwBindFlags, + [in] REFIID riid, + [out, iid_is(riid)] IUnknown **ppUnk); + + } [ -- 2.11.4.GIT