From d53b711f27f15cdeb9700e86526dab13ddf8d731 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 17 Aug 2017 20:47:16 +0200 Subject: [PATCH] netprofm: Added semi-stub Advise and Unadvise implementation. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/netprofm/list.c | 54 ++++++++++++++++++++++++++++++---- dlls/netprofm/tests/list.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 5 deletions(-) diff --git a/dlls/netprofm/list.c b/dlls/netprofm/list.c index d82ae366154..d59ee0cadbf 100644 --- a/dlls/netprofm/list.c +++ b/dlls/netprofm/list.c @@ -91,6 +91,15 @@ struct connection_point IConnectionPointContainer *container; LONG refs; IID iid; + struct list sinks; + DWORD cookie; +}; + +struct sink_entry +{ + struct list entry; + DWORD cookie; + IUnknown *unk; }; static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface) @@ -189,12 +198,33 @@ static HRESULT WINAPI connection_point_Advise( DWORD *cookie ) { struct connection_point *cp = impl_from_IConnectionPoint( iface ); - FIXME( "%p, %p, %p - stub\n", cp, sink, cookie ); + struct sink_entry *sink_entry; + IUnknown *unk; + HRESULT hr; + + FIXME( "%p, %p, %p - semi-stub\n", cp, sink, cookie ); if (!sink || !cookie) return E_POINTER; - return CONNECT_E_CANNOTCONNECT; + hr = IUnknown_QueryInterface( sink, &cp->iid, (void**)&unk ); + if (FAILED(hr)) + { + WARN( "iface %s not implemented by sink\n", debugstr_guid(&cp->iid) ); + return CO_E_FAILEDTOOPENTHREADTOKEN; + } + + sink_entry = heap_alloc( sizeof(*sink_entry) ); + if (!sink_entry) + { + IUnknown_Release( unk ); + return E_OUTOFMEMORY; + } + + sink_entry->unk = unk; + *cookie = sink_entry->cookie = ++cp->cookie; + list_add_tail( &cp->sinks, &sink_entry->entry ); + return S_OK; } static HRESULT WINAPI connection_point_Unadvise( @@ -202,9 +232,21 @@ static HRESULT WINAPI connection_point_Unadvise( DWORD cookie ) { struct connection_point *cp = impl_from_IConnectionPoint( iface ); - FIXME( "%p, %d - stub\n", cp, cookie ); + struct sink_entry *iter; + + TRACE( "%p, %d\n", cp, cookie ); + + LIST_FOR_EACH_ENTRY( iter, &cp->sinks, struct sink_entry, entry ) + { + if (iter->cookie != cookie) continue; + list_remove( &iter->entry ); + IUnknown_Release( iter->unk ); + heap_free( iter ); + return S_OK; + } - return E_POINTER; + WARN( "invalid cookie\n" ); + return OLE_E_NOCONNECTION; } static HRESULT WINAPI connection_point_EnumConnections( @@ -241,8 +283,10 @@ static HRESULT connection_point_create( cp->IConnectionPoint_iface.lpVtbl = &connection_point_vtbl; cp->container = container; cp->refs = 1; + cp->cookie = 0; + cp->iid = *riid; + list_init( &cp->sinks ); - memcpy( &cp->iid, riid, sizeof(*riid) ); IConnectionPointContainer_AddRef( container ); *obj = &cp->IConnectionPoint_iface; diff --git a/dlls/netprofm/tests/list.c b/dlls/netprofm/tests/list.c index eb8477c6e15..3937b2f64c2 100644 --- a/dlls/netprofm/tests/list.c +++ b/dlls/netprofm/tests/list.c @@ -157,6 +157,64 @@ static void test_INetworkConnection( INetworkConnection *conn ) } } +static HRESULT WINAPI Unknown_QueryInterface(INetworkListManagerEvents *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(riid, &IID_IUnknown)) { + *ppv = iface; + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static HRESULT WINAPI NetworkListManagerEvents_QueryInterface(INetworkListManagerEvents *iface, + REFIID riid, void **ppv) +{ + if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_INetworkListManagerEvents)) { + *ppv = iface; + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI NetworkListManagerEvents_AddRef(INetworkListManagerEvents *iface) +{ + return 2; +} + +static ULONG WINAPI NetworkListManagerEvents_Release(INetworkListManagerEvents *iface) +{ + return 1; +} + +static HRESULT WINAPI NetworkListManagerEvents_ConnectivityChanged(INetworkListManagerEvents *iface, + NLM_CONNECTIVITY newConnectivity) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const INetworkListManagerEventsVtbl mgr_sink_vtbl = { + NetworkListManagerEvents_QueryInterface, + NetworkListManagerEvents_AddRef, + NetworkListManagerEvents_Release, + NetworkListManagerEvents_ConnectivityChanged +}; + +static INetworkListManagerEvents mgr_sink = { &mgr_sink_vtbl }; + +static const INetworkListManagerEventsVtbl mgr_sink_unk_vtbl = { + Unknown_QueryInterface, + NetworkListManagerEvents_AddRef, + NetworkListManagerEvents_Release, + NetworkListManagerEvents_ConnectivityChanged +}; + +static INetworkListManagerEvents mgr_sink_unk = { &mgr_sink_unk_vtbl }; + static void test_INetworkListManager( void ) { IConnectionPointContainer *cpc, *cpc2; @@ -169,6 +227,7 @@ static void test_INetworkListManager( void ) INetwork *network; IEnumNetworkConnections *conn_iter; INetworkConnection *conn; + DWORD cookie; HRESULT hr; ULONG ref1, ref2; IID iid; @@ -247,6 +306,19 @@ static void test_INetworkListManager( void ) ok( hr == S_OK, "got %08x\n", hr ); ok( !memcmp( &iid, &IID_INetworkListManagerEvents, sizeof(iid) ), "Expected iid to be IID_INetworkListManagerEvents\n" ); + + hr = IConnectionPoint_Advise( pt, (IUnknown*)&mgr_sink_unk, &cookie); + ok( hr == CO_E_FAILEDTOOPENTHREADTOKEN, "Advise failed: %08x\n", hr ); + + hr = IConnectionPoint_Advise( pt, (IUnknown*)&mgr_sink, &cookie); + ok( hr == S_OK, "Advise failed: %08x\n", hr ); + + hr = IConnectionPoint_Unadvise( pt, 0xdeadbeef ); + ok( hr == OLE_E_NOCONNECTION || hr == CO_E_FAILEDTOIMPERSONATE, "Unadvise failed: %08x\n", hr ); + + hr = IConnectionPoint_Unadvise( pt, cookie ); + ok( hr == S_OK, "Unadvise failed: %08x\n", hr ); + IConnectionPoint_Release( pt ); hr = IConnectionPointContainer_FindConnectionPoint( cpc, &IID_INetworkCostManagerEvents, &pt ); -- 2.11.4.GIT