From: Hans Leidekker Subject: [PATCH 7/8] msado15: Add ISupportErrorInfo support to Field, Fields and _Recordset. Message-Id: <20191213145231.18675-7-hans@codeweavers.com> Date: Fri, 13 Dec 2019 15:52:30 +0100 Signed-off-by: Hans Leidekker --- dlls/msado15/recordset.c | 188 +++++++++++++++++++++++++++++------ dlls/msado15/tests/msado15.c | 32 ++++++ 2 files changed, 192 insertions(+), 28 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index cd623d0dc8..56cdee6652 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -34,36 +34,39 @@ WINE_DEFAULT_DEBUG_CHANNEL(msado15); struct fields; struct recordset { - _Recordset Recordset_iface; - LONG refs; - LONG state; - struct fields *fields; - LONG count; - LONG allocated; - LONG index; - VARIANT *data; + _Recordset Recordset_iface; + ISupportErrorInfo ISupportErrorInfo_iface; + LONG refs; + LONG state; + struct fields *fields; + LONG count; + LONG allocated; + LONG index; + VARIANT *data; }; struct fields { - Fields Fields_iface; - LONG refs; - Field **field; - ULONG count; - ULONG allocated; - struct recordset *recordset; + Fields Fields_iface; + ISupportErrorInfo ISupportErrorInfo_iface; + LONG refs; + Field **field; + ULONG count; + ULONG allocated; + struct recordset *recordset; }; struct field { - Field Field_iface; - LONG refs; - WCHAR *name; - DataTypeEnum type; - LONG defined_size; - LONG attrs; - LONG index; - struct recordset *recordset; + Field Field_iface; + ISupportErrorInfo ISupportErrorInfo_iface; + LONG refs; + WCHAR *name; + DataTypeEnum type; + LONG defined_size; + LONG attrs; + LONG index; + struct recordset *recordset; }; static inline struct field *impl_from_Field( Field *iface ) @@ -95,6 +98,7 @@ static ULONG WINAPI field_Release( Field *iface ) static HRESULT WINAPI field_QueryInterface( Field *iface, REFIID riid, void **obj ) { + struct field *field = impl_from_Field( iface ); TRACE( "%p, %s, %p\n", iface, debugstr_guid(riid), obj ); if (IsEqualGUID( riid, &IID_Field ) || IsEqualGUID( riid, &IID_IDispatch ) || @@ -102,6 +106,10 @@ static HRESULT WINAPI field_QueryInterface( Field *iface, REFIID riid, void **ob { *obj = iface; } + else if (IsEqualGUID( riid, &IID_ISupportErrorInfo )) + { + *obj = &field->ISupportErrorInfo_iface; + } else { FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); @@ -368,12 +376,51 @@ static const struct FieldVtbl field_vtbl = field_get_Status }; +static inline struct field *field_from_ISupportErrorInfo( ISupportErrorInfo *iface ) +{ + return CONTAINING_RECORD( iface, struct field, ISupportErrorInfo_iface ); +} + +static HRESULT WINAPI field_supporterrorinfo_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj ) +{ + struct field *field = field_from_ISupportErrorInfo( iface ); + return Field_QueryInterface( &field->Field_iface, riid, obj ); +} + +static ULONG WINAPI field_supporterrorinfo_AddRef( ISupportErrorInfo *iface ) +{ + struct field *field = field_from_ISupportErrorInfo( iface ); + return Field_AddRef( &field->Field_iface ); +} + +static ULONG WINAPI field_supporterrorinfo_Release( ISupportErrorInfo *iface ) +{ + struct field *field = field_from_ISupportErrorInfo( iface ); + return Field_Release( &field->Field_iface ); +} + +static HRESULT WINAPI field_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid ) +{ + struct field *field = field_from_ISupportErrorInfo( iface ); + FIXME( "%p, %s\n", field, debugstr_guid(riid) ); + return S_FALSE; +} + +static const ISupportErrorInfoVtbl field_supporterrorinfo_vtbl = +{ + field_supporterrorinfo_QueryInterface, + field_supporterrorinfo_AddRef, + field_supporterrorinfo_Release, + field_supporterrorinfo_InterfaceSupportsErrorInfo +}; + static HRESULT Field_create( const WCHAR *name, LONG index, struct recordset *recordset, Field **obj ) { struct field *field; if (!(field = heap_alloc_zero( sizeof(*field) ))) return E_OUTOFMEMORY; field->Field_iface.lpVtbl = &field_vtbl; + field->ISupportErrorInfo_iface.lpVtbl = &field_supporterrorinfo_vtbl; if (!(field->name = strdupW( name ))) { heap_free( field ); @@ -416,6 +463,7 @@ static ULONG WINAPI fields_Release( Fields *iface ) static HRESULT WINAPI fields_QueryInterface( Fields *iface, REFIID riid, void **obj ) { + struct fields *fields = impl_from_Fields( iface ); TRACE( "%p, %s, %p\n", iface, debugstr_guid(riid), obj ); if (IsEqualGUID( riid, &IID_Fields ) || IsEqualGUID( riid, &IID_IDispatch ) || @@ -423,6 +471,10 @@ static HRESULT WINAPI fields_QueryInterface( Fields *iface, REFIID riid, void ** { *obj = iface; } + else if (IsEqualGUID( riid, &IID_ISupportErrorInfo )) + { + *obj = &fields->ISupportErrorInfo_iface; + } else { FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); @@ -626,12 +678,51 @@ static const struct FieldsVtbl fields_vtbl = fields_CancelUpdate }; +static inline struct fields *fields_from_ISupportErrorInfo( ISupportErrorInfo *iface ) +{ + return CONTAINING_RECORD( iface, struct fields, ISupportErrorInfo_iface ); +} + +static HRESULT WINAPI fields_supporterrorinfo_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj ) +{ + struct fields *fields = fields_from_ISupportErrorInfo( iface ); + return Fields_QueryInterface( &fields->Fields_iface, riid, obj ); +} + +static ULONG WINAPI fields_supporterrorinfo_AddRef( ISupportErrorInfo *iface ) +{ + struct fields *fields = fields_from_ISupportErrorInfo( iface ); + return Fields_AddRef( &fields->Fields_iface ); +} + +static ULONG WINAPI fields_supporterrorinfo_Release( ISupportErrorInfo *iface ) +{ + struct fields *fields = fields_from_ISupportErrorInfo( iface ); + return Fields_Release( &fields->Fields_iface ); +} + +static HRESULT WINAPI fields_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid ) +{ + struct fields *fields = fields_from_ISupportErrorInfo( iface ); + FIXME( "%p, %s\n", fields, debugstr_guid(riid) ); + return S_FALSE; +} + +static const ISupportErrorInfoVtbl fields_supporterrorinfo_vtbl = +{ + fields_supporterrorinfo_QueryInterface, + fields_supporterrorinfo_AddRef, + fields_supporterrorinfo_Release, + fields_supporterrorinfo_InterfaceSupportsErrorInfo +}; + static HRESULT fields_create( struct recordset *recordset, struct fields **ret ) { struct fields *fields; if (!(fields = heap_alloc_zero( sizeof(*fields) ))) return E_OUTOFMEMORY; fields->Fields_iface.lpVtbl = &fields_vtbl; + fields->ISupportErrorInfo_iface.lpVtbl = &fields_supporterrorinfo_vtbl; fields->refs = 1; fields->recordset = recordset; _Recordset_AddRef( &fields->recordset->Recordset_iface ); @@ -686,18 +777,20 @@ static ULONG WINAPI recordset_Release( _Recordset *iface ) static HRESULT WINAPI recordset_QueryInterface( _Recordset *iface, REFIID riid, void **obj ) { + struct recordset *recordset = impl_from_Recordset( iface ); TRACE( "%p, %s, %p\n", iface, debugstr_guid(riid), obj ); - if (IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IDispatch) || - IsEqualIID(riid, &IID__ADO) || - IsEqualIID(riid, &IID_Recordset15) || - IsEqualIID(riid, &IID_Recordset20) || - IsEqualIID(riid, &IID_Recordset21) || + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID__ADO) || IsEqualIID(riid, &IID_Recordset15) || + IsEqualIID(riid, &IID_Recordset20) || IsEqualIID(riid, &IID_Recordset21) || IsEqualIID(riid, &IID__Recordset)) { *obj = iface; } + else if (IsEqualGUID( riid, &IID_ISupportErrorInfo )) + { + *obj = &recordset->ISupportErrorInfo_iface; + } else { FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); @@ -1379,12 +1472,51 @@ static const struct _RecordsetVtbl recordset_vtbl = recordset_Save }; +static inline struct recordset *recordset_from_ISupportErrorInfo( ISupportErrorInfo *iface ) +{ + return CONTAINING_RECORD( iface, struct recordset, ISupportErrorInfo_iface ); +} + +static HRESULT WINAPI recordset_supporterrorinfo_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj ) +{ + struct recordset *recordset = recordset_from_ISupportErrorInfo( iface ); + return _Recordset_QueryInterface( &recordset->Recordset_iface, riid, obj ); +} + +static ULONG WINAPI recordset_supporterrorinfo_AddRef( ISupportErrorInfo *iface ) +{ + struct recordset *recordset = recordset_from_ISupportErrorInfo( iface ); + return _Recordset_AddRef( &recordset->Recordset_iface ); +} + +static ULONG WINAPI recordset_supporterrorinfo_Release( ISupportErrorInfo *iface ) +{ + struct recordset *recordset = recordset_from_ISupportErrorInfo( iface ); + return _Recordset_Release( &recordset->Recordset_iface ); +} + +static HRESULT WINAPI recordset_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid ) +{ + struct recordset *recordset = recordset_from_ISupportErrorInfo( iface ); + FIXME( "%p, %s\n", recordset, debugstr_guid(riid) ); + return S_FALSE; +} + +static const ISupportErrorInfoVtbl recordset_supporterrorinfo_vtbl = +{ + recordset_supporterrorinfo_QueryInterface, + recordset_supporterrorinfo_AddRef, + recordset_supporterrorinfo_Release, + recordset_supporterrorinfo_InterfaceSupportsErrorInfo +}; + HRESULT Recordset_create( void **obj ) { struct recordset *recordset; if (!(recordset = heap_alloc_zero( sizeof(*recordset) ))) return E_OUTOFMEMORY; recordset->Recordset_iface.lpVtbl = &recordset_vtbl; + recordset->ISupportErrorInfo_iface.lpVtbl = &recordset_supporterrorinfo_vtbl; recordset->refs = 1; recordset->index = -1; diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 61040f691e..a3bce0b471 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -60,6 +60,7 @@ static LONG get_refs_recordset( _Recordset *recordset ) static void test_Recordset(void) { _Recordset *recordset; + ISupportErrorInfo *errorinfo; Fields *fields, *fields2; Field *field; LONG refs, count, state; @@ -70,6 +71,16 @@ static void test_Recordset(void) hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset ); ok( hr == S_OK, "got %08x\n", hr ); + /* _Recordset object supports ISupportErrorInfo */ + errorinfo = NULL; + hr = _Recordset_QueryInterface( recordset, &IID_ISupportErrorInfo, (void **)&errorinfo ); + ok( hr == S_OK, "got %08x\n", hr ); + refs = get_refs_recordset( recordset ); + ok( refs == 2, "got %d\n", refs ); + if (errorinfo) ISupportErrorInfo_Release( errorinfo ); + refs = get_refs_recordset( recordset ); + ok( refs == 1, "got %d\n", refs ); + /* handing out fields object increases recordset refcount */ refs = get_refs_recordset( recordset ); ok( refs == 1, "got %d\n", refs ); @@ -255,6 +266,7 @@ static void test_Recordset(void) static void test_Fields(void) { _Recordset *recordset; + ISupportErrorInfo *errorinfo; Fields *fields; Field *field, *field2; VARIANT val, index; @@ -270,6 +282,16 @@ static void test_Fields(void) hr = _Recordset_get_Fields( recordset, &fields ); ok( hr == S_OK, "got %08x\n", hr ); + /* Fields object supports ISupportErrorInfo */ + errorinfo = NULL; + hr = Fields_QueryInterface( fields, &IID_ISupportErrorInfo, (void **)&errorinfo ); + ok( hr == S_OK, "got %08x\n", hr ); + refs = get_refs_fields( fields ); + ok( refs == 2, "got %d\n", refs ); + if (errorinfo) ISupportErrorInfo_Release( errorinfo ); + refs = get_refs_fields( fields ); + ok( refs == 1, "got %d\n", refs ); + count = -1; hr = Fields_get_Count( fields, &count ); ok( !count, "got %d\n", count ); @@ -324,6 +346,16 @@ static void test_Fields(void) Field_Release( field2 ); SysFreeString( name ); + /* Field object supports ISupportErrorInfo */ + errorinfo = NULL; + hr = Field_QueryInterface( field, &IID_ISupportErrorInfo, (void **)&errorinfo ); + ok( hr == S_OK, "got %08x\n", hr ); + refs = get_refs_field( field ); + ok( refs == 2, "got %d\n", refs ); + if (errorinfo) ISupportErrorInfo_Release( errorinfo ); + refs = get_refs_field( field ); + ok( refs == 1, "got %d\n", refs ); + /* verify values set with _Append */ hr = Field_get_Name( field, &name ); ok( hr == S_OK, "got %08x\n", hr ); -- 2.20.1