From ba156ed28b7bc39e7bdce41e6afd9c458c2a6eb0 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 18 Aug 2017 14:43:24 +0200 Subject: [PATCH] netprofm: Implement connection points as the same object as their container. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/netprofm/list.c | 78 ++++++++++++++++++++++------------------------ dlls/netprofm/tests/list.c | 20 ++++++++++-- 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/dlls/netprofm/list.c b/dlls/netprofm/list.c index d59ee0cadbf..3f572841f96 100644 --- a/dlls/netprofm/list.c +++ b/dlls/netprofm/list.c @@ -75,6 +75,15 @@ struct connection VARIANT_BOOL connected; }; +struct connection_point +{ + IConnectionPoint IConnectionPoint_iface; + IConnectionPointContainer *container; + IID iid; + struct list sinks; + DWORD cookie; +}; + struct list_manager { INetworkListManager INetworkListManager_iface; @@ -83,16 +92,9 @@ struct list_manager LONG refs; struct list networks; struct list connections; -}; - -struct connection_point -{ - IConnectionPoint IConnectionPoint_iface; - IConnectionPointContainer *container; - LONG refs; - IID iid; - struct list sinks; - DWORD cookie; + struct connection_point list_mgr_cp; + struct connection_point cost_mgr_cp; + struct connection_point conn_mgr_cp; }; struct sink_entry @@ -146,21 +148,14 @@ static ULONG WINAPI connection_point_AddRef( IConnectionPoint *iface ) { struct connection_point *cp = impl_from_IConnectionPoint( iface ); - return InterlockedIncrement( &cp->refs ); + return IConnectionPointContainer_AddRef( cp->container ); } static ULONG WINAPI connection_point_Release( IConnectionPoint *iface ) { struct connection_point *cp = impl_from_IConnectionPoint( iface ); - LONG refs = InterlockedDecrement( &cp->refs ); - if (!refs) - { - TRACE( "destroying %p\n", cp ); - IConnectionPointContainer_Release( cp->container ); - heap_free( cp ); - } - return refs; + return IConnectionPointContainer_Release( cp->container ); } static HRESULT WINAPI connection_point_GetConnectionInterface( @@ -271,27 +266,16 @@ static const IConnectionPointVtbl connection_point_vtbl = connection_point_EnumConnections }; -static HRESULT connection_point_create( - IConnectionPoint **obj, +static void connection_point_init( + struct connection_point *cp, REFIID riid, IConnectionPointContainer *container ) { - struct connection_point *cp; - TRACE( "%p, %s, %p\n", obj, debugstr_guid(riid), container ); - - if (!(cp = heap_alloc( sizeof(*cp) ))) return E_OUTOFMEMORY; cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl; cp->container = container; - cp->refs = 1; cp->cookie = 0; cp->iid = *riid; list_init( &cp->sinks ); - - IConnectionPointContainer_AddRef( container ); - - *obj = &cp->IConnectionPoint_iface; - TRACE( "returning iface %p\n", *obj ); - return S_OK; } static inline struct network *impl_from_INetwork( @@ -1394,21 +1378,28 @@ static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPo REFIID riid, IConnectionPoint **cp) { struct list_manager *This = impl_from_IConnectionPointContainer( iface ); + struct connection_point *ret; TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp ); if (!riid || !cp) return E_POINTER; - if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ) || - IsEqualGUID( riid, &IID_INetworkCostManagerEvents ) || - IsEqualGUID( riid, &IID_INetworkConnectionEvents )) - return connection_point_create( cp, riid, iface ); - - FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + if (IsEqualGUID( riid, &IID_INetworkListManagerEvents )) + ret = &This->list_mgr_cp; + else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents )) + ret = &This->cost_mgr_cp; + else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents )) + ret = &This->conn_mgr_cp; + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + *cp = NULL; + return E_NOINTERFACE; + } - *cp = NULL; - return E_NOINTERFACE; + IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface ); + return S_OK; } static const struct IConnectionPointContainerVtbl cpc_vtbl = @@ -1784,6 +1775,13 @@ HRESULT list_manager_create( void **obj ) init_networks( mgr ); mgr->refs = 1; + connection_point_init( &mgr->list_mgr_cp, &IID_INetworkListManagerEvents, + &mgr->IConnectionPointContainer_iface ); + connection_point_init( &mgr->cost_mgr_cp, &IID_INetworkCostManagerEvents, + &mgr->IConnectionPointContainer_iface); + connection_point_init( &mgr->conn_mgr_cp, &IID_INetworkConnectionEvents, + &mgr->IConnectionPointContainer_iface ); + *obj = &mgr->INetworkListManager_iface; TRACE( "returning iface %p\n", *obj ); return S_OK; diff --git a/dlls/netprofm/tests/list.c b/dlls/netprofm/tests/list.c index 3937b2f64c2..0a1f854c00b 100644 --- a/dlls/netprofm/tests/list.c +++ b/dlls/netprofm/tests/list.c @@ -222,7 +222,7 @@ static void test_INetworkListManager( void ) INetworkCostManager *cost_mgr; NLM_CONNECTIVITY connectivity; VARIANT_BOOL connected; - IConnectionPoint *pt; + IConnectionPoint *pt, *pt2; IEnumNetworks *network_iter; INetwork *network; IEnumNetworkConnections *conn_iter; @@ -319,7 +319,10 @@ static void test_INetworkListManager( void ) hr = IConnectionPoint_Unadvise( pt, cookie ); ok( hr == S_OK, "Unadvise failed: %08x\n", hr ); - IConnectionPoint_Release( pt ); + hr = IConnectionPointContainer_FindConnectionPoint( cpc, &IID_INetworkListManagerEvents, &pt2 ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( pt == pt2, "pt != pt2\n"); + IConnectionPoint_Release( pt2 ); hr = IConnectionPointContainer_FindConnectionPoint( cpc, &IID_INetworkCostManagerEvents, &pt ); ok( hr == S_OK || hr == CO_E_FAILEDTOIMPERSONATE, "got %08x\n", hr ); @@ -355,7 +358,18 @@ static void test_INetworkListManager( void ) } IEnumNetworkConnections_Release( conn_iter ); } - INetworkListManager_Release( mgr ); + + /* cps and their container share the same ref count */ + IConnectionPoint_AddRef( pt ); + IConnectionPoint_AddRef( pt ); + + ref1 = IConnectionPoint_Release( pt ); + ref2 = INetworkListManager_Release( mgr ); + ok( ref2 == ref1 - 1, "ref = %u\n", ref1 ); + + IConnectionPoint_Release( pt ); + ref1 = IConnectionPoint_Release( pt ); + ok( !ref1, "ref = %u\n", ref1 ); } START_TEST( list ) -- 2.11.4.GIT