895 lines
22 KiB
C++
895 lines
22 KiB
C++
// testIsConnected.cpp : Defines the entry point for the console application.
|
|
//
|
|
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <stdio.h>
|
|
|
|
#include <wininet.h>
|
|
#include <iphlpapi.h>
|
|
#include <winsock2.h>
|
|
#include <malloc.h>
|
|
#include <MemUtil.h>
|
|
#include <shlwapi.h>
|
|
#include <sensapi.h>
|
|
|
|
#include <URLLogging.h>
|
|
//#include "testSens.h"
|
|
|
|
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
|
|
|
#define INTERNET_RAS_INSTALLED 0x10
|
|
#define INTERNET_CONNECTION_OFFLINE 0x20
|
|
#define INTERNET_CONNECTION_CONFIGURED 0x40
|
|
|
|
//
|
|
// from winsock.dll (version 1.1 and up)
|
|
//
|
|
//typedef BOOL (WINAPI * INETCONNECTSTATE)(LPDWORD, DWORD);
|
|
//typedef BOOL (WINAPI * INETQUERYOPTION)(HINTERNET, DWORD, LPVOID, LPDWORD);
|
|
typedef int FAR (WINAPI * WSASTARTUP)(WORD, LPWSADATA);
|
|
typedef int FAR (WINAPI * WSACLEANUP)(void);
|
|
typedef int FAR (WINAPI * WSAGETLASTERROR)(void);
|
|
typedef struct hostent FAR * (WINAPI * GETHOSTBYNAME)(const char FAR *);
|
|
typedef ULONG (WINAPI * INET_ADDR)(const CHAR FAR *);
|
|
typedef char FAR * (WINAPI * INET_NTOA)(struct in_addr);
|
|
|
|
//
|
|
// from iphlpapi.dll
|
|
//
|
|
typedef DWORD FAR (WINAPI * GETBESTINTERFACE)(IPAddr, DWORD *);
|
|
typedef DWORD FAR (WINAPI * GETINTERFACEINFO)(PIP_INTERFACE_INFO, PULONG);
|
|
typedef DWORD FAR (WINAPI * GETIPFORWARDTABLE)(PMIB_IPFORWARDTABLE, PULONG, BOOL);
|
|
typedef DWORD FAR (WINAPI * GETBESTROUTE)(IPAddr, IPAddr, PMIB_IPFORWARDROW);
|
|
|
|
//
|
|
// from sensapi.dll
|
|
//
|
|
typedef BOOL (WINAPI * ISNETWORKALIVE)(LPDWORD);
|
|
typedef BOOL (WINAPI * ISDESTINATIONREACHABLEA)(LPCSTR, LPQOCINFO);
|
|
|
|
CHAR szWU_PING_URL[] = "207.46.130.150"; // ip addr for windowsupdate.microsoft.com
|
|
//const TCHAR szWU_BASE_URL[] = _T("http://windowsupdate.microsoft.com");
|
|
|
|
BOOL g_fVerbose = FALSE;
|
|
|
|
HMODULE g_hIphlp = NULL;
|
|
HMODULE g_hSock = NULL;
|
|
HMODULE g_hSens = NULL;
|
|
|
|
// from winsock.dll (version 1.0 and up)
|
|
WSASTARTUP g_pfnWSAStartup = NULL;
|
|
WSACLEANUP g_pfnWSACleanup = NULL;
|
|
WSAGETLASTERROR g_pfnWSAGetLastError = NULL;
|
|
GETHOSTBYNAME g_pfn_gethostbyname = NULL;
|
|
INET_NTOA g_pfn_inet_ntoa = NULL;
|
|
INET_ADDR g_pfn_inet_addr = NULL;
|
|
|
|
// from iphlpapi.dll
|
|
GETINTERFACEINFO g_pfnGetInterfaceInfo = NULL;
|
|
GETIPFORWARDTABLE g_pfnGetIpForwardTable = NULL;
|
|
GETBESTINTERFACE g_pfnGetBestInterface = NULL;
|
|
GETBESTROUTE g_pfnGetBestRoute = NULL;
|
|
|
|
// from sensapi.dll
|
|
ISNETWORKALIVE g_pfnIsNetworkAlive = NULL;
|
|
ISDESTINATIONREACHABLEA g_pfnIsDestinationReachableA = NULL;
|
|
|
|
void printBestRoute(MIB_IPFORWARDROW & bestRoute)
|
|
{
|
|
CHAR szForwardDest[15 + 1];
|
|
CHAR szForwardMask[15 + 1];
|
|
CHAR szForwardNextHop[15 + 1];
|
|
struct in_addr in;
|
|
|
|
in.s_addr = bestRoute.dwForwardDest;
|
|
lstrcpyA(szForwardDest, g_pfn_inet_ntoa(in));
|
|
in.s_addr = bestRoute.dwForwardMask;
|
|
lstrcpyA(szForwardMask, g_pfn_inet_ntoa(in));
|
|
in.s_addr = bestRoute.dwForwardNextHop;
|
|
lstrcpyA(szForwardNextHop, g_pfn_inet_ntoa(in));
|
|
printf("\tdest\t= %s\n\tmask\t= %s\n\tgateway\t= %s\n\tifindex\t= %d\n\ttype\t= %d\n\tproto\t= %d\n\tage\t= %d\n",
|
|
szForwardDest,
|
|
szForwardMask,
|
|
szForwardNextHop,
|
|
bestRoute.dwForwardIfIndex,
|
|
bestRoute.dwForwardType,
|
|
bestRoute.dwForwardProto,
|
|
bestRoute.dwForwardAge);
|
|
}
|
|
|
|
|
|
BOOL MyIsConnected(WORD wVersion, LPCTSTR ptszUrl, BOOL fLive)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwErr;
|
|
|
|
LPTSTR ptszHostName = NULL;
|
|
/*
|
|
if (0x3 == wVersion)
|
|
{
|
|
printf("Sleeping 20 seconds...\n");
|
|
Sleep(20000);
|
|
return g_fConnected;
|
|
}
|
|
*/
|
|
if (0x1 == wVersion)
|
|
{
|
|
// Test latest behavior
|
|
return IsConnected(ptszUrl, fLive);
|
|
}
|
|
|
|
DWORD dwConnMethod = 0;
|
|
|
|
if (0x200 == wVersion || 0x202 == wVersion)
|
|
{
|
|
if (bRet = InternetGetConnectedState(&dwConnMethod, 0))
|
|
{
|
|
// 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)
|
|
{
|
|
DWORD dwState = 0;
|
|
DWORD dwSize = sizeof(DWORD);
|
|
|
|
if (!InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
|
|
{
|
|
printf("IsConnected(): InternetQueryOptionA failed with error %d\n", GetLastError());
|
|
}
|
|
|
|
if (dwState & (INTERNET_STATE_DISCONNECTED_BY_USER | INTERNET_STATE_DISCONNECTED))
|
|
{
|
|
bRet = FALSE;
|
|
goto lFinish;
|
|
}
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwFlags;
|
|
|
|
bRet = g_pfnIsNetworkAlive(&dwFlags);
|
|
}
|
|
|
|
//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 (((0x0200 == wVersion || 0x0202 == wVersion) &&
|
|
(!bRet || (dwConnMethod & INTERNET_CONNECTION_LAN))) || //LAN card present
|
|
//bug 299338
|
|
(0x0 == wVersion && bRet))
|
|
{
|
|
IPAddr dest = INADDR_NONE;
|
|
|
|
if (0x0200 == wVersion)
|
|
{
|
|
if (INADDR_NONE == (dest = g_pfn_inet_addr(szWU_PING_URL)))
|
|
{
|
|
printf("inet_addr(\"%s\") failed\n", szWU_PING_URL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (NULL != ptszUrl && _T('\0') != ptszUrl[0])
|
|
{
|
|
const TCHAR c_tszHttpScheme[] = _T("http://");
|
|
|
|
if (0 == _tcsncmp(ptszUrl, c_tszHttpScheme, ARRAYSIZE(c_tszHttpScheme) - 1))
|
|
{
|
|
ptszUrl += ARRAYSIZE(c_tszHttpScheme) - 1; // skip http://
|
|
}
|
|
LPCTSTR ptszDelim = _tcschr(ptszUrl, _T('/'));
|
|
if (NULL == ptszDelim)
|
|
{
|
|
ptszDelim = ptszUrl + lstrlen(ptszUrl);
|
|
}
|
|
|
|
if (NULL != (ptszHostName = (LPTSTR) malloc(sizeof(TCHAR) * (ptszDelim - ptszUrl + 1))))
|
|
{
|
|
lstrcpyn(ptszHostName, ptszUrl, ((int) (ptszDelim - ptszUrl)) + 1);
|
|
|
|
USES_IU_CONVERSION;
|
|
|
|
LPSTR pszHostName = T2A(ptszHostName);
|
|
|
|
if (0x0 != wVersion || INADDR_NONE == (dest = g_pfn_inet_addr(pszHostName)))
|
|
{
|
|
if (g_fVerbose)
|
|
{
|
|
printf("Resolving domain name for %s...\n", pszHostName);
|
|
}
|
|
|
|
int iErr = 0;
|
|
|
|
if (0x0 == wVersion)
|
|
{
|
|
WSADATA wsaData;
|
|
|
|
if (0 == (iErr = g_pfnWSAStartup(MAKEWORD(1, 1), &wsaData)))
|
|
{
|
|
if (g_fVerbose)
|
|
{
|
|
printf("WSAStartup() succeeded, wVersion = %d.%d, wHighVersion = %d.%d\n",
|
|
LOBYTE(wsaData.wVersion),
|
|
HIBYTE(wsaData.wVersion),
|
|
LOBYTE(wsaData.wHighVersion),
|
|
HIBYTE(wsaData.wHighVersion));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Tell the user that we could not find a usable */
|
|
/* WinSock DLL. */
|
|
printf("IsConnected(): WSAStartup() failed with error %d\n", iErr);
|
|
}
|
|
}
|
|
|
|
if (0 == iErr)
|
|
{
|
|
DWORD dwTimeEllapsed = GetTickCount();
|
|
|
|
struct hostent *ptHost = g_pfn_gethostbyname(pszHostName);
|
|
|
|
dwTimeEllapsed = GetTickCount() - dwTimeEllapsed;
|
|
|
|
if (NULL == ptHost)
|
|
{
|
|
dwErr = g_pfnWSAGetLastError();
|
|
printf("IsConnected(): gethostbyname(\"%s\") failed with error WSABASEERR+%d (%d), took %d msecs\n", pszHostName, dwErr - WSABASEERR, dwErr, dwTimeEllapsed);
|
|
|
|
if (0x0 == wVersion)
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
else if (AF_INET == ptHost->h_addrtype &&
|
|
sizeof(IPAddr) == ptHost->h_length &&
|
|
NULL != ptHost->h_addr_list &&
|
|
NULL != *ptHost->h_addr_list)
|
|
{
|
|
dest = *((IPAddr FAR *) ptHost->h_addr);
|
|
|
|
if (g_fVerbose)
|
|
{
|
|
printf("Host name %s resolved to be ", pszHostName);
|
|
|
|
for (IPAddr FAR * FAR * ppAddresses = (IPAddr FAR * FAR *) ptHost->h_addr_list;
|
|
*ppAddresses != NULL;
|
|
ppAddresses++)
|
|
{
|
|
struct in_addr in;
|
|
|
|
in.s_addr = **ppAddresses;
|
|
printf("%s, ", g_pfn_inet_ntoa(in));
|
|
}
|
|
printf("took %d msecs\n", dwTimeEllapsed);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("IsConnected(): gethostbyname(\"%s\") returns invalid host entry\n", pszHostName);
|
|
}
|
|
|
|
if (0x0 == wVersion)
|
|
{
|
|
if (iErr = g_pfnWSACleanup())
|
|
{
|
|
printf("IsConnected(): WSACleanup() failed with error %d\n", iErr);
|
|
}
|
|
else if (g_fVerbose)
|
|
{
|
|
printf("WSACleanup() succeeded\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("IsConnected(): call to malloc() failed\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (INADDR_NONE != dest)
|
|
{
|
|
DWORD dwIndex;
|
|
struct in_addr in;
|
|
|
|
in.s_addr = dest;
|
|
|
|
if (bRet = (NO_ERROR == (dwErr = g_pfnGetBestInterface(dest, &dwIndex))))
|
|
{
|
|
if (g_fVerbose)
|
|
{
|
|
printf("GetBestInterface(%s) succeeded, dwIndex = %d\n", g_pfn_inet_ntoa(in), dwIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("IsConnected(): GetBestInterface(%s) failed w/ error %d\n", g_pfn_inet_ntoa(in), dwErr);
|
|
}
|
|
}
|
|
}
|
|
|
|
lFinish:
|
|
if (NULL != ptszHostName)
|
|
{
|
|
free(ptszHostName);
|
|
}
|
|
|
|
printf(bRet ? "Connected\n" : "Not connected\n");
|
|
return (bRet);
|
|
}
|
|
|
|
|
|
void runApiTests(LPSTR pszURL)
|
|
{
|
|
if (!g_fVerbose)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DWORD dwFlags;
|
|
|
|
if (g_pfnIsNetworkAlive(&dwFlags))
|
|
{
|
|
printf("IsNetworkAlive(&dwFlags) returns TRUE, dwFlags = %#lx\n", dwFlags);
|
|
if (dwFlags & NETWORK_ALIVE_LAN)
|
|
{
|
|
printf("\t%s\n", "NETWORK_ALIVE_LAN");
|
|
}
|
|
if (dwFlags & NETWORK_ALIVE_WAN)
|
|
{
|
|
printf("\t%s\n", "NETWORK_ALIVE_WAN");
|
|
}
|
|
if (dwFlags & NETWORK_ALIVE_AOL)
|
|
{
|
|
printf("\t%s\n", "NETWORK_ALIVE_AOL");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("runApiTests(): IsNetworkAlive(&dwFlags) failed with error %d\n", GetLastError());
|
|
}
|
|
|
|
printf("Checking destination reachability for %s...\n", pszURL);
|
|
if (g_pfnIsDestinationReachableA(pszURL, NULL))
|
|
{
|
|
printf("IsDestinationReachableA(\"%s\", NULL) returns TRUE\n", pszURL);
|
|
}
|
|
else
|
|
{
|
|
printf("runApiTests(): IsDestinationReachableA(\"%s\", NULL) failed with error %d\n", pszURL, GetLastError());
|
|
}
|
|
printf("\n");
|
|
|
|
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
|
|
PIP_INTERFACE_INFO pIfTable = NULL;
|
|
DWORD dwOutBufLen = 0;
|
|
DWORD dwErr;
|
|
|
|
switch(dwErr = g_pfnGetInterfaceInfo(pIfTable, &dwOutBufLen))
|
|
{
|
|
case NO_ERROR:
|
|
printf("runApiTests(): GetInterfaceInfo() returns NO_ERROR with no buffer?\n");
|
|
break;
|
|
|
|
case ERROR_INSUFFICIENT_BUFFER:
|
|
if (NULL == (pIfTable = (PIP_INTERFACE_INFO) malloc(dwOutBufLen)))
|
|
{
|
|
printf("IsConnected(): call to malloc() failed\n");
|
|
}
|
|
else
|
|
{
|
|
if (NO_ERROR != (dwErr = g_pfnGetInterfaceInfo(pIfTable, &dwOutBufLen)))
|
|
{
|
|
printf("runApiTests(): GetInterfaceInfo() failed with error %d\n", dwErr);
|
|
}
|
|
else
|
|
{
|
|
if (0 != pIfTable->NumAdapters)
|
|
{
|
|
for (int i=0; i<pIfTable->NumAdapters; i++)
|
|
{
|
|
printf("Network interface #%d = %ls\n", pIfTable->Adapter[i].Index, pIfTable->Adapter[i].Name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("There is no network interface on this machine.\n");
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
free(pIfTable);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
printf("runApiTests(): GetInterfaceInfo() failed with error %d\n", dwErr);
|
|
break;
|
|
}
|
|
|
|
// Find out how big our buffer needs to be
|
|
DWORD dwSize = 0;
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER == (dwErr = g_pfnGetIpForwardTable(pIpForwardTable, &dwSize, TRUE)))
|
|
{
|
|
// Allocate the memory for the table
|
|
if (NULL != (pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc(dwSize)))
|
|
{
|
|
// Now get the table
|
|
dwErr = g_pfnGetIpForwardTable(pIpForwardTable, &dwSize, TRUE);
|
|
}
|
|
else
|
|
{
|
|
printf("runApiTests(): call to malloc() failed\n");
|
|
}
|
|
}
|
|
|
|
if (NO_ERROR == dwErr)
|
|
{
|
|
if (0 != pIpForwardTable->dwNumEntries)
|
|
{
|
|
printf("%-15.15s\t%-15.15s\t%-15.15s\t%s\t%s\t%s\t%s\n",
|
|
"Destination",
|
|
"Network Mask",
|
|
"Gateway",
|
|
"IfIndex",
|
|
"Type",
|
|
"Proto",
|
|
"Age");
|
|
printf("===============================================================================\n");
|
|
for (DWORD i=0; i < pIpForwardTable->dwNumEntries; i++)
|
|
{
|
|
PMIB_IPFORWARDROW pRow = &(pIpForwardTable->table[i]);
|
|
|
|
CHAR szForwardDest[15 + 1];
|
|
CHAR szForwardMask[15 + 1];
|
|
CHAR szForwardNextHop[15 + 1];
|
|
struct in_addr in;
|
|
|
|
in.s_addr = pRow->dwForwardDest;
|
|
lstrcpyA(szForwardDest, g_pfn_inet_ntoa(in));
|
|
in.s_addr = pRow->dwForwardMask;
|
|
lstrcpyA(szForwardMask, g_pfn_inet_ntoa(in));
|
|
in.s_addr = pRow->dwForwardNextHop;
|
|
lstrcpyA(szForwardNextHop, g_pfn_inet_ntoa(in));
|
|
printf("%15.15s\t%15.15s\t%15.15s\t%d\t%d\t%d\t%d\n",
|
|
szForwardDest,
|
|
szForwardMask,
|
|
szForwardNextHop,
|
|
pRow->dwForwardIfIndex,
|
|
pRow->dwForwardType,
|
|
pRow->dwForwardProto,
|
|
pRow->dwForwardAge);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("There is no entry in the routing table.\n");
|
|
}
|
|
printf("\n");
|
|
}
|
|
else
|
|
{
|
|
printf("runApiTests(): GetIpForwardTable() failed w/ error %d\n", dwErr);
|
|
}
|
|
|
|
DWORD dwConnMethod = 0;
|
|
|
|
if (InternetGetConnectedState(&dwConnMethod, 0))
|
|
{
|
|
printf("InternetGetConnectedState(&dwConnMethod) returns TRUE, dwConnMethod = %#lx\n", dwConnMethod);
|
|
}
|
|
else
|
|
{
|
|
printf("InternetGetConnectedState(&dwConnMethod) returns FALSE\n");
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM)
|
|
{
|
|
printf("\t%s\n", "INTERNET_CONNECTION_MODEM");
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_LAN )
|
|
{
|
|
printf("\t%s\n", "INTERNET_CONNECTION_LAN");
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_PROXY )
|
|
{
|
|
printf("\t%s\n", "INTERNET_CONNECTION_PROXY");
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY )
|
|
{
|
|
printf("\t%s\n", "INTERNET_CONNECTION_MODEM_BUSY");
|
|
}
|
|
if (dwConnMethod & INTERNET_RAS_INSTALLED )
|
|
{
|
|
printf("\t%s\n", "INTERNET_RAS_INSTALLED");
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_OFFLINE )
|
|
{
|
|
printf("\t%s\n", "INTERNET_CONNECTION_OFFLINE");
|
|
}
|
|
if (dwConnMethod & INTERNET_CONNECTION_CONFIGURED )
|
|
{
|
|
printf("\t%s\n", "INTERNET_CONNECTION_CONFIGURED");
|
|
}
|
|
printf("\n");
|
|
|
|
DWORD dwState = 0;
|
|
|
|
dwSize = sizeof(DWORD);
|
|
if (InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
|
|
{
|
|
printf("InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize) returns TRUE, dwState = %#lx\n", dwState);
|
|
if (dwState & INTERNET_STATE_CONNECTED)
|
|
{
|
|
printf("\t%s\n", "INTERNET_STATE_CONNECTED - connected state (mutually exclusive with disconnected)");
|
|
}
|
|
if (dwState & INTERNET_STATE_DISCONNECTED)
|
|
{
|
|
printf("\t%s\n", "INTERNET_STATE_DISCONNECTED - disconnected from network");
|
|
}
|
|
if (dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
|
|
{
|
|
printf("\t%s\n", "INTERNET_STATE_DISCONNECTED_BY_USER - disconnected by user request");
|
|
}
|
|
if (dwState & INTERNET_STATE_IDLE)
|
|
{
|
|
printf("\t%s\n", "INTERNET_STATE_IDLE - no network requests being made (by Wininet)");
|
|
}
|
|
if (dwState & INTERNET_STATE_BUSY)
|
|
{
|
|
printf("\t%s\n", "INTERNET_STATE_BUSY - network requests being made (by Wininet)");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("IsConnected(): InternetQueryOptionA failed with error %d\n", GetLastError());
|
|
}
|
|
printf("\n");
|
|
|
|
if (NULL != pIpForwardTable)
|
|
{
|
|
free(pIpForwardTable);
|
|
}
|
|
}
|
|
|
|
|
|
void runTest(WORD wVersion, LPSTR pszURL, BOOL fLive)
|
|
{
|
|
CHAR szVersion[50];
|
|
HRESULT hr;
|
|
BOOL fCoInit = FALSE;
|
|
|
|
switch (wVersion)
|
|
{
|
|
case 0x0200:
|
|
case 0x0202:
|
|
sprintf(szVersion, "from AU %d.%d", HIBYTE(wVersion), LOBYTE(wVersion));
|
|
break;
|
|
case 0x0:
|
|
sprintf(szVersion, "(bug fix candidate)");
|
|
break;
|
|
case 0x1:
|
|
sprintf(szVersion, "(latest code)");
|
|
break;
|
|
/*
|
|
case 0x3:
|
|
sprintf(szVersion, "(SENS test)");
|
|
if (fCoInit = FAILED(hr = CoInitialize(NULL)))
|
|
{
|
|
printf("runTest(): CoInitialize(NULL) failed w/ error %#lx\n", hr);
|
|
goto CleanUp;
|
|
}
|
|
if (g_fVerbose)
|
|
{
|
|
printf("runTest(): CoInitialize(NULL) succeeded\n");
|
|
}
|
|
if (FAILED(hr = ActivateSensNetworkNotification()))
|
|
{
|
|
printf("runTest(): ActivateSensNetworkNotification() failed w/ error %#lx\n", hr);
|
|
goto CleanUp;
|
|
}
|
|
if (g_fVerbose)
|
|
{
|
|
printf("runTest(): ActivateSensNetworkNotification() succeeded\n");
|
|
}
|
|
break;
|
|
*/
|
|
default:
|
|
printf("runTest(): unknown wVersion\n");
|
|
goto CleanUp;
|
|
}
|
|
|
|
printf("Testing connection detection/server reachability algorithm %s...\n", szVersion);
|
|
|
|
{
|
|
USES_IU_CONVERSION;
|
|
|
|
LPTSTR ptszURL = A2T(0x0200 == wVersion ? szWU_PING_URL : pszURL);
|
|
|
|
_tprintf(_T("IsConnected(\"%s\") returns %s\n"), ptszURL, MyIsConnected(wVersion, ptszURL, fLive) ? _T("TRUE") : _T("FALSE"));
|
|
}
|
|
|
|
/*
|
|
if (0x3 == wVersion)
|
|
{
|
|
if (FAILED(hr = DeactivateSensNetworkNotification()))
|
|
{
|
|
printf("runTest(): DeactivateSensNetworkNotification() failed w/ error %#lx\n", hr);
|
|
}
|
|
else if (g_fVerbose)
|
|
{
|
|
printf("runTest(): DeactivateSensNetworkNotification() succeeded\n");
|
|
}
|
|
}
|
|
*/
|
|
|
|
CleanUp:
|
|
if (fCoInit)
|
|
{
|
|
CoUninitialize();
|
|
}
|
|
}
|
|
|
|
int __cdecl main(int argc, char* argv[])
|
|
{
|
|
char c_szMethodToken[] = "/method:";
|
|
char c_szMToken[] = "/m:";
|
|
char c_szVerboseToken[] = "/verbose";
|
|
char c_szVToken[] = "/v";
|
|
char c_szCorpToken[] = "/corpwu";
|
|
char c_szLiveToken[] = "/live";
|
|
int fLive = -1;
|
|
|
|
WORD wVersion = 0xffff; // default == unknown;
|
|
LPSTR pszURL = NULL;
|
|
|
|
int index = 0;
|
|
|
|
while (index < argc - 1)
|
|
{
|
|
LPSTR psz = NULL;
|
|
|
|
index++;
|
|
|
|
if (0 == StrCmpNIA(argv[index], c_szMethodToken, ARRAYSIZE(c_szMethodToken) - 1))
|
|
{
|
|
psz = argv[index] + ARRAYSIZE(c_szMethodToken) - 1;
|
|
}
|
|
else if (0 == StrCmpNIA(argv[index], c_szMToken, ARRAYSIZE(c_szMToken) - 1))
|
|
{
|
|
psz = argv[index] + ARRAYSIZE(c_szMToken) - 1;
|
|
}
|
|
|
|
if (NULL != psz)
|
|
{
|
|
if (0xffff != wVersion)
|
|
{
|
|
// param specified twice
|
|
goto Usage;
|
|
}
|
|
|
|
char c_szOptionCode[] = "code";
|
|
char c_szOptionFix[] = "fix";
|
|
char c_szOptionAll[] = "all";
|
|
char c_szOptionSens[] = "sens";
|
|
int iMajorVersion = 0, iMinorVersion = 0;
|
|
|
|
if (2 != sscanf(psz, "%d.%d", &iMajorVersion, &iMinorVersion))
|
|
{
|
|
if (0 == StrCmpNIA(psz, c_szOptionCode, ARRAYSIZE(c_szOptionCode)))
|
|
{
|
|
iMajorVersion = 0;
|
|
iMinorVersion = 1;
|
|
}
|
|
else if (0 == StrCmpNIA(psz, c_szOptionFix, ARRAYSIZE(c_szOptionFix)))
|
|
{
|
|
iMajorVersion = iMinorVersion = 0;
|
|
}
|
|
else if (0 == StrCmpNIA(psz, c_szOptionAll, ARRAYSIZE(c_szOptionAll)))
|
|
{
|
|
iMajorVersion = 0xff;
|
|
iMinorVersion = 0xfe;
|
|
}
|
|
/*
|
|
else if (0 == StrCmpNIA(psz, c_szOptionSens, ARRAYSIZE(c_szOptionSens)))
|
|
{
|
|
iMajorVersion = 0;
|
|
iMinorVersion = 3;
|
|
}
|
|
*/
|
|
else
|
|
{
|
|
goto Usage;
|
|
}
|
|
}
|
|
wVersion = MAKEWORD(iMinorVersion, iMajorVersion);
|
|
continue;
|
|
}
|
|
|
|
if (0 == StrCmpNIA(argv[index], c_szVerboseToken, ARRAYSIZE(c_szVerboseToken)) ||
|
|
0 == StrCmpNIA(argv[index], c_szVToken, ARRAYSIZE(c_szVToken)))
|
|
{
|
|
if (g_fVerbose)
|
|
{
|
|
// param specified twice
|
|
goto Usage;
|
|
}
|
|
|
|
g_fVerbose = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (0 == StrCmpNIA(argv[index], c_szLiveToken, ARRAYSIZE(c_szLiveToken)))
|
|
{
|
|
if (-1 != fLive)
|
|
{
|
|
// param specified twice or conflicting param
|
|
goto Usage;
|
|
}
|
|
|
|
fLive = 1;
|
|
continue;
|
|
}
|
|
|
|
if (0 == StrCmpNIA(argv[index], c_szCorpToken, ARRAYSIZE(c_szCorpToken)))
|
|
{
|
|
if (-1 != fLive)
|
|
{
|
|
// param specified twice or conflicting param
|
|
goto Usage;
|
|
}
|
|
|
|
fLive = 0;
|
|
continue;
|
|
}
|
|
|
|
if ('/' != *argv[index])
|
|
{
|
|
if (NULL != pszURL)
|
|
{
|
|
// param specified twice
|
|
goto Usage;
|
|
}
|
|
|
|
pszURL = argv[index];
|
|
continue;
|
|
}
|
|
|
|
// unknown param
|
|
goto Usage;
|
|
}
|
|
|
|
switch (wVersion)
|
|
{
|
|
case 0x0200:
|
|
if (NULL != pszURL)
|
|
{
|
|
goto Usage;
|
|
}
|
|
break;
|
|
case 0x0202:
|
|
case 0x0:
|
|
case 0x1:
|
|
// case 0x3:
|
|
case 0xfffe:
|
|
if (NULL == pszURL)
|
|
{
|
|
goto Usage;
|
|
}
|
|
break;
|
|
default:
|
|
goto Usage;
|
|
}
|
|
|
|
if (-1 == fLive)
|
|
{
|
|
fLive = 1;
|
|
}
|
|
|
|
if ((NULL == g_hIphlp && NULL == (g_hIphlp = LoadLibrary(TEXT("iphlpapi.dll")))) ||
|
|
NULL == (g_pfnGetBestInterface = (GETBESTINTERFACE)::GetProcAddress(g_hIphlp, "GetBestInterface")) ||
|
|
NULL == (g_pfnGetBestRoute = (GETBESTROUTE)::GetProcAddress(g_hIphlp, "GetBestRoute")) ||
|
|
NULL == (g_pfnGetInterfaceInfo = (GETINTERFACEINFO)::GetProcAddress(g_hIphlp, "GetInterfaceInfo")) ||
|
|
NULL == (g_pfnGetIpForwardTable = (GETIPFORWARDTABLE)::GetProcAddress(g_hIphlp, "GetIpForwardTable")))
|
|
{
|
|
printf("Failed to load proc from iphlpapi.dll\n");
|
|
goto Done;
|
|
}
|
|
|
|
if ((NULL == g_hSock && NULL == (g_hSock = LoadLibrary(TEXT("ws2_32.dll")))) ||
|
|
NULL == (g_pfnWSAStartup = (WSASTARTUP)::GetProcAddress(g_hSock, "WSAStartup")) ||
|
|
NULL == (g_pfnWSACleanup = (WSACLEANUP)::GetProcAddress(g_hSock, "WSACleanup")) ||
|
|
NULL == (g_pfn_gethostbyname = (GETHOSTBYNAME)::GetProcAddress(g_hSock, "gethostbyname")) ||
|
|
NULL == (g_pfnWSAGetLastError = (WSAGETLASTERROR)::GetProcAddress(g_hSock, "WSAGetLastError")) ||
|
|
NULL == (g_pfn_inet_addr = (INET_ADDR)::GetProcAddress(g_hSock, "inet_addr")) ||
|
|
NULL == (g_pfn_inet_ntoa = (INET_NTOA)::GetProcAddress(g_hSock, "inet_ntoa")))
|
|
{
|
|
printf("Failed to load proc from ws2_32.dll\n");
|
|
goto Done;
|
|
}
|
|
|
|
if (NULL == (g_hSens = LoadLibrary(TEXT("sensapi.dll"))) ||
|
|
NULL == (g_pfnIsNetworkAlive = (ISNETWORKALIVE)::GetProcAddress(g_hSens, "IsNetworkAlive")) ||
|
|
NULL == (g_pfnIsDestinationReachableA = (ISDESTINATIONREACHABLEA)::GetProcAddress(g_hSens, "IsDestinationReachableA")))
|
|
{
|
|
printf("Failed to load proc from sensapi.dll\n");
|
|
goto Done;
|
|
}
|
|
|
|
if (0xfffe == wVersion)
|
|
{
|
|
WORD awVersions[] = {0x0200, 0x0202, 0x0, 0x1};
|
|
|
|
printf("*******************************************************************************\nRunning API tests...\n\n");
|
|
runApiTests(0x0200 == wVersion ? szWU_PING_URL : pszURL);
|
|
|
|
printf("*******************************************************************************\nRunning various connectivity tests...\n\n");
|
|
for (int i=0; i < ARRAYSIZE(awVersions); i++)
|
|
{
|
|
runTest(awVersions[i], pszURL, fLive);
|
|
printf("\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
runTest(wVersion, pszURL, fLive);
|
|
}
|
|
goto Done;
|
|
|
|
Usage:
|
|
printf("Windows Update V4 Network Connectivity/Server Reachability (IsConnected) Test\nCopyright (c) 2002. Microsoft Corporation. All rights reserved.\n\n");
|
|
printf("usage:\n\ttestIsConnected /m[ethod]:<method> [/v[erbose]] [/live | /corpwu] [<destination>]\n");
|
|
printf("where\n\t<method>\ttest method i.e. \"2.0\" for AU 2.0,\n");
|
|
printf("\t\t\t\t\t \"2.2\" for older AU 2.2,\n");
|
|
printf("\t\t\t\t\t \"fix\" for AU 2.2 w/ fix (mirrored),\n");
|
|
printf("\t\t\t\t\t \"code\" for actual AU 2.2 code w/ fix,\n");
|
|
printf("\t\t\t\t\t \"all\" to test all methods\n");
|
|
printf("\t/live\t\tspecifies destination points to the live WU server\n");
|
|
printf("\t\t\t(default; cannot be used together with /corpwu)\n");
|
|
printf("\t/corpwu\t\tspecifies destination points to a WUCE server\n");
|
|
printf("\t\t\t(cannot be used together with /live)\n");
|
|
printf("\t<destination>\thost name or full URL to check for server reachability\n\t\t\te.g. \"windowsupdate.microsoft.com\",\n\t\t\t \"v4autest\" or \"http://www.any.place/any.thing\"\n\t\t\t(not used in 2.0 mode)\n");
|
|
|
|
Done:
|
|
if (g_hIphlp != NULL)
|
|
{
|
|
FreeLibrary(g_hIphlp);
|
|
}
|
|
if (g_hSock != NULL)
|
|
{
|
|
FreeLibrary(g_hSock);
|
|
}
|
|
if (g_hSens != NULL)
|
|
{
|
|
FreeLibrary(g_hSens);
|
|
}
|
|
return 0;
|
|
}
|