From: Gabriel Ivăncescu gabrielopcode@gmail.com
Some applications (e.g. Deus Ex Human Revolution: Director's Cut) use the output from this function to determine whether they should connect.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
For DXHR, it happens on exit and it hangs retrying for a while, even on Windows, if there's an internet connection. This makes it have Windows behavior when there's no connection, to help at least in those cases. --- dlls/wininet/Makefile.in | 2 +- dlls/wininet/internet.c | 52 +++++++++++++++++++++++++++++++---- dlls/wininet/tests/internet.c | 9 ++++-- 3 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/dlls/wininet/Makefile.in b/dlls/wininet/Makefile.in index 7e8111f811d..2b5a55fb6c2 100644 --- a/dlls/wininet/Makefile.in +++ b/dlls/wininet/Makefile.in @@ -1,6 +1,6 @@ MODULE = wininet.dll IMPORTLIB = wininet -IMPORTS = $(ZLIB_PE_LIBS) mpr shlwapi shell32 user32 ws2_32 advapi32 +IMPORTS = $(ZLIB_PE_LIBS) ole32 mpr shlwapi shell32 user32 ws2_32 advapi32 EXTRAINCL = $(ZLIB_PE_CFLAGS) DELAYIMPORTS = secur32 crypt32 cryptui dhcpcsvc iphlpapi
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index 120cc9af4cc..b3fd462ffc4 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -37,8 +37,10 @@ #include <assert.h> #include <wchar.h>
+#define COBJMACROS #include "windef.h" #include "winbase.h" +#include "initguid.h" #include "winreg.h" #include "winuser.h" #include "wininet.h" @@ -51,6 +53,7 @@ #include "winternl.h" #include "iphlpapi.h" #include "dhcpcsdk.h" +#include "netlistmgr.h"
#include "internet.h" #include "resource.h" @@ -1206,24 +1209,63 @@ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved) BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnectionName, DWORD dwNameLen, DWORD dwReserved) { + NLM_CONNECTIVITY connectivity; + INetworkListManager *mgr; + VARIANT_BOOL connected; + HRESULT hres; + DWORD status; + TRACE("(%p, %p, %ld, 0x%08lx)\n", lpdwStatus, lpszConnectionName, dwNameLen, dwReserved);
/* Must be zero */ if(dwReserved) return FALSE;
- if (lpdwStatus) { - WARN("always returning LAN connection and RAS installed.\n"); - *lpdwStatus = INTERNET_CONNECTION_LAN | INTERNET_RAS_INSTALLED; + CoInitialize(NULL); + status = INTERNET_RAS_INSTALLED; + + hres = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_INPROC_SERVER, &IID_INetworkListManager, (void**)&mgr); + if (hres == S_OK) + { + if (SUCCEEDED(INetworkListManager_GetConnectivity(mgr, &connectivity)) && + connectivity != NLM_CONNECTIVITY_DISCONNECTED) + { + if (SUCCEEDED(INetworkListManager_IsConnectedToInternet(mgr, &connected)) && connected) + { + WARN("always returning LAN connection.\n"); + status |= INTERNET_CONNECTION_LAN; + } + else + { + status |= INTERNET_CONNECTION_OFFLINE; + } + } + INetworkListManager_Release(mgr); } + CoUninitialize(); + + if ((hres & 0xffff0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0)) + { + SetLastError(HRESULT_CODE(hres)); + return FALSE; + } + + if (lpdwStatus) *lpdwStatus = status;
/* When the buffer size is zero LoadStringW fills the buffer with a pointer to * the resource, avoid it as we must not change the buffer in this case */ - if(lpszConnectionName && dwNameLen) { + if (lpszConnectionName && dwNameLen) + { *lpszConnectionName = '\0'; - LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); + if (status & INTERNET_CONNECTION_LAN) + LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); }
+ if (!(status & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_MODEM | INTERNET_CONNECTION_PROXY))) + { + SetLastError(ERROR_SUCCESS); + return FALSE; + } return TRUE; }
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 97bd36f9427..0d58a12558e 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -1730,12 +1730,17 @@ static void test_InternetGetConnectedStateExW(void) }
flags = 0; - buffer[0] = 0; + wcscpy(buffer, L"wine"); + SetLastError(0xdeadbeef); res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0); trace("Internet Connection: Flags 0x%02lx - Name '%s'\n", flags, wine_dbgstr_w(buffer)); ok (flags & INTERNET_RAS_INSTALLED, "Missing RAS flag\n"); if(!res) { - win_skip("InternetGetConnectedStateExW tests require a valid connection\n"); + DWORD error = GetLastError(); + ok(error == ERROR_SUCCESS, "Last error = %#lx\n", error); + ok(!buffer[0], "Expected empty connection name, got %s\n", wine_dbgstr_w(buffer)); + + skip("InternetGetConnectedStateExW tests require a valid connection\n"); return; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/netprofm/list.c | 51 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-)
diff --git a/dlls/netprofm/list.c b/dlls/netprofm/list.c index 254cf60c263..de6f6869e3e 100644 --- a/dlls/netprofm/list.c +++ b/dlls/netprofm/list.c @@ -50,6 +50,8 @@ struct network GUID id; VARIANT_BOOL connected_to_internet; VARIANT_BOOL connected; + BOOLEAN ipv4; + BOOLEAN ipv6; };
struct connection @@ -62,6 +64,8 @@ struct connection INetwork *network; VARIANT_BOOL connected_to_internet; VARIANT_BOOL connected; + BOOLEAN ipv4; + BOOLEAN ipv6; };
struct connection_point @@ -480,9 +484,16 @@ static HRESULT WINAPI network_GetConnectivity( INetwork *iface, NLM_CONNECTIVITY *pConnectivity ) { + struct network *network = impl_from_INetwork( iface ); + FIXME( "%p, %p\n", iface, pConnectivity );
- *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET; + *pConnectivity = NLM_CONNECTIVITY_DISCONNECTED; + if (network->ipv4) + *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; + if (network->ipv6) + *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + return S_OK; }
@@ -1330,9 +1341,19 @@ static HRESULT WINAPI list_manager_GetConnectivity( INetworkListManager *iface, NLM_CONNECTIVITY *pConnectivity ) { + struct list_manager *mgr = impl_from_INetworkListManager( iface ); + struct network *network; + FIXME( "%p, %p\n", iface, pConnectivity );
- *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET; + *pConnectivity = NLM_CONNECTIVITY_DISCONNECTED; + + LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry ) + { + if (network->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; + if (network->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + } + return S_OK; }
@@ -1565,9 +1586,16 @@ static HRESULT WINAPI connection_GetConnectivity( INetworkConnection *iface, NLM_CONNECTIVITY *pConnectivity ) { + struct connection *connection = impl_from_INetworkConnection( iface ); + FIXME( "%p, %p\n", iface, pConnectivity );
- *pConnectivity = NLM_CONNECTIVITY_IPV4_INTERNET; + *pConnectivity = NLM_CONNECTIVITY_DISCONNECTED; + if (connection->ipv4) + *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; + if (connection->ipv6) + *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + return S_OK; }
@@ -1761,6 +1789,23 @@ static void init_networks( struct list_manager *mgr ) network->connected_to_internet = VARIANT_TRUE; connection->connected_to_internet = VARIANT_TRUE; } + if (aa->u1.Flags & IP_ADAPTER_IPV6_ENABLED) + { + network->ipv6 = TRUE; + connection->ipv6 = TRUE; + network->ipv4 = FALSE; + connection->ipv4 = FALSE; + if (aa->u1.Flags & IP_ADAPTER_IPV4_ENABLED) + { + network->ipv4 = TRUE; + connection->ipv4 = TRUE; + } + } + else + { + network->ipv4 = TRUE; + connection->ipv4 = TRUE; + }
connection->network = &network->INetwork_iface; INetwork_AddRef( connection->network );
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/netprofm/list.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/dlls/netprofm/list.c b/dlls/netprofm/list.c index de6f6869e3e..14cdc1a3a63 100644 --- a/dlls/netprofm/list.c +++ b/dlls/netprofm/list.c @@ -489,11 +489,16 @@ static HRESULT WINAPI network_GetConnectivity( FIXME( "%p, %p\n", iface, pConnectivity );
*pConnectivity = NLM_CONNECTIVITY_DISCONNECTED; - if (network->ipv4) - *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; - if (network->ipv6) - *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; - + if (network->connected_to_internet) + { + if (network->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; + if (network->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + } + else if (network->connected) + { + if (network->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_LOCALNETWORK; + if (network->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_LOCALNETWORK; + } return S_OK; }
@@ -1350,8 +1355,16 @@ static HRESULT WINAPI list_manager_GetConnectivity(
LIST_FOR_EACH_ENTRY( network, &mgr->networks, struct network, entry ) { - if (network->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; - if (network->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + if (network->connected_to_internet) + { + if (network->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; + if (network->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + } + else if (network->connected) + { + if (network->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_LOCALNETWORK; + if (network->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_LOCALNETWORK; + } }
return S_OK; @@ -1591,11 +1604,16 @@ static HRESULT WINAPI connection_GetConnectivity( FIXME( "%p, %p\n", iface, pConnectivity );
*pConnectivity = NLM_CONNECTIVITY_DISCONNECTED; - if (connection->ipv4) - *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; - if (connection->ipv6) - *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; - + if (connection->connected_to_internet) + { + if (connection->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_INTERNET; + if (connection->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_INTERNET; + } + else if (connection->connected) + { + if (connection->ipv4) *pConnectivity |= NLM_CONNECTIVITY_IPV4_LOCALNETWORK; + if (connection->ipv6) *pConnectivity |= NLM_CONNECTIVITY_IPV6_LOCALNETWORK; + } return S_OK; }
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=125053
Your paranoid android.
=== debian11 (32 bit report) ===
ddraw: ddraw7.c:15663: Test failed: Expected unsynchronised map for flags 0x1000. ddraw7.c:15663: Test failed: Expected unsynchronised map for flags 0x3000.
=== debian11 (build log) ===
Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24738. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24738. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24738.
Jacek Caban (@jacek) commented about dlls/wininet/internet.c:
if (SUCCEEDED(INetworkListManager_GetConnectivity(mgr, &connectivity)) &&
connectivity != NLM_CONNECTIVITY_DISCONNECTED)
{
if (SUCCEEDED(INetworkListManager_IsConnectedToInternet(mgr, &connected)) && connected)
{
WARN("always returning LAN connection.\n");
status |= INTERNET_CONNECTION_LAN;
}
else
{
status |= INTERNET_CONNECTION_OFFLINE;
}
}
}INetworkListManager_Release(mgr);
- CoUninitialize();
`CoInitialize()` may fail (eg. for MTAs) and then you will do an unmatched `CoUninitialize()` call. You could check `CoInitialize()` result, but I'm not sure why you use `CLSID_NetworkListManager` at all. Could we just use `GetAdaptersAddresses` directly instead?
Jacek Caban (@jacek) commented about dlls/netprofm/list.c:
{
network->ipv6 = TRUE;
connection->ipv6 = TRUE;
network->ipv4 = FALSE;
connection->ipv4 = FALSE;
if (aa->u1.Flags & IP_ADAPTER_IPV4_ENABLED)
{
network->ipv4 = TRUE;
connection->ipv4 = TRUE;
}
}
else
{
network->ipv4 = TRUE;
connection->ipv4 = TRUE;
}
IP_ADAPTER_IPV4_ENABLED checks look suspicious here, you check it only if IP_ADAPTER_IPV6_ENABLED is set but assume it unconditionally otherwise. Is it a workaround for the fact that those flags are not implemented in Wine?
On Tue Oct 18 08:40:21 2022 +0000, Jacek Caban wrote:
`CoInitialize()` may fail (eg. for MTAs) and then you will do an unmatched `CoUninitialize()` call. You could check `CoInitialize()` result, but I'm not sure why you use `CLSID_NetworkListManager` at all. Could we just use `GetAdaptersAddresses` directly instead?
Oh, I just wanted to re-use the existing implementation, but I wasn't aware of the pitfalls of CoInitialize. I'll look into the alternative.
On Tue Oct 18 08:40:22 2022 +0000, Jacek Caban wrote:
IP_ADAPTER_IPV4_ENABLED checks look suspicious here, you check it only if IP_ADAPTER_IPV6_ENABLED is set but assume it unconditionally otherwise. Is it a workaround for the fact that those flags are not implemented in Wine?
Yeah, I was also concerned about changing the current code behavior for ipv4, which I did not want to touch at all. Should I add a FIXME comment?
On Tue Oct 18 15:17:33 2022 +0000, Gabriel Ivăncescu wrote:
Yeah, I was also concerned about changing the current code behavior for ipv4, which I did not want to touch at all. Should I add a FIXME comment?
Unless I'm missing something, ipv6 patch will never be used in current Wine, I don't really see a point of this patch...
On Tue Oct 18 15:49:52 2022 +0000, Jacek Caban wrote:
Unless I'm missing something, ipv6 patch will never be used in current Wine, I don't really see a point of this patch...
Yeah, you're right, it seems the flag is not implemented. I'll just drop them.