⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netchck.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
return HXR_OK;
}




//******************************************************************************
//
// Method:	CHXNetCheck::Init
//
// Purpose:	Sets up the CHXNetCheck object with a context.
//		
//
// Notes:	n/a
//
//******************************************************************************


HX_RESULT 
CHXNetCheck::Init(IUnknown *pContext)
{
	HX_RESULT result = HXR_OK;

	if (!pContext)
		return HXR_FAILED;

	m_pContext = pContext;
	m_pContext->AddRef();
	return result;
}

//******************************************************************************
//
// Method:	CHXNetCheck::FInternetAvailable
//
// Purpose:	The function checks if we can attempt a connection without 
//		    being prompted to connect.  
//		Returns true if we can, false otherwise.
//
// Notes:	There is no single function for determining if a machine is 
//		connected to the internet, and it is impossible to reliably 
//		determine what is happening without side effects - such as 
//		automatic network connections taking place.
//		
//		MSDN article - 
//		"HOWTO: Detecting If you have a Connection to the Internet"
//
//		"Usually the best way to determine if you have a connection 
//		to a particular computer is to attempt the connection. If the 
//		autodial feature of Windows is enabled then attempting the 
//		connection may cause the default Internet dialup connectoid 
//		to be opened, and you will be prompted with your credentials to connect.
//
//		To avoid having the default Internet connectoid dialed, 
//		the InternetGetConnectedState function can be used to determine 
//		if there is a default Internet dialup connectoid configured and 
//		whether it is currently active or not. If there is a default 
//		Internet dialup connectoid configured and it is not currently 
//		active then InternetGetConnectedState will return FALSE. 
//		If InternetGetConnectedState returns TRUE then you can attempt 
//		to connect to the Internet resource without fear of being prompted 
//		to connect to another Internet Service Provider.
//
//		You cannot rely solely on the fact that InternetGetConnectedState 
//		returning TRUE means that you have a valid active Internet 
//		connection. It is impossible for InternetGetConnectedState 
//		to determine if the entire connection to the Internet is 
//		functioning without sending a request to a server. This is why 
//		you need to send a request to determine if you are really connected 
//		or not. You can be assured however that if InternetGetConnectedState 
//		returns TRUE, that attempting your connection will NOT cause you 
//		to be prompted to connect to the default Internet Service Provider.
//
//		Be aware that InternetGetConnectedState only reports the status 
//		of the default Internet connectoid on Internet Explorer 4.x. 
//		If a nondefault connectoid is connected, InternetGetConnectedState 
//		always returns FALSE (unless a LAN connection is used). 
//		With Internet Explorer 4.x configured to use a LAN connection, 
//		InternetGetConectedState always returns TRUE.
//
//		Internet Explorer 5 behaves differently. If you are currently dialed 
//		into a different dial-up in Internet Explorer 5, InternetGetConnectedState 
//		reports dial-up connection status as long as any connectoid is dialed 
//		or an active LAN connection exists." 
//
//******************************************************************************


