Needed by Just Cause 4.
-- v4: windows.networking.connectivity: Implement IConnectionProfile::GetNetworkConnectivityLevel(). windows.networking.connectivity/tests: Add INetworkInformationStatics::GetInternetConnectionProfile() tests. windows.networking.connectivity: Implement INetworkInformationStatics::GetInternetConnectionProfile().
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- configure.ac | 2 + .../Makefile.in | 8 ++ .../classes.idl | 23 ++++ dlls/windows.networking.connectivity/main.c | 44 +++++++ .../network_information.c | 115 ++++++++++++++++++ .../windows.networking.connectivity/private.h | 42 +++++++ .../tests/Makefile.in | 5 + .../tests/connectivity.c | 86 +++++++++++++ .../windows.networking.connectivity.spec | 10 ++ 9 files changed, 335 insertions(+) create mode 100644 dlls/windows.networking.connectivity/Makefile.in create mode 100644 dlls/windows.networking.connectivity/classes.idl create mode 100644 dlls/windows.networking.connectivity/main.c create mode 100644 dlls/windows.networking.connectivity/network_information.c create mode 100644 dlls/windows.networking.connectivity/private.h create mode 100644 dlls/windows.networking.connectivity/tests/Makefile.in create mode 100644 dlls/windows.networking.connectivity/tests/connectivity.c create mode 100644 dlls/windows.networking.connectivity/windows.networking.connectivity.spec
diff --git a/configure.ac b/configure.ac index de80d65b240..a15d65998ca 100644 --- a/configure.ac +++ b/configure.ac @@ -3231,6 +3231,8 @@ WINE_CONFIG_MAKEFILE(dlls/windows.media.speech) WINE_CONFIG_MAKEFILE(dlls/windows.media.speech/tests) WINE_CONFIG_MAKEFILE(dlls/windows.media) WINE_CONFIG_MAKEFILE(dlls/windows.media/tests) +WINE_CONFIG_MAKEFILE(dlls/windows.networking.connectivity) +WINE_CONFIG_MAKEFILE(dlls/windows.networking.connectivity/tests) WINE_CONFIG_MAKEFILE(dlls/windows.networking.hostname) WINE_CONFIG_MAKEFILE(dlls/windows.networking.hostname/tests) WINE_CONFIG_MAKEFILE(dlls/windows.networking) diff --git a/dlls/windows.networking.connectivity/Makefile.in b/dlls/windows.networking.connectivity/Makefile.in new file mode 100644 index 00000000000..f7fa3cb0002 --- /dev/null +++ b/dlls/windows.networking.connectivity/Makefile.in @@ -0,0 +1,8 @@ +MODULE = windows.networking.connectivity.dll +IMPORTS = combase +EXTRAIDLFLAGS = -DDO_NO_IMPORTS + +SOURCES = \ + classes.idl \ + main.c \ + network_information.c diff --git a/dlls/windows.networking.connectivity/classes.idl b/dlls/windows.networking.connectivity/classes.idl new file mode 100644 index 00000000000..b42f11f40d4 --- /dev/null +++ b/dlls/windows.networking.connectivity/classes.idl @@ -0,0 +1,23 @@ +/* + * Runtime Classes for windows.networking.connectivity.dll + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register + +#include "windows.networking.connectivity.idl" diff --git a/dlls/windows.networking.connectivity/main.c b/dlls/windows.networking.connectivity/main.c new file mode 100644 index 00000000000..607dd50cf84 --- /dev/null +++ b/dlls/windows.networking.connectivity/main.c @@ -0,0 +1,44 @@ +/* WinRT Windows.Networking.Connectivity Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "initguid.h" +#include "private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(connectivity); + +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID riid, void **out ) +{ + FIXME( "clsid %s, riid %s, out %p stub!\n", debugstr_guid( clsid ), debugstr_guid( riid ), out ); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllGetActivationFactory( HSTRING classid, IActivationFactory **factory ) +{ + const WCHAR *buffer = WindowsGetStringRawBuffer( classid, NULL ); + + TRACE( "class %s, factory %p.\n", debugstr_hstring( classid ), factory ); + + *factory = NULL; + + if (!wcscmp( buffer, RuntimeClass_Windows_Networking_Connectivity_NetworkInformation )) + IActivationFactory_QueryInterface( network_information_factory, &IID_IActivationFactory, (void **)factory ); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/windows.networking.connectivity/network_information.c b/dlls/windows.networking.connectivity/network_information.c new file mode 100644 index 00000000000..62b5f3680f1 --- /dev/null +++ b/dlls/windows.networking.connectivity/network_information.c @@ -0,0 +1,115 @@ +/* WinRT Windows.Networking.Connectivity.NetworkInformation Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(connectivity); + +struct network_information_statics +{ + IActivationFactory IActivationFactory_iface; + LONG ref; +}; + +static inline struct network_information_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct network_information_statics, IActivationFactory_iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct network_information_statics *impl = impl_from_IActivationFactory( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IActivationFactory )) + { + *out = &impl->IActivationFactory_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct network_information_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct network_information_statics *impl = impl_from_IActivationFactory( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + FIXME( "iface %p, instance %p stub!\n", iface, instance ); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +static struct network_information_statics network_information_statics = +{ + {&factory_vtbl}, + 1, +}; + +IActivationFactory *network_information_factory = &network_information_statics.IActivationFactory_iface; diff --git a/dlls/windows.networking.connectivity/private.h b/dlls/windows.networking.connectivity/private.h new file mode 100644 index 00000000000..0055b143d4f --- /dev/null +++ b/dlls/windows.networking.connectivity/private.h @@ -0,0 +1,42 @@ +/* WinRT Windows.Networking.Connectivity Implementation + * + * Copyright (C) 2024 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINDOWS_NETWORKING_CONNECTIVITY_PRIVATE_H +#define __WINE_WINDOWS_NETWORKING_CONNECTIVITY_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "activation.h" + +#include "wine/debug.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Networking_Connectivity +#include "windows.networking.connectivity.h" + +extern IActivationFactory *network_information_factory; + +#endif diff --git a/dlls/windows.networking.connectivity/tests/Makefile.in b/dlls/windows.networking.connectivity/tests/Makefile.in new file mode 100644 index 00000000000..351f6ceeafc --- /dev/null +++ b/dlls/windows.networking.connectivity/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = windows.networking.connectivity.dll +IMPORTS = combase + +SOURCES = \ + connectivity.c diff --git a/dlls/windows.networking.connectivity/tests/connectivity.c b/dlls/windows.networking.connectivity/tests/connectivity.c new file mode 100644 index 00000000000..83bd13ff0e4 --- /dev/null +++ b/dlls/windows.networking.connectivity/tests/connectivity.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS +#include "initguid.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winstring.h" + +#include "roapi.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Networking_Connectivity +#include "windows.networking.connectivity.h" + +#include "wine/test.h" + +#define check_interface( obj, iid ) check_interface_( __LINE__, obj, iid ) +static void check_interface_( unsigned int line, void *obj, const IID *iid ) +{ + IUnknown *iface = obj; + IUnknown *unk; + HRESULT hr; + + hr = IUnknown_QueryInterface( iface, iid, (void **)&unk ); + ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); + IUnknown_Release( unk ); +} + +static void test_NetworkInformationStatics(void) +{ + static const WCHAR *network_information_statics_name = L"Windows.Networking.Connectivity.NetworkInformation"; + IActivationFactory *factory; + HSTRING str; + HRESULT hr; + LONG ref; + + hr = WindowsCreateString( network_information_statics_name, wcslen( network_information_statics_name ), &str ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + hr = RoGetActivationFactory( str, &IID_IActivationFactory, (void **)&factory ); + WindowsDeleteString( str ); + ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ), "got hr %#lx.\n", hr ); + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip( "%s runtimeclass not registered, skipping tests.\n", wine_dbgstr_w( network_information_statics_name ) ); + return; + } + + check_interface( factory, &IID_IUnknown ); + check_interface( factory, &IID_IInspectable ); + check_interface( factory, &IID_IAgileObject ); + + ref = IActivationFactory_Release( factory ); + ok( ref == 1, "got ref %ld.\n", ref ); +} + +START_TEST(connectivity) +{ + HRESULT hr; + + hr = RoInitialize( RO_INIT_MULTITHREADED ); + ok( hr == S_OK, "RoInitialize failed, hr %#lx\n", hr ); + + test_NetworkInformationStatics(); + + RoUninitialize(); +} diff --git a/dlls/windows.networking.connectivity/windows.networking.connectivity.spec b/dlls/windows.networking.connectivity/windows.networking.connectivity.spec new file mode 100644 index 00000000000..e8e1a03b168 --- /dev/null +++ b/dlls/windows.networking.connectivity/windows.networking.connectivity.spec @@ -0,0 +1,10 @@ +@ stub SetHostNameMediaStreamingMode +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetActivationFactory(ptr ptr) +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() +@ stub FixDisabledComponentsForTeredo +@ stub RefreshTeredoClientState +@ stub TeredoExtAcquireTeredoConsumerHandle +@ stub TeredoExtReleaseTeredoConsumerHandle
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../network_information.c | 84 +++++++++++++++++++ .../windows.networking.connectivity/private.h | 40 +++++++++ .../tests/connectivity.c | 6 ++ 3 files changed, 130 insertions(+)
diff --git a/dlls/windows.networking.connectivity/network_information.c b/dlls/windows.networking.connectivity/network_information.c index 62b5f3680f1..2e203cea88e 100644 --- a/dlls/windows.networking.connectivity/network_information.c +++ b/dlls/windows.networking.connectivity/network_information.c @@ -21,9 +21,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(connectivity);
+static EventRegistrationToken dummy_cookie = {.value = 0xdeadbeef}; + struct network_information_statics { IActivationFactory IActivationFactory_iface; + INetworkInformationStatics INetworkInformationStatics_iface; LONG ref; };
@@ -48,6 +51,13 @@ static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID return S_OK; }
+ if (IsEqualGUID( iid, &IID_INetworkInformationStatics )) + { + *out = &impl->INetworkInformationStatics_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); *out = NULL; return E_NOINTERFACE; @@ -106,9 +116,83 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+DEFINE_IINSPECTABLE( network_information_statics, INetworkInformationStatics, struct network_information_statics, IActivationFactory_iface ) + +static HRESULT WINAPI network_information_statics_GetConnectionProfiles( INetworkInformationStatics *iface, IVectorView_ConnectionProfile **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI network_information_statics_GetInternetConnectionProfile( INetworkInformationStatics *iface, IConnectionProfile **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI network_information_statics_GetLanIdentifiers( INetworkInformationStatics *iface, IVectorView_LanIdentifier **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI network_information_statics_GetHostNames( INetworkInformationStatics *iface, IVectorView_HostName **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI network_information_statics_GetProxyConfigurationAsync( INetworkInformationStatics *iface, IUriRuntimeClass *uri, IAsyncOperation_ProxyConfiguration **value ) +{ + FIXME( "iface %p, uri %p, value %p stub!\n", iface, uri, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI network_information_statics_GetSortedEndpointPairs( INetworkInformationStatics *iface, IIterable_EndpointPair *endpoint, + HostNameSortOptions options, IVectorView_EndpointPair **value ) +{ + FIXME( "iface %p, endpoint %p, options %d, value %p stub!\n", iface, endpoint, options, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI network_information_statics_add_NetworkStatusChanged( INetworkInformationStatics *iface, INetworkStatusChangedEventHandler *handler, + EventRegistrationToken *cookie ) +{ + FIXME( "iface %p, handler %p, cookie %p stub!\n", iface, handler, cookie ); + *cookie = dummy_cookie; + return S_OK; +} + +static HRESULT WINAPI network_information_statics_remove_NetworkStatusChanged( INetworkInformationStatics *iface, EventRegistrationToken cookie ) +{ + FIXME( "iface %p, cookie %#I64x stub!\n", iface, cookie.value ); + return S_OK; +} + +static const struct INetworkInformationStaticsVtbl network_information_statics_vtbl = +{ + network_information_statics_QueryInterface, + network_information_statics_AddRef, + network_information_statics_Release, + /* IInspectable methods */ + network_information_statics_GetIids, + network_information_statics_GetRuntimeClassName, + network_information_statics_GetTrustLevel, + /* INetworkInformationStatics methods */ + network_information_statics_GetConnectionProfiles, + network_information_statics_GetInternetConnectionProfile, + network_information_statics_GetLanIdentifiers, + network_information_statics_GetHostNames, + network_information_statics_GetProxyConfigurationAsync, + network_information_statics_GetSortedEndpointPairs, + network_information_statics_add_NetworkStatusChanged, + network_information_statics_remove_NetworkStatusChanged, +}; + static struct network_information_statics network_information_statics = { {&factory_vtbl}, + {&network_information_statics_vtbl}, 1, };
diff --git a/dlls/windows.networking.connectivity/private.h b/dlls/windows.networking.connectivity/private.h index 0055b143d4f..9cff12a6cc6 100644 --- a/dlls/windows.networking.connectivity/private.h +++ b/dlls/windows.networking.connectivity/private.h @@ -34,9 +34,49 @@ #define WIDL_using_Windows_Foundation #define WIDL_using_Windows_Foundation_Collections #include "windows.foundation.h" +#define WIDL_using_Windows_Networking #define WIDL_using_Windows_Networking_Connectivity #include "windows.networking.connectivity.h" +#include "windows.networking.h"
extern IActivationFactory *network_information_factory;
+#define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr ) \ + static inline impl_type *impl_from( iface_type *iface ) \ + { \ + return CONTAINING_RECORD( iface, impl_type, iface_mem ); \ + } \ + static HRESULT WINAPI pfx##_QueryInterface( iface_type *iface, REFIID iid, void **out ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_QueryInterface( (IInspectable *)(expr), iid, out ); \ + } \ + static ULONG WINAPI pfx##_AddRef( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_AddRef( (IInspectable *)(expr) ); \ + } \ + static ULONG WINAPI pfx##_Release( iface_type *iface ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_Release( (IInspectable *)(expr) ); \ + } \ + static HRESULT WINAPI pfx##_GetIids( iface_type *iface, ULONG *iid_count, IID **iids ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetIids( (IInspectable *)(expr), iid_count, iids ); \ + } \ + static HRESULT WINAPI pfx##_GetRuntimeClassName( iface_type *iface, HSTRING *class_name ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetRuntimeClassName( (IInspectable *)(expr), class_name ); \ + } \ + static HRESULT WINAPI pfx##_GetTrustLevel( iface_type *iface, TrustLevel *trust_level ) \ + { \ + impl_type *impl = impl_from( iface ); \ + return IInspectable_GetTrustLevel( (IInspectable *)(expr), trust_level ); \ + } +#define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \ + DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface ) + #endif diff --git a/dlls/windows.networking.connectivity/tests/connectivity.c b/dlls/windows.networking.connectivity/tests/connectivity.c index 83bd13ff0e4..b49d2ca3a19 100644 --- a/dlls/windows.networking.connectivity/tests/connectivity.c +++ b/dlls/windows.networking.connectivity/tests/connectivity.c @@ -48,6 +48,7 @@ static void check_interface_( unsigned int line, void *obj, const IID *iid ) static void test_NetworkInformationStatics(void) { static const WCHAR *network_information_statics_name = L"Windows.Networking.Connectivity.NetworkInformation"; + INetworkInformationStatics *network_information_statics; IActivationFactory *factory; HSTRING str; HRESULT hr; @@ -69,6 +70,11 @@ static void test_NetworkInformationStatics(void) check_interface( factory, &IID_IInspectable ); check_interface( factory, &IID_IAgileObject );
+ hr = IActivationFactory_QueryInterface( factory, &IID_INetworkInformationStatics, (void **)&network_information_statics ); + ok( hr == S_OK, "got hr %#lx.\n", hr ); + + ref = INetworkInformationStatics_Release( network_information_statics ); + ok( ref == 2, "got ref %ld.\n", ref ); ref = IActivationFactory_Release( factory ); ok( ref == 1, "got ref %ld.\n", ref ); }
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- .../network_information.c | 164 +++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.networking.connectivity/network_information.c b/dlls/windows.networking.connectivity/network_information.c index 2e203cea88e..a01990bac73 100644 --- a/dlls/windows.networking.connectivity/network_information.c +++ b/dlls/windows.networking.connectivity/network_information.c @@ -18,6 +18,8 @@ */
#include "private.h" +#include "initguid.h" +#include "netlistmgr.h"
WINE_DEFAULT_DEBUG_CHANNEL(connectivity);
@@ -116,6 +118,152 @@ static const struct IActivationFactoryVtbl factory_vtbl = factory_ActivateInstance, };
+struct connection_profile +{ + IConnectionProfile IConnectionProfile_iface; + LONG ref; + + NetworkConnectivityLevel network_connectivity_level; +}; + +static inline struct connection_profile *impl_from_IConnectionProfile( IConnectionProfile *iface ) +{ + return CONTAINING_RECORD( iface, struct connection_profile, IConnectionProfile_iface ); +} + +static HRESULT WINAPI connection_profile_QueryInterface( IConnectionProfile *iface, REFIID iid, void **out ) +{ + struct connection_profile *impl = impl_from_IConnectionProfile( iface ); + + TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out ); + + if (IsEqualGUID( iid, &IID_IUnknown ) || + IsEqualGUID( iid, &IID_IInspectable ) || + IsEqualGUID( iid, &IID_IAgileObject ) || + IsEqualGUID( iid, &IID_IConnectionProfile )) + { + *out = &impl->IConnectionProfile_iface; + IInspectable_AddRef( *out ); + return S_OK; + } + + FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) ); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI connection_profile_AddRef( IConnectionProfile *iface ) +{ + struct connection_profile *impl = impl_from_IConnectionProfile( iface ); + ULONG ref = InterlockedIncrement( &impl->ref ); + TRACE( "iface %p increasing refcount to %lu.\n", iface, ref ); + return ref; +} + +static ULONG WINAPI connection_profile_Release( IConnectionProfile *iface ) +{ + struct connection_profile *impl = impl_from_IConnectionProfile( iface ); + ULONG ref = InterlockedDecrement( &impl->ref ); + + TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref ); + + if (!ref) free( impl ); + return ref; +} + +static HRESULT WINAPI connection_profile_GetIids( IConnectionProfile *iface, ULONG *iid_count, IID **iids ) +{ + FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetRuntimeClassName( IConnectionProfile *iface, HSTRING *class_name ) +{ + FIXME( "iface %p, class_name %p stub!\n", iface, class_name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetTrustLevel( IConnectionProfile *iface, TrustLevel *trust_level ) +{ + FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_get_ProfileName( IConnectionProfile *iface, HSTRING *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetNetworkConnectivityLevel( IConnectionProfile *iface, NetworkConnectivityLevel *value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetNetworkNames( IConnectionProfile *iface, IVectorView_HSTRING **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetConnectionCost( IConnectionProfile *iface, IConnectionCost **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetDataPlanStatus( IConnectionProfile *iface, IDataPlanStatus **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_get_NetworkAdapter( IConnectionProfile *iface, INetworkAdapter **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetLocalUsage( IConnectionProfile *iface, DateTime start, DateTime end, IDataUsage **value ) +{ + FIXME( "iface %p, start %llu, end %llu, value %p stub!\n", iface, start.UniversalTime, end.UniversalTime, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_GetLocalUsagePerRoamingStates( IConnectionProfile *iface, DateTime start, DateTime end, RoamingStates states, IDataUsage **value ) +{ + FIXME( "iface %p, start %llu, end %llu, states %u, value %p stub!\n", iface, start.UniversalTime, end.UniversalTime, states, value ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_profile_get_NetworkSecuritySettings( IConnectionProfile *iface, INetworkSecuritySettings **value ) +{ + FIXME( "iface %p, value %p stub!\n", iface, value ); + return E_NOTIMPL; +} + +static const struct IConnectionProfileVtbl connection_profile_vtbl = +{ + connection_profile_QueryInterface, + connection_profile_AddRef, + connection_profile_Release, + /* IInspectable methods */ + connection_profile_GetIids, + connection_profile_GetRuntimeClassName, + connection_profile_GetTrustLevel, + /* IConnectionProfile methods */ + connection_profile_get_ProfileName, + connection_profile_GetNetworkConnectivityLevel, + connection_profile_GetNetworkNames, + connection_profile_GetConnectionCost, + connection_profile_GetDataPlanStatus, + connection_profile_get_NetworkAdapter, + connection_profile_GetLocalUsage, + connection_profile_GetLocalUsagePerRoamingStates, + connection_profile_get_NetworkSecuritySettings, +}; + DEFINE_IINSPECTABLE( network_information_statics, INetworkInformationStatics, struct network_information_statics, IActivationFactory_iface )
static HRESULT WINAPI network_information_statics_GetConnectionProfiles( INetworkInformationStatics *iface, IVectorView_ConnectionProfile **value ) @@ -126,8 +274,20 @@ static HRESULT WINAPI network_information_statics_GetConnectionProfiles( INetwor
static HRESULT WINAPI network_information_statics_GetInternetConnectionProfile( INetworkInformationStatics *iface, IConnectionProfile **value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct connection_profile *impl; + + TRACE( "iface %p, value %p\n", iface, value ); + + *value = NULL; + if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; + + impl->IConnectionProfile_iface.lpVtbl = &connection_profile_vtbl; + impl->ref = 1; + impl->network_connectivity_level = NetworkConnectivityLevel_None; + + *value = &impl->IConnectionProfile_iface; + TRACE( "created IConnectionProfile %p.\n", *value ); + return S_OK; }
static HRESULT WINAPI network_information_statics_GetLanIdentifiers( INetworkInformationStatics *iface, IVectorView_LanIdentifier **value )
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 );
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Needed by Just Cause 4. --- .../network_information.c | 53 ++++++++++++++++--- .../tests/connectivity.c | 7 --- 2 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/dlls/windows.networking.connectivity/network_information.c b/dlls/windows.networking.connectivity/network_information.c index a01990bac73..8512b1c32af 100644 --- a/dlls/windows.networking.connectivity/network_information.c +++ b/dlls/windows.networking.connectivity/network_information.c @@ -123,7 +123,7 @@ struct connection_profile IConnectionProfile IConnectionProfile_iface; LONG ref;
- NetworkConnectivityLevel network_connectivity_level; + INetworkListManager *network_list_manager; };
static inline struct connection_profile *impl_from_IConnectionProfile( IConnectionProfile *iface ) @@ -167,7 +167,11 @@ static ULONG WINAPI connection_profile_Release( IConnectionProfile *iface )
TRACE( "iface %p decreasing refcount to %lu.\n", iface, ref );
- if (!ref) free( impl ); + if (!ref) + { + INetworkListManager_Release( impl->network_list_manager ); + free( impl ); + } return ref; }
@@ -197,8 +201,27 @@ static HRESULT WINAPI connection_profile_get_ProfileName( IConnectionProfile *if
static HRESULT WINAPI connection_profile_GetNetworkConnectivityLevel( IConnectionProfile *iface, NetworkConnectivityLevel *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct connection_profile *impl = impl_from_IConnectionProfile( iface ); + NetworkConnectivityLevel network_connectivity_level; + NLM_CONNECTIVITY connectivity = 0xdeadbeef; + HRESULT hr; + + TRACE( "iface %p, value %p\n", iface, value ); + + if (!value) return E_POINTER; + if (FAILED(hr = INetworkListManager_GetConnectivity( impl->network_list_manager, &connectivity ))) return hr; + + if (connectivity == NLM_CONNECTIVITY_DISCONNECTED) + network_connectivity_level = NetworkConnectivityLevel_None; + else if (connectivity & ( NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET )) + network_connectivity_level = NetworkConnectivityLevel_InternetAccess; + else if (connectivity & ( NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK | NLM_CONNECTIVITY_IPV4_NOTRAFFIC | NLM_CONNECTIVITY_IPV6_NOTRAFFIC )) + network_connectivity_level = NetworkConnectivityLevel_LocalAccess; + else + network_connectivity_level = NetworkConnectivityLevel_ConstrainedInternetAccess; + + *value = network_connectivity_level; + return S_OK; }
static HRESULT WINAPI connection_profile_GetNetworkNames( IConnectionProfile *iface, IVectorView_HSTRING **value ) @@ -274,20 +297,36 @@ static HRESULT WINAPI network_information_statics_GetConnectionProfiles( INetwor
static HRESULT WINAPI network_information_statics_GetInternetConnectionProfile( INetworkInformationStatics *iface, IConnectionProfile **value ) { + NetworkConnectivityLevel network_connectivity_level = 0xdeadbeef; + INetworkListManager *network_list_manager = NULL; struct connection_profile *impl; + HRESULT hr;
TRACE( "iface %p, value %p\n", iface, value );
*value = NULL; - if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY; + if (FAILED(hr = CoCreateInstance( &CLSID_NetworkListManager, NULL, CLSCTX_INPROC_SERVER, &IID_INetworkListManager, (void **)&network_list_manager ))) return hr; + if (!(impl = calloc( 1, sizeof(*impl) ))) + { + INetworkListManager_Release( network_list_manager ); + return E_OUTOFMEMORY; + }
impl->IConnectionProfile_iface.lpVtbl = &connection_profile_vtbl; impl->ref = 1; - impl->network_connectivity_level = NetworkConnectivityLevel_None; + impl->network_list_manager = network_list_manager; + + if (FAILED(hr = IConnectionProfile_GetNetworkConnectivityLevel( &impl->IConnectionProfile_iface, &network_connectivity_level )) || + network_connectivity_level == NetworkConnectivityLevel_None) + { + free( impl ); + INetworkListManager_Release( network_list_manager ); + return hr; + }
*value = &impl->IConnectionProfile_iface; TRACE( "created IConnectionProfile %p.\n", *value ); - return S_OK; + return hr; }
static HRESULT WINAPI network_information_statics_GetLanIdentifiers( INetworkInformationStatics *iface, IVectorView_LanIdentifier **value ) diff --git a/dlls/windows.networking.connectivity/tests/connectivity.c b/dlls/windows.networking.connectivity/tests/connectivity.c index ee2311a9e36..3aec6a5eeb9 100644 --- a/dlls/windows.networking.connectivity/tests/connectivity.c +++ b/dlls/windows.networking.connectivity/tests/connectivity.c @@ -268,7 +268,6 @@ static void check_connectivity_level_( unsigned int line, INetworkInformationSta }
hr = IConnectionProfile_GetNetworkConnectivityLevel( connection_profile, NULL ); - todo_wine ok_(__FILE__, line)( hr == E_POINTER, "got hr %#lx.\n", hr );
if (disconnect) @@ -287,22 +286,16 @@ static void check_connectivity_level_( unsigned int line, INetworkInformationSta 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 );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150169
Your paranoid android.
=== w11pro64 (32 bit report) ===
windows.networking.connectivity: connectivity.c:366: Test failed: got hr 0x80004005.
=== w11pro64_amd (64 bit report) ===
windows.networking.connectivity: connectivity.c:366: Test failed: got hr 0x80004005.
On Tue Dec 3 12:32:22 2024 +0000, Mohamad Al-Jaf wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/6917/diffs?diff_id=146807&start_sha=fd139ac00bfca12abd196c08fe18a9446a4042f4#174d4f0836cca841933a295fa43d3748470bc1b0_315_308)
No problem, done.
On Tue Dec 3 12:32:22 2024 +0000, Mohamad Al-Jaf wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/6917/diffs?diff_id=146807&start_sha=fd139ac00bfca12abd196c08fe18a9446a4042f4#174d4f0836cca841933a295fa43d3748470bc1b0_230_214)
Sounds good, done.
On Tue Dec 3 12:32:45 2024 +0000, Rémi Bernon wrote:
Wrt requiring administrator rights, tests used to run with admin rights anyway. It's not the case on some of the testbot VMs, but I think it is on most of them. This could be checked for and tests could be skipped otherwise (or simply the eventual permission error results gracefully handled in the test results).
You're right, a lot of them have admin rights. Though, the test itself is flaky. It takes a while for the network status to update.