msdaps: Add support for remoting IRow_GetColumns.
diff --git a/.gitignore b/.gitignore
index 6c26883..b11e8b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,7 @@
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 7287cd6..8836f58 100644
--- a/dlls/msdaps/Makefile.in
+++ b/dlls/msdaps/Makefile.in
@@ -20,7 +20,8 @@
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 97e5657..8a88d8c 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 @@
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 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 f6d6303..1242aee 100644
--- a/dlls/msdaps/row_server.idl
+++ b/dlls/msdaps/row_server.idl
@@ -30,6 +30,42 @@
[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);
+
+
}
[