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 );
|
||
}
|