netchck.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:13k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #ifndef _MAC_MACHO
  36. #include "OpenTransport.h"
  37. #include "OpenTptInternet.h"
  38. #endif
  39. #include "prefdefs.h"
  40. #include "netchck.h"
  41. #include "hxtick.h"
  42. #define DEF_HTTP_PORT      80
  43. #define DEF_DNS_PORT      53 //tcp
  44. enum {
  45. kOTTCPDialUnknown = 0,
  46. kOTTCPDialTCPDisabled,
  47. kOTTCPDialYes,
  48. kOTTCPDialNo
  49. };
  50. // From SCNetwork.h in SystemConfiguration.framework
  51. typedef Boolean (*SCNetworkCheckReachabilityByNameProcPtr) ( const char *nodename,
  52.                                                              int *flags );
  53. CHXNetCheck::CHXNetCheck(UINT32 timeout) :
  54. XHXNetCheck(timeout)
  55. , m_pRmaNetServices(0)
  56. , m_pRmaTCPSocket(0)
  57. , m_pContext(0)
  58. , m_fConnected(FALSE)
  59. , m_fFailed(FALSE)
  60. , m_lRefCount(0)
  61. {
  62. }
  63. CHXNetCheck::~CHXNetCheck()
  64. {
  65. if (m_pContext)
  66. m_pContext->Release();
  67. m_pContext = NULL;
  68. if (m_pRmaNetServices)
  69. m_pRmaNetServices->Release();
  70. m_pRmaNetServices = NULL;
  71. if (m_pRmaTCPSocket)
  72. m_pRmaTCPSocket->Release();
  73. m_pRmaTCPSocket = NULL;
  74. }
  75. /////////////////////////////////////////////////////////////////////////
  76. //  Method:
  77. // IUnknown::QueryInterface
  78. //  Purpose:
  79. // Implement this to export the interfaces supported by your 
  80. // object.
  81. //
  82. STDMETHODIMP CHXNetCheck::QueryInterface(REFIID riid, void** ppvObj)
  83. {
  84.     if (IsEqualIID(riid, IID_IUnknown))
  85.     {
  86.     AddRef();
  87.     *ppvObj = this;
  88.     return HXR_OK;
  89.     }
  90.     if (IsEqualIID(riid, IID_IHXTCPResponse))
  91.     {
  92.     AddRef();
  93.     *ppvObj = (IHXTCPResponse*)this;
  94.     return HXR_OK;
  95.     }
  96.     *ppvObj = NULL;
  97.     return HXR_NOINTERFACE;
  98. }
  99. /////////////////////////////////////////////////////////////////////////
  100. //  Method:
  101. // IUnknown::AddRef
  102. //  Purpose:
  103. // Everyone usually implements this the same... feel free to use
  104. // this implementation.
  105. //
  106. STDMETHODIMP_(UINT32) CHXNetCheck::AddRef()
  107. {
  108.     return InterlockedIncrement(&m_lRefCount);
  109. }
  110. /////////////////////////////////////////////////////////////////////////
  111. //  Method:
  112. // IUnknown::Release
  113. //  Purpose:
  114. // Everyone usually implements this the same... feel free to use
  115. // this implementation.
  116. //
  117. STDMETHODIMP_(UINT32) CHXNetCheck::Release()
  118. {
  119.     if (InterlockedDecrement(&m_lRefCount) > 0)
  120.     {
  121.         return m_lRefCount;
  122.     }
  123.     delete this;
  124.     return 0;
  125. }
  126. /*
  127.  * IHXTCPResponse methods
  128.  */
  129. /************************************************************************
  130.  * Method:
  131.  *     IHXTCPResponse::ConnectDone
  132.  * Purpose:
  133.  *     A Connect operation has been completed or an error has occurred.
  134.  */
  135. STDMETHODIMP CHXNetCheck::ConnectDone (HX_RESULT status)
  136. {
  137. HX_ASSERT(m_fConnected == FALSE); // We shouldn't be getting called if 
  138. // we aren't expecting it.
  139. if (status == HXR_OK)
  140. m_fConnected = TRUE;
  141. else
  142. m_fFailed = TRUE;
  143. return HXR_OK;
  144. }
  145. /************************************************************************
  146.  * Method:
  147.  *     IHXTCPResponse::ReadDone
  148.  * Purpose:
  149.  *     A Read operation has been completed or an error has occurred.
  150.  *     The data is returned in the IHXBuffer.
  151.  */
  152. STDMETHODIMP CHXNetCheck::ReadDone (HX_RESULT status,
  153. IHXBuffer* pBuffer)
  154. {
  155. HX_ASSERT(FALSE);
  156. return HXR_OK;
  157. }
  158. /************************************************************************
  159.  * Method:
  160.  *     IHXTCPResponse::WriteReady
  161.  * Purpose:
  162.  *     This is the response method for WantWrite.
  163.  *     If HX_RESULT is ok, then the TCP channel is ok to Write to.
  164.  */
  165. STDMETHODIMP CHXNetCheck::WriteReady (HX_RESULT status)
  166. {
  167. HX_ASSERT(FALSE);
  168. return HXR_OK;
  169. }
  170. /************************************************************************
  171.  * Method:
  172.  *     IHXTCPResponse::Closed
  173.  * Purpose:
  174.  *     This method is called to inform you that the TCP channel has
  175.  *     been closed by the peer or closed due to error.
  176.  */
  177. STDMETHODIMP CHXNetCheck::Closed(HX_RESULT status)
  178. {
  179. m_fConnected = FALSE;
  180. return HXR_OK;
  181. }
  182. //******************************************************************************
  183. //
  184. // Method: CHXNetCheck::Init
  185. //
  186. // Purpose: Sets up the CHXNetCheck object with a context.
  187. //
  188. //
  189. // Notes: n/a
  190. //
  191. //******************************************************************************
  192. HX_RESULT 
  193. CHXNetCheck::Init(IUnknown *pContext)
  194. {
  195. HX_RESULT result = HXR_OK;
  196. if (!pContext)
  197. return HXR_FAILED;
  198. m_pContext = pContext;
  199. m_pContext->AddRef();
  200. return result;
  201. }
  202. //******************************************************************************
  203. //
  204. // Method: CHXNetCheck::FInternetAvailable
  205. //
  206. // Purpose: Checks to see if the internet is available.  Returns true if it is, 
  207. // false otherwise.
  208. //
  209. //
  210. // Notes: n/a
  211. //
  212. //******************************************************************************
  213. BOOL 
  214. CHXNetCheck::FInternetAvailable(BOOL fPing,BOOL fProxy)
  215. {
  216.     BOOL fRet = FALSE;
  217.     BOOL fAutoDial = FALSE;
  218.     UINT16 nPort = DEF_HTTP_PORT;
  219.     ULONG32  willTCPDial;
  220.     OSErr TCPError = HXMacNetWillDial(NULL, &willTCPDial);
  221.     HX_ASSERT(noErr == TCPError);
  222.     
  223.     if (noErr == TCPError)
  224.     {
  225. switch ( willTCPDial ) 
  226. {
  227.     case kOTTCPDialTCPDisabled:
  228.     // TCP/IP is disabled
  229.     break;
  230.     case kOTTCPDialUnknown:
  231.     // We don't know whether opening a TCP endpoint will dial the modem 
  232.     break;
  233.     case kOTTCPDialYes:
  234.     // Opening a TCP endpoint will dial the modem.
  235.     fAutoDial = TRUE;
  236.     break;
  237.     case kOTTCPDialNo:
  238.     // Opening a TCP endpoint will not dial the modem.
  239.     break;
  240.      }
  241.     }
  242.     else
  243.     {
  244.      return FALSE; // no network conection or no PPP setup
  245.     }
  246.     
  247.     if (!fAutoDial)
  248.     {
  249.      if (fPing)
  250. {
  251.     // try to get DNS address to ping.
  252.     CHXString strPingAddr;
  253.     GetDNSAddress(strPingAddr);
  254.     nPort = DEF_DNS_PORT;
  255.     // No DNS address? Default to a known web server.
  256.     // XXXBJP pinging video.real.com, used in Beta 1, should be
  257.     // changed for Beta 2!!
  258.     if (strPingAddr.IsEmpty())
  259.     {
  260. HX_ASSERT(FALSE);
  261. strPingAddr = "209.66.98.23";
  262. nPort = DEF_HTTP_PORT;
  263.     }
  264.     fRet = Ping(strPingAddr, nPort, FALSE);
  265. }
  266. else 
  267.     fRet = TRUE;
  268.     }
  269.     return (fRet);
  270. }
  271. //******************************************************************************
  272. //
  273. // Method: CHXNetCheck::Ping
  274. //
  275. // Purpose: Tests to see if we can open a TCP connection to the given hostname. 
  276. // if fAynchronous is true, we call back a response object provided by
  277. // the caller (through Init).  Otherwise we block.
  278. //
  279. //
  280. // Notes: n/a
  281. //
  282. //******************************************************************************
  283. BOOL CHXNetCheck::Ping(const char *szHostName, UINT16 nPort, BOOL fAsynchronous)
  284. {
  285. ULONG32 ulStartTime, ulCurrentTime, ulInterval, ulElapsedTime;
  286. BOOL fRet = FALSE;
  287. // If we don't have the network services interface yet than try and get it here
  288. if (m_pContext && !m_pRmaNetServices)
  289.     m_pContext->QueryInterface(IID_IHXNetworkServices, (void**)&m_pRmaNetServices);
  290. if (!m_pRmaTCPSocket)
  291. m_pRmaNetServices->CreateTCPSocket(&m_pRmaTCPSocket);
  292. if (!m_pRmaTCPSocket)
  293. return FALSE;
  294. m_fFailed = m_fConnected = FALSE;
  295. m_pRmaTCPSocket->Init(this);
  296. m_pRmaTCPSocket->Connect(szHostName, nPort);
  297. ulElapsedTime = 0;
  298. ulInterval = 30000;
  299. // Get start time
  300. ulStartTime = HX_GET_TICKCOUNT();
  301. while (!m_fFailed && !m_fConnected && (ulElapsedTime < ulInterval))
  302. {
  303. SleepWell(1000);
  304.     ulCurrentTime = HX_GET_TICKCOUNT();
  305. ulElapsedTime = CALCULATE_ELAPSED_TICKS(ulStartTime, ulCurrentTime);
  306. }
  307. fRet = m_fConnected;
  308. m_pRmaTCPSocket->Release();
  309. m_pRmaTCPSocket = NULL;
  310. return (fRet);
  311. }
  312. //******************************************************************************
  313. //
  314. // Method: CHXNetCheck::GetDNSAddress
  315. //
  316. // Purpose: Determines the IP address of the user's primary DNS server.
  317. //
  318. // Notes: Returns IP address in numeric form, in a CHXString. An empty
  319. // string is returned when the IP address cannot be determined.
  320. //
  321. //******************************************************************************
  322. void CHXNetCheck::GetDNSAddress(CHXString& strDNS)
  323. {
  324. // Get information about the interface ( 0 is default )
  325. InetInterfaceInfo theInfo;
  326. OSStatus result = OTInetGetInterfaceInfo (&theInfo, 0);
  327. // Retrieve DNS from structure
  328. InetHost theDNS = theInfo.fDNSAddr;
  329. // Convert InetHost to char*
  330. char theDNSString[255]; /* Flawfinder: ignore */
  331. OTInetHostToString (theDNS,theDNSString);
  332. // Copy that to the CHXString
  333. strDNS = theDNSString;
  334. // We are done ! 
  335. }
  336. //******************************************************************************
  337. //
  338. // Method: CHXNetCheck::SleepWell
  339. //
  340. // Purpose: This method sleeps but continues to pump messages.  This allows us to 
  341. // block properly, even under such platforms as Win16.
  342. //
  343. //
  344. // Notes: n/a
  345. //
  346. //******************************************************************************
  347. void CHXNetCheck::SleepWell(ULONG32 ulInterval)
  348. {
  349. #if 0
  350. ULONG32 ulStartTime, ulCurrentTime;
  351. MSG     msg;
  352. // Get start time
  353. ulStartTime = HX_GET_TICKCOUNT();
  354. do
  355. {
  356.     // Keep pumping messages
  357.         if(PeekMessage(&msg, NULL,0,0,PM_REMOVE))
  358.     {
  359. if(msg.message == WM_QUIT) 
  360. {
  361.     PostQuitMessage(0);
  362.     break;
  363. }
  364. else
  365. {
  366.     TranslateMessage(&msg);
  367.             DispatchMessage(&msg);
  368. }
  369.     }
  370.     // If we have waited ulInterval time then drop out
  371.     ulCurrentTime = HX_GET_TICKCOUNT();
  372. } while (CALCULATE_ELAPSED_TICKS(ulStartTime, ulCurrentTime) < ulInterval);
  373. #endif
  374. }
  375. BOOL 
  376. CHXNetCheck::SmartPing()
  377. {
  378.    UINT16 nPort = DEF_HTTP_PORT;
  379.     // try to get DNS address to ping.
  380.     CHXString strPingAddr;
  381.     GetDNSAddress(strPingAddr);
  382.     nPort = DEF_DNS_PORT;
  383.     
  384.     // No DNS address? Default to a known web server.
  385.     // XXXBJP pinging video.real.com, used in Beta 1, should be
  386.     // changed for Beta 2!!
  387.     if (strPingAddr.IsEmpty())
  388.     {
  389.     strPingAddr = "209.66.98.23"; // video.real.com .. UGHHHH!!
  390.     nPort = DEF_HTTP_PORT;
  391.     }
  392.     return (Ping(strPingAddr, nPort, FALSE));
  393. }
  394. OSStatus HXMacNetWillDial( char* remoteHost, ULONG32* willDial )
  395. {
  396. OSStatus outResult = paramErr;
  397. Boolean success = FALSE;
  398. if( !willDial )
  399. {
  400. return outResult;
  401. }
  402. *willDial = kOTTCPDialUnknown;
  403. char* nodename = "real.com";
  404. if( remoteHost )
  405. {
  406. nodename = remoteHost;
  407. }
  408. SCNetworkCheckReachabilityByNameProcPtr proc;
  409. int flags;
  410. CFBundleRef sysConfigBundle = CFBundleGetBundleWithIdentifier( CFSTR("com.apple.SystemConfiguration") );
  411. if( sysConfigBundle )
  412. {
  413. proc = (SCNetworkCheckReachabilityByNameProcPtr) CFBundleGetFunctionPointerForName( sysConfigBundle, 
  414. CFSTR("SCNetworkCheckReachabilityByName") );
  415. if( proc )
  416. {
  417. success = (*proc) ( nodename, &flags );
  418. }
  419. CFRelease( sysConfigBundle );
  420. }
  421. if( success )
  422. {
  423. // see SCNetwork.h in SystemConfiguration.framework for
  424. // the meanings of flags
  425. if( flags & 1<<2 )
  426. {
  427. *willDial = kOTTCPDialYes;
  428. }
  429. else
  430. {
  431. *willDial = kOTTCPDialNo;
  432. }
  433. outResult = noErr;
  434. }
  435. return outResult;
  436. }