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; }