From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 201 ++++++++++++++++++++--------------- dlls/msado15/tests/msado15.c | 17 +-- 2 files changed, 125 insertions(+), 93 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 8e2e0edba14..9e9f8f117ab 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -270,7 +270,7 @@ static HRESULT WINAPI field_get_Type( Field *iface, DataTypeEnum *type )
static LONG get_column_count( struct recordset *recordset ) { - return recordset->fields.count; + return recordset->fields.count == -1 ? 0 : recordset->fields.count; }
static HRESULT WINAPI field_get_Value( Field *iface, VARIANT *val ) @@ -955,12 +955,115 @@ static HRESULT WINAPI fields_Invoke( Fields *iface, DISPID member, REFIID riid, return hr; }
+static BOOL resize_fields( struct fields *fields, ULONG count ) +{ + if (count > fields->allocated) + { + struct field **tmp; + ULONG new_size = max( count, fields->allocated * 2 ); + if (!(tmp = realloc( fields->field, new_size * sizeof(*tmp) ))) return FALSE; + fields->field = tmp; + fields->allocated = new_size; + } + + return TRUE; +} + +static HRESULT append_field( struct fields *fields, const DBCOLUMNINFO *info ) +{ + struct field *field; + HRESULT hr; + + hr = Field_create( info->pwszName, fields->count, fields_get_recordset(fields), &field ); + if (hr != S_OK) return hr; + field->type = info->wType; + field->defined_size = info->ulColumnSize; + if (info->dwFlags != adFldUnspecified) field->attrs = info->dwFlags; + field->prec = info->bPrecision; + field->scale = info->bScale; + + if (!(resize_fields( fields, fields->count + 1 ))) + { + Field_Release( &field->Field_iface ); + return E_OUTOFMEMORY; + } + + fields->field[fields->count++] = field; + return S_OK; +} + +static HRESULT init_fields( struct fields *fields ) +{ + struct recordset *rec = fields_get_recordset( fields ); + DBCOLUMNINFO *colinfo = NULL; + OLECHAR *strbuf = NULL; + DBORDINAL i, columns; + IColumnsInfo *info; + HRESULT hr; + + if (fields->count != -1) return S_OK; + + if (!rec->row_set) + { + fields->count = 0; + return S_OK; + } + + hr = IRowset_QueryInterface( rec->row_set, &IID_IColumnsInfo, (void **)&info ); + if (FAILED(hr) || !info) + { + fields->count = 0; + return S_OK; + } + + hr = IColumnsInfo_GetColumnInfo( info, &columns, &colinfo, &strbuf ); + IColumnsInfo_Release( info ); + if (FAILED(hr)) return hr; + + if (!resize_fields( fields, columns )) + { + CoTaskMemFree( colinfo ); + CoTaskMemFree( strbuf ); + return E_OUTOFMEMORY; + } + + fields->count = 0; + for (i = 0; i < columns; i++) + { + TRACE("Adding Column %Iu, pwszName: %s, pTypeInfo %p, iOrdinal %Iu, dwFlags 0x%08lx, " + "ulColumnSize %Iu, wType %d, bPrecision %d, bScale %d\n", + i, debugstr_w(colinfo[i].pwszName), colinfo[i].pTypeInfo, colinfo[i].iOrdinal, + colinfo[i].dwFlags, colinfo[i].ulColumnSize, colinfo[i].wType, + colinfo[i].bPrecision, colinfo[i].bScale); + + hr = append_field(fields, &colinfo[i]); + if (FAILED(hr)) + { + for (; i > 0; i--) + Field_Release(&fields->field[i - 1]->Field_iface); + fields->count = -1; + + CoTaskMemFree( colinfo ); + CoTaskMemFree( strbuf ); + + ERR("Failed to add Field name - 0x%08lx\n", hr); + return hr; + } + } + + CoTaskMemFree( colinfo ); + CoTaskMemFree( strbuf ); + return S_OK; +} + static HRESULT WINAPI fields_get_Count( Fields *iface, LONG *count ) { struct fields *fields = impl_from_Fields( iface ); + HRESULT hr;
TRACE( "%p, %p\n", fields, count );
+ if ((hr = init_fields( fields )) != S_OK) return hr; *count = fields->count; return S_OK; } @@ -1035,6 +1138,7 @@ static HRESULT WINAPI fields_get_Item( Fields *iface, VARIANT index, Field **obj
TRACE( "%p, %s, %p\n", fields, debugstr_variant(&index), obj );
+ if ((hr = init_fields( fields )) != S_OK) return hr; if ((hr = map_index( fields, &index, &i )) != S_OK) return hr;
Field_AddRef( &fields->field[i]->Field_iface ); @@ -1042,52 +1146,16 @@ static HRESULT WINAPI fields_get_Item( Fields *iface, VARIANT index, Field **obj return S_OK; }
-static BOOL resize_fields( struct fields *fields, ULONG count ) -{ - if (count > fields->allocated) - { - struct field **tmp; - ULONG new_size = max( count, fields->allocated * 2 ); - if (!(tmp = realloc( fields->field, new_size * sizeof(*tmp) ))) return FALSE; - fields->field = tmp; - fields->allocated = new_size; - } - - fields->count = count; - return TRUE; -} - -static HRESULT append_field( struct fields *fields, const DBCOLUMNINFO *info ) -{ - struct field *field; - HRESULT hr; - - hr = Field_create( info->pwszName, fields->count, fields_get_recordset(fields), &field ); - if (hr != S_OK) return hr; - field->type = info->wType; - field->defined_size = info->ulColumnSize; - if (info->dwFlags != adFldUnspecified) field->attrs = info->dwFlags; - field->prec = info->bPrecision; - field->scale = info->bScale; - - if (!(resize_fields( fields, fields->count + 1 ))) - { - Field_Release( &field->Field_iface ); - return E_OUTOFMEMORY; - } - - fields->field[fields->count - 1] = field; - return S_OK; -} - static HRESULT WINAPI fields__Append( Fields *iface, BSTR name, DataTypeEnum type, ADO_LONGPTR size, FieldAttributeEnum attr ) { struct fields *fields = impl_from_Fields( iface ); DBCOLUMNINFO colinfo; + HRESULT hr;
TRACE( "%p, %s, %u, %Id, %d\n", fields, debugstr_w(name), type, size, attr );
if (fields_get_recordset(fields)->state != adStateClosed) return MAKE_ADO_HRESULT( adErrIllegalOperation ); + if ((hr = init_fields( fields )) != S_OK) return hr;
memset( &colinfo, 0, sizeof(colinfo) ); colinfo.pwszName = name; @@ -1187,50 +1255,12 @@ static const ISupportErrorInfoVtbl fields_supporterrorinfo_vtbl = fields_supporterrorinfo_InterfaceSupportsErrorInfo };
-static void map_rowset_fields(struct recordset *recordset, struct fields *fields) -{ - HRESULT hr; - IColumnsInfo *columninfo; - DBORDINAL columns, i; - DBCOLUMNINFO *colinfo; - OLECHAR *stringsbuffer; - - /* Not Finding the interface or GetColumnInfo failing just causes 0 Fields to be returned */ - hr = IRowset_QueryInterface(recordset->row_set, &IID_IColumnsInfo, (void**)&columninfo); - if (FAILED(hr)) - return; - - hr = IColumnsInfo_GetColumnInfo(columninfo, &columns, &colinfo, &stringsbuffer); - if (SUCCEEDED(hr)) - { - for (i=0; i < columns; i++) - { - TRACE("Adding Column %Iu, pwszName: %s, pTypeInfo %p, iOrdinal %Iu, dwFlags 0x%08lx, " - "ulColumnSize %Iu, wType %d, bPrecision %d, bScale %d\n", - i, debugstr_w(colinfo[i].pwszName), colinfo[i].pTypeInfo, colinfo[i].iOrdinal, - colinfo[i].dwFlags, colinfo[i].ulColumnSize, colinfo[i].wType, - colinfo[i].bPrecision, colinfo[i].bScale); - - hr = append_field(fields, &colinfo[i]); - if (FAILED(hr)) - { - ERR("Failed to add Field name - 0x%08lx\n", hr); - return; - } - } - - CoTaskMemFree(colinfo); - CoTaskMemFree(stringsbuffer); - } - - IColumnsInfo_Release(columninfo); -} - -static void fields_init( struct recordset *recordset ) +static void Fields_create( struct recordset *recordset ) { memset( &recordset->fields, 0, sizeof(recordset->fields) ); recordset->fields.Fields_iface.lpVtbl = &fields_vtbl; recordset->fields.ISupportErrorInfo_iface.lpVtbl = &fields_supporterrorinfo_vtbl; + recordset->fields.count = -1; }
static inline struct recordset *impl_from_Recordset( _Recordset *iface ) @@ -1304,7 +1334,7 @@ static void close_recordset( struct recordset *recordset ) free(recordset->haccessors); recordset->haccessors = NULL; } - recordset->fields.count = 0; + recordset->fields.count = -1;
for (row = 0; row < recordset->count; row++) for (col = 0; col < col_count; col++) VariantClear( &recordset->data[row * col_count + col] ); @@ -2036,14 +2066,14 @@ static HRESULT load_all_recordset_data(struct recordset *recordset, IUnknown *ro DBBYTEOFFSET datasize) { IRowset *rowset2; - DBORDINAL columns; + LONG columns; HRESULT hr; DBCOUNTITEM obtained; HROW *row = NULL; int datarow = 0, datacol; char *data;
- columns = get_column_count(recordset); + hr = Fields_get_Count(&recordset->fields.Fields_iface, &columns);
hr = IUnknown_QueryInterface(rowset, &IID_IRowset, (void**)&rowset2); if (FAILED(hr)) @@ -2268,7 +2298,7 @@ static HRESULT WINAPI recordset_Open( _Recordset *iface, VARIANT source, VARIANT return hr; }
- if (get_column_count(recordset)) + if (recordset->fields.count != -1) { DBCOLUMNINFO *info; int i; @@ -2952,9 +2982,6 @@ static HRESULT WINAPI rsconstruction_put_Rowset(ADORecordsetConstruction *iface, if ( recordset->row_set ) IRowset_Release( recordset->row_set ); recordset->row_set = rowset;
- if ( !get_column_count(recordset) ) - map_rowset_fields(recordset, &recordset->fields); - recordset->state = adStateOpen; return S_OK; } @@ -3024,7 +3051,7 @@ HRESULT Recordset_create( void **obj ) VariantInit( &recordset->filter ); recordset->columntypes = NULL; recordset->haccessors = NULL; - fields_init( recordset ); + Fields_create( recordset );
*obj = &recordset->Recordset_iface; TRACE( "returning iface %p\n", *obj ); diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index cbc0feda12f..10e9dd5105b 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -1067,10 +1067,10 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) todo_wine CHECK_CALLED( rowset_QI_IRowsetExactScroll ); todo_wine CHECK_CALLED( rowset_QI_IDBAsynchStatus ); todo_wine CHECK_CALLED( rowset_info_GetProperties ); - if (exact_scroll) CHECK_CALLED( rowset_QI_IColumnsInfo ); - else todo_wine CHECK_NOT_CALLED( rowset_QI_IColumnsInfo ); - if (exact_scroll) CHECK_CALLED( column_info_GetColumnInfo ); - else todo_wine CHECK_NOT_CALLED( column_info_GetColumnInfo ); + if (exact_scroll) todo_wine CHECK_CALLED( rowset_QI_IColumnsInfo ); + else CHECK_NOT_CALLED( rowset_QI_IColumnsInfo ); + if (exact_scroll) todo_wine CHECK_CALLED( column_info_GetColumnInfo ); + else CHECK_NOT_CALLED( column_info_GetColumnInfo ); ok( hr == S_OK, "got %08lx\n", hr );
hr = _Recordset_get_State( recordset, &state ); @@ -1081,8 +1081,13 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) SET_EXPECT( rowset_QI_IColumnsInfo ); SET_EXPECT( column_info_GetColumnInfo ); hr = Fields_get_Count( fields, &count ); - todo_wine CHECK_CALLED( rowset_QI_IColumnsInfo ); - todo_wine CHECK_CALLED( column_info_GetColumnInfo ); + ok( hr == S_OK, "got %08lx\n", hr ); + CHECK_CALLED( rowset_QI_IColumnsInfo ); + CHECK_CALLED( column_info_GetColumnInfo ); + ok( count == 1, "got %ld\n", count ); + + hr = Fields_get_Count( fields, &count ); + ok( hr == S_OK, "got %08lx\n", hr ); ok( count == 1, "got %ld\n", count );
V_VT( &index ) = VT_BSTR;
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/recordset.c | 32 +++++++++++++++++++++++++++++++- dlls/msado15/tests/msado15.c | 9 +++++---- 2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 9e9f8f117ab..cfd27ae1f73 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -89,6 +89,7 @@ struct recordset LONG cache_size; ADO_LONGPTR max_records; VARIANT filter; + BOOL use_bookmarks;
DBTYPE *columntypes; HACCESSOR hacc_empty; /* haccessor for adding empty rows */ @@ -1036,6 +1037,9 @@ static HRESULT init_fields( struct fields *fields ) colinfo[i].dwFlags, colinfo[i].ulColumnSize, colinfo[i].wType, colinfo[i].bPrecision, colinfo[i].bScale);
+ /* skip bookmark column */ + if (!i && rec->use_bookmarks) continue; + hr = append_field(fields, &colinfo[i]); if (FAILED(hr)) { @@ -1314,6 +1318,7 @@ static void close_recordset( struct recordset *recordset ) recordset->accessor = NULL;
VariantClear( &recordset->filter ); + recordset->use_bookmarks = FALSE;
col_count = get_column_count( recordset );
@@ -2969,8 +2974,10 @@ static HRESULT WINAPI rsconstruction_get_Rowset(ADORecordsetConstruction *iface, static HRESULT WINAPI rsconstruction_put_Rowset(ADORecordsetConstruction *iface, IUnknown *unk) { struct recordset *recordset = impl_from_ADORecordsetConstruction( iface ); - HRESULT hr; + DBPROPSET *propset = NULL; + IRowsetInfo *info; IRowset *rowset; + HRESULT hr;
TRACE( "%p, %p\n", recordset, unk );
@@ -2982,6 +2989,29 @@ static HRESULT WINAPI rsconstruction_put_Rowset(ADORecordsetConstruction *iface, if ( recordset->row_set ) IRowset_Release( recordset->row_set ); recordset->row_set = rowset;
+ hr = IRowset_QueryInterface( rowset, &IID_IRowsetInfo, (void**)&info ); + if ( SUCCEEDED(hr) && info) + { + DBPROPIDSET propidset; + DBPROPID id[1]; + ULONG count; + + propidset.rgPropertyIDs = id; + propidset.cPropertyIDs = ARRAY_SIZE(id); + propidset.guidPropertySet = DBPROPSET_ROWSET; + id[0] = DBPROP_BOOKMARKS; + hr = IRowsetInfo_GetProperties( info, 1, &propidset, &count, &propset ); + IRowsetInfo_Release( info ); + if ( FAILED(hr) ) propset = NULL; + } + if ( propset ) + { + if (V_VT(&propset->rgProperties[0].vValue) == VT_BOOL && V_BOOL(&propset->rgProperties[0].vValue)) + recordset->use_bookmarks = TRUE; + CoTaskMemFree( propset->rgProperties ); + CoTaskMemFree( propset ); + } + recordset->state = adStateOpen; return S_OK; } diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 10e9dd5105b..959ffcfe832 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -569,10 +569,11 @@ static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG const DBPROPIDSET propertyidsets[], ULONG *out_count, DBPROPSET **propertysets1) { CHECK_EXPECT(rowset_info_GetProperties); - ok( count == 2, "got %ld\n", count ); + todo_wine ok( count == 2, "got %ld\n", count );
ok( IsEqualIID(&DBPROPSET_ROWSET, &propertyidsets[0].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[0].guidPropertySet)); - ok( propertyidsets[0].cPropertyIDs == 17, "got %ld\n", propertyidsets[0].cPropertyIDs ); + todo_wine ok( propertyidsets[0].cPropertyIDs == 17, "got %ld\n", propertyidsets[0].cPropertyIDs ); + if (count < 2) return E_NOTIMPL;
ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET, &propertyidsets[1].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[1].guidPropertySet)); ok( propertyidsets[1].cPropertyIDs == 1, "got %ld\n", propertyidsets[1].cPropertyIDs ); @@ -1063,10 +1064,10 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) SET_EXPECT( column_info_GetColumnInfo ); hr = ADORecordsetConstruction_put_Rowset( construct, rowset ); CHECK_CALLED( rowset_QI_IRowset ); - todo_wine CHECK_CALLED( rowset_QI_IRowsetInfo ); + CHECK_CALLED( rowset_QI_IRowsetInfo ); todo_wine CHECK_CALLED( rowset_QI_IRowsetExactScroll ); todo_wine CHECK_CALLED( rowset_QI_IDBAsynchStatus ); - todo_wine CHECK_CALLED( rowset_info_GetProperties ); + CHECK_CALLED( rowset_info_GetProperties ); if (exact_scroll) todo_wine CHECK_CALLED( rowset_QI_IColumnsInfo ); else CHECK_NOT_CALLED( rowset_QI_IColumnsInfo ); if (exact_scroll) todo_wine CHECK_CALLED( column_info_GetColumnInfo );
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/rowset.c | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/dlls/msado15/rowset.c b/dlls/msado15/rowset.c index 286d86871fd..7100fe919cc 100644 --- a/dlls/msado15/rowset.c +++ b/dlls/msado15/rowset.c @@ -31,6 +31,7 @@ struct rowset IColumnsInfo IColumnsInfo_iface; IRowsetChange IRowsetChange_iface; IAccessor IAccessor_iface; + IRowsetInfo IRowsetInfo_iface; LONG refs;
int columns_cnt; @@ -65,6 +66,11 @@ static inline struct rowset *impl_from_IAccessor(IAccessor *iface) return CONTAINING_RECORD(iface, struct rowset, IAccessor_iface); }
+static inline struct rowset *impl_from_IRowsetInfo(IRowsetInfo *iface) +{ + return CONTAINING_RECORD(iface, struct rowset, IRowsetInfo_iface); +} + static HRESULT WINAPI rowset_QueryInterface(IRowsetExactScroll *iface, REFIID riid, void **ppv) { struct rowset *rowset = impl_from_IRowsetExactScroll(iface); @@ -92,6 +98,10 @@ static HRESULT WINAPI rowset_QueryInterface(IRowsetExactScroll *iface, REFIID ri { *ppv = &rowset->IAccessor_iface; } + else if(IsEqualGUID(&IID_IRowsetInfo, riid)) + { + *ppv = &rowset->IRowsetInfo_iface; + }
if(*ppv) { @@ -536,6 +546,61 @@ static struct IAccessorVtbl accessor_vtbl = accessor_ReleaseAccessor };
+static HRESULT WINAPI rowset_info_QueryInterface(IRowsetInfo *iface, REFIID riid, void **ppv) +{ + struct rowset *rowset = impl_from_IRowsetInfo(iface); + return IRowsetExactScroll_QueryInterface(&rowset->IRowsetExactScroll_iface, riid, ppv); +} + +static ULONG WINAPI rowset_info_AddRef(IRowsetInfo *iface) +{ + struct rowset *rowset = impl_from_IRowsetInfo(iface); + return IRowsetExactScroll_AddRef(&rowset->IRowsetExactScroll_iface); +} + +static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface) +{ + struct rowset *rowset = impl_from_IRowsetInfo(iface); + return IRowsetExactScroll_Release(&rowset->IRowsetExactScroll_iface); +} + +static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG cPropertyIDSets, + const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets) +{ + struct rowset *rowset = impl_from_IRowsetInfo(iface); + + FIXME("%p, %lu, %p, %p, %p\n", rowset, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets); + return E_NOTIMPL; +} + +static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface, + DBORDINAL iOrdinal, REFIID riid, IUnknown **ppReferencedRowset) +{ + struct rowset *rowset = impl_from_IRowsetInfo(iface); + + FIXME("%p, %Iu, %s, %p\n", rowset, iOrdinal, wine_dbgstr_guid(riid), ppReferencedRowset); + return E_NOTIMPL; +} + +static HRESULT WINAPI rowset_info_GetSpecification(IRowsetInfo *iface, + REFIID riid, IUnknown **ppSpecification) +{ + struct rowset *rowset = impl_from_IRowsetInfo(iface); + + FIXME("%p, %s, %p\n", rowset, wine_dbgstr_guid(riid), ppSpecification); + return E_NOTIMPL; +} + +static struct IRowsetInfoVtbl rowset_info_vtbl = +{ + rowset_info_QueryInterface, + rowset_info_AddRef, + rowset_info_Release, + rowset_info_GetProperties, + rowset_info_GetReferencedRowset, + rowset_info_GetSpecification +}; + HRESULT create_mem_rowset(int count, const DBCOLUMNINFO *info, IUnknown **ret) { struct rowset *rowset; @@ -548,6 +613,7 @@ HRESULT create_mem_rowset(int count, const DBCOLUMNINFO *info, IUnknown **ret) rowset->IColumnsInfo_iface.lpVtbl = &columns_info_vtbl; rowset->IRowsetChange_iface.lpVtbl = &rowset_change_vtbl; rowset->IAccessor_iface.lpVtbl = &accessor_vtbl; + rowset->IRowsetInfo_iface.lpVtbl = &rowset_info_vtbl; rowset->refs = 1;
rowset->columns_cnt = count;
From: Piotr Caban piotr@codeweavers.com
--- dlls/msado15/rowset.c | 48 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/dlls/msado15/rowset.c b/dlls/msado15/rowset.c index 7100fe919cc..79be537d9b9 100644 --- a/dlls/msado15/rowset.c +++ b/dlls/msado15/rowset.c @@ -564,13 +564,53 @@ static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface) return IRowsetExactScroll_Release(&rowset->IRowsetExactScroll_iface); }
-static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG cPropertyIDSets, - const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets) +static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG propidsets_count, + const DBPROPIDSET propidsets[], ULONG *count, DBPROPSET **propsets) { struct rowset *rowset = impl_from_IRowsetInfo(iface); + ULONG i, j, c = 0; + DBPROP *prop;
- FIXME("%p, %lu, %p, %p, %p\n", rowset, cPropertyIDSets, rgPropertyIDSets, pcPropertySets, prgPropertySets); - return E_NOTIMPL; + TRACE("%p, %lu, %p, %p, %p\n", rowset, propidsets_count, propidsets, count, propsets); + + for (i = 0; i <propidsets_count; i++) + { + if (!IsEqualGUID(&DBPROPSET_ROWSET, &propidsets[i].guidPropertySet)) + { + FIXME("property set: %s\n", wine_dbgstr_guid(&propidsets[i].guidPropertySet)); + return E_NOTIMPL; + } + + for (j = 0; j < propidsets[i].cPropertyIDs; j++) + { + if (propidsets[i].rgPropertyIDs[j] != DBPROP_BOOKMARKS) + { + FIXME("DBPROPSET_ROWSET property %lu\n", propidsets[i].rgPropertyIDs[j]); + return E_NOTIMPL; + } + c++; + } + } + if (c != 1) return E_NOTIMPL; + + prop = CoTaskMemAlloc(sizeof(*prop)); + if (!prop) return E_OUTOFMEMORY; + *propsets = CoTaskMemAlloc(sizeof(**propsets)); + if (!*propsets) + { + CoTaskMemFree(prop); + return E_OUTOFMEMORY; + } + + *count = 1; + (*propsets)->rgProperties = prop; + (*propsets)->cProperties = 1; + (*propsets)->guidPropertySet = DBPROPSET_ROWSET; + memset(prop, 0, sizeof(*prop)); + prop->dwPropertyID = DBPROP_BOOKMARKS; + V_VT(&prop->vValue) = VT_BOOL; + V_BOOL(&prop->vValue) = VARIANT_TRUE; + return S_OK; }
static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface,