📄 autodial.c
字号:
if (!g_AutoDialConn.m_hTimerThread)
{
DEBUGMSG(ZONE_ERROR,(TEXT("Autodial: CreateThread for HangUpIdleConnectionThread failed, GLE=0x%08x\r\n"),GetLastError()));
}
#endif
g_fState = STATE_ON;
}
return dwRet;
}
DWORD AutoDialEndConnection(void)
{
return AutoDialEndConnectionInternal(FALSE);
}
// Closes the Autodial connection and frees associated resources.
// fTimedOut = TRUE if there's been a long idle time,
// fTimedOut = FALSE if we're being disconnected manually.
DWORD AutoDialEndConnectionInternal(BOOL fTimedOut)
{
BOOL fExecute = FALSE;
BOOL fShutdownInOtherProc = FALSE;
DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+AutoDialEndConnectionInternal\r\n")));
EnterCriticalSection(&g_GlobalCS);
if (STATE_ON == g_fState)
{
g_fState = STATE_SHUTTING_DOWN;
fExecute = TRUE;
}
else if (STATE_OFF == g_fState)
{
HRASCONN hRasConn;
RASCONNSTATUS rasConnStatus;
TCHAR szRasName[RAS_MaxEntryName+1];
// If we've been connected from another process, still terminate the request.
if (ERROR_SUCCESS == DetermineIfAutodialConnectionsActive(&rasConnStatus,szRasName,&hRasConn) &&
(rasConnStatus.rasconnstate != RASCS_Disconnected))
{
MyHangUp(&hRasConn);
}
fShutdownInOtherProc = TRUE;
}
LeaveCriticalSection(&g_GlobalCS);
if (!fExecute)
{
DEBUGMSG(ZONE_WARN,(TEXT("AutoDial:AutoDialEndConnectionInternal - can not shut down\r\n")));
// Another thread is disconnecting.
if (g_fState == STATE_SHUTTING_DOWN)
return ERROR_ALREADY_DISCONNECTING;
else
return fShutdownInOtherProc ? ERROR_SUCCESS : ERROR_NO_CONNECTION;
}
// Reset PublicInterface registry entry to what it was before we initialized the dialup connection
SetAsPublicInterface(NULL);
if (g_AutoDialConn.m_hRasConn)
MyHangUp(&g_AutoDialConn.m_hRasConn);
if (!fTimedOut)
{
// if g_AutoDialConn.m_hTimerEvent = 0, it'd mean that either the CreateThread
// failed at startup OR that there's a syncronization
// that someone else closed it on us. Not good in either case.
ASSERT(g_AutoDialConn.m_hTimerEvent);
if (g_AutoDialConn.m_hTimerEvent)
{
SetEvent(g_AutoDialConn.m_hTimerEvent);
WaitForSingleObject(g_AutoDialConn.m_hTimerThread,INFINITE);
}
}
CloseHandle(g_AutoDialConn.m_hTimerThread);
g_AutoDialConn.m_hTimerThread = 0;
ASSERT (g_fState == STATE_SHUTTING_DOWN);
g_fState = STATE_OFF;
g_AutoDialConn.szRasEntryName[0] = 0;
DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:-AutoDialEndConnectionInternal\r\n")));
return 0;
}
DWORD AutoDialGetConnectionStatus(RASCONNSTATUS *lpRasConnStatus, TCHAR *szRasName)
{
DWORD dwRet;
DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+AutoDialGetConnectionStatus\r\n")));
if (!lpRasConnStatus || !szRasName)
{
return ERROR_INVALID_PARAMETER;
}
szRasName[0] = 0;
if (!g_fAutodialInitialized)
{
DEBUGMSG(ZONE_ERROR,(TEXT("Autodial: AutoDialInitializeModule must be called before AutoDialStartConnection\r\n")));
ASSERT(0);
return ERROR_RASAUTO_CANNOT_INITIALIZE;
}
EnterCriticalSection(&g_GlobalCS);
if (STATE_ON == g_fState)
{
lpRasConnStatus->dwSize = sizeof(RASCONNSTATUS);
_tcscpy(szRasName,g_AutoDialConn.szRasEntryName);
dwRet = RasGetConnectStatus(g_AutoDialConn.m_hRasConn,lpRasConnStatus);
}
else
{
HRASCONN hRasConn;
dwRet = DetermineIfAutodialConnectionsActive(lpRasConnStatus,szRasName,&hRasConn);
}
LeaveCriticalSection(&g_GlobalCS);
DEBUGMSG(ZONE_CONNECTION | ZONE_FUNCTION,
(TEXT("AutoDial:-AutoDialGetConnectionStatus: szRasName=%s,RAS Err=%d,RasConnState = %d\r\n"),
szRasName,dwRet,lpRasConnStatus->rasconnstate));
return dwRet;
}
// Private helper functions
DWORD AutoDialConnect(RASDIALPARAMS *pRasDialParams)
{
static BOOL bWndClassRegistered = FALSE;
#ifdef DEBUG
DWORD err = 0;
#endif
DWORD dwRet = 0;
BOOL fPassword;
HWND hwndStatus = NULL;
MSG msg;
DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial: AutoDialConnect attempting to dial %s\r\n"),
pRasDialParams->szEntryName));
if (dwRet = RasGetEntryDialParams(NULL,pRasDialParams,&fPassword))
myleave(51);
if(g_AutoDialConn.m_fEnableOnPublicInterface)
{
RASENTRY* pRasEntry = NULL;
DWORD dwRasEntrySize = 0;
if(ERROR_BUFFER_TOO_SMALL != (dwRet = RasGetEntryProperties(NULL, pRasDialParams->szEntryName, pRasEntry, &dwRasEntrySize, NULL, 0)))
goto done;
if(!(pRasEntry = (RASENTRY*)LocalAlloc(LMEM_FIXED, dwRasEntrySize)))
{
dwRet = ERROR_OUTOFMEMORY;
goto done;
}
pRasEntry->dwSize = sizeof(RASENTRY);
if(ERROR_SUCCESS == (dwRet = RasGetEntryProperties(NULL, pRasDialParams->szEntryName, pRasEntry, &dwRasEntrySize, NULL, 0)))
{
//
// Set the network adapter associated with this RAS entry as NAT's public interface.
//
SetAsPublicInterface(pRasEntry->szDeviceName);
}
LocalFree(pRasEntry);
if(ERROR_SUCCESS != dwRet)
goto done;
}
if(!bWndClassRegistered)
{
if(IsAPIReady(SH_WMGR))
{
WNDCLASS wc = {0};
wc.lpfnWndProc = StatusWindowProc;
wc.hInstance = g_hInstance;
wc.lpszClassName = WND_CLASS;
RegisterClass(&wc);
bWndClassRegistered = TRUE;
}
}
if(bWndClassRegistered)
hwndStatus = CreateWindowEx(0, WND_CLASS, NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, g_hInstance, 0);
dwRet = RasDial(NULL, NULL, pRasDialParams, hwndStatus ? 0xFFFFFFFF : 0, hwndStatus, &g_AutoDialConn.m_hRasConn);
if (!dwRet)
{
if(!hwndStatus)
{
// Successful connection!
DEBUGMSG(ZONE_CONNECTION,(TEXT("AutoDial: Successfully connected to %s\r\n"),
pRasDialParams->szEntryName));
return 0;
}
else
{
RASCONNSTATUS RasConnStatus;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
dwRet = RasGetConnectStatus(g_AutoDialConn.m_hRasConn, &RasConnStatus);
if(ERROR_SUCCESS == dwRet)
dwRet = RasConnStatus.dwError;
if(ERROR_SUCCESS == dwRet)
{
DestroyWindow(hwndStatus);
// Successful connection!
DEBUGMSG(ZONE_CONNECTION,(TEXT("AutoDial: Successfully connected to %s\r\n"),
pRasDialParams->szEntryName));
return 0;
}
}
}
if(hwndStatus)
DestroyWindow(hwndStatus);
// Even though there was an error we still have to free resources associated with RasDial
if (g_AutoDialConn.m_hRasConn)
MyHangUp(&g_AutoDialConn.m_hRasConn);
g_AutoDialConn.m_hRasConn = 0;
done:
#ifdef DEBUG
DEBUGMSG(ZONE_ERROR,(TEXT("Autodial: AutoDialConnect failed to connect to %s with RAS err = %d, err = %d\r\n"),
pRasDialParams->szEntryName,dwRet,err));
#endif
return dwRet;
}
// Read registry settings and populate the pConnInfo structure.
DWORD AutodialReadRegistrySettings(TCHAR *pszDialRasEntryName, TCHAR *pszEntryName1, TCHAR *pszEntryName2, AUTODIAL_CONNECTION_INFO *pConnInfo)
{
#ifdef DEBUG
DWORD err = 0;
#endif
DWORD dwRet = 0;
DWORD dwLen;
DWORD dwIdleTimeOut;
DWORD dwFailRetry;
HKEY hkAutoDial = 0;
DEBUGMSG(ZONE_FUNCTION,(TEXT("AutoDial:+AutoDialReadRegistrySettings\r\n")));
// If they don't even have a registry key setup for this, fail.
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_AUTODIAL, 0, KEY_ALL_ACCESS, &hkAutoDial) && !pszDialRasEntryName)
myretleave(ERROR_RASAUTO_CANNOT_INITIALIZE,60);
dwLen = sizeof(DWORD);
// pszDialRasEntryName forces us to use the passed RAS connectiod name, ignoring
// whether autodial is disabled an the RAS names associated with it.
if (!pszDialRasEntryName)
{
DWORD dwEnabled;
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_ENABLED,0,0,(LPBYTE)&dwEnabled,&dwLen))
dwEnabled = 0; // by default, autodial is disabled.
if (!dwEnabled)
myretleave(ERROR_RASAUTO_CANNOT_INITIALIZE,70);
// Read the RAS entry name. The name MUST be set, or we return an error.
dwLen = (RAS_MaxEntryName + 1) * sizeof(TCHAR);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_ENTRYNAME1,0,0,(LPBYTE) pszEntryName1, &dwLen))
myretleave(ERROR_RASAUTO_CANNOT_INITIALIZE,80);
// The 2nd RAS entry name is optional.
dwLen = (RAS_MaxEntryName + 1) * sizeof(TCHAR);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_ENTRYNAME2,0,0,(LPBYTE) pszEntryName2, &dwLen))
pszEntryName2[0] = 0;
}
else
{
pszEntryName1[0] = pszEntryName2[0] = 0;
}
dwLen = sizeof(DWORD);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_IDLE_TIMEOUT,0,0,(LPBYTE)&dwIdleTimeOut,&dwLen))
dwIdleTimeOut = DEFAULT_IDLE_TIMEOUT;
pConnInfo->m_ftIdleTimeout = dwIdleTimeOut*FILETIME_TO_MILLISECONDS;
dwLen = sizeof(DWORD);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_FAIL_RETRY_WAIT,0,0,(LPBYTE)&dwFailRetry,&dwLen))
dwFailRetry = DEFAULT_FAIL_RETRY_WAIT;
pConnInfo->m_ftFailRetryWait = dwFailRetry*FILETIME_TO_MILLISECONDS;
dwLen = sizeof(DWORD);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_REDIAL_ATTEMPTS,0,0,(LPBYTE)&pConnInfo->m_dwRedialAttempts,&dwLen))
pConnInfo->m_dwRedialAttempts = DEFAULT_REDIAL_ATTEMPTS;
dwLen = sizeof(DWORD);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_REDIAL_PAUSE_TIME,0,0,(LPBYTE)&pConnInfo->m_dwRedialPauseTime,&dwLen))
pConnInfo->m_dwRedialPauseTime = DEFAULT_REDIAL_PAUSE_TIME;
dwLen = sizeof(DWORD);
if (ERROR_SUCCESS != RegQueryValueEx(hkAutoDial,RV_MAKE_PUBLIC_INTERFACE,0,0,(LPBYTE)&pConnInfo->m_fEnableOnPublicInterface,&dwLen))
pConnInfo->m_fEnableOnPublicInterface = TRUE;
done:
#ifdef DEBUG
if (err)
DEBUGMSG(ZONE_INIT,(TEXT("Autodial: Initialization failed, err = %d, RasError = %d\r\n"),err,dwRet));
else
DEBUGMSG(ZONE_INIT,(TEXT("Autodial: Init complete, idleTimeout = %d, FailRetryWait=%d, entry name1 = %s, entry name2 = %s, RedialAttempts = %d, RedialPauseTime = %d\r\n"),
dwIdleTimeOut,dwFailRetry,
pszEntryName1 ? pszEntryName1 : TEXT("NULL"),
pszEntryName2 ? pszEntryName2 : TEXT("NULL"),
pConnInfo->m_dwRedialAttempts,pConnInfo->m_dwRedialPauseTime));
#endif
if (hkAutoDial)
RegCloseKey(hkAutoDial);
return dwRet;
}
// This function runs in its own thread. Once the first connection has been established,
// it will wake up every minute and see when the last activity occured. After
// g_AutoDialConn.m_dwIdleTimeout milliseconds, it will hang up connection.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -