Aaro Altonen : msado15: Implement IConnectionPoint::Advise/Unadvise.
Alexandre Julliard
julliard at winehq.org
Thu Jun 18 15:33:36 CDT 2020
Module: wine
Branch: master
Commit: b852f777d979f83e9f94fba6484762245bfffbc1
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b852f777d979f83e9f94fba6484762245bfffbc1
Author: Aaro Altonen <a.altonen at hotmail.com>
Date: Wed Jun 17 15:36:15 2020 +0300
msado15: Implement IConnectionPoint::Advise/Unadvise.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49388
Signed-off-by: Aaro Altonen <a.altonen at hotmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msado15/connection.c | 65 +++++++++++++++++++++++++++++++++++++++++---
dlls/msado15/tests/msado15.c | 5 +---
2 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c
index 35202d14aa..5d8f78f53e 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
@@ -84,9 +86,16 @@ static ULONG WINAPI connection_Release( _Connection *iface )
{
struct connection *connection = impl_from_Connection( iface );
LONG refs = InterlockedDecrement( &connection->refs );
+ ULONG i;
if (!refs)
{
TRACE( "destroying %p\n", connection );
+ for (i = 0; i < connection->cp_connev.sinks_size; ++i)
+ {
+ if (connection->cp_connev.sinks[i])
+ IUnknown_Release( connection->cp_connev.sinks[i] );
+ }
+ heap_free( connection->cp_connev.sinks );
heap_free( connection->datasource );
heap_free( connection );
}
@@ -548,15 +557,61 @@ 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, **tmp;
+ ULONG new_size;
+ HRESULT hr;
+ DWORD i;
+
+ TRACE( "%p, %p, %p\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)
+ {
+ new_size = connpoint->sinks_size * 2;
+ if (!(tmp = heap_realloc_zero( connpoint->sinks, new_size * sizeof(*connpoint->sinks) )))
+ return E_OUTOFMEMORY;
+ connpoint->sinks = tmp;
+ connpoint->sinks_size = new_size;
+ }
+ }
+ else
+ {
+ if (!(connpoint->sinks = heap_alloc_zero( sizeof(*connpoint->sinks) ))) return E_OUTOFMEMORY;
+ connpoint->sinks_size = 1;
+ 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 +650,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 e072ed022f..1629fe15be 100644
--- a/dlls/msado15/tests/msado15.c
+++ b/dlls/msado15/tests/msado15.c
@@ -996,7 +996,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 );
@@ -1010,10 +1009,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 );
@@ -1042,7 +1039,7 @@ todo_wine {
ok( hr == S_OK, "got %08x\n", hr );
ok( cookie, "got %08x\n", cookie );
ok( conn_event.refs == 1, "got %d\n", conn_event.refs );
-}
+
refs = IConnectionPoint_Release( point );
ok( refs == 1, "got %u", refs );
More information about the wine-cvs
mailing list