582 lines
17 KiB
C++
582 lines
17 KiB
C++
//=======================================================================
|
|
//
|
|
// Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// File: internet.cpp
|
|
//
|
|
// Creator: PeterWi
|
|
//
|
|
// Purpose: internet functions.
|
|
//
|
|
//=======================================================================
|
|
|
|
#pragma hdrstop
|
|
|
|
#include <tchar.h>
|
|
#include <winsock2.h> // for LPWSADATA, struct hostent
|
|
#include <wininet.h> // for InternetGetConnectedState(), InternetQueryOptionA()
|
|
#include <iphlpapi.h> // for IPAddr
|
|
#include <sensapi.h> // for NETWORK_ALIVE_*
|
|
|
|
#include <logging.h> // for LOG_Block, LOG_Error and LOG_Internet
|
|
#include <MemUtil.h> // USES_IU_CONVERSION, T2A(), MemAlloc
|
|
#include <wusafefn.h>
|
|
#include <shlwapi.h> // UrlGetPart
|
|
#include <MISTSafe.h>
|
|
|
|
#include <URLLogging.h>
|
|
|
|
#define ARRAYSIZE(a) (sizeof(a)/sizeof((a)[0]))
|
|
|
|
typedef BOOL (WINAPI * ISNETWORKALIVE)(LPDWORD);
|
|
//typedef BOOL (WINAPI * INETCONNECTSTATE)(LPDWORD, DWORD);
|
|
//typedef BOOL (WINAPI * INETQUERYOPTION)(HINTERNET, DWORD, LPVOID, LPDWORD);
|
|
typedef DWORD (WINAPI * GETBESTINTERFACE)(IPAddr, DWORD *);
|
|
typedef ULONG (WINAPI * INET_ADDR)(const char FAR *);
|
|
typedef struct hostent FAR * (WINAPI * GETHOSTBYNAME)(const char FAR *name);
|
|
typedef int (WINAPI * WSASTARTUP)(WORD, LPWSADATA);
|
|
typedef int (WINAPI * WSACLEANUP)(void);
|
|
#ifdef DBG
|
|
typedef int (WINAPI * WSAGETLASTERROR)(void);
|
|
#endif
|
|
|
|
const char c_szWU_PING_URL[] = "207.46.226.17"; // current ip addr for windowsupdate.microsoft.com
|
|
|
|
// forward declarations
|
|
BOOL IsConnected_2_0(void);
|
|
|
|
// HKLM\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\IsConnected DWORD reg value
|
|
#define ISCONNECTEDMODE_Unknown -1 // static variable not initialized yet
|
|
#define ISCONNECTEDMODE_Default 0
|
|
// live: use AU 2.0 logic
|
|
// test = InternetGetConnectedState + InternetQueryOption + GetBestInterface on static IP
|
|
// CorpWU: same as ISCONNECTEDMODE_IsNetworkAliveAndGetBestInterface
|
|
#define ISCONNECTEDMODE_AlwaysConnected 1
|
|
// live/CorpWU: Assume the destination is always reachable. e.g. via D-tap connection.
|
|
#define ISCONNECTEDMODE_IsNetworkAliveOnly 2
|
|
// live/CorpWU: test = IsNetworkAlive.
|
|
#define ISCONNECTEDMODE_IsNetworkAliveAndGetBestInterface 3
|
|
// live: test = IsNetworkAlive + GetBestInterface on static IP
|
|
// CorpWU: test = IsNetworkAlive + gethostbyname + GetBestInterface
|
|
|
|
#define ISCONNECTEDMODE_MinValue 0
|
|
#define ISCONNECTEDMODE_MaxValue 3
|
|
|
|
inline DWORD GetIsConnectedMode(void)
|
|
{
|
|
static DWORD s_dwIsConnectedMode = ISCONNECTEDMODE_Unknown;
|
|
|
|
if (ISCONNECTEDMODE_Unknown == s_dwIsConnectedMode)
|
|
{
|
|
// Assume using default connection detection mechanism
|
|
s_dwIsConnectedMode = ISCONNECTEDMODE_Default;
|
|
|
|
const TCHAR c_tszRegKeyWU[] = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate");
|
|
const TCHAR c_tszRegUrlLogIsConnectedMode[] = _T("IsConnectedMode");
|
|
|
|
HKEY hkey;
|
|
|
|
if (NO_ERROR == RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
c_tszRegKeyWU,
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hkey))
|
|
{
|
|
DWORD dwSize = sizeof(s_dwIsConnectedMode);
|
|
DWORD dwType;
|
|
|
|
if (NO_ERROR != RegQueryValueEx(
|
|
hkey,
|
|
c_tszRegUrlLogIsConnectedMode,
|
|
0,
|
|
&dwType,
|
|
(LPBYTE) &s_dwIsConnectedMode,
|
|
&dwSize) ||
|
|
REG_DWORD != dwType ||
|
|
sizeof(s_dwIsConnectedMode) != dwSize ||
|
|
// comment out the next line to avoid error C4296: '>' : expression is always false
|
|
// ISCONNECTEDMODE_MinValue > s_dwIsConnectedMode ||
|
|
ISCONNECTEDMODE_MaxValue < s_dwIsConnectedMode)
|
|
{
|
|
s_dwIsConnectedMode = ISCONNECTEDMODE_Default;
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
return s_dwIsConnectedMode;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// IsConnected()
|
|
// detect if there is a connection currently that can be used to
|
|
// connect to Windows Update site.
|
|
// If yes, we activate the shedule DLL
|
|
//
|
|
// Input : ptszUrl - Url containing host name to check for connection
|
|
// fLive - whether the destination is the live site
|
|
// Output: None
|
|
// Return: TRUE if we are connected and we can reach the web site.
|
|
// FALSE if we cannot reach the site or we are not connected.
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
BOOL IsConnected(LPCTSTR ptszUrl, BOOL fLive)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwFlags = 0;
|
|
ISNETWORKALIVE pIsNetworkAlive = NULL;
|
|
HMODULE hIphlp = NULL, hSock = NULL, hSens = NULL;
|
|
DWORD dwIsConnectedMode = GetIsConnectedMode();
|
|
|
|
LOG_Block("IsConnected");
|
|
|
|
if (ISCONNECTEDMODE_AlwaysConnected == dwIsConnectedMode)
|
|
{
|
|
LOG_Internet(_T("AlwaysConnected"));
|
|
bRet = TRUE;
|
|
goto lFinish;
|
|
}
|
|
|
|
if (fLive && ISCONNECTEDMODE_Default == dwIsConnectedMode)
|
|
{
|
|
LOG_Internet(_T("Use 2.0 algorithm"));
|
|
bRet = IsConnected_2_0();
|
|
goto lFinish;
|
|
}
|
|
|
|
// InternetGetConnectedState() returns FALSE if Wininet/IE AutoDial is configured.
|
|
// Thus we can't rely on it to see if we have network connectivity.
|
|
#if 0
|
|
DWORD dwConnMethod = 0, dwState = 0, dwSize = sizeof(DWORD);
|
|
|
|
bRet = InternetGetConnectedState(&dwConnMethod, 0);
|
|
|
|
#ifdef DBG
|
|
|
|
LOG_Internet(_T("Connection Method is %#lx"), dwConnMethod);
|
|
LOG_Internet(_T("InternetGetConnectedState() return value %d"), bRet);
|
|
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM)
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_MODEM"));
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_LAN )
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_LAN"));
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_PROXY )
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_PROXY"));
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY )
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_MODEM_BUSY"));
|
|
}
|
|
#endif
|
|
|
|
if (bRet)
|
|
{
|
|
// modem is dialing
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY)
|
|
{
|
|
bRet = FALSE;
|
|
goto lFinish;
|
|
}
|
|
|
|
// check if there is a proxy but currently user is offline
|
|
if (dwConnMethod & INTERNET_CONNECTION_PROXY)
|
|
{
|
|
if (InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
|
|
{
|
|
if (dwState & (INTERNET_STATE_DISCONNECTED_BY_USER | INTERNET_STATE_DISCONNECTED))
|
|
{
|
|
bRet = FALSE;
|
|
goto lFinish;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_Error(_T("IsConnected() fail to get InternetQueryOption (%#lx)"), GetLastError());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// further test the case that user didn't run icw but is using a modem connection
|
|
//
|
|
const DWORD dwModemConn = (INTERNET_CONNECTION_MODEM | INTERNET_CONNECTION_MODEM_BUSY);
|
|
if ((dwConnMethod & dwModemConn) == dwModemConn)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
//one final check for connectivity by pinging microsoft.com
|
|
//if (bRet)
|
|
//{
|
|
// bRet = CheckByPing(szURL);
|
|
//}
|
|
//bugfix for InternetGetConnectedState API - if LAN card is disabled it still returns LAN connection
|
|
//use GetBestInterface and see if there is any error trying to reach an outside IP address
|
|
//this may fix scenarios in homelan case where there is no actual connection to internet??
|
|
if (!bRet || (dwConnMethod & INTERNET_CONNECTION_LAN)) //LAN card present
|
|
//bug 299338
|
|
{
|
|
// do gethostbyname and GetBestInterface
|
|
}
|
|
#endif
|
|
|
|
if (NULL == (hSens = LoadLibraryFromSystemDir(TEXT("sensapi.dll"))) ||
|
|
NULL == (pIsNetworkAlive = (ISNETWORKALIVE)::GetProcAddress(hSens, "IsNetworkAlive")))
|
|
{
|
|
LOG_Error(_T("failed to load IsNetworkAlive() from sensapi.dll"));
|
|
goto lFinish;
|
|
}
|
|
|
|
if (pIsNetworkAlive(&dwFlags))
|
|
{
|
|
#ifdef DBG
|
|
if (NETWORK_ALIVE_LAN & dwFlags)
|
|
{
|
|
LOG_Internet(_T("active LAN card(s) detected"));
|
|
}
|
|
if (NETWORK_ALIVE_WAN & dwFlags)
|
|
{
|
|
LOG_Internet(_T("active RAS connection(s) detected"));
|
|
}
|
|
if (NETWORK_ALIVE_AOL & dwFlags)
|
|
{
|
|
LOG_Internet(_T("AOL connection detected"));
|
|
}
|
|
#endif
|
|
if (ISCONNECTEDMODE_IsNetworkAliveOnly == dwIsConnectedMode)
|
|
{
|
|
LOG_Internet(_T("IsNetworkAliveOnly ok"));
|
|
bRet = TRUE;
|
|
goto lFinish;
|
|
}
|
|
|
|
// can't be moved into where ptszHostName and pszHostName are
|
|
// MemAlloc'ed since pszHostName will be used outside that block.
|
|
USES_IU_CONVERSION;
|
|
|
|
GETBESTINTERFACE pGetBestInterface = NULL;
|
|
INET_ADDR pInetAddr = NULL;
|
|
LPCSTR pszHostName = NULL;
|
|
|
|
if (fLive && ISCONNECTEDMODE_IsNetworkAliveAndGetBestInterface == dwIsConnectedMode)
|
|
{
|
|
pszHostName = c_szWU_PING_URL;
|
|
}
|
|
else
|
|
{
|
|
// !fLive && (ISCONNECTEDMODE_Default == dwIsConnectedMode ||
|
|
// ISCONNECTEDMODE_IsNetworkAliveAndGetBestInterface == dwIsConnectedMode)
|
|
if (NULL == ptszUrl || _T('\0') == ptszUrl[0])
|
|
{
|
|
LOG_Error(_T("IsConnected() invalid parameter"));
|
|
}
|
|
else
|
|
{
|
|
TCHAR tszHostName[40]; // arbitrary buffer size that should work with most domain names
|
|
DWORD dwCchHostName = ARRAYSIZE(tszHostName);
|
|
LPTSTR ptszHostName = tszHostName;
|
|
|
|
HRESULT hr = UrlGetPart(ptszUrl, tszHostName, &dwCchHostName, URL_PART_HOSTNAME, 0);
|
|
|
|
if (E_POINTER == hr)
|
|
{
|
|
if (NULL != (ptszHostName = (LPTSTR) MemAlloc(sizeof(TCHAR) * dwCchHostName)))
|
|
{
|
|
hr = UrlGetPart(ptszUrl, ptszHostName, &dwCchHostName, URL_PART_HOSTNAME, 0);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
LOG_Error(_T("failed to extract hostname (error %#lx)"), hr);
|
|
}
|
|
else
|
|
{
|
|
pszHostName = T2A(ptszHostName);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NULL == pszHostName)
|
|
{
|
|
LOG_Error(_T("call to T2A (IU version) failed"));
|
|
}
|
|
else if (
|
|
NULL != (hIphlp = LoadLibraryFromSystemDir(TEXT("iphlpapi.dll"))) &&
|
|
NULL != (hSock = LoadLibraryFromSystemDir(TEXT("ws2_32.dll"))) &&
|
|
NULL != (pGetBestInterface = (GETBESTINTERFACE)::GetProcAddress(hIphlp, "GetBestInterface")) &&
|
|
NULL != (pInetAddr = (INET_ADDR)::GetProcAddress(hSock, "inet_addr")))
|
|
{
|
|
IPAddr dest;
|
|
|
|
LOG_Internet(_T("checking connection to %hs..."), pszHostName);
|
|
|
|
//fixcode: should check against broadcasting IP addresses
|
|
if (INADDR_NONE == (dest = pInetAddr(pszHostName)))
|
|
{
|
|
GETHOSTBYNAME pGetHostByName = NULL;
|
|
WSASTARTUP pWSAStartup = NULL;
|
|
WSACLEANUP pWSACleanup = NULL;
|
|
#ifdef DBG
|
|
WSAGETLASTERROR pWSAGetLastError = NULL;
|
|
#endif
|
|
WSADATA wsaData;
|
|
int iErr = 0;
|
|
|
|
if (NULL != (pGetHostByName = (GETHOSTBYNAME)::GetProcAddress(hSock, "gethostbyname")) &&
|
|
#ifdef DBG
|
|
NULL != (pWSAGetLastError = (WSAGETLASTERROR)::GetProcAddress(hSock, "WSAGetLastError")) &&
|
|
#endif
|
|
NULL != (pWSAStartup = (WSASTARTUP)::GetProcAddress(hSock, "WSAStartup")) &&
|
|
NULL != (pWSACleanup = (WSACLEANUP)::GetProcAddress(hSock, "WSACleanup")) &&
|
|
|
|
//fixcode: should be called at the constructor of CUrlLog and when IU (when online) or AU starts.
|
|
0 == pWSAStartup(MAKEWORD(1, 1), &wsaData))
|
|
{
|
|
#ifdef DBG
|
|
DWORD dwStartTime = GetTickCount();
|
|
#endif
|
|
struct hostent *ptHost = pGetHostByName(pszHostName);
|
|
|
|
if (NULL != ptHost &&
|
|
AF_INET == ptHost->h_addrtype &&
|
|
sizeof(IPAddr) == ptHost->h_length &&
|
|
NULL != ptHost->h_addr_list &&
|
|
NULL != ptHost->h_addr)
|
|
{
|
|
// take the first IP address
|
|
dest = *((IPAddr FAR *) ptHost->h_addr);
|
|
#ifdef DBG
|
|
LOG_Internet(
|
|
_T("Host name %hs resolved to be %d.%d.%d.%d, took %d msecs"),
|
|
pszHostName,
|
|
(BYTE) ((ptHost->h_addr)[0]),
|
|
(BYTE) ((ptHost->h_addr)[1]),
|
|
(BYTE) ((ptHost->h_addr)[2]),
|
|
(BYTE) ((ptHost->h_addr)[3]),
|
|
GetTickCount() - dwStartTime);
|
|
#endif
|
|
}
|
|
#ifdef DBG
|
|
else
|
|
{
|
|
LOG_Internet(_T("Host name %hs couldn't be resolved (error %d), took %d msecs"), pszHostName, pWSAGetLastError(), GetTickCount() - dwStartTime);
|
|
}
|
|
#endif
|
|
//fixcode: should be called at the destructor of CUrlLog and when IU (when online) or AU ends.
|
|
if (iErr = pWSACleanup())
|
|
{
|
|
LOG_Error(_T("failed to clean up winsock (error %d)"), iErr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_Error(_T("failed to load winsock procs or WSAStartup() failed"));
|
|
}
|
|
}
|
|
|
|
if (INADDR_NONE != dest)
|
|
{
|
|
DWORD dwErr, dwIndex;
|
|
|
|
if (bRet = (NO_ERROR == (dwErr = pGetBestInterface(dest, &dwIndex))))
|
|
{
|
|
LOG_Internet(_T("route found on interface #%d"), dwIndex);
|
|
}
|
|
else
|
|
{
|
|
LOG_Internet(_T("GetBestInterface() failed w/ error %d"), dwErr);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_Error(_T("failed to load procs from winsock/ip helper (error %d)"), GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_Internet(_T("no active connection detected"));
|
|
}
|
|
|
|
lFinish:
|
|
if (hIphlp != NULL)
|
|
{
|
|
FreeLibrary(hIphlp);
|
|
}
|
|
if (hSock != NULL)
|
|
{
|
|
FreeLibrary(hSock);
|
|
}
|
|
if (hSens != NULL)
|
|
{
|
|
FreeLibrary(hSens);
|
|
}
|
|
|
|
return (bRet);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
//
|
|
// Function IsConnected_2_0()
|
|
// detect if there is a cunection currently can be used to
|
|
// connect to live Windows Update site.
|
|
// If yes, we activate the shedule DLL
|
|
//
|
|
// Input : None
|
|
// Output: None
|
|
// Return: TRUE if we are connected and we can reach the web site.
|
|
// FALSE if we cannot reach the live site or we are not connected.
|
|
//
|
|
//
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
BOOL IsConnected_2_0()
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwConnMethod, dwState = 0, dwSize = sizeof(DWORD), dwErr, dwIndex;
|
|
GETBESTINTERFACE pGetBestInterface = NULL;
|
|
INET_ADDR pInet_addr = NULL;
|
|
HMODULE hIphlp = NULL, hSock = NULL;
|
|
|
|
LOG_Block("IsConnected");
|
|
|
|
bRet = InternetGetConnectedState(&dwConnMethod, 0);
|
|
|
|
/*
|
|
#ifdef DBG
|
|
|
|
LOG_Internet(_T("Connection Method is %#lx"), dwConnMethod);
|
|
LOG_Internet(_T("InternetGetConnectedState() return value %d"), bRet);
|
|
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM)
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_MODEM"));
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_LAN )
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_LAN"));
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_PROXY )
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_PROXY"));
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY )
|
|
{
|
|
LOG_Internet(_T("\t%s"), _T("INTERNET_CONNECTION_MODEM_BUSY"));
|
|
}
|
|
#endif
|
|
*/
|
|
|
|
if (bRet)
|
|
{
|
|
// modem is dialing
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY)
|
|
{
|
|
bRet = FALSE;
|
|
goto lFinish;
|
|
}
|
|
|
|
// check if there is a proxy but currently user is offline
|
|
if (dwConnMethod & INTERNET_CONNECTION_PROXY)
|
|
{
|
|
if (InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
|
|
{
|
|
if (dwState & (INTERNET_STATE_DISCONNECTED_BY_USER | INTERNET_STATE_DISCONNECTED))
|
|
{
|
|
bRet = FALSE;
|
|
goto lFinish;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG_Error(_T("IsConnected() fail to get InternetQueryOption (%#lx)"), GetLastError());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// further test the case that user didn't run icw but is using a modem connection
|
|
//
|
|
const DWORD dwModemConn = (INTERNET_CONNECTION_MODEM | INTERNET_CONNECTION_MODEM_BUSY);
|
|
if ((dwConnMethod & dwModemConn) == dwModemConn)
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
//one final check for connectivity by pinging microsoft.com
|
|
//if (bRet)
|
|
//{
|
|
// bRet = CheckByPing(szURL);
|
|
//}
|
|
//bugfix for InternetGetConnectedState API - if LAN card is disabled it still returns LAN connection
|
|
//use GetBestInterface and see if there is any error trying to reach an outside IP address
|
|
//this may fix scenarios in homelan case where there is no actual connection to internet??
|
|
if ((bRet && (dwConnMethod & INTERNET_CONNECTION_LAN)) || //LAN card present
|
|
(!bRet)) //bug 299338
|
|
{
|
|
struct sockaddr_in dest;
|
|
hSock = LoadLibraryFromSystemDir(TEXT("ws2_32.dll"));
|
|
hIphlp = LoadLibraryFromSystemDir(TEXT("iphlpapi.dll"));
|
|
if ((hIphlp == NULL) || (hSock == NULL))
|
|
{
|
|
goto lFinish;
|
|
}
|
|
|
|
pGetBestInterface = (GETBESTINTERFACE)::GetProcAddress(hIphlp, "GetBestInterface");
|
|
pInet_addr = (INET_ADDR)::GetProcAddress(hSock, "inet_addr");
|
|
if ((pGetBestInterface == NULL) || (pInet_addr == NULL))
|
|
{
|
|
goto lFinish;
|
|
}
|
|
if ((dest.sin_addr.s_addr = pInet_addr(c_szWU_PING_URL)) == INADDR_ANY)
|
|
{
|
|
goto lFinish;
|
|
}
|
|
if (NO_ERROR != (dwErr = pGetBestInterface(dest.sin_addr.s_addr, &dwIndex)))
|
|
{
|
|
LOG_ErrorMsg(dwErr);
|
|
bRet = FALSE;
|
|
//any error bail out for now
|
|
/*
|
|
if (dwErr == ERROR_NETWORK_UNREACHABLE) //winerror.h
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
*/
|
|
}
|
|
else
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
lFinish:
|
|
if (hIphlp != NULL)
|
|
{
|
|
FreeLibrary(hIphlp);
|
|
}
|
|
if (hSock != NULL)
|
|
{
|
|
FreeLibrary(hSock);
|
|
}
|
|
|
|
LOG_Internet(_T("%s"), bRet ? _T("Connected") : _T("Not connected"));
|
|
return (bRet);
|
|
}
|