Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=16676
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/msado15/connection.c | 46 ++++++++++++++++++++++++------ dlls/msado15/main.c | 51 ++++++++++++++++++++++++++++++++++ dlls/msado15/msado15_private.h | 7 +++++ 3 files changed, 95 insertions(+), 9 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c index d55c0d18a35..80297dcdc16 100644 --- a/dlls/msado15/connection.c +++ b/dlls/msado15/connection.c @@ -156,29 +156,57 @@ static HRESULT WINAPI connection_QueryInterface( _Connection *iface, REFIID riid
static HRESULT WINAPI connection_GetTypeInfoCount( _Connection *iface, UINT *count ) { - FIXME( "%p, %p\n", iface, count ); - return E_NOTIMPL; + struct connection *connection = impl_from_Connection( iface ); + TRACE( "%p, %p\n", connection, count ); + *count = 1; + return S_OK; }
static HRESULT WINAPI connection_GetTypeInfo( _Connection *iface, UINT index, LCID lcid, ITypeInfo **info ) { - FIXME( "%p, %u, %u, %p\n", iface, index, lcid, info ); - return E_NOTIMPL; + struct connection *connection = impl_from_Connection( iface ); + TRACE( "%p, %u, %u, %p\n", connection, index, lcid, info ); + return get_typeinfo(Connection_tid, info); }
static HRESULT WINAPI connection_GetIDsOfNames( _Connection *iface, REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid ) { - FIXME( "%p, %s, %p, %u, %u, %p\n", iface, debugstr_guid(riid), names, count, lcid, dispid ); - return E_NOTIMPL; + struct connection *connection = impl_from_Connection( iface ); + HRESULT hr; + ITypeInfo *typeinfo; + + TRACE( "%p, %s, %p, %u, %u, %p\n", connection, debugstr_guid(riid), names, count, lcid, dispid ); + + hr = get_typeinfo(Connection_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid); + ITypeInfo_Release(typeinfo); + } + + return hr; }
static HRESULT WINAPI connection_Invoke( _Connection *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) { - FIXME( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", iface, member, debugstr_guid(riid), lcid, flags, params, - result, excep_info, arg_err ); - return E_NOTIMPL; + struct connection *connection = impl_from_Connection( iface ); + HRESULT hr; + ITypeInfo *typeinfo; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", connection, member, debugstr_guid(riid), lcid, flags, + params, result, excep_info, arg_err ); + + hr = get_typeinfo(Connection_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &connection->Connection_iface, member, flags, params, + result, excep_info, arg_err); + ITypeInfo_Release(typeinfo); + } + + return hr; }
static HRESULT WINAPI connection_get_Properties( _Connection *iface, Properties **obj ) diff --git a/dlls/msado15/main.c b/dlls/msado15/main.c index 0b8de1f9117..0f75c160b24 100644 --- a/dlls/msado15/main.c +++ b/dlls/msado15/main.c @@ -174,3 +174,54 @@ HRESULT WINAPI DllUnregisterServer( void ) { return __wine_unregister_resources( hinstance ); } + +static ITypeLib *typelib; +static ITypeInfo *typeinfos[LAST_tid]; + +static REFIID tid_ids[] = { + &IID__Connection, +}; + +static HRESULT load_typelib(void) +{ + HRESULT hres; + ITypeLib *tl; + + if(typelib) + return S_OK; + + hres = LoadRegTypeLib(&LIBID_ADODB, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); + if(FAILED(hres)) { + ERR("LoadRegTypeLib failed: %08x\n", hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) + ITypeLib_Release(tl); + return hres; +} + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) +{ + HRESULT hres; + + if (FAILED(hres = load_typelib())) + return hres; + + if(!typeinfos[tid]) { + ITypeInfo *ti; + + hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); + if(FAILED(hres)) { + ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) + ITypeInfo_Release(ti); + } + + *typeinfo = typeinfos[tid]; + ITypeInfo_AddRef(*typeinfo); + return S_OK; +} \ No newline at end of file diff --git a/dlls/msado15/msado15_private.h b/dlls/msado15/msado15_private.h index dd98c382e2b..a5b22f29446 100644 --- a/dlls/msado15/msado15_private.h +++ b/dlls/msado15/msado15_private.h @@ -42,4 +42,11 @@ static inline WCHAR *strdupW( const WCHAR *src ) return dst; }
+typedef enum tid_t { + Connection_tid, + LAST_tid +} tid_t; + +HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) DECLSPEC_HIDDEN; + #endif /* _WINE_MSADO15_PRIVATE_H_ */