Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

894 lines
22 KiB

  1. // testIsConnected.cpp : Defines the entry point for the console application.
  2. //
  3. #include <windows.h>
  4. #include <tchar.h>
  5. #include <stdio.h>
  6. #include <wininet.h>
  7. #include <iphlpapi.h>
  8. #include <winsock2.h>
  9. #include <malloc.h>
  10. #include <MemUtil.h>
  11. #include <shlwapi.h>
  12. #include <sensapi.h>
  13. #include <URLLogging.h>
  14. //#include "testSens.h"
  15. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  16. #define INTERNET_RAS_INSTALLED 0x10
  17. #define INTERNET_CONNECTION_OFFLINE 0x20
  18. #define INTERNET_CONNECTION_CONFIGURED 0x40
  19. //
  20. // from winsock.dll (version 1.1 and up)
  21. //
  22. //typedef BOOL (WINAPI * INETCONNECTSTATE)(LPDWORD, DWORD);
  23. //typedef BOOL (WINAPI * INETQUERYOPTION)(HINTERNET, DWORD, LPVOID, LPDWORD);
  24. typedef int FAR (WINAPI * WSASTARTUP)(WORD, LPWSADATA);
  25. typedef int FAR (WINAPI * WSACLEANUP)(void);
  26. typedef int FAR (WINAPI * WSAGETLASTERROR)(void);
  27. typedef struct hostent FAR * (WINAPI * GETHOSTBYNAME)(const char FAR *);
  28. typedef ULONG (WINAPI * INET_ADDR)(const CHAR FAR *);
  29. typedef char FAR * (WINAPI * INET_NTOA)(struct in_addr);
  30. //
  31. // from iphlpapi.dll
  32. //
  33. typedef DWORD FAR (WINAPI * GETBESTINTERFACE)(IPAddr, DWORD *);
  34. typedef DWORD FAR (WINAPI * GETINTERFACEINFO)(PIP_INTERFACE_INFO, PULONG);
  35. typedef DWORD FAR (WINAPI * GETIPFORWARDTABLE)(PMIB_IPFORWARDTABLE, PULONG, BOOL);
  36. typedef DWORD FAR (WINAPI * GETBESTROUTE)(IPAddr, IPAddr, PMIB_IPFORWARDROW);
  37. //
  38. // from sensapi.dll
  39. //
  40. typedef BOOL (WINAPI * ISNETWORKALIVE)(LPDWORD);
  41. typedef BOOL (WINAPI * ISDESTINATIONREACHABLEA)(LPCSTR, LPQOCINFO);
  42. CHAR szWU_PING_URL[] = "207.46.130.150"; // ip addr for windowsupdate.microsoft.com
  43. //const TCHAR szWU_BASE_URL[] = _T("http://windowsupdate.microsoft.com");
  44. BOOL g_fVerbose = FALSE;
  45. HMODULE g_hIphlp = NULL;
  46. HMODULE g_hSock = NULL;
  47. HMODULE g_hSens = NULL;
  48. // from winsock.dll (version 1.0 and up)
  49. WSASTARTUP g_pfnWSAStartup = NULL;
  50. WSACLEANUP g_pfnWSACleanup = NULL;
  51. WSAGETLASTERROR g_pfnWSAGetLastError = NULL;
  52. GETHOSTBYNAME g_pfn_gethostbyname = NULL;
  53. INET_NTOA g_pfn_inet_ntoa = NULL;
  54. INET_ADDR g_pfn_inet_addr = NULL;
  55. // from iphlpapi.dll
  56. GETINTERFACEINFO g_pfnGetInterfaceInfo = NULL;
  57. GETIPFORWARDTABLE g_pfnGetIpForwardTable = NULL;
  58. GETBESTINTERFACE g_pfnGetBestInterface = NULL;
  59. GETBESTROUTE g_pfnGetBestRoute = NULL;
  60. // from sensapi.dll
  61. ISNETWORKALIVE g_pfnIsNetworkAlive = NULL;
  62. ISDESTINATIONREACHABLEA g_pfnIsDestinationReachableA = NULL;
  63. void printBestRoute(MIB_IPFORWARDROW & bestRoute)
  64. {
  65. CHAR szForwardDest[15 + 1];
  66. CHAR szForwardMask[15 + 1];
  67. CHAR szForwardNextHop[15 + 1];
  68. struct in_addr in;
  69. in.s_addr = bestRoute.dwForwardDest;
  70. lstrcpyA(szForwardDest, g_pfn_inet_ntoa(in));
  71. in.s_addr = bestRoute.dwForwardMask;
  72. lstrcpyA(szForwardMask, g_pfn_inet_ntoa(in));
  73. in.s_addr = bestRoute.dwForwardNextHop;
  74. lstrcpyA(szForwardNextHop, g_pfn_inet_ntoa(in));
  75. 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",
  76. szForwardDest,
  77. szForwardMask,
  78. szForwardNextHop,
  79. bestRoute.dwForwardIfIndex,
  80. bestRoute.dwForwardType,
  81. bestRoute.dwForwardProto,
  82. bestRoute.dwForwardAge);
  83. }
  84. BOOL MyIsConnected(WORD wVersion, LPCTSTR ptszUrl, BOOL fLive)
  85. {
  86. BOOL bRet = FALSE;
  87. DWORD dwErr;
  88. LPTSTR ptszHostName = NULL;
  89. /*
  90. if (0x3 == wVersion)
  91. {
  92. printf("Sleeping 20 seconds...\n");
  93. Sleep(20000);
  94. return g_fConnected;
  95. }
  96. */
  97. if (0x1 == wVersion)
  98. {
  99. // Test latest behavior
  100. return IsConnected(ptszUrl, fLive);
  101. }
  102. DWORD dwConnMethod = 0;
  103. if (0x200 == wVersion || 0x202 == wVersion)
  104. {
  105. if (bRet = InternetGetConnectedState(&dwConnMethod, 0))
  106. {
  107. // modem is dialing
  108. if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY)
  109. {
  110. bRet = FALSE;
  111. goto lFinish;
  112. }
  113. // check if there is a proxy but currently user is offline
  114. if (dwConnMethod & INTERNET_CONNECTION_PROXY)
  115. {
  116. DWORD dwState = 0;
  117. DWORD dwSize = sizeof(DWORD);
  118. if (!InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
  119. {
  120. printf("IsConnected(): InternetQueryOptionA failed with error %d\n", GetLastError());
  121. }
  122. if (dwState & (INTERNET_STATE_DISCONNECTED_BY_USER | INTERNET_STATE_DISCONNECTED))
  123. {
  124. bRet = FALSE;
  125. goto lFinish;
  126. }
  127. }
  128. }
  129. else
  130. {
  131. //
  132. // further test the case that user didn't run icw but is using a modem connection
  133. //
  134. const DWORD dwModemConn = (INTERNET_CONNECTION_MODEM | INTERNET_CONNECTION_MODEM_BUSY);
  135. if ((dwConnMethod & dwModemConn) == dwModemConn)
  136. {
  137. bRet = TRUE;
  138. }
  139. }
  140. }
  141. else
  142. {
  143. DWORD dwFlags;
  144. bRet = g_pfnIsNetworkAlive(&dwFlags);
  145. }
  146. //one final check for connectivity by pinging microsoft.com
  147. //if (bRet)
  148. //{
  149. // bRet = CheckByPing(szURL);
  150. //}
  151. //bugfix for InternetGetConnectedState API - if LAN card is disabled it still returns LAN connection
  152. //use GetBestInterface and see if there is any error trying to reach an outside IP address
  153. //this may fix scenarios in homelan case where there is no actual connection to internet??
  154. if (((0x0200 == wVersion || 0x0202 == wVersion) &&
  155. (!bRet || (dwConnMethod & INTERNET_CONNECTION_LAN))) || //LAN card present
  156. //bug 299338
  157. (0x0 == wVersion && bRet))
  158. {
  159. IPAddr dest = INADDR_NONE;
  160. if (0x0200 == wVersion)
  161. {
  162. if (INADDR_NONE == (dest = g_pfn_inet_addr(szWU_PING_URL)))
  163. {
  164. printf("inet_addr(\"%s\") failed\n", szWU_PING_URL);
  165. }
  166. }
  167. else
  168. {
  169. if (NULL != ptszUrl && _T('\0') != ptszUrl[0])
  170. {
  171. const TCHAR c_tszHttpScheme[] = _T("http://");
  172. if (0 == _tcsncmp(ptszUrl, c_tszHttpScheme, ARRAYSIZE(c_tszHttpScheme) - 1))
  173. {
  174. ptszUrl += ARRAYSIZE(c_tszHttpScheme) - 1; // skip http://
  175. }
  176. LPCTSTR ptszDelim = _tcschr(ptszUrl, _T('/'));
  177. if (NULL == ptszDelim)
  178. {
  179. ptszDelim = ptszUrl + lstrlen(ptszUrl);
  180. }
  181. if (NULL != (ptszHostName = (LPTSTR) malloc(sizeof(TCHAR) * (ptszDelim - ptszUrl + 1))))
  182. {
  183. lstrcpyn(ptszHostName, ptszUrl, ((int) (ptszDelim - ptszUrl)) + 1);
  184. USES_IU_CONVERSION;
  185. LPSTR pszHostName = T2A(ptszHostName);
  186. if (0x0 != wVersion || INADDR_NONE == (dest = g_pfn_inet_addr(pszHostName)))
  187. {
  188. if (g_fVerbose)
  189. {
  190. printf("Resolving domain name for %s...\n", pszHostName);
  191. }
  192. int iErr = 0;
  193. if (0x0 == wVersion)
  194. {
  195. WSADATA wsaData;
  196. if (0 == (iErr = g_pfnWSAStartup(MAKEWORD(1, 1), &wsaData)))
  197. {
  198. if (g_fVerbose)
  199. {
  200. printf("WSAStartup() succeeded, wVersion = %d.%d, wHighVersion = %d.%d\n",
  201. LOBYTE(wsaData.wVersion),
  202. HIBYTE(wsaData.wVersion),
  203. LOBYTE(wsaData.wHighVersion),
  204. HIBYTE(wsaData.wHighVersion));
  205. }
  206. }
  207. else
  208. {
  209. /* Tell the user that we could not find a usable */
  210. /* WinSock DLL. */
  211. printf("IsConnected(): WSAStartup() failed with error %d\n", iErr);
  212. }
  213. }
  214. if (0 == iErr)
  215. {
  216. DWORD dwTimeEllapsed = GetTickCount();
  217. struct hostent *ptHost = g_pfn_gethostbyname(pszHostName);
  218. dwTimeEllapsed = GetTickCount() - dwTimeEllapsed;
  219. if (NULL == ptHost)
  220. {
  221. dwErr = g_pfnWSAGetLastError();
  222. printf("IsConnected(): gethostbyname(\"%s\") failed with error WSABASEERR+%d (%d), took %d msecs\n", pszHostName, dwErr - WSABASEERR, dwErr, dwTimeEllapsed);
  223. if (0x0 == wVersion)
  224. {
  225. bRet = FALSE;
  226. }
  227. }
  228. else if (AF_INET == ptHost->h_addrtype &&
  229. sizeof(IPAddr) == ptHost->h_length &&
  230. NULL != ptHost->h_addr_list &&
  231. NULL != *ptHost->h_addr_list)
  232. {
  233. dest = *((IPAddr FAR *) ptHost->h_addr);
  234. if (g_fVerbose)
  235. {
  236. printf("Host name %s resolved to be ", pszHostName);
  237. for (IPAddr FAR * FAR * ppAddresses = (IPAddr FAR * FAR *) ptHost->h_addr_list;
  238. *ppAddresses != NULL;
  239. ppAddresses++)
  240. {
  241. struct in_addr in;
  242. in.s_addr = **ppAddresses;
  243. printf("%s, ", g_pfn_inet_ntoa(in));
  244. }
  245. printf("took %d msecs\n", dwTimeEllapsed);
  246. }
  247. }
  248. else
  249. {
  250. printf("IsConnected(): gethostbyname(\"%s\") returns invalid host entry\n", pszHostName);
  251. }
  252. if (0x0 == wVersion)
  253. {
  254. if (iErr = g_pfnWSACleanup())
  255. {
  256. printf("IsConnected(): WSACleanup() failed with error %d\n", iErr);
  257. }
  258. else if (g_fVerbose)
  259. {
  260. printf("WSACleanup() succeeded\n");
  261. }
  262. }
  263. }
  264. }
  265. }
  266. else
  267. {
  268. printf("IsConnected(): call to malloc() failed\n");
  269. }
  270. }
  271. }
  272. if (INADDR_NONE != dest)
  273. {
  274. DWORD dwIndex;
  275. struct in_addr in;
  276. in.s_addr = dest;
  277. if (bRet = (NO_ERROR == (dwErr = g_pfnGetBestInterface(dest, &dwIndex))))
  278. {
  279. if (g_fVerbose)
  280. {
  281. printf("GetBestInterface(%s) succeeded, dwIndex = %d\n", g_pfn_inet_ntoa(in), dwIndex);
  282. }
  283. }
  284. else
  285. {
  286. printf("IsConnected(): GetBestInterface(%s) failed w/ error %d\n", g_pfn_inet_ntoa(in), dwErr);
  287. }
  288. }
  289. }
  290. lFinish:
  291. if (NULL != ptszHostName)
  292. {
  293. free(ptszHostName);
  294. }
  295. printf(bRet ? "Connected\n" : "Not connected\n");
  296. return (bRet);
  297. }
  298. void runApiTests(LPSTR pszURL)
  299. {
  300. if (!g_fVerbose)
  301. {
  302. return;
  303. }
  304. DWORD dwFlags;
  305. if (g_pfnIsNetworkAlive(&dwFlags))
  306. {
  307. printf("IsNetworkAlive(&dwFlags) returns TRUE, dwFlags = %#lx\n", dwFlags);
  308. if (dwFlags & NETWORK_ALIVE_LAN)
  309. {
  310. printf("\t%s\n", "NETWORK_ALIVE_LAN");
  311. }
  312. if (dwFlags & NETWORK_ALIVE_WAN)
  313. {
  314. printf("\t%s\n", "NETWORK_ALIVE_WAN");
  315. }
  316. if (dwFlags & NETWORK_ALIVE_AOL)
  317. {
  318. printf("\t%s\n", "NETWORK_ALIVE_AOL");
  319. }
  320. }
  321. else
  322. {
  323. printf("runApiTests(): IsNetworkAlive(&dwFlags) failed with error %d\n", GetLastError());
  324. }
  325. printf("Checking destination reachability for %s...\n", pszURL);
  326. if (g_pfnIsDestinationReachableA(pszURL, NULL))
  327. {
  328. printf("IsDestinationReachableA(\"%s\", NULL) returns TRUE\n", pszURL);
  329. }
  330. else
  331. {
  332. printf("runApiTests(): IsDestinationReachableA(\"%s\", NULL) failed with error %d\n", pszURL, GetLastError());
  333. }
  334. printf("\n");
  335. PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
  336. PIP_INTERFACE_INFO pIfTable = NULL;
  337. DWORD dwOutBufLen = 0;
  338. DWORD dwErr;
  339. switch(dwErr = g_pfnGetInterfaceInfo(pIfTable, &dwOutBufLen))
  340. {
  341. case NO_ERROR:
  342. printf("runApiTests(): GetInterfaceInfo() returns NO_ERROR with no buffer?\n");
  343. break;
  344. case ERROR_INSUFFICIENT_BUFFER:
  345. if (NULL == (pIfTable = (PIP_INTERFACE_INFO) malloc(dwOutBufLen)))
  346. {
  347. printf("IsConnected(): call to malloc() failed\n");
  348. }
  349. else
  350. {
  351. if (NO_ERROR != (dwErr = g_pfnGetInterfaceInfo(pIfTable, &dwOutBufLen)))
  352. {
  353. printf("runApiTests(): GetInterfaceInfo() failed with error %d\n", dwErr);
  354. }
  355. else
  356. {
  357. if (0 != pIfTable->NumAdapters)
  358. {
  359. for (int i=0; i<pIfTable->NumAdapters; i++)
  360. {
  361. printf("Network interface #%d = %ls\n", pIfTable->Adapter[i].Index, pIfTable->Adapter[i].Name);
  362. }
  363. }
  364. else
  365. {
  366. printf("There is no network interface on this machine.\n");
  367. }
  368. printf("\n");
  369. }
  370. free(pIfTable);
  371. }
  372. break;
  373. default:
  374. printf("runApiTests(): GetInterfaceInfo() failed with error %d\n", dwErr);
  375. break;
  376. }
  377. // Find out how big our buffer needs to be
  378. DWORD dwSize = 0;
  379. if (ERROR_INSUFFICIENT_BUFFER == (dwErr = g_pfnGetIpForwardTable(pIpForwardTable, &dwSize, TRUE)))
  380. {
  381. // Allocate the memory for the table
  382. if (NULL != (pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc(dwSize)))
  383. {
  384. // Now get the table
  385. dwErr = g_pfnGetIpForwardTable(pIpForwardTable, &dwSize, TRUE);
  386. }
  387. else
  388. {
  389. printf("runApiTests(): call to malloc() failed\n");
  390. }
  391. }
  392. if (NO_ERROR == dwErr)
  393. {
  394. if (0 != pIpForwardTable->dwNumEntries)
  395. {
  396. printf("%-15.15s\t%-15.15s\t%-15.15s\t%s\t%s\t%s\t%s\n",
  397. "Destination",
  398. "Network Mask",
  399. "Gateway",
  400. "IfIndex",
  401. "Type",
  402. "Proto",
  403. "Age");
  404. printf("===============================================================================\n");
  405. for (DWORD i=0; i < pIpForwardTable->dwNumEntries; i++)
  406. {
  407. PMIB_IPFORWARDROW pRow = &(pIpForwardTable->table[i]);
  408. CHAR szForwardDest[15 + 1];
  409. CHAR szForwardMask[15 + 1];
  410. CHAR szForwardNextHop[15 + 1];
  411. struct in_addr in;
  412. in.s_addr = pRow->dwForwardDest;
  413. lstrcpyA(szForwardDest, g_pfn_inet_ntoa(in));
  414. in.s_addr = pRow->dwForwardMask;
  415. lstrcpyA(szForwardMask, g_pfn_inet_ntoa(in));
  416. in.s_addr = pRow->dwForwardNextHop;
  417. lstrcpyA(szForwardNextHop, g_pfn_inet_ntoa(in));
  418. printf("%15.15s\t%15.15s\t%15.15s\t%d\t%d\t%d\t%d\n",
  419. szForwardDest,
  420. szForwardMask,
  421. szForwardNextHop,
  422. pRow->dwForwardIfIndex,
  423. pRow->dwForwardType,
  424. pRow->dwForwardProto,
  425. pRow->dwForwardAge);
  426. }
  427. }
  428. else
  429. {
  430. printf("There is no entry in the routing table.\n");
  431. }
  432. printf("\n");
  433. }
  434. else
  435. {
  436. printf("runApiTests(): GetIpForwardTable() failed w/ error %d\n", dwErr);
  437. }
  438. DWORD dwConnMethod = 0;
  439. if (InternetGetConnectedState(&dwConnMethod, 0))
  440. {
  441. printf("InternetGetConnectedState(&dwConnMethod) returns TRUE, dwConnMethod = %#lx\n", dwConnMethod);
  442. }
  443. else
  444. {
  445. printf("InternetGetConnectedState(&dwConnMethod) returns FALSE\n");
  446. }
  447. if (dwConnMethod & INTERNET_CONNECTION_MODEM)
  448. {
  449. printf("\t%s\n", "INTERNET_CONNECTION_MODEM");
  450. }
  451. if (dwConnMethod & INTERNET_CONNECTION_LAN )
  452. {
  453. printf("\t%s\n", "INTERNET_CONNECTION_LAN");
  454. }
  455. if (dwConnMethod & INTERNET_CONNECTION_PROXY )
  456. {
  457. printf("\t%s\n", "INTERNET_CONNECTION_PROXY");
  458. }
  459. if (dwConnMethod & INTERNET_CONNECTION_MODEM_BUSY )
  460. {
  461. printf("\t%s\n", "INTERNET_CONNECTION_MODEM_BUSY");
  462. }
  463. if (dwConnMethod & INTERNET_RAS_INSTALLED )
  464. {
  465. printf("\t%s\n", "INTERNET_RAS_INSTALLED");
  466. }
  467. if (dwConnMethod & INTERNET_CONNECTION_OFFLINE )
  468. {
  469. printf("\t%s\n", "INTERNET_CONNECTION_OFFLINE");
  470. }
  471. if (dwConnMethod & INTERNET_CONNECTION_CONFIGURED )
  472. {
  473. printf("\t%s\n", "INTERNET_CONNECTION_CONFIGURED");
  474. }
  475. printf("\n");
  476. DWORD dwState = 0;
  477. dwSize = sizeof(DWORD);
  478. if (InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
  479. {
  480. printf("InternetQueryOptionA(NULL, INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize) returns TRUE, dwState = %#lx\n", dwState);
  481. if (dwState & INTERNET_STATE_CONNECTED)
  482. {
  483. printf("\t%s\n", "INTERNET_STATE_CONNECTED - connected state (mutually exclusive with disconnected)");
  484. }
  485. if (dwState & INTERNET_STATE_DISCONNECTED)
  486. {
  487. printf("\t%s\n", "INTERNET_STATE_DISCONNECTED - disconnected from network");
  488. }
  489. if (dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
  490. {
  491. printf("\t%s\n", "INTERNET_STATE_DISCONNECTED_BY_USER - disconnected by user request");
  492. }
  493. if (dwState & INTERNET_STATE_IDLE)
  494. {
  495. printf("\t%s\n", "INTERNET_STATE_IDLE - no network requests being made (by Wininet)");
  496. }
  497. if (dwState & INTERNET_STATE_BUSY)
  498. {
  499. printf("\t%s\n", "INTERNET_STATE_BUSY - network requests being made (by Wininet)");
  500. }
  501. }
  502. else
  503. {
  504. printf("IsConnected(): InternetQueryOptionA failed with error %d\n", GetLastError());
  505. }
  506. printf("\n");
  507. if (NULL != pIpForwardTable)
  508. {
  509. free(pIpForwardTable);
  510. }
  511. }
  512. void runTest(WORD wVersion, LPSTR pszURL, BOOL fLive)
  513. {
  514. CHAR szVersion[50];
  515. HRESULT hr;
  516. BOOL fCoInit = FALSE;
  517. switch (wVersion)
  518. {
  519. case 0x0200:
  520. case 0x0202:
  521. sprintf(szVersion, "from AU %d.%d", HIBYTE(wVersion), LOBYTE(wVersion));
  522. break;
  523. case 0x0:
  524. sprintf(szVersion, "(bug fix candidate)");
  525. break;
  526. case 0x1:
  527. sprintf(szVersion, "(latest code)");
  528. break;
  529. /*
  530. case 0x3:
  531. sprintf(szVersion, "(SENS test)");
  532. if (fCoInit = FAILED(hr = CoInitialize(NULL)))
  533. {
  534. printf("runTest(): CoInitialize(NULL) failed w/ error %#lx\n", hr);
  535. goto CleanUp;
  536. }
  537. if (g_fVerbose)
  538. {
  539. printf("runTest(): CoInitialize(NULL) succeeded\n");
  540. }
  541. if (FAILED(hr = ActivateSensNetworkNotification()))
  542. {
  543. printf("runTest(): ActivateSensNetworkNotification() failed w/ error %#lx\n", hr);
  544. goto CleanUp;
  545. }
  546. if (g_fVerbose)
  547. {
  548. printf("runTest(): ActivateSensNetworkNotification() succeeded\n");
  549. }
  550. break;
  551. */
  552. default:
  553. printf("runTest(): unknown wVersion\n");
  554. goto CleanUp;
  555. }
  556. printf("Testing connection detection/server reachability algorithm %s...\n", szVersion);
  557. {
  558. USES_IU_CONVERSION;
  559. LPTSTR ptszURL = A2T(0x0200 == wVersion ? szWU_PING_URL : pszURL);
  560. _tprintf(_T("IsConnected(\"%s\") returns %s\n"), ptszURL, MyIsConnected(wVersion, ptszURL, fLive) ? _T("TRUE") : _T("FALSE"));
  561. }
  562. /*
  563. if (0x3 == wVersion)
  564. {
  565. if (FAILED(hr = DeactivateSensNetworkNotification()))
  566. {
  567. printf("runTest(): DeactivateSensNetworkNotification() failed w/ error %#lx\n", hr);
  568. }
  569. else if (g_fVerbose)
  570. {
  571. printf("runTest(): DeactivateSensNetworkNotification() succeeded\n");
  572. }
  573. }
  574. */
  575. CleanUp:
  576. if (fCoInit)
  577. {
  578. CoUninitialize();
  579. }
  580. }
  581. int __cdecl main(int argc, char* argv[])
  582. {
  583. char c_szMethodToken[] = "/method:";
  584. char c_szMToken[] = "/m:";
  585. char c_szVerboseToken[] = "/verbose";
  586. char c_szVToken[] = "/v";
  587. char c_szCorpToken[] = "/corpwu";
  588. char c_szLiveToken[] = "/live";
  589. int fLive = -1;
  590. WORD wVersion = 0xffff; // default == unknown;
  591. LPSTR pszURL = NULL;
  592. int index = 0;
  593. while (index < argc - 1)
  594. {
  595. LPSTR psz = NULL;
  596. index++;
  597. if (0 == StrCmpNIA(argv[index], c_szMethodToken, ARRAYSIZE(c_szMethodToken) - 1))
  598. {
  599. psz = argv[index] + ARRAYSIZE(c_szMethodToken) - 1;
  600. }
  601. else if (0 == StrCmpNIA(argv[index], c_szMToken, ARRAYSIZE(c_szMToken) - 1))
  602. {
  603. psz = argv[index] + ARRAYSIZE(c_szMToken) - 1;
  604. }
  605. if (NULL != psz)
  606. {
  607. if (0xffff != wVersion)
  608. {
  609. // param specified twice
  610. goto Usage;
  611. }
  612. char c_szOptionCode[] = "code";
  613. char c_szOptionFix[] = "fix";
  614. char c_szOptionAll[] = "all";
  615. char c_szOptionSens[] = "sens";
  616. int iMajorVersion = 0, iMinorVersion = 0;
  617. if (2 != sscanf(psz, "%d.%d", &iMajorVersion, &iMinorVersion))
  618. {
  619. if (0 == StrCmpNIA(psz, c_szOptionCode, ARRAYSIZE(c_szOptionCode)))
  620. {
  621. iMajorVersion = 0;
  622. iMinorVersion = 1;
  623. }
  624. else if (0 == StrCmpNIA(psz, c_szOptionFix, ARRAYSIZE(c_szOptionFix)))
  625. {
  626. iMajorVersion = iMinorVersion = 0;
  627. }
  628. else if (0 == StrCmpNIA(psz, c_szOptionAll, ARRAYSIZE(c_szOptionAll)))
  629. {
  630. iMajorVersion = 0xff;
  631. iMinorVersion = 0xfe;
  632. }
  633. /*
  634. else if (0 == StrCmpNIA(psz, c_szOptionSens, ARRAYSIZE(c_szOptionSens)))
  635. {
  636. iMajorVersion = 0;
  637. iMinorVersion = 3;
  638. }
  639. */
  640. else
  641. {
  642. goto Usage;
  643. }
  644. }
  645. wVersion = MAKEWORD(iMinorVersion, iMajorVersion);
  646. continue;
  647. }
  648. if (0 == StrCmpNIA(argv[index], c_szVerboseToken, ARRAYSIZE(c_szVerboseToken)) ||
  649. 0 == StrCmpNIA(argv[index], c_szVToken, ARRAYSIZE(c_szVToken)))
  650. {
  651. if (g_fVerbose)
  652. {
  653. // param specified twice
  654. goto Usage;
  655. }
  656. g_fVerbose = TRUE;
  657. continue;
  658. }
  659. if (0 == StrCmpNIA(argv[index], c_szLiveToken, ARRAYSIZE(c_szLiveToken)))
  660. {
  661. if (-1 != fLive)
  662. {
  663. // param specified twice or conflicting param
  664. goto Usage;
  665. }
  666. fLive = 1;
  667. continue;
  668. }
  669. if (0 == StrCmpNIA(argv[index], c_szCorpToken, ARRAYSIZE(c_szCorpToken)))
  670. {
  671. if (-1 != fLive)
  672. {
  673. // param specified twice or conflicting param
  674. goto Usage;
  675. }
  676. fLive = 0;
  677. continue;
  678. }
  679. if ('/' != *argv[index])
  680. {
  681. if (NULL != pszURL)
  682. {
  683. // param specified twice
  684. goto Usage;
  685. }
  686. pszURL = argv[index];
  687. continue;
  688. }
  689. // unknown param
  690. goto Usage;
  691. }
  692. switch (wVersion)
  693. {
  694. case 0x0200:
  695. if (NULL != pszURL)
  696. {
  697. goto Usage;
  698. }
  699. break;
  700. case 0x0202:
  701. case 0x0:
  702. case 0x1:
  703. // case 0x3:
  704. case 0xfffe:
  705. if (NULL == pszURL)
  706. {
  707. goto Usage;
  708. }
  709. break;
  710. default:
  711. goto Usage;
  712. }
  713. if (-1 == fLive)
  714. {
  715. fLive = 1;
  716. }
  717. if ((NULL == g_hIphlp && NULL == (g_hIphlp = LoadLibrary(TEXT("iphlpapi.dll")))) ||
  718. NULL == (g_pfnGetBestInterface = (GETBESTINTERFACE)::GetProcAddress(g_hIphlp, "GetBestInterface")) ||
  719. NULL == (g_pfnGetBestRoute = (GETBESTROUTE)::GetProcAddress(g_hIphlp, "GetBestRoute")) ||
  720. NULL == (g_pfnGetInterfaceInfo = (GETINTERFACEINFO)::GetProcAddress(g_hIphlp, "GetInterfaceInfo")) ||
  721. NULL == (g_pfnGetIpForwardTable = (GETIPFORWARDTABLE)::GetProcAddress(g_hIphlp, "GetIpForwardTable")))
  722. {
  723. printf("Failed to load proc from iphlpapi.dll\n");
  724. goto Done;
  725. }
  726. if ((NULL == g_hSock && NULL == (g_hSock = LoadLibrary(TEXT("ws2_32.dll")))) ||
  727. NULL == (g_pfnWSAStartup = (WSASTARTUP)::GetProcAddress(g_hSock, "WSAStartup")) ||
  728. NULL == (g_pfnWSACleanup = (WSACLEANUP)::GetProcAddress(g_hSock, "WSACleanup")) ||
  729. NULL == (g_pfn_gethostbyname = (GETHOSTBYNAME)::GetProcAddress(g_hSock, "gethostbyname")) ||
  730. NULL == (g_pfnWSAGetLastError = (WSAGETLASTERROR)::GetProcAddress(g_hSock, "WSAGetLastError")) ||
  731. NULL == (g_pfn_inet_addr = (INET_ADDR)::GetProcAddress(g_hSock, "inet_addr")) ||
  732. NULL == (g_pfn_inet_ntoa = (INET_NTOA)::GetProcAddress(g_hSock, "inet_ntoa")))
  733. {
  734. printf("Failed to load proc from ws2_32.dll\n");
  735. goto Done;
  736. }
  737. if (NULL == (g_hSens = LoadLibrary(TEXT("sensapi.dll"))) ||
  738. NULL == (g_pfnIsNetworkAlive = (ISNETWORKALIVE)::GetProcAddress(g_hSens, "IsNetworkAlive")) ||
  739. NULL == (g_pfnIsDestinationReachableA = (ISDESTINATIONREACHABLEA)::GetProcAddress(g_hSens, "IsDestinationReachableA")))
  740. {
  741. printf("Failed to load proc from sensapi.dll\n");
  742. goto Done;
  743. }
  744. if (0xfffe == wVersion)
  745. {
  746. WORD awVersions[] = {0x0200, 0x0202, 0x0, 0x1};
  747. printf("*******************************************************************************\nRunning API tests...\n\n");
  748. runApiTests(0x0200 == wVersion ? szWU_PING_URL : pszURL);
  749. printf("*******************************************************************************\nRunning various connectivity tests...\n\n");
  750. for (int i=0; i < ARRAYSIZE(awVersions); i++)
  751. {
  752. runTest(awVersions[i], pszURL, fLive);
  753. printf("\n");
  754. }
  755. }
  756. else
  757. {
  758. runTest(wVersion, pszURL, fLive);
  759. }
  760. goto Done;
  761. Usage:
  762. printf("Windows Update V4 Network Connectivity/Server Reachability (IsConnected) Test\nCopyright (c) 2002. Microsoft Corporation. All rights reserved.\n\n");
  763. printf("usage:\n\ttestIsConnected /m[ethod]:<method> [/v[erbose]] [/live | /corpwu] [<destination>]\n");
  764. printf("where\n\t<method>\ttest method i.e. \"2.0\" for AU 2.0,\n");
  765. printf("\t\t\t\t\t \"2.2\" for older AU 2.2,\n");
  766. printf("\t\t\t\t\t \"fix\" for AU 2.2 w/ fix (mirrored),\n");
  767. printf("\t\t\t\t\t \"code\" for actual AU 2.2 code w/ fix,\n");
  768. printf("\t\t\t\t\t \"all\" to test all methods\n");
  769. printf("\t/live\t\tspecifies destination points to the live WU server\n");
  770. printf("\t\t\t(default; cannot be used together with /corpwu)\n");
  771. printf("\t/corpwu\t\tspecifies destination points to a WUCE server\n");
  772. printf("\t\t\t(cannot be used together with /live)\n");
  773. 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");
  774. Done:
  775. if (g_hIphlp != NULL)
  776. {
  777. FreeLibrary(g_hIphlp);
  778. }
  779. if (g_hSock != NULL)
  780. {
  781. FreeLibrary(g_hSock);
  782. }
  783. if (g_hSens != NULL)
  784. {
  785. FreeLibrary(g_hSens);
  786. }
  787. return 0;
  788. }