From: Mohamad Al-Jaf mohamadaljaf@gmail.com
windows.networking.connectivity/tests: Remove IPv6 tests. --- .../tests/Makefile.in | 2 +- .../tests/connectivity.c | 334 +++++++++++++++++- 2 files changed, 333 insertions(+), 3 deletions(-)
diff --git a/dlls/windows.networking.connectivity/tests/Makefile.in b/dlls/windows.networking.connectivity/tests/Makefile.in index 351f6ceeafc..2c715ccf2bb 100644 --- a/dlls/windows.networking.connectivity/tests/Makefile.in +++ b/dlls/windows.networking.connectivity/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = windows.networking.connectivity.dll -IMPORTS = combase +IMPORTS = combase iphlpapi ws2_32
SOURCES = \ connectivity.c diff --git a/dlls/windows.networking.connectivity/tests/connectivity.c b/dlls/windows.networking.connectivity/tests/connectivity.c index b49d2ca3a19..ee2311a9e36 100644 --- a/dlls/windows.networking.connectivity/tests/connectivity.c +++ b/dlls/windows.networking.connectivity/tests/connectivity.c @@ -31,8 +31,22 @@ #define WIDL_using_Windows_Networking_Connectivity #include "windows.networking.connectivity.h"
+#include "netlistmgr.h" +#include "ws2tcpip.h" +#include "iphlpapi.h" +#include "netioapi.h" + #include "wine/test.h"
+typedef struct +{ + boolean dhcp; + char ip_address[64]; + char subnet_mask[64]; + char gateway[64]; + char dns[64]; +} NetworkConfig; + #define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) static void check_interface_( unsigned int line, void *obj, const IID *iid ) { @@ -45,11 +59,265 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) IUnknown_Release( unk ); }
+static HRESULT configure_network( const char *ip_address, const char *subnet, const char *gateway, const char *dns ) +{ + char command[512]; + + if (!ip_address && !subnet && !gateway && !dns) + { + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface set interface "Ethernet" disable > nul 2>&1"" ); + trace( "disabling network adapter\n" ); + if(system( command )) return E_FAIL; + } + if (dns) + { + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface ip set dns name="Ethernet" static %s > nul 2>&1"", dns ); + trace( "setting dns = %s\n", dns ); + if(system( command )) return E_FAIL; + } + if (ip_address && subnet && gateway) + { + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface ip set address name="Ethernet" static %s %s %s > nul 2>&1"", ip_address, subnet, gateway ); + trace( "setting ip address = %s, subnet = %s, gateway = %s\n", ip_address, subnet, gateway ); + if(system( command )) return E_FAIL; + } + + return S_OK; +} + +static HRESULT get_network_configuration( NetworkConfig *config ) +{ + IP_ADAPTER_ADDRESSES *addresses = NULL, *adapter = NULL; + IP_ADAPTER_UNICAST_ADDRESS *unicast = NULL; + IP_ADAPTER_GATEWAY_ADDRESS *gateway = NULL; + IP_ADAPTER_DNS_SERVER_ADDRESS *dns = NULL; + IP_ADAPTER_PREFIX *prefix = NULL; + struct sockaddr_in *ipv4 = NULL; + ULONG size = 0; + DWORD error; + + GetAdaptersAddresses( AF_UNSPEC, 0, NULL, addresses, &size ); + if (!(addresses = (IP_ADAPTER_ADDRESSES *)calloc( 1, size ))) return E_OUTOFMEMORY; + error = GetAdaptersAddresses( AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, NULL, addresses, &size ); + if (error) goto done; + + adapter = addresses; + while (adapter) + { + if (adapter->OperStatus != IfOperStatusUp) + { + adapter = adapter->Next; + continue; + } + + config->dhcp = adapter->Flags & IP_ADAPTER_DHCP_ENABLED; + + unicast = adapter->FirstUnicastAddress; + while (unicast) + { + if (unicast->Address.lpSockaddr->sa_family == AF_INET) + { + ipv4 = (struct sockaddr_in *)unicast->Address.lpSockaddr; + inet_ntop( AF_INET, &ipv4->sin_addr, config->ip_address, sizeof( config->ip_address ) ); + } + unicast = unicast->Next; + } + + gateway = adapter->FirstGatewayAddress; + while (gateway) + { + if (gateway->Address.lpSockaddr->sa_family == AF_INET) + { + ipv4 = (struct sockaddr_in *)gateway->Address.lpSockaddr; + inet_ntop( AF_INET, &ipv4->sin_addr, config->gateway, sizeof( config->gateway ) ); + break; + } + gateway = gateway->Next; + } + + dns = adapter->FirstDnsServerAddress; + if (dns && dns->Address.lpSockaddr->sa_family == AF_INET) + { + ipv4 = (struct sockaddr_in *)dns->Address.lpSockaddr; + inet_ntop( AF_INET, &ipv4->sin_addr, config->dns, sizeof( config->dns ) ); + } + + prefix = adapter->FirstPrefix; + while (prefix) + { + if (prefix->Address.lpSockaddr->sa_family == AF_INET) + { + struct in_addr subnet; + DWORD mask; + + ConvertLengthToIpv4Mask( prefix->PrefixLength, &mask ); + subnet.S_un.S_addr = mask; + inet_ntop( AF_INET, &subnet, config->subnet_mask, sizeof( config->subnet_mask ) ); + break; + } + prefix = prefix->Next; + } + + break; + } + +done: + free( addresses ); + return HRESULT_FROM_WIN32( error ); +} + +void restore_network_configuration( const NetworkConfig *config ) +{ + char command[512]; + + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface set interface "Ethernet" enable > nul 2>&1"" ); + system( command ); + + if (config->dhcp) + { + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface ip set address name="Ethernet" dhcp > nul 2>&1"" ); + system( command ); + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface ip set dns name="Ethernet" source=dhcp > nul 2>&1"" ); + system( command ); + return; + } + if (strlen( config->dns )) + { + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface ip set dns name="Ethernet" static %s > nul 2>&1"", config->dns ); + system( command ); + } + if (strlen( config->ip_address )) + { + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface ip set address name="Ethernet" static %s %s %s > nul 2>&1"", + config->ip_address, config->subnet_mask, config->gateway ); + system( command ); + } +} + +#define restart_network( network_list_manager ) restart_network_( __LINE__, network_list_manager ) +static HRESULT restart_network_( unsigned int line, INetworkListManager *network_list_manager ) +{ + DWORD start = GetTickCount(), timeout = 30000, elapsed; + VARIANT_BOOL connected = 0xdead; + char command[512]; + + snprintf( command, sizeof( command ), "cmd.exe /c "netsh interface set interface "Ethernet" disable && timeout /t 2 && netsh interface set interface "Ethernet" enable > nul 2>&1"" ); + if(system( command )) return E_FAIL; + + while (connected != VARIANT_TRUE) + { + elapsed = GetTickCount() - start; + if (elapsed > timeout) + { + trace_(__FILE__, line)( "failed to restart the network adapter.\n" ); + return E_FAIL; + } + INetworkListManager_IsConnected( network_list_manager, &connected ); + Sleep( 500 ); + } + + return S_OK; +} + +#define network_status_changed( network_list_manager, connectivity ) network_status_changed_( __LINE__, network_list_manager, connectivity ) +static boolean network_status_changed_( unsigned int line, INetworkListManager *network_list_manager, NLM_CONNECTIVITY *connectivity ) +{ + DWORD start = GetTickCount(), timeout = 30000, elapsed; + NLM_CONNECTIVITY old_connectivity = *connectivity; + HRESULT hr = E_FAIL; + + while (old_connectivity == *connectivity) + { + elapsed = GetTickCount() - start; + if (elapsed > timeout) + { + trace_(__FILE__, line)( "failed to get updated connectivity.\n" ); + break; + } + hr = INetworkListManager_GetConnectivity( network_list_manager, connectivity ); + Sleep( 500 ); + } + + flaky_wine + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + return !(old_connectivity == *connectivity); +} + +#define check_connectivity_level( network_information_statics, network_list_manager, disconnect ) \ + check_connectivity_level_( __LINE__, network_information_statics, network_list_manager, disconnect ) +static void check_connectivity_level_( unsigned int line, INetworkInformationStatics *network_information_statics, INetworkListManager *network_list_manager, boolean disconnect ) +{ + IConnectionProfile *connection_profile = (void *)0xdeadbeef; + NetworkConnectivityLevel network_connectivity_level; + NLM_CONNECTIVITY connectivity; + HRESULT hr; + + hr = INetworkInformationStatics_GetInternetConnectionProfile( network_information_statics, &connection_profile ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + + connectivity = 0xdeadbeef; + hr = INetworkListManager_GetConnectivity( network_list_manager, &connectivity ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + ok_(__FILE__, line)( connectivity != 0xdeadbeef, "failed to get connectivity information\n" ); + trace_(__FILE__, line)( "GetConnectivity: %08x\n", connectivity ); + if (connectivity == NLM_CONNECTIVITY_DISCONNECTED) + { + ok_(__FILE__, line)( !connection_profile, "expected NULL, got connection_profile %p.\n", connection_profile ); + skip( "Internet connection unavailable, skipping tests.\n" ); + return; + } + + hr = IConnectionProfile_GetNetworkConnectivityLevel( connection_profile, NULL ); + todo_wine + ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr ); + + if (disconnect) + { + hr = configure_network( NULL, NULL, NULL, NULL ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + connectivity = 0xdeadbeef; + if (!network_status_changed( network_list_manager, &connectivity )) goto out; + ok_(__FILE__, line)( connectivity != 0xdeadbeef, "failed to get connectivity information\n" ); + trace_(__FILE__, line)( "GetConnectivity: %08x\n", connectivity ); + } + + network_connectivity_level = 0xdeadbeef; + hr = IConnectionProfile_GetNetworkConnectivityLevel( connection_profile, &network_connectivity_level ); + if (disconnect) + todo_wine + ok_(__FILE__, line)( hr == 0x8007023e, "got hr %#lx.\n", hr ); + else + todo_wine + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + todo_wine + ok_(__FILE__, line)( network_connectivity_level != 0xdeadbeef, "failed to get network_connectivity_level\n" ); + + if (connectivity == NLM_CONNECTIVITY_DISCONNECTED) + todo_wine + ok_(__FILE__, line)( network_connectivity_level == NetworkConnectivityLevel_None, "got network_connectivity_level %d.\n", network_connectivity_level ); + else if (connectivity & ( NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET )) + todo_wine + ok_(__FILE__, line)( network_connectivity_level == NetworkConnectivityLevel_InternetAccess, "got network_connectivity_level %d.\n", network_connectivity_level ); + else if (connectivity & ( NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK | NLM_CONNECTIVITY_IPV4_NOTRAFFIC | NLM_CONNECTIVITY_IPV6_NOTRAFFIC )) + todo_wine + ok_(__FILE__, line)( network_connectivity_level == NetworkConnectivityLevel_LocalAccess, "got network_connectivity_level %d.\n", network_connectivity_level ); + else + todo_wine + ok_(__FILE__, line)( network_connectivity_level == NetworkConnectivityLevel_ConstrainedInternetAccess, "got network_connectivity_level %d.\n", network_connectivity_level ); + + trace_(__FILE__, line)( "network_connectivity_level = %d\n", network_connectivity_level ); +out: + IConnectionProfile_Release( connection_profile ); +} + static void test_NetworkInformationStatics(void) { static const WCHAR *network_information_statics_name = L"Windows.Networking.Connectivity.NetworkInformation"; - INetworkInformationStatics *network_information_statics; - IActivationFactory *factory; + INetworkInformationStatics *network_information_statics = (void *)0xdeadbeef; + INetworkListManager *network_list_manager = (void *)0xdeadbeef; + IActivationFactory *factory = (void *)0xdeadbeef; + NLM_CONNECTIVITY connectivity; + NetworkConfig network_config; HSTRING str; HRESULT hr; LONG ref; @@ -73,6 +341,68 @@ static void test_NetworkInformationStatics(void) hr = IActivationFactory_QueryInterface( factory, &IID_INetworkInformationStatics, (void **)&network_information_statics ); ok( hr == S_OK, "got hr %#lx.\n", hr );
+ check_interface( network_information_statics, &IID_IAgileObject ); + + hr = CoCreateInstance( &CLSID_NetworkListManager, NULL, CLSCTX_INPROC_SERVER, &IID_INetworkListManager, (void **)&network_list_manager ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (FAILED(hr)) + { + skip( "couldn't create an instance of NetworkListManager\n" ); + goto error; + } + + /* NetworkConnectivityLevel_InternetAccess */ + check_connectivity_level( network_information_statics, network_list_manager, FALSE ); + memset( &network_config, 0, sizeof( network_config ) ); + if (FAILED(hr = get_network_configuration( &network_config ))) + { + skip( "couldn't get network configuration\n" ); + goto done; + } + + /* NetworkConnectivityLevel_LocalAccess */ + hr = INetworkListManager_GetConnectivity( network_list_manager, &connectivity ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (FAILED(hr = configure_network( NULL, NULL, NULL, "192.168.2.1" ))) + { + skip( "couldn't configure the network adapter\n" ); + goto done; + } + hr = restart_network( network_list_manager ); + flaky_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (!network_status_changed( network_list_manager, &connectivity )) goto done; + check_connectivity_level( network_information_statics, network_list_manager, FALSE ); + restore_network_configuration( &network_config ); + + hr = INetworkListManager_GetConnectivity( network_list_manager, &connectivity ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = configure_network( "192.168.1.1", "255.255.255.0", "192.168.1.1", "192.168.2.1" ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = restart_network( network_list_manager ); + flaky_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (!network_status_changed( network_list_manager, &connectivity )) goto done; + check_connectivity_level( network_information_statics, network_list_manager, FALSE ); + restore_network_configuration( &network_config ); + + /* NetworkConnectivityLevel_None */ + hr = INetworkListManager_GetConnectivity( network_list_manager, &connectivity ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + hr = configure_network( NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + if (!network_status_changed( network_list_manager, &connectivity )) goto done; + check_connectivity_level( network_information_statics, network_list_manager, FALSE ); + restore_network_configuration( &network_config ); + + hr = restart_network( network_list_manager ); + flaky_wine + ok( hr == S_OK, "got hr %#lx.\n", hr ); + check_connectivity_level( network_information_statics, network_list_manager, TRUE ); +done: + restore_network_configuration( &network_config ); + INetworkListManager_Release( network_list_manager ); +error: ref = INetworkInformationStatics_Release( network_information_statics ); ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory );