Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/msado15/main.c | 1 + dlls/msado15/msado15_private.h | 1 + dlls/msado15/recordset.c | 132 ++++++++++++++++++++++++++++++++- dlls/msado15/tests/msado15.c | 20 +++++ 4 files changed, 152 insertions(+), 2 deletions(-)
diff --git a/dlls/msado15/main.c b/dlls/msado15/main.c index 3479ceb5b02..6b85c84e8e8 100644 --- a/dlls/msado15/main.c +++ b/dlls/msado15/main.c @@ -184,6 +184,7 @@ static REFIID tid_ids[] = { &IID__Connection, &IID_Field, &IID_Fields, + &IID_Properties, &IID__Recordset, &IID__Stream, }; diff --git a/dlls/msado15/msado15_private.h b/dlls/msado15/msado15_private.h index 55afac3f389..600dcb90a97 100644 --- a/dlls/msado15/msado15_private.h +++ b/dlls/msado15/msado15_private.h @@ -48,6 +48,7 @@ typedef enum tid_t { Connection_tid, Field_tid, Fields_tid, + Properties_tid, Recordset_tid, Stream_tid, LAST_tid diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 68d4c22d802..b45802f02ab 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -65,6 +65,7 @@ struct field { Field Field_iface; ISupportErrorInfo ISupportErrorInfo_iface; + Properties Properties_iface; LONG refs; WCHAR *name; DataTypeEnum type; @@ -79,6 +80,11 @@ static inline struct field *impl_from_Field( Field *iface ) return CONTAINING_RECORD( iface, struct field, Field_iface ); }
+static inline struct field *impl_from_Properties( Properties *iface ) +{ + return CONTAINING_RECORD( iface, struct field, Properties_iface ); +} + static ULONG WINAPI field_AddRef( Field *iface ) { struct field *field = impl_from_Field( iface ); @@ -181,8 +187,12 @@ static HRESULT WINAPI field_Invoke( Field *iface, DISPID member, REFIID riid, LC
static HRESULT WINAPI field_get_Properties( Field *iface, Properties **obj ) { - FIXME( "%p, %p\n", iface, obj ); - return E_NOTIMPL; + struct field *field = impl_from_Field( iface ); + TRACE( "%p, %p\n", iface, obj ); + + *obj = &field->Properties_iface; + Properties_AddRef(&field->Properties_iface); + return S_OK; }
static HRESULT WINAPI field_get_ActualSize( Field *iface, LONG *size ) @@ -447,6 +457,123 @@ static const ISupportErrorInfoVtbl field_supporterrorinfo_vtbl = field_supporterrorinfo_InterfaceSupportsErrorInfo };
+static HRESULT WINAPI field_props_QueryInterface(Properties *iface, REFIID riid, void **ppv) +{ + struct field *field = impl_from_Properties( iface ); + return Field_QueryInterface(&field->Field_iface, riid, ppv); +} + +static ULONG WINAPI field_props_AddRef(Properties *iface) +{ + struct field *field = impl_from_Properties( iface ); + return Field_AddRef(&field->Field_iface); +} + +static ULONG WINAPI field_props_Release(Properties *iface) +{ + struct field *field = impl_from_Properties( iface ); + return Field_Release(&field->Field_iface); +} + +static HRESULT WINAPI field_props_GetTypeInfoCount(Properties *iface, UINT *count) +{ + struct field *field = impl_from_Properties( iface ); + TRACE( "%p, %p\n", field, count ); + *count = 1; + return S_OK; +} + +static HRESULT WINAPI field_props_GetTypeInfo(Properties *iface, UINT index, LCID lcid, ITypeInfo **info) +{ + struct field *field = impl_from_Properties( iface ); + TRACE( "%p, %u, %u, %p\n", field, index, lcid, info ); + return get_typeinfo(Properties_tid, info); +} + +static HRESULT WINAPI field_props_GetIDsOfNames(Properties *iface, REFIID riid, LPOLESTR *names, UINT count, + LCID lcid, DISPID *dispid ) +{ + struct field *field = impl_from_Properties( iface ); + HRESULT hr; + ITypeInfo *typeinfo; + + TRACE( "%p, %s, %p, %u, %u, %p\n", field, debugstr_guid(riid), names, count, lcid, dispid ); + + hr = get_typeinfo(Properties_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI field_props_Invoke(Properties *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, + DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) +{ + struct field *field = impl_from_Properties( iface ); + HRESULT hr; + ITypeInfo *typeinfo; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", field, member, debugstr_guid(riid), lcid, flags, params, + result, excep_info, arg_err ); + + hr = get_typeinfo(Properties_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &field->Field_iface, member, flags, params, + result, excep_info, arg_err); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI field_props_get_Count(Properties *iface, LONG *count) +{ + struct field *field = impl_from_Properties( iface ); + FIXME( "%p, %p\n", field, count); + *count = 0; + return S_OK; +} + +static HRESULT WINAPI field_props__NewEnum(Properties *iface, IUnknown **object) +{ + struct field *field = impl_from_Properties( iface ); + FIXME( "%p, %p\n", field, object); + return E_NOTIMPL; +} + +static HRESULT WINAPI field_props_Refresh(Properties *iface) +{ + struct field *field = impl_from_Properties( iface ); + FIXME( "%p\n", field); + return E_NOTIMPL; +} + +static HRESULT WINAPI field_props_get_Item(Properties *iface, VARIANT index, Property **object) +{ + struct field *field = impl_from_Properties( iface ); + FIXME( "%p, %s, %p\n", field, debugstr_variant(&index), object); + return MAKE_ADO_HRESULT(adErrItemNotFound);; +} + +static struct PropertiesVtbl field_properties_vtbl = +{ + field_props_QueryInterface, + field_props_AddRef, + field_props_Release, + field_props_GetTypeInfoCount, + field_props_GetTypeInfo, + field_props_GetIDsOfNames, + field_props_Invoke, + field_props_get_Count, + field_props__NewEnum, + field_props_Refresh, + field_props_get_Item +}; + static HRESULT Field_create( const WCHAR *name, LONG index, struct recordset *recordset, Field **obj ) { struct field *field; @@ -454,6 +581,7 @@ static HRESULT Field_create( const WCHAR *name, LONG index, struct recordset *re if (!(field = heap_alloc_zero( sizeof(*field) ))) return E_OUTOFMEMORY; field->Field_iface.lpVtbl = &field_vtbl; field->ISupportErrorInfo_iface.lpVtbl = &field_supporterrorinfo_vtbl; + field->Properties_iface.lpVtbl = &field_properties_vtbl; if (!(field->name = strdupW( name ))) { heap_free( field ); diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index db606f21fab..b5f1b70dedd 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -68,6 +68,8 @@ static void test_Recordset(void) ISupportErrorInfo *errorinfo; Fields *fields, *fields2; Field *field; + Properties *props; + Property *prop; LONG refs, count, state; VARIANT missing, val, index; CursorLocationEnum location; @@ -184,6 +186,24 @@ static void test_Recordset(void) ok( hr == S_OK, "got %08x\n", hr ); SysFreeString( name );
+ hr = Field_QueryInterface(field, &IID_Properties, (void**)&props); + ok( hr == E_NOINTERFACE, "got %08x\n", hr ); + + hr = Field_get_Properties(field, &props); + ok( hr == S_OK, "got %08x\n", hr ); + + count = -1; + hr = Properties_get_Count(props, &count); + ok( hr == S_OK, "got %08x\n", hr ); + ok( !count, "got %d\n", count ); + + V_VT( &index ) = VT_I4; + V_I4( &index ) = 1000; + hr = Properties_get_Item(props, index, &prop); + ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08x\n", hr ); + + Properties_Release(props); + hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified ); ok( hr == S_OK, "got %08x\n", hr ); ok( is_eof( recordset ), "not eof\n" );
On 4/22/21 9:33 AM, Alistair Leslie-Hughes wrote:
+static HRESULT WINAPI field_props_QueryInterface(Properties *iface, REFIID riid, void **ppv) +{
- struct field *field = impl_from_Properties( iface );
- return Field_QueryInterface(&field->Field_iface, riid, ppv);
+}
This appears to be incorrect. Querying for IID_Field from Properties does not work on Windows.