Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49388 Signed-off-by: Aaro Altonen a.altonen@hotmail.com --- dlls/msado15/connection.c | 56 +++++++++++++++++++++++++++++++++--- dlls/msado15/tests/msado15.c | 4 --- 2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c index 35202d14aa..caca9cd298 100644 --- a/dlls/msado15/connection.c +++ b/dlls/msado15/connection.c @@ -40,6 +40,8 @@ struct connection_point IConnectionPoint IConnectionPoint_iface; struct connection *conn; const IID *riid; + IUnknown **sinks; + ULONG sinks_size; };
struct connection @@ -87,6 +89,7 @@ static ULONG WINAPI connection_Release( _Connection *iface ) if (!refs) { TRACE( "destroying %p\n", connection ); + heap_free( connection->cp_connev.sinks ); heap_free( connection->datasource ); heap_free( connection ); } @@ -548,15 +551,58 @@ static HRESULT WINAPI connpoint_Advise( IConnectionPoint *iface, IUnknown *unk_s DWORD *cookie ) { struct connection_point *connpoint = impl_from_IConnectionPoint( iface ); - FIXME( "%p, %p, %p\n", connpoint, unk_sink, cookie ); - return E_NOTIMPL; + IUnknown *sink; + HRESULT hr; + DWORD i; + + TRACE( "%p, %p, %u\n", iface, unk_sink, cookie ); + + if (!unk_sink || !cookie) return E_FAIL; + + if (FAILED(hr = IUnknown_QueryInterface( unk_sink, &IID_ConnectionEventsVt, (void**)&sink ))) + { + *cookie = 0; + return E_FAIL; + } + + if (connpoint->sinks) + { + for (i = 0; i < connpoint->sinks_size; ++i) + { + if (!connpoint->sinks[i]) + break; + } + + if (i == connpoint->sinks_size) + { + connpoint->sinks_size *= 2; + connpoint->sinks = heap_realloc_zero( connpoint->sinks, + connpoint->sinks_size * sizeof(*connpoint->sinks) ); + } + } + else + { + connpoint->sinks_size = 1; + connpoint->sinks = heap_alloc_zero( sizeof(*connpoint->sinks) ); + i = 0; + } + + connpoint->sinks[i] = sink; + *cookie = i + 1; + return S_OK; }
static HRESULT WINAPI connpoint_Unadvise( IConnectionPoint *iface, DWORD cookie ) { struct connection_point *connpoint = impl_from_IConnectionPoint( iface ); - FIXME( "%p, %d\n", connpoint, cookie ); - return E_NOTIMPL; + TRACE( "%p, %u\n", connpoint, cookie ); + + if (!cookie || cookie > connpoint->sinks_size || !connpoint->sinks || !connpoint->sinks[cookie - 1]) + return E_FAIL; + + IUnknown_Release( connpoint->sinks[cookie - 1] ); + connpoint->sinks[cookie - 1] = NULL; + return S_OK; }
static HRESULT WINAPI connpoint_EnumConnections( IConnectionPoint *iface, @@ -595,6 +641,8 @@ HRESULT Connection_create( void **obj ) connection->cp_connev.conn = connection; connection->cp_connev.riid = &DIID_ConnectionEvents; connection->cp_connev.IConnectionPoint_iface.lpVtbl = &connpoint_vtbl; + connection->cp_connev.sinks = NULL; + connection->cp_connev.sinks_size = 0;
*obj = &connection->Connection_iface; TRACE( "returning iface %p\n", *obj ); diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 3e3997ed41..5f43307af7 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -987,7 +987,6 @@ static void test_ConnectionPoint(void) hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, &point ); ok( hr == S_OK, "got %08x\n", hr );
-todo_wine { /* nothing advised yet */ hr = IConnectionPoint_Unadvise( point, 3 ); ok( hr == E_FAIL, "got %08x\n", hr ); @@ -1001,10 +1000,8 @@ todo_wine { cookie = 0xdeadbeef; hr = IConnectionPoint_Advise( point, NULL, &cookie ); ok( hr == E_FAIL, "got %08x\n", hr ); -} ok( cookie == 0xdeadbeef, "got %08x\n", cookie );
-todo_wine { /* unsupported sink */ cookie = 0xdeadbeef; hr = IConnectionPoint_Advise( point, (void*)&support_err_sink, &cookie ); @@ -1026,7 +1023,6 @@ todo_wine {
hr = IConnectionPoint_Unadvise( point, cookie ); ok( hr == S_OK, "got %08x\n", hr ); -}
refs = IConnectionPoint_Release( point ); ok( refs == 1, "got %u", refs );
On Tue, 2020-06-16 at 07:47 +0300, Aaro Altonen wrote:
- if (connpoint->sinks)
- {
for (i = 0; i < connpoint->sinks_size; ++i)
{
if (!connpoint->sinks[i])
break;
}
if (i == connpoint->sinks_size)
{
connpoint->sinks_size *= 2;
connpoint->sinks = heap_realloc_zero( connpoint->sinks,
connpoint->sinks_size * sizeof(*connpoint->sinks) );
You should check for allocation failure. Look at recordset.c:resize_fields for example.
}
- }
- else
- {
connpoint->sinks_size = 1;
connpoint->sinks = heap_alloc_zero( sizeof(*connpoint->sinks) );
And here.