937 lines
28 KiB
C
937 lines
28 KiB
C
|
/*********************************************************************/
|
|||
|
/** Copyright(c) 1995 Microsoft Corporation. **/
|
|||
|
/*********************************************************************/
|
|||
|
|
|||
|
//***
|
|||
|
//
|
|||
|
// Filename: rasapiif.c
|
|||
|
//
|
|||
|
// Description: Handles all the RASAPI32 calls
|
|||
|
//
|
|||
|
// History: May 11,1996 NarenG Created original version.
|
|||
|
//
|
|||
|
#include "ddm.h"
|
|||
|
#include "util.h"
|
|||
|
#include "objects.h"
|
|||
|
#include "rasmanif.h"
|
|||
|
#include "rasapiif.h"
|
|||
|
#include "handlers.h"
|
|||
|
#include "timer.h"
|
|||
|
#include <time.h>
|
|||
|
#include <mprapi.h>
|
|||
|
#include <mprapip.h>
|
|||
|
|
|||
|
HPORT
|
|||
|
RasGetHport(
|
|||
|
IN HRASCONN hRasConnSubEntry
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
RasPortConnected(
|
|||
|
IN HRASCONN hRasConn,
|
|||
|
IN HRASCONN hRasConnSubEntry,
|
|||
|
IN DEVICE_OBJECT * pDevObj,
|
|||
|
IN HANDLE hDIMInterface
|
|||
|
)
|
|||
|
{
|
|||
|
CONNECTION_OBJECT * pConnObj;
|
|||
|
DWORD dwRetCode;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|||
|
|
|||
|
//
|
|||
|
// Set this port to be notified by rasapi32 on disconnect.
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = RasConnectionNotification(
|
|||
|
hRasConnSubEntry,
|
|||
|
gblSupervisorEvents[NUM_DDM_EVENTS
|
|||
|
+ (gblDeviceTable.NumDeviceBuckets*2)
|
|||
|
+ DeviceObjHashPortToBucket(pDevObj->hPort)],
|
|||
|
RASCN_Disconnection );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasConnectionNotification returned %d", dwRetCode );
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get handle to the connection or bundle for this link
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = RasPortGetBundle(NULL, pDevObj->hPort, &(pDevObj->hConnection));
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasPortGetBundle returned %d", dwRetCode );
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
pIfObject = IfObjectGetPointer( hDIMInterface );
|
|||
|
|
|||
|
if ( pIfObject == NULL )
|
|||
|
{
|
|||
|
RTASSERT( FALSE );
|
|||
|
dwRetCode = ERROR_NO_SUCH_INTERFACE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If this interface was disconnected by DDMDisconnectInterface,
|
|||
|
// then do not let this device through.
|
|||
|
//
|
|||
|
|
|||
|
if ( pIfObject->fFlags & IFFLAG_DISCONNECT_INITIATED )
|
|||
|
{
|
|||
|
dwRetCode = ERROR_PORT_DISCONNECTED;
|
|||
|
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasPortConnected: Admin disconnected port" );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Allocate a connection object if it does not exist yet
|
|||
|
//
|
|||
|
|
|||
|
pConnObj = ConnObjGetPointer( pDevObj->hConnection );
|
|||
|
|
|||
|
if ( pConnObj == (CONNECTION_OBJECT *)NULL )
|
|||
|
{
|
|||
|
RASPPPIP RasPppIp;
|
|||
|
RASPPPIPX RasPppIpx;
|
|||
|
DWORD dwSize;
|
|||
|
|
|||
|
pConnObj = ConnObjAllocateAndInit( hDIMInterface,
|
|||
|
pDevObj->hConnection );
|
|||
|
|
|||
|
if ( pConnObj == (CONNECTION_OBJECT *)NULL )
|
|||
|
{
|
|||
|
dwRetCode = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
ConnObjInsertInTable( pConnObj );
|
|||
|
|
|||
|
//
|
|||
|
// First get the projection info, make sure IP or IPX
|
|||
|
// were negotiated
|
|||
|
//
|
|||
|
|
|||
|
dwSize = sizeof( RasPppIpx );
|
|||
|
RasPppIpx.dwSize = sizeof( RasPppIpx );
|
|||
|
|
|||
|
dwRetCode = RasGetProjectionInfo(
|
|||
|
hRasConn,
|
|||
|
RASP_PppIpx,
|
|||
|
&RasPppIpx,
|
|||
|
&dwSize );
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
pConnObj->PppProjectionResult.ipx.dwError = dwRetCode;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pConnObj->PppProjectionResult.ipx.dwError = RasPppIpx.dwError;
|
|||
|
|
|||
|
ConvertStringToIpxAddress(
|
|||
|
RasPppIpx.szIpxAddress,
|
|||
|
pConnObj->PppProjectionResult.ipx.bLocalAddress);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
dwSize = sizeof( RasPppIp );
|
|||
|
RasPppIp.dwSize = sizeof( RasPppIp );
|
|||
|
|
|||
|
dwRetCode = RasGetProjectionInfo(
|
|||
|
hRasConn,
|
|||
|
RASP_PppIp,
|
|||
|
&RasPppIp,
|
|||
|
&dwSize );
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
pConnObj->PppProjectionResult.ip.dwError = dwRetCode;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pConnObj->PppProjectionResult.ip.dwError = RasPppIp.dwError;
|
|||
|
|
|||
|
ConvertStringToIpAddress(
|
|||
|
RasPppIp.szIpAddress,
|
|||
|
&(pConnObj->PppProjectionResult.ip.dwLocalAddress));
|
|||
|
|
|||
|
ConvertStringToIpAddress(
|
|||
|
RasPppIp.szServerIpAddress,
|
|||
|
&(pConnObj->PppProjectionResult.ip.dwRemoteAddress));
|
|||
|
}
|
|||
|
|
|||
|
if ((pConnObj->PppProjectionResult.ipx.dwError!=NO_ERROR )
|
|||
|
&&
|
|||
|
(pConnObj->PppProjectionResult.ip.dwError!=NO_ERROR ))
|
|||
|
{
|
|||
|
dwRetCode = ERROR_PPP_NO_PROTOCOLS_CONFIGURED;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
pConnObj->fFlags = CONN_OBJ_IS_PPP;
|
|||
|
pConnObj->hPort = pDevObj->hPort;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Make sure that we are adding a link to a connection for the
|
|||
|
// same interface that initiated the connection.
|
|||
|
//
|
|||
|
|
|||
|
if ( hDIMInterface != pConnObj->hDIMInterface )
|
|||
|
{
|
|||
|
dwRetCode = ERROR_INTERFACE_CONFIGURATION;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pDevObj->hRasConn = hRasConnSubEntry;
|
|||
|
GetSystemTimeAsFileTime( (FILETIME*)&(pDevObj->qwActiveTime) );
|
|||
|
|
|||
|
//
|
|||
|
// Add this link to the connection block.
|
|||
|
//
|
|||
|
|
|||
|
if ((dwRetCode = ConnObjAddLink(pConnObj, pDevObj)) != NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Notify router managers that we are connected if we have
|
|||
|
// not done so already.
|
|||
|
//
|
|||
|
|
|||
|
if ( !( pConnObj->fFlags & CONN_OBJ_PROJECTIONS_NOTIFIED ) )
|
|||
|
{
|
|||
|
RASDIALPARAMS RasDialParams;
|
|||
|
BOOL fPassword;
|
|||
|
|
|||
|
dwRetCode = IfObjectConnected(
|
|||
|
hDIMInterface,
|
|||
|
(HCONN)pDevObj->hConnection,
|
|||
|
&(pConnObj->PppProjectionResult) );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
pConnObj->fFlags |= CONN_OBJ_PROJECTIONS_NOTIFIED;
|
|||
|
|
|||
|
//
|
|||
|
// Get username and domain name
|
|||
|
//
|
|||
|
|
|||
|
ZeroMemory( &RasDialParams, sizeof( RasDialParams ) );
|
|||
|
RasDialParams.dwSize = sizeof( RasDialParams );
|
|||
|
wcscpy( RasDialParams.szEntryName, pIfObject->lpwsInterfaceName );
|
|||
|
|
|||
|
dwRetCode = RasGetEntryDialParams( gblpRouterPhoneBook,
|
|||
|
&RasDialParams,
|
|||
|
&fPassword);
|
|||
|
|
|||
|
if ( dwRetCode == NO_ERROR )
|
|||
|
{
|
|||
|
wcscpy( pConnObj->wchUserName, RasDialParams.szUserName );
|
|||
|
wcscpy( pConnObj->wchDomainName, RasDialParams.szDomain );
|
|||
|
ZeroMemory( &RasDialParams, sizeof( RasDialParams ) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
wcscpy( pConnObj->wchInterfaceName, pIfObject->lpwsInterfaceName );
|
|||
|
|
|||
|
GetSystemTimeAsFileTime( (FILETIME*)&(pDevObj->qwActiveTime) );
|
|||
|
pConnObj->qwActiveTime = pDevObj->qwActiveTime;
|
|||
|
pConnObj->InterfaceType = pIfObject->IfType;
|
|||
|
|
|||
|
pIfObject->dwLastError = NO_ERROR;
|
|||
|
|
|||
|
//
|
|||
|
// If this was initiated by an admin api. Let the caller
|
|||
|
// know that we are connected.
|
|||
|
//
|
|||
|
|
|||
|
if (pIfObject->hEventNotifyCaller != INVALID_HANDLE_VALUE)
|
|||
|
{
|
|||
|
SetEvent( pIfObject->hEventNotifyCaller );
|
|||
|
|
|||
|
CloseHandle( pIfObject->hEventNotifyCaller );
|
|||
|
|
|||
|
pIfObject->hEventNotifyCaller = INVALID_HANDLE_VALUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Reduce the media count for this device
|
|||
|
//
|
|||
|
|
|||
|
if ( !(pDevObj->fFlags & DEV_OBJ_MARKED_AS_INUSE) )
|
|||
|
{
|
|||
|
if ( pDevObj->fFlags & DEV_OBJ_ALLOW_ROUTERS )
|
|||
|
{
|
|||
|
MediaObjRemoveFromTable( pDevObj->wchDeviceType );
|
|||
|
}
|
|||
|
|
|||
|
pDevObj->fFlags |= DEV_OBJ_MARKED_AS_INUSE;
|
|||
|
|
|||
|
gblDeviceTable.NumDevicesInUse++;
|
|||
|
|
|||
|
//
|
|||
|
// Possibly need to notify the router managers of
|
|||
|
// unreachability
|
|||
|
//
|
|||
|
|
|||
|
IfObjectNotifyAllOfReachabilityChange( FALSE,
|
|||
|
INTERFACE_OUT_OF_RESOURCES );
|
|||
|
}
|
|||
|
|
|||
|
RasSetRouterUsage( pDevObj->hPort, TRUE );
|
|||
|
|
|||
|
}while( FALSE );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasPortConnected: Cleaning up hPort=%d, error %d",
|
|||
|
pDevObj->hPort, dwRetCode );
|
|||
|
|
|||
|
RasApiCleanUpPort( pDevObj );
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: RasConnectCallback
|
|||
|
//
|
|||
|
// Returns: None
|
|||
|
//
|
|||
|
// Description: Callback function that will be called by RASAPI32 for any
|
|||
|
// state change.
|
|||
|
//
|
|||
|
BOOL
|
|||
|
RasConnectCallback(
|
|||
|
IN DWORD dwCallbackId,
|
|||
|
IN DWORD dwSubEntryId,
|
|||
|
IN HRASCONN hRasConn,
|
|||
|
IN DWORD dwMsg,
|
|||
|
IN RASCONNSTATE RasConnState,
|
|||
|
IN DWORD dwError,
|
|||
|
IN DWORD dwExtendedError
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwIndex;
|
|||
|
ROUTER_INTERFACE_OBJECT * pIfObject = NULL;
|
|||
|
DEVICE_OBJECT * pDevObj = NULL;
|
|||
|
HANDLE hDIMInterface = (HANDLE)UlongToPtr(dwCallbackId);
|
|||
|
HRASCONN hRasConnSubEntry;
|
|||
|
DWORD dwRetCode;
|
|||
|
HPORT hPort;
|
|||
|
LPWSTR lpwsAudit[2];
|
|||
|
|
|||
|
if ( dwMsg != WM_RASDIALEVENT )
|
|||
|
{
|
|||
|
RTASSERT( dwMsg == WM_RASDIALEVENT );
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
switch( RasConnState )
|
|||
|
{
|
|||
|
|
|||
|
case RASCS_Connected:
|
|||
|
case RASCS_SubEntryConnected:
|
|||
|
case RASCS_SubEntryDisconnected:
|
|||
|
case RASCS_Disconnected:
|
|||
|
case RASCS_PortOpened:
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
if ( dwError != NO_ERROR )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Ignore these intermediate events
|
|||
|
//
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|||
|
|
|||
|
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
//
|
|||
|
// Get pointer to device object and hRasConn of the device
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = RasGetSubEntryHandle( hRasConn,
|
|||
|
dwSubEntryId,
|
|||
|
&hRasConnSubEntry );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasGetSubEntryHandle( 0x%x, 0x%x, 0x%x ) = %d",
|
|||
|
hRasConn, dwSubEntryId, &hRasConnSubEntry, dwRetCode );
|
|||
|
|
|||
|
if ( dwError == NO_ERROR )
|
|||
|
{
|
|||
|
dwError = dwRetCode;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
hPort = RasGetHport( hRasConnSubEntry );
|
|||
|
|
|||
|
if ( hPort == (HPORT)INVALID_HANDLE_VALUE )
|
|||
|
{
|
|||
|
RTASSERT( FALSE );
|
|||
|
|
|||
|
dwRetCode = ERROR_INVALID_PORT_HANDLE;
|
|||
|
|
|||
|
if ( dwError == NO_ERROR )
|
|||
|
{
|
|||
|
dwError = dwRetCode;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( ( pDevObj = DeviceObjGetPointer( hPort ) ) == NULL )
|
|||
|
{
|
|||
|
dwRetCode = ERROR_NOT_ROUTER_PORT;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( !( pDevObj->fFlags & DEV_OBJ_ALLOW_ROUTERS ) )
|
|||
|
{
|
|||
|
dwRetCode = ERROR_NOT_ROUTER_PORT;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( dwError == NO_ERROR )
|
|||
|
{
|
|||
|
dwError = dwRetCode;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( dwError == NO_ERROR )
|
|||
|
{
|
|||
|
switch( RasConnState )
|
|||
|
{
|
|||
|
case RASCS_PortOpened:
|
|||
|
|
|||
|
pDevObj->fFlags |= DEV_OBJ_OPENED_FOR_DIALOUT;
|
|||
|
pDevObj->hRasConn = hRasConnSubEntry;
|
|||
|
break;
|
|||
|
|
|||
|
case RASCS_Connected:
|
|||
|
case RASCS_SubEntryConnected:
|
|||
|
|
|||
|
DDM_PRINT(gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasConnectCallback:PortConnected,dwSubEntryId=%d,hPort=%d",
|
|||
|
dwSubEntryId, hPort );
|
|||
|
|
|||
|
dwError = RasPortConnected( hRasConn,
|
|||
|
hRasConnSubEntry,
|
|||
|
pDevObj,
|
|||
|
hDIMInterface );
|
|||
|
break;
|
|||
|
|
|||
|
case RASCS_SubEntryDisconnected:
|
|||
|
case RASCS_Disconnected:
|
|||
|
|
|||
|
pDevObj->fFlags &= ~DEV_OBJ_OPENED_FOR_DIALOUT;
|
|||
|
pDevObj->hRasConn = (HRASCONN)NULL;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
RTASSERT( FALSE );
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if ( ( RasConnState == RASCS_Connected ) ||
|
|||
|
( RasConnState == RASCS_SubEntryConnected )||
|
|||
|
( RasConnState == RASCS_PortOpened ) )
|
|||
|
{
|
|||
|
if ( dwError == NO_ERROR )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( pDevObj != NULL )
|
|||
|
{
|
|||
|
pDevObj->fFlags &= ~DEV_OBJ_OPENED_FOR_DIALOUT;
|
|||
|
pDevObj->hRasConn = (HRASCONN)NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DDM_PRINT(gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasConnectCallback:Could not connect to SubEntry %d,dwError=%d",
|
|||
|
dwSubEntryId, dwError );
|
|||
|
|
|||
|
//
|
|||
|
// Has the bundle failed to connect?
|
|||
|
//
|
|||
|
|
|||
|
pIfObject = IfObjectGetPointer( hDIMInterface );
|
|||
|
|
|||
|
if ( pIfObject == NULL )
|
|||
|
{
|
|||
|
RTASSERT( FALSE );
|
|||
|
dwError = ERROR_NO_SUCH_INTERFACE;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
--pIfObject->dwNumSubEntriesCounter;
|
|||
|
|
|||
|
if ( ( pIfObject->dwNumSubEntriesCounter == 0 ) ||
|
|||
|
( RasConnState == RASCS_Disconnected ) ||
|
|||
|
!(pIfObject->fFlags & IFFLAG_DIALMODE_DIALALL))
|
|||
|
{
|
|||
|
if ( pIfObject->State == RISTATE_CONNECTED )
|
|||
|
{
|
|||
|
//
|
|||
|
// Interface is already connected so it doesn't matter if this
|
|||
|
// device failed.
|
|||
|
//
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasConnectCallback:Could not connect to interface %ws",
|
|||
|
pIfObject->lpwsInterfaceName );
|
|||
|
|
|||
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"RasConnectCallback: hanging up 0x%x", pIfObject->hRasConn);
|
|||
|
RasHangUp( pIfObject->hRasConn );
|
|||
|
|
|||
|
pIfObject->hRasConn = (HRASCONN)NULL;
|
|||
|
|
|||
|
//
|
|||
|
// If the admin as initiated a disconnect or we are out of
|
|||
|
// retries
|
|||
|
//
|
|||
|
|
|||
|
if ( ( pIfObject->fFlags & IFFLAG_DISCONNECT_INITIATED ) ||
|
|||
|
( pIfObject->dwNumOfReConnectAttemptsCounter == 0 ) )
|
|||
|
{
|
|||
|
//
|
|||
|
// Mark as unreachable due to connection failure the admin did
|
|||
|
// not disconnect.
|
|||
|
//
|
|||
|
|
|||
|
if ( !( pIfObject->fFlags & IFFLAG_DISCONNECT_INITIATED ) )
|
|||
|
{
|
|||
|
pIfObject->fFlags |= IFFLAG_CONNECTION_FAILURE;
|
|||
|
}
|
|||
|
|
|||
|
IfObjectDisconnected( pIfObject );
|
|||
|
|
|||
|
IfObjectNotifyOfReachabilityChange(
|
|||
|
pIfObject,
|
|||
|
FALSE,
|
|||
|
INTERFACE_CONNECTION_FAILURE );
|
|||
|
|
|||
|
//
|
|||
|
// If we were disconnected by the admin then we should
|
|||
|
// immediately go to the reachable state.
|
|||
|
//
|
|||
|
|
|||
|
if ( pIfObject->fFlags & IFFLAG_DISCONNECT_INITIATED )
|
|||
|
{
|
|||
|
IfObjectNotifyOfReachabilityChange(
|
|||
|
pIfObject,
|
|||
|
TRUE,
|
|||
|
INTERFACE_CONNECTION_FAILURE );
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->dwLastError = dwError;
|
|||
|
|
|||
|
if ( pDevObj != NULL )
|
|||
|
{
|
|||
|
lpwsAudit[0] = pIfObject->lpwsInterfaceName;
|
|||
|
lpwsAudit[1] = pDevObj->wchPortName;
|
|||
|
|
|||
|
DDMLogErrorString( ROUTERLOG_CONNECTION_ATTEMPT_FAILED,
|
|||
|
2, lpwsAudit, dwError, 2 );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If this was initiated by an admin api. Let the caller
|
|||
|
// know that we are not connected.
|
|||
|
//
|
|||
|
|
|||
|
if (pIfObject->hEventNotifyCaller != INVALID_HANDLE_VALUE)
|
|||
|
{
|
|||
|
SetEvent( pIfObject->hEventNotifyCaller );
|
|||
|
|
|||
|
CloseHandle( pIfObject->hEventNotifyCaller );
|
|||
|
|
|||
|
pIfObject->hEventNotifyCaller = INVALID_HANDLE_VALUE;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Otherwise we try again
|
|||
|
//
|
|||
|
|
|||
|
pIfObject->dwNumOfReConnectAttemptsCounter--;
|
|||
|
|
|||
|
//
|
|||
|
// Stagger the reconnectime randomly between 0 and twice the
|
|||
|
// configured reconnect time.
|
|||
|
//
|
|||
|
|
|||
|
srand( (unsigned)time( NULL ) );
|
|||
|
|
|||
|
TimerQInsert(
|
|||
|
pIfObject->hDIMInterface,
|
|||
|
rand()%((pIfObject->dwSecondsBetweenReConnectAttempts*2)+1),
|
|||
|
ReConnectInterface );
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
while( FALSE );
|
|||
|
|
|||
|
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|||
|
|
|||
|
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: RasConnectionInitiate
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - Success
|
|||
|
// Non-zero returns - Failure
|
|||
|
//
|
|||
|
// Description: Called to initiate a demand-dial connection
|
|||
|
//
|
|||
|
DWORD
|
|||
|
RasConnectionInitiate(
|
|||
|
IN ROUTER_INTERFACE_OBJECT * pIfObject,
|
|||
|
IN BOOL fRedialAttempt
|
|||
|
)
|
|||
|
{
|
|||
|
RASDIALEXTENSIONS RasDialExtensions;
|
|||
|
RASDIALPARAMS RasDialParams;
|
|||
|
DWORD dwXportIndex;
|
|||
|
DWORD dwRetCode;
|
|||
|
RASENTRY re;
|
|||
|
DWORD dwSize;
|
|||
|
RASEAPUSERIDENTITY* pRasEapUserIdentity = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// Do not try to connect if the interface is disabled or out of resources
|
|||
|
// or the service is paused or the interface is marked as unreachable due
|
|||
|
// to connection failure.
|
|||
|
//
|
|||
|
|
|||
|
if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
|
|||
|
{
|
|||
|
return( ERROR_INTERFACE_DISABLED );
|
|||
|
}
|
|||
|
|
|||
|
if ( pIfObject->fFlags & IFFLAG_OUT_OF_RESOURCES )
|
|||
|
{
|
|||
|
return( ERROR_INTERFACE_HAS_NO_DEVICES );
|
|||
|
}
|
|||
|
|
|||
|
if ( gblDDMConfigInfo.pServiceStatus->dwCurrentState == SERVICE_PAUSED )
|
|||
|
{
|
|||
|
return( ERROR_SERVICE_IS_PAUSED );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If this is not a redial attempt then we reset the reconnect attempts
|
|||
|
// counter and unset the admin disconnected flag if it was set.
|
|||
|
//
|
|||
|
|
|||
|
if ( !fRedialAttempt )
|
|||
|
{
|
|||
|
pIfObject->dwNumOfReConnectAttemptsCounter =
|
|||
|
pIfObject->dwNumOfReConnectAttempts;
|
|||
|
|
|||
|
pIfObject->fFlags &= ~IFFLAG_DISCONNECT_INITIATED;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Do not allow the reconnect attempt to go thru if the admin has
|
|||
|
// disconnected this interface.
|
|||
|
//
|
|||
|
|
|||
|
if ( pIfObject->fFlags & IFFLAG_DISCONNECT_INITIATED )
|
|||
|
{
|
|||
|
return( ERROR_INTERFACE_DISCONNECTED );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Build PppInterfaceInfo structure to pass down to RasDial that will pass
|
|||
|
// it on to PPP.
|
|||
|
//
|
|||
|
|
|||
|
for ( dwXportIndex = 0;
|
|||
|
dwXportIndex < gblDDMConfigInfo.dwNumRouterManagers;
|
|||
|
dwXportIndex++ )
|
|||
|
{
|
|||
|
switch( gblRouterManagers[dwXportIndex].DdmRouterIf.dwProtocolId )
|
|||
|
{
|
|||
|
case PID_IPX:
|
|||
|
|
|||
|
|
|||
|
if (pIfObject->Transport[dwXportIndex].fState & RITRANSPORT_ENABLED)
|
|||
|
{
|
|||
|
pIfObject->PppInterfaceInfo.hIPXInterface =
|
|||
|
pIfObject->Transport[dwXportIndex].hInterface;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pIfObject->PppInterfaceInfo.hIPXInterface=INVALID_HANDLE_VALUE;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case PID_IP:
|
|||
|
|
|||
|
if (pIfObject->Transport[dwXportIndex].fState & RITRANSPORT_ENABLED)
|
|||
|
{
|
|||
|
pIfObject->PppInterfaceInfo.hIPInterface =
|
|||
|
pIfObject->Transport[dwXportIndex].hInterface;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pIfObject->PppInterfaceInfo.hIPInterface = INVALID_HANDLE_VALUE;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
RTASSERT( FALSE );
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->PppInterfaceInfo.IfType = pIfObject->IfType;
|
|||
|
pIfObject->dwNumSubEntriesCounter = pIfObject->dwNumSubEntries;
|
|||
|
|
|||
|
//
|
|||
|
// Initiate the connection
|
|||
|
//
|
|||
|
|
|||
|
ZeroMemory( &RasDialExtensions, sizeof( RasDialExtensions ) );
|
|||
|
RasDialExtensions.dwSize = sizeof( RasDialExtensions );
|
|||
|
RasDialExtensions.dwfOptions = RDEOPT_Router;
|
|||
|
RasDialExtensions.reserved = (ULONG_PTR)&(pIfObject->PppInterfaceInfo);
|
|||
|
|
|||
|
ZeroMemory( &RasDialParams, sizeof( RasDialParams ) );
|
|||
|
|
|||
|
RasDialParams.dwSize = sizeof( RasDialParams );
|
|||
|
RasDialParams.dwCallbackId = PtrToUlong(pIfObject->hDIMInterface);
|
|||
|
RasDialParams.dwSubEntry = 0;
|
|||
|
|
|||
|
wcscpy( RasDialParams.szCallbackNumber, TEXT("*") );
|
|||
|
wcscpy( RasDialParams.szEntryName, pIfObject->lpwsInterfaceName );
|
|||
|
|
|||
|
//
|
|||
|
// Do we need to call RasEapGetIdentity?
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = RasGetEapUserIdentity(
|
|||
|
gblpRouterPhoneBook,
|
|||
|
pIfObject->lpwsInterfaceName,
|
|||
|
RASEAPF_NonInteractive,
|
|||
|
NULL,
|
|||
|
&pRasEapUserIdentity);
|
|||
|
|
|||
|
if ( ERROR_INVALID_FUNCTION_FOR_ENTRY == dwRetCode )
|
|||
|
{
|
|||
|
//
|
|||
|
// This entry does not require RasEapGetIdentity. Get its credentials.
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = MprAdminInterfaceGetCredentialsInternal(
|
|||
|
NULL,
|
|||
|
pIfObject->lpwsInterfaceName,
|
|||
|
(LPWSTR)&(RasDialParams.szUserName),
|
|||
|
(LPWSTR)&(RasDialParams.szPassword),
|
|||
|
(LPWSTR)&(RasDialParams.szDomain) );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
return( ERROR_NO_INTERFACE_CREDENTIALS_SET );
|
|||
|
}
|
|||
|
}
|
|||
|
else if ( NO_ERROR != dwRetCode )
|
|||
|
{
|
|||
|
if ( ERROR_INTERACTIVE_MODE == dwRetCode )
|
|||
|
{
|
|||
|
dwRetCode = ERROR_NO_INTERFACE_CREDENTIALS_SET;
|
|||
|
}
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
wcscpy( RasDialParams.szUserName, pRasEapUserIdentity->szUserName );
|
|||
|
|
|||
|
RasDialExtensions.RasEapInfo.dwSizeofEapInfo =
|
|||
|
pRasEapUserIdentity->dwSizeofEapInfo;
|
|||
|
RasDialExtensions.RasEapInfo.pbEapInfo =
|
|||
|
pRasEapUserIdentity->pbEapInfo;
|
|||
|
}
|
|||
|
|
|||
|
if( (0 != gblDDMConfigInfo.cDigitalIPAddresses)
|
|||
|
|| (0 != gblDDMConfigInfo.cAnalogIPAddresses))
|
|||
|
{
|
|||
|
|
|||
|
ZeroMemory(&re, sizeof(RASENTRY));
|
|||
|
|
|||
|
re.dwSize = sizeof(RASENTRY);
|
|||
|
|
|||
|
dwSize = sizeof(RASENTRY);
|
|||
|
|
|||
|
if(ERROR_SUCCESS == (dwRetCode = RasGetEntryProperties(
|
|||
|
gblpRouterPhoneBook,
|
|||
|
pIfObject->lpwsInterfaceName,
|
|||
|
&re,
|
|||
|
&dwSize,
|
|||
|
NULL,
|
|||
|
NULL)))
|
|||
|
{
|
|||
|
if(RASET_Vpn == re.dwType)
|
|||
|
{
|
|||
|
char *pszMungedPhoneNumber = NULL;
|
|||
|
char szPhoneNumber[RAS_MaxPhoneNumber + 1];
|
|||
|
WCHAR wszMungedPhoneNumber[RAS_MaxPhoneNumber + 1];
|
|||
|
|
|||
|
//
|
|||
|
// Convert the phonenumber to ansi
|
|||
|
//
|
|||
|
|
|||
|
WideCharToMultiByte(
|
|||
|
CP_ACP,
|
|||
|
0,
|
|||
|
re.szLocalPhoneNumber,
|
|||
|
-1,
|
|||
|
szPhoneNumber,
|
|||
|
sizeof( szPhoneNumber ),
|
|||
|
NULL,
|
|||
|
NULL );
|
|||
|
|
|||
|
//
|
|||
|
// Munge the phonenumber
|
|||
|
//
|
|||
|
|
|||
|
dwRetCode = MungePhoneNumber(
|
|||
|
szPhoneNumber,
|
|||
|
gblDDMConfigInfo.dwIndex,
|
|||
|
&dwSize,
|
|||
|
&pszMungedPhoneNumber);
|
|||
|
|
|||
|
if(ERROR_SUCCESS == dwRetCode)
|
|||
|
{
|
|||
|
//
|
|||
|
// Change the munged phonenumber to widechar
|
|||
|
//
|
|||
|
|
|||
|
MultiByteToWideChar( CP_ACP,
|
|||
|
0,
|
|||
|
pszMungedPhoneNumber,
|
|||
|
-1,
|
|||
|
wszMungedPhoneNumber,
|
|||
|
RAS_MaxPhoneNumber + 1);
|
|||
|
|
|||
|
if ( wcslen( wszMungedPhoneNumber ) <= RAS_MaxPhoneNumber)
|
|||
|
{
|
|||
|
wcscpy( RasDialParams.szPhoneNumber,
|
|||
|
wszMungedPhoneNumber );
|
|||
|
|
|||
|
DDM_PRINT(gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|||
|
"Munged Phone Number=%ws",
|
|||
|
RasDialParams.szPhoneNumber);
|
|||
|
|
|||
|
//
|
|||
|
// Increase the index so that we try the
|
|||
|
// next FEP the next time this is dialed.
|
|||
|
//
|
|||
|
|
|||
|
gblDDMConfigInfo.dwIndex += 1;
|
|||
|
|
|||
|
LocalFree( pszMungedPhoneNumber );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
dwRetCode = RasDial( &RasDialExtensions,
|
|||
|
gblpRouterPhoneBook,
|
|||
|
&RasDialParams,
|
|||
|
2,
|
|||
|
RasConnectCallback,
|
|||
|
&(pIfObject->hRasConn) );
|
|||
|
|
|||
|
//
|
|||
|
// Zero out these since they contained sensitive password information
|
|||
|
//
|
|||
|
|
|||
|
ZeroMemory( &RasDialParams, sizeof( RasDialParams ) );
|
|||
|
|
|||
|
RasFreeEapUserIdentity( pRasEapUserIdentity );
|
|||
|
|
|||
|
if ( dwRetCode != NO_ERROR )
|
|||
|
{
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
pIfObject->State = RISTATE_CONNECTING;
|
|||
|
|
|||
|
pIfObject->fFlags |= IFFLAG_LOCALLY_INITIATED;
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
}
|