BOOL 
CHXNetCheck::FInternetAvailable(BOOL fPing, BOOL fProxy)
{
	using namespace NetDetectLog; 
	NetDetectLogLib logLib;

	BOOL fRet = FALSE;
	UINT16 nPort = DEF_HTTP_PORT;
	
#ifndef _WIN16

	WRITE_LOG0("FInternetAvailable fc entered...");

	HKEY hKey = 0 ;
	DWORD fAutoDial = 0 ;
	DWORD regType = 0 ;
	DWORD cbBuf;

#if !defined(WIN32_PLATFORM_PSPC)
	// set the error mode since we'll do some DLL loading and we want the OS to be
	// quiet whhen we do this
	UINT oldErrorMode = ::SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
#endif /* !defined(WIN32_PLATFORM_PSPC) */

	// XXXSO - agreed to use InternetGetConnectedState function only.
	// The rest of the code should be called when this function is not available.

	BOOL fConnected = FALSE;
	if( SUCCEEDED( WinInetGetConnected( fConnected )))
	{
	    fRet = fPing ? SmartPing() : fConnected;
	    goto Ret;
	}

// XXXKM - agreed to remove proxy impact on net detect; instead let the following code determine
// if we are connected or not - doing so will alleviate issues with proxy and dialup
#if 0
	if (fProxy)
	    return TRUE;
#endif

	WRITE_LOG0("Old algorithm entered ... ");
	WRITE_LOG0("Checking autodial flag ...");

	// XXXKM - check this early; if autodial is set, then return FALSE temporarily
	// check the autodial bit in the registry.
	cbBuf = sizeof(fAutoDial);
	if (RegOpenKey(HKEY_CURRENT_USER, OS_STRING("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
		&hKey) == ERROR_SUCCESS)
	{
	    OSVERSIONINFO osv;

	    memset(&osv, 0, sizeof(osv));
	    osv.dwOSVersionInfoSize = sizeof(osv);
	    GetVersionEx(&osv);
	    if (osv.dwPlatformId != VER_PLATFORM_WIN32_NT)
	    {
		WRITE_LOG0("Checking Win95/98 EnableAutodial flag in HKCU/Software/Microsoft/Windows"
		    "/Current Version/Internet Settings...");

		// check for the Win95/98 flag
		RegQueryValueEx(hKey, OS_STRING("EnableAutodial"), NULL, &regType, (BYTE *) &fAutoDial, &cbBuf);
	    }
	    else
	    {
		WRITE_LOG0("Checking for the RAS key on NT.");

		// XXXKM - check for the RAS key on NT; only way I could find around the assert/crash in rasapi32.dll
		// in situations where the dll existed, but ras was disabled/removed on the machine
		HKEY hRasKey = 0;
		if (::RegOpenKey(HKEY_LOCAL_MACHINE, OS_STRING("SOFTWARE\\Microsoft\\RAS"), &hRasKey) == ERROR_SUCCESS)
		{
		    // close the ras key
		    ::RegCloseKey(hRasKey);

		    // initialize to FALSE so this works the way it always has if something doesn't go right
		    fAutoDial = FALSE;
		    if (!m_hRasApiModule)
			m_hRasApiModule = ::LoadLibrary(OS_STRING("rasapi32.dll"));

		    if (m_hRasApiModule)
		    {
			WRITE_LOG0("rasapi32.dll loaded...");
			
			// try and get the API to enumerate RAS devices
			FPRASENUMDEVICES fpRasEnumDevices = (FPRASENUMDEVICES)GetProcAddress(m_hRasApiModule,
			    OS_STRING("RasEnumDevicesA"));
			if (!fpRasEnumDevices)
			{
			    fpRasEnumDevices  = (FPRASENUMDEVICES)GetProcAddress(m_hRasApiModule,
			    OS_STRING("RasEnumDevicesW"));
			}

			// we use this to see if there is a RAS enabled device on this system and also to 
			// check for initialization of the RAS subsystem since it will return an error if 
			// RAS is disabled or fails to initialize for whatever reason
			// XXXKM - this was added to prevent crashing on Win NT systems in the EnumEntries call
			// on machines where RAS has been disabled due to hardware profiles
			if (fpRasEnumDevices)
			{
			    WRITE_LOG0("Checking the RAS enabled devices...");
			    
			    RASDEVINFO rasDevInfo[1];
			    rasDevInfo[0].dwSize = sizeof(rasDevInfo);
			    DWORD bufferSize = sizeof(rasDevInfo);
			    DWORD numEntries = 0;
			    DWORD retVal = fpRasEnumDevices(rasDevInfo, &bufferSize, &numEntries);

			    // check if there was actually a RAS enabled device; this API will return an error
			    // if there are no RAS devices enabled, or if the RAS subsystem couldn't be initialized
			    if (retVal == ERROR_BUFFER_TOO_SMALL || retVal == ERROR_SUCCESS && numEntries == 1)
			    {
				// find the right entrypoint in the rasapi32.dll
				FPRASENUMENTRIES fpRasEnumEntries = (FPRASENUMENTRIES)GetProcAddress(m_hRasApiModule,
				    OS_STRING("RasEnumEntriesA"));
				if (!fpRasEnumEntries)
				{
				    fpRasEnumEntries = (FPRASENUMENTRIES)GetProcAddress(m_hRasApiModule,
				    OS_STRING("RasEnumEntriesW"));
				}

				// if we've got the RAS entries function, then call it
				if (fpRasEnumEntries)
				{
				    WRITE_LOG0("Calling RasEnumEntries function...");
				    
				    // setup the RAS entry structure for a single dialup item
				    RASENTRYNAME rasEntryName[1];
				    rasEntryName[0].dwSize = sizeof(rasEntryName);
				    bufferSize = sizeof(rasEntryName);
				    numEntries = 0;
				    // call the function to see how many dialup entries there are
				    retVal = fpRasEnumEntries(NULL, NULL, rasEntryName, &bufferSize, &numEntries);
				    // if our buffer is too small (i.e. there are more than one phone book entries)
				    // or we get a single item, then we have dialup, so set autodial to TRUE so 
				    // we'll tread lightly
				    if (retVal == ERROR_BUFFER_TOO_SMALL || (numEntries == 1 && retVal == ERROR_SUCCESS))
					fAutoDial = TRUE;
				}
			    }
			}
		    }
		}
	    }
	    // close the key when we're done with it
	    ::RegCloseKey(hKey);
	}

	WRITE_LOG1("Checked AUTODIAL flag = %d.", fAutoDial);

	// XXXKM - only check netcard active status if autodial is not on; if it's on, then
	// assume we are doing stuff through RAS connection only and ignore netcard for now;
	// only temporary
	if (!fAutoDial && FNetCardActive())
	{
	    WRITE_LOG0("FNetCardActive fc returned TRUE. goto exit ...");

	    fRet = TRUE;
	    goto Ret;
	}


	if (!fAutoDial) // 	if it's not set, go ahead and try the network
	{
	    if (fPing)
		fRet = SmartPing();
	    else 
		fRet = TRUE;

	    goto Ret;
	}
	else // See if we have an active RAS connection
	{		
	    WRITE_LOG0("Any active RAS connection?");

	    DWORD cRasConns = 0;
	    RASCONN rgRasConn[5];
	    DWORD cb = sizeof(rgRasConn);
	    
	    if (!m_hRasApiModule)
		    m_hRasApiModule= LoadLibrary(OS_STRING("rasapi32.dll"));
	    // add this code if this ever gets into win16; win16 will return nonnull on error from load library  #if _WIN16 if (m_handle < HINSTANCE_ERROR) m_handle = NULL; #endif
	    if (!m_hRasApiModule) // Dialup networking is not installed.
	    {
		    WRITE_LOG0("Dialup networking not installed ...");

	    	    if (fPing)
		    	fRet = SmartPing();
	    	    else 
		    	fRet = TRUE;
		    goto Ret;
	    }

	    if (!m_pRasEnumConnections)
		    m_pRasEnumConnections =
			(FPRASENUMCONNECTIONS)GetProcAddress(m_hRasApiModule,OS_STRING("RasEnumConnectionsA"));

	    if (!m_pRasEnumConnections) // Dialup networking is not installed.
	    {
		    WRITE_LOG0("Cannot load RasEnumConnections fc...");

		    if (fPing)
		    	fRet = SmartPing();
	    	    else 
		    	fRet = TRUE;
		    goto Ret;
	    }

	    rgRasConn[0].dwSize = sizeof(RASCONN);
	    m_pRasEnumConnections(rgRasConn, &cb, &cRasConns);
	    
	    WRITE_LOG1("RasEnumConnections found %d connections...", cRasConns);

	    if (cRasConns)
	    {

	    	    if (fPing)
		    	fRet = SmartPing();
	    	    else 
		    	fRet = TRUE;
		    goto Ret;
	    }
	    else
	    {
		    fRet = FALSE;
		    goto Ret;
	    }
	}
Ret:

	// free up the library if loaded
	if (m_hRasApiModule)
	{
	    ::FreeLibrary(m_hRasApiModule);
	    m_hRasApiModule = NULL;
	}

#if !defined(WIN32_PLATFORM_PSPC)
	// reset the error mode to the old value
	::SetErrorMode(oldErrorMode);
#endif /* !defined(WIN32_PLATFORM_PSPC) */

	WRITE_LOG1("FInternetAvailable terminated with %s value...", 
	    fRet ? "TRUE" : "FALSE");

	return(fRet);

#else
	// Win16 section
	// =-=w16.0  for win16 always returns true, since there is no popup dialog in the way
	return (TRUE);
#endif

}

//******************************************************************************
//
// Method:	CHXNetCheck::Ping
//
// Purpose:	Tests to see if we can open a TCP connection to the given hostname. 
//			if fAynchronous is true, we call back a response object provided by
//			the caller (through Init).  Otherwise we block.
//		
//
// Notes:	n/a
//
//******************************************************************************

BOOL CHXNetCheck::Ping(const char *szHostName, UINT16 nPort, BOOL fAsynchronous)
{
	ULONG32 ulStartTime, ulCurrentTime, ulElapsedTime;
	BOOL fRet = FALSE;

	// If we don't have the network services interface yet than try and get it here
	if (m_pContext && !m_pRmaNetServices)
	    m_pContext->QueryInterface(IID_IHXNetworkServices, (void**)&m_pRmaNetServices);

	if (!m_pRmaTCPSocket && m_pRmaNetServices)
		m_pRmaNetServices->CreateTCPSocket(&m_pRmaTCPSocket);

	if (!m_pRmaTCPSocket)
		return FALSE;

	m_fFailed = m_fConnected = FALSE;
	m_pRmaTCPSocket->Init(this);
	
	m_pRmaTCPSocket->Connect(szHostName, nPort);

	ulElapsedTime = 0;
	
	// Get start time
	ulStartTime = HX_GET_TICKCOUNT();
	while (!m_fFailed && !m_fConnected && (ulElapsedTime < m_Timeout))
	{
		SleepWell(1000);
	    ulCurrentTime = HX_GET_TICKCOUNT();
		ulElapsedTime = CALCULATE_ELAPSED_TICKS(ulStartTime, ulCurrentTime);
	}
	fRet = m_fConnected;

	m_pRmaTCPSocket->Release();
	m_pRmaTCPSocket = NULL;

	return (fRet);
}

//******************************************************************************
//
// Method:	CHXNetCheck::SleepWell
//
// Purpose:	This method sleeps but continues to pump messages.  This allows us to 
//			block properly, even under such platforms as Win16.
//		
//
// Notes:	n/a
//
//******************************************************************************

void CHXNetCheck::SleepWell(ULONG32 ulInterval)
{
	ULONG32 ulStartTime, ulCurrentTime;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -