Commit ba156ed2 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

netprofm: Implement connection points as the same object as their container.

parent 5266ef3b
...@@ -75,6 +75,15 @@ struct connection ...@@ -75,6 +75,15 @@ struct connection
VARIANT_BOOL connected; VARIANT_BOOL connected;
}; };
struct connection_point
{
IConnectionPoint IConnectionPoint_iface;
IConnectionPointContainer *container;
IID iid;
struct list sinks;
DWORD cookie;
};
struct list_manager struct list_manager
{ {
INetworkListManager INetworkListManager_iface; INetworkListManager INetworkListManager_iface;
...@@ -83,16 +92,9 @@ struct list_manager ...@@ -83,16 +92,9 @@ struct list_manager
LONG refs; LONG refs;
struct list networks; struct list networks;
struct list connections; struct list connections;
}; struct connection_point list_mgr_cp;
struct connection_point cost_mgr_cp;
struct connection_point struct connection_point conn_mgr_cp;
{
IConnectionPoint IConnectionPoint_iface;
IConnectionPointContainer *container;
LONG refs;
IID iid;
struct list sinks;
DWORD cookie;
}; };
struct sink_entry struct sink_entry
...@@ -146,21 +148,14 @@ static ULONG WINAPI connection_point_AddRef( ...@@ -146,21 +148,14 @@ static ULONG WINAPI connection_point_AddRef(
IConnectionPoint *iface ) IConnectionPoint *iface )
{ {
struct connection_point *cp = impl_from_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( static ULONG WINAPI connection_point_Release(
IConnectionPoint *iface ) IConnectionPoint *iface )
{ {
struct connection_point *cp = impl_from_IConnectionPoint( iface ); struct connection_point *cp = impl_from_IConnectionPoint( iface );
LONG refs = InterlockedDecrement( &cp->refs ); return IConnectionPointContainer_Release( cp->container );
if (!refs)
{
TRACE( "destroying %p\n", cp );
IConnectionPointContainer_Release( cp->container );
heap_free( cp );
}
return refs;
} }
static HRESULT WINAPI connection_point_GetConnectionInterface( static HRESULT WINAPI connection_point_GetConnectionInterface(
...@@ -271,27 +266,16 @@ static const IConnectionPointVtbl connection_point_vtbl = ...@@ -271,27 +266,16 @@ static const IConnectionPointVtbl connection_point_vtbl =
connection_point_EnumConnections connection_point_EnumConnections
}; };
static HRESULT connection_point_create( static void connection_point_init(
IConnectionPoint **obj, struct connection_point *cp,
REFIID riid, REFIID riid,
IConnectionPointContainer *container ) 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->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl;
cp->container = container; cp->container = container;
cp->refs = 1;
cp->cookie = 0; cp->cookie = 0;
cp->iid = *riid; cp->iid = *riid;
list_init( &cp->sinks ); 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( static inline struct network *impl_from_INetwork(
...@@ -1394,21 +1378,28 @@ static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPo ...@@ -1394,21 +1378,28 @@ static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPo
REFIID riid, IConnectionPoint **cp) REFIID riid, IConnectionPoint **cp)
{ {
struct list_manager *This = impl_from_IConnectionPointContainer( iface ); struct list_manager *This = impl_from_IConnectionPointContainer( iface );
struct connection_point *ret;
TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp ); TRACE( "%p, %s, %p\n", This, debugstr_guid(riid), cp );
if (!riid || !cp) if (!riid || !cp)
return E_POINTER; return E_POINTER;
if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ) || if (IsEqualGUID( riid, &IID_INetworkListManagerEvents ))
IsEqualGUID( riid, &IID_INetworkCostManagerEvents ) || ret = &This->list_mgr_cp;
IsEqualGUID( riid, &IID_INetworkConnectionEvents )) else if (IsEqualGUID( riid, &IID_INetworkCostManagerEvents ))
return connection_point_create( cp, riid, iface ); ret = &This->cost_mgr_cp;
else if (IsEqualGUID( riid, &IID_INetworkConnectionEvents ))
FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); ret = &This->conn_mgr_cp;
else
{
FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
*cp = NULL;
return E_NOINTERFACE;
}
*cp = NULL; IConnectionPoint_AddRef( *cp = &ret->IConnectionPoint_iface );
return E_NOINTERFACE; return S_OK;
} }
static const struct IConnectionPointContainerVtbl cpc_vtbl = static const struct IConnectionPointContainerVtbl cpc_vtbl =
...@@ -1784,6 +1775,13 @@ HRESULT list_manager_create( void **obj ) ...@@ -1784,6 +1775,13 @@ HRESULT list_manager_create( void **obj )
init_networks( mgr ); init_networks( mgr );
mgr->refs = 1; 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; *obj = &mgr->INetworkListManager_iface;
TRACE( "returning iface %p\n", *obj ); TRACE( "returning iface %p\n", *obj );
return S_OK; return S_OK;
......
...@@ -222,7 +222,7 @@ static void test_INetworkListManager( void ) ...@@ -222,7 +222,7 @@ static void test_INetworkListManager( void )
INetworkCostManager *cost_mgr; INetworkCostManager *cost_mgr;
NLM_CONNECTIVITY connectivity; NLM_CONNECTIVITY connectivity;
VARIANT_BOOL connected; VARIANT_BOOL connected;
IConnectionPoint *pt; IConnectionPoint *pt, *pt2;
IEnumNetworks *network_iter; IEnumNetworks *network_iter;
INetwork *network; INetwork *network;
IEnumNetworkConnections *conn_iter; IEnumNetworkConnections *conn_iter;
...@@ -319,7 +319,10 @@ static void test_INetworkListManager( void ) ...@@ -319,7 +319,10 @@ static void test_INetworkListManager( void )
hr = IConnectionPoint_Unadvise( pt, cookie ); hr = IConnectionPoint_Unadvise( pt, cookie );
ok( hr == S_OK, "Unadvise failed: %08x\n", hr ); 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 ); hr = IConnectionPointContainer_FindConnectionPoint( cpc, &IID_INetworkCostManagerEvents, &pt );
ok( hr == S_OK || hr == CO_E_FAILEDTOIMPERSONATE, "got %08x\n", hr ); ok( hr == S_OK || hr == CO_E_FAILEDTOIMPERSONATE, "got %08x\n", hr );
...@@ -355,7 +358,18 @@ static void test_INetworkListManager( void ) ...@@ -355,7 +358,18 @@ static void test_INetworkListManager( void )
} }
IEnumNetworkConnections_Release( conn_iter ); 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 ) START_TEST( list )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment