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

📄 autodial.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
DWORD HangUpIdleConnectionThread(LPVOID lpv)
{
	RAS_STATS pppStats;
	DWORD cbPPPStats = sizeof(pppStats);
	DWORD dwActualOut;
	__int64    ftCur;		// treated as a FILETIME, current time
	RASCONNSTATUS rasConnStatus;

	pppStats.dwSize      = sizeof(pppStats);
	rasConnStatus.dwSize = sizeof (RASCONNSTATUS);
	
	while ( WAIT_TIMEOUT == WaitForSingleObject(g_AutoDialConn.m_hTimerEvent,HANGUP_SLEEP_INTERVAL))
	{
		// If the connection came down in another way (for instance someone unplugging phone)
		// then we need to shut down AutoDial stuff.  

		EnterCriticalSection(&g_GlobalCS);
		ASSERT(g_fState == STATE_ON || g_fState == STATE_SHUTTING_DOWN || g_fState == STATE_STARTING_UP);

		if (g_fState == STATE_SHUTTING_DOWN || g_fState == STATE_STARTING_UP)
		{
			// In this state the timer fired after we initiated a shutdown
			// but before we could kill this thread from AutodialEndConnection,
			// so just keep going through loop in this case.
			DEBUGMSG(ZONE_WARN,(TEXT("AutoDial: HangupIdleConnectionThread called when state=STATE_SHUTTING_DOWN or STATE_STARTING_UP\r\n")));

			LeaveCriticalSection(&g_GlobalCS);
			continue;
		}
		if (g_fState != STATE_ON)
		{
			DEBUGMSG(ZONE_ERROR | ZONE_CONNECTION,(TEXT("AutoDial: Warning, leaving HangUpIdleConnectionThread because g_fState is not on.  Invalid case\r\n")));
			LeaveCriticalSection(&g_GlobalCS);
			return 0;
		}

		if (ERROR_SUCCESS != RasGetConnectStatus(g_AutoDialConn.m_hRasConn,&rasConnStatus) ||
		   (rasConnStatus.rasconnstate == RASCS_Disconnected))
		{
			DEBUGMSG(ZONE_CONNECTION,(TEXT("AutoDial: Leaving HangUpIdleConnectionThread because connection has been disconnected\r\n")));
			LeaveCriticalSection(&g_GlobalCS);
			AutoDialEndConnectionInternal(TRUE);
			return 0;
		}
		LeaveCriticalSection(&g_GlobalCS);

		GetCurrentFT((FILETIME *) &ftCur);
		RasIOControl(g_AutoDialConn.m_hRasConn,RASCNTL_STATISTICS,0,0,(PVOID) &pppStats,cbPPPStats,&dwActualOut);
		DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+HangUpIdleConnectionThread.  pppStats.dwBytesXmited=%d, pppStats.dwBytesRcved=%d,g_AutoDialConn.m_dwBytesTxRx=%d\r\n"),
										pppStats.dwBytesXmited,pppStats.dwBytesRcved,g_AutoDialConn.m_dwBytesTxRx));


		// Has there been activity since the last time this thread ran?
		if (pppStats.dwBytesXmited + pppStats.dwBytesRcved - g_AutoDialConn.m_dwBytesTxRx > 0)
		{
			g_AutoDialConn.m_dwBytesTxRx = pppStats.dwBytesXmited +
										   pppStats.dwBytesRcved;
			g_AutoDialConn.m_ftLastActivity = ftCur;
		}
		else if (ftCur - g_AutoDialConn.m_ftLastActivity > g_AutoDialConn.m_ftIdleTimeout)
		{
			DEBUGMSG(ZONE_CONNECTION,(TEXT("Autodial:  Disconnecting RAS connection due to long idle time\r\n")));
			AutoDialEndConnectionInternal(TRUE); 
			break;
		}
	}
	return 0;
}

// Returns TRUE if it found connection (and sets pConnState), FALSE otherwise.
BOOL GetConnectedStatus(TCHAR *szEntryName, RASCONNSTATUS *lpRasConn, HRASCONN *phRasConn)
{
	DWORD 			dwConnections;
	DWORD           dwErr;
	LPRASCONN		pRasConn;
	BYTE			RasConnData[10*sizeof(RASCONN)];
	DWORD       	cb;
	DWORD 			i;

	DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+CheckConnected\r\n")));
	
	// This will create the default entries if the key does not exist.
	RasEnumEntries (NULL, NULL, NULL, &cb, NULL);

	pRasConn = (LPRASCONN) RasConnData;
	pRasConn->dwSize = sizeof(RASCONN);
	cb = sizeof(RasConnData);

	// Get a list of all connections
	if (ERROR_SUCCESS != (dwErr = RasEnumConnections(pRasConn,&cb,&dwConnections)))
	{
		DEBUGMSG(ZONE_ERROR,(L"RasEnumConnections failed, error=0x%08x\r\n",dwErr));
		return FALSE;
	}
		
	// Look through the list for a value of szEntryName.
	for (i = 0; i < dwConnections; i++)
	{
		if (! (_tcsncmp (szEntryName,pRasConn[i].szEntryName,RAS_MaxEntryName)))
			break;
	}

	if (i == dwConnections)
		return FALSE; // did not find szEntryName in current active connections.

	lpRasConn->dwSize = sizeof(RASCONNSTATUS);
	if (ERROR_SUCCESS != (dwErr = RasGetConnectStatus(pRasConn[i].hrasconn,lpRasConn))) 
	{
		DEBUGMSG(ZONE_ERROR,(L"RasGetConnectStatus failed, error=0x%08x\r\n",dwErr));
		return FALSE;
	}

	*phRasConn = pRasConn[i].hrasconn;
	return TRUE;
}

// This function takes the entry name and makes sure that no existing connections
// exist with it yet.

DWORD CheckConnected(TCHAR *szEntryName)
{
	RASCONNSTATUS RasConnStatus;
	HRASCONN      hRasConn;

	if (GetConnectedStatus(szEntryName,&RasConnStatus,&hRasConn) && (RasConnStatus.rasconnstate != RASCS_Disconnected))
	{
		DEBUGMSG(ZONE_ERROR,(TEXT("AutoDial: Checking to see if %s connectoid connection returns ERROR_DIAL_ALREADY_IN_PROGRESS")
		                     TEXT("will not initiate dial\r\n"),szEntryName));
		return ERROR_DIAL_ALREADY_IN_PROGRESS;
	}
	return ERROR_SUCCESS;
}

// It's possible another process is using autodial (i.e. device.exe
// IPNat loaded autodial, but we're doing this query from services.exe NATAdmin).
// In this case see if the connection is active and fill in state appropriatly.
DWORD DetermineIfAutodialConnectionsActive(RASCONNSTATUS *lpRasConnStatus, TCHAR *szRasName, HRASCONN *phRasConn)
{
	AUTODIAL_CONNECTION_INFO adConnInfo;
	TCHAR 			szEntryName1[RAS_MaxEntryName + 1];
	TCHAR 			szEntryName2[RAS_MaxEntryName + 1];
	DWORD           dwRet;

	szEntryName1[0] = szEntryName2[0] = 0;

	if (ERROR_SUCCESS == AutodialReadRegistrySettings(NULL,szEntryName1,szEntryName2,&adConnInfo)) 
	{
		DEBUGCHK(szEntryName1[0]);

		if (GetConnectedStatus(szEntryName1,lpRasConnStatus,phRasConn)) 
		{
			_tcscpy(szRasName,szEntryName1);
			dwRet = ERROR_SUCCESS;
		}
		else if (szEntryName2[0] && GetConnectedStatus(szEntryName2,lpRasConnStatus,phRasConn)) 
		{
			_tcscpy(szRasName,szEntryName2);
			dwRet = ERROR_SUCCESS;
		}
		else 
		{
			dwRet = ERROR_NO_CONNECTION;
		}
	}
	else
	{
		lpRasConnStatus->rasconnstate = RASCS_Disconnected;
		szRasName[0] = 0;
		dwRet = ERROR_NO_CONNECTION;
	}
	return dwRet;
}



// SetFailTime and CheckFailRetry are functions that help maintain and check
// the last time of failure list.  The idea here is that we don't want autodial
// to keep trying to dial again and again if it constantly fails.

// Called on failure of Autodial to establish a connection.
void SetFailTime(void)
{
	__int64    ftNow;		// treated as a FILETIME
	DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+SetFailTime\r\n")));

	if (!g_AutoDialConn.m_ftFailRetryWait)
		return;
	
	GetCurrentFT((FILETIME *) &ftNow);
	if (ftNow - g_AutoDialConn.g_ftLastFailTime < g_AutoDialConn.m_ftFailRetryWait)
	{
		g_AutoDialConn.m_iLastFailIndex += 1;
	}
	else
	{
		g_AutoDialConn.g_ftLastFailTime = ftNow;
		g_AutoDialConn.m_iLastFailIndex = 1;
	}
}

// Called on initilization, makes sure numerous calls to the autodialer haven't
// failed in a short time frame.
BOOL CheckFailRetry(void)
{
	__int64    ftNow;	// treated as a FILETIME

	DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+CheckFailRetry\r\n")));
	if (!g_AutoDialConn.m_ftFailRetryWait || 
	     g_AutoDialConn.m_iLastFailIndex < FAIL_RETRY_ATTEMPTS)
	{
		return TRUE;
	}

	GetCurrentFT((FILETIME *) &ftNow);
	
	if (ftNow - g_AutoDialConn.g_ftLastFailTime < g_AutoDialConn.m_ftFailRetryWait)
	{
		DEBUGMSG(ZONE_ERROR,(TEXT("Autodial:CheckFailRetry has failed, too many retries\r\n")));
		return FALSE;
	}
	
	return TRUE;
}

typedef DWORD (WINAPI *PFN_GETINTERFACEINFO)(IN PIP_INTERFACE_INFO pIfTable, OUT PULONG dwOutBufLen);
typedef DWORD (WINAPI *PFN_IPRELEASEADDRESS)(PIP_ADAPTER_INDEX_MAP AdapterInfo);
typedef DWORD (WINAPI *PFN_IPRENEWADDRESS)(PIP_ADAPTER_INDEX_MAP AdapterInfo);

PFN_GETINTERFACEINFO pfnGetInterfaceInfo;
PFN_IPRELEASEADDRESS pfnIpReleaseAddress;
PFN_IPRENEWADDRESS   pfnIpRenewAddress;

// Connection Sharing (i.e. NAT, i.e. ICS, i.e. Home Gateway) determines whether
// to enable Address translation when it receives a LanaUp call on a given
// interface based on whether the reg key HKLM\Comm\ConnectionSharing\PublicInterface
// mateches the name of interface coming up.  Before we call RasDial we reset
// this reg key.

void SetAsPublicInterface(TCHAR *szEntryName)
{
	HKEY            hKey;
	static TCHAR    PrimaryPublicInterface[257];
	static DWORD    dwTypePublicInterface;

	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, ICSRegKey, 0, 
	                                  KEY_ALL_ACCESS, &hKey))
	{
		return;
	}
	
	if(szEntryName != NULL)
	{
	    //
	    // Store the name of our primary public interface before overriding it with autodial adapter
	    //
	    if(PrimaryPublicInterface[0] == TEXT('\x0'))
	    {
	        DWORD dw = sizeof(PrimaryPublicInterface);
	    
	        RegQueryValueEx(hKey, ICSRegPublicInterface, 0, &dwTypePublicInterface, (LPBYTE)PrimaryPublicInterface, &dw);
	    }
	    
	    //
	    // Set PublicInterface registry value to the name of autodial network adapter
	    //
	    RegSetValueEx(hKey, ICSRegPublicInterface, 0, REG_SZ, (LPBYTE)szEntryName, sizeof(TCHAR)*(lstrlen(szEntryName)+1));
	}
	else
	{
	    //
	    // Restore PublicInterface registry value to our primary public interface
	    //
	    RegSetValueEx(hKey, ICSRegPublicInterface, 0, dwTypePublicInterface, (LPBYTE)PrimaryPublicInterface, sizeof(TCHAR)*(lstrlen(PrimaryPublicInterface)+1));
	    
	    if(pfnGetInterfaceInfo && pfnIpReleaseAddress && pfnIpRenewAddress)
	    {
	        DWORD dwSize = 0;
	        
	        if(ERROR_INSUFFICIENT_BUFFER == (*pfnGetInterfaceInfo)(NULL, &dwSize))
	        {
	            PIP_INTERFACE_INFO pIfTable;
	            
	            if(pIfTable = (PIP_INTERFACE_INFO)LocalAlloc(LMEM_FIXED, dwSize))
	            {
	                if(ERROR_SUCCESS == (*pfnGetInterfaceInfo)(pIfTable, &dwSize))
	                {
	                    int i;
    	                
	                    for(i = 0; i < pIfTable->NumAdapters; ++i)
	                    {
	                        if(0 == wcscmp(pIfTable->Adapter[i].Name, PrimaryPublicInterface))
	                        {
	                            //
	                            // Release and immediately renew IP address of the primary public interface
	                            // so that NAT can reinitialize itself to use the primary interface.
	                            //
	                            (*pfnIpReleaseAddress)(&pIfTable->Adapter[i]);
	                            (*pfnIpRenewAddress)(&pIfTable->Adapter[i]);
	                            break;
	                        }
	                    }
	                }
    	            
	                LocalFree(pIfTable);
	            }
	        }
	    }
	    
	    PrimaryPublicInterface[0] = TEXT('\x0');
	}
	
	RegCloseKey(hKey);
	return;
}



BOOL WINAPI DllEntry( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
	static HANDLE hIphplapi = NULL;
	
	switch(fdwReason) 
	{
        case DLL_PROCESS_ATTACH:
#ifdef UNDER_CE
			DEBUGREGISTER((HINSTANCE)hInstDll);
#endif		
            g_hInstance = hInstDll;
            DisableThreadLibraryCalls ((HMODULE)hInstDll);
            
            if(hIphplapi = LoadLibrary(L"iphlpapi.dll"))
            {
                pfnGetInterfaceInfo = (PFN_GETINTERFACEINFO) GetProcAddress(hIphplapi, L"GetInterfaceInfo");
                pfnIpReleaseAddress = (PFN_IPRELEASEADDRESS) GetProcAddress(hIphplapi, L"IpReleaseAddress");
                pfnIpRenewAddress = (PFN_IPRENEWADDRESS) GetProcAddress(hIphplapi, L"IpRenewAddress");
            }
		    break;

		case DLL_PROCESS_DETACH:
		    
		    if(hIphplapi)
		        FreeLibrary(hIphplapi);
		
		break;
	}
	return TRUE;
}

⌨️ 快捷键说明

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