wininet: Handle offline state in InternetGetConnectedStateExW.

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>
This commit is contained in:
Gabriel Ivăncescu 2022-10-18 19:40:05 +03:00 committed by Alexandre Julliard
parent 6c161f3359
commit 0ad36ed3e7
2 changed files with 61 additions and 7 deletions

View file

@ -1206,24 +1206,73 @@ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved)
BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnectionName,
DWORD dwNameLen, DWORD dwReserved)
{
IP_ADAPTER_ADDRESSES *buf = NULL, *aa;
ULONG size = 0;
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;
for (;;)
{
ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER |
GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_INCLUDE_ALL_GATEWAYS;
ULONG errcode = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, buf, &size);
if (errcode == ERROR_SUCCESS)
break;
heap_free(buf);
if (errcode == ERROR_BUFFER_OVERFLOW && !(buf = heap_alloc(size)))
errcode = ERROR_NOT_ENOUGH_MEMORY;
if (errcode != ERROR_BUFFER_OVERFLOW)
{
if (errcode != ERROR_NO_DATA)
{
SetLastError(errcode);
return FALSE;
}
buf = NULL;
break;
}
}
status = INTERNET_RAS_INSTALLED;
for (aa = buf; aa; aa = aa->Next)
{
/* Connected, but not necessarily to internet */
if (aa->FirstUnicastAddress)
status |= INTERNET_CONNECTION_OFFLINE;
/* Connected to internet */
if (aa->FirstGatewayAddress)
{
WARN("always returning LAN connection.\n");
status &= ~INTERNET_CONNECTION_OFFLINE;
status |= INTERNET_CONNECTION_LAN;
break;
}
}
heap_free(buf);
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;
}

View file

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