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

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-08-18 14:43:24 +02:00 committed by Alexandre Julliard
parent 5266ef3bc5
commit ba156ed28b
2 changed files with 55 additions and 43 deletions

View file

@ -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 );
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;
}
FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
*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;

View file

@ -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 )