Although I couldn't find other uses for `list_manager_create`, it seems that in this case is working just fine. The list manager should be released once the `IEnumNetworkConnections` is destroyed.
From: Sebastián Aedo saedo@codeweavers.com
Signed-off-by: Sebastián Aedo saedo@codeweavers.com --- dlls/netprofm/tests/list.c | 46 +++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/dlls/netprofm/tests/list.c b/dlls/netprofm/tests/list.c index 9295eeebc7c..6f46c125763 100644 --- a/dlls/netprofm/tests/list.c +++ b/dlls/netprofm/tests/list.c @@ -25,15 +25,21 @@ #include "netlistmgr.h" #include "wine/test.h"
-static void test_INetwork( INetwork *network ) +static void test_INetwork( INetwork *network, INetworkConnection *conn ) { NLM_NETWORK_CATEGORY category; NLM_CONNECTIVITY connectivity; NLM_DOMAIN_TYPE domain_type; VARIANT_BOOL connected; + IEnumNetworkConnections *conn_iter; + VARIANT_BOOL is_connection_present; + GUID conn_id; + GUID local_conn_id; GUID id; BSTR str; HRESULT hr; + INetworkConnection *local_conn; + ULONG fetched;
str = NULL; hr = INetwork_GetName( network, &str ); @@ -81,6 +87,40 @@ static void test_INetwork( INetwork *network ) hr = INetwork_get_IsConnectedToInternet( network, &connected ); ok( hr == S_OK, "got %08lx\n", hr ); trace("connected to internet %d\n", connected); + + if (!conn) return; + + trace("about to test GetNetworkConnections\n"); + memset( &conn_id, 0, sizeof(conn_id) ); + hr = INetworkConnection_GetConnectionId( conn, &conn_id ); + ok( hr == S_OK, "got %08lx\n", hr ); + trace("input connection id %s\n", wine_dbgstr_guid(&conn_id)); + + conn_iter = NULL; + hr = INetwork_GetNetworkConnections( network, &conn_iter ); + todo_wine ok( hr == S_OK, "got %08lx\n", hr ); + + is_connection_present = FALSE; + if (conn_iter) + { + while ((hr = IEnumNetworkConnections_Next( conn_iter, 1, &local_conn, &fetched )) == S_OK) + { + memset( &local_conn_id, 0, sizeof(local_conn_id) ); + hr = INetworkConnection_GetConnectionId( local_conn, &local_conn_id ); + ok( hr == S_OK, "got %08lx\n", hr ); + trace("local connection id %s\n", wine_dbgstr_guid(&local_conn_id)); + + if (IsEqualGUID(&conn_id, &local_conn_id)) + is_connection_present = TRUE; + + INetworkConnection_Release( local_conn ); + local_conn = (void *)0xdeadbeef; + } + ok( !local_conn, "got wrong pointer: %p.\n", local_conn ); + IEnumNetworkConnections_Release( conn_iter ); + } + + todo_wine ok( is_connection_present, "connection was not present in network\n" ); }
static void test_INetworkConnection( INetworkConnection *conn ) @@ -130,7 +170,7 @@ static void test_INetworkConnection( INetworkConnection *conn ) ok( hr == S_OK, "got %08lx\n", hr ); if (network) { - test_INetwork( network ); + test_INetwork( network, conn ); INetwork_Release( network ); }
@@ -344,7 +384,7 @@ static void test_INetworkListManager( void ) { while ((hr = IEnumNetworks_Next( network_iter, 1, &network, NULL )) == S_OK) { - test_INetwork( network ); + test_INetwork( network, NULL ); INetwork_Release( network ); } IEnumNetworks_Release( network_iter );
From: Sebastián Aedo saedo@codeweavers.com
Signed-off-by: Sebastián Aedo saedo@codeweavers.com --- dlls/netprofm/list.c | 52 ++++++++++++++++++++++++++++++-------- dlls/netprofm/tests/list.c | 4 +-- 2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/dlls/netprofm/list.c b/dlls/netprofm/list.c index e22609dcaf6..db4f13f532e 100644 --- a/dlls/netprofm/list.c +++ b/dlls/netprofm/list.c @@ -94,6 +94,9 @@ struct sink_entry IUnknown *unk; };
+static HRESULT create_connections_enum( + struct list_manager *, IEnumNetworkConnections** ); + static inline struct list_manager *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface) { return CONTAINING_RECORD(iface, struct list_manager, IConnectionPointContainer_iface); @@ -111,6 +114,12 @@ static inline struct connection_point *impl_from_IConnectionPoint( return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface ); }
+static inline struct list_manager *impl_from_INetworkListManager( + INetworkListManager *iface ) +{ + return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface ); +} + static HRESULT WINAPI connection_point_QueryInterface( IConnectionPoint *iface, REFIID riid, @@ -432,12 +441,42 @@ static HRESULT WINAPI network_GetDomainType( return S_OK; }
+static ULONG WINAPI connection_Release( + INetworkConnection *iface ); + static HRESULT WINAPI network_GetNetworkConnections( INetwork *iface, IEnumNetworkConnections **ppEnumNetworkConnection ) { - FIXME( "%p, %p\n", iface, ppEnumNetworkConnection ); - return E_NOTIMPL; + HRESULT hr; + INetworkListManager *network_list_mgr = NULL; + struct list_manager *mgr = NULL; + struct network *current_network = impl_from_INetwork( iface ); + + struct connection *connection, *next; + struct network *network; + + if (FAILED(hr = list_manager_create((void**)&network_list_mgr))) + return hr; + + mgr = impl_from_INetworkListManager(network_list_mgr); + + if (FAILED(hr = create_connections_enum(mgr, ppEnumNetworkConnection))) + return hr; + + TRACE("%p, %s\n", iface, debugstr_guid(¤t_network->id)); + + LIST_FOR_EACH_ENTRY_SAFE(connection, next, &mgr->connections, struct connection, entry) + { + network = impl_from_INetwork(connection->network); + if (!IsEqualGUID(&network->id, ¤t_network->id)) + { + TRACE("Filtering %s\n", debugstr_guid(&network->id)); + list_remove(&connection->entry); + } + } + + return S_OK; }
static HRESULT WINAPI network_GetTimeCreatedAndConnected( @@ -881,12 +920,6 @@ static HRESULT create_networks_enum( return S_OK; }
-static inline struct list_manager *impl_from_INetworkListManager( - INetworkListManager *iface ) -{ - return CONTAINING_RECORD( iface, struct list_manager, INetworkListManager_iface ); -} - struct connections_enum { IEnumNetworkConnections IEnumNetworkConnections_iface; @@ -1057,9 +1090,6 @@ static HRESULT WINAPI connections_enum_Reset( return S_OK; }
-static HRESULT create_connections_enum( - struct list_manager *, IEnumNetworkConnections** ); - static HRESULT WINAPI connections_enum_Clone( IEnumNetworkConnections *iface, IEnumNetworkConnections **ret ) { diff --git a/dlls/netprofm/tests/list.c b/dlls/netprofm/tests/list.c index 6f46c125763..b58aef9bdec 100644 --- a/dlls/netprofm/tests/list.c +++ b/dlls/netprofm/tests/list.c @@ -98,7 +98,7 @@ static void test_INetwork( INetwork *network, INetworkConnection *conn )
conn_iter = NULL; hr = INetwork_GetNetworkConnections( network, &conn_iter ); - todo_wine ok( hr == S_OK, "got %08lx\n", hr ); + ok( hr == S_OK, "got %08lx\n", hr );
is_connection_present = FALSE; if (conn_iter) @@ -120,7 +120,7 @@ static void test_INetwork( INetwork *network, INetworkConnection *conn ) IEnumNetworkConnections_Release( conn_iter ); }
- todo_wine ok( is_connection_present, "connection was not present in network\n" ); + ok( is_connection_present, "connection was not present in network\n" ); }
static void test_INetworkConnection( INetworkConnection *conn )
Hans Leidekker (@hans) commented about dlls/netprofm/list.c:
static HRESULT WINAPI network_GetNetworkConnections( INetwork *iface, IEnumNetworkConnections **ppEnumNetworkConnection ) {
- FIXME( "%p, %p\n", iface, ppEnumNetworkConnection );
- return E_NOTIMPL;
- HRESULT hr;
- INetworkListManager *network_list_mgr = NULL;
- struct list_manager *mgr = NULL;
- struct network *current_network = impl_from_INetwork( iface );
- struct connection *connection, *next;
- struct network *network;
- if (FAILED(hr = list_manager_create((void**)&network_list_mgr)))
return hr;
We shouldn't need to create a new list manager here. You can instead store a pointer to the list manager in the network object if you take care to properly addref and release the objects.
On Sat Nov 5 15:42:45 2022 +0000, Hans Leidekker wrote:
We shouldn't need to create a new list manager here. You can instead store a pointer to the list manager in the network object if you take care to properly addref and release the objects.
I thought that could be an option but I wasn't sure if every `INetwork` object can only come from an `INetworkListManager`. I'll look into that!